mirror of
https://github.com/HeyPuter/puter.git
synced 2026-08-26 07:57:10 +00:00
fix(dashboard): make app drag-to-reorder work on touch (iOS)
On iOS/WebKit the pager's `touch-action: pan-x` made horizontal touchmove non-cancelable, so the moment a long-press drag moved the finger the browser started a native page-pan and fired pointercancel, aborting the reorder before it visibly began. Preventing pointermove doesn't stop native scrolling on iOS, and the reordering `touch-action: none` rule was applied only after the drag began — too late, since touch-action is latched at gesture start. Drop the explicit pan-x (back to auto) so horizontal touchmove is cancelable, and install a non-passive touchmove listener that preventDefaults only once reordering is armed (post long-press). Before arming it's a no-op, so a quick swipe still flips pages natively.
This commit is contained in:
@@ -603,6 +603,18 @@ const TabApps = {
|
||||
document.addEventListener('keydown', d.onKey);
|
||||
window.addEventListener('blur', d.onBlur);
|
||||
|
||||
// iOS/WebKit latches touch-action at gesture start and treats an
|
||||
// in-progress pan as non-cancelable, so preventing pointermove can't
|
||||
// stop the pager from scrolling out from under a drag (it just fires
|
||||
// pointercancel and kills the reorder). A non-passive touchmove that
|
||||
// preventDefaults *once reordering is armed* is what actually holds the
|
||||
// scroller still. Before arming (readyToDrag false) it's a no-op, so a
|
||||
// quick pre-long-press swipe still flips pages natively.
|
||||
if ( pointerType === 'touch' ) {
|
||||
d.onTouchMove = ev => { if ( d.readyToDrag ) ev.preventDefault(); };
|
||||
document.addEventListener('touchmove', d.onTouchMove, { passive: false });
|
||||
}
|
||||
|
||||
// Touch: a long-press *arms* reordering (it doesn't grab the tile yet).
|
||||
// Moving after that begins the drag; holding still instead lets the
|
||||
// native long-press context menu (Uninstall) fire. A finger that moves
|
||||
@@ -831,6 +843,7 @@ const TabApps = {
|
||||
document.removeEventListener('pointercancel', d.onCancel);
|
||||
document.removeEventListener('keydown', d.onKey);
|
||||
window.removeEventListener('blur', d.onBlur);
|
||||
if ( d.onTouchMove ) document.removeEventListener('touchmove', d.onTouchMove, { passive: false });
|
||||
clearTimeout(d.longPressTimer);
|
||||
clearTimeout(d.edgeTimer);
|
||||
clearTimeout(d.flipClearTimer);
|
||||
|
||||
@@ -776,7 +776,12 @@ input.myapps-search::-webkit-search-decoration {
|
||||
padding-top: 8px;
|
||||
scroll-snap-type: x mandatory;
|
||||
overscroll-behavior-x: contain;
|
||||
touch-action: pan-x;
|
||||
/* Deliberately not pan-x: an explicit pan value makes horizontal touchmove
|
||||
non-cancelable on iOS/WebKit, so the pager pans out from under a
|
||||
long-press drag and cancels it. With the default (auto) the non-passive
|
||||
touchmove listener installed during a reorder can preventDefault the
|
||||
native pan; a quick pre-long-press swipe still flips pages natively. */
|
||||
touch-action: auto;
|
||||
scrollbar-width: none;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user