jevstrudel.git / website / src / jev / SandboxNotice.jsx
SandboxNotice.jsx33 lines · 1.5 KB · raw
1// A line above the editor while its code is someone else's (sandbox.mjs):
2// whose it is, that it plays in a sandbox, and what that leaves out. When
3// the browser keeps the sandbox's audio off, it says to press the frame's
4// own button, which the page then shows.
5import { useSyncExternalStore } from 'react';
6import { sandbox } from './sandbox.mjs';
7
8export function SandboxNotice() {
9  const state = useSyncExternalStore(sandbox.subscribe, sandbox.get, sandbox.get);
10  const from = state.foreign;
11  if (!from) return null;
12  const whose = from.song ? (
13    <>
14      <b>{from.song.title}</b> by <b>{from.song.author}</b> is a listener's code
15    </>
16  ) : from.ai ? (
17    <>
18      Your AI (<b>{from.ai}</b>) played this code; its Jev calls count against your budget
19    </>
20  ) : (
21    <>This code came from a link</>
22  );
23  return (
24    <div className="border-b border-muted bg-lineHighlight text-foreground font-mono text-xs px-3 py-1 shrink-0" data-sandbox>
25      🔒 {whose}: it plays in a sandbox, apart from this page and your account (no visuals or listening party). Load
26      any site song to leave it.
27      {(state.status === 'loading' || state.status === 'playing') && state.audio && state.audio !== 'running' && (
28        <span className="text-yellow-400"> Your browser holds its sound: press ▶ in the box at the bottom right.</span>
29      )}
30      {state.status === 'error' && <span className="text-red-400"> The sandbox could not start: {state.error}</span>}
31    </div>
32  );
33}