A music player that connects to your cloud/distributed storage.
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

at 1680a1e4e4b5ca50148f808c16fa15cbee2cdeb0 118 lines 3.1 kB view raw
1import * as TID from "@atcute/tid"; 2import { html } from "lit-html"; 3 4import * as Output from "~/common/output.js"; 5import { SCHEME } from "~/components/input/https/constants.js"; 6import { parseURI } from "~/components/input/https/common.js"; 7import { effect } from "~/common/signal.js"; 8import foundation from "~/common/foundation.js"; 9 10import { setup } from "~/facets/connect/common.js"; 11 12foundation.setup({ title: "Connect HTTPS | Diffuse" }); 13 14//////////////////////////////////////////// 15// SETUP 16//////////////////////////////////////////// 17 18const [inputConfigurator, outputOrchestrator, sourcesOrchestrator] = 19 await Promise.all([ 20 foundation.configurator.input(), 21 foundation.orchestrator.output(), 22 foundation.orchestrator.sources(), 23 ]); 24 25await Promise.all([ 26 customElements.whenDefined(inputConfigurator.localName), 27 customElements.whenDefined(outputOrchestrator.localName), 28 customElements.whenDefined(sourcesOrchestrator.localName), 29]); 30 31//////////////////////////////////////////// 32// UI 33//////////////////////////////////////////// 34 35const { setItems, setError } = setup({ 36 title: "HTTPS", 37 hasOutput: false, 38 39 description: html` 40 <p>Add HTTPS urls as audio sources.</p> 41 `, 42 43 formFields: html` 44 <label>URL <input id="https-url" type="url" placeholder="https://example.com/audio.mp3" required></label> 45 `, 46 47 onSubmit: () => addUrl(), 48}); 49 50const urlInput = /** @type {HTMLInputElement} */ (document.querySelector("#https-url")); 51 52//////////////////////////////////////////// 53// REACTIVE LIST 54//////////////////////////////////////////// 55 56effect(() => { 57 const inputSources = sourcesOrchestrator.sources()[SCHEME] ?? []; 58 59 setItems( 60 inputSources.map((source) => { 61 const parsed = parseURI(source.uri); 62 return { 63 name: source.uri, 64 detail: parsed?.host ?? "", 65 isInput: true, 66 isOutput: false, 67 isSelectedOutput: false, 68 onRemove: () => removeUrl(source.uri), 69 }; 70 }), 71 ); 72}); 73//////////////////////////////////////////// 74// ACTIONS 75//////////////////////////////////////////// 76 77/** @param {string} uri */ 78async function removeUrl(uri) { 79 setError(null); 80 try { 81 const tracks = await Output.data(outputOrchestrator.tracks); 82 const detachedTracks = await inputConfigurator.detach({ 83 fileUriOrScheme: uri, 84 tracks, 85 }); 86 87 if (detachedTracks) await outputOrchestrator.tracks.save(detachedTracks); 88 } catch (err) { 89 setError(err instanceof Error ? err.message : "Failed to remove URL"); 90 } 91} 92 93async function addUrl() { 94 const url = urlInput.value?.trim(); 95 if (!url) return; 96 97 const now = new Date().toISOString(); 98 const tracksCol = outputOrchestrator.tracks.collection(); 99 const existingTracks = tracksCol.state === "loaded" ? tracksCol.data : []; 100 101 await outputOrchestrator.tracks.save([ 102 ...existingTracks, 103 { 104 $type: "sh.diffuse.output.track", 105 id: TID.now(), 106 createdAt: now, 107 updatedAt: now, 108 kind: "placeholder", 109 uri: url, 110 }, 111 ]); 112} 113 114//////////////////////////////////////////// 115// 🚀 116//////////////////////////////////////////// 117 118foundation.ready();