diff --git a/src/lib/modules/util.ts b/src/lib/modules/util.ts index 67e1b3b..0048e9e 100644 --- a/src/lib/modules/util.ts +++ b/src/lib/modules/util.ts @@ -27,3 +27,32 @@ export const formatNetworkSpeed = (speed: number) => { if (speed < 1000 * 1000 * 1000) return `${(speed / 1000 / 1000).toFixed(1)} Mbps`; return `${(speed / 1000 / 1000 / 1000).toFixed(1)} Gbps`; }; + +export enum SortBy { + NAME_ASC, + NAME_DESC, +} + +type SortFunc = (a?: string, b?: string) => number; + +const collator = new Intl.Collator(undefined, { numeric: true, sensitivity: "base" }); + +const sortByNameAsc: SortFunc = (a, b) => { + if (a && b) return collator.compare(a, b); + if (a) return -1; + if (b) return 1; + return 0; +}; + +const sortByNameDesc: SortFunc = (a, b) => -sortByNameAsc(a, b); + +export const sortEntries = (entries: T[], sortBy: SortBy) => { + let sortFunc: SortFunc; + if (sortBy === SortBy.NAME_ASC) { + sortFunc = sortByNameAsc; + } else { + sortFunc = sortByNameDesc; + } + + entries.sort((a, b) => sortFunc(a.name, b.name)); +}; diff --git a/src/lib/molecules/Categories/Categories.svelte b/src/lib/molecules/Categories/Categories.svelte index 0c07e2b..a11313e 100644 --- a/src/lib/molecules/Categories/Categories.svelte +++ b/src/lib/molecules/Categories/Categories.svelte @@ -1,8 +1,9 @@ -{#if categories.length > 0} +{#if categoriesWithName.length > 0}
- {#each categories as category} + {#each categoriesWithName as { info }} - import type { Writable } from "svelte/store"; + import { untrack } from "svelte"; + import { get, type Writable } from "svelte/store"; import { CheckBox } from "$lib/components/inputs"; import { getFileInfo, type FileInfo, type CategoryInfo } from "$lib/modules/filesystem"; + import { SortBy, sortEntries } from "$lib/modules/util"; import type { SelectedCategory } from "$lib/molecules/Categories"; import SubCategories from "$lib/molecules/SubCategories.svelte"; import { masterKeyStore } from "$lib/stores"; @@ -17,6 +19,7 @@ onSubCategoryClick: (subCategory: SelectedCategory) => void; onSubCategoryCreateClick: () => void; onSubCategoryMenuClick: (subCategory: SelectedCategory) => void; + sortBy?: SortBy; isFileRecursive: boolean; } @@ -27,21 +30,42 @@ onSubCategoryClick, onSubCategoryCreateClick, onSubCategoryMenuClick, + sortBy = SortBy.NAME_ASC, isFileRecursive = $bindable(), }: Props = $props(); - let files: { info: Writable; isRecursive: boolean }[] = $state([]); + let files: { name?: string; info: Writable; isRecursive: boolean }[] = $state( + [], + ); $effect(() => { files = info.files ?.filter(({ isRecursive }) => isFileRecursive || !isRecursive) - .map(({ id, isRecursive }) => ({ - info: getFileInfo(id, $masterKeyStore?.get(1)?.key!), - isRecursive, - })) ?? []; + .map(({ id, isRecursive }) => { + const info = getFileInfo(id, $masterKeyStore?.get(1)?.key!); + return { + name: get(info)?.name, + info, + isRecursive, + }; + }) ?? []; - // TODO: Sorting + const sort = () => { + sortEntries(files, sortBy); + }; + return untrack(() => { + sort(); + + const unsubscribes = files.map((file) => + file.info.subscribe((value) => { + if (file.name === value?.name) return; + file.name = value?.name; + sort(); + }), + ); + return () => unsubscribes.forEach((unsubscribe) => unsubscribe()); + }); }); diff --git a/src/routes/(main)/directory/[[id]]/DirectoryEntries/DirectoryEntries.svelte b/src/routes/(main)/directory/[[id]]/DirectoryEntries/DirectoryEntries.svelte index e482e38..baa9760 100644 --- a/src/routes/(main)/directory/[[id]]/DirectoryEntries/DirectoryEntries.svelte +++ b/src/routes/(main)/directory/[[id]]/DirectoryEntries/DirectoryEntries.svelte @@ -7,6 +7,7 @@ type DirectoryInfo, type FileInfo, } from "$lib/modules/filesystem"; + import { SortBy, sortEntries } from "$lib/modules/util"; import { fileUploadStatusStore, isFileUploading, @@ -15,7 +16,6 @@ } from "$lib/stores"; import File from "./File.svelte"; import SubDirectory from "./SubDirectory.svelte"; - import { SortBy, sortEntries } from "./service"; import UploadingFile from "./UploadingFile.svelte"; import type { SelectedDirectoryEntry } from "../service"; diff --git a/src/routes/(main)/directory/[[id]]/DirectoryEntries/index.ts b/src/routes/(main)/directory/[[id]]/DirectoryEntries/index.ts index 72ab278..075644e 100644 --- a/src/routes/(main)/directory/[[id]]/DirectoryEntries/index.ts +++ b/src/routes/(main)/directory/[[id]]/DirectoryEntries/index.ts @@ -1,2 +1 @@ export { default } from "./DirectoryEntries.svelte"; -export * from "./service"; diff --git a/src/routes/(main)/directory/[[id]]/DirectoryEntries/service.ts b/src/routes/(main)/directory/[[id]]/DirectoryEntries/service.ts deleted file mode 100644 index b797727..0000000 --- a/src/routes/(main)/directory/[[id]]/DirectoryEntries/service.ts +++ /dev/null @@ -1,31 +0,0 @@ -export enum SortBy { - NAME_ASC, - NAME_DESC, -} - -type SortFunc = (a?: string, b?: string) => number; - -const collator = new Intl.Collator(undefined, { numeric: true, sensitivity: "base" }); - -const sortByNameAsc: SortFunc = (a, b) => { - if (a && b) return collator.compare(a, b); - if (a) return -1; - if (b) return 1; - return 0; -}; - -const sortByNameDesc: SortFunc = (a, b) => -sortByNameAsc(a, b); - -export const sortEntries = ( - entries: T[], - sortBy: SortBy = SortBy.NAME_ASC, -) => { - let sortFunc: SortFunc; - if (sortBy === SortBy.NAME_ASC) { - sortFunc = sortByNameAsc; - } else { - sortFunc = sortByNameDesc; - } - - entries.sort((a, b) => sortFunc(a.name, b.name)); -};