diff options
| author | Adam Malczewski <[email protected]> | 2026-04-10 02:34:58 +0900 |
|---|---|---|
| committer | Adam Malczewski <[email protected]> | 2026-04-10 02:34:58 +0900 |
| commit | e3e6c664b547666a367c96062523753699fdeb90 (patch) | |
| tree | 074127ffbf4cb4ff8af08a1f3e37e3049917fe6c /src | |
| parent | 391279ebbf632896e04c214a627ebc53ca0a16ae (diff) | |
| download | flashair-speedsync-e3e6c664b547666a367c96062523753699fdeb90.tar.gz flashair-speedsync-e3e6c664b547666a367c96062523753699fdeb90.zip | |
add auto-show image toggle, ui niceness, more complete readme
Diffstat (limited to 'src')
| -rw-r--r-- | src/App.svelte | 76 | ||||
| -rw-r--r-- | src/lib/components/ImagePreview.svelte | 6 |
2 files changed, 13 insertions, 69 deletions
diff --git a/src/App.svelte b/src/App.svelte index 7a634cc..5fa63a7 100644 --- a/src/App.svelte +++ b/src/App.svelte @@ -13,8 +13,7 @@ let loading = $state(false); let error = $state<string | undefined>(undefined); let isDark = $state(false); - let deleting = $state(false); - let showDeleteConfirm = $state(false); + let showNewImage = $state(false); let isAutoCaching = $state(false); let cachedCount = $state(0); let totalCount = $state(0); @@ -68,8 +67,8 @@ autoCacheService.stop(); startAutoCacheWithPollPause(images); - // Auto-select the newest if nothing was selected - if (selectedFile === undefined && images.length > 0) { + // Auto-select the newest if nothing was selected, or if showNewImage is on + if ((showNewImage || selectedFile === undefined) && images.length > 0) { selectedFile = images[0]; } }); @@ -102,45 +101,6 @@ selectedFile = file; } - function requestDelete() { - if (selectedFile === undefined) return; - showDeleteConfirm = true; - } - - async function confirmDelete() { - showDeleteConfirm = false; - if (selectedFile === undefined) return; - - const fileToDelete = selectedFile; - deleting = true; - try { - await flashair.deleteFile(fileToDelete.path); - // Remove from cache and auto-cache queue - void imageCache.delete('thumbnail', fileToDelete.path); - void imageCache.delete('full', fileToDelete.path); - autoCacheService.removeImage(fileToDelete.path); - pollService.removeKnownPath(fileToDelete.path); - // Remove from list and select next image - const idx = images.findIndex((f) => f.path === fileToDelete.path); - images = images.filter((f) => f.path !== fileToDelete.path); - if (images.length === 0) { - selectedFile = undefined; - } else if (idx >= images.length) { - selectedFile = images[images.length - 1]; - } else { - selectedFile = images[idx]; - } - } catch (e) { - error = `Delete failed: ${e instanceof Error ? e.message : String(e)}`; - } finally { - deleting = false; - } - } - - function cancelDelete() { - showDeleteConfirm = false; - } - function handleAnimationDone(path: string) { const updated = new Set(newImagePaths); updated.delete(path); @@ -251,13 +211,16 @@ </svg> {/if} </button> - <!-- Delete --> - <button class="btn btn-lg btn-circle btn-error" onclick={() => requestDelete()} disabled={selectedFile === undefined || deleting}> - {#if deleting} - <span class="loading loading-spinner loading-sm"></span> + <!-- Show New Image toggle --> + <button class="btn btn-lg btn-circle {showNewImage ? 'btn-accent' : 'btn-neutral'}" onclick={() => (showNewImage = !showNewImage)} aria-label="Toggle auto-show new images"> + {#if showNewImage} + <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-5"> + <path stroke-linecap="round" stroke-linejoin="round" d="M2.036 12.322a1.012 1.012 0 0 1 0-.639C3.423 7.51 7.36 4.5 12 4.5c4.638 0 8.573 3.007 9.963 7.178.07.207.07.431 0 .639C20.577 16.49 16.64 19.5 12 19.5c-4.638 0-8.573-3.007-9.963-7.178Z" /> + <path stroke-linecap="round" stroke-linejoin="round" d="M15 12a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z" /> + </svg> {:else} <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-5"> - <path stroke-linecap="round" stroke-linejoin="round" d="m14.74 9-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 0 1-2.244 2.077H8.084a2.25 2.25 0 0 1-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 0 0-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 0 1 3.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 0 0-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 0 0-7.5 0" /> + <path stroke-linecap="round" stroke-linejoin="round" d="M3.98 8.223A10.477 10.477 0 0 0 1.934 12c1.292 4.338 5.31 7.5 10.066 7.5.993 0 1.953-.138 2.863-.395M6.228 6.228A10.451 10.451 0 0 1 12 4.5c4.756 0 8.773 3.162 10.065 7.498a10.522 10.522 0 0 1-4.293 5.774M6.228 6.228 3 3m3.228 3.228 3.65 3.65m7.894 7.894L21 21m-3.228-3.228-3.65-3.65m0 0a3 3 0 1 0-4.243-4.243m4.242 4.242L9.88 9.88" /> </svg> {/if} </button> @@ -287,23 +250,6 @@ </button> </div> -<!-- Delete confirmation modal --> -{#if showDeleteConfirm && selectedFile !== undefined} - <dialog class="modal modal-open"> - <div class="modal-box"> - <h3 class="text-lg font-bold">Delete photo?</h3> - <p class="py-4">This will permanently delete <strong>{selectedFile.filename}</strong> from the SD card.</p> - <div class="modal-action"> - <button class="btn" onclick={() => cancelDelete()}>Cancel</button> - <button class="btn btn-error" onclick={() => void confirmDelete()}>Delete</button> - </div> - </div> - <form method="dialog" class="modal-backdrop"> - <button onclick={() => cancelDelete()}>close</button> - </form> - </dialog> -{/if} - {#if showDebug} <CacheDebug /> {/if} diff --git a/src/lib/components/ImagePreview.svelte b/src/lib/components/ImagePreview.svelte index 22b40da..78677f7 100644 --- a/src/lib/components/ImagePreview.svelte +++ b/src/lib/components/ImagePreview.svelte @@ -438,7 +438,7 @@ <!-- svelte-ignore a11y_no_static_element_interactions --> <div - class="h-full flex items-center justify-center bg-base-300 relative overflow-hidden touch-none" + class="h-full flex items-center justify-center bg-black relative overflow-hidden touch-none" bind:this={containerEl} onwheel={handleWheel} > @@ -453,7 +453,7 @@ </div> {:else} {#if downloading && progress < 1} - <div class="absolute inset-0 z-10 flex items-center justify-center bg-base-300/80 backdrop-blur-sm"> + <div class="absolute inset-0 z-10 flex items-center justify-center bg-black/80 backdrop-blur-sm"> <div class="bg-base-100 rounded-box p-4 shadow-xl max-w-xs w-full mx-4"> <div class="flex items-center gap-2"> <progress class="progress progress-primary flex-1" value={progressPercent} max="100"></progress> @@ -463,7 +463,6 @@ </div> {/if} {#if fullObjectUrl !== undefined} - {#key fullObjectUrl} <img src={fullObjectUrl} alt={file.filename} @@ -476,7 +475,6 @@ draggable="false" onload={handleImageLoad} /> - {/key} {:else if showThumbnail} <div class="w-full max-h-full overflow-hidden" |
