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