From a85af250a7609ac3e4d77fe9e2b5f189006a0c1c Mon Sep 17 00:00:00 2001 From: BatLeDev Date: Thu, 4 Jun 2026 15:04:21 +0200 Subject: [PATCH 1/2] feat(ui): use shared useAutoScrollBottom from lib-vue on run page --- package-lock.json | 12 ++++-- ui/package.json | 2 +- ui/src/composables/use-follow-bottom.ts | 39 ------------------- .../pages/processings/[id]/runs/[runId].vue | 5 ++- 4 files changed, 12 insertions(+), 46 deletions(-) delete mode 100644 ui/src/composables/use-follow-bottom.ts diff --git a/package-lock.json b/package-lock.json index 2d23eb65..719291e1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -665,9 +665,9 @@ } }, "node_modules/@data-fair/lib-vue": { - "version": "1.27.1", - "resolved": "https://registry.npmjs.org/@data-fair/lib-vue/-/lib-vue-1.27.1.tgz", - "integrity": "sha512-vpUu7GXvdy3fNYiX6Y/heka+FBLrltcy/9ksCfVn0yTsOiXrS3tFwaD3RUMQUF+Q72KsGNI47A6TN9fgpOb/5w==", + "version": "1.28.0", + "resolved": "https://registry.npmjs.org/@data-fair/lib-vue/-/lib-vue-1.28.0.tgz", + "integrity": "sha512-1cd1ZWHHQdrgLaoBuu3fsBrhSE5AbM1ZKMz5WklGzFWmvQMfsEnXm/iBOrrWgfZNaJO75he+txs95IaY6X552A==", "license": "MIT", "dependencies": { "@data-fair/lib-common-types": "^1.7.1", @@ -677,6 +677,7 @@ "universal-cookie": "^7.2.0" }, "peerDependencies": { + "@vueuse/core": ">=10", "dayjs": "1", "ofetch": "1", "reconnecting-websocket": "4", @@ -684,6 +685,9 @@ "vue-router": "4 || 5" }, "peerDependenciesMeta": { + "@vueuse/core": { + "optional": true + }, "dayjs": { "optional": true }, @@ -12193,7 +12197,7 @@ "dependencies": { "@data-fair/frame": "^0.18.4", "@data-fair/lib-utils": "^1.8.0", - "@data-fair/lib-vue": "^1.27.1", + "@data-fair/lib-vue": "^1.28.0", "@data-fair/lib-vuetify": "^2.0.5", "@data-fair/processings-shared": "*", "@intlify/unplugin-vue-i18n": "^11.0.7", diff --git a/ui/package.json b/ui/package.json index a974e248..536f325a 100644 --- a/ui/package.json +++ b/ui/package.json @@ -18,7 +18,7 @@ "dependencies": { "@data-fair/frame": "^0.18.4", "@data-fair/lib-utils": "^1.8.0", - "@data-fair/lib-vue": "^1.27.1", + "@data-fair/lib-vue": "^1.28.0", "@data-fair/lib-vuetify": "^2.0.5", "@data-fair/processings-shared": "*", "@intlify/unplugin-vue-i18n": "^11.0.7", diff --git a/ui/src/composables/use-follow-bottom.ts b/ui/src/composables/use-follow-bottom.ts deleted file mode 100644 index d44c6313..00000000 --- a/ui/src/composables/use-follow-bottom.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { useScroll, useEventListener } from '@vueuse/core' - -/** - * Stick-to-bottom autoscroll for a live run log: follows new entries while the - * user is at the bottom, any upward scroll or wheel-up stops it, scrolling back - * to the bottom resumes. - * - * Targets the current document — what actually scrolls both standalone and - * inside data-fair's fixed-height d-frame iframe (never window.top). VueUse's - * `arrivedState.bottom` carries a built-in 1px tolerance, and appending a log - * fires no scroll event, so following only ever turns off on a real upward - * scroll — no manual threshold needed. - * - * @param logCount reactive getter for the log length (the growth signal) - * @param isActive getter telling whether the run is still streaming - */ -export const useFollowBottom = (logCount: () => number, isActive: () => boolean) => { - // Start following so a freshly opened, still-running run pins to its tail even - // though the page loads scrolled to the top. - const following = ref(true) - - const { arrivedState, directions, y } = useScroll(window, { - onScroll: () => { - if (directions.top) following.value = false // scrolled up → stop - else if (arrivedState.bottom) following.value = true // back at bottom → resume - } - }) - - // A wheel-up reaches us even when the page can't scroll (short page, or - // data-fair's auto-height embed where the parent scrolls) — the only - // "stop following" signal available there. - useEventListener(window, 'wheel', (e: WheelEvent) => { if (e.deltaY < 0) following.value = false }, { passive: true }) - - const pinToBottom = () => { y.value = (document.scrollingElement ?? document.documentElement).scrollHeight } - - watch(logCount, () => { if (isActive() && following.value) pinToBottom() }, { flush: 'post' }) - - return { following } -} diff --git a/ui/src/pages/processings/[id]/runs/[runId].vue b/ui/src/pages/processings/[id]/runs/[runId].vue index dc451fb0..ef787de8 100644 --- a/ui/src/pages/processings/[id]/runs/[runId].vue +++ b/ui/src/pages/processings/[id]/runs/[runId].vue @@ -61,7 +61,7 @@