Closed Robloche closed 2 years ago
I tried to reproduce this issue in a small CodePen but didn't succeed. I was hoping someone else had run into a similar bug...
@Robloche I genuinely appreciate you attempting to create an example. I've only updated the labels to help organize and manage these issues at a higher level.
We really can't start to fix this until we can reproduce but we can keep this issue open as a light 🔦 for others that may run into something similar. And then maybe someone else will have a case that can be reproduced that we can move forward with.
Thank again for taking the time to create the issue and describe in detail what you're seeing, i'm hopeful this will help others and we can get the issue identified.
Update: The issue is still present in my app.
I'm sorry I cannot still reproduce this bug in a small example but I can now share my app. Please go to https://viva.videofutur.fr/, then:
@hartzis It would be super nice from you if you could just have a look at the bug and see if it rings some bell. Thanks!
Also not working for me and cannot reproduce or share app.
Update: The issue is still present in my app.
I'm sorry I cannot still reproduce this bug in a small example but I can now share my app. Please go to https://viva.videofutur.fr/, then:
- Check that you can drag the movie covers.
- Click on a movie. This opens a detailed view of the movie.
- Scroll down a bit and try dragging the covers.
- Notice how the dragging never ends.
@hartzis It would be super nice from you if you could just have a look at the bug and see if it rings some bell. Thanks!
I am able to replicate this on my desktop in chrome. 😳 that is weird...
I have no idea, lol. I'd need a reproducible example that i can edit/manipulate the code to investigate further.
Could you maybe share the code of just the Swipeable
usage for that element and how you're handling the translate for the carousel?
Thanks for having taken the time to check my issue. I'm glad you experienced it either. I really tried to build a CodePen but even with an intricate DOM structure, I couldn't reproduce the bug...
Regarding my code, I had to write the following React component since my codebase is a little bit old and does not use React hooks:
import * as React from 'react';
import {useSwipeable} from 'react-swipeable';
type SwipeablePropType = {
+children: React.Element<*>
};
export const Swipeable: React.ComponentType<SwipeablePropType> = ({children, ...props}: SwipeablePropType) => {
const handlers = useSwipeable(props);
/* eslint-disable react/jsx-props-no-spreading */
return <div
className='swipeable'
{...handlers}>{children}</div>;
/* eslint-enable react/jsx-props-no-spreading */
};
And here's how I use it:
<Swipeable
onSwiped={this.handleOnSwiped}
onSwiping={this.handleOnSwiping}
trackMouse>
<div
className='sectionSlider'
onTransitionEnd={this.handleOnTransitionEnd}
ref={(instance) => {
this.slider = instance;
}}>
{tiles}
</div>
</Swipeable>
handleOnSwiping = (eventData) => {
const {deltaX} = eventData;
const {displayType, maxPageIndex, pageIndex} = this.state;
const {slider, sliderPositions} = this;
if (!slider || maxPageIndex <= 0 || displayType === SECTION_DISPLAY_GRID) {
return;
}
// Trick explained below
this.setState({isSwiping: true});
const posX = sliderPositions[pageIndex];
const newPosX = posX + deltaX;
slider.style.transform = `translateX(${newPosX}px) translateZ(0)`;
};
handleOnSwiped = (eventData) => {
const {dir, velocity} = eventData;
const {displayType, maxPageIndex} = this.state;
// Trick explained below
this.resetSwipeTimeout();
this.swipeTimeout = setTimeout(() => this.setState({isSwiping: false}), SWIPE_COOLDOWN_TIME);
if (maxPageIndex <= 0 || displayType === SECTION_DISPLAY_GRID) {
return;
}
const pageStep = Math.ceil(velocity / PAGE_VELOCITY_STEP);
if (dir === 'Left') {
this.goToNextPage(pageStep);
} else if (dir === 'Right') {
this.goToPreviousPage(pageStep);
}
};
Without the isSwiping
trick, releasing the button that triggers onSwiped
event also triggers the opening of a tile's detailed view (depending on where the mouse cursor ended). So I wait 10 ms (SWIPE_COOLDOWN_TIME
) before allowing a click on a tile.
howdy again,
Was able to take a look today at your code above.
Couple things i noticed:
the timeout could have something to do with it 🤷
event
from the eventData
during handleOnSwiped
instead?
handleOnSwiped = (eventData) => {
const {dir, velocity, event} = eventData;
const {displayType, maxPageIndex} = this.state;
// prevent tile detail page from loading event.preventDefault()
Additionally i took another look at the page and interaction and noticed that the swiping stops if you release the mouse when you're not in the modal, so this tells me there may be something specific within the modal that is causing this weirdness.
i hope this helps you figure this out. Closing for now but please re-open and let me know if you're able to get an example working where i can test things out.
Hello,
First of all: thanks for taking a deeper look at my issue.
I tried event.preventDefault()
but it did not work (detail view still opens when mouse button is released), plus it did not solved my main issue.
However, I had totally missed the fact that the swiping stops if the button is release outside the modal. That gives me a solid track to explore.
I'll re-open this issue if something new occurs.
Thanks again,
I use
react-swipeable
in 2 different places in my app. In the first one, it perfectly works but in the second one,onSwiped
is not triggered.I used the event listener breakpoint of Chrome inspector and when I release the button, it correctly breaks. But the internal
onUp
function ofreact-swipeable
is never called.Several things worthy to note:
div
, one of them having theposition: fixed
rule).Here's how I use the hook:
Using
onSwiping
I set thetransform
CSS rule to make adiv
follow the mouse, then usingonSwiped
I actually perform an action on thediv
's content.I put
console.log
s into both handlers and here's what I get when it works:And when it doesn't:
The
swiped
log actually prints when I close the modal (i.e. unmount the component).I tested this with the latest versions of Chrome and Firefox.