fix(gui): hold page edge-flips while a folder merge is being offered

A tile in the pager's last column sits inside the 60px edge-flip zone, so
resting a dragged icon on it — the folder-making gesture — armed the edge
dwell alongside the merge dwell, and the page flipped out from under the
very folder the user was watching form (the merge target scrolls away
mid-offer, and the drop then resolves against its stale resting rect).
Worst on phones, where 72px tiles overlap the zone across the whole last
column.

A live merge offer now holds the edge flip: entering the zone arms no
dwell while an offer stands, and an offer that arrives during a running
dwell is re-checked at the flip (a resting pointer fires no event that
could clear the timer). Carrying the icon off the tile withdraws the offer
and the hold with it, so deliberate flips — resting in the bare edge
gutter — behave as before.
This commit is contained in:
jelveh
2026-08-08 00:02:27 -07:00
parent 052e188545
commit 74a819c92f
+14 -2
View File
@@ -1791,8 +1791,16 @@ const TabApps = {
const r = scroller.getBoundingClientRect();
let dir = 0;
if ( px >= r.right - DRAG_EDGE_ZONE ) dir = 1;
else if ( px <= r.left + DRAG_EDGE_ZONE ) dir = -1;
// A merge offer in progress means the icon is parked on a tile, not
// asking for a page — and a last-column tile sits inside the edge
// zone, so without this hold the page would flip out from under the
// very folder the user is watching form. Carrying the icon off the
// tile withdraws the offer (see _updatePlaceholder), and with it
// this hold.
if ( ! d.mergeEl ) {
if ( px >= r.right - DRAG_EDGE_ZONE ) dir = 1;
else if ( px <= r.left + DRAG_EDGE_ZONE ) dir = -1;
}
const atEnd = (dir === 1 && this._page >= this._pageCount - 1);
const atStart = (dir === -1 && this._page <= 0);
@@ -1810,6 +1818,10 @@ const TabApps = {
d.edgeTimer = null;
d.edgeDir = 0;
if ( this._drag !== d ) return;
// The offer can arrive while this dwell runs (resting on an
// edge-zone tile starts both countdowns): no pointer event fires
// during a rest to clear the timer, so re-check at the flip.
if ( d.mergeEl ) return;
d.flipping = true;
this.goToPage(d.$el_window, this._page + dir, true);
clearTimeout(d.flipClearTimer);