From 9e001730c286cbce13a15897ee35dc1bc99db115 Mon Sep 17 00:00:00 2001 From: Varun Patil Date: Sun, 29 Oct 2023 11:51:20 -0700 Subject: [PATCH] refactor(viewer): sidebar debouncing Signed-off-by: Varun Patil --- src/components/viewer/Viewer.vue | 51 +++++++++++++++----------------- src/services/utils/algo.ts | 25 ++++++++++++++-- 2 files changed, 47 insertions(+), 29 deletions(-) diff --git a/src/components/viewer/Viewer.vue b/src/components/viewer/Viewer.vue index 2205b346..52aa33e6 100644 --- a/src/components/viewer/Viewer.vue +++ b/src/components/viewer/Viewer.vue @@ -1059,38 +1059,35 @@ export default defineComponent({ * to the sidebar while the user is scrolling through photos. */ async openSidebar() { - const photo = this.currentPhoto!; + const photo = this.currentPhoto; + if (!photo) return; + const abort = () => !this.isOpen || photo !== this.currentPhoto; - // Update the sidebar - const update = async () => { - const abort = () => !this.isOpen || photo !== this.currentPhoto; - if (abort()) return; - - _m.sidebar.setTab('memories-metadata'); - if (this.routeIsPublic || this.isLocal) { - _m.sidebar.open(photo); - } else { - const fileInfo = (await dav.getFiles([photo]))[0]; + // Update the sidebar, first call immediate + utils.setRenewingTimeout( + this, + '_sidebarUpdateTimer', + async () => { if (abort()) return; - // get attributes - const filename = fileInfo?.filename; - const useNative = fileInfo?.originalFilename?.startsWith('/files/'); + _m.sidebar.setTab('memories-metadata'); + if (this.routeIsPublic || this.isLocal) { + _m.sidebar.open(photo); + } else { + const fileInfo = (await dav.getFiles([photo]))[0]; + if (!fileInfo || abort()) return; - // open sidebar - _m.sidebar.open(photo, filename, useNative); - } - }; + // get attributes + const filename = fileInfo?.filename; + const useNative = fileInfo?.originalFilename?.startsWith('/files/'); - // Do not debounce the first call - let callback = update; - if (!this.sidebarUpdateTimer) { - callback(); - callback = async () => {}; - } - - // Debounce the rest - utils.setRenewingTimeout(this, 'sidebarUpdateTimer', callback, SIDEBAR_DEBOUNCE_MS); + // open sidebar + _m.sidebar.open(photo, filename, useNative); + } + }, + SIDEBAR_DEBOUNCE_MS, + true, + ); }, handleAppSidebarOpen() { diff --git a/src/services/utils/algo.ts b/src/services/utils/algo.ts index 8eaaedba..cd5e0049 100644 --- a/src/services/utils/algo.ts +++ b/src/services/utils/algo.ts @@ -80,8 +80,29 @@ export function randomSubarray(arr: T[], size: number): T[] { return shuffled.slice(min); } -/** Set a timer that renews if existing */ -export function setRenewingTimeout(ctx: any, name: string, callback: (() => void) | null, delay: number): void { +/** + * Set a timer that renews if existing . + * + * @param ctx Context to store the timeout in + * @param name Name of the timeout + * @param callback Callback to call when the timeout expires + * @param delay Delay in milliseconds + * @param immediate If true, call the callback immediately if no timeout exists + */ +export function setRenewingTimeout( + ctx: any, + name: string, + callback: (() => void) | null, + delay: number, + immediate?: boolean, +): void { + // Call immediately if no timeout exists + if (immediate && !ctx[name]) { + callback?.(); + callback = null; + } + + // Clear existing timeout and set a new one if (ctx[name]) window.clearTimeout(ctx[name]); ctx[name] = window.setTimeout(() => { ctx[name] = 0;