Jon Taylor commited on
Commit
dd10606
1 Parent(s): 76b9248

ui updates

Browse files
frontend/app/components/Card.js CHANGED
@@ -1,11 +1,9 @@
1
- export default function Card({ headerText = "Header", HeaderIcon, children }) {
2
  return (
3
- <div className="overflow-hidden rounded-lg bg-white border shadow-lg">
4
- <header className="flex flex-row gap-2 px-4 py-5 sm:px-6">
5
- <HeaderIcon className="w-5 h5" />
6
- <h3 className="text-sm font-bold">{headerText}</h3>
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 { Accordion, ActionIcon, Button, SegmentedControl } from "@mantine/core";
 
 
 
 
 
 
4
  import { useForm } from "@mantine/form";
5
- import { IconRotateClockwise } from "@tabler/icons-react";
 
 
 
 
 
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 defaultValue="camera">
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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="inference" key="inference">
50
- <Accordion.Control value="inference">Inference</Accordion.Control>
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
- @tailwind components;
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
- const inter = Inter({ subsets: ["latin"] });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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={`${inter.className} bg-gray-100`}>
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="h-screen grid grid-cols-[480px_1fr]">
6
- <aside className="overflow-y-auto border-r border-gray-200 bg-white">
7
- <Controls />
8
- global settings: resolution
9
- <br />
10
- camera settings: simulcast - fps bitrate seed guidance
11
- <br />
12
- seed, guidance, strength, cn scale, cn start, cn end, canny low
13
- threshold, canny_high_threshold, debug canny
14
- </aside>
15
- <main className="overflow-y-auto">Main</main>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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: {