A music player that connects to your cloud/distributed storage. diffuse.sh
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122import * as TID from "@atcute/tid";import { defineElement, DiffuseElement } from "~/common/element.js";import { SCHEME } from "./constants.js";import { buildURI, loadHandles, saveHandles, tidsFromTracks,} from "./common.js";
/** * @import {InputActions, InputSchemeProvider} from "@specs/components/input/types.d.ts" * @import {ProxiedActions} from "~/common/worker.d.ts" * @import {Track} from "~/definitions/types.d.ts" */
////////////////////////////////////////////// ELEMENT////////////////////////////////////////////
/** * @implements {ProxiedActions<InputActions>} * @implements {InputSchemeProvider} */class LocalInput extends DiffuseElement { static NAME = "diffuse/input/local"; static WORKER_URL = "components/input/local/worker.js";
SCHEME = SCHEME;
/** @type {Map<string, string>} tid → handle name */ #names = new Map();
constructor() { super();
/** @type {ProxiedActions<InputActions>} */ this.proxy = this.workerProxy();
this.artwork = this.proxy.artwork; this.consult = this.proxy.consult; this.detach = this.proxy.detach; this.groupConsult = this.proxy.groupConsult; this.list = this.proxy.list; this.resolve = this.proxy.resolve; }
// LIFECYCLE
/** @override */ async connectedCallback() { super.connectedCallback(); const handles = await loadHandles(); for (const [tid, handle] of Object.entries(handles)) { this.#names.set(tid, handle.name); } }
// 🛠️
/** * Prompts the user to pick a directory. * Stores handle in IDB. * Returns the URI for the track placeholder. */ async addDirectory() { const dirHandle = await /** @type {any} */ (globalThis).showDirectoryPicker( { mode: "read" }, );
const tid = TID.now(); const handles = await loadHandles();
handles[tid] = dirHandle; await saveHandles(handles); this.#names.set(tid, dirHandle.name);
return buildURI(tid); }
/** * Prompts the user to pick one or more files. * Stores handles in IDB. * Returns the URIs for the track placeholders. */ async addFiles() { const fileHandles = await /** @type {any} */ (globalThis) .showOpenFilePicker({ multiple: true }); const handles = await loadHandles(); const uris = [];
for (const fileHandle of fileHandles) { const tid = TID.now(); handles[tid] = fileHandle; this.#names.set(tid, fileHandle.name); uris.push(buildURI(tid)); }
await saveHandles(handles); return uris; }
/** @param {Track[]} tracks */ sources(tracks) { return Object.values(tidsFromTracks(tracks)).map((tid) => ({ label: this.#names.get(tid) ?? tid, uri: buildURI(tid), })); }}
export default LocalInput;
////////////////////////////////////////////// REGISTER////////////////////////////////////////////
export const CLASS = LocalInput;export const NAME = "di-local";
defineElement(NAME, CLASS);