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:
parent
454836b551
commit
c33b918d74
7 changed files with 52 additions and 81 deletions
|
@ -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();
|
|
45
web/src/lib/stores/folders.svelte.ts
Normal file
45
web/src/lib/stores/folders.svelte.ts
Normal 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();
|
|
@ -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';
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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));
|
||||||
|
|
||||||
|
|
|
@ -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];
|
||||||
|
|
|
@ -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"
|
||||||
|
|
Loading…
Reference in a new issue