summaryrefslogtreecommitdiffhomepage
path: root/src/lib/components
diff options
context:
space:
mode:
authorAdam Malczewski <[email protected]>2026-04-09 19:55:19 +0900
committerAdam Malczewski <[email protected]>2026-04-09 19:55:19 +0900
commitbafc36cbb2287ecb3b806cb32118a9ee9d5f7170 (patch)
tree2b2196ef84bb20dc97bcdd61b15c7154aa569733 /src/lib/components
parenta39e2501b81c1e52437839e018bd5bf07b46616c (diff)
downloadflashair-speedsync-bafc36cbb2287ecb3b806cb32118a9ee9d5f7170.tar.gz
flashair-speedsync-bafc36cbb2287ecb3b806cb32118a9ee9d5f7170.zip
auto-caching setup
Diffstat (limited to 'src/lib/components')
-rw-r--r--src/lib/components/CachedThumbnail.svelte38
-rw-r--r--src/lib/components/ImagePreview.svelte13
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();
}
}
}