refactor(viewer): sidebar debouncing

Signed-off-by: Varun Patil <radialapps@gmail.com>
pull/900/head
Varun Patil 2023-10-29 11:51:20 -07:00
parent a8d940acd0
commit 9e001730c2
2 changed files with 47 additions and 29 deletions

View File

@ -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() {

View File

@ -80,8 +80,29 @@ export function randomSubarray<T>(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;