tangled
alpha
login
or
join now
tokono.ma
/
diffuse
5
fork
atom
A music player that connects to your cloud/distributed storage.
5
fork
atom
overview
issues
4
pulls
pipelines
refactor: isPlaying + hasEnded audio signals
Steven Vandevelde
3 months ago
3f0c795b
1bf8226e
+22
-25
3 changed files
expand all
collapse all
unified
split
src
components
engine
audio
element.js
orchestrator
queue-audio
element.js
themes
blur
artwork-controller
element.js
+16
-21
src/components/engine/audio/element.js
···
30
30
#items = signal(/** @type {Audio[]} */ ([]));
31
31
#volume = signal(0.5);
32
32
33
33
-
$hasEnded = signal(false);
34
34
-
$isPlaying = signal(false);
35
35
-
36
33
// STATE
37
34
38
38
-
hasEnded = this.$hasEnded.get;
39
39
-
isPlaying = this.$isPlaying.get;
40
35
items = this.#items.get;
41
36
volume = this.#volume.get;
42
37
···
56
51
play: { strategy: "leaderOnly", fn: this.play },
57
52
seek: { strategy: "leaderOnly", fn: this.seek },
58
53
supply: { strategy: "replicate", fn: this.supply },
59
59
-
60
60
-
setHasEnded: { strategy: "replicate", fn: this.$hasEnded.set },
61
61
-
setIsPlaying: { strategy: "replicate", fn: this.$isPlaying.set },
62
54
},
63
55
);
64
56
···
68
60
this.play = actions.play;
69
61
this.seek = actions.seek;
70
62
this.supply = actions.supply;
71
71
-
72
72
-
this.$hasEnded.set = actions.setHasEnded;
73
73
-
this.$isPlaying.set = actions.setIsPlaying;
74
63
}
75
64
}
76
65
···
270
259
}
271
260
272
261
/**
262
262
+
* Convenience signal to track if something is, or was, playing.
263
263
+
*/
264
264
+
isPlaying() {
265
265
+
return computed(() => {
266
266
+
const item = this.items()?.[0];
267
267
+
if (!item) return false;
268
268
+
269
269
+
const state = this.state(item.id);
270
270
+
if (!state) return false;
271
271
+
272
272
+
return state.isPlaying() || state.hasEnded() || state.progress() === 1;
273
273
+
});
274
274
+
}
275
275
+
276
276
+
/**
273
277
* Get the state of a single audio item.
274
278
*
275
279
* @param {string} audioId
···
321
325
this.$state = {
322
326
duration: signal(0),
323
327
hasEnded: signal(false),
324
324
-
isPlaying: signal(true),
328
328
+
isPlaying: signal(false),
325
329
isPreload: signal(this.hasAttribute("preload")),
326
330
loadingState: signal(/** @type {LoadingState} */ ("loading")),
327
331
progress: signal(ip ? parseFloat(ip) : 0),
···
422
426
audio.currentTime = 0;
423
427
424
428
engineItem(audio)?.$state.hasEnded.set(true);
425
425
-
engineItem(audio)?.engine?.$hasEnded.set(true);
426
429
}
427
430
428
431
/**
···
440
443
*/
441
444
pauseEvent(event) {
442
445
const audio = /** @type {HTMLAudioElement} */ (event.target);
443
443
-
444
446
const item = engineItem(audio);
445
445
-
const itemState = item?.$state;
446
446
-
const ended = itemState
447
447
-
? itemState.hasEnded.value || itemState.progress.value === 1
448
448
-
: false;
449
447
450
448
item?.$state.isPlaying.set(false);
451
451
-
item?.engine?.$isPlaying.set(ended);
452
449
}
453
450
454
451
/**
···
460
457
const item = engineItem(audio);
461
458
item?.$state.hasEnded.set(false);
462
459
item?.$state.isPlaying.set(true);
463
463
-
item?.engine?.$hasEnded.set(false);
464
464
-
item?.engine?.$isPlaying.set(true);
465
460
466
461
// In case audio was preloaded:
467
462
if (audio.readyState === 4) finishedLoading(event);
+5
-2
src/components/orchestrator/queue-audio/element.js
···
50
50
if (!this.queue) return;
51
51
52
52
const activeTrack = this.queue.now();
53
53
-
const isPlaying = untracked(this.audio.isPlaying);
53
53
+
const isPlaying = untracked(this.audio.isPlaying());
54
54
55
55
// Resolve URIs
56
56
const resolvedUri = activeTrack
···
86
86
if (!this.audio) return;
87
87
if (!this.queue) return;
88
88
89
89
-
if (this.audio.hasEnded()) await this.queue.shift();
89
89
+
const now = this.queue.now();
90
90
+
const aud = now ? this.audio.state(now.id) : undefined;
91
91
+
92
92
+
if (aud?.hasEnded()) await this.queue.shift();
90
93
}
91
94
}
92
95
+1
-2
src/themes/blur/artwork-controller/element.js
···
76
76
});
77
77
78
78
#isPlaying = computed(() => {
79
79
-
return !!this.$queue.value?.now() &&
80
80
-
this.$audio.value?.isPlaying() === true;
79
79
+
return this.$audio.value?.isPlaying()();
81
80
});
82
81
83
82
// LIFECYCLE