fix log scroll

This commit is contained in:
Julian Freeman
2025-12-08 09:11:53 -04:00
parent 7c1c9c6a2f
commit f23b37a581
2 changed files with 31 additions and 11 deletions

View File

@@ -50,5 +50,9 @@ export const useLogsStore = defineStore('logs', () => {
logs.value = []
}
return { logs, addLog, initListener, clearLogs }
// UI State Persistence
const autoScroll = ref(true)
const scrollTop = ref(0)
return { logs, addLog, initListener, clearLogs, autoScroll, scrollTop }
})

View File

@@ -1,12 +1,11 @@
// filepath: src/views/Logs.vue
<script setup lang="ts">
import { ref, computed, nextTick, watch } from 'vue'
import { ref, computed, nextTick, watch, onMounted } from 'vue'
import { useLogsStore } from '../stores/logs'
import { Trash2, Search } from 'lucide-vue-next'
const logsStore = useLogsStore()
const logsContainer = ref<HTMLElement | null>(null)
const autoScroll = ref(true)
const filterLevel = ref<'all' | 'info' | 'error'>('all')
const searchQuery = ref('')
@@ -18,9 +17,20 @@ const filteredLogs = computed(() => {
})
})
// Auto-scroll
// Restore scroll position on mount
onMounted(() => {
if (logsContainer.value) {
logsContainer.value.scrollTop = logsStore.scrollTop
// If it was auto-scrolling, ensure it's at bottom in case new logs arrived while away
if (logsStore.autoScroll) {
logsContainer.value.scrollTop = logsContainer.value.scrollHeight
}
}
})
// Auto-scroll watcher
watch(() => logsStore.logs.length, () => {
if (autoScroll.value) {
if (logsStore.autoScroll) {
nextTick(() => {
if (logsContainer.value) {
logsContainer.value.scrollTop = logsContainer.value.scrollHeight
@@ -29,6 +39,15 @@ watch(() => logsStore.logs.length, () => {
}
})
function handleScroll(e: Event) {
const target = e.target as HTMLElement;
logsStore.scrollTop = target.scrollTop;
// Check if user is near bottom (allow 20px threshold)
const isAtBottom = target.scrollTop + target.clientHeight >= target.scrollHeight - 20;
logsStore.autoScroll = isAtBottom;
}
function formatTime(ts: number) {
const d = new Date(ts)
const year = d.getFullYear()
@@ -96,10 +115,7 @@ function formatTime(ts: number) {
<div
ref="logsContainer"
class="absolute inset-0 overflow-auto p-4 space-y-1"
@scroll="(e) => {
const target = e.target as HTMLElement;
autoScroll = target.scrollTop + target.clientHeight >= target.scrollHeight - 10;
}"
@scroll="handleScroll"
>
<div v-if="filteredLogs.length === 0" class="h-full flex items-center justify-center text-gray-400 dark:text-gray-600">
No logs to display
@@ -114,9 +130,9 @@ function formatTime(ts: number) {
</div>
<!-- Auto-scroll indicator -->
<div v-if="!autoScroll" class="absolute bottom-4 right-4">
<div v-if="!logsStore.autoScroll" class="absolute bottom-4 right-4">
<button
@click="() => { if(logsContainer) logsContainer.scrollTop = logsContainer.scrollHeight }"
@click="() => { if(logsContainer) { logsContainer.scrollTop = logsContainer.scrollHeight; logsStore.autoScroll = true; } }"
class="bg-blue-600 hover:bg-blue-700 text-white text-xs px-3 py-1.5 rounded-full shadow-lg transition-colors"
>
Resume Auto-scroll