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.

chore: more examples

+74 -5
+37
src/themes/loader/constituent/examples/generate-playlist.txt
··· 1 + <main> 2 + <button>Generate playlist</button> 3 + <ol></ol> 4 + </main> 5 + 6 + <style> 7 + @import "./styles/base.css"; 8 + @import "./styles/diffuse/page.css"; 9 + </style> 10 + 11 + <script type="module"> 12 + import foundation from "./common/constituents/foundation.js"; 13 + 14 + const queue = foundation.engine.queue(); 15 + 16 + /** 17 + * Playlist generator 18 + */ 19 + function generatePlaylist(items) { 20 + const playlist = [ 21 + ...queue.past(), 22 + ...(queue.now() ? [queue.now()] : []), 23 + ...queue.future().filter((i) => i.manualEntry), 24 + ]; 25 + 26 + const element = document.querySelector("main ol"); 27 + if (!element) return; 28 + 29 + element.innerHTML = playlist 30 + .map((item) => `<li>${item.tags.artist} - ${item.tags.title}</li>`) 31 + .join(""); 32 + } 33 + 34 + document.body.querySelector("button").onclick = () => { 35 + generatePlaylist(); 36 + }; 37 + </script>
+35 -4
src/themes/loader/constituent/index.js
··· 25 25 const output = foundation.orchestrator.output(); 26 26 27 27 effect(() => { 28 - const col = output.constituents.collection(); 28 + const col = output.constituents.collection().sort((a, b) => { 29 + return a.name.toLocaleLowerCase().localeCompare(b.name.toLocaleLowerCase()); 30 + }); 29 31 30 32 const h = col.length 31 33 ? html` 32 34 <ul> 33 35 ${col.map((c) => 34 36 html` 35 - <li> 37 + <li style="margin-bottom: var(--space-2xs)"> 36 38 <a href="themes/loader/constituent/s/?cid=${c.cid}"> 37 39 ${c.name} 38 40 </a> 41 + <br /> 42 + <small> 43 + <span @click="${deleteConstituent( 44 + c.cid, 45 + )}" style="cursor: pointer;"> 46 + Delete 47 + </span> 48 + </small> 39 49 </li> 40 50 ` 41 51 )} ··· 56 66 or create some using the tools below. 57 67 </p> 58 68 `; 69 + 70 + /** 71 + * @param {string} cid 72 + */ 73 + function deleteConstituent(cid) { 74 + return () => { 75 + output.constituents.save( 76 + output.constituents.collection().filter((c) => c.cid !== cid), 77 + ); 78 + }; 79 + } 59 80 60 81 //////////////////////////////////////////// 61 82 // BUILD ··· 133 154 break; 134 155 } 135 156 case "save": 136 - await output.constituents.save([constituent]); 157 + await saveConstituent(constituent); 137 158 break; 138 159 case "save+open": 139 - await output.constituents.save([constituent]); 160 + await saveConstituent(constituent); 140 161 window.open(`${location.href}s/?cid=${constituent.cid}`, "blank"); 141 162 break; 142 163 } 143 164 } 165 + 166 + /** 167 + * @param {Constituent} constituent 168 + */ 169 + async function saveConstituent(constituent) { 170 + const col = output.constituents.collection(); 171 + const colWithoutName = col.filter((c) => c.name !== constituent.name); 172 + 173 + await output.constituents.save([...colWithoutName, constituent]); 174 + }
+2 -1
src/themes/loader/constituent/index.vto
··· 93 93 <selectedcontent></selectedcontent> 94 94 </button> 95 95 96 - <option value="now-playing.txt" selected>Now playing + Next Queue Item</option> 96 + <option value="now-playing.txt" selected>Now playing & next queue item</option> 97 + <option value="generate-playlist.txt">Generate playlist from queue</option> 97 98 </select> 98 99 </div> 99 100 <p>