Experiment to rebuild Diffuse using web applets.
1import Webamp from "webamp";
2import { URLTrack } from "webamp";
3
4import type { Output, Track } from "@applets/core/types.d.ts";
5import { applet, waitUntilAppletIsReady } from "../../theme.ts";
6
7////////////////////////////////////////////
8// 🎨 Styles
9////////////////////////////////////////////
10import "@styles/themes/webamp/index.css";
11
12////////////////////////////////////////////
13// 🗂️ Applets
14////////////////////////////////////////////
15
16const configurator = {
17 input: await applet("../../configurator/input"),
18};
19
20const orchestrator = {
21 output: await applet<Output>("../../orchestrator/output-management"),
22
23 // TODO: Should this be explicitely be ran after the output orchestrator is loaded?
24 input: await applet("../../orchestrator/input-cache"),
25};
26
27////////////////////////////////////////////
28// ⚡
29////////////////////////////////////////////
30const amp = new Webamp({
31 initialTracks: [],
32});
33
34const ampNode = document.createElement("div");
35ampNode.style = "height: 100vh; left: 0; position: absolute; top: 0; width: 100%; z-index: -1000;";
36document.body.appendChild(ampNode);
37amp.renderWhenReady(ampNode);
38
39orchestrator.output.ondata = async () => {
40 const tracks = await loadTracks();
41 amp.setTracksToPlay([]);
42 amp.appendTracks(tracks);
43 amp.nextTrack();
44};
45
46////////////////////////////////////////////
47// 🛠️
48////////////////////////////////////////////
49async function loadTracks(): Promise<URLTrack[]> {
50 return await orchestrator.output.data.tracks.reduce(
51 async (promise: Promise<URLTrack[]>, track: Track) => {
52 const acc = await promise;
53
54 // TODO: Ideally the URL should only be resolved when needed,
55 // but webamp doesn't allow for that.
56 // Maybe you could work around it with a service worker.
57 const url = await configurator.input.sendAction<string | undefined>("resolve", track.uri, {
58 timeoutDuration: 60000,
59 });
60
61 if (!url) return acc;
62
63 const urlTrack: URLTrack = {
64 url,
65 metaData: {
66 title: track.tags?.title || "",
67 artist: track.tags?.artist || "",
68 album: track.tags?.album,
69 },
70 duration: track.stats?.duration,
71 };
72
73 return [...acc, urlTrack];
74 },
75 Promise.resolve([]),
76 );
77}