From 706753207500f43e0e3277ba735e7e853067538a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 16 Feb 2026 19:53:46 +0000 Subject: [PATCH 1/6] Initial plan From d02b25949e7dde04824ca9ff1c0e9a04f7f9f243 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 16 Feb 2026 19:56:21 +0000 Subject: [PATCH 2/6] Implement Auto-Scroll menu enhancements with flyout submenus Co-authored-by: thehack904 <35552907+thehack904@users.noreply.github.com> --- static/css/base.css | 3 ++- static/js/auto-scroll.js | 4 ++- templates/_header.html | 46 ++++++++++++++++++++++++++++++++-- templates/guide.html | 53 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 102 insertions(+), 4 deletions(-) diff --git a/static/css/base.css b/static/css/base.css index c0884d9..8611f96 100644 --- a/static/css/base.css +++ b/static/css/base.css @@ -97,7 +97,8 @@ body { font-family: Arial, sans-serif; margin:0; } /* Submenu (fly-out for Themes) */ .submenu { position: relative; } -.submenu > a { display: flex; justify-content: space-between; align-items: center; } +.submenu > a { display: flex; justify-content: space-between; align-items: center; padding-right: 28px !important; position: relative; } +.submenu > a::after { content: "▸"; position: absolute; right: 10px; top: 50%; transform: translateY(-50%); } .submenu-content { display: none; position: absolute; diff --git a/static/js/auto-scroll.js b/static/js/auto-scroll.js index 2d9f9a1..21646b7 100644 --- a/static/js/auto-scroll.js +++ b/static/js/auto-scroll.js @@ -11,7 +11,7 @@ function setPref(v) { localStorage.setItem(PREF_KEY, v ? 'true' : 'false'); } const SELECTOR_PRIORITY = ['#guideOuter', '.guide-outer', '.grid-col']; - const scrollSpeed = 1.2; // px per frame (visual) + let scrollSpeed = 1.2; // px per frame (visual) const idleDelay = 15000; // ms initial inactivity/start delay (15s) const waitForContentMs = 5000; // wait up to 5s for rows to be populated before cloning const contentSampleCount = 3; // sample when checking readiness @@ -436,6 +436,8 @@ window.__autoScroll.clearEnd = function(){ endReached = false; endReachedAt = 0; }; window.__autoScroll.recompute = function(){ scroller = null; }; window.__autoScroll.cloneNow = function(){ if (!scroller) scroller = findScroller(); return cloneOnce(scroller); }; + window.__autoScroll.setSpeed = function(speed){ if (typeof speed === 'number' && speed > 0) { scrollSpeed = speed; log('setSpeed ->', scrollSpeed); } else { log('setSpeed: invalid speed', speed); } }; + window.__autoScroll.getSpeed = function(){ return scrollSpeed; }; window.__autoScroll.status = function(){ return { isScrolling, pref: prefEnabled(), loopMode, scrollerInfo: scroller ? { id: scroller.id, scrollTop: scroller.scrollTop, scrollHeight: scroller.scrollHeight, clientHeight: scroller.clientHeight, cloned: !!scroller.dataset.__autoScrollCloned, prependedHeight: scroller.dataset.__autoScrollPrependedHeight } : null, rafId: !!rafId, watchdog: !!watchdogInterval }; }; window.__autoScroll.debug = function(){ return { lastActivity, idleDelay, scrollSpeed, isScrolling, pref: prefEnabled(), loopMode, endReached, endReachedAt, autoRestart, autoRestartDelayMs, scrollerInfo: scroller ? { id: scroller.id, scrollTop: scroller.scrollTop, scrollHeight: scroller.scrollHeight, clientHeight: scroller.clientHeight, cloned: !!scroller.dataset.__autoScrollCloned, prependedHeight: scroller.dataset.__autoScrollPrependedHeight } : null, rafId, lastFrameTime, watchdogInterval }; }; diff --git a/templates/_header.html b/templates/_header.html index 9ecd347..97e2cfd 100644 --- a/templates/_header.html +++ b/templates/_header.html @@ -28,7 +28,20 @@ Logs
  • About
  • {% endif %} - Toggle Auto-Scroll + Change Password
  • Logs
  • About
  • {% endif %} -
  • Toggle Auto-Scroll
  • +
  • + + + +
  • Change Password
  • diff --git a/templates/guide.html b/templates/guide.html index 08b7aa8..3e8fa2e 100644 --- a/templates/guide.html +++ b/templates/guide.html @@ -547,6 +547,59 @@

    Program Info

    }); + + From b038fd82f2197216763c5ceb4bc784088a697de3 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 16 Feb 2026 20:00:52 +0000 Subject: [PATCH 3/6] Address code review feedback - improve retry logic and code formatting Co-authored-by: thehack904 <35552907+thehack904@users.noreply.github.com> --- static/js/auto-scroll.js | 9 ++++++++- templates/guide.html | 16 +++++++++++++++- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/static/js/auto-scroll.js b/static/js/auto-scroll.js index 21646b7..60586f2 100644 --- a/static/js/auto-scroll.js +++ b/static/js/auto-scroll.js @@ -436,7 +436,14 @@ window.__autoScroll.clearEnd = function(){ endReached = false; endReachedAt = 0; }; window.__autoScroll.recompute = function(){ scroller = null; }; window.__autoScroll.cloneNow = function(){ if (!scroller) scroller = findScroller(); return cloneOnce(scroller); }; - window.__autoScroll.setSpeed = function(speed){ if (typeof speed === 'number' && speed > 0) { scrollSpeed = speed; log('setSpeed ->', scrollSpeed); } else { log('setSpeed: invalid speed', speed); } }; + window.__autoScroll.setSpeed = function(speed) { + if (typeof speed === 'number' && speed > 0) { + scrollSpeed = speed; + log('setSpeed ->', scrollSpeed); + } else { + log('setSpeed: invalid speed', speed); + } + }; window.__autoScroll.getSpeed = function(){ return scrollSpeed; }; window.__autoScroll.status = function(){ return { isScrolling, pref: prefEnabled(), loopMode, scrollerInfo: scroller ? { id: scroller.id, scrollTop: scroller.scrollTop, scrollHeight: scroller.scrollHeight, clientHeight: scroller.clientHeight, cloned: !!scroller.dataset.__autoScrollCloned, prependedHeight: scroller.dataset.__autoScrollPrependedHeight } : null, rafId: !!rafId, watchdog: !!watchdogInterval }; }; window.__autoScroll.debug = function(){ return { lastActivity, idleDelay, scrollSpeed, isScrolling, pref: prefEnabled(), loopMode, endReached, endReachedAt, autoRestart, autoRestartDelayMs, scrollerInfo: scroller ? { id: scroller.id, scrollTop: scroller.scrollTop, scrollHeight: scroller.scrollHeight, clientHeight: scroller.clientHeight, cloned: !!scroller.dataset.__autoScrollCloned, prependedHeight: scroller.dataset.__autoScrollPrependedHeight } : null, rafId, lastFrameTime, watchdogInterval }; }; diff --git a/templates/guide.html b/templates/guide.html index 3e8fa2e..cf518df 100644 --- a/templates/guide.html +++ b/templates/guide.html @@ -596,7 +596,21 @@

    Program Info

    applySavedSpeed(); // Re-apply speed when auto-scroll is loaded (in case it loads after DOMContentLoaded) - setTimeout(applySavedSpeed, 500); + // Use a retry mechanism with maximum attempts + let retryCount = 0; + const maxRetries = 5; + const retryInterval = 100; + + function retryApplySavedSpeed() { + if (window.__autoScroll && typeof window.__autoScroll.setSpeed === 'function') { + applySavedSpeed(); + } else if (retryCount < maxRetries) { + retryCount++; + setTimeout(retryApplySavedSpeed, retryInterval); + } + } + + setTimeout(retryApplySavedSpeed, retryInterval); }); From ca138af2971df9d9b0c9d2b7768e3a9519ee2706 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 16 Feb 2026 20:02:24 +0000 Subject: [PATCH 4/6] Improve error messages for better debugging Co-authored-by: thehack904 <35552907+thehack904@users.noreply.github.com> --- templates/guide.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/guide.html b/templates/guide.html index cf518df..dd8e089 100644 --- a/templates/guide.html +++ b/templates/guide.html @@ -565,7 +565,7 @@

    Program Info

    window.__autoScroll.setSpeed(speedValue); } } catch (e) { - console.debug('applySavedSpeed error', e); + console.debug('Failed to apply saved auto-scroll speed', e); } } @@ -582,7 +582,7 @@

    Program Info

    console.debug('Scroll speed set to', speed, '(' + speedValue + ' px/frame)'); } } catch (e) { - console.error('handleSpeedClick error', e); + console.error('Failed to save scroll speed preference', e); } } } From f4f8f882d65f5eb9f19a6adf7883e5e69f07e450 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 16 Feb 2026 20:03:14 +0000 Subject: [PATCH 5/6] Add comments and improve error message clarity Co-authored-by: thehack904 <35552907+thehack904@users.noreply.github.com> --- templates/guide.html | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/templates/guide.html b/templates/guide.html index dd8e089..c54ecd9 100644 --- a/templates/guide.html +++ b/templates/guide.html @@ -565,7 +565,7 @@

    Program Info

    window.__autoScroll.setSpeed(speedValue); } } catch (e) { - console.debug('Failed to apply saved auto-scroll speed', e); + console.debug('Failed to retrieve or apply saved auto-scroll speed from localStorage', e); } } @@ -596,10 +596,10 @@

    Program Info

    applySavedSpeed(); // Re-apply speed when auto-scroll is loaded (in case it loads after DOMContentLoaded) - // Use a retry mechanism with maximum attempts + // Use a retry mechanism with maximum attempts to handle async script loading let retryCount = 0; - const maxRetries = 5; - const retryInterval = 100; + const maxRetries = 5; // Max 5 attempts to find auto-scroll API + const retryInterval = 100; // 100ms between retries (total max wait: 500ms) function retryApplySavedSpeed() { if (window.__autoScroll && typeof window.__autoScroll.setSpeed === 'function') { From 4cbb659b9ea70903ee6f9dbec80a8d39650abcd1 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 16 Feb 2026 20:12:55 +0000 Subject: [PATCH 6/6] Fix nested submenu hover behavior with direct child selector Co-authored-by: thehack904 <35552907+thehack904@users.noreply.github.com> --- static/css/base.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/static/css/base.css b/static/css/base.css index 8611f96..1428f04 100644 --- a/static/css/base.css +++ b/static/css/base.css @@ -112,7 +112,7 @@ body { font-family: Arial, sans-serif; margin:0; } } .submenu-content li a { padding: 10px 14px; display: block; color: #eee; text-decoration: none; } .submenu-content li a:hover { background-color: #0af; color: #fff; } -.submenu:hover .submenu-content { display: block; } +.submenu:hover > .submenu-content { display: block; } /* Remove default list bullets and padding for all dropdowns & submenus */ .dropdown-content,