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

Configure Feed

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

at v4 76 lines 1.8 kB view raw
1import { BroadcastableDiffuseElement, defineElement } from "~/common/element.js"; 2import { effect, signal } from "~/common/signal.js"; 3import foundation from "~/common/foundation.js"; 4 5 6/** 7 * @import {ScrobbleElement} from "~/components/supplement/types.d.ts" 8 * @import {Track} from "~/definitions/types.d.ts" 9 */ 10 11let initialised = false; 12 13effect(() => { 14 const audio = foundation.signals.engine.audio(); 15 if (!audio) return; 16 17 if (!initialised) { 18 setupScrobbler(); 19 initialised = true; 20 } 21}); 22 23/** 24 * Pretend we're a scrobbler and cache tracks whenever they are "scrobbled" 25 */ 26async function setupScrobbler() { 27 await foundation.orchestrator.scrobbleAudio(); 28 await customElements.whenDefined("dct-scrobbler"); 29 30 const s = new PretendScrobbler(); 31 s.setAttribute("group", foundation.GROUP); 32 33 const c = await foundation.configurator.scrobbles(); 34 c.append(s); 35} 36 37/** 38 * @implements {ScrobbleElement} 39 */ 40class PretendScrobbler extends BroadcastableDiffuseElement { 41 isAuthenticated = signal(true).get; 42 isAuthenticating = signal(false).get; 43 handle = signal(null).get; 44 45 async nowPlaying() {} 46 47 /** 48 * @param {Track} track 49 */ 50 async scrobble(track) { 51 const i = await foundation.configurator.input(); 52 await i.cache([track.uri]); 53 } 54 55 // LIFECYCLE 56 57 /** @override */ 58 connectedCallback() { 59 // Broadcast if needed 60 if (this.hasAttribute("group")) { 61 const actions = this.broadcast(this.identifier, { 62 nowPlaying: { strategy: "leaderOnly", fn: this.nowPlaying }, 63 scrobble: { strategy: "leaderOnly", fn: this.scrobble }, 64 }); 65 66 if (actions) { 67 this.nowPlaying = actions.nowPlaying; 68 this.scrobble = actions.scrobble; 69 } 70 } 71 72 super.connectedCallback(); 73 } 74} 75 76defineElement("dct-scrobbler", PretendScrobbler);