forked from
tokono.ma/diffuse
A music player that connects to your cloud/distributed storage.
1import { defineElement, DiffuseElement, query, whenElementsDefined } from "~/common/element.js";
2import { computed, signal } from "~/common/signal.js";
3
4/**
5 * @import {OutputElement} from "~/components/output/types.d.ts"
6 * @import AudioEngine from "~/components/engine/audio/element.js"
7 * @import QueueEngine from "~/components/engine/queue/element.js"
8 */
9
10////////////////////////////////////////////
11// ELEMENT
12////////////////////////////////////////////
13
14/**
15 * Provides commonly used computed signals derived from the audio engine,
16 * queue engine, and output — so theme elements don't need to re-implement them.
17 */
18class ControllerOrchestrator extends DiffuseElement {
19 static NAME = "diffuse/orchestrator/controller";
20
21 // SIGNALS - DEPENDENCIES
22
23 $audio = signal(/** @type {AudioEngine | undefined} */ (undefined));
24 $output = signal(/** @type {OutputElement | undefined} */ (undefined));
25 $queue = signal(/** @type {QueueEngine | undefined} */ (undefined));
26
27 // SIGNALS - COMPUTED
28
29 audio = computed(() => {
30 const curr = this.$queue.value?.now();
31 return curr ? this.$audio.value?.state(curr.id) : undefined;
32 });
33
34 currentTrack = computed(() => {
35 const item = this.$queue.value?.now();
36 if (!item) return undefined;
37 const col = this.$output.value?.tracks.collection();
38 if (!col || col.state !== "loaded") return undefined;
39 return col.data.find((t) => t.id === item.id);
40 });
41
42 isPlaying = computed(() => {
43 return this.$audio.value?.isPlaying();
44 });
45
46 // LIFECYCLE
47
48 /**
49 * @override
50 */
51 connectedCallback() {
52 super.connectedCallback();
53
54 /** @type {AudioEngine} */
55 const audio = query(this, "audio-engine-selector");
56
57 /** @type {OutputElement} */
58 const output = query(this, "output-selector");
59
60 /** @type {QueueEngine} */
61 const queue = query(this, "queue-engine-selector");
62
63 whenElementsDefined({ audio, output, queue }).then(() => {
64 this.$audio.value = audio;
65 this.$output.value = output;
66 this.$queue.value = queue;
67 });
68 }
69}
70
71export default ControllerOrchestrator;
72
73////////////////////////////////////////////
74// REGISTER
75////////////////////////////////////////////
76
77export const CLASS = ControllerOrchestrator;
78export const NAME = "do-controller";
79
80defineElement(NAME, CLASS);