mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-03-07 14:09:59 +00:00
[Manager] Auto scroll logs terminal to bottom (#3141)
Co-authored-by: github-actions <github-actions@github.com>
This commit is contained in:
@@ -20,7 +20,7 @@
|
||||
>
|
||||
<div v-for="(panel, index) in taskPanels" :key="index">
|
||||
<Panel
|
||||
:expanded="expandedPanels[index] || false"
|
||||
:expanded="collapsedPanels[index] || false"
|
||||
toggleable
|
||||
class="shadow-elevation-1 rounded-lg mt-2 dark-theme:bg-black dark-theme:border-black"
|
||||
>
|
||||
@@ -28,11 +28,11 @@
|
||||
<div class="flex items-center justify-between w-full py-2">
|
||||
<div class="flex flex-col text-sm font-medium leading-normal">
|
||||
<span>{{ panel.taskName }}</span>
|
||||
<span v-show="expandedPanels[index]" class="text-muted">
|
||||
<span class="text-muted">
|
||||
{{
|
||||
index === taskPanels.length - 1
|
||||
? 'In progress'
|
||||
: 'Completed ✓'
|
||||
isInProgress(index)
|
||||
? $t('g.inProgress')
|
||||
: $t('g.completed') + ' ✓'
|
||||
}}
|
||||
</span>
|
||||
</div>
|
||||
@@ -41,9 +41,9 @@
|
||||
<template #toggleicon>
|
||||
<Button
|
||||
:icon="
|
||||
expandedPanels[index]
|
||||
? 'pi pi-chevron-down'
|
||||
: 'pi pi-chevron-right'
|
||||
collapsedPanels[index]
|
||||
? 'pi pi-chevron-right'
|
||||
: 'pi pi-chevron-down'
|
||||
"
|
||||
text
|
||||
class="text-neutral-300"
|
||||
@@ -51,11 +51,17 @@
|
||||
/>
|
||||
</template>
|
||||
<div
|
||||
:ref="
|
||||
index === taskPanels.length - 1
|
||||
? (el) => (lastPanelRef = el as HTMLElement)
|
||||
: undefined
|
||||
"
|
||||
class="overflow-y-auto h-64 rounded-lg bg-black"
|
||||
:class="{
|
||||
'h-64': index !== taskPanels.length - 1,
|
||||
'flex-grow': index === taskPanels.length - 1
|
||||
}"
|
||||
@scroll="handleScroll"
|
||||
>
|
||||
<div class="h-full">
|
||||
<div
|
||||
@@ -86,26 +92,68 @@ import {
|
||||
|
||||
const { taskLogs } = useComfyManagerStore()
|
||||
const progressDialogContent = useManagerProgressDialogStore()
|
||||
const managerStore = useComfyManagerStore()
|
||||
|
||||
const isInProgress = (index: number) =>
|
||||
index === taskPanels.value.length - 1 && managerStore.uncompletedCount > 0
|
||||
|
||||
const taskPanels = computed(() => taskLogs)
|
||||
const isExpanded = computed(() => progressDialogContent.isExpanded)
|
||||
const isCollapsed = computed(() => !isExpanded.value)
|
||||
|
||||
const expandedPanels = ref<Record<number, boolean>>({})
|
||||
const collapsedPanels = ref<Record<number, boolean>>({})
|
||||
const togglePanel = (index: number) => {
|
||||
expandedPanels.value[index] = !expandedPanels.value[index]
|
||||
collapsedPanels.value[index] = !collapsedPanels.value[index]
|
||||
}
|
||||
|
||||
const sectionsContainerRef = ref<HTMLElement | null>(null)
|
||||
const { y: scrollY } = useScroll(sectionsContainerRef)
|
||||
const { y: scrollY } = useScroll(sectionsContainerRef, {
|
||||
eventListenerOptions: {
|
||||
passive: true
|
||||
}
|
||||
})
|
||||
|
||||
const scrollToBottom = () => {
|
||||
const lastPanelRef = ref<HTMLElement | null>(null)
|
||||
const isUserScrolling = ref(false)
|
||||
const lastPanelLogs = computed(() => taskPanels.value?.at(-1)?.logs)
|
||||
|
||||
const isAtBottom = (el: HTMLElement | null) => {
|
||||
if (!el) return false
|
||||
const threshold = 20
|
||||
return Math.abs(el.scrollHeight - el.scrollTop - el.clientHeight) < threshold
|
||||
}
|
||||
|
||||
const scrollLastPanelToBottom = () => {
|
||||
if (!lastPanelRef.value || isUserScrolling.value) return
|
||||
lastPanelRef.value.scrollTop = lastPanelRef.value.scrollHeight
|
||||
}
|
||||
const scrollContentToBottom = () => {
|
||||
scrollY.value = sectionsContainerRef.value?.scrollHeight ?? 0
|
||||
}
|
||||
|
||||
whenever(() => isExpanded.value, scrollToBottom)
|
||||
const resetUserScrolling = () => {
|
||||
isUserScrolling.value = false
|
||||
}
|
||||
const handleScroll = (e: Event) => {
|
||||
const target = e.target as HTMLElement
|
||||
if (target !== lastPanelRef.value) return
|
||||
|
||||
isUserScrolling.value = !isAtBottom(target)
|
||||
}
|
||||
|
||||
const onLogsAdded = () => {
|
||||
// If user is scrolling manually, don't automatically scroll to bottom
|
||||
if (isUserScrolling.value) return
|
||||
|
||||
scrollLastPanelToBottom()
|
||||
}
|
||||
|
||||
whenever(lastPanelLogs, onLogsAdded, { flush: 'post', deep: true })
|
||||
whenever(() => isExpanded.value, scrollContentToBottom)
|
||||
whenever(isCollapsed, resetUserScrolling)
|
||||
|
||||
onMounted(() => {
|
||||
expandedPanels.value = {}
|
||||
scrollToBottom()
|
||||
scrollContentToBottom()
|
||||
})
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
|
||||
Reference in New Issue
Block a user