diff options
| author | Adam Malczewski <[email protected]> | 2026-04-09 19:55:19 +0900 |
|---|---|---|
| committer | Adam Malczewski <[email protected]> | 2026-04-09 19:55:19 +0900 |
| commit | bafc36cbb2287ecb3b806cb32118a9ee9d5f7170 (patch) | |
| tree | 2b2196ef84bb20dc97bcdd61b15c7154aa569733 /src/lib/components | |
| parent | a39e2501b81c1e52437839e018bd5bf07b46616c (diff) | |
| download | flashair-speedsync-bafc36cbb2287ecb3b806cb32118a9ee9d5f7170.tar.gz flashair-speedsync-bafc36cbb2287ecb3b806cb32118a9ee9d5f7170.zip | |
auto-caching setup
Diffstat (limited to 'src/lib/components')
| -rw-r--r-- | src/lib/components/CachedThumbnail.svelte | 38 | ||||
| -rw-r--r-- | src/lib/components/ImagePreview.svelte | 13 |
2 files changed, 45 insertions, 6 deletions
diff --git a/src/lib/components/CachedThumbnail.svelte b/src/lib/components/CachedThumbnail.svelte index f0fe8bf..3a6d452 100644 --- a/src/lib/components/CachedThumbnail.svelte +++ b/src/lib/components/CachedThumbnail.svelte @@ -1,6 +1,7 @@ <script lang="ts"> import { flashair } from '../flashair'; import { imageCache } from '../cache'; + import { autoCacheService } from '../cache'; interface Props { path: string; @@ -11,6 +12,7 @@ let blobUrl = $state<string | undefined>(undefined); let rawBlobUrl: string | undefined; + let cacheProgress = $state<number | undefined>(undefined); $effect(() => { const currentPath = path; @@ -26,6 +28,17 @@ }; }); + // Subscribe to auto-cache progress updates + $effect(() => { + const currentPath = path; + const unsubscribe = autoCacheService.subscribe(() => { + cacheProgress = autoCacheService.getProgress(currentPath); + }); + // Set initial value + cacheProgress = autoCacheService.getProgress(currentPath); + return unsubscribe; + }); + async function loadThumbnail(filePath: string) { // Try cache first const cached = await imageCache.get('thumbnail', filePath); @@ -51,15 +64,28 @@ // Thumbnail fetch failed — show placeholder } } + + let cachePercent = $derived( + cacheProgress !== undefined ? Math.round(cacheProgress * 100) : undefined + ); </script> {#if blobUrl !== undefined} - <img - src={blobUrl} - {alt} - class="w-full aspect-square rounded object-cover" - draggable="false" - /> + <div class="relative w-full aspect-square"> + <img + src={blobUrl} + {alt} + class="w-full aspect-square rounded object-cover" + draggable="false" + /> + {#if cachePercent !== undefined && cachePercent < 100} + <div class="absolute inset-0 flex items-center justify-center"> + <div class="radial-progress text-primary bg-base-300/60 border-2 border-base-300/60" style:--value={cachePercent} style:--size="2.5rem" style:--thickness="3px" role="progressbar"> + <span class="text-[0.6rem] font-bold text-primary-content drop-shadow">{cachePercent}%</span> + </div> + </div> + {/if} + </div> {:else} <div class="w-full aspect-square rounded bg-base-300 flex items-center justify-center"> <span class="loading loading-spinner loading-sm"></span> diff --git a/src/lib/components/ImagePreview.svelte b/src/lib/components/ImagePreview.svelte index f5032a6..20a9937 100644 --- a/src/lib/components/ImagePreview.svelte +++ b/src/lib/components/ImagePreview.svelte @@ -2,6 +2,7 @@ import { flashair } from '../flashair'; import type { FlashAirFileEntry } from '../flashair'; import { imageCache } from '../cache'; + import { autoCacheService } from '../cache'; interface Props { file: FlashAirFileEntry | undefined; @@ -251,6 +252,12 @@ currentAbort.abort(); currentAbort = undefined; } + // If we were downloading and got aborted (e.g. user navigated away), + // make sure to resume the auto-cache service. + if (downloading) { + downloading = false; + autoCacheService.resumeAfterUserDownload(); + } }; }); @@ -330,12 +337,14 @@ fullObjectUrl = objectUrl; progress = 1; downloading = false; + autoCacheService.markCached(entry.path); return; } downloading = true; progress = 0; loadError = undefined; + autoCacheService.pauseForUserDownload(); const url = flashair.fileUrl(entry.path); const totalBytes = entry.size; @@ -352,11 +361,13 @@ if (abort.signal.aborted) return; // Store in cache (fire-and-forget) void imageCache.put('full', entry.path, blob); + autoCacheService.markCached(entry.path); const objectUrl = URL.createObjectURL(blob); rawObjectUrl = objectUrl; fullObjectUrl = objectUrl; progress = 1; downloading = false; + autoCacheService.resumeAfterUserDownload(); return; } @@ -376,6 +387,7 @@ const blob = new Blob(chunks); // Store in cache (fire-and-forget) void imageCache.put('full', entry.path, blob); + autoCacheService.markCached(entry.path); const objectUrl = URL.createObjectURL(blob); rawObjectUrl = objectUrl; fullObjectUrl = objectUrl; @@ -386,6 +398,7 @@ } finally { if (!abort.signal.aborted) { downloading = false; + autoCacheService.resumeAfterUserDownload(); } } } |
