XKit-Rewritten icon indicating copy to clipboard operation
XKit-Rewritten copied to clipboard

feat(Quick Reblog): Improve touchscreen gesture compatibility

Open marcustyphoon opened this issue 1 month ago • 1 comments

Description

Currently, on touchscreen devices, the "hover the mouse over the reblog button" method used to open the Quick Reblog modal can only be triggered by tapping the button until the touchscreen device registers a long press, and relying on our code to cancel the resulting context menu, resulting in the "mouse" still being over the reblog button. This is slow, and also breaks in iOS, as there's no contextmenu event there for us to cancel.

This enables, in addition, a slightly different gesture: tapping the button and then slightly moving one's finger (which prevents the button from having its normal effect). The button can then be released immediately and the Quick Reblog menu should open. This is implemented by detecting the pointercancel event.

(pointerenter—which would straight-up replace mouseenter—or touchstart could potentially be used to slightly increase discoverability; that would make the Quick Reblog menu appear immediately on tap, even when doing a normal tap that does normal button behavior, which looks a little flicker-y I think. touchend should also work, with no particular benefit I can think of.)

We also need to be able to close the popup on touchscreens, just as we can open it. Unfortunately, no mouseleave or equivalent event can be used to trigger removePopupOnLeave() when using this gesture, I guess because the mouse/pointer/focus/whatever is never placed within the reblog button and so it never leaves. This thus fires that handler on any touch that's not within the button. Is there a less-stupid way to do this? (No, popover="auto" doesn't count.) edit: It's particularly notable with the new a/b that we want to be able to dismiss the popup without opening a post in the blog view modal.

Testing steps

On each type of testable touchscreen device, enable Quick Reblog and confirm that:

  • Tapping the reblog button does the normal button behavior; Quick Reblog has no effect
  • Long pressing the reblog button opens the Quick Reblog popup (unless the platform is iOS)
    • Once opened this way, the Quick Reblog modal can be closed by tapping outside of it and waiting a moment
    • Once opened this way, the Quick Reblog modal can be closed by tap-and-dragging outside of it, then waiting a moment (Chromium responsive design mode does not, as it has popupElement.parentNode?.matches(':hover') === true in this case, not sure why. Firefox responsive design mode does not let me test this. What does Firefox for Android do?)
  • Tapping and moving your finger slightly, then releasing the tab, opens the Quick Reblog popup
    • Once opened this way, the Quick Reblog modal can be closed by tapping outside of it and waiting a moment
    • Once opened this way, the Quick Reblog modal can be closed by tap-and-dragging outside of it, then waiting a moment
  • Enable Classic Footer with the "Turn reblog buttons back into links" option and repeat the above.

I have tested this in iOS 18 safari (real device), iOS safari 17 (simulator), desktop chromium 105 responsive design mode, and desktop firefox 145 responsive design mode. I haven't tested this in Firefox for Android (real device or simulator; I do have a simulator but I don't remember offhand how to work it).

marcustyphoon avatar Nov 29 '25 09:11 marcustyphoon

As I'm sure you've guessed:

  [
    'auxclick',
    'mousedown',
    'mouseenter',
    'mouseleave',
    // 'mousemove',
    'mouseout',
    'mouseover',
    'mouseup',
    'click',
    'pointercancel',
    'pointerdown',
    'pointerenter',
    'pointerleave',
    // 'pointermove',
    'pointerout',
    'pointerover',
    // 'pointerrawupdate',
    'pointerup',
    'touchcancel',
    'touchend',
    // 'touchmove',
    'touchstart'
  ].forEach(eventType => {
    reblogButton.addEventListener(eventType, event => {
      console.log(`reblogButton ${eventType}`, event);
    });
  });

marcustyphoon avatar Nov 29 '25 09:11 marcustyphoon