Maintain dragHold onTouchMove#3107
Conversation
|
Another option might be to fork |
|
Maybe I should have started a new PR for #3074, but my new changes rely on the existing changes in here, so I combined them. The effect in I went through the uses of
So the logic is a little too complex to say definitively that it's OK to let |
|
I did test my changes against #2847 and I don't see any difference if I remove Both
so I believe that we should be covered whether or not this comment from |
|
I think I'm about ready to start experimenting with forking |
|
Hi! Thanks for all the information.
That makes sense. This seems relatively independent from other changes. Could we make this change in a separate PR? Cleaving off functionality on a complex issue like this will simplify the review process and provide a more granular commit history to track regressions.
For these kinds of references, it would be useful if you could link to the specific line(s) of code you are referring to in the codebase. That would make it quicker for me to get up to speed, as I wouldn't have to look it up by filename or Search in Files. If you use "Copy Permalink", then GitHub will insert the snippet:
Lines 47 to 57 in 1fee57f There may be an extension for VS Code that makes this easier to do from your editor, but I'm not sure. So far I have been browsing the codebase on GitHub to get this. Hope that's helpful :)
I would be open to it, if it's reliable. As you've pointed out, the root of the problem seems to be that If we reduced Are there any potential downsides to I'll make a high level comment as I'm trying to wrap my head around all this: Conceptually, a clean transition from
This is the only part that doesn't seem quite right to me. However please correct me if I'm missing your point.
The idea is that
We can hook into beginDrag if need to. I think that would correspond to the start of the drag, after FYI We're using a patched react-dnd because react-dnd/react-dnd#3664 hasn't been merged. |
The issue with #3074 is that I realize now that So I see the logic in putting |
It is, thanks. I was trying to get everything written down before I had to stop working for the day, but a lot of those big snippets could have been linked instead. |
I see, thank you. This makes total sense.
I wouldn't be comfortable allowing
Yes, I think that would definitely work. Another approach would be to add In the short term, it adds complexity by adding another touch/drag-related state variable. In the long term, it helps us transition from globals to Redux state. What do you think? |
It depends on how many milliseconds we reduced it by. I would assume that 25ms would be good enough, but would need to test it out.
I think the only downside is that it might not work. I don't think there's anything wrong with drag-and-drop beginning before the long press, but the events might interfere or get blocked. We would need to test it out to know for sure.
|
I think that sounds good, and it sounds like it will work. I could also see moving to a single variable that would be a sort of enum for the different state that it's in, like It looks like |
I can start a new one. It sounds like we are also going to revert the other changes in here and add some sort of |
Okay, I'm open to an empirical approach.
That's what I mean, you can use |
Yes! I like that. It would enforce mutual exclusivity. (We use PascalCase for enum values.)
This might just be semantics, but the Redux state is global. It just forces updates to occur in the order they are dispatched, helping with race conditions.
Yeah, this is a concern.
I'm not sure about a ref. Which component would it live in? The long press state needs to be coordinated across thoughts. To add to the confusion, we also have https://github.com/cybersemics/em/blob/c7d9cde5095e1866525ae9fd372a694242568db2/src/stores/longPressStore.ts. Though according to your comment, it may no longer be needed (?). (Separate PR to remove |
I was just saying that one of our options is to replace the timeout entirely so that we have more control over the internal timing of when I haven't mapped out exactly how that would work yet, which is why I haven't been more specific. Something like in a forked copy of
|
OK! That seems like a good change to make in a new PR.
Sure, maybe by "global" I really meant "unrestricted", since as we go into below, its value updates immediately and is not affected by React or Redux lifecycles.
Basically it would look something like: which is not my favorite pattern but it happens in plenty of other places.
|
Can you clarify. Is this a single ref for all thoughts, or a separate ref for each thought? |
I think a separate ref for each thought, since I would just put it into |
Got it, thanks. If all of the longpressing behavior were isolated to a single thought, I would be okay with a ref. For coordinating across thoughts, I would prefer to use the Redux store.
I'm not sure I understand the difference between the proposed I don't see the point of storing something from the Redux state in a ref when the Redux state can be accessed directly, but maybe I'm missing something.
Thanks, that will help reduce the scope and make it easier for me to evaluate the risk compared to solving #3072 and #3073 and #3074 all at once.
I generally agree with the need to synchronize the long press with react-dnd instead of maintaining a separate timeout in |
I'm hesitant to fork due to the maintenance costs that will potentially be incurred over time. I know we're trying to move away from the timeout approach, but what if we could guarantee that our This looks promising from my testing, and does not require a fork: const dragDropManager = useDragDropManager()
useEffect(() => {
const backend = dragDropManager.getBackend() as any
const onStart = () => {
setTimeout(() => {
console.log('handleTopMoveStartDelay should be called now')
}, TIMEOUT_LONG_PRESS_THOUGHT)
}
backend.addEventListener(backend.options.rootElement, 'start', onStart)
return () => {
backend.removeEventListener(backend.options.rootElement, 'start', onStart)
}
}, [dragDropManager]) |
The only thing is that variables pulled out of the state with |
|
Sorry, which |
This one, a secret third That's the only place that checks |
Omg 😱
In that case, maybe we could access |
Yeah, that's a good idea. |
I added that snippet to This looks promising because that ~40ms discrepancy would explain why there's a narrow window where If we want to, it should also be possible to move the |
Yes, this is what I'm suggesting. I think it would be less maintenance than a fork. If you are able to identify the (deterministic) cause of the 40ms discrepancy, then we could avoid tightly coupling to |

Fixes #3072 and #3073 and #3074
I can prevent the gesture from showing after the
dragHoldaction fires by adding that condition toshouldCancelGesture. Additionally, if I cleartimerIdRefafter the timeout fires and activates the long press, I can preventdragHoldfrom getting resetonTouchMove.However, drag-and-drop does not activate, most likely because
in
TouchBackendImpl.tsdoes not fire at the exact same time asin
useLongPress.So the result is that, after executing this type of quick move at the correct time:
touchmoveeventsonTouchEndVideo.14.mov
I'm still looking at
TouchBackendImplto try to verify that this is related tosetTimeout. Would you be open to subtracting a few milliseconds fromTIMEOUT_LONG_PRESS_THOUGHTin:in order to guarantee that drag-and-drop activates before long press, so that quick movements don't get discarded?