From 72f82216058f515b184f5647e9bfc04ef3df2164 Mon Sep 17 00:00:00 2001 From: Jacob Schmidt Date: Sat, 28 Feb 2026 17:20:40 -0600 Subject: [PATCH] Optimize calendar refresh scheduling and cancel stale loads --- .../src/lib/components/SidePanel.svelte | 120 +++++++++++------- 1 file changed, 76 insertions(+), 44 deletions(-) diff --git a/Journal.App/src/lib/components/SidePanel.svelte b/Journal.App/src/lib/components/SidePanel.svelte index 37743f0..3a68539 100644 --- a/Journal.App/src/lib/components/SidePanel.svelte +++ b/Journal.App/src/lib/components/SidePanel.svelte @@ -120,8 +120,10 @@ let showSaveViewInput = false; let saveViewName = ""; let hasLoadedSavedViews = false; - let lastCalendarTimelineKey = ""; let calendarTimelineDebounce: ReturnType | null = null; + let calendarDataVersion = 0; + let calendarScheduleKey = ""; + let calendarRefreshRequestId = 0; let lastActiveSection = ""; let calendarLastRefreshedAt = ""; let calendarDateExplicitlySelected = false; @@ -310,11 +312,44 @@ return tagTokens.some((token) => normalized.includes(token)); } + function scheduleCalendarRefresh(delayMs = 200) { + if (activeSection !== "calendar") return; + + const scheduleKey = [ + selectedCalendarDate?.key ?? "", + calendarYear, + calendarMonth, + calendarViewMode, + calendarSortMode, + calendarQuery, + calendarTags, + calendarTypes, + calendarStartDate, + calendarEndDate, + calendarDataVersion, + ].join("|"); + + if (scheduleKey === calendarScheduleKey && calendarTimelineDebounce) { + return; + } + + calendarScheduleKey = scheduleKey; + if (calendarTimelineDebounce) { + clearTimeout(calendarTimelineDebounce); + } + + calendarTimelineDebounce = setTimeout(() => { + void refreshCalendarTimeline(); + }, delayMs); + } + async function refreshCalendarTimeline(): Promise { + const requestId = ++calendarRefreshRequestId; calendarBusy = true; calendarError = ""; try { const dataDirectory = await getDataDirectory(); + if (requestId !== calendarRefreshRequestId) return; if (!dataDirectory) { calendarTimelineItems = []; return; @@ -325,12 +360,14 @@ dataDirectory, query: calendarQuery.trim() || undefined, }); + if (requestId !== calendarRefreshRequestId) return; const [fragmentDtos, listDtos, todoDtos] = await Promise.all([ listFragments(), listLists(), listTodoLists(), ]); + if (requestId !== calendarRefreshRequestId) return; const query = calendarQuery.trim(); const tagTokens = splitFilterTokens(calendarTags); @@ -425,10 +462,13 @@ second: "2-digit", }); } catch (error) { + if (requestId !== calendarRefreshRequestId) return; calendarError = String(error); calendarTimelineItems = []; } finally { - calendarBusy = false; + if (requestId === calendarRefreshRequestId) { + calendarBusy = false; + } } } @@ -818,53 +858,45 @@ loadSavedViews(); } - $: calendarTimelineRefreshKey = JSON.stringify({ - activeSection, - calendarYear, - calendarMonth, - selectedCalendarDate, - calendarViewMode, - calendarSortMode, - calendarQuery, - calendarTags, - calendarTypes, - calendarStartDate, - calendarEndDate, - entriesSig: $entriesStore - .map((item) => `${item.id}:${item.label}`) - .join("|"), - fragmentsSig: $fragmentsStore - .map((item) => `${item.id}:${item.label}`) - .join("|"), - listsSig: $listsStore.map((item) => `${item.id}:${item.label}`).join("|"), - todosSig: $todoListsStore - .map((item) => { - const todos = ($todosStore[item.id] ?? []) - .map((todo) => `${todo.text}:${todo.done ? "1" : "0"}`) - .join("~"); - return `${item.id}:${item.label}:${todos}`; - }) - .join("|"), - }); - $: if ( - activeSection === "calendar" && - calendarTimelineRefreshKey !== lastCalendarTimelineKey - ) { - lastCalendarTimelineKey = calendarTimelineRefreshKey; - if (calendarTimelineDebounce) { - clearTimeout(calendarTimelineDebounce); - } - calendarTimelineDebounce = setTimeout(() => { - void refreshCalendarTimeline(); - }, 200); + $: if (activeSection === "calendar") { + // Track store mutations without building large string signatures. + const storeInvalidationTick = [ + $entriesStore, + $fragmentsStore, + $listsStore, + $todoListsStore, + $todosStore, + ]; + void storeInvalidationTick; + calendarDataVersion += 1; + } + + $: if (activeSection === "calendar") { + const calendarTrigger = [ + selectedCalendarDate?.key ?? "", + calendarYear, + calendarMonth, + calendarViewMode, + calendarSortMode, + calendarQuery, + calendarTags, + calendarTypes, + calendarStartDate, + calendarEndDate, + calendarDataVersion, + ]; + void calendarTrigger; + scheduleCalendarRefresh(200); } $: if (activeSection === "calendar" && lastActiveSection !== "calendar") { calendarDateExplicitlySelected = false; + calendarScheduleKey = ""; void forceRefreshCalendar({ allowWhileBusy: true }); - setTimeout(() => { - void forceRefreshCalendar({ allowWhileBusy: true }); - }, 500); + } + $: if (activeSection !== "calendar" && calendarTimelineDebounce) { + clearTimeout(calendarTimelineDebounce); + calendarTimelineDebounce = null; } $: lastActiveSection = activeSection;