diff --git a/frontend/viewer/src/lib/storage/project-storage.svelte.ts b/frontend/viewer/src/lib/storage/project-storage.svelte.ts index 8143639496..0d04ebcaa2 100644 --- a/frontend/viewer/src/lib/storage/project-storage.svelte.ts +++ b/frontend/viewer/src/lib/storage/project-storage.svelte.ts @@ -35,9 +35,13 @@ class ProjectStorageProp extends StorageProp { export class ProjectStorage { readonly selectedTaskId: ProjectStorageProp; readonly currentView: ProjectStorageProp; + readonly entryListViewMode: ProjectStorageProp; + readonly dictionaryPreview: ProjectStorageProp; constructor(projectCode: string, backend: IPreferencesService) { this.selectedTaskId = new ProjectStorageProp(projectCode, 'selectedTaskId', backend); this.currentView = new ProjectStorageProp(projectCode, 'currentView', backend); + this.entryListViewMode = new ProjectStorageProp(projectCode, 'entryListViewMode', backend); + this.dictionaryPreview = new ProjectStorageProp(projectCode, 'dictionaryPreview', backend); } } diff --git a/frontend/viewer/src/project/browse/BrowseView.svelte b/frontend/viewer/src/project/browse/BrowseView.svelte index 7551afa572..6dd1ce1318 100644 --- a/frontend/viewer/src/project/browse/BrowseView.svelte +++ b/frontend/viewer/src/project/browse/BrowseView.svelte @@ -19,10 +19,12 @@ import {useProjectContext} from '$project/project-context.svelte'; import type {EntryListViewMode} from './EntryListViewOptions.svelte'; import EntryListViewOptions from './EntryListViewOptions.svelte'; + import {useProjectStorage} from '$lib/storage/project-storage.svelte'; const projectContext = useProjectContext(); const viewService = useViewService(); const dialogsService = useDialogsService(); + const entryListViewMode = useProjectStorage().entryListViewMode; // DESKTOP: the entry is a sibling of the list (it's a split view). We can switch between selected entries. // So, selectedEntryId itself drives navigation. @@ -37,7 +39,7 @@ let semanticDomain = $state(); let partOfSpeech = $state(); let sort = $state(); - let entryMode: EntryListViewMode = $state('simple'); + const entryMode: EntryListViewMode = $derived(entryListViewMode.current === 'preview' ? 'preview' : 'simple'); async function newEntry() { const entry = await dialogsService.createNewEntry(undefined, { @@ -85,7 +87,7 @@
search ? SortField.SearchRelevance : SortField.Headword} /> - + entryMode, (v) => void entryListViewMode.set(v)} />
entryResource.loading, 50); - let dictionaryPreview: 'show' | 'hide' | 'sticky' = $state('show'); - const sticky = $derived.by(() => dictionaryPreview === 'sticky'); + const dictionaryPreview: DictionaryPreviewMode = $derived( + isDictionaryPreviewMode(dictionaryPreviewStorage.current) ? dictionaryPreviewStorage.current : 'show' + ); + function isDictionaryPreviewMode(value: string): value is DictionaryPreviewMode { + return value === 'show' || value === 'hide' || value === 'sticky'; + } + const sticky = $derived(dictionaryPreview === 'sticky'); let readonly = $state(false); let deleted = $state(false); @@ -107,7 +116,7 @@
{#snippet actions()} - sticky, (value) => dictionaryPreview = value ? 'sticky' : 'show'} + sticky, (value) => void dictionaryPreviewStorage.set(value ? 'sticky' : 'show')} aria-label={$t`Toggle pinned`} class="aspect-square" size="sm"> @@ -125,7 +134,7 @@ {/if}

{headword}

- + dictionaryPreview, (v) => void dictionaryPreviewStorage.set(v)} bind:readonly />