feat(frontend): implement file viewer page with metadata editing and tag picker
- files/[id]/+page.svelte: full-screen preview (100dvh), sticky top bar,
prev/next nav via anchor API, notes/datetime/is_public editing, TagPicker,
EXIF display, keyboard navigation (←/→/Esc)
- TagPicker.svelte: assigned tags with remove, searchable available tags to add
- Fix infinite request loop: previewSrc read inside $effect tracked as dependency;
wrapped in untrack() to prevent re-triggering on blob URL assignment
- vite-mock-plugin: add GET/PATCH /files/{id}, preview endpoint, tags CRUD,
anchor-based pagination, in-memory mutable state for file overrides and tags
- files/+page.svelte: migrate from deprecated $app/stores to $app/state
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
<script lang="ts">
|
||||
import { page } from '$app/stores';
|
||||
import { page } from '$app/state';
|
||||
import { goto } from '$app/navigation';
|
||||
import { api } from '$lib/api/client';
|
||||
import { ApiError } from '$lib/api/client';
|
||||
@@ -29,7 +29,7 @@
|
||||
let error = $state('');
|
||||
let filterOpen = $state(false);
|
||||
|
||||
let filterParam = $derived($page.url.searchParams.get('filter'));
|
||||
let filterParam = $derived(page.url.searchParams.get('filter'));
|
||||
let activeTokens = $derived(parseDslFilter(filterParam));
|
||||
let sortState = $derived($fileSorting);
|
||||
|
||||
@@ -71,7 +71,7 @@
|
||||
}
|
||||
|
||||
function applyFilter(filter: string | null) {
|
||||
const url = new URL($page.url);
|
||||
const url = new URL(page.url);
|
||||
if (filter) {
|
||||
url.searchParams.set('filter', filter);
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user