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.

feat: default constituents config

+105 -57
+61
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"; 5 + import QueueTracksOrchestrator from "@components/orchestrator/queue-tracks/element.js"; 6 + import IndexedDBOutput from "@components/output/polymorphic/indexed-db/element.js"; 7 + import DefaultRefiner from "@components/transformer/output/refiner/default/element.js"; 8 + import JsonStringOutput from "@components/transformer/output/string/json/element.js"; 9 + import { effect } from "../signal.js"; 10 + 11 + export const GROUP = "constituents"; 12 + 13 + /** 14 + * Default config for constituents. 15 + */ 16 + export function config() { 17 + // Input 18 + const openSubsonic = new OpenSubsonic(); 19 + const s3 = new S3(); 20 + 21 + const input = new InputConfigurator(); 22 + input.setAttribute("id", "input"); 23 + input.append(openSubsonic, s3); 24 + 25 + document.body.append(input); 26 + 27 + // Queue 28 + const queue = new Queue(); 29 + queue.setAttribute("group", GROUP); 30 + 31 + document.body.append(queue); 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(); 46 + oqt.setAttribute("group", GROUP); 47 + oqt.setAttribute("input-selector", "#input"); 48 + oqt.setAttribute("output-selector", "#output"); 49 + oqt.setAttribute("queue-engine-selector", queue.localName); 50 + 51 + document.body.append(oqt); 52 + 53 + // Signals & effects 54 + effect(() => { 55 + const trigger = queue.now(); 56 + const _other_trigger = queue.poolHash(); 57 + 58 + queue.fill({ amount: 10, shuffled: true }); 59 + if (!trigger) queue.shift(); 60 + }); 61 + }
+3
src/common/constituents/default/config.js
··· 1 + import { config } from "../default.js"; 2 + 3 + config();
+6 -2
src/common/element.js
··· 67 67 state: "state" in this ? this.state : undefined, 68 68 }); 69 69 70 - const root = this.shadowRoot ? this.shadowRoot : this; 71 - render(tmp, root); 70 + render(tmp, this.root()); 72 71 } 73 72 74 73 /** */ 75 74 forceRender() { 76 75 return this.#render(); 76 + } 77 + 78 + /** */ 79 + root() { 80 + return (this.shadowRoot ?? this); 77 81 } 78 82 79 83 // LIFECYCLE
+8 -2
src/components/configurator/input/element.js
··· 42 42 */ 43 43 createWorker() { 44 44 const worker = super.createWorker(); 45 - this.configureWorker(worker); 45 + 46 + // Wait for child elements to be rendered 47 + setTimeout(() => this.configureWorker(worker), 0); 48 + 46 49 return worker; 47 50 } 48 51 ··· 54 57 async configureWorker(worker) { 55 58 const inputs = await this.inputTunnels(); 56 59 60 + // Check if any inputs are present 61 + if (inputs.length === 0) return; 62 + 57 63 // Configure worker with input ports 58 64 const args = transfer({ 59 65 ports: Object.fromEntries(inputs.map((input) => { ··· 67 73 } 68 74 69 75 async inputTunnels() { 70 - const inputElements = this.querySelectorAll(":scope > *"); 76 + const inputElements = this.children; 71 77 const inputs = await Array.from(inputElements).reduce( 72 78 /** 73 79 * @param {Promise<Array<Input>>} acc
+17 -23
src/themes/blur/artwork-controller/element.js
··· 11 11 * @import {RenderArg} from "@common/element.d.ts" 12 12 * @import {Track} from "@definitions/types.d.ts" 13 13 * @import {InputElement} from "@components/input/types.d.ts" 14 - * @import {OutputElement} from "@components/output/types.d.ts" 15 14 * @import {Artwork} from "@components/processor/artwork/types.d.ts" 16 15 */ 17 16 18 17 class ArtworkController extends DiffuseElement { 19 - // constructor() { 20 - // super(); 21 - // this.attachShadow({ mode: "open" }); 22 - // } 18 + constructor() { 19 + super(); 20 + this.attachShadow({ mode: "open" }); 21 + } 23 22 24 23 // SIGNALS 25 24 ··· 70 69 debouncedChangeArtwork(queue.now()); 71 70 }); 72 71 73 - this.effect(() => { 74 - const trigger = queue.now(); 75 - const _other_trigger = queue.poolHash(); 76 - 77 - queue.fill({ amount: 10, shuffled: true }); 78 - if (!trigger) queue.shift(); 79 - }); 80 - 81 72 // Force render when elements are defined 82 73 83 74 // this.effect(() => { ··· 138 129 139 130 // No artwork, fade out existing. 140 131 if (art.length === 0) { 141 - this.querySelectorAll(":scope .artwork img").forEach((el) => { 132 + this.root().querySelectorAll(".artwork img").forEach((el) => { 142 133 const element = /** @type {HTMLElement} */ (el); 143 134 element.style.opacity = "0"; 144 135 const hash = element.getAttribute("data-hash"); ··· 151 142 const hash = xxh32r(art[0].bytes).toString(); 152 143 153 144 /** @type {HTMLImageElement | null} */ 154 - const existingArtwork = this.querySelector( 155 - `:scope .artwork img[data-hash="${hash}"]`, 145 + const existingArtwork = this.root().querySelector( 146 + `.artwork img[data-hash="${hash}"]`, 156 147 ); 157 148 158 149 // If the artwork is the same, stop here. ··· 188 179 this.#artworkLightMode.value = o > 165; 189 180 190 181 /** @type {HTMLElement | null} */ 191 - const bg = this.querySelector(":scope .controller__background"); 182 + const bg = this.root().querySelector(".controller__background"); 192 183 if (bg) bg.style.backgroundColor = color.rgba; 193 184 194 185 /** @type {HTMLElement | null} */ 195 - const main = this.querySelector(":scope main"); 186 + const main = this.root().querySelector("main"); 196 187 if (main) main.style.backgroundColor = color.rgba; 197 188 198 189 img.style.opacity = "1"; 199 190 200 - this.querySelectorAll(":scope .artwork img").forEach((el) => { 191 + this.root().querySelectorAll(".artwork img").forEach((el) => { 201 192 if (el === img) return; 202 193 203 194 const element = /** @type {HTMLElement} */ (el); ··· 207 198 }; 208 199 209 200 // Insert new artwork 210 - this.querySelector(":scope .artwork")?.appendChild(img); 201 + this.root().querySelector(".artwork")?.appendChild(img); 211 202 }); 212 203 213 204 this.effect(() => { 214 - // if (artworkLightMode()) { 215 - // controller.classList.add("controller__inner--light-mode"); 216 - // } else controller.classList.remove("controller__inner--light-mode"); 205 + const controller = this.root().querySelector(".controller__inner"); 206 + if (!controller) return; 207 + 208 + if (this.#artworkLightMode.value) { 209 + controller.classList.add("controller__inner--light-mode"); 210 + } else controller.classList.remove("controller__inner--light-mode"); 217 211 }); 218 212 } 219 213
+10 -30
src/themes/blur/artwork-controller/index.vto
··· 4 4 5 5 styles: 6 6 - ../../../styles/base.css 7 - 8 - scripts: 9 - - element.js 10 7 --- 11 8 12 9 <!-- ELEMENTS --> 13 10 14 11 <de-audio group="constituents"></de-audio> 15 - <de-queue group="constituents"></de-queue> 16 - 17 - <do-queue-tracks 18 - input-selector="dc-input" 19 - output-selector="#output" 20 - queue-engine-selector="de-queue" 21 - ></do-queue-tracks> 22 - 23 12 <dp-artwork></dp-artwork> 24 - 25 - <dtor-default id="output" output-selector="dtos-json"></dtor-default> 26 - <dtos-json output-selector="dop-indexed-db"></dtos-json> 27 - <dop-indexed-db></dop-indexed-db> 28 - 29 - <dc-input> 30 - <di-opensubsonic></di-opensubsonic> 31 - <di-s3></di-s3> 32 - </dc-input> 33 13 34 14 <db-artwork-controller 35 15 artwork-processor-selector="dp-artwork" 36 - audio-engine-selector="de-queue" 37 - input-selector="dc-input" 16 + audio-engine-selector="de-audio" 17 + input-selector="#input" 38 18 queue-engine-selector="de-queue" 39 19 > 40 20 </db-artwork-controller> ··· 42 22 <!-- SCRIPTS --> 43 23 44 24 <script type="module"> 45 - import "../../../components/configurator/input/element.js" 25 + import { config } from "../../../common/constituents/default.js" 26 + 46 27 import "../../../components/engine/audio/element.js" 47 - import "../../../components/engine/queue/element.js" 48 - import "../../../components/input/opensubsonic/element.js" 49 - import "../../../components/input/s3/element.js" 50 - import "../../../components/orchestrator/queue-tracks/element.js" 51 - import "../../../components/output/polymorphic/indexed-db/element.js" 52 28 import "../../../components/processor/artwork/element.js" 53 - import "../../../components/transformer/output/refiner/default/element.js" 54 - import "../../../components/transformer/output/string/json/element.js" 29 + 30 + // Prepare default constituents setup 31 + config() 32 + 33 + // Only then initiate artwork controller 34 + import("./element.js") 55 35 </script>