mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-10-23 10:29:33 +02:00
fix(mobile): hand a swipe-locked drag back to the scroll past the swipe's drift limit
A scroll whose first move past the tap slop leaned sideways (a thumb arc) locked as 'swipe' for the whole contact, and SwipeHandler drops a swipe at 50 px of vertical drift, so the gesture did nothing. Past that limit the drag is now a 'y' scroll. Also brings the mobile-handlers fileoverview to the current 500 ms / 50 px limits and notes in the Mobile Guide that a selection pauses the swipe and a wide terminal pans instead.
This commit is contained in:
1 parent
63cada938d
commit
e8fc08beb3
4 files changed
+30
-5
No files matched your search
@@ -37,7 +37,8 @@ a bottom sheet rather than a dropdown. On a folding phone (iPhone Duo) dialogs s
|
||||
the hinge, and opening or closing the device is treated as the device changing shape, never
|
||||
as the keyboard appearing.
|
||||
|
||||
**Swipe left and right** on the terminal to switch sessions.
|
||||
**Swipe left and right** on the terminal to switch sessions. A visible text selection pauses
|
||||
the swipe, and a terminal wider than the screen pans sideways instead.
|
||||
|
||||
## The home screen
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
* toolbar/accessory bar repositioning, terminal resize on keyboard open/close,
|
||||
* and input scroll-into-view. Uses 100px threshold for iOS address bar drift.
|
||||
* - SwipeHandler — Horizontal swipe detection on the terminal area for session switching.
|
||||
* 80px minimum distance, 300ms maximum time, 100px max vertical drift.
|
||||
* 80px minimum distance, 500ms maximum time, 50px max vertical drift.
|
||||
*
|
||||
* All three have init()/cleanup() lifecycle methods. They are re-initialized after SSE
|
||||
* reconnect (in handleInit) to prevent stale closures.
|
||||
|
||||
@@ -1200,7 +1200,8 @@ Object.assign(CodemanApp.prototype, {
|
||||
// slop, so a diagonal drag cannot pan and scroll at the same time. 'swipe'
|
||||
// is a sideways drag on a terminal that cannot pan: it is the session
|
||||
// swipe's (SwipeHandler, mobile-handlers.js), so it neither scrolls nor
|
||||
// ends as a tap on the session being left. Published per gesture as
|
||||
// ends as a tap on the session being left, until it drifts past the
|
||||
// swipe's vertical limit and becomes a 'y' scroll. Published per gesture as
|
||||
// `this._terminalGestureAxis`, which SwipeHandler reads to stand aside
|
||||
// for a scroll or a pan.
|
||||
let panAxis = null;
|
||||
@@ -1335,7 +1336,18 @@ Object.assign(CodemanApp.prototype, {
|
||||
// fling, so a jittery tap would both position the cursor AND scroll.
|
||||
if (!didScroll) return;
|
||||
ev.preventDefault();
|
||||
if (panAxis === 'swipe') return;
|
||||
if (panAxis === 'swipe') {
|
||||
// Past the swipe's own vertical drift limit the session swipe has
|
||||
// given up, so the drag is a scroll after all (a thumb arc whose
|
||||
// first move leaned sideways): hand it to 'y'.
|
||||
const drift = typeof SwipeHandler !== 'undefined' ? SwipeHandler.maxVerticalDrift : 50;
|
||||
if (Math.abs(touchY - touchStartY) <= drift) return;
|
||||
panAxis = 'y';
|
||||
this._terminalGestureAxis = 'y';
|
||||
touchLastX = touchX;
|
||||
touchLastY = touchY;
|
||||
return;
|
||||
}
|
||||
if (panAxis === 'x') {
|
||||
// Pan the container, and touch nothing the vertical path owns —
|
||||
// no pixelAccum, no velocity, so touchend cannot turn a sideways
|
||||
|
||||
@@ -147,6 +147,18 @@ describe('terminal touch handler hands sideways drags to the swipe', () => {
|
||||
expect(TERMINAL_SOURCE).toContain("panAxis = travelX > travelY ? (canPanHorizontally() ? 'x' : 'swipe') : 'y';");
|
||||
expect(TERMINAL_SOURCE).toContain('this._terminalGestureAxis = panAxis;');
|
||||
// A 'swipe' is neither a scroll nor (didScroll is set) a tap.
|
||||
expect(TERMINAL_SOURCE).toContain("if (panAxis === 'swipe') return;");
|
||||
expect(TERMINAL_SOURCE).toContain("if (panAxis === 'swipe') {");
|
||||
});
|
||||
|
||||
it("hands a 'swipe' drag back to the scroll once it passes the swipe's own drift limit", () => {
|
||||
// A thumb arc whose first move leans sideways (+9 px across, +5 px down) locks
|
||||
// as 'swipe'; SwipeHandler drops it past maxVerticalDrift, so without the
|
||||
// handback the 300 px of downward travel that follows would do nothing.
|
||||
const start = TERMINAL_SOURCE.indexOf("if (panAxis === 'swipe') {");
|
||||
const block = TERMINAL_SOURCE.slice(start, TERMINAL_SOURCE.indexOf("if (panAxis === 'x') {", start));
|
||||
expect(block).toContain('SwipeHandler.maxVerticalDrift');
|
||||
expect(block).toContain('if (Math.abs(touchY - touchStartY) <= drift) return;');
|
||||
expect(block).toContain("panAxis = 'y';");
|
||||
expect(block).toContain("this._terminalGestureAxis = 'y';");
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user