rewrite log viewer panes: smart auto-scroll with follow button

- Track scroll position per log pane (container logs, build logs, deployment cards)
- Auto-scroll to bottom only when user is already at bottom (tail-follow)
- When user scrolls up to review earlier output, pause auto-scroll
- Show a '↓ Follow' button when auto-scroll is paused; clicking resumes
- Only scroll on actual content changes (skip no-op updates)
- Use overflow-y: auto for proper scrollable containers
- Add break-words to prevent horizontal overflow on long lines

Closes #17
This commit is contained in:
clawbot
2026-02-15 20:48:43 -08:00
parent d4eae284b5
commit be6080280e
3 changed files with 88 additions and 20 deletions

View File

@@ -85,8 +85,17 @@
</a>
{{end}}
</div>
<div x-ref="logsWrapper" class="bg-gray-900 rounded-lg p-4 overflow-auto" style="max-height: 400px;">
<pre class="text-gray-100 text-xs font-mono whitespace-pre-wrap" x-text="logs"></pre>
<div class="relative">
<div x-ref="logsWrapper" class="bg-gray-900 rounded-lg p-4 overflow-y-auto" style="max-height: 400px;">
<pre class="text-gray-100 text-xs font-mono whitespace-pre-wrap break-words m-0" x-text="logs"></pre>
</div>
<button
x-show="!_autoScroll"
x-transition
@click="_autoScroll = true; Alpine.store('utils').scrollToBottom($refs.logsWrapper)"
class="absolute bottom-2 right-4 bg-primary-600 hover:bg-primary-700 text-white text-xs px-3 py-1 rounded-full shadow-lg opacity-90 hover:opacity-100 transition"
title="Scroll to bottom"
>↓ Follow</button>
</div>
{{if .Logs.Valid}}<script type="text/plain" class="initial-logs">{{.Logs.String}}</script>{{end}}
</div>