summaryrefslogtreecommitdiff
path: root/Omni
diff options
context:
space:
mode:
authorBen Sima <ben@bensima.com>2025-12-01 15:41:19 -0500
committerBen Sima <ben@bensima.com>2025-12-01 15:41:19 -0500
commit2151b67836d209645b85bb64d56a96bfbf2859cd (patch)
tree25f8b87331a689486405de977c8624cb71df9c16 /Omni
parent5b3256b500ebb9a2f953c8b54917626b11988448 (diff)
Add autoscroll toggle button for timeline
Adds a toggle button next to the LIVE indicator that controls whether the timeline auto-scrolls to new events. Default is ON. - renderAutoscrollToggle button with ⬇ icon - toggleAutoscroll() JS function tracks state - htmx:afterSettle checks autoscrollEnabled before scrolling - Blue styling to differentiate from green LIVE button Task-Id: t-222
Diffstat (limited to 'Omni')
-rw-r--r--Omni/Jr/Web.hs35
-rw-r--r--Omni/Jr/Web/Style.hs17
2 files changed, 50 insertions, 2 deletions
diff --git a/Omni/Jr/Web.hs b/Omni/Jr/Web.hs
index a493395..6a2d826 100644
--- a/Omni/Jr/Web.hs
+++ b/Omni/Jr/Web.hs
@@ -2273,11 +2273,23 @@ renderLiveToggle =
]
" LIVE"
--- | JavaScript for toggling live updates
+-- | Render the autoscroll toggle button
+renderAutoscrollToggle :: (Monad m) => Lucid.HtmlT m ()
+renderAutoscrollToggle =
+ Lucid.button_
+ [ Lucid.class_ "timeline-autoscroll-toggle",
+ Lucid.id_ "autoscroll-toggle",
+ Lucid.makeAttribute "onclick" "toggleAutoscroll()",
+ Lucid.title_ "Toggle automatic scrolling to newest events"
+ ]
+ " ⬇ Auto-scroll"
+
+-- | JavaScript for toggling live updates and autoscroll
liveToggleJs :: Text
liveToggleJs =
Text.unlines
[ "var liveUpdatesEnabled = true;",
+ "var autoscrollEnabled = true;",
"",
"function toggleLiveUpdates() {",
" liveUpdatesEnabled = !liveUpdatesEnabled;",
@@ -2287,11 +2299,28 @@ liveToggleJs =
" }",
"}",
"",
+ "function toggleAutoscroll() {",
+ " autoscrollEnabled = !autoscrollEnabled;",
+ " var btn = document.getElementById('autoscroll-toggle');",
+ " if (btn) {",
+ " btn.classList.toggle('timeline-autoscroll-disabled', !autoscrollEnabled);",
+ " }",
+ "}",
+ "",
"document.body.addEventListener('htmx:beforeRequest', function(evt) {",
" var timeline = document.getElementById('unified-timeline');",
" if (timeline && timeline.contains(evt.target) && !liveUpdatesEnabled) {",
" evt.preventDefault();",
" }",
+ "});",
+ "",
+ "document.body.addEventListener('htmx:afterSettle', function(evt) {",
+ " if (autoscrollEnabled) {",
+ " var log = document.querySelector('.timeline-events');",
+ " if (log) {",
+ " log.scrollTop = log.scrollHeight;",
+ " }",
+ " }",
"});"
]
@@ -2352,7 +2381,9 @@ renderUnifiedTimeline tid legacyComments events status now = do
when (totalCents > 0) <| Lucid.toHtml (formatCostHeader totalCents)
when (totalCents > 0 && totalTokens > 0) <| metaSep
when (totalTokens > 0) <| Lucid.toHtml (formatTokensHeader totalTokens <> " tokens")
- when isInProgress <| renderLiveToggle
+ when isInProgress <| do
+ renderLiveToggle
+ renderAutoscrollToggle
if null nonCostEvents && null legacyComments
then Lucid.p_ [Lucid.class_ "empty-msg"] "No activity yet."
diff --git a/Omni/Jr/Web/Style.hs b/Omni/Jr/Web/Style.hs
index cf32570..bbf828b 100644
--- a/Omni/Jr/Web/Style.hs
+++ b/Omni/Jr/Web/Style.hs
@@ -1597,6 +1597,23 @@ unifiedTimelineStyles = do
backgroundColor "#f3f4f6"
border (px 1) solid "#d1d5db"
Stylesheet.key "animation" ("none" :: Text)
+ ".timeline-autoscroll-toggle" ? do
+ fontSize (px 10)
+ fontWeight bold
+ color "#3b82f6"
+ backgroundColor "#dbeafe"
+ padding (px 2) (px 6) (px 2) (px 6)
+ borderRadius (px 10) (px 10) (px 10) (px 10)
+ marginLeft (px 4)
+ border (px 1) solid "#93c5fd"
+ cursor pointer
+ Stylesheet.key "transition" ("all 0.2s ease" :: Text)
+ ".timeline-autoscroll-toggle:hover" ? do
+ Stylesheet.key "box-shadow" ("0 0 6px rgba(59,130,246,0.3)" :: Text)
+ ".timeline-autoscroll-toggle.timeline-autoscroll-disabled" ? do
+ color "#6b7280"
+ backgroundColor "#f3f4f6"
+ border (px 1) solid "#d1d5db"
".timeline-live" ? do
fontSize (px 10)
fontWeight bold