import type { Collection, InitialQueryBuilder } from "@tanstack/db" import type { FileEntry } from "./api" export const sortOptions = ["Name", "Kind", "Created", "Modified", "Size"] as const export type Sort = (typeof sortOptions)[number] export const viewOptions = ["list", "grid"] as const export type View = (typeof viewOptions)[number] const numericLocale = new Intl.Locale(new Intl.Collator().resolvedOptions().locale, { numeric: true, }).toString() function sortValue(file: FileEntry, sort: Sort): number | string { switch (sort) { case "Name": return file.name case "Kind": return file.kind case "Created": return Date.parse(file.createdAt) case "Modified": return Date.parse(file.updatedAt) case "Size": return file.size default: return file.name } } export function fileQuery( q: InitialQueryBuilder, collection: Collection, search: string, sort: Sort, descending: boolean, parentId?: string, ) { const term = search.trim().toLocaleLowerCase() const order = { direction: descending ? ("desc" as const) : ("asc" as const), stringSort: "locale" as const, locale: numericLocale, } return q .from({ file: collection }) .fn.where( ({ file }) => !file.trashedAt && file.parentId === parentId && file.name.toLocaleLowerCase().includes(term), ) .fn.select(({ file }) => ({ ...file, sortValue: sortValue(file, sort), })) .orderBy(({ $selected }) => $selected.sortValue, order) .orderBy(({ $selected }) => $selected.name, order) .orderBy(({ $selected }) => $selected.id, { direction: order.direction, stringSort: "locale" }) } export function validName(name: string) { return ( name.trim().length > 0 && name !== "." && name !== ".." && !Array.from(name).some( (character) => character.charCodeAt(0) < 32 || character === "/" || character === "\\", ) ) } export function selectedEntries(files: FileEntry[], selected: string[]) { return files.filter((file) => selected.includes(file.id)) }