Skip to content

Commit 39a6d17

Browse files
authored
Merge pull request #22 from stagas/help
feat: add help modal
2 parents bd64f5e + 9411ba1 commit 39a6d17

File tree

7 files changed

+167
-17
lines changed

7 files changed

+167
-17
lines changed

src/as/dsp/build.ts

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -376,9 +376,24 @@ export function TrackBuild(track: Track) {
376376
setupVm.CreateValues(context.values)
377377
setupVm.End()
378378

379-
let L = program.scope.vars['L']
380-
let R = program.scope.vars['R']
381-
let LR = program.scope.vars['LR']
379+
let L: AstNode | undefined = program.scope.vars['L']
380+
let R: AstNode | undefined = program.scope.vars['R']
381+
let LR: AstNode | undefined = program.scope.vars['LR']
382+
383+
// @ts-ignore
384+
if (L?.value?.kind !== ValueBase.Kind.Audio && L?.value?.kind !== ValueBase.Kind.Dynamic) {
385+
L = undefined
386+
}
387+
388+
// @ts-ignore
389+
if (R?.value?.kind !== ValueBase.Kind.Audio && R?.value?.kind !== ValueBase.Kind.Dynamic) {
390+
R = undefined
391+
}
392+
393+
// @ts-ignore
394+
if (LR?.value?.kind !== ValueBase.Kind.Audio && LR?.value?.kind !== ValueBase.Kind.Dynamic) {
395+
LR = undefined
396+
}
382397

383398
const slice = program.scope.stack.slice(-2)
384399
if (slice.length === 2) {
@@ -389,6 +404,33 @@ export function TrackBuild(track: Track) {
389404
LR ??= slice.pop()!
390405
}
391406

407+
// @ts-ignore
408+
if (L?.value?.kind !== ValueBase.Kind.Audio && L?.value?.kind !== ValueBase.Kind.Dynamic) {
409+
L = undefined
410+
}
411+
412+
// @ts-ignore
413+
if (R?.value?.kind !== ValueBase.Kind.Audio && R?.value?.kind !== ValueBase.Kind.Dynamic) {
414+
R = undefined
415+
}
416+
417+
// @ts-ignore
418+
if (LR?.value?.kind !== ValueBase.Kind.Audio && LR?.value?.kind !== ValueBase.Kind.Dynamic) {
419+
LR = undefined
420+
}
421+
422+
if (!LR) {
423+
if (L && R) { }
424+
else if (L) {
425+
LR = L
426+
L = undefined
427+
}
428+
else if (R) {
429+
LR = R
430+
R = undefined
431+
}
432+
}
433+
392434
const out = {
393435
L: L?.value as Value.Audio | undefined,
394436
R: R?.value as Value.Audio | undefined,

src/comp/DspEditorUi.tsx

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,11 @@ import { BUFFER_SIZE, createDspNode, PreviewService, SoundValue } from 'dsp'
22
import type { Pane } from 'editor'
33
import { Gfx, Matrix, Rect, wasm as wasmGfx } from 'gfx'
44
import type { Token } from 'lang'
5-
import { $, dispose, Sigui } from 'sigui'
5+
import { Sigui } from 'sigui'
66
import { Canvas } from 'ui'
77
import { assign, dom, Lru, throttle } from 'utils'
8-
import { cn } from '~/lib/cn.ts'
98
import { DspEditor } from '~/src/comp/DspEditor.tsx'
109
import { screen } from '~/src/screen.ts'
11-
import { state } from '~/src/state.ts'
1210
import { ListMarkWidget, RmsDecoWidget, WaveGlDecoWidget } from '~/src/ui/editor/widgets/index.ts'
1311
import { copyRingInto } from '~/src/util/copy-ring-into.ts'
1412

@@ -364,7 +362,7 @@ export function DspEditorUi() {
364362
info.el = <div class="flex flex-1">
365363
<div class="w-full h-[calc(100vh-87px)] pt-2">
366364
<div class="relative flex w-full h-full">
367-
{() => info.didBuildPane && <div class="absolute left-0 top-0 w-full h-full flex flex-row">
365+
{() => info.didBuildPane && <div class="absolute left-0 top-0 w-full h-full flex flex-col md:flex-row">
368366
{dspEditor}
369367
{canvas}
370368
</div>}

src/comp/Help.tsx

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import { getAllProps, getAllPropsDetailed, getAllPropsReverse } from 'dsp'
2+
import { H3 } from 'ui'
3+
import { keys } from 'utils'
4+
import { dspGens } from '~/generated/typescript/dsp-gens.ts'
5+
6+
const HIDDEN_PROPS = new Set<any>([
7+
'gain',
8+
])
9+
const AUDIO_PROPS = new Set<any>([
10+
'in',
11+
'sidechain',
12+
])
13+
const STACK_PROPS = new Set<any>([
14+
'in',
15+
])
16+
const HIDDEN_GENS = new Set<any>([
17+
'gen',
18+
'osc',
19+
'biquad',
20+
'moog',
21+
'svf',
22+
'dcc',
23+
'dcfix',
24+
])
25+
26+
const OPERATORS = {
27+
'=': { name: 'assign', kind: 'binary' },
28+
'?': { name: 'pick', kind: 'binary' },
29+
'+': { name: 'add', kind: 'binary' },
30+
'-': { name: 'subtract', kind: 'binary' },
31+
'*': { name: 'multiply', kind: 'binary' },
32+
'/': { name: 'divide', kind: 'binary' },
33+
'%': { name: 'modulo', kind: 'binary' },
34+
'^': { name: 'power', kind: 'binary' },
35+
}
36+
37+
export function Help() {
38+
return <div class="h-[80dvh]">
39+
<div class="flex flex-col flex-wrap gap-4">
40+
<H3>Gens</H3>
41+
<div class="h-[50dvh] flex flex-col flex-wrap gap-4">
42+
{keys(dspGens).filter(name => !HIDDEN_GENS.has(name)).map(name => {
43+
const props = getAllProps(name)
44+
return <div>
45+
<span class="text-neutral-200">{name}</span>
46+
<div class="w-20 flex flex-row flex-wrap gap-1">
47+
{props.filter(name => !HIDDEN_PROPS.has(name)).map(name =>
48+
<span class="text-xs leading-none">{name}</span>
49+
)}
50+
</div>
51+
</div>
52+
})}
53+
</div>
54+
</div>
55+
<div class="flex flex-col flex-wrap gap-4">
56+
<H3>Ops</H3>
57+
<div class="h-[15dvh] flex flex-col flex-wrap">
58+
{keys(OPERATORS).map(id => {
59+
const { name, kind } = OPERATORS[id]
60+
return <div class="flex flex-row flex-nowrap items-center gap-1">
61+
<span class="text-neutral-200">{id}</span>
62+
<span class="">{name}</span>
63+
</div>
64+
})}
65+
</div>
66+
</div>
67+
</div>
68+
}

src/comp/HelpModal.tsx

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { $ } from 'sigui'
2+
import { Help } from '~/src/comp/Help.tsx'
3+
import { state } from '~/src/state.ts'
4+
5+
export function showHelpModal() {
6+
state.modalIsCancelled = false
7+
8+
const off = $.fx(() => {
9+
const { modalIsCancelled } = state
10+
if (modalIsCancelled) {
11+
off()
12+
return
13+
}
14+
const { user } = state
15+
$()
16+
if (user == null) {
17+
state.modal = <Help />
18+
state.modalIsOpen = true
19+
state.modalIsCancelled = false
20+
}
21+
else {
22+
state.modal = null
23+
state.modalIsOpen = false
24+
queueMicrotask(() => off())
25+
}
26+
})
27+
}

src/lang/interpreter.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { dspGens } from '~/generated/typescript/dsp-gens.ts'
22
import type { DspApi } from '~/src/as/dsp/build'
33
import { getAllPropsReverse } from '~/src/as/dsp/util.ts'
4-
import type { Value } from '~/src/as/dsp/value.ts'
4+
import { Value } from '~/src/as/dsp/value.ts'
55
import { Token } from '~/src/lang/tokenize.ts'
66
import { parseNumber, type NumberFormat, type NumberInfo } from '~/src/lang/util.ts'
77

@@ -343,7 +343,9 @@ export function interpret(g: DspApi, data: Record<string, any>, tokens: Token[])
343343
if (r == null) return
344344
while (scope.stack.length) {
345345
l = scope.stack.pop() as AstNode & { value: Value }
346+
// if (l.value.kind === Value.Kind.Audio) {
346347
r = g.math.add(l.value, r)
348+
// }
347349
}
348350
const node = new AstNode(AstNode.Type.Result, { value: r }, [t])
349351
return node

src/pages/App.tsx

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
1-
import { AudioWaveform, Plus, UserCircle, UserCircle2, X } from 'lucide'
1+
import { AudioWaveform, HelpCircle, LogIn, Plus, UserCircle, UserCircle2, X } from 'lucide'
22
import { Sigui } from 'sigui'
33
import { Button, DropDown } from 'ui'
44
import { dom } from 'utils'
55
import type { z } from 'zod'
66
import type { Profiles } from '~/api/models.ts'
77
import { cn } from '~/lib/cn.ts'
88
import { icon } from '~/lib/icon.ts'
9+
import { wrapActionAuth } from '~/src/comp/AuthModal.tsx'
910
import { dspEditorUi } from '~/src/comp/DspEditorUi.tsx'
11+
import { showHelpModal } from '~/src/comp/HelpModal.tsx'
1012
import { Toast } from '~/src/comp/Toast.tsx'
1113
import { ICON_24, ICON_32, ICON_48 } from '~/src/constants.ts'
1214
import { CreateProfile } from '~/src/pages/CreateProfile.tsx'
@@ -230,8 +232,9 @@ export function App() {
230232
const Home = () => <div class="flex flex-row">
231233
<div class="flex flex-col">
232234
<div class="h-12 border-b border-b-neutral-500 text-xl flex items-center p-2 gap-1">
233-
<Link href="/">{icon(AudioWaveform, ICON_32)}</Link>
234-
<div class="leading-none">ravescript</div>
235+
<Link href="/" class="flex flex-row flex-nowrap items-center gap-1 hover:no-underline">
236+
{icon(AudioWaveform, ICON_32)} <div class="leading-none text-neutral-400">ravescript</div>
237+
</Link>
235238
</div>
236239
<div class=" h-[calc(100vh-80px)] overflow-y-scroll">
237240
<div class="flex flex-col">{() => info.profile ? [
@@ -253,12 +256,21 @@ export function App() {
253256
<div class="flex items-center">{() => getDspControls().el}</div>
254257
</div>
255258
<div class="flex items-center gap-2">{() => [
256-
<Link class="flex flex-row items-center text-lg mr-1" onclick={createSound}>
257-
{icon(Plus, ICON_32)} <span>New sound</span>
259+
<Link class="flex flex-row items-center mr-16 gap-1" onclick={showHelpModal}>
260+
<span>help</span>
261+
{icon(HelpCircle, { ...ICON_24, class: 'mb-0.5 text-neutral-400' })}
262+
</Link>,
263+
<Link class="flex flex-row items-center mr-16" onclick={createSound}>
264+
<span>new sound</span>
265+
{icon(Plus, { ...ICON_32, class: 'mb-0.5 text-neutral-400' })}
266+
</Link>,
267+
!state.user && <Link class="flex flex-row items-center gap-1" onclick={wrapActionAuth(() => { })}>
268+
<span>Login</span>
269+
{icon(LogIn, { ...ICON_24, class: 'mb-0.5 text-neutral-400' })}
258270
</Link>,
259271
...(() => !state.user ? [] : [
260-
<Link class="ml-16" href={() => `/${state.user?.defaultProfile}`}>{() => state.profile?.displayName}</Link>,
261-
<DropDown right handle={icon(UserCircle, ICON_24)} items={() => [
272+
<Link href={() => `/${state.user?.defaultProfile}`}>{() => state.profile?.displayName}</Link>,
273+
<DropDown right handle={icon(UserCircle, { ...ICON_24, class: 'mb-0.5' })} items={() => [
262274
// [<Link class="px-2 py-1 hover:no-underline flex items-center justify-end" href="/settings">Settings</Link>, () => { }],
263275
[state.user ? <Link class="px-2 py-1 hover:no-underline flex items-center justify-end" onclick={logoutUser}>Logout</Link> : <div />, () => { }],
264276
[<Link class="px-2 py-1 hover:no-underline flex items-center justify-end" href="/new-profile">New profile</Link>, () => { }],
@@ -282,7 +294,7 @@ export function App() {
282294
</div>
283295
</div>
284296

285-
const Modal = () => state.modalIsOpen && <div class="fixed w-full h-full flex items-center justify-center bg-[#111a] z-30" onpointermove={dom.prevent.stop}>
297+
const AuthModal = () => state.modalIsOpen && <div class="fixed w-full h-full flex items-center justify-center bg-[#111a] z-30" onpointermove={dom.prevent.stop}>
286298
<div class="bg-neutral-700 p-6 border-4 border-[#000] relative">
287299
<Button bare class="absolute top-0 right-0 m-1" onclick={() => {
288300
state.modalIsOpen = false
@@ -294,7 +306,7 @@ export function App() {
294306

295307
return <main class="flex flex-col relative">{() => [
296308
<Toast />,
297-
Modal(),
309+
AuthModal(),
298310
(() => {
299311
const { pathname } = state
300312
$()

tailwind.config.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ export default {
1111
theme: {
1212
fontFamily: {
1313
sans: ['"Fustat"', 'sans-serif'],
14+
mono: ['"IBM Plex Mono"', 'monospace'],
1415
},
1516
extend: {},
1617
},

0 commit comments

Comments
 (0)