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.

wip: improved facets page

+473 -341
src/_components/facets.vto src/_components/facets/list.vto
+13
src/_components/facets/header.vto
··· 1 + <header> 2 + <div> 3 + <div> 4 + <a class="diffuse-logo" href="./" style="display: inline-block;"> 5 + {{ await comp.diffuse.logo() }} 6 + </a> 7 + </div> 8 + <p class="construct dither-mask" style="margin-top: 0; max-width: none;"> 9 + Facets 10 + </p> 11 + </div> 12 + <div class="dither-mask filler"></div> 13 + </header>
+57
src/_components/facets/nav.vto
··· 1 + {{ set guideClass = () => url?.startsWith('/facets/') && !url?.startsWith('/facets/you/') && !url?.startsWith('/facets/featured/') && !url?.startsWith('/facets/playback/') && !url?.startsWith('/facets/browse/') && !url?.startsWith('/facets/audio-input/') && !url?.startsWith('/facets/user-data/') ? 'button--bg-twist-2' : 'button--transparent' }} 2 + 3 + <nav> 4 + <a href="facets/" class="button {{ guideClass() }} button--border"> 5 + <span class="with-icon"> 6 + <i class="ph-fill ph-book-open-text"></i> 7 + Guide 8 + </span> 9 + </a> 10 + 11 + <a href="facets/you/" class="button {{ url?.startsWith('/facets/you/') ? 'button--bg-twist-2' : 'button--transparent' }} button--border"> 12 + <span class="with-icon"> 13 + <i class="ph-fill ph-person"></i> 14 + Your collection 15 + </span> 16 + </a> 17 + 18 + <a href="facets/featured/" class="button {{ url?.startsWith('/facets/featured/') ? 'button--bg-twist-2' : 'button--transparent' }} button--border"> 19 + <span class="with-icon"> 20 + <i class="ph-fill ph-sparkle"></i> 21 + Featured 22 + </span> 23 + </a> 24 + 25 + <a href="facets/build/" class="button {{ url?.startsWith('/facets/build/') ? 'button--bg-twist-2' : 'button--transparent' }} button--border"> 26 + <span class="with-icon"> 27 + <i class="ph-fill ph-hammer"></i> 28 + Build 29 + </span> 30 + </a> 31 + 32 + <div class="divider"></div> 33 + 34 + <a href="facets/playback/" class="button {{ url?.startsWith('/facets/playback/') ? 'button--bg-twist-2' : 'button--transparent' }} button--border"> 35 + <span class="with-icon"> 36 + Playback 37 + </span> 38 + </a> 39 + 40 + <a href="facets/browse/" class="button {{ url?.startsWith('/facets/browse/') ? 'button--bg-twist-2' : 'button--transparent' }} button--border"> 41 + <span class="with-icon"> 42 + Browse 43 + </span> 44 + </a> 45 + 46 + <a href="facets/audio-input/" class="button {{ url?.startsWith('/facets/audio-input/') ? 'button--bg-twist-2' : 'button--transparent' }} button--border"> 47 + <span class="with-icon"> 48 + Audio input 49 + </span> 50 + </a> 51 + 52 + <a href="facets/user-data/" class="button {{ url?.startsWith('/facets/user-data/') ? 'button--bg-twist-2' : 'button--transparent' }} button--border"> 53 + <span class="with-icon"> 54 + User data 55 + </span> 56 + </a> 57 + </nav>
+264
src/facets/_index.vto
··· 1 + --- 2 + layout: layouts/diffuse.vto 3 + base: ../ 4 + 5 + styles: 6 + - styles/base.css 7 + - styles/diffuse/page.css 8 + - vendor/@phosphor-icons/bold/style.css 9 + - vendor/@phosphor-icons/fill/style.css 10 + 11 + scripts: 12 + - facets/index.js 13 + 14 + examples: 15 + - url: "facets/examples/now-playing/index.html" 16 + title: "Now playing" 17 + desc: > 18 + Shows what's currently set to "now playing" in the queue, along with a button to shift the queue to the next track. 19 + - url: "facets/examples/generate-playlist/index.html" 20 + title: "Generate playlist" 21 + desc: > 22 + Make a list of what previously played in the queue. 23 + --- 24 + 25 + <header> 26 + <div> 27 + <div> 28 + <a class="diffuse-logo" href="./" style="display: inline-block;"> 29 + {{ await comp.diffuse.logo() }} 30 + </a> 31 + </div> 32 + <p class="construct dither-mask" style="margin-top: 0; max-width: none;"> 33 + Facets 34 + </p> 35 + <p> 36 + Facets are various interface components each loaded in their own web page. Every used component is configured so that it operates in broadcast mode, making all the pages communicate with each other. 37 + </p> 38 + 39 + <ul class="table-of-contents"> 40 + <li><a href="facets/#collection">Your collection</a></li> 41 + <li><a href="facets/#featured">Featured</a></li> 42 + <li><a href="facets/#usage">Usage</a></li> 43 + <li><a href="facets/#built-in">Built-in</a></li> 44 + <li><a href="facets/#community">Community</a></li> 45 + <li><a href="facets/#build">Build</a></li> 46 + <li><a href="facets/#foundation">Foundation</a></li> 47 + <li><a href="facets/#examples">Examples</a></li> 48 + <li><a href="facets/#notes">Notes</a></li> 49 + </ul> 50 + </div> 51 + <div class="dither-mask filler"></div> 52 + </header> 53 + <main> 54 + <!-- YOUR COLLECTION --> 55 + <section> 56 + <h2 id="collection">Your collection</h2> 57 + <div id="list"> 58 + <div class="with-icon" style="font-size: var(--fs-sm);"> 59 + <i class="ph-bold ph-spinner-gap"></i> 60 + Loading items 61 + </div> 62 + </div> 63 + </section> 64 + 65 + <!-- FEATURED + USAGE --> 66 + <div class="columns"> 67 + <section class="flex"> 68 + <h2 id="featured">Featured</h2> 69 + 70 + <ol style="list-style: none; padding-left: 0;"> 71 + <li> 72 + <p> 73 + <i class="ph-fill ph-plus"></i> 74 + <strong><a href="{{ ('themes/webamp/configurators/input/facet/index.html') |> facetLoaderURL }}">Add</a></strong> audio from various places on the web and your device. 75 + </p> 76 + </li> 77 + <li> 78 + <p> 79 + <i class="ph-fill ph-queue"></i> 80 + <strong><a href="{{ ('themes/webamp/browser/facet/index.html') |> facetLoaderURL }}">Browse</a></strong> your collection to put something into the queue. 81 + </p> 82 + </li> 83 + <li> 84 + <p> 85 + <i class="ph-fill ph-queue"></i> 86 + <strong><a href="{{ ('facets/tools/auto-queue/index.html') |> facetLoaderURL }}">Automate</a></strong> adding items to the queue, for infinite playback or listening to a playlist. 87 + </p> 88 + </li> 89 + <li> 90 + <p> 91 + <i class="ph-fill ph-music-note"></i> 92 + <strong><a href="{{ ('themes/blur/artwork-controller/facet/index.html') |> facetLoaderURL }}">Play</a></strong> queued songs. 93 + </p> 94 + </li> 95 + <li> 96 + <p> 97 + <i class="ph-fill ph-person"></i> 98 + <strong><a href="{{ ('themes/webamp/configurators/output/facet/index.html') |> facetLoaderURL }}">Manage</a></strong> your user data, sync with your other devices or other people. 99 + </p> 100 + </li> 101 + </ol> 102 + </section> 103 + 104 + <section class="flex"> 105 + <h2 id="usage">Usage</h2> 106 + <p> 107 + To use these facets, simply open whichever ones provide the functionality that you're looking for at a given moment. You can browse existing ones here and create one below. 108 + </p> 109 + <p> 110 + For example, say you want to play music; two options would be: (1) <a href="{{ ('themes/webamp/browser/facet/index.html') |> facetLoaderURL }}">browse</a> for a specific song and add it to the queue, or (2) <a href="{{ ('facets/tools/auto-queue/index.html') |> facetLoaderURL }}">automatically</a> add a bunch of shuffled songs to the queue. Next, you need a way to play the items you added to the queue. That's where a <a href="{{ ('themes/blur/artwork-controller/facet/index.html') |> facetLoaderURL }}">controller</a> could be used. 111 + </p> 112 + <p> 113 + <em>You might ask, why can't I do all of this in just one window? That's what <a href="themes/">themes</a> are for, if you need something more streamlined. If you however want a customised experience, or prefer certain interfaces for certain things, that's what facets are for.</em> 114 + </p> 115 + <p> 116 + <small><i class="ph-fill ph-info"></i> Every facet has access to your audio collection and your user data, along with any other shared state.</small> 117 + </p> 118 + </section> 119 + </div> 120 + 121 + <!-- BUILT-IN + COMMUNITY --> 122 + <div class="columns"> 123 + <section class="flex"> 124 + <h2 id="built-in">Built-in</h2> 125 + 126 + {{ await comp.facets.list({ id: "builtin", items: facets }) }} 127 + </section> 128 + 129 + <section class="flex"> 130 + <h2 id="community">Community</h2> 131 + <p> 132 + Check out some facets from the community and load them here. 133 + </p> 134 + <p> 135 + <small><i class="ph-fill ph-info"></i> Nothing here yet, too early.</small> 136 + </p> 137 + </section> 138 + </div> 139 + 140 + <!-- / --> 141 + <div class="dither-mask filler" style="height: var(--space-2xl); margin-top: var(--space-2xl);"></div> 142 + 143 + <!-- BUILD --> 144 + <section> 145 + <h2 id="build">Build</h2> 146 + 147 + <form id="build-form" class="columns"> 148 + <div class="flex"> 149 + <p style="margin-top: 0"> 150 + If you know a bit of HTML & Javascript, you can write your own or plug in some code you found elsewhere: 151 + </p> 152 + 153 + <div id="html-input-container" class="code-editor monospace-font"> 154 + </div> 155 + </div> 156 + 157 + <div class="flex"> 158 + <p style="margin-top: 0"> 159 + Your code here builds on the <a href="facets/#foundation">foundation</a> listed below, it'll be injected into a <code>&lt;div id="container"&gt;</code> element in the body. 160 + </p> 161 + <p> 162 + <input id="name-input" type="text" placeholder="Name" name="name" required /> 163 + </p> 164 + <p> 165 + <textarea id="description-input" placeholder="Description" name="description" rows="2"></textarea> 166 + </p> 167 + <p> 168 + <span class="button-row"> 169 + <button name="save">Save</button> 170 + <button name="save+open">Save &amp; Open</button> 171 + </span> 172 + </p> 173 + </div> 174 + </form> 175 + </section> 176 + 177 + <!-- FOUNDATION --> 178 + <div class="columns"> 179 + <section class="flex"> 180 + <h2 id="foundation">Foundation</h2> 181 + 182 + <p> 183 + Diffuse comes with a foundation that preconfigures all elements so you don't have to set them up yourself, along with a combination of elements for certain features. It internally tracks the DOM addition of the custom elements, so no need to worry about setting up an element multiple times. 184 + </p> 185 + <p> 186 + <small><i class="ph-fill ph-info"></i> Refer to the <a href="#elements">elements index</a> to find out what each element does.</small> 187 + </p> 188 + <div class="code-block"> 189 + <code> 190 + {{- echo -}} 191 + import foundation from "common/facets/foundation.js" 192 + {{ /echo }} 193 + {{ echo -}}foundation.engine.audio(){{- /echo }} 194 + {{ echo -}}foundation.engine.queue(){{- /echo }} 195 + {{ echo -}}foundation.engine.repeatShuffle(){{- /echo }} 196 + {{ echo -}}foundation.engine.scope(){{- /echo }} 197 + 198 + {{ echo -}}foundation.orchestrator.autoQueue(){{- /echo }} 199 + {{ echo -}}foundation.orchestrator.favourites(){{- /echo }} 200 + {{ echo -}}foundation.orchestrator.input(){{- /echo }} 201 + {{ echo -}}foundation.orchestrator.output(){{- /echo }} 202 + {{ echo -}}foundation.orchestrator.queueAudio(){{- /echo }} 203 + {{ echo -}}foundation.orchestrator.processTracks(){{- /echo }} 204 + {{ echo -}}foundation.orchestrator.scopedTracks(){{- /echo }} 205 + {{ echo -}}foundation.orchestrator.sources(){{- /echo }} 206 + 207 + {{ echo -}}foundation.processor.artwork(){{- /echo }} 208 + {{ echo -}}foundation.processor.metadata(){{- /echo }} 209 + {{ echo -}}foundation.processor.search(){{- /echo -}} 210 + </code> 211 + </div> 212 + 213 + <p> 214 + <small>Features:</small> 215 + </p> 216 + <ul style="margin-bottom: 0;"> 217 + <li> 218 + <span>Fill the queue automatically <small>(infinite play)</small></span> 219 + <div class="list-description"> 220 + <code>foundation.features.fillQueueAutomatically()</code> 221 + </div> 222 + </li> 223 + <li> 224 + <span>Play audio from the queue</span> 225 + <div class="list-description"> 226 + <code>foundation.features.playAudioFromQueue()</code> 227 + </div> 228 + </li> 229 + <li> 230 + <span>Process inputs <small>(into tracks, etc)</small></span> 231 + <div class="list-description"> 232 + <code>foundation.features.processInputs()</code> 233 + </div> 234 + </li> 235 + <li> 236 + <span>Search through your collection</span> 237 + <div class="list-description" style="margin-bottom: 0;"> 238 + <code>foundation.features.searchThroughCollection()</code> 239 + </div> 240 + </li> 241 + </ul> 242 + </section> 243 + 244 + <section class="flex"> 245 + <h2 id="examples">Examples</h2> 246 + 247 + <p> 248 + Some simple examples to help you understand how to build your own facet. Fork them to load them into the code editor below (or save → edit). 249 + </p> 250 + 251 + {{ await comp.facets.list({ id: "examples", items: examples }) }} 252 + 253 + <h2 id="notes">Notes</h2> 254 + <p> 255 + While you have the ability to do whatever you want in a custom facet, the existing facets are designed to work a certain way; so here's some things to keep in mind: 256 + </p> 257 + <ul> 258 + <li><span>In most cases you'll want to call <code>foundation.features.processInputs()</code> so that your audio files and streams actually show up.</span></li> 259 + <li><span>Most elements are configured in broadcast mode so they communicate across tabs. There are a few exceptions such as inputs, where we prefer parallelisation.</span></li> 260 + <li><span>You can use facets in combination with themes by adding the elements used in the theme to a group and then passing in the group name as a URL query parameter (eg. <code>group=facets</code>)</span></li> 261 + </ul> 262 + </section> 263 + </div> 264 + </main>
src/facets/index.js src/facets/_index.js
+17 -248
src/facets/index.vto
··· 1 1 --- 2 2 layout: layouts/diffuse.vto 3 - base: ../ 3 + base: ../../ 4 + title: Guide | Facets | Diffuse 4 5 5 6 styles: 6 7 - styles/base.css 7 8 - styles/diffuse/page.css 8 9 - vendor/@phosphor-icons/bold/style.css 9 10 - vendor/@phosphor-icons/fill/style.css 11 + --- 10 12 11 - scripts: 12 - - facets/index.js 13 + {{ await comp.facets.header() }} 13 14 14 - examples: 15 - - url: "facets/examples/now-playing/index.html" 16 - title: "Now playing" 17 - desc: > 18 - Shows what's currently set to "now playing" in the queue, along with a button to shift the queue to the next track. 19 - - url: "facets/examples/generate-playlist/index.html" 20 - title: "Generate playlist" 21 - desc: > 22 - Make a list of what previously played in the queue. 23 - --- 15 + <main> 16 + {{ await comp.facets.nav({ url }) }} 24 17 25 - <header> 26 - <div> 27 - <div> 28 - <a class="diffuse-logo" href="./" style="display: inline-block;"> 29 - {{ await comp.diffuse.logo() }} 30 - </a> 31 - </div> 32 - <p class="construct dither-mask" style="margin-top: 0; max-width: none;"> 33 - Facets 18 + <section> 19 + <h1 hidden>Guide</h1> 20 + <p> 21 + To use these facets, simply open whichever ones provide the functionality that you're looking for at a given moment. You can browse existing ones here and create one below. 22 + </p> 23 + <p> 24 + For example, say you want to play music; two options would be: (1) <a href="{{ ('themes/webamp/browser/facet/index.html') |> facetLoaderURL }}">browse</a> for a specific song and add it to the queue, or (2) <a href="{{ ('facets/tools/auto-queue/index.html') |> facetLoaderURL }}">automatically</a> add a bunch of shuffled songs to the queue. Next, you need a way to play the items you added to the queue. That's where a <a href="{{ ('themes/blur/artwork-controller/facet/index.html') |> facetLoaderURL }}">controller</a> could be used. 25 + </p> 26 + <p> 27 + <em>You might ask, why can't I do all of this in just one window? That's what <a href="themes/">themes</a> are for, if you need something more streamlined. If you however want a customised experience, or prefer certain interfaces for certain things, that's what facets are for.</em> 34 28 </p> 35 29 <p> 36 - Facets are various interface components each loaded in their own web page. Every used component is configured so that it operates in broadcast mode, making all the pages communicate with each other. 30 + <small><i class="ph-fill ph-info"></i> Every facet has access to your audio collection and your user data, along with any other shared state.</small> 37 31 </p> 38 - 39 - <ul class="table-of-contents"> 40 - <li><a href="facets/#collection">Your collection</a></li> 41 - <li><a href="facets/#featured">Featured</a></li> 42 - <li><a href="facets/#usage">Usage</a></li> 43 - <li><a href="facets/#built-in">Built-in</a></li> 44 - <li><a href="facets/#community">Community</a></li> 45 - <li><a href="facets/#build">Build</a></li> 46 - <li><a href="facets/#foundation">Foundation</a></li> 47 - <li><a href="facets/#examples">Examples</a></li> 48 - <li><a href="facets/#notes">Notes</a></li> 49 - </ul> 50 - </div> 51 - <div class="dither-mask filler"></div> 52 - </header> 53 - <main> 54 - <!-- YOUR COLLECTION --> 55 - <section> 56 - <h2 id="collection">Your collection</h2> 57 - <div id="list"> 58 - <div class="with-icon" style="font-size: var(--fs-sm);"> 59 - <i class="ph-bold ph-spinner-gap"></i> 60 - Loading items 61 - </div> 62 - </div> 63 32 </section> 64 - 65 - <!-- FEATURED + USAGE --> 66 - <div class="columns"> 67 - <section class="flex"> 68 - <h2 id="featured">Featured</h2> 69 - 70 - <ol style="list-style: none; padding-left: 0;"> 71 - <li> 72 - <p> 73 - <i class="ph-fill ph-plus"></i> 74 - <strong><a href="{{ ('themes/webamp/configurators/input/facet/index.html') |> facetLoaderURL }}">Add</a></strong> audio from various places on the web and your device. 75 - </p> 76 - </li> 77 - <li> 78 - <p> 79 - <i class="ph-fill ph-queue"></i> 80 - <strong><a href="{{ ('themes/webamp/browser/facet/index.html') |> facetLoaderURL }}">Browse</a></strong> your collection to put something into the queue. 81 - </p> 82 - </li> 83 - <li> 84 - <p> 85 - <i class="ph-fill ph-queue"></i> 86 - <strong><a href="{{ ('facets/tools/auto-queue/index.html') |> facetLoaderURL }}">Automate</a></strong> adding items to the queue, for infinite playback or listening to a playlist. 87 - </p> 88 - </li> 89 - <li> 90 - <p> 91 - <i class="ph-fill ph-music-note"></i> 92 - <strong><a href="{{ ('themes/blur/artwork-controller/facet/index.html') |> facetLoaderURL }}">Play</a></strong> queued songs. 93 - </p> 94 - </li> 95 - <li> 96 - <p> 97 - <i class="ph-fill ph-person"></i> 98 - <strong><a href="{{ ('themes/webamp/configurators/output/facet/index.html') |> facetLoaderURL }}">Manage</a></strong> your user data, sync with your other devices or other people. 99 - </p> 100 - </li> 101 - </ol> 102 - </section> 103 - 104 - <section class="flex"> 105 - <h2 id="usage">Usage</h2> 106 - <p> 107 - To use these facets, simply open whichever ones provide the functionality that you're looking for at a given moment. You can browse existing ones here and create one below. 108 - </p> 109 - <p> 110 - For example, say you want to play music; two options would be: (1) <a href="{{ ('themes/webamp/browser/facet/index.html') |> facetLoaderURL }}">browse</a> for a specific song and add it to the queue, or (2) <a href="{{ ('facets/tools/auto-queue/index.html') |> facetLoaderURL }}">automatically</a> add a bunch of shuffled songs to the queue. Next, you need a way to play the items you added to the queue. That's where a <a href="{{ ('themes/blur/artwork-controller/facet/index.html') |> facetLoaderURL }}">controller</a> could be used. 111 - </p> 112 - <p> 113 - <em>You might ask, why can't I do all of this in just one window? That's what <a href="themes/">themes</a> are for, if you need something more streamlined. If you however want a customised experience, or prefer certain interfaces for certain things, that's what facets are for.</em> 114 - </p> 115 - <p> 116 - <small><i class="ph-fill ph-info"></i> Every facet has access to your audio collection and your user data, along with any other shared state.</small> 117 - </p> 118 - </section> 119 - </div> 120 - 121 - <!-- BUILT-IN + COMMUNITY --> 122 - <div class="columns"> 123 - <section class="flex"> 124 - <h2 id="built-in">Built-in</h2> 125 - 126 - {{ await comp.facets({ id: "builtin", items: facets }) }} 127 - </section> 128 - 129 - <section class="flex"> 130 - <h2 id="community">Community</h2> 131 - <p> 132 - Check out some facets from the community and load them here. 133 - </p> 134 - <p> 135 - <small><i class="ph-fill ph-info"></i> Nothing here yet, too early.</small> 136 - </p> 137 - </section> 138 - </div> 139 - 140 - <!-- / --> 141 - <div class="dither-mask filler" style="height: var(--space-2xl); margin-top: var(--space-2xl);"></div> 142 - 143 - <!-- BUILD --> 144 - <section> 145 - <h2 id="build">Build</h2> 146 - 147 - <form id="build-form" class="columns"> 148 - <div class="flex"> 149 - <p style="margin-top: 0"> 150 - If you know a bit of HTML & Javascript, you can write your own or plug in some code you found elsewhere: 151 - </p> 152 - 153 - <div id="html-input-container" class="code-editor monospace-font"> 154 - </div> 155 - </div> 156 - 157 - <div class="flex"> 158 - <p style="margin-top: 0"> 159 - Your code here builds on the <a href="facets/#foundation">foundation</a> listed below, it'll be injected into a <code>&lt;div id="container"&gt;</code> element in the body. 160 - </p> 161 - <p> 162 - <input id="name-input" type="text" placeholder="Name" name="name" required /> 163 - </p> 164 - <p> 165 - <textarea id="description-input" placeholder="Description" name="description" rows="2"></textarea> 166 - </p> 167 - <p> 168 - <span class="button-row"> 169 - <button name="save">Save</button> 170 - <button name="save+open">Save &amp; Open</button> 171 - </span> 172 - </p> 173 - </div> 174 - </form> 175 - </section> 176 - 177 - <!-- FOUNDATION --> 178 - <div class="columns"> 179 - <section class="flex"> 180 - <h2 id="foundation">Foundation</h2> 181 - 182 - <p> 183 - Diffuse comes with a foundation that preconfigures all elements so you don't have to set them up yourself, along with a combination of elements for certain features. It internally tracks the DOM addition of the custom elements, so no need to worry about setting up an element multiple times. 184 - </p> 185 - <p> 186 - <small><i class="ph-fill ph-info"></i> Refer to the <a href="#elements">elements index</a> to find out what each element does.</small> 187 - </p> 188 - <div class="code-block"> 189 - <code> 190 - {{- echo -}} 191 - import foundation from "common/facets/foundation.js" 192 - {{ /echo }} 193 - {{ echo -}}foundation.engine.audio(){{- /echo }} 194 - {{ echo -}}foundation.engine.queue(){{- /echo }} 195 - {{ echo -}}foundation.engine.repeatShuffle(){{- /echo }} 196 - {{ echo -}}foundation.engine.scope(){{- /echo }} 197 - 198 - {{ echo -}}foundation.orchestrator.autoQueue(){{- /echo }} 199 - {{ echo -}}foundation.orchestrator.favourites(){{- /echo }} 200 - {{ echo -}}foundation.orchestrator.input(){{- /echo }} 201 - {{ echo -}}foundation.orchestrator.output(){{- /echo }} 202 - {{ echo -}}foundation.orchestrator.queueAudio(){{- /echo }} 203 - {{ echo -}}foundation.orchestrator.processTracks(){{- /echo }} 204 - {{ echo -}}foundation.orchestrator.scopedTracks(){{- /echo }} 205 - {{ echo -}}foundation.orchestrator.sources(){{- /echo }} 206 - 207 - {{ echo -}}foundation.processor.artwork(){{- /echo }} 208 - {{ echo -}}foundation.processor.metadata(){{- /echo }} 209 - {{ echo -}}foundation.processor.search(){{- /echo -}} 210 - </code> 211 - </div> 212 - 213 - <p> 214 - <small>Features:</small> 215 - </p> 216 - <ul style="margin-bottom: 0;"> 217 - <li> 218 - <span>Fill the queue automatically <small>(infinite play)</small></span> 219 - <div class="list-description"> 220 - <code>foundation.features.fillQueueAutomatically()</code> 221 - </div> 222 - </li> 223 - <li> 224 - <span>Play audio from the queue</span> 225 - <div class="list-description"> 226 - <code>foundation.features.playAudioFromQueue()</code> 227 - </div> 228 - </li> 229 - <li> 230 - <span>Process inputs <small>(into tracks, etc)</small></span> 231 - <div class="list-description"> 232 - <code>foundation.features.processInputs()</code> 233 - </div> 234 - </li> 235 - <li> 236 - <span>Search through your collection</span> 237 - <div class="list-description" style="margin-bottom: 0;"> 238 - <code>foundation.features.searchThroughCollection()</code> 239 - </div> 240 - </li> 241 - </ul> 242 - </section> 243 - 244 - <section class="flex"> 245 - <h2 id="examples">Examples</h2> 246 - 247 - <p> 248 - Some simple examples to help you understand how to build your own facet. Fork them to load them into the code editor below (or save → edit). 249 - </p> 250 - 251 - {{ await comp.facets({ id: "examples", items: examples }) }} 252 - 253 - <h2 id="notes">Notes</h2> 254 - <p> 255 - While you have the ability to do whatever you want in a custom facet, the existing facets are designed to work a certain way; so here's some things to keep in mind: 256 - </p> 257 - <ul> 258 - <li><span>In most cases you'll want to call <code>foundation.features.processInputs()</code> so that your audio files and streams actually show up.</span></li> 259 - <li><span>Most elements are configured in broadcast mode so they communicate across tabs. There are a few exceptions such as inputs, where we prefer parallelisation.</span></li> 260 - <li><span>You can use facets in combination with themes by adding the elements used in the theme to a group and then passing in the group name as a URL query parameter (eg. <code>group=facets</code>)</span></li> 261 - </ul> 262 - </section> 263 - </div> 264 33 </main>
+89
src/styles/diffuse/code-editor.css
··· 1 + .code-editor { 2 + font-size: var(--fs-sm); 3 + font-size: calc((var(--fs-xs) + var(--fs-sm)) / 2); 4 + height: var(--container-xs); 5 + } 6 + 7 + .code-editor .cm-editor { 8 + background: var(--code-color); 9 + height: 100%; 10 + 11 + .cm-selectionBackground, 12 + &::selection { 13 + background: var(--accent-mark) !important; 14 + } 15 + 16 + .cm-content { 17 + padding: var(--space-2xs) var(--space-3xs); 18 + padding-right: var(--space-2xs); 19 + } 20 + 21 + .cm-gutters { 22 + background: oklch(from var(--code-color) calc(l - 0.025) c h); 23 + border: 0; 24 + color: oklch(from var(--text-color) l c h / 0.375); 25 + font-size: var(--fs-xs); 26 + line-height: 20px; 27 + } 28 + 29 + .cm-activeLineGutter { 30 + background: var(--accent); 31 + color: var(--bg-color); 32 + } 33 + 34 + .cm-scroller { 35 + font-family: inherit; 36 + } 37 + 38 + .cm-selectionMatch, 39 + .cm-matchingBracket { 40 + background: var(--accent-highlight); 41 + } 42 + 43 + .cm-activeline { 44 + background: oklch(from var(--text-color) l c h / 0.075); 45 + } 46 + 47 + .cm-cursor, 48 + .cm-dropCursor { 49 + border-left-color: var(--text-color); 50 + } 51 + 52 + .cm-tooltip { 53 + background: var(--bg-color); 54 + border: 0; 55 + padding: var(--space-3xs); 56 + } 57 + 58 + .cm-tooltip-autocomplete ul li[aria-selected] { 59 + background: var(--accent); 60 + color: var(--bg-color); 61 + } 62 + 63 + /* Code styling */ 64 + .ͼi { 65 + color: var(--accent); 66 + } 67 + 68 + .ͼe { 69 + color: var(--accent-twist-4); 70 + } 71 + 72 + .ͼb { 73 + color: var(--accent-twist-1); 74 + color: oklch(from currentColor l c h / 0.6); 75 + } 76 + 77 + .ͼg { 78 + color: var(--accent-twist-2); 79 + } 80 + 81 + .ͼf { 82 + color: var(--accent-twist-5); 83 + } 84 + 85 + .ͼ5, 86 + .ͼm { 87 + color: oklch(from currentColor l c h / 0.4); 88 + } 89 + }
+33 -93
src/styles/diffuse/page.css
··· 37 37 max-width: var(--container-xl); 38 38 } 39 39 40 - .code-editor { 41 - font-size: var(--fs-sm); 42 - font-size: calc((var(--fs-xs) + var(--fs-sm)) / 2); 43 - height: var(--container-xs); 44 - } 45 - 46 - .code-editor .cm-editor { 47 - background: var(--code-color); 48 - height: 100%; 49 - 50 - .cm-selectionBackground, 51 - &::selection { 52 - background: var(--accent-mark) !important; 53 - } 54 - 55 - .cm-content { 56 - padding: var(--space-2xs) var(--space-3xs); 57 - padding-right: var(--space-2xs); 58 - } 59 - 60 - .cm-gutters { 61 - background: oklch(from var(--code-color) calc(l - 0.025) c h); 62 - border: 0; 63 - color: oklch(from var(--text-color) l c h / 0.375); 64 - font-size: var(--fs-xs); 65 - line-height: 20px; 66 - } 67 - 68 - .cm-activeLineGutter { 69 - background: var(--accent); 70 - color: var(--bg-color); 71 - } 72 - 73 - .cm-scroller { 74 - font-family: inherit; 75 - } 76 - 77 - .cm-selectionMatch, 78 - .cm-matchingBracket { 79 - background: var(--accent-highlight); 80 - } 81 - 82 - .cm-activeline { 83 - background: oklch(from var(--text-color) l c h / 0.075); 84 - } 85 - 86 - .cm-cursor, 87 - .cm-dropCursor { 88 - border-left-color: var(--text-color); 89 - } 90 - 91 - .cm-tooltip { 92 - background: var(--bg-color); 93 - border: 0; 94 - padding: var(--space-3xs); 95 - } 96 - 97 - .cm-tooltip-autocomplete ul li[aria-selected] { 98 - background: var(--accent); 99 - color: var(--bg-color); 100 - } 101 - 102 - /* Code styling */ 103 - .ͼi { 104 - color: var(--accent); 105 - } 106 - 107 - .ͼe { 108 - color: var(--accent-twist-4); 109 - } 110 - 111 - .ͼb { 112 - color: var(--accent-twist-1); 113 - color: oklch(from currentColor l c h / 0.6); 114 - } 115 - 116 - .ͼg { 117 - color: var(--accent-twist-2); 118 - } 119 - 120 - .ͼf { 121 - color: var(--accent-twist-5); 122 - } 123 - 124 - .ͼ5, 125 - .ͼm { 126 - color: oklch(from currentColor l c h / 0.4); 127 - } 128 - } 129 - 130 40 /** 131 41 * Containers 132 42 */ ··· 327 237 --button-bg-opacity: 0.6; 328 238 background: oklch(from var(--accent) l c h / var(--button-bg-opacity)); 329 239 border: 0; 330 - border-radius: var(--radius-md); 240 + border-radius: 999px; 331 241 color: var(--bg-color); 332 242 cursor: pointer; 333 243 display: inline-block; 334 244 font-family: inherit; 335 245 font-weight: 500; 336 246 line-height: var(--leading-tight); 337 - padding: var(--space-2xs) var(--space-xs); 247 + padding: var(--space-2xs) calc((var(--space-xs) + var(--space-sm)) / 2); 338 248 transition-duration: 500ms; 339 - transition-property: background-color, opacity; 249 + transition-property: background-color, border-color, opacity; 340 250 341 251 & * { 342 252 pointer-events: none; ··· 372 282 background-color: oklch(from var(--accent-twist-5) l c h / var(--button-bg-opacity)); 373 283 } 374 284 285 + &.button--border { 286 + border: 2px solid transparent; 287 + } 288 + 375 289 &.button--transparent { 376 290 background-color: transparent; 377 291 color: var(--text-color); 292 + opacity: var(--button-bg-opacity); 293 + 294 + &.button--border { 295 + border-color: oklch(from currentColor l c h / var(--button-bg-opacity)); 296 + } 378 297 } 379 298 380 299 &.button--small { ··· 409 328 .button-row { 410 329 display: inline-flex; 411 330 gap: var(--space-2xs); 331 + } 332 + 333 + .divider { 334 + background-color: oklch(from currentColor l c h / 0.05); 335 + height: stretch; 336 + width: 1px; 412 337 } 413 338 414 339 .todo { ··· 509 434 opacity: 0.25; 510 435 } 511 436 } 437 + } 438 + 439 + /** 440 + * Nav 441 + */ 442 + 443 + nav { 444 + align-items: center; 445 + border-bottom: 1px solid oklch(from currentColor l c h / 0.05); 446 + display: flex; 447 + flex-wrap: wrap; 448 + gap: var(--space-xs); 449 + margin-bottom: var(--space-lg); 450 + margin-top: var(--space-md); 451 + padding-bottom: var(--space-md); 512 452 } 513 453 514 454 /**