From f47322cbeeef8f58809d7ef8a67cef0d18d7205e Mon Sep 17 00:00:00 2001 From: firestarsdog <229254897+firestarsdog@users.noreply.github.com> Date: Wed, 9 Sep 2026 02:09:10 -0400 Subject: [PATCH] are your fingies fixed --- .../system/the_galaxy/assets/mobile/js/app.js | 15 ++++++--- .../the_galaxy/tests/test_ui_vue_frontend.py | 32 ++++++++++++++++++- 2 files changed, 41 insertions(+), 6 deletions(-) diff --git a/starpilot/system/the_galaxy/assets/mobile/js/app.js b/starpilot/system/the_galaxy/assets/mobile/js/app.js index 860be5c9e..b88b6f693 100644 --- a/starpilot/system/the_galaxy/assets/mobile/js/app.js +++ b/starpilot/system/the_galaxy/assets/mobile/js/app.js @@ -113,19 +113,25 @@ initRouter() const scheduleRestore = () => { clearTimeout(timer) - timer = setTimeout(() => setScrolling(false), 120) + const scrollY = window.scrollY + // Finger release and completion notifications can precede the last movement. + // Keep glass disabled until the scroll position has also settled. + timer = setTimeout(() => { + if (window.scrollY !== scrollY) scheduleRestore() + else setScrolling(false) + }, 120) } document.addEventListener("scroll", () => { scrollEnded = false setScrolling(true) + clearTimeout(timer) if (!nativeScrollEnd) scheduleRestore() }, { passive: true }) document.addEventListener("scrollend", () => { scrollEnded = true - clearTimeout(timer) - setScrolling(false) + scheduleRestore() }, { passive: true }) window.addEventListener("touchstart", (e) => { @@ -135,8 +141,7 @@ initRouter() const releaseTouches = (e) => { for (const touch of e.changedTouches) touches.delete(touch.identifier) - if (scrollEnded) setScrolling(false) - else if (!nativeScrollEnd && !touches.size) scheduleRestore() + if (!touches.size && (scrollEnded || !nativeScrollEnd)) scheduleRestore() } window.addEventListener("touchend", releaseTouches, { passive: true }) window.addEventListener("touchcancel", releaseTouches, { passive: true }) diff --git a/starpilot/system/the_galaxy/tests/test_ui_vue_frontend.py b/starpilot/system/the_galaxy/tests/test_ui_vue_frontend.py index 6f7952719..37dc4720e 100644 --- a/starpilot/system/the_galaxy/tests/test_ui_vue_frontend.py +++ b/starpilot/system/the_galaxy/tests/test_ui_vue_frontend.py @@ -553,6 +553,10 @@ const handlers = { document: {}, window: {} }; const classes = new Set(); const timers = new Map(); let nextTimer = 0; +const window = { + scrollY: 0, + addEventListener: (name, fn) => { handlers.window[name] = fn; }, +}; class Element { constructor(modal = false) { this.modal = modal; } closest() { return this.modal ? this : null; } @@ -566,7 +570,7 @@ const document = { if (native) document.onscrollend = null; vm.runInNewContext(source.slice(source.indexOf('// Disable card blur'), source.indexOf('// Layer 2')), { document, Element, - window: { addEventListener: (name, fn) => { handlers.window[name] = fn; } }, + window, setTimeout: fn => { timers.set(++nextTimer, fn); return nextTimer; }, clearTimeout: id => timers.delete(id), }); @@ -575,6 +579,20 @@ const fire = (scope, name, ids = [], modal = false) => handlers[scope][name]?.({ }); const tick = () => { const pending = [...timers.values()]; timers.clear(); pending.forEach(fn => fn()); }; const active = () => classes.has('is-scrolling'); +// Inertial movement can continue between delivered scroll events after release. +fire('window', 'touchstart', [10]); +fire('document', 'scroll'); +fire('window', 'touchend', [10]); +if (native) fire('document', 'scrollend'); +window.scrollY = 100; +tick(); +assert.equal(active(), true, 'finger release must not end momentum scrolling'); +window.scrollY = 160; +tick(); +assert.equal(active(), true, 'continued movement must keep blur disabled'); +tick(); +assert.equal(active(), false, 'restore after completion and a stable position'); +fire('document', 'scrollend'); fire('window', 'wheel'); assert.equal(active(), false, 'wheel without document movement'); fire('window', 'touchstart', [1, 2]); @@ -588,12 +606,23 @@ fire('window', 'touchcancel', [2]); tick(); assert.equal(active(), native, 'native completion must be authoritative'); fire('document', 'scrollend'); +tick(); +assert.equal(active(), false); +// More scroll events after a completion signal invalidate its pending restore. +fire('document', 'scroll'); +fire('document', 'scrollend'); +fire('document', 'scroll'); +tick(); +assert.equal(active(), native, 'new scrolling cancels the previous native completion'); +fire('document', 'scrollend'); +tick(); assert.equal(active(), false); fire('window', 'touchstart', [4]); fire('document', 'scroll'); fire('document', 'scrollend'); assert.equal(active(), true, 'hold survives completion'); fire('window', 'touchend', [4]); +tick(); assert.equal(active(), false, 'release after completion cannot leave state stuck'); fire('document', 'scroll'); fire('window', 'hashchange'); @@ -603,6 +632,7 @@ fire('document', 'scroll'); tick(); assert.equal(active(), native, 'fallback only on unsupported browsers'); fire('document', 'scrollend'); +tick(); assert.equal(active(), false); """ result = subprocess.run(