@viji-dev/sdk 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +155 -60
- package/bin/viji.js +9 -29
- package/dist/assets/artist-dts-BHUsvSI6.js +613 -0
- package/dist/assets/artist-dts-p5-Cyw8vmy_.js +736 -0
- package/dist/assets/core-CiQx3w0t.js +12 -0
- package/dist/assets/dark-plus-C3mMm8J8.js +1 -0
- package/dist/assets/docs-api-PBLtY4Ni.js +12381 -0
- package/dist/assets/engine-javascript-CXyY7cc8.js +141 -0
- package/dist/assets/essentia-wasm.web-0S-sW98u-CYV1l1zv.js +38 -0
- package/dist/assets/essentia.js-core.es-DnrJE0uR-DOSrF5_G.js +32 -0
- package/dist/assets/glsl-DMyvO4G4.js +1 -0
- package/dist/assets/index-BhFxsauQ.js +215 -0
- package/dist/assets/index-BqhVeA7U.css +1 -0
- package/dist/assets/index-T4TOjvD0.js +1 -0
- package/dist/assets/index-Wz9WqGqz.js +52 -0
- package/dist/assets/index-t24aGwla.js +1 -0
- package/dist/assets/javascript-wDzz0qaB.js +1 -0
- package/dist/assets/shader-uniforms-GdaUkQPK.js +1 -0
- package/dist/assets/typescript-BPQ3VLAy.js +1 -0
- package/dist/assets/viji.worker-CQSJ0SiO-ljtBlcNZ.js +27018 -0
- package/{index.html → dist/index.html} +2 -1
- package/package.json +31 -35
- package/src/cli/commands/build.js +50 -99
- package/src/cli/commands/create.js +32 -47
- package/src/cli/commands/dev.js +30 -97
- package/src/cli/server/dev-server.js +233 -0
- package/src/cli/server/scene-scanner.js +93 -0
- package/src/cli/server/vite-scene-plugin.d.ts +2 -0
- package/src/cli/server/vite-scene-plugin.js +134 -0
- package/src/cli/utils/cli-utils.js +29 -139
- package/src/cli/utils/scene-compiler.js +10 -17
- package/src/templates/scene-templates.js +85 -0
- package/.gitignore +0 -29
- package/eslint.config.js +0 -37
- package/postcss.config.js +0 -6
- package/scenes/audio-visualizer/main.js +0 -287
- package/scenes/core-demo/main.js +0 -532
- package/scenes/demo-scene/main.js +0 -619
- package/scenes/global.d.ts +0 -15
- package/scenes/particle-system/main.js +0 -349
- package/scenes/tsconfig.json +0 -12
- package/scenes/video-mirror/main.ts +0 -436
- package/src/App.css +0 -42
- package/src/App.tsx +0 -279
- package/src/cli/commands/init.js +0 -262
- package/src/components/SDKPage.tsx +0 -337
- package/src/components/core/CoreContainer.tsx +0 -126
- package/src/components/ui/DeviceSelectionList.tsx +0 -137
- package/src/components/ui/FPSCounter.tsx +0 -78
- package/src/components/ui/FileDropzonePanel.tsx +0 -120
- package/src/components/ui/FileListPanel.tsx +0 -285
- package/src/components/ui/InputExpansionPanel.tsx +0 -31
- package/src/components/ui/MediaPlayerControls.tsx +0 -191
- package/src/components/ui/MenuContainer.tsx +0 -71
- package/src/components/ui/ParametersMenu.tsx +0 -797
- package/src/components/ui/ProjectSwitcherMenu.tsx +0 -192
- package/src/components/ui/QuickInputControls.tsx +0 -542
- package/src/components/ui/SDKMenuSystem.tsx +0 -96
- package/src/components/ui/SettingsMenu.tsx +0 -346
- package/src/components/ui/SimpleInputControls.tsx +0 -137
- package/src/index.css +0 -68
- package/src/main.tsx +0 -10
- package/src/scenes-hmr.ts +0 -158
- package/src/services/project-filesystem.ts +0 -436
- package/src/stores/scene-player/index.ts +0 -3
- package/src/stores/scene-player/input-manager.store.ts +0 -1045
- package/src/stores/scene-player/scene-session.store.ts +0 -659
- package/src/styles/globals.css +0 -111
- package/src/templates/minimal-template.js +0 -11
- package/src/utils/debounce.js +0 -34
- package/src/vite-env.d.ts +0 -1
- package/tailwind.config.js +0 -18
- package/tsconfig.app.json +0 -27
- package/tsconfig.json +0 -27
- package/tsconfig.node.json +0 -27
- package/vite.config.ts +0 -54
- /package/{public → dist}/favicon.png +0 -0
|
@@ -1,346 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import {
|
|
3
|
-
Card,
|
|
4
|
-
CardBody,
|
|
5
|
-
Switch,
|
|
6
|
-
Select,
|
|
7
|
-
SelectItem,
|
|
8
|
-
Button,
|
|
9
|
-
Divider,
|
|
10
|
-
Chip
|
|
11
|
-
} from '@heroui/react';
|
|
12
|
-
import {
|
|
13
|
-
CogIcon,
|
|
14
|
-
ComputerDesktopIcon,
|
|
15
|
-
EyeIcon,
|
|
16
|
-
ClockIcon
|
|
17
|
-
} from '@heroicons/react/24/outline';
|
|
18
|
-
import { useSceneSessionStore } from '../../stores/scene-player/scene-session.store';
|
|
19
|
-
|
|
20
|
-
interface SettingsMenuProps {
|
|
21
|
-
className?: string;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
const SettingsMenu: React.FC<SettingsMenuProps> = ({ className = '' }) => {
|
|
25
|
-
const showFPS = useSceneSessionStore((s) => s.uiPreferences?.showFPSCounter ?? false);
|
|
26
|
-
|
|
27
|
-
// Store selectors
|
|
28
|
-
const session = useSceneSessionStore((state) => state.session);
|
|
29
|
-
const updateCoreConfig = useSceneSessionStore((state) => state.updateCoreConfig);
|
|
30
|
-
const setShowFPSCounter = useSceneSessionStore((state) => state.setShowFPSCounter);
|
|
31
|
-
|
|
32
|
-
// Get current settings from core config
|
|
33
|
-
const currentResolution = (session?.coreConfig as any)?.resolution ?? 1.0;
|
|
34
|
-
const currentFrameRateMode = session?.coreConfig?.frameRateMode || 'full';
|
|
35
|
-
|
|
36
|
-
const handleResolutionChange = async (resolution: string) => {
|
|
37
|
-
const resolutionValue = parseFloat(resolution);
|
|
38
|
-
try {
|
|
39
|
-
await updateCoreConfig({ resolution: resolutionValue });
|
|
40
|
-
} catch (error) {
|
|
41
|
-
console.error('Failed to update resolution:', error);
|
|
42
|
-
}
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
const handleFrameRateChange = async (frameRateMode: string) => {
|
|
46
|
-
try {
|
|
47
|
-
await updateCoreConfig({ frameRateMode: frameRateMode as 'full' | 'half' });
|
|
48
|
-
} catch (error) {
|
|
49
|
-
console.error('Failed to update frame rate:', error);
|
|
50
|
-
}
|
|
51
|
-
};
|
|
52
|
-
|
|
53
|
-
const handleShowFPSChange = (show: boolean) => {
|
|
54
|
-
setShowFPSCounter(show);
|
|
55
|
-
};
|
|
56
|
-
|
|
57
|
-
const getResolutionLabel = (resolution: number) => {
|
|
58
|
-
switch (resolution) {
|
|
59
|
-
case 1.0:
|
|
60
|
-
return 'Full (1.0x)';
|
|
61
|
-
case 0.5:
|
|
62
|
-
return 'Half (0.5x)';
|
|
63
|
-
case 0.75:
|
|
64
|
-
return 'High (0.75x)';
|
|
65
|
-
case 0.25:
|
|
66
|
-
return 'Low (0.25x)';
|
|
67
|
-
default:
|
|
68
|
-
return `Custom (${resolution}x)`;
|
|
69
|
-
}
|
|
70
|
-
};
|
|
71
|
-
|
|
72
|
-
const getFrameRateLabel = (mode: string) => {
|
|
73
|
-
switch (mode) {
|
|
74
|
-
case 'full':
|
|
75
|
-
return 'Full (60 FPS)';
|
|
76
|
-
case 'half':
|
|
77
|
-
return 'Half (30 FPS)';
|
|
78
|
-
default:
|
|
79
|
-
return mode;
|
|
80
|
-
}
|
|
81
|
-
};
|
|
82
|
-
|
|
83
|
-
const resolutionOptions = [
|
|
84
|
-
{ value: '1.0', label: 'Full Resolution', description: '100% of canvas size (recommended)' },
|
|
85
|
-
{ value: '0.75', label: 'High Resolution', description: '75% of canvas size' },
|
|
86
|
-
{ value: '0.5', label: 'Half Resolution', description: '50% of canvas size' },
|
|
87
|
-
{ value: '0.25', label: 'Low Resolution', description: '25% of canvas size' },
|
|
88
|
-
];
|
|
89
|
-
|
|
90
|
-
const frameRateOptions = [
|
|
91
|
-
{ value: 'full', label: 'Full Frame Rate', description: '60 FPS (smooth)' },
|
|
92
|
-
{ value: 'half', label: 'Half Frame Rate', description: '30 FPS (battery saving)' },
|
|
93
|
-
];
|
|
94
|
-
|
|
95
|
-
// Ensure the selected keys match available options
|
|
96
|
-
const selectedResolutionKey = resolutionOptions.find(opt => parseFloat(opt.value) === currentResolution)?.value || '1.0';
|
|
97
|
-
const selectedFrameRateKey = frameRateOptions.find(opt => opt.value === currentFrameRateMode)?.value || 'full';
|
|
98
|
-
|
|
99
|
-
if (!session) {
|
|
100
|
-
return (
|
|
101
|
-
<div className="p-4 text-center text-white/60">
|
|
102
|
-
<p>No active scene</p>
|
|
103
|
-
</div>
|
|
104
|
-
);
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
return (
|
|
108
|
-
<div className={`h-full p-4 overflow-y-auto ${className}`}>
|
|
109
|
-
{/* Render Settings Section */}
|
|
110
|
-
<div className="space-y-6">
|
|
111
|
-
<Card className="bg-white/5">
|
|
112
|
-
<CardBody className="p-4">
|
|
113
|
-
<div className="flex items-center space-x-2 mb-4">
|
|
114
|
-
<ComputerDesktopIcon className="w-5 h-5 text-primary-400" />
|
|
115
|
-
<h3 className="text-white font-medium">Render Settings</h3>
|
|
116
|
-
</div>
|
|
117
|
-
|
|
118
|
-
<div className="space-y-4">
|
|
119
|
-
{/* Resolution Setting */}
|
|
120
|
-
<div>
|
|
121
|
-
<div className="flex items-center justify-between mb-2">
|
|
122
|
-
<label className="text-white text-sm font-medium">
|
|
123
|
-
Resolution
|
|
124
|
-
</label>
|
|
125
|
-
<Chip
|
|
126
|
-
size="sm"
|
|
127
|
-
variant="flat"
|
|
128
|
-
color="primary"
|
|
129
|
-
className="text-xs"
|
|
130
|
-
>
|
|
131
|
-
{getResolutionLabel(currentResolution)}
|
|
132
|
-
</Chip>
|
|
133
|
-
</div>
|
|
134
|
-
|
|
135
|
-
<Select
|
|
136
|
-
selectedKeys={[selectedResolutionKey]}
|
|
137
|
-
onSelectionChange={(keys) => {
|
|
138
|
-
const selectedValue = Array.from(keys)[0];
|
|
139
|
-
if (selectedValue) {
|
|
140
|
-
handleResolutionChange(selectedValue as string);
|
|
141
|
-
}
|
|
142
|
-
}}
|
|
143
|
-
variant="bordered"
|
|
144
|
-
size="sm"
|
|
145
|
-
className="w-full visualizer-select [&_[data-slot=value]]:!text-white [&_[data-slot=value]]:!opacity-100"
|
|
146
|
-
placeholder="Select resolution"
|
|
147
|
-
aria-label="Resolution setting"
|
|
148
|
-
classNames={{
|
|
149
|
-
trigger: "bg-black/20 border-white/20 text-white data-[hover=true]:bg-black/30",
|
|
150
|
-
label: "text-white/80",
|
|
151
|
-
value: "!text-white !opacity-100",
|
|
152
|
-
innerWrapper: "text-white",
|
|
153
|
-
selectorIcon: "text-white/60",
|
|
154
|
-
listbox: "bg-black/90",
|
|
155
|
-
popoverContent: "bg-black/90 border border-white/20"
|
|
156
|
-
}}
|
|
157
|
-
style={{
|
|
158
|
-
// @ts-ignore - Force override HeroUI CSS variables
|
|
159
|
-
"--nextui-content1": "white",
|
|
160
|
-
"--nextui-content1-foreground": "white",
|
|
161
|
-
"--nextui-foreground": "white"
|
|
162
|
-
} as any}
|
|
163
|
-
>
|
|
164
|
-
{resolutionOptions.map((option) => (
|
|
165
|
-
<SelectItem
|
|
166
|
-
key={option.value}
|
|
167
|
-
textValue={option.label}
|
|
168
|
-
className="text-white data-[hover=true]:bg-white/10"
|
|
169
|
-
|
|
170
|
-
>
|
|
171
|
-
<div className="flex flex-col">
|
|
172
|
-
<span className="text-sm font-medium text-white">{option.label}</span>
|
|
173
|
-
<span className="text-xs text-white/60">{option.description}</span>
|
|
174
|
-
</div>
|
|
175
|
-
</SelectItem>
|
|
176
|
-
))}
|
|
177
|
-
</Select>
|
|
178
|
-
|
|
179
|
-
<p className="text-xs text-white/60 mt-1">
|
|
180
|
-
Lower resolution multiplier improves performance but reduces visual quality
|
|
181
|
-
</p>
|
|
182
|
-
</div>
|
|
183
|
-
|
|
184
|
-
{/* Frame Rate Setting */}
|
|
185
|
-
<div>
|
|
186
|
-
<div className="flex items-center justify-between mb-2">
|
|
187
|
-
<label className="text-white text-sm font-medium">
|
|
188
|
-
Frame Rate
|
|
189
|
-
</label>
|
|
190
|
-
<Chip
|
|
191
|
-
size="sm"
|
|
192
|
-
variant="flat"
|
|
193
|
-
color="secondary"
|
|
194
|
-
className="text-xs"
|
|
195
|
-
>
|
|
196
|
-
{getFrameRateLabel(currentFrameRateMode)}
|
|
197
|
-
</Chip>
|
|
198
|
-
</div>
|
|
199
|
-
|
|
200
|
-
<Select
|
|
201
|
-
selectedKeys={[selectedFrameRateKey]}
|
|
202
|
-
onSelectionChange={(keys) => {
|
|
203
|
-
const selectedValue = Array.from(keys)[0];
|
|
204
|
-
if (selectedValue) {
|
|
205
|
-
handleFrameRateChange(selectedValue as string);
|
|
206
|
-
}
|
|
207
|
-
}}
|
|
208
|
-
variant="bordered"
|
|
209
|
-
size="sm"
|
|
210
|
-
className="w-full visualizer-select [&_[data-slot=value]]:!text-white [&_[data-slot=value]]:!opacity-100"
|
|
211
|
-
placeholder="Select frame rate"
|
|
212
|
-
aria-label="Frame rate setting"
|
|
213
|
-
classNames={{
|
|
214
|
-
trigger: "bg-black/20 border-white/20 text-white data-[hover=true]:bg-black/30",
|
|
215
|
-
label: "text-white/80",
|
|
216
|
-
value: "!text-white !opacity-100",
|
|
217
|
-
innerWrapper: "text-white",
|
|
218
|
-
selectorIcon: "text-white/60",
|
|
219
|
-
listbox: "bg-black/90",
|
|
220
|
-
popoverContent: "bg-black/90 border border-white/20"
|
|
221
|
-
}}
|
|
222
|
-
style={{
|
|
223
|
-
// @ts-ignore - Force override HeroUI CSS variables
|
|
224
|
-
"--nextui-content1": "white",
|
|
225
|
-
"--nextui-content1-foreground": "white",
|
|
226
|
-
"--nextui-foreground": "white"
|
|
227
|
-
} as any}
|
|
228
|
-
>
|
|
229
|
-
{frameRateOptions.map((option) => (
|
|
230
|
-
<SelectItem
|
|
231
|
-
key={option.value}
|
|
232
|
-
textValue={option.label}
|
|
233
|
-
className="text-white data-[hover=true]:bg-white/10"
|
|
234
|
-
|
|
235
|
-
>
|
|
236
|
-
<div className="flex flex-col">
|
|
237
|
-
<span className="text-sm font-medium text-white">{option.label}</span>
|
|
238
|
-
<span className="text-xs text-white/60">{option.description}</span>
|
|
239
|
-
</div>
|
|
240
|
-
</SelectItem>
|
|
241
|
-
))}
|
|
242
|
-
</Select>
|
|
243
|
-
|
|
244
|
-
<p className="text-xs text-white/60 mt-1">
|
|
245
|
-
Half frame rate reduces CPU usage and extends battery life
|
|
246
|
-
</p>
|
|
247
|
-
</div>
|
|
248
|
-
</div>
|
|
249
|
-
</CardBody>
|
|
250
|
-
</Card>
|
|
251
|
-
|
|
252
|
-
{/* Interface Settings Section */}
|
|
253
|
-
<Card className="bg-white/5">
|
|
254
|
-
<CardBody className="p-4">
|
|
255
|
-
<div className="flex items-center space-x-2 mb-4">
|
|
256
|
-
<EyeIcon className="w-5 h-5 text-secondary-400" />
|
|
257
|
-
<h3 className="text-white font-medium">Interface Settings</h3>
|
|
258
|
-
</div>
|
|
259
|
-
|
|
260
|
-
<div className="space-y-4">
|
|
261
|
-
{/* Show FPS Setting */}
|
|
262
|
-
<div className="flex items-center justify-between">
|
|
263
|
-
<div className="flex-1">
|
|
264
|
-
<div className="flex items-center space-x-2">
|
|
265
|
-
<ClockIcon className="w-4 h-4 text-white/60" />
|
|
266
|
-
<label className="text-white text-sm font-medium">
|
|
267
|
-
Show FPS Counter
|
|
268
|
-
</label>
|
|
269
|
-
</div>
|
|
270
|
-
<p className="text-xs text-white/60 mt-1">
|
|
271
|
-
Display real-time frames per second in the bottom center
|
|
272
|
-
</p>
|
|
273
|
-
</div>
|
|
274
|
-
<Switch
|
|
275
|
-
isSelected={showFPS}
|
|
276
|
-
onValueChange={handleShowFPSChange}
|
|
277
|
-
color="secondary"
|
|
278
|
-
size="sm"
|
|
279
|
-
/>
|
|
280
|
-
</div>
|
|
281
|
-
</div>
|
|
282
|
-
</CardBody>
|
|
283
|
-
</Card>
|
|
284
|
-
|
|
285
|
-
{/* Performance Info Section */}
|
|
286
|
-
<Card className="bg-white/5">
|
|
287
|
-
<CardBody className="p-4">
|
|
288
|
-
<div className="flex items-center space-x-2 mb-4">
|
|
289
|
-
<CogIcon className="w-5 h-5 text-success-400" />
|
|
290
|
-
<h3 className="text-white font-medium">Performance Info</h3>
|
|
291
|
-
</div>
|
|
292
|
-
|
|
293
|
-
<div className="space-y-3">
|
|
294
|
-
<div className="flex justify-between text-sm">
|
|
295
|
-
<span className="text-white/60">Current Resolution:</span>
|
|
296
|
-
<span className="text-white">{getResolutionLabel(currentResolution)}</span>
|
|
297
|
-
</div>
|
|
298
|
-
|
|
299
|
-
<div className="flex justify-between text-sm">
|
|
300
|
-
<span className="text-white/60">Frame Rate Mode:</span>
|
|
301
|
-
<span className="text-white">{getFrameRateLabel(currentFrameRateMode)}</span>
|
|
302
|
-
</div>
|
|
303
|
-
|
|
304
|
-
<div className="flex justify-between text-sm">
|
|
305
|
-
<span className="text-white/60">Core Status:</span>
|
|
306
|
-
<span className="text-white">
|
|
307
|
-
{session.coreInstance ? 'Active' : 'Inactive'}
|
|
308
|
-
</span>
|
|
309
|
-
</div>
|
|
310
|
-
|
|
311
|
-
<Divider className="my-3" />
|
|
312
|
-
|
|
313
|
-
<div className="text-xs text-white/40">
|
|
314
|
-
<p>Settings are applied immediately and affect performance.</p>
|
|
315
|
-
<p className="mt-1">Lower settings recommended for older devices.</p>
|
|
316
|
-
</div>
|
|
317
|
-
</div>
|
|
318
|
-
</CardBody>
|
|
319
|
-
</Card>
|
|
320
|
-
|
|
321
|
-
{/* Reset to Defaults */}
|
|
322
|
-
<div className="pt-4">
|
|
323
|
-
<Button
|
|
324
|
-
variant="flat"
|
|
325
|
-
size="sm"
|
|
326
|
-
className="w-full text-white/60 hover:text-white"
|
|
327
|
-
onPress={async () => {
|
|
328
|
-
try {
|
|
329
|
-
await updateCoreConfig({
|
|
330
|
-
frameRateMode: 'full'
|
|
331
|
-
});
|
|
332
|
-
setShowFPSCounter(false);
|
|
333
|
-
} catch (error) {
|
|
334
|
-
console.error('Failed to reset settings:', error);
|
|
335
|
-
}
|
|
336
|
-
}}
|
|
337
|
-
>
|
|
338
|
-
Reset to Defaults
|
|
339
|
-
</Button>
|
|
340
|
-
</div>
|
|
341
|
-
</div>
|
|
342
|
-
</div>
|
|
343
|
-
);
|
|
344
|
-
};
|
|
345
|
-
|
|
346
|
-
export default SettingsMenu;
|
|
@@ -1,137 +0,0 @@
|
|
|
1
|
-
import React, { useState } from 'react';
|
|
2
|
-
import { Button, Chip } from '@heroui/react';
|
|
3
|
-
import {
|
|
4
|
-
VideoCameraIcon,
|
|
5
|
-
MicrophoneIcon,
|
|
6
|
-
CursorArrowRaysIcon,
|
|
7
|
-
VideoCameraSlashIcon,
|
|
8
|
-
NoSymbolIcon
|
|
9
|
-
} from '@heroicons/react/24/outline';
|
|
10
|
-
|
|
11
|
-
interface SimpleInputControlsProps {
|
|
12
|
-
className?: string;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
const SimpleInputControls: React.FC<SimpleInputControlsProps> = ({ className = '' }) => {
|
|
16
|
-
const [audioInput, setAudioInput] = useState<'none' | 'microphone'>('none');
|
|
17
|
-
const [videoInput, setVideoInput] = useState<'none' | 'camera'>('none');
|
|
18
|
-
const [interactionEnabled, setInteractionEnabled] = useState(true);
|
|
19
|
-
|
|
20
|
-
const handleAudioToggle = () => {
|
|
21
|
-
setAudioInput(audioInput === 'none' ? 'microphone' : 'none');
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
const handleVideoToggle = () => {
|
|
25
|
-
setVideoInput(videoInput === 'none' ? 'camera' : 'none');
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
const handleInteractionToggle = () => {
|
|
29
|
-
setInteractionEnabled(!interactionEnabled);
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
const getAudioIcon = () => {
|
|
33
|
-
return audioInput === 'microphone' ? MicrophoneIcon : NoSymbolIcon;
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
const getVideoIcon = () => {
|
|
37
|
-
return videoInput === 'camera' ? VideoCameraIcon : VideoCameraSlashIcon;
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
const getInteractionIcon = () => {
|
|
41
|
-
return CursorArrowRaysIcon;
|
|
42
|
-
};
|
|
43
|
-
|
|
44
|
-
return (
|
|
45
|
-
<div className={`flex flex-col space-y-2 pointer-events-auto ${className}`}>
|
|
46
|
-
{/* Audio Input Button */}
|
|
47
|
-
<div className="flex flex-col items-center">
|
|
48
|
-
<Button
|
|
49
|
-
isIconOnly
|
|
50
|
-
variant="flat"
|
|
51
|
-
className={`
|
|
52
|
-
w-12 h-12 bg-black/40 backdrop-blur-sm border border-white/20
|
|
53
|
-
hover:bg-white/10 transition-all duration-200
|
|
54
|
-
${audioInput === 'microphone' ? 'border-primary-500 bg-primary-500/20' : ''}
|
|
55
|
-
`}
|
|
56
|
-
onPress={handleAudioToggle}
|
|
57
|
-
aria-label={audioInput === 'microphone' ? 'Disable microphone' : 'Enable microphone'}
|
|
58
|
-
>
|
|
59
|
-
{React.createElement(getAudioIcon(), {
|
|
60
|
-
className: `w-5 h-5 ${audioInput === 'microphone' ? 'text-primary-400' : 'text-white/60'}`
|
|
61
|
-
})}
|
|
62
|
-
</Button>
|
|
63
|
-
{audioInput === 'microphone' && (
|
|
64
|
-
<Chip
|
|
65
|
-
size="sm"
|
|
66
|
-
variant="flat"
|
|
67
|
-
color="primary"
|
|
68
|
-
className="text-xs mt-1"
|
|
69
|
-
>
|
|
70
|
-
Mic
|
|
71
|
-
</Chip>
|
|
72
|
-
)}
|
|
73
|
-
</div>
|
|
74
|
-
|
|
75
|
-
{/* Video Input Button */}
|
|
76
|
-
<div className="flex flex-col items-center">
|
|
77
|
-
<Button
|
|
78
|
-
isIconOnly
|
|
79
|
-
variant="flat"
|
|
80
|
-
className={`
|
|
81
|
-
w-12 h-12 bg-black/40 backdrop-blur-sm border border-white/20
|
|
82
|
-
hover:bg-white/10 transition-all duration-200
|
|
83
|
-
${videoInput === 'camera' ? 'border-primary-500 bg-primary-500/20' : ''}
|
|
84
|
-
`}
|
|
85
|
-
onPress={handleVideoToggle}
|
|
86
|
-
aria-label={videoInput === 'camera' ? 'Disable camera' : 'Enable camera'}
|
|
87
|
-
>
|
|
88
|
-
{React.createElement(getVideoIcon(), {
|
|
89
|
-
className: `w-5 h-5 ${videoInput === 'camera' ? 'text-primary-400' : 'text-white/60'}`
|
|
90
|
-
})}
|
|
91
|
-
</Button>
|
|
92
|
-
{videoInput === 'camera' && (
|
|
93
|
-
<Chip
|
|
94
|
-
size="sm"
|
|
95
|
-
variant="flat"
|
|
96
|
-
color="primary"
|
|
97
|
-
className="text-xs mt-1"
|
|
98
|
-
>
|
|
99
|
-
Cam
|
|
100
|
-
</Chip>
|
|
101
|
-
)}
|
|
102
|
-
</div>
|
|
103
|
-
|
|
104
|
-
{/* Interaction Toggle Button */}
|
|
105
|
-
<div className="flex flex-col items-center">
|
|
106
|
-
<Button
|
|
107
|
-
isIconOnly
|
|
108
|
-
variant="flat"
|
|
109
|
-
className={`
|
|
110
|
-
w-12 h-12 bg-black/40 backdrop-blur-sm border border-white/20
|
|
111
|
-
hover:bg-white/10 transition-all duration-200
|
|
112
|
-
${interactionEnabled ? 'border-primary-500 bg-primary-500/20' : ''}
|
|
113
|
-
`}
|
|
114
|
-
onPress={handleInteractionToggle}
|
|
115
|
-
aria-label={interactionEnabled ? 'Disable interactions' : 'Enable interactions'}
|
|
116
|
-
>
|
|
117
|
-
{React.createElement(getInteractionIcon(), {
|
|
118
|
-
className: `w-5 h-5 ${interactionEnabled ? 'text-primary-400' : 'text-white/60'}`
|
|
119
|
-
})}
|
|
120
|
-
</Button>
|
|
121
|
-
{interactionEnabled && (
|
|
122
|
-
<Chip
|
|
123
|
-
size="sm"
|
|
124
|
-
variant="flat"
|
|
125
|
-
color="primary"
|
|
126
|
-
className="text-xs mt-1"
|
|
127
|
-
>
|
|
128
|
-
Interactive
|
|
129
|
-
</Chip>
|
|
130
|
-
)}
|
|
131
|
-
</div>
|
|
132
|
-
</div>
|
|
133
|
-
);
|
|
134
|
-
};
|
|
135
|
-
|
|
136
|
-
export default SimpleInputControls;
|
|
137
|
-
|
package/src/index.css
DELETED
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
:root {
|
|
2
|
-
font-family: system-ui, Avenir, Helvetica, Arial, sans-serif;
|
|
3
|
-
line-height: 1.5;
|
|
4
|
-
font-weight: 400;
|
|
5
|
-
|
|
6
|
-
color-scheme: light dark;
|
|
7
|
-
color: rgba(255, 255, 255, 0.87);
|
|
8
|
-
background-color: #242424;
|
|
9
|
-
|
|
10
|
-
font-synthesis: none;
|
|
11
|
-
text-rendering: optimizeLegibility;
|
|
12
|
-
-webkit-font-smoothing: antialiased;
|
|
13
|
-
-moz-osx-font-smoothing: grayscale;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
a {
|
|
17
|
-
font-weight: 500;
|
|
18
|
-
color: #646cff;
|
|
19
|
-
text-decoration: inherit;
|
|
20
|
-
}
|
|
21
|
-
a:hover {
|
|
22
|
-
color: #535bf2;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
body {
|
|
26
|
-
margin: 0;
|
|
27
|
-
display: flex;
|
|
28
|
-
place-items: center;
|
|
29
|
-
min-width: 320px;
|
|
30
|
-
min-height: 100vh;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
h1 {
|
|
34
|
-
font-size: 3.2em;
|
|
35
|
-
line-height: 1.1;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
button {
|
|
39
|
-
border-radius: 8px;
|
|
40
|
-
border: 1px solid transparent;
|
|
41
|
-
padding: 0.6em 1.2em;
|
|
42
|
-
font-size: 1em;
|
|
43
|
-
font-weight: 500;
|
|
44
|
-
font-family: inherit;
|
|
45
|
-
background-color: #1a1a1a;
|
|
46
|
-
cursor: pointer;
|
|
47
|
-
transition: border-color 0.25s;
|
|
48
|
-
}
|
|
49
|
-
button:hover {
|
|
50
|
-
border-color: #646cff;
|
|
51
|
-
}
|
|
52
|
-
button:focus,
|
|
53
|
-
button:focus-visible {
|
|
54
|
-
outline: 4px auto -webkit-focus-ring-color;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
@media (prefers-color-scheme: light) {
|
|
58
|
-
:root {
|
|
59
|
-
color: #213547;
|
|
60
|
-
background-color: #ffffff;
|
|
61
|
-
}
|
|
62
|
-
a:hover {
|
|
63
|
-
color: #747bff;
|
|
64
|
-
}
|
|
65
|
-
button {
|
|
66
|
-
background-color: #f9f9f9;
|
|
67
|
-
}
|
|
68
|
-
}
|
package/src/main.tsx
DELETED