A music player that connects to your cloud/distributed storage.
5
fork

Configure Feed

Select the types of activity you want to include in your feed.

chore: simplify webamp setup

+15 -64
-2
src/components/configurator/input/worker.js
··· 60 60 Object.keys(groups).map(async (scheme) => { 61 61 const input = grabInput(scheme, ports); 62 62 63 - console.log("🔮", scheme); 64 - 65 63 if (!input) { 66 64 return { 67 65 [scheme]: {
+1 -1
src/components/processor/search/element.js
··· 30 30 31 31 // SIGNALS 32 32 33 - #cacheId = signal(/** @type {string} */ ("")); 33 + #cacheId = signal(/** @type {string | undefined} */ (undefined)); 34 34 35 35 // STATE 36 36
+1 -1
src/components/processor/search/types.d.ts
··· 15 15 export type Schema = Orama<typeof SCHEMA>; 16 16 17 17 export type State = { 18 - cacheId: SignalReader<string>; 18 + cacheId: SignalReader<string | undefined>; 19 19 };
+2 -2
src/components/processor/search/worker.js
··· 20 20 export const $inserted = signal(/** @type {Set<string>} */ (new Set())); 21 21 22 22 // Communicated state 23 - export const $cacheId = signal(/** @type {string} */ ("")); 23 + export const $cacheId = signal(/** @type {string | undefined} */ (undefined)); 24 24 25 25 //////////////////////////////////////////// 26 26 // DATABASE ··· 91 91 92 92 $inserted.value = newSet; 93 93 $cacheId.value = ids.length === 0 94 - ? "" 94 + ? undefined 95 95 : xxh32(ids.sort().join("")).toString(); 96 96 } 97 97
+1 -1
src/themes/webamp/browser/element.js
··· 124 124 */ 125 125 render({ html }) { 126 126 const isLoading = this.$output.value?.tracks?.state() !== "loaded" || 127 - this.$search.value?.cacheId() === ""; 127 + this.$search.value?.cacheId() === undefined; 128 128 const tracks = this.#searchResults.value; 129 129 130 130 return html`
+10 -57
src/themes/webamp/index.js
··· 41 41 // 📡 42 42 //////////////////////////////////////////// 43 43 44 - const currBase = 0; 45 - 46 - const $currTrack = signal(/** @type {null | number} */ (null)); 47 - const $playlist = signal(/** @type {Set<string>} */ (new Set()), { 44 + const $playlist = signal(/** @type {Array<Track>} */ ([]), { 48 45 eager: true, 49 46 }); 50 47 ··· 78 75 79 76 amp.media.loadFromUrl = loadOverride.bind(amp.media); 80 77 81 - /** 82 - * Observe changes in Webamp's internal store. 83 - */ 84 - amp.store.subscribe(() => { 85 - const state = amp.store.getState(); 86 - 87 - if ( 88 - state.playlist.currentTrack !== null && 89 - state.playlist.currentTrack - currBase > 0 90 - ) { 91 - $currTrack.value = state.playlist.currentTrack - currBase; 92 - } 93 - }); 94 - 95 78 //////////////////////////////////////////// 96 79 // 📡 97 80 //////////////////////////////////////////// ··· 110 93 ...future, 111 94 ]; 112 95 113 - const oldSet = untracked($playlist.get); 114 - const newSet = new Set(playlist.map((i) => i.id)); 96 + const lengthLastPlaylist = untracked($playlist.get).length; 97 + const tracksToAdd = playlist.slice(lengthLastPlaylist); 115 98 116 - const addedItems = newSet.difference(oldSet); 99 + $playlist.value = playlist; 117 100 118 - // TODO: Can't do removals yet without resetting the webamp instance. 119 - // const removedItems = oldSet.difference(newSet); 120 - 121 - if (addedItems.size === 0) return; 122 - 123 - playlist.forEach((item, idx) => { 124 - if (addedItems.has(item.id) === false) return; 125 - 126 - // TODO 127 - // if (item.stats?.duration == undefined) return; 128 - 129 - // TODO: Inserting at a specific index doesn't work 130 - ampElement.addTrack(item); 131 - }); 132 - 133 - if (untracked($currTrack.get) === null) { 134 - amp.setCurrentTrack(past.length); 135 - } 136 - 137 - $playlist.value = newSet; 101 + tracksToAdd.forEach((t) => ampElement.addTrack(t)); 138 102 }); 139 103 140 104 /** 141 - * Whenever Webamp's queue changes, 142 - * reflect the change in our queue too. 105 + * Keep note of when search is ready. 143 106 */ 144 - effect(() => { 145 - if (($currTrack.value ?? 0) > untracked(queue.past).length) { 146 - queue.shift(); 147 - } 148 - }); 149 - 150 - /** */ 151 107 const tracksPromise = Promise.withResolvers(); 152 108 153 109 effect(() => { ··· 155 111 if (state !== "loaded") return; 156 112 157 113 const cacheId = search.cacheId(); 158 - if (cacheId === "") return; 114 + if (cacheId === undefined) return; 159 115 160 116 tracksPromise.resolve("loaded"); 161 117 }); ··· 201 157 202 158 amp.onClose(() => winampIsShown = false); 203 159 204 - // TODO: 205 - // amp.onMinimize(() => amp.close()); 206 - 207 160 //////////////////////////////////////////// 208 161 // 🛠️ 209 162 //////////////////////////////////////////// 210 163 211 - function addBatch() { 212 - queue.fill({ augment: true, amount: 50, shuffled: true }); 164 + async function addBatch() { 165 + await queue.fill({ augment: true, amount: 50, shuffled: true }); 213 166 214 167 // Automatically insert track if there isn't any 215 - if (!queue.now()) queue.shift(); 168 + if (!queue.now()) await queue.shift(); 216 169 } 217 170 218 171 function windowManager() {