Experiment to rebuild Diffuse using web applets.
0
fork

Configure Feed

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

feat: basics for blur theme

+96 -75
+3 -3
src/pages/constituents/blur/artwork-controller/_applet.astro
··· 37 37 display: flex; 38 38 flex-direction: column; 39 39 font-size: var(--fs-sm); 40 - height: 100vh; 41 - max-width: var(--container-2xs); 40 + height: 100dvh; 41 + /* max-width: var(--container-xs); */ 42 42 overflow: hidden; 43 43 position: relative; 44 44 transition: ··· 285 285 import { FastAverageColor } from "fast-average-color"; 286 286 import { Temporal } from "@js-temporal/polyfill"; 287 287 288 - import { computed, effect, type Signal, signal, throttled } from "spellcaster"; 288 + import { computed, effect, type Signal, signal } from "spellcaster"; 289 289 import { tags, text, type ElementConfigurator } from "spellcaster/hyperscript.js"; 290 290 291 291 import type { ManagedOutput, Track } from "@applets/core/types";
+4 -46
src/pages/orchestrator/queue-audio-tracks/_applet.astro
··· 1 1 <script> 2 2 import type { ManagedOutput } from "@applets/core/types.d.ts"; 3 - import { applet, inputUrl, reactive, register, wait } from "@scripts/applets/common"; 3 + import { applet, inputUrl, makeConnect, register } from "@scripts/applets/common"; 4 4 5 5 //////////////////////////////////////////// 6 6 // SETUP 7 7 //////////////////////////////////////////// 8 8 import type * as AudioEngine from "@applets/engine/audio/types.d.ts"; 9 9 import type * as QueueEngine from "@applets/engine/queue/types.d.ts"; 10 - import type { Applet } from "@web-applets/sdk"; 11 10 12 11 // Register applet 13 12 const context = register(); 13 + const connect = makeConnect(context); 14 14 15 15 // Applet connections 16 16 const configurator = { ··· 19 19 }; 20 20 21 21 const engine = { 22 - audio: await applet<AudioEngine.State>("../../engine/audio"), 23 - queue: await applet<QueueEngine.State>("../../engine/queue"), 22 + audio: await applet<AudioEngine.State>("../../engine/audio", { groupId: context.groupId }), 23 + queue: await applet<QueueEngine.State>("../../engine/queue", { groupId: context.groupId }), 24 24 }; 25 25 26 26 //////////////////////////////////////////// 27 - // ACTIONS 28 - //////////////////////////////////////////// 29 - 30 - // TODO: Shuffle, limit track amount, etc. 31 - async function fill() { 32 - const tracks = configurator.output.data.tracks.collection; 33 - 34 - await engine.queue.sendAction("add", tracks, { 35 - timeoutDuration: 60000, 36 - }); 37 - 38 - // Automatically insert track if there isn't any 39 - if (!engine.queue.data.now) { 40 - await engine.queue.sendAction("shift"); 41 - } 42 - } 43 - 44 - //////////////////////////////////////////// 45 27 // Connections 46 28 //////////////////////////////////////////// 47 29 await context.settled(); 48 - 49 - function connect<D, T>( 50 - applet: Applet<D>, 51 - dataFn: (data: D) => T, 52 - effectFn: (t: T, setter: (t: T) => void) => void, 53 - ) { 54 - if (!context.isMainInstance()) return; 55 - return reactive(applet, dataFn, effectFn); 56 - } 57 30 58 31 //////////////////////////////////////////// 59 32 // ⚙️ [Connections → Engines] ··· 111 84 timeoutDuration: 60000, 112 85 }, 113 86 ); 114 - 115 - // Add more tracks to the queue if needed 116 - if (activeTrack) fill(); 117 87 }, 118 88 ); 119 - 120 - //////////////////////////////////////////// 121 - // 🏕️ [Connections → Output] 122 - // 📦 OUTPUT 123 - //////////////////////////////////////////// 124 - 125 - // Add tracks to the queue once the tracks have been loaded; 126 - // and every time the collection changes. 127 - 128 - wait(configurator.output, (d) => d?.tracks.state === "loaded").then(() => { 129 - connect(configurator.output, (data) => data.tracks.cacheId, fill); 130 - }); 131 89 </script>
+5
src/pages/themes/blur/index.astro
··· 4 4 5 5 <Page title="Diffuse"> 6 6 <script src="../../../scripts/themes/blur/index.js"></script> 7 + 8 + <main> 9 + <iframe src="../../constituents/blur/artwork-controller/?groupId=deck-a"></iframe> 10 + <iframe src="../../constituents/blur/artwork-controller/?groupId=deck-b"></iframe> 11 + </main> 7 12 </Page>
+11
src/scripts/applets/common.ts
··· 291 291 }); 292 292 } 293 293 294 + export function makeConnect<X>(context: BroadcastedApplet<X>) { 295 + return <D, T>( 296 + applet: Applet<D>, 297 + dataFn: (data: D) => T, 298 + effectFn: (t: T, setter: (t: T) => void) => void, 299 + ) => { 300 + if (!context.isMainInstance()) return; 301 + return reactive(applet, dataFn, effectFn); 302 + }; 303 + } 304 + 294 305 //////////////////////////////////////////// 295 306 // ⚡️ COMMON ACTION CALLS 296 307 ////////////////////////////////////////////
+38 -6
src/scripts/themes/blur/index.ts
··· 1 + import type { Applet } from "@web-applets/sdk"; 2 + 3 + import type { ManagedOutput } from "@applets/core/types"; 4 + import { applet } from "@scripts/applets/common"; 5 + 1 6 //////////////////////////////////////////// 2 7 // 🎨 Styles 3 8 //////////////////////////////////////////// ··· 6 11 //////////////////////////////////////////// 7 12 // 🗂️ Applets 8 13 //////////////////////////////////////////// 9 - const ui = {}; 14 + import type * as QueueEngine from "@applets/engine/queue/types.d.ts"; 10 15 11 - // TESTING 16 + const idA = "deck-a"; 17 + const idB = "deck-b"; 12 18 13 - // wait(configurator.output, (data) => data?.tracks?.state === "loaded").then(async () => { 14 - // await processor.search.sendAction("supply", configurator.output.data.tracks.collection); 15 - // const tracks = await processor.search.sendAction("search", "artist lee last"); 16 - // tracks.forEach((t: Track) => console.log(t.tags)); 19 + const configurator = { 20 + output: await applet<ManagedOutput>("../../configurator/output"), 21 + }; 22 + 23 + const engine = { 24 + queue: { 25 + A: await applet<QueueEngine.State>("../../engine/queue", { groupId: idA }), 26 + B: await applet<QueueEngine.State>("../../engine/queue", { groupId: idB }), 27 + }, 28 + }; 29 + 30 + // TODO: Shuffle, limit track amount, etc. 31 + async function fill(deck: Applet<QueueEngine.State>) { 32 + const tracks = configurator.output.data.tracks.collection; 33 + 34 + await deck.sendAction("add", tracks, { 35 + timeoutDuration: 60000, 36 + }); 37 + 38 + // Automatically insert track if there isn't any 39 + if (!deck.data.now) { 40 + await deck.sendAction("shift"); 41 + } 42 + } 43 + 44 + // Add tracks to the queue once the tracks have been loaded; 45 + // and every time the collection changes. 46 + 47 + // wait(configurator.output, (d) => d?.tracks.state === "loaded").then(() => { 48 + // connect(configurator.output, (data) => data.tracks.cacheId, fill); 17 49 // });
+34 -19
src/styles/themes/blur/index.css
··· 1 1 @import "./variables.css"; 2 + @import "../../diffuse/colors.css"; 3 + @import "../../diffuse/fonts.css"; 2 4 3 5 /*********************************** 4 - * Fonts 6 + * Base 5 7 ***********************************/ 6 - :root { 7 - font-family: "Inter", sans-serif; 8 - font-size: var(--fs-base); 9 - } 10 - 11 - @supports (font-variation-settings: normal) { 12 - :root { 13 - font-family: "InterVariable", sans-serif; 14 - font-feature-settings: 15 - "ss03" 2, 16 - "ss02" 2; 17 - font-optical-sizing: auto; 18 - } 19 - } 20 - 21 8 body { 22 - background-color: var(--delicate-cloud); 23 - color: var(--made-in-the-shade); 9 + background-color: oklch(from var(--bg-color) calc(l - 0.025) c h); 10 + color: var(--text-color); 24 11 display: flex; 25 12 flex-direction: column; 26 13 overflow: hidden; ··· 50 37 width: 0; 51 38 } 52 39 53 - /* Audio is special case, iframe needs to be "visible" in order to play the audio. */ 40 + /* Audio is a special case, iframe needs to be "visible" in order to play the audio. */ 54 41 #applet__engine__audio { 55 42 height: 1px; 56 43 left: 0; ··· 60 47 top: 0; 61 48 width: 1px; 62 49 } 50 + 51 + /*********************************** 52 + * Main 53 + ***********************************/ 54 + main { 55 + display: grid; 56 + gap: var(--space-2xs); 57 + grid-template-columns: repeat(3, 1fr); 58 + grid-template-rows: auto; 59 + height: 100dvh; 60 + overflow: hidden; 61 + padding: var(--space-md) var(--space-md); 62 + 63 + & iframe { 64 + border-radius: 6px; 65 + } 66 + } 67 + 68 + /*********************************** 69 + * Applets 70 + ***********************************/ 71 + 72 + iframe[src*="/artwork-controller/"] { 73 + grid-column: 3; 74 + height: 100%; 75 + max-width: var(--container-2xs); 76 + width: 100%; 77 + }
+1 -1
src/styles/themes/pilot/index.css
··· 66 66 width: 0; 67 67 } 68 68 69 - /* Audio is special case, iframe needs to be "visible" in order to play the audio. */ 69 + /* Audio is a special case, iframe needs to be "visible" in order to play the audio. */ 70 70 #applet__engine__audio { 71 71 height: 1px; 72 72 left: 0;