Spaces:
Runtime error
Runtime error
Update .eslintrc.json, .gitattributes, and 71 more files...
Browse filesThis view is limited to 50 files because it contains too many changes.
See raw diff
- .eslintrc.json +0 -4
- .gitattributes +0 -41
- .gitignore +0 -36
- Dockerfile +2 -3
- LICENSE +0 -16
- README.md +0 -10
- components/AudioPlayer.tsx +0 -133
- components/DebugView.tsx +0 -88
- components/FallingBehindWarning.tsx +0 -12
- components/HeightMapImage.tsx +0 -52
- components/ImagePlane.tsx +0 -25
- components/Info.tsx +0 -119
- components/ModelInference.tsx +0 -214
- components/PageHead.tsx +0 -49
- components/Pause.tsx +0 -41
- components/PromptEntry.tsx +0 -271
- components/PromptPanel.tsx +0 -360
- components/RotatingBox.tsx +0 -41
- components/Settings.tsx +0 -289
- components/Share.tsx +0 -319
- components/SpectrogramViewer.tsx +0 -110
- components/ThreeCanvas.tsx +0 -39
- components/about/CaptionedImage.tsx +0 -25
- components/about/ToApp.tsx +0 -44
- external/unmute.js +0 -340
- next.config.js +0 -6
- package-lock.json +0 -0
- pages/_app.tsx +0 -14
- pages/about.tsx +0 -584
- pages/api/baseten.js +0 -17
- pages/api/server.js +0 -17
- pages/index.tsx +0 -384
- postcss.config.js +0 -6
- public/about/acoustic_folk_fiddle_solo.mp3 +0 -0
- public/about/acoustic_folk_fiddle_solo.png +0 -0
- public/about/arabic_gospel.mp3 +0 -0
- public/about/astronaut.gif +0 -3
- public/about/church_bells_to_electronic_beats.mp3 +0 -0
- public/about/detroit_rap_to_jazz_denoising_0_6_seed_50.mp3 +0 -0
- public/about/fantasy_ballad_to_teen_boy_pop_star.mp3 +0 -0
- public/about/fourier_transform.png +0 -0
- public/about/funky_sax.gif +0 -3
- public/about/funky_sax.mp3 +0 -0
- public/about/funky_sax.png +0 -0
- public/about/funky_sax_to_piano.mp3 +0 -0
- public/about/funky_sax_to_piano.png +0 -0
- public/about/hand_drawn.mp3 +0 -0
- public/about/hand_drawn_spectrogram.png +0 -0
- public/about/happy_cows_interpolation.gif +0 -3
- public/about/img2img_example.png +0 -3
.eslintrc.json
DELETED
@@ -1,4 +0,0 @@
|
|
1 |
-
{
|
2 |
-
"extends": "next/core-web-vitals",
|
3 |
-
"rules": { "react/no-unescaped-entities": 0 }
|
4 |
-
}
|
|
|
|
|
|
|
|
.gitattributes
DELETED
@@ -1,41 +0,0 @@
|
|
1 |
-
*.7z filter=lfs diff=lfs merge=lfs -text
|
2 |
-
*.arrow filter=lfs diff=lfs merge=lfs -text
|
3 |
-
*.bin filter=lfs diff=lfs merge=lfs -text
|
4 |
-
*.bz2 filter=lfs diff=lfs merge=lfs -text
|
5 |
-
*.ckpt filter=lfs diff=lfs merge=lfs -text
|
6 |
-
*.ftz filter=lfs diff=lfs merge=lfs -text
|
7 |
-
*.gz filter=lfs diff=lfs merge=lfs -text
|
8 |
-
*.h5 filter=lfs diff=lfs merge=lfs -text
|
9 |
-
*.joblib filter=lfs diff=lfs merge=lfs -text
|
10 |
-
*.lfs.* filter=lfs diff=lfs merge=lfs -text
|
11 |
-
*.mlmodel filter=lfs diff=lfs merge=lfs -text
|
12 |
-
*.model filter=lfs diff=lfs merge=lfs -text
|
13 |
-
*.msgpack filter=lfs diff=lfs merge=lfs -text
|
14 |
-
*.npy filter=lfs diff=lfs merge=lfs -text
|
15 |
-
*.npz filter=lfs diff=lfs merge=lfs -text
|
16 |
-
*.onnx filter=lfs diff=lfs merge=lfs -text
|
17 |
-
*.ot filter=lfs diff=lfs merge=lfs -text
|
18 |
-
*.parquet filter=lfs diff=lfs merge=lfs -text
|
19 |
-
*.pb filter=lfs diff=lfs merge=lfs -text
|
20 |
-
*.pickle filter=lfs diff=lfs merge=lfs -text
|
21 |
-
*.pkl filter=lfs diff=lfs merge=lfs -text
|
22 |
-
*.pt filter=lfs diff=lfs merge=lfs -text
|
23 |
-
*.pth filter=lfs diff=lfs merge=lfs -text
|
24 |
-
*.rar filter=lfs diff=lfs merge=lfs -text
|
25 |
-
*.safetensors filter=lfs diff=lfs merge=lfs -text
|
26 |
-
saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
27 |
-
*.tar.* filter=lfs diff=lfs merge=lfs -text
|
28 |
-
*.tflite filter=lfs diff=lfs merge=lfs -text
|
29 |
-
*.tgz filter=lfs diff=lfs merge=lfs -text
|
30 |
-
*.wasm filter=lfs diff=lfs merge=lfs -text
|
31 |
-
*.xz filter=lfs diff=lfs merge=lfs -text
|
32 |
-
*.zip filter=lfs diff=lfs merge=lfs -text
|
33 |
-
*.zst filter=lfs diff=lfs merge=lfs -text
|
34 |
-
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
35 |
-
public/about/astronaut.gif filter=lfs diff=lfs merge=lfs -text
|
36 |
-
public/about/funky_sax.gif filter=lfs diff=lfs merge=lfs -text
|
37 |
-
public/about/happy_cows_interpolation.gif filter=lfs diff=lfs merge=lfs -text
|
38 |
-
public/about/img2img_example.png filter=lfs diff=lfs merge=lfs -text
|
39 |
-
public/about/latent_space_interpolation.png filter=lfs diff=lfs merge=lfs -text
|
40 |
-
public/about/spectrogram_label.png filter=lfs diff=lfs merge=lfs -text
|
41 |
-
public/about/web_app_screenshot.png filter=lfs diff=lfs merge=lfs -text
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.gitignore
DELETED
@@ -1,36 +0,0 @@
|
|
1 |
-
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
2 |
-
|
3 |
-
# dependencies
|
4 |
-
/node_modules
|
5 |
-
/.pnp
|
6 |
-
.pnp.js
|
7 |
-
.env
|
8 |
-
# testing
|
9 |
-
/coverage
|
10 |
-
|
11 |
-
# next.js
|
12 |
-
/.next/
|
13 |
-
/out/
|
14 |
-
|
15 |
-
# production
|
16 |
-
/build
|
17 |
-
|
18 |
-
# misc
|
19 |
-
.DS_Store
|
20 |
-
*.pem
|
21 |
-
|
22 |
-
# debug
|
23 |
-
npm-debug.log*
|
24 |
-
yarn-debug.log*
|
25 |
-
yarn-error.log*
|
26 |
-
.pnpm-debug.log*
|
27 |
-
|
28 |
-
# local env files
|
29 |
-
.env*.local
|
30 |
-
|
31 |
-
# vercel
|
32 |
-
.vercel
|
33 |
-
|
34 |
-
# typescript
|
35 |
-
*.tsbuildinfo
|
36 |
-
next-env.d.ts
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Dockerfile
CHANGED
@@ -6,9 +6,8 @@ WORKDIR /app
|
|
6 |
RUN chown -R app /app
|
7 |
RUN chmod -R 777 /app
|
8 |
USER app
|
9 |
-
|
10 |
-
|
11 |
-
COPY . ./
|
12 |
RUN npm ci
|
13 |
COPY . .
|
14 |
|
6 |
RUN chown -R app /app
|
7 |
RUN chmod -R 777 /app
|
8 |
USER app
|
9 |
+
RUN git clone https://github.com/riffusion/riffusion-app ./
|
10 |
+
COPY package.json ./
|
|
|
11 |
RUN npm ci
|
12 |
COPY . .
|
13 |
|
LICENSE
DELETED
@@ -1,16 +0,0 @@
|
|
1 |
-
Copyright 2022 Hayk Martiros and Seth Forsgren
|
2 |
-
|
3 |
-
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
4 |
-
associated documentation files (the "Software"), to deal in the Software without restriction,
|
5 |
-
including without limitation the rights to use, copy, modify, merge, publish, distribute,
|
6 |
-
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
|
7 |
-
furnished to do so, subject to the following conditions:
|
8 |
-
|
9 |
-
The above copyright notice and this permission notice shall be included in all copies or substantial
|
10 |
-
portions of the Software.
|
11 |
-
|
12 |
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
13 |
-
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
14 |
-
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES
|
15 |
-
OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
16 |
-
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
README.md
DELETED
@@ -1,10 +0,0 @@
|
|
1 |
-
---
|
2 |
-
title: Test2
|
3 |
-
emoji: 🌍
|
4 |
-
colorFrom: purple
|
5 |
-
colorTo: blue
|
6 |
-
sdk: docker
|
7 |
-
pinned: false
|
8 |
-
---
|
9 |
-
|
10 |
-
Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
components/AudioPlayer.tsx
DELETED
@@ -1,133 +0,0 @@
|
|
1 |
-
import { useEffect, useState } from "react";
|
2 |
-
|
3 |
-
import * as Tone from "tone";
|
4 |
-
|
5 |
-
import { InferenceResult } from "../types";
|
6 |
-
|
7 |
-
interface AudioPlayerProps {
|
8 |
-
paused: boolean;
|
9 |
-
inferenceResults: InferenceResult[];
|
10 |
-
nowPlayingCallback: (result: InferenceResult, playerTime: number) => void;
|
11 |
-
playerIsBehindCallback: (isBehind: boolean) => void;
|
12 |
-
}
|
13 |
-
|
14 |
-
/**
|
15 |
-
* Audio player with Tone.js
|
16 |
-
*
|
17 |
-
* TODO(hayk): Look into https://github.com/E-Kuerschner/useAudioPlayer as an alternative.
|
18 |
-
*/
|
19 |
-
export default function AudioPlayer({
|
20 |
-
paused,
|
21 |
-
inferenceResults,
|
22 |
-
nowPlayingCallback,
|
23 |
-
playerIsBehindCallback,
|
24 |
-
}: AudioPlayerProps) {
|
25 |
-
const [tonePlayer, setTonePlayer] = useState<Tone.Player>(null);
|
26 |
-
|
27 |
-
const [numClipsPlayed, setNumClipsPlayed] = useState(0);
|
28 |
-
const [prevNumClipsPlayed, setPrevNumClipsPlayed] = useState(0);
|
29 |
-
|
30 |
-
const [resultCounter, setResultCounter] = useState(0);
|
31 |
-
|
32 |
-
// On load, create a player synced to the tone transport
|
33 |
-
useEffect(() => {
|
34 |
-
if (tonePlayer) {
|
35 |
-
return;
|
36 |
-
}
|
37 |
-
|
38 |
-
if (inferenceResults.length === 0) {
|
39 |
-
return;
|
40 |
-
}
|
41 |
-
|
42 |
-
const result = inferenceResults[0];
|
43 |
-
|
44 |
-
const player = new Tone.Player(result.audio, () => {
|
45 |
-
player.loop = true;
|
46 |
-
player.sync().start(0);
|
47 |
-
|
48 |
-
// Set up a callback to increment numClipsPlayed at the edge of each clip
|
49 |
-
const bufferLength = player.sampleTime * player.buffer.length;
|
50 |
-
|
51 |
-
// TODO(hayk): Set this callback up to vary each time using duration_s
|
52 |
-
Tone.Transport.scheduleRepeat((time) => {
|
53 |
-
setNumClipsPlayed((n) => n + 1);
|
54 |
-
}, bufferLength);
|
55 |
-
|
56 |
-
setTonePlayer(player);
|
57 |
-
|
58 |
-
// Make further load callbacks do nothing.
|
59 |
-
player.buffer.onload = () => {};
|
60 |
-
}).toDestination();
|
61 |
-
}, [tonePlayer, inferenceResults]);
|
62 |
-
|
63 |
-
// On play/pause button, play/pause the audio with the tone transport
|
64 |
-
useEffect(() => {
|
65 |
-
if (!paused) {
|
66 |
-
if (Tone.context.state == "suspended") {
|
67 |
-
Tone.context.resume();
|
68 |
-
}
|
69 |
-
|
70 |
-
if (tonePlayer) {
|
71 |
-
Tone.Transport.start();
|
72 |
-
}
|
73 |
-
} else {
|
74 |
-
if (tonePlayer) {
|
75 |
-
Tone.Transport.pause();
|
76 |
-
}
|
77 |
-
}
|
78 |
-
}, [paused, tonePlayer]);
|
79 |
-
|
80 |
-
// If there is a new clip, switch to it
|
81 |
-
useEffect(() => {
|
82 |
-
if (numClipsPlayed == prevNumClipsPlayed) {
|
83 |
-
return;
|
84 |
-
}
|
85 |
-
|
86 |
-
const maxResultCounter = Math.max(
|
87 |
-
...inferenceResults.map((r) => r.counter)
|
88 |
-
);
|
89 |
-
|
90 |
-
if (maxResultCounter < resultCounter) {
|
91 |
-
console.info(
|
92 |
-
"No new result available, looping previous clip",
|
93 |
-
resultCounter,
|
94 |
-
maxResultCounter
|
95 |
-
);
|
96 |
-
playerIsBehindCallback(true);
|
97 |
-
return;
|
98 |
-
}
|
99 |
-
|
100 |
-
playerIsBehindCallback(false);
|
101 |
-
|
102 |
-
const result = inferenceResults.find(
|
103 |
-
(r: InferenceResult) => r.counter == resultCounter
|
104 |
-
);
|
105 |
-
|
106 |
-
setResultCounter((c) => c + 1);
|
107 |
-
|
108 |
-
tonePlayer.load(result.audio).then(() => {
|
109 |
-
// Re-jigger the transport so it stops playing old buffers. It seems like this doesn't
|
110 |
-
// introduce a gap, but watch out for that.
|
111 |
-
Tone.Transport.pause();
|
112 |
-
if (!paused) {
|
113 |
-
Tone.Transport.start();
|
114 |
-
}
|
115 |
-
|
116 |
-
const playerTime = Tone.Transport.seconds;
|
117 |
-
nowPlayingCallback(result, playerTime);
|
118 |
-
});
|
119 |
-
|
120 |
-
setPrevNumClipsPlayed(numClipsPlayed);
|
121 |
-
}, [
|
122 |
-
numClipsPlayed,
|
123 |
-
prevNumClipsPlayed,
|
124 |
-
resultCounter,
|
125 |
-
inferenceResults,
|
126 |
-
paused,
|
127 |
-
nowPlayingCallback,
|
128 |
-
playerIsBehindCallback,
|
129 |
-
tonePlayer,
|
130 |
-
]);
|
131 |
-
|
132 |
-
return null;
|
133 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
components/DebugView.tsx
DELETED
@@ -1,88 +0,0 @@
|
|
1 |
-
import { Dialog } from "@headlessui/react";
|
2 |
-
import { useState } from "react";
|
3 |
-
import { ImStatsBars } from "react-icons/im";
|
4 |
-
import styled from "styled-components";
|
5 |
-
|
6 |
-
import { InferenceResult, PromptInput } from "../types";
|
7 |
-
|
8 |
-
interface DebugViewProps {
|
9 |
-
promptInputs: PromptInput[];
|
10 |
-
inferenceResults: InferenceResult[];
|
11 |
-
nowPlayingResult: InferenceResult;
|
12 |
-
open: boolean;
|
13 |
-
setOpen: (open: boolean) => void;
|
14 |
-
}
|
15 |
-
|
16 |
-
const ModalContainer = styled.div`
|
17 |
-
position: absolute;
|
18 |
-
top: 0;
|
19 |
-
left: 0;
|
20 |
-
width: 100vw;
|
21 |
-
height: 100vh;
|
22 |
-
background: rgba(0, 0, 0, 0.5);
|
23 |
-
display: flex;
|
24 |
-
align-items: center;
|
25 |
-
justify-content: center;
|
26 |
-
`;
|
27 |
-
|
28 |
-
export default function DebugView({
|
29 |
-
promptInputs,
|
30 |
-
inferenceResults,
|
31 |
-
nowPlayingResult,
|
32 |
-
open,
|
33 |
-
setOpen,
|
34 |
-
}: DebugViewProps) {
|
35 |
-
return (
|
36 |
-
<>
|
37 |
-
<Dialog
|
38 |
-
open={open}
|
39 |
-
onClose={() => setOpen(false)}
|
40 |
-
as="div"
|
41 |
-
className="fixed inset-0 z-30"
|
42 |
-
key="debug-dialog"
|
43 |
-
>
|
44 |
-
<ModalContainer key="debug-modal">
|
45 |
-
<div className="px-4 text-center text-sm whitespace-nowrap h-[40rem] w-[70rem] overflow-x-scroll">
|
46 |
-
<div className="my-8 inline-block transform rounded-2xl bg-white p-6 text-left align-middle shadow-xl transition-all">
|
47 |
-
<Dialog.Panel>
|
48 |
-
<h2 className="text-xl font-medium leading-6 text-gray-900 pb-2">
|
49 |
-
Prompt Inputs
|
50 |
-
</h2>
|
51 |
-
<div className="mt-4 font-mono">
|
52 |
-
{promptInputs.map((promptInput) => (
|
53 |
-
<div key={promptInput.prompt}>
|
54 |
-
"{promptInput.prompt}" - {promptInput.transitionCounter}
|
55 |
-
</div>
|
56 |
-
))}
|
57 |
-
</div>
|
58 |
-
<h2 className="text-xl font-medium leading-6 text-gray-900 pb-2">
|
59 |
-
Inference Results
|
60 |
-
</h2>
|
61 |
-
<div className="mt-4 font-mono">
|
62 |
-
<ul>
|
63 |
-
{inferenceResults.map((result) => (
|
64 |
-
<li
|
65 |
-
key={result.counter}
|
66 |
-
className={
|
67 |
-
result.counter === nowPlayingResult?.counter
|
68 |
-
? "text-red-700"
|
69 |
-
: "text-black"
|
70 |
-
}
|
71 |
-
>
|
72 |
-
<b>#{result.counter}</b> - Alpha{" "}
|
73 |
-
{result.input.alpha.toFixed(2)} from ("
|
74 |
-
{result.input.start.prompt}", {result.input.start.seed})
|
75 |
-
to ("
|
76 |
-
{result.input.end.prompt}", {result.input.end.seed})
|
77 |
-
</li>
|
78 |
-
))}
|
79 |
-
</ul>
|
80 |
-
</div>
|
81 |
-
</Dialog.Panel>
|
82 |
-
</div>
|
83 |
-
</div>
|
84 |
-
</ModalContainer>
|
85 |
-
</Dialog>
|
86 |
-
</>
|
87 |
-
);
|
88 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
components/FallingBehindWarning.tsx
DELETED
@@ -1,12 +0,0 @@
|
|
1 |
-
export default function FallingBehindWarning() {
|
2 |
-
return (
|
3 |
-
<div
|
4 |
-
className="fixed z-20 top-8 left-12 bg-yellow-50 border border-yellow-600 text-yellow-700 px-4 py-3 rounded"
|
5 |
-
role="alert"
|
6 |
-
>
|
7 |
-
<span className="block sm:inline mr-8">
|
8 |
-
<b>Uh oh!</b> Servers are behind, scaling up...
|
9 |
-
</span>
|
10 |
-
</div>
|
11 |
-
);
|
12 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
components/HeightMapImage.tsx
DELETED
@@ -1,52 +0,0 @@
|
|
1 |
-
import { DoubleSide, RepeatWrapping, sRGBEncoding } from "three";
|
2 |
-
import {
|
3 |
-
useTexture,
|
4 |
-
} from "@react-three/drei";
|
5 |
-
|
6 |
-
import { vertexShader, fragmentShader } from "../shaders";
|
7 |
-
|
8 |
-
interface HeightMapImageProps {
|
9 |
-
url: string;
|
10 |
-
position: [number, number, number];
|
11 |
-
rotation: [number, number, number];
|
12 |
-
scale: [number, number, number];
|
13 |
-
}
|
14 |
-
|
15 |
-
export default function HeightMapImage(props: HeightMapImageProps) {
|
16 |
-
const url = props.url;
|
17 |
-
|
18 |
-
// Load the heightmap image
|
19 |
-
const heightMap = useTexture(url);
|
20 |
-
heightMap.wrapS = RepeatWrapping;
|
21 |
-
heightMap.wrapT = RepeatWrapping;
|
22 |
-
|
23 |
-
// Load the texture map
|
24 |
-
const textureMap = useTexture(url);
|
25 |
-
textureMap.wrapS = RepeatWrapping;
|
26 |
-
textureMap.wrapT = RepeatWrapping;
|
27 |
-
|
28 |
-
return (
|
29 |
-
<mesh
|
30 |
-
position={props.position}
|
31 |
-
rotation={props.rotation}
|
32 |
-
scale={props.scale}
|
33 |
-
>
|
34 |
-
{/* TODO hayk reduce */}
|
35 |
-
<planeGeometry args={[1, 1, 256, 256]} />
|
36 |
-
<shaderMaterial
|
37 |
-
uniforms={{
|
38 |
-
// Feed the heightmap
|
39 |
-
bumpTexture: { value: heightMap },
|
40 |
-
// Feed the scaling constant for the heightmap
|
41 |
-
bumpScale: { value: -0.5 },
|
42 |
-
// Feed the texture map
|
43 |
-
terrainTexture: { value: textureMap },
|
44 |
-
}}
|
45 |
-
// Feed the shaders as strings
|
46 |
-
vertexShader={vertexShader}
|
47 |
-
fragmentShader={fragmentShader}
|
48 |
-
side={DoubleSide}
|
49 |
-
/>
|
50 |
-
</mesh>
|
51 |
-
);
|
52 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
components/ImagePlane.tsx
DELETED
@@ -1,25 +0,0 @@
|
|
1 |
-
import * as THREE from "three";
|
2 |
-
import React, { Suspense } from "react";
|
3 |
-
import { useLoader } from "@react-three/fiber";
|
4 |
-
|
5 |
-
interface ImagePlaneProps {
|
6 |
-
url: string;
|
7 |
-
height: number;
|
8 |
-
duration: number;
|
9 |
-
}
|
10 |
-
|
11 |
-
/**
|
12 |
-
* Draw an image on a plane geometry.
|
13 |
-
*/
|
14 |
-
export default function ImagePlane(props: ImagePlaneProps) {
|
15 |
-
const texture = useLoader(THREE.TextureLoader, props.url);
|
16 |
-
|
17 |
-
return (
|
18 |
-
<Suspense fallback={null}>
|
19 |
-
<mesh rotation-z={-Math.PI / 2} position-y={props.height}>
|
20 |
-
<planeGeometry attach="geometry" args={[props.duration, 5]} />
|
21 |
-
<meshBasicMaterial attach="material" map={texture} />
|
22 |
-
</mesh>
|
23 |
-
</Suspense>
|
24 |
-
);
|
25 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
components/Info.tsx
DELETED
@@ -1,119 +0,0 @@
|
|
1 |
-
import { Dialog, Transition } from "@headlessui/react";
|
2 |
-
import { Fragment, useState } from "react";
|
3 |
-
import { FiInfo } from "react-icons/fi";
|
4 |
-
import styled, { css } from "styled-components";
|
5 |
-
|
6 |
-
const ModalContainer = styled.div`
|
7 |
-
position: absolute;
|
8 |
-
top: 0;
|
9 |
-
left: 0;
|
10 |
-
width: 100vw;
|
11 |
-
height: 100vh;
|
12 |
-
background: rgba(0, 0, 0, 0.5);
|
13 |
-
display: flex;
|
14 |
-
align-items: center;
|
15 |
-
justify-content: center;
|
16 |
-
`;
|
17 |
-
|
18 |
-
export default function Info() {
|
19 |
-
const [open, setOpen] = useState(false);
|
20 |
-
|
21 |
-
var classNameCondition = ""
|
22 |
-
if (open) {
|
23 |
-
classNameCondition = "fixed z-20 top-44 right-4 md:top-48 md:right-8 bg-sky-400 w-14 h-14 rounded-full drop-shadow-lg flex justify-center items-center text-white text-2xl hover:bg-sky-500 hover:drop-shadow-2xl"
|
24 |
-
} else {
|
25 |
-
classNameCondition = "fixed z-20 top-44 right-4 md:top-48 md:right-8 bg-slate-100 w-14 h-14 rounded-full drop-shadow-lg flex justify-center items-center text-sky-900 text-2xl hover:text-white hover:bg-sky-600 hover:drop-shadow-2xl"
|
26 |
-
}
|
27 |
-
|
28 |
-
return (
|
29 |
-
<>
|
30 |
-
<button
|
31 |
-
title="Info"
|
32 |
-
className={classNameCondition}
|
33 |
-
onClick={() => setOpen(true)}
|
34 |
-
>
|
35 |
-
<FiInfo />
|
36 |
-
</button>
|
37 |
-
|
38 |
-
<Transition appear show={open} as={Fragment}>
|
39 |
-
<Dialog
|
40 |
-
as="div"
|
41 |
-
className="fixed inset-0 z-20 overflow-y-auto"
|
42 |
-
onClose={() => setOpen(false)}
|
43 |
-
>
|
44 |
-
<div className="min-h-screen px-4 text-center">
|
45 |
-
<Transition.Child
|
46 |
-
as={Fragment}
|
47 |
-
enter="ease-out duration-300"
|
48 |
-
enterFrom="opacity-0"
|
49 |
-
enterTo="opacity-100"
|
50 |
-
leave="ease-in duration-200"
|
51 |
-
leaveFrom="opacity-100"
|
52 |
-
leaveTo="opacity-0"
|
53 |
-
>
|
54 |
-
<Dialog.Overlay className="fixed inset-0" />
|
55 |
-
</Transition.Child>
|
56 |
-
|
57 |
-
<span
|
58 |
-
className="inline-block h-screen align-middle"
|
59 |
-
aria-hidden="true"
|
60 |
-
>
|
61 |
-
​
|
62 |
-
</span>
|
63 |
-
<Transition.Child
|
64 |
-
as={Fragment}
|
65 |
-
enter="ease-out duration-300"
|
66 |
-
enterFrom="opacity-0 scale-95"
|
67 |
-
enterTo="opacity-100 scale-100"
|
68 |
-
leave="ease-in duration-200"
|
69 |
-
leaveFrom="opacity-100 scale-100"
|
70 |
-
leaveTo="opacity-0 scale-95"
|
71 |
-
>
|
72 |
-
<ModalContainer>
|
73 |
-
<div className="my-8 inline-block w-full max-w-md transform overflow-hidden rounded-2xl bg-white p-6 text-left align-middle shadow-xl transition-all">
|
74 |
-
<Dialog.Title
|
75 |
-
as="h1"
|
76 |
-
className="text-3xl font-medium leading-6 text-gray-900 pb-2"
|
77 |
-
>
|
78 |
-
Welcome to Riffusion
|
79 |
-
</Dialog.Title>
|
80 |
-
<div className="mt-4">
|
81 |
-
<p className="text-sm text-gray-500">
|
82 |
-
Riffusion generates endless new jams from any text prompt. Try typing in your favorite artist or genre, and you'll hear the music gradually transform.<br></br>
|
83 |
-
<br></br>
|
84 |
-
The diffusion model first creates images from your prompt, and then converts them into music. Learn more about surfing the latent space of sound below.<br></br>
|
85 |
-
</p>
|
86 |
-
</div>
|
87 |
-
|
88 |
-
<div className="mt-6">
|
89 |
-
|
90 |
-
<button
|
91 |
-
className="relative inline-flex items-center justify-center p-0.5 mb-2 mr-2 overflow-hidden text-sm font-medium text-gray-900 rounded-lg group bg-sky-500 group-hover:from-sky-600 group-hover:to-sky-500 hover:text-white"
|
92 |
-
onClick={() => {
|
93 |
-
window.open("/about", "_blank");
|
94 |
-
setOpen(false);
|
95 |
-
}}
|
96 |
-
>
|
97 |
-
<span className="relative px-5 py-2 transition-all ease-in duration-75 bg-white rounded-md group-hover:bg-opacity-0">
|
98 |
-
Surfing the what?
|
99 |
-
</span>
|
100 |
-
</button>
|
101 |
-
|
102 |
-
<button
|
103 |
-
type="button"
|
104 |
-
className="text-white bg-gradient-to-br from-purple-600 to-sky-500 hover:bg-gradient-to-bl font-medium rounded-lg text-sm px-5 py-2.5 text-center mr-2 mb-2"
|
105 |
-
onClick={() => setOpen(false)}
|
106 |
-
>
|
107 |
-
Let's Riff 🎸
|
108 |
-
</button>
|
109 |
-
|
110 |
-
</div>
|
111 |
-
</div>
|
112 |
-
</ModalContainer>
|
113 |
-
</Transition.Child>
|
114 |
-
</div>
|
115 |
-
</Dialog>
|
116 |
-
</Transition>
|
117 |
-
</>
|
118 |
-
);
|
119 |
-
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
components/ModelInference.tsx
DELETED
@@ -1,214 +0,0 @@
|
|
1 |
-
import { useRouter } from "next/router";
|
2 |
-
import { useCallback, useEffect, useState } from "react";
|
3 |
-
|
4 |
-
import {
|
5 |
-
AppState,
|
6 |
-
InferenceInput,
|
7 |
-
InferenceResult,
|
8 |
-
PromptInput,
|
9 |
-
} from "../types";
|
10 |
-
|
11 |
-
interface ModelInferenceProps {
|
12 |
-
alpha: number;
|
13 |
-
alphaRollover: boolean;
|
14 |
-
seed: number;
|
15 |
-
appState: AppState;
|
16 |
-
promptInputs: PromptInput[];
|
17 |
-
nowPlayingResult: InferenceResult;
|
18 |
-
newResultCallback: (input: InferenceInput, result: InferenceResult) => void;
|
19 |
-
useBaseten: boolean;
|
20 |
-
denoising: number;
|
21 |
-
seedImageId: string;
|
22 |
-
}
|
23 |
-
|
24 |
-
/**
|
25 |
-
* Calls the server to run model inference.
|
26 |
-
*
|
27 |
-
*
|
28 |
-
*/
|
29 |
-
export default function ModelInference({
|
30 |
-
alpha,
|
31 |
-
alphaRollover,
|
32 |
-
seed,
|
33 |
-
appState,
|
34 |
-
promptInputs,
|
35 |
-
nowPlayingResult,
|
36 |
-
newResultCallback,
|
37 |
-
useBaseten,
|
38 |
-
denoising,
|
39 |
-
seedImageId,
|
40 |
-
}: ModelInferenceProps) {
|
41 |
-
// Create parameters for the inference request
|
42 |
-
const [guidance, setGuidance] = useState(7.0);
|
43 |
-
const [numInferenceSteps, setNumInferenceSteps] = useState(50);
|
44 |
-
const [maskImageId, setMaskImageId] = useState(null);
|
45 |
-
|
46 |
-
const [initializedUrlParams, setInitializedUrlParams] = useState(false);
|
47 |
-
const [numRequestsMade, setNumRequestsMade] = useState(0);
|
48 |
-
const [numResponsesReceived, setNumResponsesReceived] = useState(0);
|
49 |
-
|
50 |
-
useEffect(() => {
|
51 |
-
console.log("Using baseten: ", useBaseten);
|
52 |
-
}, [useBaseten]);
|
53 |
-
|
54 |
-
// Set initial params from URL query strings
|
55 |
-
const router = useRouter();
|
56 |
-
useEffect(() => {
|
57 |
-
if (router.query.guidance) {
|
58 |
-
setGuidance(parseFloat(router.query.guidance as string));
|
59 |
-
}
|
60 |
-
|
61 |
-
if (router.query.numInferenceSteps) {
|
62 |
-
setNumInferenceSteps(parseInt(router.query.numInferenceSteps as string));
|
63 |
-
}
|
64 |
-
|
65 |
-
if (router.query.maskImageId) {
|
66 |
-
if (router.query.maskImageId === "none") {
|
67 |
-
setMaskImageId("");
|
68 |
-
} else {
|
69 |
-
setMaskImageId(router.query.maskImageId as string);
|
70 |
-
}
|
71 |
-
}
|
72 |
-
|
73 |
-
setInitializedUrlParams(true);
|
74 |
-
}, [router.query]);
|
75 |
-
|
76 |
-
// Memoized function to kick off an inference request
|
77 |
-
const runInference = useCallback(
|
78 |
-
async (
|
79 |
-
alpha: number,
|
80 |
-
seed: number,
|
81 |
-
appState: AppState,
|
82 |
-
promptInputs: PromptInput[]
|
83 |
-
) => {
|
84 |
-
const startPrompt = promptInputs[promptInputs.length - 3].prompt;
|
85 |
-
const endPrompt = promptInputs[promptInputs.length - 2].prompt;
|
86 |
-
|
87 |
-
const transitioning = appState == AppState.TRANSITION;
|
88 |
-
|
89 |
-
const inferenceInput = {
|
90 |
-
alpha: alpha,
|
91 |
-
num_inference_steps: numInferenceSteps,
|
92 |
-
seed_image_id: seedImageId,
|
93 |
-
mask_image_id: maskImageId,
|
94 |
-
start: {
|
95 |
-
prompt: startPrompt,
|
96 |
-
seed: seed,
|
97 |
-
denoising: denoising,
|
98 |
-
guidance: guidance,
|
99 |
-
},
|
100 |
-
end: {
|
101 |
-
prompt: transitioning ? endPrompt : startPrompt,
|
102 |
-
seed: transitioning ? seed : seed + 1,
|
103 |
-
denoising: denoising,
|
104 |
-
guidance: guidance,
|
105 |
-
},
|
106 |
-
};
|
107 |
-
|
108 |
-
console.log(`Inference #${numRequestsMade}: `, {
|
109 |
-
alpha: alpha,
|
110 |
-
prompt_a: inferenceInput.start.prompt,
|
111 |
-
seed_a: inferenceInput.start.seed,
|
112 |
-
prompt_b: inferenceInput.end.prompt,
|
113 |
-
seed_b: inferenceInput.end.seed,
|
114 |
-
appState: appState,
|
115 |
-
});
|
116 |
-
|
117 |
-
setNumRequestsMade((n) => n + 1);
|
118 |
-
|
119 |
-
// Customize for baseten
|
120 |
-
const apiHandler = useBaseten ? "/api/baseten" : "/api/server";
|
121 |
-
const payload = useBaseten
|
122 |
-
? { worklet_input: inferenceInput }
|
123 |
-
: inferenceInput;
|
124 |
-
|
125 |
-
const response = await fetch(apiHandler, {
|
126 |
-
method: "POST",
|
127 |
-
body: JSON.stringify(payload),
|
128 |
-
});
|
129 |
-
|
130 |
-
const data = await response.json();
|
131 |
-
|
132 |
-
console.log(`Got result #${numResponsesReceived}`);
|
133 |
-
|
134 |
-
if (useBaseten) {
|
135 |
-
if (data?.worklet_output?.model_output) {
|
136 |
-
newResultCallback(
|
137 |
-
inferenceInput,
|
138 |
-
JSON.parse(data.worklet_output.model_output)
|
139 |
-
);
|
140 |
-
}
|
141 |
-
// Note, data is currently wrapped in a data field
|
142 |
-
else if (data?.data?.worklet_output?.model_output) {
|
143 |
-
newResultCallback(
|
144 |
-
inferenceInput,
|
145 |
-
JSON.parse(data.data.worklet_output.model_output)
|
146 |
-
);
|
147 |
-
} else {
|
148 |
-
console.error("Baseten call failed: ", data);
|
149 |
-
}
|
150 |
-
} else {
|
151 |
-
// Note, data is currently wrapped in a data field
|
152 |
-
newResultCallback(inferenceInput, data.data);
|
153 |
-
}
|
154 |
-
|
155 |
-
setNumResponsesReceived((n) => n + 1);
|
156 |
-
},
|
157 |
-
[
|
158 |
-
denoising,
|
159 |
-
guidance,
|
160 |
-
maskImageId,
|
161 |
-
numInferenceSteps,
|
162 |
-
seedImageId,
|
163 |
-
newResultCallback,
|
164 |
-
numRequestsMade,
|
165 |
-
numResponsesReceived,
|
166 |
-
useBaseten,
|
167 |
-
]
|
168 |
-
);
|
169 |
-
|
170 |
-
// Kick off inference requests
|
171 |
-
useEffect(() => {
|
172 |
-
// Make sure things are initialized properly
|
173 |
-
if (
|
174 |
-
!initializedUrlParams ||
|
175 |
-
appState == AppState.UNINITIALIZED ||
|
176 |
-
promptInputs.length == 0
|
177 |
-
) {
|
178 |
-
return;
|
179 |
-
}
|
180 |
-
|
181 |
-
// Wait for alpha rollover to resolve.
|
182 |
-
if (alphaRollover) {
|
183 |
-
return;
|
184 |
-
}
|
185 |
-
|
186 |
-
if (numRequestsMade == 0) {
|
187 |
-
// Kick off the first request
|
188 |
-
runInference(alpha, seed, appState, promptInputs);
|
189 |
-
} else if (numRequestsMade == numResponsesReceived) {
|
190 |
-
// Otherwise buffer ahead a few from where the audio player currently is
|
191 |
-
// TODO(hayk): Replace this with better buffer management
|
192 |
-
|
193 |
-
const nowPlayingCounter = nowPlayingResult ? nowPlayingResult.counter : 0;
|
194 |
-
const numAhead = numRequestsMade - nowPlayingCounter;
|
195 |
-
|
196 |
-
if (numAhead < 3) {
|
197 |
-
runInference(alpha, seed, appState, promptInputs);
|
198 |
-
}
|
199 |
-
}
|
200 |
-
}, [
|
201 |
-
initializedUrlParams,
|
202 |
-
alpha,
|
203 |
-
alphaRollover,
|
204 |
-
seed,
|
205 |
-
appState,
|
206 |
-
promptInputs,
|
207 |
-
nowPlayingResult,
|
208 |
-
numRequestsMade,
|
209 |
-
numResponsesReceived,
|
210 |
-
runInference,
|
211 |
-
]);
|
212 |
-
|
213 |
-
return null;
|
214 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
components/PageHead.tsx
DELETED
@@ -1,49 +0,0 @@
|
|
1 |
-
import Head from "next/head";
|
2 |
-
|
3 |
-
export default function PageHead() {
|
4 |
-
return (
|
5 |
-
<Head>
|
6 |
-
<title>Riffusion</title>
|
7 |
-
<meta property="og:site_name" content="Riffusion" />
|
8 |
-
|
9 |
-
<meta
|
10 |
-
property="article:author"
|
11 |
-
content="Seth Forsgren and Hayk Martiros"
|
12 |
-
/>
|
13 |
-
|
14 |
-
<meta property="article:tag" content="music" />
|
15 |
-
<meta property="article:tag" content="machine learning" />
|
16 |
-
<meta property="article:tag" content="artificial intelligence" />
|
17 |
-
<meta property="article:tag" content="generative music" />
|
18 |
-
|
19 |
-
<meta property="og:title" content="Riffusion" />
|
20 |
-
<meta name="twitter:title" content="Riffusion" />
|
21 |
-
|
22 |
-
<meta
|
23 |
-
name="description"
|
24 |
-
content="Stable diffusion for real-time music generation"
|
25 |
-
/>
|
26 |
-
<meta
|
27 |
-
name="og:description"
|
28 |
-
content="Stable diffusion for real-time music generation"
|
29 |
-
/>
|
30 |
-
<meta
|
31 |
-
name="twitter:description"
|
32 |
-
content="Stable diffusion for real-time music generation"
|
33 |
-
/>
|
34 |
-
|
35 |
-
<meta name="twitter:card" content="summary" />
|
36 |
-
|
37 |
-
<meta property="og:image" content="https://i.imgur.com/fywZpQ7.jpeg" />
|
38 |
-
<meta name="twitter:image" content="https://i.imgur.com/fywZpQ7.jpeg" />
|
39 |
-
|
40 |
-
<meta property="og:type" content="website" />
|
41 |
-
|
42 |
-
<meta property="og:url" content="http://www.riffusion." />
|
43 |
-
<meta property="og:locale" content="en_US" />
|
44 |
-
<meta property="og:website" content="http://wwww.riffusion" />
|
45 |
-
|
46 |
-
<link rel="icon" href="/favicon.ico" />
|
47 |
-
</Head>
|
48 |
-
);
|
49 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
components/Pause.tsx
DELETED
@@ -1,41 +0,0 @@
|
|
1 |
-
import { useEffect } from "react";
|
2 |
-
import { FiPause, FiPlay } from "react-icons/fi";
|
3 |
-
|
4 |
-
interface PauseProps {
|
5 |
-
paused: boolean;
|
6 |
-
setPaused: (value: boolean) => void;
|
7 |
-
}
|
8 |
-
|
9 |
-
export default function Pause({
|
10 |
-
paused,
|
11 |
-
setPaused,
|
12 |
-
}: PauseProps) {
|
13 |
-
|
14 |
-
// Print the state into the console
|
15 |
-
useEffect(() => {
|
16 |
-
if (paused) {
|
17 |
-
console.log("Pause");
|
18 |
-
} else {
|
19 |
-
console.log("Play");
|
20 |
-
}
|
21 |
-
}, [paused]);
|
22 |
-
|
23 |
-
var classNameCondition = ""
|
24 |
-
if (paused) {
|
25 |
-
classNameCondition="animate-pulse fixed z-20 top-4 right-4 md:top-8 md:right-8 w-14 h-14 rounded-full drop-shadow-lg flex justify-center items-center text-white text-2xl bg-red-500 hover:bg-red-600 ring-4 ring-red-700 focus:outline-none hover:drop-shadow-2xl"
|
26 |
-
} else {
|
27 |
-
classNameCondition="fixed z-20 top-4 right-4 md:top-8 md:right-8 bg-slate-100 w-14 h-14 rounded-full drop-shadow-lg flex justify-center items-center text-sky-900 text-2xl hover:text-white hover:bg-sky-600 hover:drop-shadow-2xl"
|
28 |
-
}
|
29 |
-
|
30 |
-
return (
|
31 |
-
<>
|
32 |
-
<button
|
33 |
-
title="Pause"
|
34 |
-
className= {classNameCondition}
|
35 |
-
onClick={() => setPaused(!paused)}
|
36 |
-
>
|
37 |
-
{paused ? <FiPlay /> : <FiPause />}
|
38 |
-
</button>
|
39 |
-
</>
|
40 |
-
);
|
41 |
-
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
components/PromptEntry.tsx
DELETED
@@ -1,271 +0,0 @@
|
|
1 |
-
import { InferenceInput, InferenceResult, PlayingState } from "../types";
|
2 |
-
import { IoMdClose } from "react-icons/io";
|
3 |
-
import Pause from "./Pause";
|
4 |
-
|
5 |
-
interface PromptEntryProps {
|
6 |
-
prompt: string;
|
7 |
-
index: number;
|
8 |
-
className: string;
|
9 |
-
playingState: PlayingState;
|
10 |
-
resetCallback: () => void;
|
11 |
-
inferenceResults: InferenceResult[];
|
12 |
-
nowPlayingResult: InferenceResult;
|
13 |
-
setPaused: (value: boolean) => void;
|
14 |
-
}
|
15 |
-
|
16 |
-
export default function PromptEntry({
|
17 |
-
prompt,
|
18 |
-
index,
|
19 |
-
className,
|
20 |
-
playingState,
|
21 |
-
resetCallback,
|
22 |
-
inferenceResults,
|
23 |
-
nowPlayingResult,
|
24 |
-
setPaused
|
25 |
-
}: PromptEntryProps) {
|
26 |
-
|
27 |
-
const getPromptCopy = (prompt: string) => {
|
28 |
-
switch (playingState) {
|
29 |
-
case PlayingState.UNINITIALIZED:
|
30 |
-
case PlayingState.SAME_PROMPT:
|
31 |
-
switch (index) {
|
32 |
-
case 0:
|
33 |
-
return (
|
34 |
-
<div className="tooltip text-left" data-tip="⏪ Jump to previous prompt?" onClick={() => { jumpToPrompt(prompt, inferenceResults, setPaused, nowPlayingResult) }} >
|
35 |
-
<p className={className}>{prompt}</p>
|
36 |
-
</div>
|
37 |
-
);
|
38 |
-
case 1:
|
39 |
-
return (
|
40 |
-
<div className="tooltip text-left" data-tip="⏪ Jump to previous prompt?" onClick={() => { jumpToPrompt(prompt, inferenceResults, setPaused, nowPlayingResult) }} >
|
41 |
-
<p className={className}>{prompt}</p>
|
42 |
-
</div>
|
43 |
-
);
|
44 |
-
case 2:
|
45 |
-
// active prompt
|
46 |
-
if (prompt == " " || prompt == "") {
|
47 |
-
return <span className="text-slate-600">{"<enter prompt>"}</span>;
|
48 |
-
} else {
|
49 |
-
return (
|
50 |
-
<div className="tooltip text-left" data-tip="🔁 Restart current prompt?" onClick={() => { jumpToPrompt(prompt, inferenceResults, setPaused, nowPlayingResult) }} >
|
51 |
-
<p className={className}>{prompt}</p>
|
52 |
-
</div>
|
53 |
-
)
|
54 |
-
}
|
55 |
-
case 3:
|
56 |
-
if (prompt == " " || prompt == "") {
|
57 |
-
return <p className={className}>...</p>
|
58 |
-
} else {
|
59 |
-
return (
|
60 |
-
<div className="tooltip text-left" data-tip="🚀 Jump to upcoming prompt?" onClick={() => { jumpToPrompt(prompt, inferenceResults, setPaused, nowPlayingResult) }} >
|
61 |
-
<p className={className}>{prompt}</p>
|
62 |
-
</div>
|
63 |
-
)
|
64 |
-
}
|
65 |
-
case 4:
|
66 |
-
if (prompt == " " || prompt == "") {
|
67 |
-
return <p className={className}>UP NEXT: Anything you want</p>;
|
68 |
-
} else {
|
69 |
-
return (
|
70 |
-
<div className="tooltip text-left" data-tip="🚀 Jump to upcoming prompt?" onClick={() => { jumpToPrompt(prompt, inferenceResults, setPaused, nowPlayingResult) }} >
|
71 |
-
<p className={className}>UP NEXT: {prompt}</p>
|
72 |
-
</div>
|
73 |
-
)
|
74 |
-
}
|
75 |
-
default: {
|
76 |
-
console.log("UNHANDLED default");
|
77 |
-
return <p className={className}>{prompt}</p>;
|
78 |
-
}
|
79 |
-
}
|
80 |
-
case PlayingState.TRANSITION:
|
81 |
-
switch (index) {
|
82 |
-
case 0:
|
83 |
-
return (
|
84 |
-
<div className="tooltip text-left" data-tip="⏪ Jump to previous prompt?" onClick={() => { jumpToPrompt(prompt, inferenceResults, setPaused, nowPlayingResult) }} >
|
85 |
-
<p className={className}>{prompt}</p>
|
86 |
-
</div>
|
87 |
-
);
|
88 |
-
case 1:
|
89 |
-
return (
|
90 |
-
<div className="tooltip text-left" data-tip="⏪ Jump to previous prompt?" onClick={() => { jumpToPrompt(prompt, inferenceResults, setPaused, nowPlayingResult) }} >
|
91 |
-
<p className={className}>{prompt}</p>
|
92 |
-
</div>
|
93 |
-
);
|
94 |
-
case 2:
|
95 |
-
return (
|
96 |
-
<div className="tooltip text-left" data-tip="🔁 Restart outgoing prompt?" onClick={() => { jumpToPrompt(prompt, inferenceResults, setPaused, nowPlayingResult) }} >
|
97 |
-
<p className={className}>{prompt}</p>
|
98 |
-
</div>
|
99 |
-
)
|
100 |
-
case 3:
|
101 |
-
if (prompt == " " || prompt == "") {
|
102 |
-
return <p className={className}> -enter prompt- </p>;
|
103 |
-
} else {
|
104 |
-
return (
|
105 |
-
<div className="tooltip text-left" data-tip="🚀 Jump to incoming prompt?" onClick={() => { jumpToPrompt(prompt, inferenceResults, setPaused, nowPlayingResult) }} >
|
106 |
-
<p className={className}>{prompt}</p>
|
107 |
-
</div>
|
108 |
-
)
|
109 |
-
}
|
110 |
-
case 4:
|
111 |
-
if (prompt == " " || prompt == "") {
|
112 |
-
return <p className={className}>...</p>;
|
113 |
-
} else {
|
114 |
-
return (
|
115 |
-
<div className="tooltip text-left" data-tip="🚀 Jump to upcoming prompt?" onClick={() => { jumpToPrompt(prompt, inferenceResults, setPaused, nowPlayingResult) }} >
|
116 |
-
<p className={className}>{prompt}</p>
|
117 |
-
</div>
|
118 |
-
)
|
119 |
-
}
|
120 |
-
case 5:
|
121 |
-
if (prompt == " " || prompt == "") {
|
122 |
-
return <p className={className}>UP NEXT: Anything you want</p>;
|
123 |
-
} else {
|
124 |
-
return (
|
125 |
-
<div className="tooltip text-left" data-tip="🚀 Jump to upcoming prompt?" onClick={() => { jumpToPrompt(prompt, inferenceResults, setPaused, nowPlayingResult) }} >
|
126 |
-
<p className={className}>UP NEXT: {prompt}</p>
|
127 |
-
</div>
|
128 |
-
)
|
129 |
-
}
|
130 |
-
default: {
|
131 |
-
console.log("UNHANDLED default");
|
132 |
-
return <p className={className}>{prompt}</p>;
|
133 |
-
}
|
134 |
-
}
|
135 |
-
}
|
136 |
-
};
|
137 |
-
|
138 |
-
return (
|
139 |
-
<div className="flex cursor-pointer">
|
140 |
-
{getPromptCopy(prompt)}
|
141 |
-
|
142 |
-
{/* TODO(hayk): Re-enable this when it's working. */}
|
143 |
-
{/* {index == 2 ? (
|
144 |
-
<IoMdClose
|
145 |
-
className="w-6 h-6 ml-2 text-gray-400"
|
146 |
-
onClick={() => {
|
147 |
-
resetCallback();
|
148 |
-
}}
|
149 |
-
/>
|
150 |
-
) : null} */}
|
151 |
-
</div >
|
152 |
-
);
|
153 |
-
}
|
154 |
-
|
155 |
-
export function jumpToPrompt(prompt: String, inferenceResults: InferenceResult[], setPaused: (value: boolean) => void, nowPlayingResult?: InferenceResult) {
|
156 |
-
|
157 |
-
// Pause player since this function will open new tab that user will interact with
|
158 |
-
setPaused(true)
|
159 |
-
|
160 |
-
let firstTimePromptAppears = -1;
|
161 |
-
for (let i = 0; i < inferenceResults.length; i++) {
|
162 |
-
if (inferenceResults[i].input.start.prompt === prompt) {
|
163 |
-
firstTimePromptAppears = i;
|
164 |
-
break;
|
165 |
-
}
|
166 |
-
}
|
167 |
-
if (firstTimePromptAppears == -1) {
|
168 |
-
let url = generateLinkToUpcomingPrompt(prompt, nowPlayingResult)
|
169 |
-
window.location.href = url;
|
170 |
-
}
|
171 |
-
else {
|
172 |
-
let url = generateLinkToPreviousInput(inferenceResults[firstTimePromptAppears].input)
|
173 |
-
window.location.href = url;
|
174 |
-
}
|
175 |
-
}
|
176 |
-
|
177 |
-
export function generateLinkToUpcomingPrompt(prompt, nowPlayingResult?: InferenceResult) {
|
178 |
-
|
179 |
-
var promptString = "&prompt=" + prompt;
|
180 |
-
promptString = promptString.replace(/ /g, "+");
|
181 |
-
|
182 |
-
if (nowPlayingResult != null) {
|
183 |
-
var denoisingString = "&denoising=" + nowPlayingResult.input.start.denoising;
|
184 |
-
var seedImageIdString = "&seedImageId=" + nowPlayingResult.input.seed_image_id;
|
185 |
-
} else {
|
186 |
-
denoisingString = "";
|
187 |
-
seedImageIdString = "";
|
188 |
-
}
|
189 |
-
|
190 |
-
var baseUrl = window.location.origin + "/?";
|
191 |
-
var url = baseUrl + promptString + denoisingString + seedImageIdString;
|
192 |
-
return url;
|
193 |
-
}
|
194 |
-
|
195 |
-
// Todo: DRY this and share functions
|
196 |
-
export function generateLinkToPreviousInput(selectedInput: InferenceInput) {
|
197 |
-
var prompt;
|
198 |
-
var seed;
|
199 |
-
var denoising;
|
200 |
-
var maskImageId;
|
201 |
-
var seedImageId;
|
202 |
-
var guidance;
|
203 |
-
var numInferenceSteps;
|
204 |
-
var alphaVelocity;
|
205 |
-
|
206 |
-
prompt = selectedInput.start.prompt;
|
207 |
-
seed = selectedInput.start.seed;
|
208 |
-
denoising = selectedInput.start.denoising;
|
209 |
-
maskImageId = selectedInput.mask_image_id;
|
210 |
-
seedImageId = selectedInput.seed_image_id;
|
211 |
-
|
212 |
-
var baseUrl = window.location.origin + "/?";
|
213 |
-
|
214 |
-
if (prompt != null) {
|
215 |
-
var promptString = "&prompt=" + prompt;
|
216 |
-
} else {
|
217 |
-
promptString = "";
|
218 |
-
}
|
219 |
-
if (seed != null) {
|
220 |
-
var seedString = "&seed=" + seed;
|
221 |
-
} else {
|
222 |
-
seedString = "";
|
223 |
-
}
|
224 |
-
if (denoising != null) {
|
225 |
-
var denoisingString = "&denoising=" + denoising;
|
226 |
-
} else {
|
227 |
-
denoisingString = "";
|
228 |
-
}
|
229 |
-
if (maskImageId != null) {
|
230 |
-
var maskImageIdString = "&maskImageId=" + maskImageId;
|
231 |
-
} else {
|
232 |
-
maskImageIdString = "";
|
233 |
-
}
|
234 |
-
if (seedImageId != null) {
|
235 |
-
var seedImageIdString = "&seedImageId=" + seedImageId;
|
236 |
-
} else {
|
237 |
-
seedImageIdString = "";
|
238 |
-
}
|
239 |
-
if (guidance != null) {
|
240 |
-
var guidanceString = "&guidance=" + guidance;
|
241 |
-
} else {
|
242 |
-
guidanceString = "";
|
243 |
-
}
|
244 |
-
if (numInferenceSteps != null) {
|
245 |
-
var numInferenceStepsString = "&numInferenceSteps=" + numInferenceSteps;
|
246 |
-
} else {
|
247 |
-
numInferenceStepsString = "";
|
248 |
-
}
|
249 |
-
if (alphaVelocity != null) {
|
250 |
-
var alphaVelocityString = "&alphaVelocity=" + alphaVelocity;
|
251 |
-
} else {
|
252 |
-
alphaVelocityString = "";
|
253 |
-
}
|
254 |
-
|
255 |
-
// Format strings to have + in place of spaces for ease of sharing, note this is only necessary for prompts currently
|
256 |
-
promptString = promptString.replace(/ /g, "+");
|
257 |
-
|
258 |
-
// create url string with the variables above combined
|
259 |
-
var shareUrl =
|
260 |
-
baseUrl +
|
261 |
-
promptString +
|
262 |
-
seedString +
|
263 |
-
denoisingString +
|
264 |
-
maskImageIdString +
|
265 |
-
seedImageIdString +
|
266 |
-
guidanceString +
|
267 |
-
numInferenceStepsString +
|
268 |
-
alphaVelocityString;
|
269 |
-
|
270 |
-
return shareUrl;
|
271 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
components/PromptPanel.tsx
DELETED
@@ -1,360 +0,0 @@
|
|
1 |
-
import PromptEntry from "./PromptEntry";
|
2 |
-
|
3 |
-
import { AppState, PlayingState, InferenceResult, PromptInput } from "../types";
|
4 |
-
import { useRef } from "react";
|
5 |
-
import { samplePrompts, rollTheDicePrompts } from "../samplePrompts";
|
6 |
-
|
7 |
-
interface PromptPanelProps {
|
8 |
-
prompts: PromptInput[];
|
9 |
-
inferenceResults: InferenceResult[];
|
10 |
-
nowPlayingResult: InferenceResult;
|
11 |
-
appState: AppState;
|
12 |
-
changePrompt: (prompt: string, index: number) => void;
|
13 |
-
resetCallback: () => void;
|
14 |
-
setPaused: (paused: boolean) => void;
|
15 |
-
}
|
16 |
-
|
17 |
-
export default function PromptPanel({
|
18 |
-
prompts,
|
19 |
-
inferenceResults,
|
20 |
-
nowPlayingResult,
|
21 |
-
appState,
|
22 |
-
changePrompt,
|
23 |
-
resetCallback,
|
24 |
-
setPaused,
|
25 |
-
}: PromptPanelProps) {
|
26 |
-
const inputPrompt = useRef(null);
|
27 |
-
|
28 |
-
var playingState: PlayingState;
|
29 |
-
|
30 |
-
const getDisplayPrompts = () => {
|
31 |
-
var displayPrompts = [];
|
32 |
-
|
33 |
-
if (nowPlayingResult == null) {
|
34 |
-
playingState = PlayingState.UNINITIALIZED;
|
35 |
-
} else if (
|
36 |
-
nowPlayingResult.input.start.prompt == nowPlayingResult.input.end.prompt
|
37 |
-
) {
|
38 |
-
playingState = PlayingState.SAME_PROMPT;
|
39 |
-
} else {
|
40 |
-
playingState = PlayingState.TRANSITION;
|
41 |
-
}
|
42 |
-
|
43 |
-
// Add the last 4 prompts from playedResults
|
44 |
-
// filter inferenceResults to only include results that have been played
|
45 |
-
const playedResults = inferenceResults.filter((r) => r.played);
|
46 |
-
|
47 |
-
// filter playedResults to include only results where alpha is 0.25 (the first alpha of a new transition)
|
48 |
-
const playedResultsAlpha = playedResults.filter(
|
49 |
-
(r) => r.input.alpha == 0.25
|
50 |
-
);
|
51 |
-
|
52 |
-
// filter playedResultsAlpha to include only results where playedResultsAlpha.input.start.prompt is not the same as playedResultsAlpha.input.end.prompt
|
53 |
-
const playedResultsAlphaTransition = playedResultsAlpha.filter(
|
54 |
-
(r) => r.input.start.prompt != r.input.end.prompt
|
55 |
-
);
|
56 |
-
|
57 |
-
// select the last 4 results
|
58 |
-
const lastPlayedResultsAlphaTransition =
|
59 |
-
playedResultsAlphaTransition.slice(-4);
|
60 |
-
|
61 |
-
// add the most recent end prompts to the displayPrompts
|
62 |
-
lastPlayedResultsAlphaTransition.forEach((result) => {
|
63 |
-
displayPrompts.push({ prompt: result.input.end.prompt });
|
64 |
-
});
|
65 |
-
|
66 |
-
// Handle the case where there are less than 4 played results (i.e. the initial state)
|
67 |
-
if (displayPrompts.length < 4) {
|
68 |
-
const promptsToAdd = prompts.slice(displayPrompts.length, 4);
|
69 |
-
displayPrompts = [...promptsToAdd, ...displayPrompts];
|
70 |
-
}
|
71 |
-
|
72 |
-
// Add in the upNext and staged prompts
|
73 |
-
// select the last 2 prompts from prompts
|
74 |
-
const lastPrompts = prompts.slice(-2);
|
75 |
-
|
76 |
-
// make a copy of the lastPrompts with new pointers
|
77 |
-
const lastPromptsCopy = lastPrompts.map((p) => ({ ...p }));
|
78 |
-
|
79 |
-
// if any of the lastPrompts have a transitionCounter, replace them with "" because they are already represented in the displayPrompts
|
80 |
-
lastPromptsCopy.forEach((prompt, index) => {
|
81 |
-
if (prompt.transitionCounter != null) {
|
82 |
-
lastPromptsCopy[index].prompt = "";
|
83 |
-
lastPromptsCopy[index].transitionCounter = null;
|
84 |
-
}
|
85 |
-
});
|
86 |
-
|
87 |
-
// add the prompts to the displayPrompts
|
88 |
-
lastPromptsCopy.forEach((p) => {
|
89 |
-
displayPrompts.push(p);
|
90 |
-
});
|
91 |
-
|
92 |
-
// if playingState == PlayingState.SAME_PROMPT or playingState == PlayingState.UNINITIALIZED, remove the first prompt from displayPrompts
|
93 |
-
if (
|
94 |
-
playingState == PlayingState.SAME_PROMPT ||
|
95 |
-
playingState == PlayingState.UNINITIALIZED
|
96 |
-
) {
|
97 |
-
displayPrompts.shift();
|
98 |
-
}
|
99 |
-
|
100 |
-
return displayPrompts;
|
101 |
-
};
|
102 |
-
|
103 |
-
const getPromptEntryClassName = (index: number) => {
|
104 |
-
switch (playingState) {
|
105 |
-
case PlayingState.UNINITIALIZED:
|
106 |
-
return promptEntryClassNames_5_0[index];
|
107 |
-
case PlayingState.SAME_PROMPT:
|
108 |
-
if (appState != AppState.TRANSITION) {
|
109 |
-
return promptEntryClassNames_5_0[index];
|
110 |
-
} else {
|
111 |
-
switch (nowPlayingResult.input.alpha) {
|
112 |
-
case 0:
|
113 |
-
return promptEntryClassNames_5_0[index];
|
114 |
-
case 0.25:
|
115 |
-
return promptEntryClassNames_5_25[index];
|
116 |
-
case 0.5:
|
117 |
-
return promptEntryClassNames_5_50[index];
|
118 |
-
case 0.75:
|
119 |
-
return promptEntryClassNames_5_75[index];
|
120 |
-
case 1:
|
121 |
-
return promptEntryClassNames_5_1[index];
|
122 |
-
}
|
123 |
-
}
|
124 |
-
case PlayingState.TRANSITION:
|
125 |
-
switch (nowPlayingResult.input.alpha) {
|
126 |
-
case 0:
|
127 |
-
return promptEntryClassNames_6_0[index];
|
128 |
-
case 0.25:
|
129 |
-
return promptEntryClassNames_6_25[index];
|
130 |
-
case 0.5:
|
131 |
-
return promptEntryClassNames_6_50[index];
|
132 |
-
case 0.75:
|
133 |
-
return promptEntryClassNames_6_75[index];
|
134 |
-
case 1:
|
135 |
-
return promptEntryClassNames_6_1[index];
|
136 |
-
}
|
137 |
-
default:
|
138 |
-
// These states are reached if alpha is greater than 1 but the new inference is not ready
|
139 |
-
if (appState != AppState.TRANSITION) {
|
140 |
-
return promptEntryClassNames_5_0[index];
|
141 |
-
} else if (playingState == PlayingState.SAME_PROMPT) {
|
142 |
-
return promptEntryClassNames_5_1[index];
|
143 |
-
} else {
|
144 |
-
return promptEntryClassNames_6_1[index];
|
145 |
-
}
|
146 |
-
}
|
147 |
-
};
|
148 |
-
|
149 |
-
const rollTheDice = () => {
|
150 |
-
const prompts = [...samplePrompts, ...rollTheDicePrompts];
|
151 |
-
|
152 |
-
const selectedPrompt = prompts[Math.floor(Math.random() * prompts.length)];
|
153 |
-
|
154 |
-
inputPrompt.current.value = selectedPrompt;
|
155 |
-
};
|
156 |
-
|
157 |
-
return (
|
158 |
-
<>
|
159 |
-
<main className="z-10 fixed w-full md:static md:w-2/3 md:min-h-screen">
|
160 |
-
<div className="pl-10 pr-10 md:pl-20">
|
161 |
-
<div className="h-[78vh] landscape:sm:max-[750px]:h-[62vh] md:h-[80vh] flex flex-col justify-around pt-[10vh] pr-5">
|
162 |
-
{getDisplayPrompts().map((prompt, index) => (
|
163 |
-
<PromptEntry
|
164 |
-
prompt={prompt.prompt}
|
165 |
-
className={getPromptEntryClassName(index)}
|
166 |
-
index={index}
|
167 |
-
key={index}
|
168 |
-
playingState={playingState}
|
169 |
-
resetCallback={resetCallback}
|
170 |
-
inferenceResults={inferenceResults}
|
171 |
-
nowPlayingResult={nowPlayingResult}
|
172 |
-
setPaused={setPaused}
|
173 |
-
/>
|
174 |
-
))}
|
175 |
-
</div>
|
176 |
-
|
177 |
-
{/* // Form trims spaces, and only submits if the remaining prompt is more than 0 characters */}
|
178 |
-
<form
|
179 |
-
noValidate={true}
|
180 |
-
onSubmit={(e) => {
|
181 |
-
e.preventDefault();
|
182 |
-
const prompt = e.currentTarget.prompt.value;
|
183 |
-
const trimmedPrompt = prompt.trimStart();
|
184 |
-
if (trimmedPrompt.length > 0) {
|
185 |
-
changePrompt(trimmedPrompt, prompts.length - 1);
|
186 |
-
inputPrompt.current.value = "";
|
187 |
-
} else {
|
188 |
-
inputPrompt.current.value = "";
|
189 |
-
}
|
190 |
-
}}
|
191 |
-
>
|
192 |
-
<input
|
193 |
-
className="flex w-full md:fixed md:w-5/12 h-12 pl-3 pr-3 text-lg text-sky-900 dark:text-sky-100 rounded-lg border-sky-700 border-4 hover:border-sky-600 focus:outline-none focus:border-sky-400"
|
194 |
-
ref={inputPrompt}
|
195 |
-
type="text"
|
196 |
-
id="prompt"
|
197 |
-
name="prompt"
|
198 |
-
placeholder="What do you want to hear next?"
|
199 |
-
maxLength={150}
|
200 |
-
minLength={2}
|
201 |
-
required={true}
|
202 |
-
autoComplete="off"
|
203 |
-
/>
|
204 |
-
</form>
|
205 |
-
<div className="hidden md:block">
|
206 |
-
<div>
|
207 |
-
<button
|
208 |
-
className="flex -ml-8 pt-2 h-12 w-12 text-xl text-white"
|
209 |
-
onClick={() => {
|
210 |
-
rollTheDice();
|
211 |
-
}}
|
212 |
-
>
|
213 |
-
🎲
|
214 |
-
</button>
|
215 |
-
</div>
|
216 |
-
</div>
|
217 |
-
</div>
|
218 |
-
</main>
|
219 |
-
</>
|
220 |
-
);
|
221 |
-
}
|
222 |
-
|
223 |
-
export function refreshPage() {
|
224 |
-
window.location.reload();
|
225 |
-
}
|
226 |
-
|
227 |
-
const promptEntryClassNameDict = {
|
228 |
-
0: "font-extralight text-xs text-gray-500 text-opacity-20",
|
229 |
-
1: "font-extralight text-xs text-gray-400 text-opacity-20",
|
230 |
-
2: "font-extralight text-sm text-gray-300 text-opacity-30",
|
231 |
-
3: "font-extralight text-sm text-gray-200 text-opacity-30",
|
232 |
-
4: "font-light text-sm text-gray-200 text-opacity-40",
|
233 |
-
5: "font-light text-base text-gray-200 text-opacity-40",
|
234 |
-
6: "font-light text-base text-gray-100 text-opacity-50",
|
235 |
-
7: "font-light text-base text-gray-100 text-opacity-50", // starter for 0
|
236 |
-
|
237 |
-
8: "font-light text-base text-gray-100 text-opacity-50",
|
238 |
-
9: "font-light text-lg text-gray-100 text-opacity-50",
|
239 |
-
10: "font-light text-lg text-gray-100 text-opacity-60",
|
240 |
-
11: "font-normal text-lg text-gray-100 text-opacity-60",
|
241 |
-
12: "font-normal text-xl text-gray-100 text-opacity-60",
|
242 |
-
13: "font-normal text-xl text-gray-100 text-opacity-70",
|
243 |
-
14: "font-normal text-xl text-gray-100 text-opacity-70",
|
244 |
-
15: "font-normal text-xl text-gray-100 text-opacity-70", // starter for 1
|
245 |
-
|
246 |
-
16: "font-medium text-2xl text-gray-100 text-opacity-80", // 0%
|
247 |
-
17: "font-medium text-3xl text-gray-100 text-opacity-90", // 25%
|
248 |
-
18: "font-semibold text-4xl text-white", // 50%
|
249 |
-
19: "font-bold text-4xl text-white", // 75%
|
250 |
-
20: "font-bold text-5xl text-white",
|
251 |
-
21: "font-bold text-5xl text-white",
|
252 |
-
22: "font-bold text-5xl text-white",
|
253 |
-
23: "font-bold text-5xl text-white", // starter for 2 "start"
|
254 |
-
|
255 |
-
24: "font-bold text-5xl text-white",
|
256 |
-
25: "font-bold text-4xl text-white", // 75%
|
257 |
-
26: "font-semibold text-4xl text-white", // 50%
|
258 |
-
27: "font-medium text-3xl text-gray-100 text-opacity-90", // 25%
|
259 |
-
28: "font-normal text-2xl text-gray-100 text-opacity-80",
|
260 |
-
29: "font-normal text-l text-gray-100 text-opacity-70",
|
261 |
-
30: "font-normal text-l text-gray-100 text-opacity-70",
|
262 |
-
31: "font-normal text-l text-gray-100 text-opacity-70", // starter for 3 "end"
|
263 |
-
|
264 |
-
32: "font-normal text-base text-gray-100 text-opacity-70",
|
265 |
-
33: "font-normal text-base text-gray-100 text-opacity-60",
|
266 |
-
34: "font-normal text-base text-gray-100 text-opacity-60",
|
267 |
-
35: "font-normal text-base text-gray-100 text-opacity-60", // starter for 4 when "staging"
|
268 |
-
|
269 |
-
36: "font-normal text-base text-gray-100 text-opacity-60", // starter for 4 and 5 "Up Next"
|
270 |
-
};
|
271 |
-
|
272 |
-
// ClassNames below
|
273 |
-
// Note that 6_0 and 5_25 are never reached in current stucture
|
274 |
-
|
275 |
-
const promptEntryClassNames_5_0 = {
|
276 |
-
0: promptEntryClassNameDict[7],
|
277 |
-
1: promptEntryClassNameDict[15],
|
278 |
-
2: promptEntryClassNameDict[23], // This is the start and end prompt
|
279 |
-
3: promptEntryClassNameDict[31], // This is the staged prompt
|
280 |
-
4: promptEntryClassNameDict[36], // This is the UP NEXT prompt
|
281 |
-
};
|
282 |
-
|
283 |
-
const promptEntryClassNames_5_25 = {
|
284 |
-
// This is not reached unless user has poor connection or delayed server response
|
285 |
-
0: promptEntryClassNameDict[7],
|
286 |
-
1: promptEntryClassNameDict[15],
|
287 |
-
2: promptEntryClassNameDict[23], // This is the start and end prompt
|
288 |
-
3: promptEntryClassNameDict[31], // This is the staged prompt
|
289 |
-
4: promptEntryClassNameDict[36], // This is the UP NEXT prompt
|
290 |
-
};
|
291 |
-
|
292 |
-
const promptEntryClassNames_5_50 = {
|
293 |
-
0: promptEntryClassNameDict[6],
|
294 |
-
1: promptEntryClassNameDict[14],
|
295 |
-
2: promptEntryClassNameDict[22],
|
296 |
-
3: promptEntryClassNameDict[30],
|
297 |
-
4: promptEntryClassNameDict[36],
|
298 |
-
};
|
299 |
-
|
300 |
-
const promptEntryClassNames_5_75 = {
|
301 |
-
0: promptEntryClassNameDict[5],
|
302 |
-
1: promptEntryClassNameDict[13],
|
303 |
-
2: promptEntryClassNameDict[21],
|
304 |
-
3: promptEntryClassNameDict[29],
|
305 |
-
4: promptEntryClassNameDict[36],
|
306 |
-
};
|
307 |
-
|
308 |
-
const promptEntryClassNames_5_1 = {
|
309 |
-
0: promptEntryClassNameDict[4],
|
310 |
-
1: promptEntryClassNameDict[12],
|
311 |
-
2: promptEntryClassNameDict[20],
|
312 |
-
3: promptEntryClassNameDict[28],
|
313 |
-
4: promptEntryClassNameDict[36],
|
314 |
-
};
|
315 |
-
|
316 |
-
const promptEntryClassNames_6_0 = {
|
317 |
-
// This is not reached unless user has poor connection or delayed server response
|
318 |
-
0: promptEntryClassNameDict[3],
|
319 |
-
1: promptEntryClassNameDict[11],
|
320 |
-
2: promptEntryClassNameDict[19],
|
321 |
-
3: promptEntryClassNameDict[27],
|
322 |
-
4: promptEntryClassNameDict[35],
|
323 |
-
5: promptEntryClassNameDict[36],
|
324 |
-
};
|
325 |
-
|
326 |
-
const promptEntryClassNames_6_25 = {
|
327 |
-
0: promptEntryClassNameDict[3],
|
328 |
-
1: promptEntryClassNameDict[11],
|
329 |
-
2: promptEntryClassNameDict[19],
|
330 |
-
3: promptEntryClassNameDict[27],
|
331 |
-
4: promptEntryClassNameDict[35],
|
332 |
-
5: promptEntryClassNameDict[36],
|
333 |
-
};
|
334 |
-
|
335 |
-
const promptEntryClassNames_6_50 = {
|
336 |
-
0: promptEntryClassNameDict[2],
|
337 |
-
1: promptEntryClassNameDict[10],
|
338 |
-
2: promptEntryClassNameDict[18],
|
339 |
-
3: promptEntryClassNameDict[26],
|
340 |
-
4: promptEntryClassNameDict[34],
|
341 |
-
5: promptEntryClassNameDict[36],
|
342 |
-
};
|
343 |
-
|
344 |
-
const promptEntryClassNames_6_75 = {
|
345 |
-
0: promptEntryClassNameDict[1],
|
346 |
-
1: promptEntryClassNameDict[9],
|
347 |
-
2: promptEntryClassNameDict[17],
|
348 |
-
3: promptEntryClassNameDict[25],
|
349 |
-
4: promptEntryClassNameDict[33],
|
350 |
-
5: promptEntryClassNameDict[36],
|
351 |
-
};
|
352 |
-
|
353 |
-
const promptEntryClassNames_6_1 = {
|
354 |
-
0: promptEntryClassNameDict[0],
|
355 |
-
1: promptEntryClassNameDict[8],
|
356 |
-
2: promptEntryClassNameDict[16],
|
357 |
-
3: promptEntryClassNameDict[24],
|
358 |
-
4: promptEntryClassNameDict[32],
|
359 |
-
5: promptEntryClassNameDict[36],
|
360 |
-
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|