1
0
Fork 0
mirror of https://github.com/immich-app/immich.git synced 2024-12-28 06:31:58 +00:00

refactor(web): folders store (#14305)

* refactor(web): folders store

* use typescript private
This commit is contained in:
Michel Heusschen 2024-11-23 20:22:13 +01:00 committed by GitHub
parent 454836b551
commit c33b918d74
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 52 additions and 81 deletions

View file

@ -1,69 +0,0 @@
import {
getAssetsByOriginalPath,
getUniqueOriginalPaths,
/**
* TODO: Incorrect type
*/
type AssetResponseDto,
} from '@immich/sdk';
import { get, writable } from 'svelte/store';
type AssetCache = {
[path: string]: AssetResponseDto[];
};
type FoldersStore = {
uniquePaths: string[] | null;
assets: AssetCache;
};
function createFoldersStore() {
const initialState: FoldersStore = {
uniquePaths: null,
assets: {},
};
const { subscribe, set, update } = writable(initialState);
async function fetchUniquePaths() {
const state = get(foldersStore);
if (state.uniquePaths !== null) {
return;
}
const uniquePaths = await getUniqueOriginalPaths();
if (uniquePaths) {
update((state) => ({ ...state, uniquePaths }));
}
}
async function fetchAssetsByPath(path: string) {
const state = get(foldersStore);
if (state.assets[path]) {
return;
}
const assets = await getAssetsByOriginalPath({ path });
if (assets) {
update((state) => ({
...state,
assets: { ...state.assets, [path]: assets },
}));
}
}
function clearCache() {
set(initialState);
}
return {
subscribe,
fetchUniquePaths,
fetchAssetsByPath,
clearCache,
};
}
export const foldersStore = createFoldersStore();

View file

@ -0,0 +1,45 @@
import {
getAssetsByOriginalPath,
getUniqueOriginalPaths,
/**
* TODO: Incorrect type
*/
type AssetResponseDto,
} from '@immich/sdk';
type AssetCache = {
[path: string]: AssetResponseDto[];
};
class FoldersStore {
private initialized = false;
uniquePaths = $state<string[]>([]);
assets = $state<AssetCache>({});
async fetchUniquePaths() {
if (this.initialized) {
return;
}
this.initialized = true;
const uniquePaths = await getUniqueOriginalPaths();
this.uniquePaths.push(...uniquePaths);
this.uniquePaths.sort();
}
async fetchAssetsByPath(path: string) {
if (this.assets[path]) {
return;
}
this.assets[path] = await getAssetsByOriginalPath({ path });
}
clearCache() {
this.initialized = false;
this.uniquePaths = [];
this.assets = {};
}
}
export const foldersStore = new FoldersStore();

View file

@ -1,6 +1,6 @@
import { browser } from '$app/environment'; import { browser } from '$app/environment';
import { goto } from '$app/navigation'; import { goto } from '$app/navigation';
import { foldersStore } from '$lib/stores/folders.store'; import { foldersStore } from '$lib/stores/folders.svelte';
import { purchaseStore } from '$lib/stores/purchase.store'; import { purchaseStore } from '$lib/stores/purchase.store';
import { serverInfo } from '$lib/stores/server-info.store'; import { serverInfo } from '$lib/stores/server-info.store';
import { preferences as preferences$, resetSavedUser, user as user$ } from '$lib/stores/user.store'; import { preferences as preferences$, resetSavedUser, user as user$ } from '$lib/stores/user.store';

View file

@ -7,8 +7,6 @@ export const normalizeTreePath = (path: string) => path.replace(/^\//, '').repla
export function buildTree(paths: string[]) { export function buildTree(paths: string[]) {
const root: RecursiveObject = {}; const root: RecursiveObject = {};
paths.sort();
for (const path of paths) { for (const path of paths) {
const parts = path.split('/'); const parts = path.split('/');
let current = root; let current = root;

View file

@ -9,7 +9,7 @@
import TreeItems from '$lib/components/shared-components/tree/tree-items.svelte'; import TreeItems from '$lib/components/shared-components/tree/tree-items.svelte';
import { AppRoute, QueryParameter } from '$lib/constants'; import { AppRoute, QueryParameter } from '$lib/constants';
import type { Viewport } from '$lib/stores/assets.store'; import type { Viewport } from '$lib/stores/assets.store';
import { foldersStore } from '$lib/stores/folders.store'; import { foldersStore } from '$lib/stores/folders.svelte';
import { buildTree, normalizeTreePath } from '$lib/utils/tree-utils'; import { buildTree, normalizeTreePath } from '$lib/utils/tree-utils';
import { mdiFolder, mdiFolderHome, mdiFolderOutline } from '@mdi/js'; import { mdiFolder, mdiFolderHome, mdiFolderOutline } from '@mdi/js';
import { onMount } from 'svelte'; import { onMount } from 'svelte';
@ -27,7 +27,7 @@
const viewport: Viewport = $state({ width: 0, height: 0 }); const viewport: Viewport = $state({ width: 0, height: 0 });
let pathSegments = $derived(data.path ? data.path.split('/') : []); let pathSegments = $derived(data.path ? data.path.split('/') : []);
let tree = $derived(buildTree($foldersStore?.uniquePaths || [])); let tree = $derived(buildTree(foldersStore.uniquePaths));
let currentPath = $derived($page.url.searchParams.get(QueryParameter.PATH) || ''); let currentPath = $derived($page.url.searchParams.get(QueryParameter.PATH) || '');
let currentTreeItems = $derived(currentPath ? data.currentFolders : Object.keys(tree)); let currentTreeItems = $derived(currentPath ? data.currentFolders : Object.keys(tree));

View file

@ -1,10 +1,9 @@
import { QueryParameter } from '$lib/constants'; import { QueryParameter } from '$lib/constants';
import { foldersStore } from '$lib/stores/folders.store'; import { foldersStore } from '$lib/stores/folders.svelte';
import { authenticate } from '$lib/utils/auth'; import { authenticate } from '$lib/utils/auth';
import { getFormatter } from '$lib/utils/i18n'; import { getFormatter } from '$lib/utils/i18n';
import { getAssetInfoFromParam } from '$lib/utils/navigation'; import { getAssetInfoFromParam } from '$lib/utils/navigation';
import { buildTree, normalizeTreePath } from '$lib/utils/tree-utils'; import { buildTree, normalizeTreePath } from '$lib/utils/tree-utils';
import { get } from 'svelte/store';
import type { PageLoad } from './$types'; import type { PageLoad } from './$types';
export const load = (async ({ params, url }) => { export const load = (async ({ params, url }) => {
@ -13,18 +12,16 @@ export const load = (async ({ params, url }) => {
const $t = await getFormatter(); const $t = await getFormatter();
await foldersStore.fetchUniquePaths(); await foldersStore.fetchUniquePaths();
const { uniquePaths } = get(foldersStore);
let pathAssets = null; let pathAssets = null;
const path = url.searchParams.get(QueryParameter.PATH); const path = url.searchParams.get(QueryParameter.PATH);
if (path) { if (path) {
await foldersStore.fetchAssetsByPath(path); await foldersStore.fetchAssetsByPath(path);
const { assets } = get(foldersStore); pathAssets = foldersStore.assets[path] || null;
pathAssets = assets[path] || null;
} }
let tree = buildTree(uniquePaths || []); let tree = buildTree(foldersStore.uniquePaths);
const parts = normalizeTreePath(path || '').split('/'); const parts = normalizeTreePath(path || '').split('/');
for (const part of parts) { for (const part of parts) {
tree = tree?.[part]; tree = tree?.[part];

View file

@ -10,7 +10,7 @@
"skipLibCheck": true, "skipLibCheck": true,
"sourceMap": true, "sourceMap": true,
"strict": true, "strict": true,
"target": "es2020", "target": "es2022",
"types": ["vitest/globals"] "types": ["vitest/globals"]
}, },
"extends": "./.svelte-kit/tsconfig.json" "extends": "./.svelte-kit/tsconfig.json"