Spaces:
Build error
Build error
upgrade dependencies and fix README.md
Browse files- .gitattributes +1 -1
- README.md +29 -0
- package-lock.json +0 -0
- package.json +3 -3
- public/samples/claps/empty_project.clap +3 -0
- public/samples/claps/empty_project.yaml +24 -0
- src/components/editors/EntityEditor/index.tsx +199 -79
- src/components/tasks/useTasks.tsx +0 -3
- src/components/toolbars/top-menu/file/index.tsx +22 -2
- src/services/assistant/useAssistant.ts +0 -4
- src/services/audio/useAudio.ts +0 -5
- src/services/broadcast/useBroadcast.ts +0 -4
- src/services/debug.ts +36 -0
- src/services/editors/entity-editor/getDefaultEntityEditorState.ts +3 -0
- src/services/editors/entity-editor/useEntityEditor.ts +20 -8
- src/services/editors/project-editor/useProjectEditor.ts +0 -5
- src/services/editors/script-editor/useScriptEditor.ts +0 -5
- src/services/editors/segment-editor/useSegmentEditor.ts +0 -5
- src/services/editors/useEditors.ts +0 -4
- src/services/index.ts +3 -1
- src/services/io/useIO.ts +0 -4
- src/services/metrics/useMetrics.ts +0 -5
- src/services/monitor/useMonitor.ts +0 -5
- src/services/plugins/usePlugins.ts +4 -3
- src/services/renderer/useRenderer.ts +0 -4
- src/services/resolver/useResolver.ts +0 -5
- src/services/settings/useSettings.ts +0 -4
- src/services/simulator/useSimulator.ts +0 -4
- src/services/ui/theme.ts +56 -55
- src/services/ui/useUI.ts +0 -4
.gitattributes
CHANGED
@@ -2,6 +2,6 @@
|
|
2 |
*.xcf filter=lfs diff=lfs merge=lfs -text
|
3 |
*.jpeg filter=lfs diff=lfs merge=lfs -text
|
4 |
*.jpg filter=lfs diff=lfs merge=lfs -text
|
5 |
-
|
6 |
*.png filter=lfs diff=lfs merge=lfs -text
|
7 |
*.excalidraw filter=lfs diff=lfs merge=lfs -text
|
|
|
2 |
*.xcf filter=lfs diff=lfs merge=lfs -text
|
3 |
*.jpeg filter=lfs diff=lfs merge=lfs -text
|
4 |
*.jpg filter=lfs diff=lfs merge=lfs -text
|
5 |
+
*.csv filter=lfs diff=lfs merge=lfs -text
|
6 |
*.png filter=lfs diff=lfs merge=lfs -text
|
7 |
*.excalidraw filter=lfs diff=lfs merge=lfs -text
|
README.md
CHANGED
@@ -60,11 +60,40 @@ Clapper is under a GPL v3 licence, see the [LICENCE](LICENSE.txt) file for more
|
|
60 |
|
61 |
### Installation
|
62 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
63 |
```bash
|
64 |
npm i
|
65 |
npm run dev
|
66 |
```
|
67 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
68 |
### Code conventions
|
69 |
|
70 |
I haven't setup Prettier or a Linter yet.
|
|
|
60 |
|
61 |
### Installation
|
62 |
|
63 |
+
### Prerequisites
|
64 |
+
|
65 |
+
As a prerequisite you need to have [git lfs](https://git-lfs.com/) installed (see the `.gitattributes` file at the root of project):
|
66 |
+
|
67 |
+
```bash
|
68 |
+
git lfs install
|
69 |
+
```
|
70 |
+
|
71 |
+
Clapper has been tested with Node `20.9.*`.
|
72 |
+
|
73 |
+
To make sure you use this version, you can use [NVM](https://github.com/nvm-sh/nvm) to activate it:
|
74 |
+
|
75 |
+
```bash
|
76 |
+
nvm use
|
77 |
+
```
|
78 |
+
|
79 |
+
If you find that Clapper is working with a more recent (stable) version of Node, or have a better version management to suggest, please open a ticket.
|
80 |
+
|
81 |
+
### Installing and running the app
|
82 |
+
|
83 |
```bash
|
84 |
npm i
|
85 |
npm run dev
|
86 |
```
|
87 |
|
88 |
+
### Making sure everything is working properly
|
89 |
+
|
90 |
+
There are no tests yet (I will create a ticket for that),
|
91 |
+
but until then you can run the following command to make sure all the types are consistant and properly set:
|
92 |
+
|
93 |
+
```bash
|
94 |
+
npm run build
|
95 |
+
```
|
96 |
+
|
97 |
### Code conventions
|
98 |
|
99 |
I haven't setup Prettier or a Linter yet.
|
package-lock.json
CHANGED
The diff for this file is too large to render.
See raw diff
|
|
package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1 |
{
|
2 |
"name": "@aitube/clapper",
|
3 |
-
"version": "0.0.
|
4 |
"private": true,
|
5 |
"description": "🎬 Clapper",
|
6 |
"scripts": {
|
@@ -12,9 +12,9 @@
|
|
12 |
"dependencies": {
|
13 |
"@aitube/broadway": "0.0.22",
|
14 |
"@aitube/clap": "0.0.30",
|
15 |
-
"@aitube/clapper-services": "0.0.
|
16 |
"@aitube/engine": "0.0.26",
|
17 |
-
"@aitube/timeline": "0.0.
|
18 |
"@fal-ai/serverless-client": "^0.11.0",
|
19 |
"@gradio/client": "^1.1.1",
|
20 |
"@huggingface/hub": "^0.15.1",
|
|
|
1 |
{
|
2 |
"name": "@aitube/clapper",
|
3 |
+
"version": "0.0.3",
|
4 |
"private": true,
|
5 |
"description": "🎬 Clapper",
|
6 |
"scripts": {
|
|
|
12 |
"dependencies": {
|
13 |
"@aitube/broadway": "0.0.22",
|
14 |
"@aitube/clap": "0.0.30",
|
15 |
+
"@aitube/clapper-services": "0.0.22",
|
16 |
"@aitube/engine": "0.0.26",
|
17 |
+
"@aitube/timeline": "0.0.42",
|
18 |
"@fal-ai/serverless-client": "^0.11.0",
|
19 |
"@gradio/client": "^1.1.1",
|
20 |
"@huggingface/hub": "^0.15.1",
|
public/samples/claps/empty_project.clap
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:42bb7d554f5209f9c0e801c3d71b3b11730f80a2c7a39cf4ac7baf94743d7be1
|
3 |
+
size 375
|
public/samples/claps/empty_project.yaml
ADDED
@@ -0,0 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
- format: clap-0
|
2 |
+
numberOfEntities: 0
|
3 |
+
numberOfScenes: 0
|
4 |
+
numberOfSegments: 27
|
5 |
+
- id: 5ffcfd0b-cb91-465e-87b6-bde41037373e
|
6 |
+
title: ""
|
7 |
+
description: An exciting new project
|
8 |
+
synopsis: ""
|
9 |
+
licence: ""
|
10 |
+
orientation: landscape
|
11 |
+
durationInMs: 18000
|
12 |
+
width: 1024
|
13 |
+
height: 575
|
14 |
+
defaultVideoModel: AnimateDiff-Lightning
|
15 |
+
extraPositivePrompt: []
|
16 |
+
screenplay: ""
|
17 |
+
isLoop: false
|
18 |
+
isInteractive: false
|
19 |
+
- id: e16478cf-3535-48e9-98e8-f702ec9ca348
|
20 |
+
track: 0
|
21 |
+
startTimeInMs: 0
|
22 |
+
endTimeInMs: 0
|
23 |
+
category: video
|
24 |
+
outputType: video
|
src/components/editors/EntityEditor/index.tsx
CHANGED
@@ -1,88 +1,208 @@
|
|
1 |
-
import {
|
|
|
|
|
2 |
|
3 |
-
import { FormFile } from "@/components/forms/FormFile"
|
4 |
-
import { FormInput } from "@/components/forms/FormInput"
|
5 |
-
import { FormSection } from "@/components/forms/FormSection"
|
6 |
-
import {
|
7 |
-
import {
|
8 |
-
import {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
9 |
|
10 |
export function EntityEditor() {
|
11 |
-
const
|
12 |
-
|
13 |
-
|
14 |
-
const
|
15 |
-
const
|
16 |
-
|
17 |
-
const current = useEntityEditor(s => s.current)
|
18 |
-
const setCurrent = useEntityEditor(s => s.setCurrent)
|
19 |
-
|
20 |
-
const
|
21 |
-
const
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
if (!entity) {
|
27 |
-
segment = activeSegments.find(s => clap.entityIndex[s?.entityId as any])
|
28 |
-
entity = clap.entityIndex[segment?.entityId as any]
|
29 |
-
}
|
30 |
|
31 |
useEffect(() => {
|
32 |
-
setCurrent(
|
33 |
-
}, [
|
34 |
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
40 |
|
41 |
-
// TODO: adapt the editor based on the kind of
|
42 |
-
// entity (character, location..)
|
43 |
-
//
|
44 |
-
// I think we can use UI elements of our legacy character editor
|
45 |
-
// that I did in a Hugging Face space
|
46 |
return (
|
47 |
-
<
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
88 |
}
|
|
|
1 |
+
import { useEffect } from "react";
|
2 |
+
import { ClapEntity, ClapSegmentCategory, newEntity } from "@aitube/clap";
|
3 |
+
import { useTimeline } from "@aitube/timeline";
|
4 |
|
5 |
+
import { FormFile } from "@/components/forms/FormFile";
|
6 |
+
import { FormInput } from "@/components/forms/FormInput";
|
7 |
+
import { FormSection } from "@/components/forms/FormSection";
|
8 |
+
import { FormSelect } from "@/components/forms/FormSelect";
|
9 |
+
import { Button } from "@/components/ui/button";
|
10 |
+
import { useEntityEditor, useIO } from "@/services";
|
11 |
+
|
12 |
+
function EntityList({ onSelectEntity }: {
|
13 |
+
onSelectEntity: (entityId: string) => void;
|
14 |
+
}) {
|
15 |
+
const entities = useTimeline(s => s.entities);
|
16 |
+
const setCurrent = useEntityEditor(s => s.setCurrent);
|
17 |
+
const addEntity = useEntityEditor(s => s.addEntity);
|
18 |
+
const removeEntity = useEntityEditor(s => s.removeEntity);
|
19 |
+
|
20 |
+
const handleAddEntity = () => {
|
21 |
+
const entity: ClapEntity = newEntity({
|
22 |
+
id: Date.now().toString(),
|
23 |
+
label: "NEW_ENTITY",
|
24 |
+
category: ClapSegmentCategory.CHARACTER,
|
25 |
+
description: "",
|
26 |
+
appearance: "",
|
27 |
+
}); // ignoring some fields for now
|
28 |
+
addEntity(entity);
|
29 |
+
};
|
30 |
+
|
31 |
+
return (
|
32 |
+
<div className="pt-4">
|
33 |
+
<div className="mb-2">
|
34 |
+
<h1 className="px-4 mb-4 text-xl font-bold inline">Entities</h1>
|
35 |
+
<Button onClick={handleAddEntity} className="absolute top-2 right-2" variant="secondary">
|
36 |
+
New +
|
37 |
+
</Button>
|
38 |
+
</div>
|
39 |
+
<ul>
|
40 |
+
{entities.map((entity: ClapEntity) => (
|
41 |
+
<li key={entity.id} className={`flex py-1 px-2`}>
|
42 |
+
<Button
|
43 |
+
onClick={() => {
|
44 |
+
setCurrent(entity);
|
45 |
+
onSelectEntity(entity.id);
|
46 |
+
}}
|
47 |
+
variant="ghost"
|
48 |
+
>
|
49 |
+
{entity.label} ({entity.category})
|
50 |
+
</Button>
|
51 |
+
<Button onClick={() => removeEntity(entity.id)} className={`ml-2 ml-auto`} variant="destructive" size="sm">
|
52 |
+
Remove
|
53 |
+
</Button>
|
54 |
+
</li>
|
55 |
+
))}
|
56 |
+
</ul>
|
57 |
+
</div>
|
58 |
+
);
|
59 |
+
}
|
60 |
|
61 |
export function EntityEditor() {
|
62 |
+
const entities = useTimeline(s => s.entities);
|
63 |
+
const updateEntities = useTimeline(s => s.updateEntities);
|
64 |
+
|
65 |
+
const saveEntitiesToClap = useIO(s => s.saveEntitiesToClap);
|
66 |
+
const openEntitiesFromClap = useIO(s => s.openEntitiesFromClap);
|
67 |
+
|
68 |
+
const current = useEntityEditor(s => s.current);
|
69 |
+
const setCurrent = useEntityEditor(s => s.setCurrent);
|
70 |
+
|
71 |
+
const draft = useEntityEditor(s => s.draft);
|
72 |
+
const setDraft = useEntityEditor(s => s.setDraft);
|
73 |
+
|
74 |
+
const showEntityList = useEntityEditor(s => s.showEntityList);
|
75 |
+
const setShowEntityList = useEntityEditor(s => s.setShowEntityList);
|
|
|
|
|
|
|
|
|
|
|
76 |
|
77 |
useEffect(() => {
|
78 |
+
setCurrent(entities.at(0));
|
79 |
+
}, [entities, setCurrent]);
|
80 |
|
81 |
+
useEffect(() => {
|
82 |
+
setDraft(current);
|
83 |
+
}, [current, setDraft]);
|
84 |
+
|
85 |
+
const handleInputChange = (field: keyof ClapEntity, value: string | number | undefined) => {
|
86 |
+
if (!draft) { return }
|
87 |
+
let updatedValue = value;
|
88 |
+
if (field === "age") {
|
89 |
+
updatedValue = value === "" ? undefined : parseInt(value as string);
|
90 |
+
}
|
91 |
+
if (field === "label") {
|
92 |
+
updatedValue = value?.toString().toUpperCase();
|
93 |
+
}
|
94 |
+
|
95 |
+
setDraft({ ...draft, [field]: updatedValue })
|
96 |
+
};
|
97 |
+
|
98 |
+
const handleSave = () => {
|
99 |
+
if (!draft) { return }
|
100 |
+
updateEntities([ draft ]);
|
101 |
+
};
|
102 |
+
|
103 |
+
const handleFileUpload = async (field: "imageId" | "audioId", file: File) => {
|
104 |
+
if (!draft) { return }
|
105 |
+
const dataUrl = await new Promise<string>((resolve) => {
|
106 |
+
const reader = new FileReader();
|
107 |
+
reader.onload = (e) => resolve(e.target?.result as string);
|
108 |
+
reader.readAsDataURL(file);
|
109 |
+
});
|
110 |
+
setDraft({ ...draft, [field]: dataUrl });
|
111 |
+
};
|
112 |
+
|
113 |
+
const handleExport = async () => {
|
114 |
+
if (!draft) { return }
|
115 |
+
await saveEntitiesToClap([ draft ]);
|
116 |
+
};
|
117 |
+
|
118 |
+
const handleImport = async (file: File) => {
|
119 |
+
await openEntitiesFromClap(file);
|
120 |
+
};
|
121 |
+
|
122 |
+
const handleBack = () => {
|
123 |
+
setShowEntityList(true);
|
124 |
+
};
|
125 |
+
|
126 |
+
const handleSelectEntity = (entityId: string) => {
|
127 |
+
setShowEntityList(false);
|
128 |
+
};
|
129 |
|
|
|
|
|
|
|
|
|
|
|
130 |
return (
|
131 |
+
<div className="flex flex-col w-full h-full overflow-x-auto">
|
132 |
+
{showEntityList ? (
|
133 |
+
<div className="mb-4">
|
134 |
+
<EntityList onSelectEntity={handleSelectEntity} />
|
135 |
+
</div>
|
136 |
+
) : (
|
137 |
+
<div className="flex">
|
138 |
+
{draft && (
|
139 |
+
<FormSection className="px-2">
|
140 |
+
<Button onClick={handleBack}>Back</Button>
|
141 |
+
<FormInput
|
142 |
+
label="Identifier (UPPERCASE)"
|
143 |
+
value={draft.label || ""}
|
144 |
+
onChange={(value) => handleInputChange("label", value)}
|
145 |
+
/>
|
146 |
+
<FormSelect<ClapSegmentCategory>
|
147 |
+
label="Category"
|
148 |
+
selectedItemId={draft.category}
|
149 |
+
items={Object.values(ClapSegmentCategory).map((category: ClapSegmentCategory) => ({
|
150 |
+
id: category,
|
151 |
+
label: category,
|
152 |
+
value: category,
|
153 |
+
}))}
|
154 |
+
onSelect={(value) => handleInputChange("category", value)}
|
155 |
+
/>
|
156 |
+
{/* ... form fields ... */}
|
157 |
+
<FormFile
|
158 |
+
label="Visual Identity"
|
159 |
+
onChange={(files) => files[0] && handleFileUpload("imageId", files[0])}
|
160 |
+
/>
|
161 |
+
{draft.imageId && (
|
162 |
+
<div className="mt-2">
|
163 |
+
<img src={draft.imageId} alt="Entity Preview" className="max-w-full h-auto" />
|
164 |
+
</div>
|
165 |
+
)}
|
166 |
+
<FormFile
|
167 |
+
label="Audio Identity"
|
168 |
+
onChange={(files) => files[0] && handleFileUpload("audioId", files[0])}
|
169 |
+
/>
|
170 |
+
{draft.audioId && (
|
171 |
+
<div className="mt-2">
|
172 |
+
<audio controls src={draft.audioId} />
|
173 |
+
</div>
|
174 |
+
)}
|
175 |
+
<FormInput
|
176 |
+
label="Description"
|
177 |
+
value={draft.description || ""}
|
178 |
+
onChange={(value) => handleInputChange("description", value)}
|
179 |
+
/>
|
180 |
+
<FormInput
|
181 |
+
label="Appearance"
|
182 |
+
value={draft.appearance || ""}
|
183 |
+
onChange={(value) => handleInputChange("appearance", value)}
|
184 |
+
/>
|
185 |
+
<FormInput
|
186 |
+
label="Age"
|
187 |
+
value={draft.age?.toString() || ""}
|
188 |
+
onChange={(value) => handleInputChange("age", value)}
|
189 |
+
/>
|
190 |
+
<FormInput
|
191 |
+
label="Gender"
|
192 |
+
value={draft.gender || ""}
|
193 |
+
onChange={(value) => handleInputChange("gender", value)}
|
194 |
+
/>
|
195 |
+
<div className="mt-4 flex space-x-2">
|
196 |
+
<Button onClick={handleSave}>Save</Button>
|
197 |
+
<Button onClick={handleExport}>Export</Button>
|
198 |
+
</div>
|
199 |
+
<div className="mt-4 flex space-x-2">
|
200 |
+
<FormFile label="Import" onChange={(files) => files[0] && handleImport(files[0])} />
|
201 |
+
</div>
|
202 |
+
</FormSection>
|
203 |
+
)}
|
204 |
+
</div>
|
205 |
+
)}
|
206 |
+
</div>
|
207 |
+
);
|
208 |
}
|
src/components/tasks/useTasks.tsx
CHANGED
@@ -342,6 +342,3 @@ export const useTasks = create<TasksStore>((set, get) => ({
|
|
342 |
}
|
343 |
}));
|
344 |
|
345 |
-
if (typeof window !== "undefined") {
|
346 |
-
(window as any).useTasks = useTasks;
|
347 |
-
}
|
|
|
342 |
}
|
343 |
}));
|
344 |
|
|
|
|
|
|
src/components/toolbars/top-menu/file/index.tsx
CHANGED
@@ -3,10 +3,10 @@ import { useEffect } from "react"
|
|
3 |
import { useTimeline } from "@aitube/timeline"
|
4 |
import { useHotkeys } from "react-hotkeys-hook"
|
5 |
|
6 |
-
import { MenubarContent, MenubarItem, MenubarMenu, MenubarSeparator, MenubarShortcut, MenubarTrigger } from "@/components/ui/menubar"
|
7 |
import { useOpenFilePicker, useQueryStringParams } from "@/lib/hooks"
|
8 |
import { IframeWarning } from "@/components/dialogs/iframe-warning"
|
9 |
-
import { useIO } from "@/services
|
10 |
|
11 |
export function TopMenuFile() {
|
12 |
const { clapUrl } = useQueryStringParams({
|
@@ -31,6 +31,8 @@ export function TopMenuFile() {
|
|
31 |
const saveZipFile = useIO(s => s.saveZipFile)
|
32 |
const saveKdenline = useIO(s => s.saveKdenline)
|
33 |
|
|
|
|
|
34 |
useEffect(() => {
|
35 |
(async () => {
|
36 |
if (!clapUrl) {
|
@@ -55,6 +57,13 @@ export function TopMenuFile() {
|
|
55 |
<MenubarMenu>
|
56 |
<MenubarTrigger>File</MenubarTrigger>
|
57 |
<MenubarContent>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
58 |
<MenubarItem onClick={() => {
|
59 |
openFilePicker()
|
60 |
}}>
|
@@ -67,6 +76,17 @@ export function TopMenuFile() {
|
|
67 |
Save project (.clap)<MenubarShortcut>⌘S</MenubarShortcut>
|
68 |
</MenubarItem>
|
69 |
<MenubarSeparator />
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
70 |
{/*
|
71 |
<MenubarItem
|
72 |
onClick={() => {
|
|
|
3 |
import { useTimeline } from "@aitube/timeline"
|
4 |
import { useHotkeys } from "react-hotkeys-hook"
|
5 |
|
6 |
+
import { MenubarContent, MenubarItem, MenubarMenu, MenubarSeparator, MenubarShortcut, MenubarSub, MenubarSubContent, MenubarSubTrigger, MenubarTrigger } from "@/components/ui/menubar"
|
7 |
import { useOpenFilePicker, useQueryStringParams } from "@/lib/hooks"
|
8 |
import { IframeWarning } from "@/components/dialogs/iframe-warning"
|
9 |
+
import { useIO, useUI } from "@/services"
|
10 |
|
11 |
export function TopMenuFile() {
|
12 |
const { clapUrl } = useQueryStringParams({
|
|
|
31 |
const saveZipFile = useIO(s => s.saveZipFile)
|
32 |
const saveKdenline = useIO(s => s.saveKdenline)
|
33 |
|
34 |
+
const hasBetaAccess = useUI(s => s.hasBetaAccess)
|
35 |
+
|
36 |
useEffect(() => {
|
37 |
(async () => {
|
38 |
if (!clapUrl) {
|
|
|
57 |
<MenubarMenu>
|
58 |
<MenubarTrigger>File</MenubarTrigger>
|
59 |
<MenubarContent>
|
60 |
+
{hasBetaAccess &&
|
61 |
+
<MenubarItem onClick={() => {
|
62 |
+
openClapUrl('/samples/claps/empty_project.clap')
|
63 |
+
}}>
|
64 |
+
New Project<MenubarShortcut>⌘N</MenubarShortcut>
|
65 |
+
</MenubarItem>
|
66 |
+
}
|
67 |
<MenubarItem onClick={() => {
|
68 |
openFilePicker()
|
69 |
}}>
|
|
|
76 |
Save project (.clap)<MenubarShortcut>⌘S</MenubarShortcut>
|
77 |
</MenubarItem>
|
78 |
<MenubarSeparator />
|
79 |
+
<MenubarSub>
|
80 |
+
<MenubarSubTrigger>Examples</MenubarSubTrigger>
|
81 |
+
<MenubarSubContent>
|
82 |
+
<MenubarItem onClick={() => {
|
83 |
+
openClapUrl('/samples/claps/wasteland.clap')
|
84 |
+
}}>
|
85 |
+
Wasteland
|
86 |
+
</MenubarItem>
|
87 |
+
</MenubarSubContent>
|
88 |
+
</MenubarSub>
|
89 |
+
<MenubarSeparator />
|
90 |
{/*
|
91 |
<MenubarItem
|
92 |
onClick={() => {
|
src/services/assistant/useAssistant.ts
CHANGED
@@ -279,7 +279,3 @@ export function useInitAssistant() {
|
|
279 |
setVoiceTranscript(transcript)
|
280 |
}, [transcript])
|
281 |
}
|
282 |
-
|
283 |
-
if (typeof window !== "undefined") {
|
284 |
-
(window as any).useAssistant = useAssistant
|
285 |
-
}
|
|
|
279 |
setVoiceTranscript(transcript)
|
280 |
}, [transcript])
|
281 |
}
|
|
|
|
|
|
|
|
src/services/audio/useAudio.ts
CHANGED
@@ -101,8 +101,3 @@ export const useAudio = create<AudioStore>((set, get) => ({
|
|
101 |
})
|
102 |
},
|
103 |
}))
|
104 |
-
|
105 |
-
|
106 |
-
if (typeof window !== "undefined") {
|
107 |
-
(window as any).useAudio = useAudio
|
108 |
-
}
|
|
|
101 |
})
|
102 |
},
|
103 |
}))
|
|
|
|
|
|
|
|
|
|
src/services/broadcast/useBroadcast.ts
CHANGED
@@ -24,7 +24,3 @@ export const useBroadcast = create<BroadcastStore>((set, get) => ({
|
|
24 |
return isBroadcasting
|
25 |
},
|
26 |
}))
|
27 |
-
|
28 |
-
if (typeof window !== "undefined") {
|
29 |
-
(window as any).useBroadcast = useBroadcast
|
30 |
-
}
|
|
|
24 |
return isBroadcasting
|
25 |
},
|
26 |
}))
|
|
|
|
|
|
|
|
src/services/debug.ts
ADDED
@@ -0,0 +1,36 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import { useTasks } from "@/components/tasks/useTasks"
|
2 |
+
import { useAssistant } from "./assistant/useAssistant"
|
3 |
+
import { useAudio } from "./audio/useAudio"
|
4 |
+
import { useBroadcast } from "./broadcast/useBroadcast"
|
5 |
+
import { useEditors, useEntityEditor, useProjectEditor, useScriptEditor, useSegmentEditor } from "./editors"
|
6 |
+
import { useIO } from "./io/useIO"
|
7 |
+
import { useMetrics } from "./metrics/useMetrics"
|
8 |
+
import { useMonitor } from "./monitor/useMonitor"
|
9 |
+
import { useRenderer } from "./renderer/useRenderer"
|
10 |
+
import { useResolver } from "./resolver/useResolver"
|
11 |
+
import { useSettings } from "./settings/useSettings"
|
12 |
+
import { useSimulator } from "./simulator/useSimulator"
|
13 |
+
import { useUI } from "./ui/useUI"
|
14 |
+
|
15 |
+
// those are just used for developer convenience
|
16 |
+
// to help debug things in the chrome developer console
|
17 |
+
if (typeof window !== "undefined") {
|
18 |
+
const w = window as any
|
19 |
+
w.useTasks = useTasks
|
20 |
+
w.useAssistant = useAssistant
|
21 |
+
w.useAudio = useAudio
|
22 |
+
w.useBroadcast = useBroadcast
|
23 |
+
w.useEditors = useEditors
|
24 |
+
w.useEntityEditor = useEntityEditor
|
25 |
+
w.useProjectEditor = useProjectEditor
|
26 |
+
w.useScriptEditor = useScriptEditor
|
27 |
+
w.useSegmentEditor = useSegmentEditor
|
28 |
+
w.useIO = useIO
|
29 |
+
w.useMetrics = useMetrics
|
30 |
+
w.useMonitor = useMonitor
|
31 |
+
w.useRenderer = useRenderer
|
32 |
+
w.useResolver = useResolver
|
33 |
+
w.useSettings = useSettings
|
34 |
+
w.useSimulator = useSimulator
|
35 |
+
w.useUI = useUI
|
36 |
+
}
|
src/services/editors/entity-editor/getDefaultEntityEditorState.ts
CHANGED
@@ -5,6 +5,9 @@ export function getDefaultEntityEditorState(): EntityEditorState {
|
|
5 |
current: undefined,
|
6 |
version: 0,
|
7 |
history: [],
|
|
|
|
|
|
|
8 |
}
|
9 |
|
10 |
return state
|
|
|
5 |
current: undefined,
|
6 |
version: 0,
|
7 |
history: [],
|
8 |
+
|
9 |
+
draft: undefined,
|
10 |
+
showEntityList: false,
|
11 |
}
|
12 |
|
13 |
return state
|
src/services/editors/entity-editor/useEntityEditor.ts
CHANGED
@@ -1,19 +1,31 @@
|
|
1 |
-
"use client"
|
2 |
-
|
3 |
import { create } from "zustand"
|
4 |
import { ClapEntity } from "@aitube/clap"
|
5 |
import { EntityEditorStore } from "@aitube/clapper-services"
|
|
|
6 |
|
7 |
import { getDefaultEntityEditorState } from "./getDefaultEntityEditorState"
|
8 |
|
9 |
export const useEntityEditor = create<EntityEditorStore>((set, get) => ({
|
10 |
...getDefaultEntityEditorState(),
|
11 |
-
setCurrent: (current?: ClapEntity) =>
|
12 |
undo: () => {},
|
13 |
redo: () => {},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
14 |
}))
|
15 |
-
|
16 |
-
|
17 |
-
if (typeof window !== "undefined") {
|
18 |
-
(window as any).useEntityEditor = useEntityEditor
|
19 |
-
}
|
|
|
|
|
|
|
1 |
import { create } from "zustand"
|
2 |
import { ClapEntity } from "@aitube/clap"
|
3 |
import { EntityEditorStore } from "@aitube/clapper-services"
|
4 |
+
import { TimelineStore, useTimeline } from "@aitube/timeline"
|
5 |
|
6 |
import { getDefaultEntityEditorState } from "./getDefaultEntityEditorState"
|
7 |
|
8 |
export const useEntityEditor = create<EntityEditorStore>((set, get) => ({
|
9 |
...getDefaultEntityEditorState(),
|
10 |
+
setCurrent: (current?: ClapEntity) => set({ current }),
|
11 |
undo: () => {},
|
12 |
redo: () => {},
|
13 |
+
setDraft: (draft?: ClapEntity) => set({ draft }),
|
14 |
+
selectEntity: (id: string) => {
|
15 |
+
const { entityIndex }: TimelineStore = useTimeline.getState()
|
16 |
+
set({ current: entityIndex[id] })
|
17 |
+
},
|
18 |
+
addEntity: (entity: ClapEntity) => {
|
19 |
+
const { addEntities }: TimelineStore = useTimeline.getState()
|
20 |
+
addEntities([entity])
|
21 |
+
get().setCurrent(entity)
|
22 |
+
},
|
23 |
+
removeEntity: (id: string) => {
|
24 |
+
const { deleteEntities }: TimelineStore = useTimeline.getState()
|
25 |
+
deleteEntities([id])
|
26 |
+
get().setCurrent(undefined)
|
27 |
+
},
|
28 |
+
setShowEntityList: (showEntityList: boolean) => {
|
29 |
+
set({ showEntityList })
|
30 |
+
}
|
31 |
}))
|
|
|
|
|
|
|
|
|
|
src/services/editors/project-editor/useProjectEditor.ts
CHANGED
@@ -19,8 +19,3 @@ export const useProjectEditor = create<ProjectEditorStore>((set, get) => ({
|
|
19 |
undo: () => {},
|
20 |
redo: () => {},
|
21 |
}))
|
22 |
-
|
23 |
-
|
24 |
-
if (typeof window !== "undefined") {
|
25 |
-
(window as any).useProjectEditor = useProjectEditor
|
26 |
-
}
|
|
|
19 |
undo: () => {},
|
20 |
redo: () => {},
|
21 |
}))
|
|
|
|
|
|
|
|
|
|
src/services/editors/script-editor/useScriptEditor.ts
CHANGED
@@ -207,8 +207,3 @@ export const useScriptEditor = create<ScriptEditorStore>((set, get) => ({
|
|
207 |
undo: () => {},
|
208 |
redo: () => {},
|
209 |
}))
|
210 |
-
|
211 |
-
|
212 |
-
if (typeof window !== "undefined") {
|
213 |
-
(window as any).useScriptEditor = useScriptEditor
|
214 |
-
}
|
|
|
207 |
undo: () => {},
|
208 |
redo: () => {},
|
209 |
}))
|
|
|
|
|
|
|
|
|
|
src/services/editors/segment-editor/useSegmentEditor.ts
CHANGED
@@ -12,8 +12,3 @@ export const useSegmentEditor = create<SegmentEditorStore>((set, get) => ({
|
|
12 |
undo: () => {},
|
13 |
redo: () => {},
|
14 |
}))
|
15 |
-
|
16 |
-
|
17 |
-
if (typeof window !== "undefined") {
|
18 |
-
(window as any).useSegmentEditor = useSegmentEditor
|
19 |
-
}
|
|
|
12 |
undo: () => {},
|
13 |
redo: () => {},
|
14 |
}))
|
|
|
|
|
|
|
|
|
|
src/services/editors/useEditors.ts
CHANGED
@@ -10,7 +10,3 @@ export const useEditors = create<EditorsStore>((set, get) => ({
|
|
10 |
setView: (view: EditorView) => { set({ view }) },
|
11 |
}))
|
12 |
|
13 |
-
|
14 |
-
if (typeof window !== "undefined") {
|
15 |
-
(window as any).useEditors = useEditors
|
16 |
-
}
|
|
|
10 |
setView: (view: EditorView) => { set({ view }) },
|
11 |
}))
|
12 |
|
|
|
|
|
|
|
|
src/services/index.ts
CHANGED
@@ -18,4 +18,6 @@ export { useRenderer } from "./renderer/useRenderer"
|
|
18 |
export { useResolver } from "./resolver/useResolver"
|
19 |
export { useSettings } from "./settings/useSettings"
|
20 |
export { useUI } from "./ui/useUI"
|
21 |
-
export { useTasks }
|
|
|
|
|
|
18 |
export { useResolver } from "./resolver/useResolver"
|
19 |
export { useSettings } from "./settings/useSettings"
|
20 |
export { useUI } from "./ui/useUI"
|
21 |
+
export { useTasks }
|
22 |
+
|
23 |
+
import "./debug"
|
src/services/io/useIO.ts
CHANGED
@@ -766,7 +766,3 @@ export const useIO = create<IOStore>((set, get) => ({
|
|
766 |
return entities
|
767 |
},
|
768 |
}))
|
769 |
-
|
770 |
-
if (typeof window !== "undefined") {
|
771 |
-
(window as any).useIO = useIO
|
772 |
-
}
|
|
|
766 |
return entities
|
767 |
},
|
768 |
}))
|
|
|
|
|
|
|
|
src/services/metrics/useMetrics.ts
CHANGED
@@ -10,8 +10,3 @@ export const useMetrics = create<MetricsStore>((set, get) => ({
|
|
10 |
|
11 |
// TODO: add a track metric callback
|
12 |
}))
|
13 |
-
|
14 |
-
|
15 |
-
if (typeof window !== "undefined") {
|
16 |
-
(window as any).useMetrics = useMetrics
|
17 |
-
}
|
|
|
10 |
|
11 |
// TODO: add a track metric callback
|
12 |
}))
|
|
|
|
|
|
|
|
|
|
src/services/monitor/useMonitor.ts
CHANGED
@@ -147,8 +147,3 @@ setTimeout(() => {
|
|
147 |
useMonitor.getState().bindShortcuts()
|
148 |
}
|
149 |
}, 0)
|
150 |
-
|
151 |
-
|
152 |
-
if (typeof window !== "undefined") {
|
153 |
-
(window as any).useMonitor = useMonitor
|
154 |
-
}
|
|
|
147 |
useMonitor.getState().bindShortcuts()
|
148 |
}
|
149 |
}, 0)
|
|
|
|
|
|
|
|
|
|
src/services/plugins/usePlugins.ts
CHANGED
@@ -2,22 +2,22 @@
|
|
2 |
|
3 |
import { create } from "zustand"
|
4 |
import { ClapperPlugin, ClapperPluginApi, ClapperPluginMeta, PluginsStore, PublicServices } from "@aitube/clapper-services"
|
|
|
5 |
|
6 |
import { getDefaultPluginsState } from "./getDefaultPluginsState"
|
7 |
import { useScriptEditor } from "../editors/script-editor/useScriptEditor"
|
8 |
import { useMonitor } from "../monitor/useMonitor"
|
9 |
-
import {
|
10 |
import { useRenderer } from "../renderer"
|
11 |
import { useBroadcast } from "../broadcast/useBroadcast"
|
12 |
import { useResolver } from "../resolver/useResolver"
|
13 |
import { useAssistant } from "../assistant/useAssistant"
|
14 |
import { useAudio } from "../audio/useAudio"
|
15 |
import { useUI } from "../ui"
|
16 |
-
|
17 |
import { fetchAndRun } from "./fetchAndRun"
|
18 |
-
import { useTasks } from "@/components/tasks/useTasks"
|
19 |
import { useEditors, useEntityEditor, useProjectEditor, useSegmentEditor } from "../editors"
|
20 |
import { useSimulator } from "../simulator/useSimulator"
|
|
|
21 |
|
22 |
export const usePlugins = create<PluginsStore>((set, get) => ({
|
23 |
...getDefaultPluginsState(),
|
@@ -62,6 +62,7 @@ export const usePlugins = create<PluginsStore>((set, get) => ({
|
|
62 |
broadcast: useBroadcast,
|
63 |
simulator: useSimulator,
|
64 |
ui: useUI,
|
|
|
65 |
}
|
66 |
},
|
67 |
pluginApiGetSettings: async (id: string) => {
|
|
|
2 |
|
3 |
import { create } from "zustand"
|
4 |
import { ClapperPlugin, ClapperPluginApi, ClapperPluginMeta, PluginsStore, PublicServices } from "@aitube/clapper-services"
|
5 |
+
import { useTimeline } from "@aitube/timeline"
|
6 |
|
7 |
import { getDefaultPluginsState } from "./getDefaultPluginsState"
|
8 |
import { useScriptEditor } from "../editors/script-editor/useScriptEditor"
|
9 |
import { useMonitor } from "../monitor/useMonitor"
|
10 |
+
import { useTasks } from "@/components/tasks/useTasks"
|
11 |
import { useRenderer } from "../renderer"
|
12 |
import { useBroadcast } from "../broadcast/useBroadcast"
|
13 |
import { useResolver } from "../resolver/useResolver"
|
14 |
import { useAssistant } from "../assistant/useAssistant"
|
15 |
import { useAudio } from "../audio/useAudio"
|
16 |
import { useUI } from "../ui"
|
|
|
17 |
import { fetchAndRun } from "./fetchAndRun"
|
|
|
18 |
import { useEditors, useEntityEditor, useProjectEditor, useSegmentEditor } from "../editors"
|
19 |
import { useSimulator } from "../simulator/useSimulator"
|
20 |
+
import { useIO } from "../io/useIO"
|
21 |
|
22 |
export const usePlugins = create<PluginsStore>((set, get) => ({
|
23 |
...getDefaultPluginsState(),
|
|
|
62 |
broadcast: useBroadcast,
|
63 |
simulator: useSimulator,
|
64 |
ui: useUI,
|
65 |
+
io: useIO,
|
66 |
}
|
67 |
},
|
68 |
pluginApiGetSettings: async (id: string) => {
|
src/services/renderer/useRenderer.ts
CHANGED
@@ -226,7 +226,3 @@ export const useRenderer = create<RendererStore>((set, get) => ({
|
|
226 |
|
227 |
}
|
228 |
}))
|
229 |
-
|
230 |
-
if (typeof window !== "undefined") {
|
231 |
-
(window as any).useRenderer = useRenderer
|
232 |
-
}
|
|
|
226 |
|
227 |
}
|
228 |
}))
|
|
|
|
|
|
|
|
src/services/resolver/useResolver.ts
CHANGED
@@ -590,9 +590,4 @@ export const useResolver = create<ResolverStore>((set, get) => ({
|
|
590 |
}
|
591 |
return segment
|
592 |
}
|
593 |
-
|
594 |
}))
|
595 |
-
|
596 |
-
if (typeof window !== "undefined") {
|
597 |
-
(window as any).useResolver = useResolver
|
598 |
-
}
|
|
|
590 |
}
|
591 |
return segment
|
592 |
}
|
|
|
593 |
}))
|
|
|
|
|
|
|
|
src/services/settings/useSettings.ts
CHANGED
@@ -662,7 +662,3 @@ export const useSettings = create<SettingsStore>()(
|
|
662 |
},
|
663 |
),
|
664 |
)
|
665 |
-
|
666 |
-
if (typeof window !== "undefined") {
|
667 |
-
(window as any).useSettings = useSettings
|
668 |
-
}
|
|
|
662 |
},
|
663 |
),
|
664 |
)
|
|
|
|
|
|
|
|
src/services/simulator/useSimulator.ts
CHANGED
@@ -28,7 +28,3 @@ export const useSimulator = create<SimulatorStore>((set, get) => ({
|
|
28 |
return isRunning
|
29 |
}
|
30 |
}))
|
31 |
-
|
32 |
-
if (typeof window !== "undefined") {
|
33 |
-
(window as any).useSimulator = useSimulator
|
34 |
-
}
|
|
|
28 |
return isRunning
|
29 |
}
|
30 |
}))
|
|
|
|
|
|
|
|
src/services/ui/theme.ts
CHANGED
@@ -15,33 +15,31 @@
|
|
15 |
|
16 |
import { ClapSegmentCategory } from "@aitube/clap"
|
17 |
import { UITheme, UIThemeName } from "@aitube/clapper-services"
|
18 |
-
import {
|
19 |
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
[ClapSegmentCategory.
|
24 |
-
[ClapSegmentCategory.
|
25 |
-
[ClapSegmentCategory.
|
26 |
-
[ClapSegmentCategory.
|
27 |
-
[ClapSegmentCategory.
|
28 |
-
[ClapSegmentCategory.
|
29 |
-
[ClapSegmentCategory.
|
30 |
-
[ClapSegmentCategory.
|
31 |
-
[ClapSegmentCategory.
|
32 |
-
[ClapSegmentCategory.
|
33 |
-
[ClapSegmentCategory.
|
34 |
-
[ClapSegmentCategory.
|
35 |
-
[ClapSegmentCategory.
|
36 |
-
[ClapSegmentCategory.
|
37 |
-
[ClapSegmentCategory.
|
38 |
-
[ClapSegmentCategory.
|
39 |
-
[ClapSegmentCategory.
|
40 |
-
[ClapSegmentCategory.
|
41 |
-
[ClapSegmentCategory.
|
42 |
-
[ClapSegmentCategory.
|
43 |
-
[ClapSegmentCategory.CAMERA]: 10,
|
44 |
-
[ClapSegmentCategory.GENERIC]: 200,
|
45 |
}
|
46 |
|
47 |
// a grey and yellow theme, inspired by the entertainment world
|
@@ -86,9 +84,7 @@ export const backstage: UITheme = {
|
|
86 |
backgroundColor: "#27272A",
|
87 |
},
|
88 |
cell: {
|
89 |
-
|
90 |
-
lightness: 78.6,
|
91 |
-
hues: baseClapSegmentCategoryHues,
|
92 |
|
93 |
waveform: {
|
94 |
// "original" style
|
@@ -153,10 +149,7 @@ export const midnight: UITheme = {
|
|
153 |
backgroundColor: "#27372A",
|
154 |
},
|
155 |
cell: {
|
156 |
-
|
157 |
-
lightness: 78.6,
|
158 |
-
hues: baseClapSegmentCategoryHues,
|
159 |
-
|
160 |
waveform: {
|
161 |
// "original" style
|
162 |
// lineSpacing: 2,
|
@@ -219,10 +212,7 @@ export const lavender: UITheme = {
|
|
219 |
backgroundColor: "#27272A",
|
220 |
},
|
221 |
cell: {
|
222 |
-
|
223 |
-
lightness: 78.6,
|
224 |
-
hues: baseClapSegmentCategoryHues,
|
225 |
-
|
226 |
waveform: {
|
227 |
// "original" style
|
228 |
// lineSpacing: 2,
|
@@ -285,9 +275,7 @@ export const flix: UITheme = {
|
|
285 |
backgroundColor: "#27272A",
|
286 |
},
|
287 |
cell: {
|
288 |
-
|
289 |
-
lightness: 78.6,
|
290 |
-
hues: baseClapSegmentCategoryHues,
|
291 |
|
292 |
waveform: {
|
293 |
// "original" style
|
@@ -351,9 +339,7 @@ export const lore: UITheme = {
|
|
351 |
backgroundColor: "#27272A",
|
352 |
},
|
353 |
cell: {
|
354 |
-
|
355 |
-
lightness: 78.6,
|
356 |
-
hues: baseClapSegmentCategoryHues,
|
357 |
|
358 |
waveform: {
|
359 |
// "original" style
|
@@ -418,9 +404,7 @@ export const gordon: UITheme = {
|
|
418 |
backgroundColor: "#535353",
|
419 |
},
|
420 |
cell: {
|
421 |
-
|
422 |
-
lightness: 78.6,
|
423 |
-
hues: baseClapSegmentCategoryHues,
|
424 |
|
425 |
waveform: {
|
426 |
// "original" style
|
@@ -486,9 +470,7 @@ export const system360: UITheme = {
|
|
486 |
backgroundColor: "#f0f0e8",
|
487 |
},
|
488 |
cell: {
|
489 |
-
|
490 |
-
lightness: 78.6,
|
491 |
-
hues: baseClapSegmentCategoryHues,
|
492 |
|
493 |
waveform: {
|
494 |
// "original" style
|
@@ -552,9 +534,30 @@ export const silent: UITheme = {
|
|
552 |
backgroundColor: "#1f1f1f",
|
553 |
},
|
554 |
cell: {
|
555 |
-
|
556 |
-
|
557 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
558 |
|
559 |
waveform: {
|
560 |
// "original" style
|
@@ -618,9 +621,7 @@ export const sandy: UITheme = {
|
|
618 |
backgroundColor: "#b0a3a3",
|
619 |
},
|
620 |
cell: {
|
621 |
-
|
622 |
-
lightness: 78.6,
|
623 |
-
hues: baseClapSegmentCategoryHues,
|
624 |
|
625 |
waveform: {
|
626 |
// "original" style
|
|
|
15 |
|
16 |
import { ClapSegmentCategory } from "@aitube/clap"
|
17 |
import { UITheme, UIThemeName } from "@aitube/clapper-services"
|
18 |
+
import { ClapSegmentCategoryColors } from "@aitube/timeline"
|
19 |
|
20 |
+
export const baseClapSegmentCategoryColors: ClapSegmentCategoryColors = {
|
21 |
+
[ClapSegmentCategory.SPLAT]: { hue: 347, saturation: 30, lightness: 78.6 },
|
22 |
+
[ClapSegmentCategory.MESH]: { hue: 32, saturation: 30, lightness: 78.6 },
|
23 |
+
[ClapSegmentCategory.DEPTH]: { hue: 242, saturation: 30, lightness: 78.6 },
|
24 |
+
[ClapSegmentCategory.EVENT]: { hue: 270, saturation: 30, lightness: 78.6 },
|
25 |
+
[ClapSegmentCategory.INTERFACE]: { hue: 216, saturation: 30, lightness: 78.6 },
|
26 |
+
[ClapSegmentCategory.PHENOMENON]: { hue: 270, saturation: 30, lightness: 78.6 },
|
27 |
+
[ClapSegmentCategory.VIDEO]: { hue: 70, saturation: 30, lightness: 78.6 },
|
28 |
+
[ClapSegmentCategory.STORYBOARD]: { hue: 70, saturation: 30, lightness: 78.6 },
|
29 |
+
[ClapSegmentCategory.TRANSITION]: { hue: 55, saturation: 30, lightness: 78.6 },
|
30 |
+
[ClapSegmentCategory.CHARACTER]: { hue: 285.8, saturation: 30, lightness: 78.6 },
|
31 |
+
[ClapSegmentCategory.LOCATION]: { hue: 80.9, saturation: 30, lightness: 78.6 },
|
32 |
+
[ClapSegmentCategory.TIME]: { hue: 250, saturation: 30, lightness: 78.6 },
|
33 |
+
[ClapSegmentCategory.ERA]: { hue: 250, saturation: 30, lightness: 78.6 },
|
34 |
+
[ClapSegmentCategory.LIGHTING]: { hue: 50, saturation: 30, lightness: 78.6 },
|
35 |
+
[ClapSegmentCategory.WEATHER]: { hue: 197.2, saturation: 30, lightness: 78.6 },
|
36 |
+
[ClapSegmentCategory.ACTION]: { hue: 3, saturation: 30, lightness: 78.6 },
|
37 |
+
[ClapSegmentCategory.MUSIC]: { hue: 100, saturation: 30, lightness: 78.6 },
|
38 |
+
[ClapSegmentCategory.SOUND]: { hue: 60, saturation: 30, lightness: 78.6 },
|
39 |
+
[ClapSegmentCategory.DIALOGUE]: { hue: 23, saturation: 30, lightness: 78.6 },
|
40 |
+
[ClapSegmentCategory.STYLE]: { hue: 285, saturation: 30, lightness: 78.6 },
|
41 |
+
[ClapSegmentCategory.CAMERA]: { hue: 10, saturation: 30, lightness: 78.6 },
|
42 |
+
[ClapSegmentCategory.GENERIC]: { hue: 200, saturation: 30, lightness: 78.6 },
|
|
|
|
|
43 |
}
|
44 |
|
45 |
// a grey and yellow theme, inspired by the entertainment world
|
|
|
84 |
backgroundColor: "#27272A",
|
85 |
},
|
86 |
cell: {
|
87 |
+
categoryColors: baseClapSegmentCategoryColors,
|
|
|
|
|
88 |
|
89 |
waveform: {
|
90 |
// "original" style
|
|
|
149 |
backgroundColor: "#27372A",
|
150 |
},
|
151 |
cell: {
|
152 |
+
categoryColors: baseClapSegmentCategoryColors,
|
|
|
|
|
|
|
153 |
waveform: {
|
154 |
// "original" style
|
155 |
// lineSpacing: 2,
|
|
|
212 |
backgroundColor: "#27272A",
|
213 |
},
|
214 |
cell: {
|
215 |
+
categoryColors: baseClapSegmentCategoryColors,
|
|
|
|
|
|
|
216 |
waveform: {
|
217 |
// "original" style
|
218 |
// lineSpacing: 2,
|
|
|
275 |
backgroundColor: "#27272A",
|
276 |
},
|
277 |
cell: {
|
278 |
+
categoryColors: baseClapSegmentCategoryColors,
|
|
|
|
|
279 |
|
280 |
waveform: {
|
281 |
// "original" style
|
|
|
339 |
backgroundColor: "#27272A",
|
340 |
},
|
341 |
cell: {
|
342 |
+
categoryColors: baseClapSegmentCategoryColors,
|
|
|
|
|
343 |
|
344 |
waveform: {
|
345 |
// "original" style
|
|
|
404 |
backgroundColor: "#535353",
|
405 |
},
|
406 |
cell: {
|
407 |
+
categoryColors: baseClapSegmentCategoryColors,
|
|
|
|
|
408 |
|
409 |
waveform: {
|
410 |
// "original" style
|
|
|
470 |
backgroundColor: "#f0f0e8",
|
471 |
},
|
472 |
cell: {
|
473 |
+
categoryColors: baseClapSegmentCategoryColors,
|
|
|
|
|
474 |
|
475 |
waveform: {
|
476 |
// "original" style
|
|
|
534 |
backgroundColor: "#1f1f1f",
|
535 |
},
|
536 |
cell: {
|
537 |
+
categoryColors: {
|
538 |
+
[ClapSegmentCategory.SPLAT]: { hue: 347, saturation: 0, lightness: 85 },
|
539 |
+
[ClapSegmentCategory.MESH]: { hue: 32, saturation: 0, lightness: 85 },
|
540 |
+
[ClapSegmentCategory.DEPTH]: { hue: 242, saturation: 0, lightness: 85 },
|
541 |
+
[ClapSegmentCategory.EVENT]: { hue: 270, saturation: 0, lightness: 85 },
|
542 |
+
[ClapSegmentCategory.INTERFACE]: { hue: 216, saturation: 0, lightness: 85 },
|
543 |
+
[ClapSegmentCategory.PHENOMENON]: { hue: 270, saturation: 0, lightness: 85 },
|
544 |
+
[ClapSegmentCategory.VIDEO]: { hue: 70, saturation: 0, lightness: 85 },
|
545 |
+
[ClapSegmentCategory.STORYBOARD]: { hue: 70, saturation: 0, lightness: 85 },
|
546 |
+
[ClapSegmentCategory.TRANSITION]: { hue: 55, saturation: 0, lightness: 85 },
|
547 |
+
[ClapSegmentCategory.CHARACTER]: { hue: 285.8, saturation: 0, lightness: 85 },
|
548 |
+
[ClapSegmentCategory.LOCATION]: { hue: 80.9, saturation: 0, lightness: 85 },
|
549 |
+
[ClapSegmentCategory.TIME]: { hue: 250, saturation: 0, lightness: 85 },
|
550 |
+
[ClapSegmentCategory.ERA]: { hue: 250, saturation: 0, lightness: 85 },
|
551 |
+
[ClapSegmentCategory.LIGHTING]: { hue: 50, saturation: 0, lightness: 85 },
|
552 |
+
[ClapSegmentCategory.WEATHER]: { hue: 197.2, saturation: 0, lightness: 85 },
|
553 |
+
[ClapSegmentCategory.ACTION]: { hue: 3, saturation: 0, lightness: 85 },
|
554 |
+
[ClapSegmentCategory.MUSIC]: { hue: 100, saturation: 0, lightness: 85 },
|
555 |
+
[ClapSegmentCategory.SOUND]: { hue: 60, saturation: 0, lightness: 85 },
|
556 |
+
[ClapSegmentCategory.DIALOGUE]: { hue: 23, saturation: 0, lightness: 85 },
|
557 |
+
[ClapSegmentCategory.STYLE]: { hue: 285, saturation: 0, lightness: 85 },
|
558 |
+
[ClapSegmentCategory.CAMERA]: { hue: 10, saturation: 0, lightness: 85 },
|
559 |
+
[ClapSegmentCategory.GENERIC]: { hue: 200, saturation: 0, lightness: 85 },
|
560 |
+
},
|
561 |
|
562 |
waveform: {
|
563 |
// "original" style
|
|
|
621 |
backgroundColor: "#b0a3a3",
|
622 |
},
|
623 |
cell: {
|
624 |
+
categoryColors: baseClapSegmentCategoryColors,
|
|
|
|
|
625 |
|
626 |
waveform: {
|
627 |
// "original" style
|
src/services/ui/useUI.ts
CHANGED
@@ -75,7 +75,3 @@ export const useUI = create<UIStore>()(
|
|
75 |
},
|
76 |
),
|
77 |
)
|
78 |
-
|
79 |
-
if (typeof window !== "undefined") {
|
80 |
-
(window as any).useUI = useUI
|
81 |
-
}
|
|
|
75 |
},
|
76 |
),
|
77 |
)
|
|
|
|
|
|
|
|