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: improve diffuse element

+89 -69
+18 -10
src/common/element.js
··· 6 6 */ 7 7 8 8 export default class DiffuseElement extends HTMLElement { 9 - #teardown = () => {}; 9 + #disposables = /** @type {Array<() => void>} */ ([]); 10 + 11 + #teardown() { 12 + this.#disposables.forEach((fn) => fn()); 13 + } 10 14 11 15 constructor() { 12 16 super(); 13 - this.process = this.process.bind(this); 17 + this.morphedRender = this.morphedRender.bind(this); 14 18 } 15 19 16 - process() { 20 + morphedRender() { 17 21 if (!("render" in this && typeof this.render === "function")) return; 18 22 if (!("state" in this)) return; 19 23 ··· 26 30 updated.innerHTML = tmp.trim(); 27 31 const root = this.shadowRoot ? this.shadowRoot : this; 28 32 29 - /** @type {Node} */ 30 - const result = morphdom( 33 + morphdom( 31 34 root, 32 35 updated, 33 36 { 34 37 childrenOnly: true, 35 38 }, 36 39 ); 37 - 38 - return result; 39 40 } 40 41 41 42 /** ··· 44 45 * @param {string} newValue 45 46 */ 46 47 attributeChangedCallback(_name, oldValue, newValue) { 47 - if (oldValue !== newValue) this.process(); 48 + if (oldValue !== newValue) this.morphedRender(); 49 + } 50 + 51 + /** 52 + * @param {() => void} fn 53 + */ 54 + effect(fn) { 55 + this.#disposables.push(effect(fn)); 48 56 } 49 57 50 58 /** ··· 59 67 connectedCallback() { 60 68 if (!("render" in this && typeof this.render === "function")) return; 61 69 62 - this.#teardown = effect(() => { 70 + this.effect(() => { 63 71 if (!("render" in this && typeof this.render === "function")) return; 64 72 if (!("state" in this)) return; 65 73 66 - this.innerHTML = this.render({ html: this.html, state: this.state }); 74 + this.morphedRender(); 67 75 }); 68 76 } 69 77
src/elements/constituent/blur/browser-list.d.ts src/elements/constituent/blur/browser-list/types.d.ts
-58
src/elements/constituent/blur/browser-list.js
··· 1 - import DiffuseElement from "@common/element.js"; 2 - import { signal } from "@common/signals.js"; 3 - 4 - /** 5 - * @import {RenderArg} from "@common/element.d.ts" 6 - * @import {Track} from "@elements/core/types.d.ts" 7 - * 8 - * @import {State} from "./browser-list.d.ts" 9 - */ 10 - 11 - //////////////////////////////////////////////// 12 - // ELEMENT 13 - //////////////////////////////////////////////// 14 - 15 - class List extends DiffuseElement { 16 - tracks = signal(/** @type {Track[]} */ ([])); 17 - 18 - // STATE 19 - 20 - get state() { 21 - return { 22 - tracks: this.tracks, 23 - }; 24 - } 25 - 26 - // RENDER 27 - 28 - /** 29 - * @param {RenderArg<State>} _ 30 - */ 31 - render({ html, state }) { 32 - console.log("Rendering", state.tracks()); 33 - 34 - const list = state.tracks().map((t) => 35 - html` 36 - <div id="track-${t.id}">${t}</div> 37 - ` 38 - ); 39 - 40 - return html` 41 - <style> 42 - :host { 43 - color: blue; 44 - } 45 - </style> 46 - <section>${list.join("")}</section> 47 - `; 48 - } 49 - } 50 - 51 - export { List as ConstituentBlurBrowserList }; 52 - export default List; 53 - 54 - //////////////////////////////////////////////// 55 - // REGISTER 56 - //////////////////////////////////////////////// 57 - 58 - customElements.define("constituent-blur-browser-list", List);
+70
src/elements/constituent/blur/browser-list/index.js
··· 1 + import DiffuseElement from "@common/element.js"; 2 + import { signal } from "@common/signals.js"; 3 + 4 + /** 5 + * @import {RenderArg} from "@common/element.d.ts" 6 + * @import {Track} from "@elements/core/types.d.ts" 7 + * 8 + * @import {State} from "./types.d.ts" 9 + */ 10 + 11 + //////////////////////////////////////////// 12 + // ELEMENT 13 + //////////////////////////////////////////// 14 + 15 + class BrowserList extends DiffuseElement { 16 + tracks = signal(/** @type {Track[]} */ ([])); 17 + 18 + // STATE 19 + 20 + get state() { 21 + return { 22 + tracks: this.tracks, 23 + }; 24 + } 25 + 26 + // LIFECYCLE 27 + 28 + /** 29 + * @override 30 + * 31 + * TODO: Remove, just an example. 32 + */ 33 + connectedCallback() { 34 + super.connectedCallback(); 35 + this.effect(() => {}); 36 + } 37 + 38 + // RENDER 39 + 40 + /** 41 + * @param {RenderArg<State>} _ 42 + */ 43 + render({ html, state }) { 44 + console.log("Rendering", state.tracks()); 45 + 46 + const list = state.tracks().map((t, idx) => 47 + html` 48 + <div id="track-${idx}">${t}</div> 49 + ` 50 + ); 51 + 52 + return html` 53 + <style> 54 + :host { 55 + color: blue; 56 + } 57 + </style> 58 + <section>${list.join("")}</section> 59 + `; 60 + } 61 + } 62 + 63 + export { BrowserList as ConstituentBlurBrowserList }; 64 + export default BrowserList; 65 + 66 + //////////////////////////////////////////// 67 + // REGISTER 68 + //////////////////////////////////////////// 69 + 70 + customElements.define("constituent-blur-browser-list", BrowserList);
+1 -1
src/theme/blur/index.vto
··· 4 4 <link rel="stylesheet" href="../../styles/theme/blur/index.css" /> 5 5 6 6 <script type="module"> 7 - import "../../elements/constituent/blur/browser-list.js"; 7 + import "../../elements/constituent/blur/browser-list/index.js"; 8 8 </script> 9 9 </head> 10 10 <body>