Spaces:
Sleeping
Sleeping
Jon Taylor
commited on
Commit
•
dd10606
1
Parent(s):
76b9248
ui updates
Browse files- frontend/app/components/Card.js +5 -7
- frontend/app/components/Controls.js +73 -6
- frontend/app/components/HUDItem.js +8 -0
- frontend/app/components/TrayButton.js +30 -0
- frontend/app/globals.css +13 -2
- frontend/app/layout.js +20 -5
- frontend/app/test/page.js +74 -11
- frontend/tailwind.config.js +1 -13
frontend/app/components/Card.js
CHANGED
@@ -1,11 +1,9 @@
|
|
1 |
-
export default function Card({
|
2 |
return (
|
3 |
-
<div className="
|
4 |
-
<
|
5 |
-
|
6 |
-
|
7 |
-
</header>
|
8 |
-
<main className="px-4 pb-4">{children}</main>
|
9 |
</div>
|
10 |
);
|
11 |
}
|
|
|
1 |
+
export default function Card({ children }) {
|
2 |
return (
|
3 |
+
<div className="rounded-xl bg-white border border-zinc-200 p-2 w-full max-w-3xl aspect-video">
|
4 |
+
<div className="overflow-hidden flex-1 h-full bg-zinc-50 rounded-md flex items-center justify-center">
|
5 |
+
{children}
|
6 |
+
</div>
|
|
|
|
|
7 |
</div>
|
8 |
);
|
9 |
}
|
frontend/app/components/Controls.js
CHANGED
@@ -1,8 +1,19 @@
|
|
1 |
"use client";
|
2 |
|
3 |
-
import {
|
|
|
|
|
|
|
|
|
|
|
|
|
4 |
import { useForm } from "@mantine/form";
|
5 |
-
import {
|
|
|
|
|
|
|
|
|
|
|
6 |
import React from "react";
|
7 |
import FieldSet from "./FieldSet";
|
8 |
import Label from "./Label";
|
@@ -13,6 +24,8 @@ import TextInput from "./TextInput";
|
|
13 |
export const Controls = React.memo(() => {
|
14 |
const form = useForm({
|
15 |
initialValues: {
|
|
|
|
|
16 |
steps: 1,
|
17 |
guidance: 0.1,
|
18 |
seed: 45678,
|
@@ -22,7 +35,62 @@ export const Controls = React.memo(() => {
|
|
22 |
|
23 |
return (
|
24 |
<div className="flex flex-col gap-4">
|
25 |
-
<Accordion
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
26 |
<Accordion.Item value="camera" key="camera">
|
27 |
<Accordion.Control value="camera">Camera</Accordion.Control>
|
28 |
<Accordion.Panel>
|
@@ -46,8 +114,8 @@ export const Controls = React.memo(() => {
|
|
46 |
</FieldSet>
|
47 |
</Accordion.Panel>
|
48 |
</Accordion.Item>
|
49 |
-
<Accordion.Item value="
|
50 |
-
<Accordion.Control value="inference">
|
51 |
<Accordion.Panel>
|
52 |
<div className="flex flex-col gap-4">
|
53 |
<TextInput
|
@@ -108,7 +176,6 @@ export const Controls = React.memo(() => {
|
|
108 |
<Button className="rounded-full" onClick={() => console.log(form.values)}>
|
109 |
Submit
|
110 |
</Button>
|
111 |
-
Strength
|
112 |
</div>
|
113 |
);
|
114 |
});
|
|
|
1 |
"use client";
|
2 |
|
3 |
+
import {
|
4 |
+
Accordion,
|
5 |
+
ActionIcon,
|
6 |
+
Button,
|
7 |
+
SegmentedControl,
|
8 |
+
Textarea,
|
9 |
+
} from "@mantine/core";
|
10 |
import { useForm } from "@mantine/form";
|
11 |
+
import {
|
12 |
+
IconArrowDownRight,
|
13 |
+
IconMinus,
|
14 |
+
IconPlus,
|
15 |
+
IconRotateClockwise,
|
16 |
+
} from "@tabler/icons-react";
|
17 |
import React from "react";
|
18 |
import FieldSet from "./FieldSet";
|
19 |
import Label from "./Label";
|
|
|
24 |
export const Controls = React.memo(() => {
|
25 |
const form = useForm({
|
26 |
initialValues: {
|
27 |
+
positivePrompt: "some kind of prompt",
|
28 |
+
negativePrompt: "bad hands",
|
29 |
steps: 1,
|
30 |
guidance: 0.1,
|
31 |
seed: 45678,
|
|
|
35 |
|
36 |
return (
|
37 |
<div className="flex flex-col gap-4">
|
38 |
+
<Accordion
|
39 |
+
defaultValue="prompt"
|
40 |
+
classNames={{
|
41 |
+
chevron: "w-[20px] text-indigo-500",
|
42 |
+
label: "font-medium text-zinc-900",
|
43 |
+
control: "hover:bg-zinc-50",
|
44 |
+
item: "border-zinc-200",
|
45 |
+
}}
|
46 |
+
chevron={<IconArrowDownRight size={20} stroke={2} className="block" />}
|
47 |
+
>
|
48 |
+
<Accordion.Item value="prompt" key="prompt">
|
49 |
+
<Accordion.Control value="prompt">Prompt</Accordion.Control>
|
50 |
+
<Accordion.Panel>
|
51 |
+
<FieldSet>
|
52 |
+
<div className="flex flex-col">
|
53 |
+
<div className="flex flex-row items-center gap-2 mb-2">
|
54 |
+
<IconPlus size={20} stroke={1} className="text-emerald-500" />
|
55 |
+
<span className="font-mono uppercase text-xs tracking-wider text-emerald-600">
|
56 |
+
Positive Prompt
|
57 |
+
</span>
|
58 |
+
</div>
|
59 |
+
<Textarea
|
60 |
+
autosize
|
61 |
+
className="rounded-md"
|
62 |
+
minRows={3}
|
63 |
+
defaultValue={form.getInputProps("positivePrompt").value}
|
64 |
+
onChange={(v) => form.setFieldValue("positivePrompt", v)}
|
65 |
+
classNames={{
|
66 |
+
input:
|
67 |
+
"p-3 font-mono text-emerald-800 bg-emerald-600/[0.07] border-emerald-500/30 focus:border-emerald-500 focus:ring-1 focus:ring-inset focus:ring-emerald-500",
|
68 |
+
}}
|
69 |
+
/>
|
70 |
+
</div>
|
71 |
+
<div className="flex flex-col">
|
72 |
+
<div className="flex flex-row items-center gap-2 mb-2">
|
73 |
+
<IconMinus size={20} stroke={1} className="text-rose-500" />
|
74 |
+
<span className="font-mono uppercase text-xs tracking-wider text-rose-600">
|
75 |
+
Negative Prompt
|
76 |
+
</span>
|
77 |
+
</div>
|
78 |
+
<Textarea
|
79 |
+
autosize
|
80 |
+
className="rounded-md"
|
81 |
+
minRows={3}
|
82 |
+
defaultValue={form.getInputProps("negativePrompt").value}
|
83 |
+
onChange={(v) => form.setFieldValue("negativePrompt", v)}
|
84 |
+
classNames={{
|
85 |
+
input:
|
86 |
+
"p-3 font-mono text-rose-800 bg-rose-600/[0.07] border-rose-500/30 focus:border-rose-500 focus:ring-1 focus:ring-inset focus:ring-rose-500",
|
87 |
+
}}
|
88 |
+
/>
|
89 |
+
</div>
|
90 |
+
</FieldSet>
|
91 |
+
</Accordion.Panel>
|
92 |
+
</Accordion.Item>
|
93 |
+
|
94 |
<Accordion.Item value="camera" key="camera">
|
95 |
<Accordion.Control value="camera">Camera</Accordion.Control>
|
96 |
<Accordion.Panel>
|
|
|
114 |
</FieldSet>
|
115 |
</Accordion.Panel>
|
116 |
</Accordion.Item>
|
117 |
+
<Accordion.Item value="diffusion" key="diffusion">
|
118 |
+
<Accordion.Control value="inference">Diffusion</Accordion.Control>
|
119 |
<Accordion.Panel>
|
120 |
<div className="flex flex-col gap-4">
|
121 |
<TextInput
|
|
|
176 |
<Button className="rounded-full" onClick={() => console.log(form.values)}>
|
177 |
Submit
|
178 |
</Button>
|
|
|
179 |
</div>
|
180 |
);
|
181 |
});
|
frontend/app/components/HUDItem.js
ADDED
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
export const HUDItem = ({ value, label }) => (
|
2 |
+
<div className="font-mono text-xs tracking-wider uppercase border border-zinc-200 rounded-md py-2 px-3">
|
3 |
+
<span className="text-zinc-500">{label}: </span>
|
4 |
+
<span className="font-bold text-zinc-700">{value}</span>
|
5 |
+
</div>
|
6 |
+
);
|
7 |
+
|
8 |
+
export default HUDItem;
|
frontend/app/components/TrayButton.js
ADDED
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import { Button } from "@mantine/core";
|
2 |
+
|
3 |
+
const DEFAULT_COLORS =
|
4 |
+
"bg-indigo-700 text-indigo-100 hover:text-indigo-50 hover:bg-indigo-600";
|
5 |
+
const DEFAULT_ICON_COLORS = "text-indigo-300 group-hover:text-indigo-200";
|
6 |
+
|
7 |
+
const RED_COLORS =
|
8 |
+
"bg-rose-700 text-rose-100 hover:text-rose-50 hover:bg-rose-600";
|
9 |
+
const RED_ICON_COLORS = "text-rose-300 group-hover:text-rose-200";
|
10 |
+
|
11 |
+
export const TrayButton = ({ Icon, red = false, children }) => (
|
12 |
+
<Button
|
13 |
+
size="md"
|
14 |
+
radius="xl"
|
15 |
+
className={`group transition-colors duration-300 ${
|
16 |
+
red ? RED_COLORS : DEFAULT_COLORS
|
17 |
+
}`}
|
18 |
+
leftSection={
|
19 |
+
<Icon
|
20 |
+
size={20}
|
21 |
+
stroke={2}
|
22 |
+
className={`${
|
23 |
+
red ? RED_ICON_COLORS : DEFAULT_ICON_COLORS
|
24 |
+
} transition-colors duration-300`}
|
25 |
+
/>
|
26 |
+
}
|
27 |
+
>
|
28 |
+
{children}
|
29 |
+
</Button>
|
30 |
+
);
|
frontend/app/globals.css
CHANGED
@@ -1,10 +1,12 @@
|
|
1 |
-
@
|
2 |
-
@tailwind utilities;
|
3 |
|
4 |
@layer tailwind {
|
5 |
@tailwind base;
|
6 |
}
|
7 |
|
|
|
|
|
|
|
8 |
* {
|
9 |
box-sizing: border-box;
|
10 |
}
|
@@ -31,3 +33,12 @@ body {
|
|
31 |
-moz-osx-font-smoothing: grayscale;
|
32 |
@apply text-black;
|
33 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
@import "@mantine/core/styles.css";
|
|
|
2 |
|
3 |
@layer tailwind {
|
4 |
@tailwind base;
|
5 |
}
|
6 |
|
7 |
+
@tailwind components;
|
8 |
+
@tailwind utilities;
|
9 |
+
|
10 |
* {
|
11 |
box-sizing: border-box;
|
12 |
}
|
|
|
33 |
-moz-osx-font-smoothing: grayscale;
|
34 |
@apply text-black;
|
35 |
}
|
36 |
+
|
37 |
+
body {
|
38 |
+
font-family: var(--font-sans);
|
39 |
+
overflow-x: hidden;
|
40 |
+
}
|
41 |
+
|
42 |
+
.font-mono {
|
43 |
+
font-family: var(--font-mono);
|
44 |
+
}
|
frontend/app/layout.js
CHANGED
@@ -1,9 +1,20 @@
|
|
1 |
-
import { ColorSchemeScript, MantineProvider, createTheme } from "@mantine/core";
|
2 |
-
import "@mantine/core/styles.layer.css";
|
3 |
-
import { Inter } from "next/font/google";
|
4 |
import "./globals.css";
|
5 |
|
6 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7 |
|
8 |
export const metadata = {
|
9 |
title: "Real-time SDTurbo + WebRTC",
|
@@ -34,8 +45,12 @@ export default function RootLayout({ children }) {
|
|
34 |
<html lang="en">
|
35 |
<head>
|
36 |
<ColorSchemeScript />
|
|
|
|
|
|
|
|
|
37 |
</head>
|
38 |
-
<body className={`${
|
39 |
<MantineProvider theme={theme}>{children}</MantineProvider>
|
40 |
</body>
|
41 |
</html>
|
|
|
|
|
|
|
|
|
1 |
import "./globals.css";
|
2 |
|
3 |
+
import { ColorSchemeScript, MantineProvider, createTheme } from "@mantine/core";
|
4 |
+
import { Space_Grotesk, Space_Mono } from "next/font/google";
|
5 |
+
|
6 |
+
// Font
|
7 |
+
const sans = Space_Grotesk({
|
8 |
+
subsets: ["latin"],
|
9 |
+
weight: ["400", "500", "600"],
|
10 |
+
variable: "--font-sans",
|
11 |
+
});
|
12 |
+
|
13 |
+
const mono = Space_Mono({
|
14 |
+
subsets: ["latin"],
|
15 |
+
weight: ["400", "700"],
|
16 |
+
variable: "--font-mono",
|
17 |
+
});
|
18 |
|
19 |
export const metadata = {
|
20 |
title: "Real-time SDTurbo + WebRTC",
|
|
|
45 |
<html lang="en">
|
46 |
<head>
|
47 |
<ColorSchemeScript />
|
48 |
+
<meta
|
49 |
+
name="viewport"
|
50 |
+
content="minimum-scale=1, initial-scale=1, width=device-width, user-scalable=no"
|
51 |
+
/>
|
52 |
</head>
|
53 |
+
<body className={`${sans.variable} ${mono.variable}`}>
|
54 |
<MantineProvider theme={theme}>{children}</MantineProvider>
|
55 |
</body>
|
56 |
</html>
|
frontend/app/test/page.js
CHANGED
@@ -1,18 +1,81 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
import Controls from "../components/Controls";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
|
3 |
export default function Test() {
|
|
|
|
|
4 |
return (
|
5 |
-
<div className="
|
6 |
-
<
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
<
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
16 |
</div>
|
17 |
);
|
18 |
}
|
|
|
1 |
+
"use client";
|
2 |
+
|
3 |
+
import { ActionIcon } from "@mantine/core";
|
4 |
+
import {
|
5 |
+
IconDoorExit,
|
6 |
+
IconInfoSquareRoundedFilled,
|
7 |
+
IconLayoutSidebarRightCollapse,
|
8 |
+
IconLayoutSidebarRightExpand,
|
9 |
+
} from "@tabler/icons-react";
|
10 |
+
import { useState } from "react";
|
11 |
+
import Avatar from "../components/Avatar";
|
12 |
+
import Card from "../components/Card";
|
13 |
import Controls from "../components/Controls";
|
14 |
+
import { HUDItem } from "../components/HUDItem";
|
15 |
+
import { TrayButton } from "../components/TrayButton";
|
16 |
+
|
17 |
+
/**
|
18 |
+
global settings: resolution
|
19 |
+
<br />
|
20 |
+
camera settings: simulcast - fps bitrate seed guidance
|
21 |
+
<br />
|
22 |
+
seed, guidance, strength, cn scale, cn start, cn end, canny low
|
23 |
+
threshold, canny_high_threshold, debug canny
|
24 |
+
*/
|
25 |
|
26 |
export default function Test() {
|
27 |
+
const [panelHidden, setPanelHidden] = useState(false);
|
28 |
+
|
29 |
return (
|
30 |
+
<div className="flex flex-col min-h-screen">
|
31 |
+
<div
|
32 |
+
className={`flex-1 grid ${
|
33 |
+
panelHidden ? "grid-cols-[0px_1fr]" : "grid-cols-[460px_1fr]"
|
34 |
+
}`}
|
35 |
+
>
|
36 |
+
<aside className="overflow-y-auto max-h-screen border-r border-zinc-200 bg-white">
|
37 |
+
<Controls />
|
38 |
+
</aside>
|
39 |
+
<div className="max-h-screen bg-zinc-100 flex items-center justify-center relative">
|
40 |
+
<header className="flex flex-row justify-between px-3 absolute top-3 w-full">
|
41 |
+
<ActionIcon
|
42 |
+
size="lg"
|
43 |
+
className="rounded-md bg-zinc-200 hover:bg-indigo-500 hover:text-indigo-50 text-zinc-500 transition-colors duration-300"
|
44 |
+
onClick={() => setPanelHidden(!panelHidden)}
|
45 |
+
>
|
46 |
+
{panelHidden ? (
|
47 |
+
<IconLayoutSidebarRightCollapse size={20} stroke={2} />
|
48 |
+
) : (
|
49 |
+
<IconLayoutSidebarRightExpand size={20} stroke={2} />
|
50 |
+
)}
|
51 |
+
</ActionIcon>
|
52 |
+
<div className="flex flex-row gap-2">
|
53 |
+
<HUDItem label="Expiry" value="3:00" />
|
54 |
+
<HUDItem label="FPS" value="0" />
|
55 |
+
</div>
|
56 |
+
</header>
|
57 |
+
|
58 |
+
<main className="w-full h-full flex flex-col max-w-lg xl:max-w-2xl 2xl:max-w-full 2xl:flex-row items-center justify-center p-6 gap-3">
|
59 |
+
<Card>
|
60 |
+
<iframe
|
61 |
+
class="w-full aspect-video"
|
62 |
+
src="https://www.youtube.com/embed/dQw4w9WgXcQ"
|
63 |
+
allowFullScreen
|
64 |
+
></iframe>
|
65 |
+
</Card>
|
66 |
+
<Card>
|
67 |
+
<Avatar />
|
68 |
+
</Card>
|
69 |
+
</main>
|
70 |
+
|
71 |
+
<footer className="absolute flex flex-row gap-2 bottom-3 right-3">
|
72 |
+
<TrayButton Icon={IconInfoSquareRoundedFilled}>About</TrayButton>
|
73 |
+
<TrayButton red Icon={IconDoorExit}>
|
74 |
+
Leave
|
75 |
+
</TrayButton>
|
76 |
+
</footer>
|
77 |
+
</div>
|
78 |
+
</div>
|
79 |
</div>
|
80 |
);
|
81 |
}
|
frontend/tailwind.config.js
CHANGED
@@ -7,19 +7,7 @@ module.exports = {
|
|
7 |
],
|
8 |
theme: {
|
9 |
extend: {
|
10 |
-
color: {
|
11 |
-
brandDark: {
|
12 |
-
100: "#161618",
|
13 |
-
200: "#161618",
|
14 |
-
300: "#161618",
|
15 |
-
400: "#161618",
|
16 |
-
500: "#161618",
|
17 |
-
600: "#161618",
|
18 |
-
700: "#161618",
|
19 |
-
800: "#161618",
|
20 |
-
900: "#161618",
|
21 |
-
},
|
22 |
-
},
|
23 |
container: {
|
24 |
center: true,
|
25 |
screens: {
|
|
|
7 |
],
|
8 |
theme: {
|
9 |
extend: {
|
10 |
+
color: {},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
11 |
container: {
|
12 |
center: true,
|
13 |
screens: {
|