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: separate process-tracks interface

+127 -14
+8 -1
src/_data/facets.json
··· 95 95 "desc": "The default setup for user-data storage output. Adds support for: AT Protocol and S3-compatible storage. For both of these a custom local-first syncing algorithm is used." 96 96 }, 97 97 { 98 - "url": "facets/data/process-tracks/index.html", 98 + "url": "facets/data/process-tracks/prelude/index.html", 99 99 "title": "Process Tracks", 100 100 "kind": "prelude", 101 101 "category": "Data", 102 102 "featured": true, 103 103 "desc": "Process all your audio inputs automatically into tracks when opening any interface. Only happens once every 10 minutes, if the processing was completed." 104 + }, 105 + { 106 + "url": "facets/data/process-tracks/index.html", 107 + "title": "Process Tracks", 108 + "category": "Data", 109 + "featured": true, 110 + "desc": "Process all your audio sources into tracks. Shows a progress bar when processing is occuring." 104 111 }, 105 112 { 106 113 "url": "facets/misc/scrobble/index.html",
+1 -1
src/common/facets/constants.js
··· 25 25 [ 26 26 "facets/data/input-bundle/index.html", 27 27 "facets/data/output-bundle/index.html", 28 - "facets/data/process-tracks/index.html", 28 + "facets/data/process-tracks/prelude/index.html", 29 29 ].includes(facet.url) 30 30 ) { 31 31 return [{
+27
src/facets/data/process-tracks/index.html
··· 1 + <div id="container"> 2 + <div class="window" style="height: auto"> 3 + <div class="title-bar"> 4 + <div class="title-bar-icon"> 5 + <img src="images/icons/windows_98/gears-0.png" height="14" /> 6 + </div> 7 + <div class="title-bar-text" draggable="false">Process tracks</div> 8 + <div class="title-bar-controls"> 9 + <button aria-label="Close" onclick="window.close()"></button> 10 + </div> 11 + </div> 12 + <div class="window-body"> 13 + <div id="placeholder"></div> 14 + </div> 15 + </div> 16 + </div> 17 + 18 + <style> 19 + @import "./styles/variables.css"; 20 + @import "./themes/winamp/fonts.css"; 21 + @import "./themes/winamp/facet.css"; 22 + 23 + @import "./vendor/98.css"; 24 + @import "./themes/winamp/98-vars.css"; 25 + @import "./themes/winamp/98-extra.css"; 26 + </style> 27 + 1 28 <script type="module" src="facets/data/process-tracks/index.inline.js"></script>
+66 -11
src/facets/data/process-tracks/index.inline.js
··· 1 + import * as Output from "~/common/output.js"; 2 + import { html, render as litRender } from "lit-html"; 3 + import { effect } from "~/common/signal.js"; 1 4 import foundation from "~/common/foundation.js"; 2 5 3 - const KEY = "facets/data/process-tracks/timestamp"; 4 - const MAX_TIME_DIFF = 10 * 60 * 1000; 6 + const orchestrator = await foundation.orchestrator.processTracks({ 7 + disableWhenReady: true, 8 + }); 5 9 6 - const lastTimestamp = localStorage.getItem(KEY); 7 - const now = Date.now(); 8 - const diff = lastTimestamp ? now - JSON.parse(lastTimestamp) : MAX_TIME_DIFF; 10 + const placeholder = document.querySelector("#placeholder"); 11 + if (!placeholder) throw new Error("No #placeholder element"); 9 12 10 - if (diff >= MAX_TIME_DIFF) { 11 - const orchestrator = await foundation.orchestrator.processTracks({ 12 - disableWhenReady: true, 13 - }); 13 + /** 14 + * Wait until tracks are loaded and only then start processing. 15 + */ 16 + async function process() { 17 + const output = await foundation.orchestrator.output(); 14 18 15 - // Wait until we're actually done processing, only then set the timestamp 19 + await Output.data(output.tracks); 16 20 await orchestrator.process(); 17 - localStorage.setItem(KEY, JSON.stringify(now)); 18 21 } 22 + 23 + effect(() => { 24 + const isProcessing = orchestrator.isProcessing(); 25 + const { processed, total } = orchestrator.progress(); 26 + const percentage = total > 0 ? Math.round((processed / total) * 100) : 0; 27 + 28 + litRender( 29 + isProcessing 30 + ? html` 31 + <fieldset> 32 + <legend>Processing tracks</legend> 33 + <div class="with-icon with-icon--large"> 34 + <img src="images/icons/windows_98/gears-0.png" width="24" /> 35 + <span> 36 + ${total === 0 37 + ? "Going through all the inputs and gathering the tracks ..." 38 + : `Making sure each track has metadata & statistics (${processed} / ${total}) ...`} 39 + </span> 40 + </div> 41 + <div 42 + class="progress-indicator" 43 + style="margin-top: var(--grouped-element-spacing);" 44 + > 45 + <div 46 + class="progress-indicator-bar" 47 + style="width: ${percentage}%" 48 + > 49 + </div> 50 + </div> 51 + </fieldset> 52 + ` 53 + : html` 54 + <fieldset> 55 + <div class="with-icon with-icon--large"> 56 + <img src="images/icons/windows_98/gears-0.png" width="24" /> 57 + <div> 58 + <p> 59 + Go through all the inputs you've added and get the last audio files and 60 + their metadata. 61 + </p> 62 + <p> 63 + <button @click="${process}"> 64 + Process sources 65 + </button> 66 + </p> 67 + </div> 68 + </div> 69 + </fieldset> 70 + `, 71 + /** @type {HTMLElement} */ (placeholder), 72 + ); 73 + });
+1
src/facets/data/process-tracks/prelude/index.html
··· 1 + <script type="module" src="facets/data/process-tracks/prelude/index.inline.js"></script>
+22
src/facets/data/process-tracks/prelude/index.inline.js
··· 1 + import * as Output from "~/common/output.js"; 2 + import foundation from "~/common/foundation.js"; 3 + 4 + const KEY = "facets/data/process-tracks/timestamp"; 5 + const MAX_TIME_DIFF = 10 * 60 * 1000; 6 + 7 + const lastTimestamp = localStorage.getItem(KEY); 8 + const now = Date.now(); 9 + const diff = lastTimestamp ? now - JSON.parse(lastTimestamp) : MAX_TIME_DIFF; 10 + 11 + if (diff >= MAX_TIME_DIFF) { 12 + const output = await foundation.orchestrator.output(); 13 + await Output.data(output.tracks); 14 + 15 + const orchestrator = await foundation.orchestrator.processTracks({ 16 + disableWhenReady: true, 17 + }); 18 + 19 + // Wait until we're actually done processing, only then set the timestamp 20 + await orchestrator.process(); 21 + localStorage.setItem(KEY, JSON.stringify(now)); 22 + }
+2 -1
src/themes/winamp/98-vars.css
··· 1 - :host { 1 + :host, 2 + :root { 2 3 /* Color */ 3 4 --text-color: #222222; 4 5 --surface: #c0c0c0;