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: add .ready signal to output elements

+47 -15
+14 -4
src/components/configurator/output/element.js
··· 213 213 214 214 selectedOutput = computed(() => this.#selectedOutput.value ?? null); 215 215 216 + ready = computed(() => { 217 + const out = this.#selectedOutput.value; 218 + if (out) return out.ready(); 219 + 220 + const def = this.#defaultOutput.value; 221 + if (def) return def.ready(); 222 + 223 + return this.#setupFinished.value; 224 + }); 225 + 216 226 // LIFECYCLE 217 227 218 228 /** ··· 283 293 return [[d.id, d]]; 284 294 }), 285 295 ); 286 - } 296 + }; 287 297 288 298 // ADDITIONAL ACTIONS 289 299 290 300 deselect = async () => { 291 301 localStorage.removeItem(`${STORAGE_PREFIX}/selected/id`); 292 302 this.#selectedOutput.value = await this.#findSelectedOutput(); 293 - } 303 + }; 294 304 295 305 options = async () => { 296 306 const deps = this.dependencies(); ··· 307 317 element: /** @type {OutputElement} */ (v), 308 318 }; 309 319 }); 310 - } 320 + }; 311 321 312 322 /** 313 323 * @param {string} id ··· 315 325 select = async (id) => { 316 326 localStorage.setItem(`${STORAGE_PREFIX}/selected/id`, id); 317 327 this.#selectedOutput.value = await this.#findSelectedOutput(); 318 - } 328 + }; 319 329 } 320 330 321 331 export default OutputConfigurator;
+4
src/components/orchestrator/output/element.js
··· 67 67 return this.output.tracks; 68 68 } 69 69 70 + get ready() { 71 + return this.output.ready; 72 + } 73 + 70 74 // PROXY ADDITIONAL OUTPUT CONFIGURATOR ACTIONS 71 75 72 76 get deselect() {
+1
src/components/output/bytes/automerge-repo-server/element.js
··· 96 96 this.playlists = this.#manager.playlists; 97 97 this.themes = this.#manager.themes; 98 98 this.tracks = this.#manager.tracks; 99 + this.ready = () => true; 99 100 } 100 101 101 102 // LIFECYCLE
+11 -5
src/components/output/bytes/s3/element.js
··· 1 1 import { BroadcastableDiffuseElement } from "@common/element.js"; 2 + import { computed, signal } from "@common/signal.js"; 2 3 import { outputManager } from "../../common.js"; 3 4 4 5 /** ··· 58 59 this.tracks = this.#manager.tracks; 59 60 } 60 61 62 + // STATE 63 + 64 + ready = computed(() => { 65 + return this.#bucketSignal.value !== undefined 66 + }); 67 + 61 68 // LIFECYCLE 62 69 63 70 /** ··· 85 92 * @param {Bucket} bucket 86 93 */ 87 94 setBucket(bucket) { 88 - this.#bucketValue = bucket; 95 + this.#bucketSignal.value = bucket; 89 96 } 90 97 91 - /** @type {Bucket | undefined} */ 92 - #bucketValue; 98 + #bucketSignal = signal(/** @type {Bucket | undefined} */ (undefined)); 93 99 94 100 /** @returns {Bucket} */ 95 101 #bucket() { 96 - if (!this.#bucketValue) { 102 + if (!this.#bucketSignal.value) { 97 103 throw new Error("Bucket not set, call setBucket() first."); 98 104 } 99 - return this.#bucketValue; 105 + return this.#bucketSignal.value; 100 106 } 101 107 102 108 // GET & PUT
+1
src/components/output/polymorphic/indexed-db/element.js
··· 55 55 this.playlists = this.#manager.playlists; 56 56 this.themes = this.#manager.themes; 57 57 this.tracks = this.#manager.tracks; 58 + this.ready = () => true; 58 59 } 59 60 60 61 // LIFECYCLE
+6 -2
src/components/output/raw/atproto/element.js
··· 1 1 import { Client, ok } from "@atcute/client"; 2 2 import { BroadcastableDiffuseElement } from "@common/element.js"; 3 - import { signal } from "@common/signal.js"; 3 + import { computed, signal } from "@common/signal.js"; 4 4 import { outputManager } from "../../common.js"; 5 5 import { login, logout, OAuthUserAgent, restoreOrFinalize } from "./oauth.js"; 6 6 7 7 /** 8 8 * @import {Signal} from "@common/signal.d.ts" 9 - * @import {OutputElement, OutputManager} from "../../types.d.ts" 9 + * @import {OutputManager} from "../../types.d.ts" 10 10 * @import {ATProtoOutputElement} from "./types.d.ts" 11 11 */ 12 12 ··· 71 71 // STATE 72 72 73 73 did = this.#did.get; 74 + 75 + ready = computed(() => { 76 + return this.#did.value !== null && navigator.onLine 77 + }); 74 78 75 79 // LIFECYCLE 76 80
+3 -4
src/components/output/types.d.ts
··· 6 6 & DiffuseElement 7 7 & OutputManagerDeputy<Encoding>; 8 8 9 - export type OutputManagerDeputy<Encoding = null> = Omit< 10 - OutputManager<Encoding>, 11 - "signals" 12 - >; 9 + export type OutputManagerDeputy<Encoding = null> = 10 + & Omit<OutputManager<Encoding>, "signals"> 11 + & { ready: SignalReader<boolean> }; 13 12 14 13 export type OutputManager<Encoding = null> = { 15 14 facets: {
+3
src/components/transformer/output/base.js
··· 109 109 return this.output.signal()?.tracks.state() ?? "sleeping"; 110 110 }), 111 111 }, 112 + 113 + // Other non-data related state 114 + ready: computed(() => this.output.signal()?.ready() ?? false), 112 115 }; 113 116 114 117 return m;
+1
src/components/transformer/output/bytes/automerge/element.js
··· 155 155 this.playlists = manager.playlists; 156 156 this.themes = manager.themes; 157 157 this.tracks = manager.tracks; 158 + this.ready = base.ready; 158 159 } 159 160 } 160 161
+1
src/components/transformer/output/bytes/json/element.js
··· 84 84 this.playlists = manager.playlists; 85 85 this.themes = manager.themes; 86 86 this.tracks = manager.tracks; 87 + this.ready = base.ready; 87 88 } 88 89 } 89 90
+1
src/components/transformer/output/refiner/default/element.js
··· 51 51 this.playlists = manager.playlists; 52 52 this.themes = manager.themes; 53 53 this.tracks = manager.tracks; 54 + this.ready = base.ready; 54 55 } 55 56 } 56 57
+1
src/components/transformer/output/string/json/element.js
··· 67 67 this.playlists = manager.playlists; 68 68 this.themes = manager.themes; 69 69 this.tracks = manager.tracks; 70 + this.ready = base.ready; 70 71 } 71 72 } 72 73