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

feat: use output configurator in constituents

Changed files
+47 -24
src
common
constituents
components
output
polymorphic
indexed-db
transformer
output
string
json
themes
blur
artwork-controller
webamp
+13 -3
src/common/constituents/default.js
··· 1 import InputConfigurator from "@components/configurator/input/element.js"; 2 import Queue from "@components/engine/queue/element.js"; 3 import OpenSubsonic from "@components/input/opensubsonic/element.js"; 4 import S3 from "@components/input/s3/element.js"; ··· 32 33 // Output 34 const idb = new IndexedDBOutput(); 35 const json = new JsonStringOutput(); 36 - json.setAttribute("output-selector", idb.localName); 37 38 const refiner = new DefaultRefiner(); 39 refiner.setAttribute("id", "output"); 40 - refiner.setAttribute("output-selector", json.localName); 41 42 - document.body.append(idb, json, refiner); 43 44 // Orchestrators 45 const oqt = new QueueTracksOrchestrator(); ··· 68 69 configurator: { 70 input, 71 }, 72 engine: { 73 queue,
··· 1 import InputConfigurator from "@components/configurator/input/element.js"; 2 + import OutputConfigurator from "@components/configurator/output/element.js"; 3 import Queue from "@components/engine/queue/element.js"; 4 import OpenSubsonic from "@components/input/opensubsonic/element.js"; 5 import S3 from "@components/input/s3/element.js"; ··· 33 34 // Output 35 const idb = new IndexedDBOutput(); 36 + idb.setAttribute("id", "idb-json-output") 37 + idb.setAttribute("namespace", "json") 38 + 39 const json = new JsonStringOutput(); 40 + json.setAttribute("id", "idb-json") 41 + json.setAttribute("output-selector", "#idb-json-output"); 42 + 43 + const output = new OutputConfigurator(); 44 + output.setAttribute("default", "idb-json"); 45 + output.append(json); 46 47 const refiner = new DefaultRefiner(); 48 refiner.setAttribute("id", "output"); 49 + refiner.setAttribute("output-selector", output.localName); 50 51 + document.body.append(idb, output, refiner); 52 53 // Orchestrators 54 const oqt = new QueueTracksOrchestrator(); ··· 77 78 configurator: { 79 input, 80 + output, 81 }, 82 engine: { 83 queue,
+4
src/common/element.js
··· 20 * around rendering and managing signals. 21 */ 22 export class DiffuseElement extends HTMLElement { 23 #connected = Promise.withResolvers(); 24 #disposables = /** @type {Array<() => void>} */ ([]); 25 ··· 98 // LIFECYCLE 99 100 connectedCallback() { 101 this.#connected.resolve(null); 102 103 if (!("render" in this && typeof this.render === "function")) return; ··· 109 } 110 111 disconnectedCallback() { 112 this.#teardown(); 113 } 114
··· 20 * around rendering and managing signals. 21 */ 22 export class DiffuseElement extends HTMLElement { 23 + $connected = signal(false) 24 + 25 #connected = Promise.withResolvers(); 26 #disposables = /** @type {Array<() => void>} */ ([]); 27 ··· 100 // LIFECYCLE 101 102 connectedCallback() { 103 + this.$connected.value = true 104 this.#connected.resolve(null); 105 106 if (!("render" in this && typeof this.render === "function")) return; ··· 112 } 113 114 disconnectedCallback() { 115 + this.$connected.value = false 116 this.#teardown(); 117 } 118
+2 -2
src/components/output/common.js
··· 1 - import { signal } from "@common/signal.js"; 2 3 /** 4 * @import {OutputManager, OutputManagerProperties} from "./types.d.ts" ··· 19 ts.value = "loaded"; 20 } 21 22 - loadTracks(); 23 24 return { 25 tracks: {
··· 1 + import { effect, signal } from "@common/signal.js"; 2 3 /** 4 * @import {OutputManager, OutputManagerProperties} from "./types.d.ts" ··· 19 ts.value = "loaded"; 20 } 21 22 + effect(loadTracks); 23 24 return { 25 tracks: {
+10 -2
src/components/output/polymorphic/indexed-db/element.js
··· 28 const manager = outputManager({ 29 tracks: { 30 empty: () => undefined, 31 - get: () => p.get({ name: this.#cat("tracks") }), 32 - put: (data) => p.put({ name: this.#cat("tracks"), data }), 33 }, 34 }); 35 36 this.tracks = manager.tracks; 37 } 38 39 /** @param {string} name */ 40 #cat(name) {
··· 28 const manager = outputManager({ 29 tracks: { 30 empty: () => undefined, 31 + get: () => { 32 + if (!this.$connected.value) return undefined 33 + return p.get({ name: this.#cat("tracks") }) 34 + }, 35 + put: (data) => { 36 + if (!this.$connected.value) return 37 + return p.put({ name: this.#cat("tracks"), data }) 38 + }, 39 }, 40 }); 41 42 this.tracks = manager.tracks; 43 } 44 + 45 + // 🛠️ 46 47 /** @param {string} name */ 48 #cat(name) {
+3 -3
src/components/transformer/output/base.js
··· 54 await this.output.whenDefined; 55 await this.output.signal()?.tracks.save(newTracks); 56 }, 57 - state: computed(() => 58 - this.output.signal()?.tracks.state() ?? "loading" 59 - ), 60 }, 61 }; 62
··· 54 await this.output.whenDefined; 55 await this.output.signal()?.tracks.save(newTracks); 56 }, 57 + state: computed(() => { 58 + return this.output.signal()?.tracks.state() ?? "loading" 59 + }), 60 }, 61 }; 62
+2 -1
src/components/transformer/output/string/json/element.js
··· 20 tracks: { 21 ...base.tracks, 22 collection: computed(() => { 23 - const json = base.tracks.collection() ?? "[]"; 24 25 // Try parsing JSON 26 try {
··· 20 tracks: { 21 ...base.tracks, 22 collection: computed(() => { 23 + let json = base.tracks.collection(); 24 + if (typeof json !== "string") json = "[]" 25 26 // Try parsing JSON 27 try {
+3
src/themes/blur/artwork-controller/element.css
··· 1 :host { 2 --transition-durition: 750ms; 3 }
··· 1 + @import "../../../styles/vendor/phosphor/fill/style.css"; 2 + @import "../../../styles/animations.css"; 3 + 4 :host { 5 --transition-durition: 750ms; 6 }
+2 -5
src/themes/blur/artwork-controller/element.js
··· 121 122 this.effect(() => { 123 const now = !!queue.now(); 124 - const bool = !now || 125 - (now && this.#audio()?.loadingState() !== "loaded"); 126 127 if (this.#isLoadingTimeout) { 128 clearTimeout(this.#isLoadingTimeout); ··· 398 399 return html` 400 <style> 401 - @import "../../../styles/vendor/phosphor/fill/style.css"; 402 - @import "../../../styles/animations.css"; 403 - @import "./element.css"; 404 </style> 405 406 <main style="background-color: ${this.#artworkColor.value ??
··· 121 122 this.effect(() => { 123 const now = !!queue.now(); 124 + const bool = (now && this.#audio()?.loadingState() !== "loaded"); 125 126 if (this.#isLoadingTimeout) { 127 clearTimeout(this.#isLoadingTimeout); ··· 397 398 return html` 399 <style> 400 + @import "${import.meta.resolve('./element.css')}"; 401 </style> 402 403 <main style="background-color: ${this.#artworkColor.value ??
+7 -7
src/themes/blur/artwork-controller/index.vto
··· 3 base: ../../../ 4 5 styles: 6 - - ../../../styles/vendor/phosphor/fill/style.css 7 - - ../../../styles/base.css 8 --- 9 10 <!-- ELEMENTS --> ··· 23 <!-- SCRIPTS --> 24 25 <script type="module"> 26 - import { config } from "../../../common/constituents/default.js" 27 - import QueueAudioOrchestrator from "../../../components/orchestrator/queue-audio/element.js"; 28 29 - import "../../../components/engine/audio/element.js" 30 - import "../../../components/processor/artwork/element.js" 31 32 // Prepare default constituents setup 33 const defaults = config() 34 35 // Only then initiate artwork controller 36 - import("./element.js") 37 38 // Orchestrators 39
··· 3 base: ../../../ 4 5 styles: 6 + - styles/vendor/phosphor/fill/style.css 7 + - styles/base.css 8 --- 9 10 <!-- ELEMENTS --> ··· 23 <!-- SCRIPTS --> 24 25 <script type="module"> 26 + import { config } from "./common/constituents/default.js" 27 + import QueueAudioOrchestrator from "./components/orchestrator/queue-audio/element.js"; 28 29 + import "./components/engine/audio/element.js" 30 + import "./components/processor/artwork/element.js" 31 32 // Prepare default constituents setup 33 const defaults = config() 34 35 // Only then initiate artwork controller 36 + import("./themes/blur/artwork-controller/element.js") 37 38 // Orchestrators 39
+1 -1
src/themes/webamp/index.js
··· 1 import "@components/configurator/output/element.js"; 2 import "@components/input/opensubsonic/element.js"; 3 import "@components/input/s3/element.js"; 4 - // import "@components/orchestrator/process-tracks/element.js"; 5 import "@components/orchestrator/queue-tracks/element.js"; 6 import "@components/output/polymorphic/indexed-db/element.js"; 7 import "@components/processor/metadata/element.js";
··· 1 import "@components/configurator/output/element.js"; 2 import "@components/input/opensubsonic/element.js"; 3 import "@components/input/s3/element.js"; 4 + import "@components/orchestrator/process-tracks/element.js"; 5 import "@components/orchestrator/queue-tracks/element.js"; 6 import "@components/output/polymorphic/indexed-db/element.js"; 7 import "@components/processor/metadata/element.js";