UNPKG

@e280/quay

Version:

File-browser and outliner UI for the web

95 lines (78 loc) 3.06 kB
import {MapG} from "@e280/stz" import {Content, html} from "@benev/slate" import Quay from "../../../index.js" import {Group} from "../../group.js" import {Codex} from "../../aspects/codex/codex.js" import {MediaFormat, MediaSchema} from "./schema.js" import {GroupConfig, SearchFn, SortFn} from "../../types.js" import {CodexItem} from "../../aspects/codex/parts/codex-item.js" export class MediaGroup extends Group<MediaSchema> implements Group { static config = (): GroupConfig<MediaSchema> => { const formatIcons = new MapG<MediaFormat, Content>() .set("audio", html`<sl-icon name=music-note-beamed></sl-icon>`) .set("video", html`<sl-icon name=film></sl-icon>`) .set("image", html`<sl-icon name=image></sl-icon>`) .set("other", html`<sl-icon name=file-earmark></sl-icon>`) const filters = new Map<string, SearchFn<MediaSchema>>() .set("all", () => true) .set("video", item => item.isKind("folder") || (item.isKind("file") && item.specimen.format === "video")) .set("audio", item => item.isKind("folder") || (item.isKind("file") && item.specimen.format === "audio")) const sorts = new Map<string, SortFn<MediaSchema>>() .set("label", (a, b) => a.specimen.label.localeCompare(b.specimen.label)) .set("format", (a, b) => { if (a.isKind("file") && b.isKind("file")) return a.specimen.format.localeCompare(b.specimen.format) if (a.isKind("file")) return -1 if (b.isKind("file")) return 1 return 0 }) const search: (terms: string[], item: CodexItem<MediaSchema>) => boolean = (terms, item) => { const query = terms.join(" ").trim().toLowerCase() if (query === "") return true if (item.kind === "folder") { return item.children.some(child => search(terms, child)) } return item.specimen.label.toLowerCase().includes(query) } const codex = Codex.setup<MediaSchema>({ folder: {icon: html`<sl-icon name="folder"></sl-icon>`}, file: {icon: html`<sl-icon name="file"></sl-icon>`}, }) const root = codex.root( codex.create("folder", {label: "project"}) ) const renderIcon = (item: CodexItem<MediaSchema>, opened: boolean) => { return item.isKind("file") ? formatIcons.require(item.specimen.format) : opened ? html`<sl-icon name="folder2-open"></sl-icon>` : item.taxon.icon } return { codex, root, sorts, filters: filters, defaultFilter: "all", defaultSort: "label", search: (terms, item) => { return terms.some(term => ( item.kind.includes(term) || item.id.includes(term) || item.specimen.label.includes(term) )) || search(terms, item) }, renderIcon, renderLabel: item => item.specimen.label, renderPreview: (item: CodexItem<MediaSchema>) => { return (item.isKind("file") && item.specimen.previewUrl) ? html`<img src=${item.specimen.previewUrl}>` : renderIcon(item, false) // // TODO icons // : html`<sl-icon name=${item.taxon.icon}></sl-icon>` }, permissions: item => Quay.permissions.all, } } constructor() { super(MediaGroup.config()) } }