Jon Taylor commited on
Commit
1e8ff3b
1 Parent(s): 2bca5f7
env.example CHANGED
@@ -6,4 +6,5 @@ SAFETY_CHECKER=1
6
  TORCH_COMPILE=1
7
  USE_TAESD=1
8
  BOT_WILL_IDLE=1
9
- FPS_CAP=
 
 
6
  TORCH_COMPILE=1
7
  USE_TAESD=1
8
  BOT_WILL_IDLE=1
9
+ FPS_CAP=
10
+ FAST_API_RELOAD=false
frontend/app/components/Avatar.js ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ export default function Avatar() {
2
+ return (
3
+ <span className="inline-block h-14 w-14 overflow-hidden rounded-full bg-gray-100">
4
+ <svg
5
+ className="h-full w-full text-gray-300"
6
+ fill="currentColor"
7
+ viewBox="0 0 24 24"
8
+ >
9
+ <path d="M24 20.993V24H0v-2.996A14.977 14.977 0 0112.004 15c4.904 0 9.26 2.354 11.996 5.993zM16.002 8.999a4 4 0 11-8 0 4 4 0 018 0z" />
10
+ </svg>
11
+ </span>
12
+ );
13
+ }
frontend/app/components/Call.js ADDED
@@ -0,0 +1,87 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ "use client";
2
+
3
+ import Link from "next/link";
4
+ import { useCallback, useEffect, useState } from "react";
5
+ import Card from "../components/Card";
6
+ import { VideoCameraIcon, PaintBrushIcon } from "@heroicons/react/24/outline";
7
+ import Avatar from "../components/Avatar";
8
+ import CreateRoom from "../components/CreateRoom";
9
+ import { apiUrl } from "../utils";
10
+ import Join from "../components/Joining";
11
+ import { DailyVideo, useLocalSessionId } from "@daily-co/daily-react";
12
+
13
+ const STATE_IDLE = "idle";
14
+ const STATE_JOINING = "joining";
15
+ const STATE_JOINED = "joined";
16
+ const STATE_LEFT = "left";
17
+ const BOT_STATE_STARTING = "bot_starting";
18
+ const BOT_STATE_STARTED = "bot_started";
19
+
20
+ export default function Call() {
21
+ const [callState, setCallState] = useState(STATE_IDLE);
22
+ const [roomUrl, setRoomUrl] = useState();
23
+ const [botState, setBotState] = useState(BOT_STATE_STARTING);
24
+ const localSessionId = useLocalSessionId();
25
+
26
+ const start = useCallback(async () => {
27
+ const resp = await fetch(`${apiUrl}/start`, {
28
+ method: "POST",
29
+ mode: "cors",
30
+ cache: "no-cache",
31
+ credentials: "same-origin",
32
+ headers: {
33
+ "Content-Type": "application/json",
34
+ },
35
+ body: JSON.stringify({ room_url: roomUrl }),
36
+ });
37
+
38
+ const data = await resp.json();
39
+ }, [roomUrl]);
40
+
41
+ useEffect(() => {
42
+ if (callState !== STATE_JOINED || botState === BOT_STATE_STARTED) return;
43
+ start();
44
+ }, [callState, botState, start]);
45
+
46
+ if (callState === STATE_IDLE) {
47
+ return (
48
+ <CreateRoom
49
+ onCreateRoom={(roomUrl) => {
50
+ setRoomUrl(roomUrl);
51
+ setCallState(STATE_JOINING);
52
+ }}
53
+ />
54
+ );
55
+ }
56
+
57
+ if (callState === STATE_JOINING) {
58
+ return <Join roomUrl={roomUrl} onJoin={() => setCallState(STATE_JOINED)} />;
59
+ }
60
+
61
+ // Main call loop
62
+ return (
63
+ <main className="container py-24">
64
+ <div className="grid grid-cols-2 grid-flow-col gap-4">
65
+ <div>
66
+ <Card headerText="Local Webcam" HeaderIcon={VideoCameraIcon}>
67
+ <div className="overflow-hidden bg-gray-50 sm:rounded-lg">
68
+ <div className="aspect-video flex items-center justify-center">
69
+ <DailyVideo automirror sessionId={localSessionId} />
70
+ </div>
71
+ </div>
72
+ </Card>
73
+ <div className="relative">Config - Resolution, Mbps, FPS</div>
74
+ </div>
75
+ <div>
76
+ <Card headerText="Inference" HeaderIcon={PaintBrushIcon}>
77
+ <div className="overflow-hidden bg-gray-50 sm:rounded-lg">
78
+ <div className="aspect-video flex items-center justify-center">
79
+ <Avatar />
80
+ </div>
81
+ </div>
82
+ </Card>
83
+ </div>
84
+ </div>
85
+ </main>
86
+ );
87
+ }
frontend/app/components/Card.js ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
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
+ }
frontend/app/components/CreateRoom.js ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { ArrowRightIcon } from "@heroicons/react/20/solid";
2
+ import { useState } from "react";
3
+ import { apiUrl } from "../utils";
4
+
5
+ export default function CreateRoom({ onCreateRoom }) {
6
+ const [fetching, setFetching] = useState(false);
7
+
8
+ async function create() {
9
+ setFetching(true);
10
+
11
+ const resp = await fetch(`${apiUrl}/create`, {
12
+ method: "POST",
13
+ mode: "cors",
14
+ cache: "no-cache",
15
+ credentials: "same-origin",
16
+ headers: {
17
+ "Content-Type": "application/json",
18
+ },
19
+ });
20
+
21
+ const data = await resp.json();
22
+
23
+ if (!data.room_url) {
24
+ setFetching(false);
25
+ console.log("error creating room");
26
+ }
27
+
28
+ onCreateRoom(data.room_url);
29
+ }
30
+
31
+ return (
32
+ <div className="bg-white shadow sm:rounded-lg max-w-xl mx-auto">
33
+ <div className="px-4 py-5 sm:p-6">
34
+ <h3 className="text-base font-semibold leading-6 text-gray-900">
35
+ What is this
36
+ </h3>
37
+ <div className="mt-2 text-sm text-gray-500">
38
+ <p>Explanation goes here</p>
39
+ </div>
40
+ <div className="mt-5">
41
+ <button
42
+ type="button"
43
+ disabled={fetching}
44
+ className="inline-flex items-center gap-x-2 rounded-md bg-indigo-600 px-3.5 py-2.5 text-sm font-semibold text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600"
45
+ onClick={() => create()}
46
+ >
47
+ Start
48
+ <ArrowRightIcon className="-h-5 w-5" aria-hidden="true" />
49
+ </button>
50
+ </div>
51
+ </div>
52
+ </div>
53
+ );
54
+ }
frontend/app/components/Joining.js ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { useDaily } from "@daily-co/daily-react";
2
+ import { useEffect } from "react";
3
+
4
+ export default function Join({ roomUrl, onJoin }) {
5
+ const daily = useDaily();
6
+
7
+ useEffect(() => {
8
+ daily.join({ url: roomUrl });
9
+
10
+ onJoin();
11
+ });
12
+
13
+ return (
14
+ <div className="bg-white shadow sm:rounded-lg max-w-xl mx-auto">
15
+ <div className="px-4 py-5 sm:p-6">
16
+ <h3 className="text-base font-semibold leading-6 text-gray-900">
17
+ Joining...
18
+ </h3>
19
+ </div>
20
+ </div>
21
+ );
22
+ }
frontend/app/components/PresetPrompts.js ADDED
@@ -0,0 +1,178 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { Popover, Transition } from "@headlessui/react";
2
+ import { ChevronDownIcon } from "@heroicons/react/20/solid";
3
+ import { Fragment } from "react";
4
+
5
+ const solutions = [
6
+ {
7
+ name: "Insights",
8
+ description: "Measure actions your users take",
9
+ href: "##",
10
+ icon: IconOne,
11
+ },
12
+ {
13
+ name: "Automations",
14
+ description: "Create your own targeted content",
15
+ href: "##",
16
+ icon: IconTwo,
17
+ },
18
+ {
19
+ name: "Reports",
20
+ description: "Keep track of your growth",
21
+ href: "##",
22
+ icon: IconThree,
23
+ },
24
+ ];
25
+
26
+ export default function PresetPrompts() {
27
+ return (
28
+ <div className="top-16 w-full max-w-sm px-4">
29
+ <Popover className="relative">
30
+ {({ open }) => (
31
+ <>
32
+ <Popover.Button
33
+ className={`
34
+ ${open ? "text-white" : "text-white/90"}
35
+ group inline-flex items-center rounded-md bg-orange-700 px-3 py-2 text-base font-medium hover:text-white focus:outline-none focus-visible:ring-2 focus-visible:ring-white/75`}
36
+ >
37
+ <span>Solutions</span>
38
+ <ChevronDownIcon
39
+ className={`${open ? "text-orange-300" : "text-orange-300/70"}
40
+ ml-2 h-5 w-5 transition duration-150 ease-in-out group-hover:text-orange-300/80`}
41
+ aria-hidden="true"
42
+ />
43
+ </Popover.Button>
44
+ <Transition
45
+ as={Fragment}
46
+ enter="transition ease-out duration-200"
47
+ enterFrom="opacity-0 translate-y-1"
48
+ enterTo="opacity-100 translate-y-0"
49
+ leave="transition ease-in duration-150"
50
+ leaveFrom="opacity-100 translate-y-0"
51
+ leaveTo="opacity-0 translate-y-1"
52
+ >
53
+ <Popover.Panel className="absolute left-1/2 z-10 mt-3 w-screen max-w-sm -translate-x-1/2 transform px-4 sm:px-0 lg:max-w-3xl">
54
+ <div className="overflow-hidden rounded-lg shadow-lg ring-1 ring-black/5">
55
+ <div className="relative grid gap-8 bg-white p-7 lg:grid-cols-2">
56
+ {solutions.map((item) => (
57
+ <a
58
+ key={item.name}
59
+ href={item.href}
60
+ className="-m-3 flex items-center rounded-lg p-2 transition duration-150 ease-in-out hover:bg-gray-50 focus:outline-none focus-visible:ring focus-visible:ring-orange-500/50"
61
+ >
62
+ <div className="flex h-10 w-10 shrink-0 items-center justify-center text-white sm:h-12 sm:w-12">
63
+ <item.icon aria-hidden="true" />
64
+ </div>
65
+ <div className="ml-4">
66
+ <p className="text-sm font-medium text-gray-900">
67
+ {item.name}
68
+ </p>
69
+ <p className="text-sm text-gray-500">
70
+ {item.description}
71
+ </p>
72
+ </div>
73
+ </a>
74
+ ))}
75
+ </div>
76
+ <div className="bg-gray-50 p-4">
77
+ <a
78
+ href="##"
79
+ className="flow-root rounded-md px-2 py-2 transition duration-150 ease-in-out hover:bg-gray-100 focus:outline-none focus-visible:ring focus-visible:ring-orange-500/50"
80
+ >
81
+ <span className="flex items-center">
82
+ <span className="text-sm font-medium text-gray-900">
83
+ Documentation
84
+ </span>
85
+ </span>
86
+ <span className="block text-sm text-gray-500">
87
+ Start integrating products and tools
88
+ </span>
89
+ </a>
90
+ </div>
91
+ </div>
92
+ </Popover.Panel>
93
+ </Transition>
94
+ </>
95
+ )}
96
+ </Popover>
97
+ </div>
98
+ );
99
+ }
100
+
101
+ function IconOne() {
102
+ return (
103
+ <svg
104
+ width="48"
105
+ height="48"
106
+ viewBox="0 0 48 48"
107
+ fill="none"
108
+ xmlns="http://www.w3.org/2000/svg"
109
+ >
110
+ <rect width="48" height="48" rx="8" fill="#FFEDD5" />
111
+ <path
112
+ d="M24 11L35.2583 17.5V30.5L24 37L12.7417 30.5V17.5L24 11Z"
113
+ stroke="#FB923C"
114
+ strokeWidth="2"
115
+ />
116
+ <path
117
+ fillRule="evenodd"
118
+ clipRule="evenodd"
119
+ d="M16.7417 19.8094V28.1906L24 32.3812L31.2584 28.1906V19.8094L24 15.6188L16.7417 19.8094Z"
120
+ stroke="#FDBA74"
121
+ strokeWidth="2"
122
+ />
123
+ <path
124
+ fillRule="evenodd"
125
+ clipRule="evenodd"
126
+ d="M20.7417 22.1196V25.882L24 27.7632L27.2584 25.882V22.1196L24 20.2384L20.7417 22.1196Z"
127
+ stroke="#FDBA74"
128
+ strokeWidth="2"
129
+ />
130
+ </svg>
131
+ );
132
+ }
133
+
134
+ function IconTwo() {
135
+ return (
136
+ <svg
137
+ width="48"
138
+ height="48"
139
+ viewBox="0 0 48 48"
140
+ fill="none"
141
+ xmlns="http://www.w3.org/2000/svg"
142
+ >
143
+ <rect width="48" height="48" rx="8" fill="#FFEDD5" />
144
+ <path
145
+ d="M28.0413 20L23.9998 13L19.9585 20M32.0828 27.0001L36.1242 34H28.0415M19.9585 34H11.8755L15.9171 27"
146
+ stroke="#FB923C"
147
+ strokeWidth="2"
148
+ />
149
+ <path
150
+ fillRule="evenodd"
151
+ clipRule="evenodd"
152
+ d="M18.804 30H29.1963L24.0001 21L18.804 30Z"
153
+ stroke="#FDBA74"
154
+ strokeWidth="2"
155
+ />
156
+ </svg>
157
+ );
158
+ }
159
+
160
+ function IconThree() {
161
+ return (
162
+ <svg
163
+ width="48"
164
+ height="48"
165
+ viewBox="0 0 48 48"
166
+ fill="none"
167
+ xmlns="http://www.w3.org/2000/svg"
168
+ >
169
+ <rect width="48" height="48" rx="8" fill="#FFEDD5" />
170
+ <rect x="13" y="32" width="2" height="4" fill="#FDBA74" />
171
+ <rect x="17" y="28" width="2" height="8" fill="#FDBA74" />
172
+ <rect x="21" y="24" width="2" height="12" fill="#FDBA74" />
173
+ <rect x="25" y="20" width="2" height="16" fill="#FDBA74" />
174
+ <rect x="29" y="16" width="2" height="20" fill="#FB923C" />
175
+ <rect x="33" y="12" width="2" height="24" fill="#FB923C" />
176
+ </svg>
177
+ );
178
+ }
frontend/app/globals.css CHANGED
@@ -2,26 +2,13 @@
2
  @tailwind components;
3
  @tailwind utilities;
4
 
5
- :root {
6
- --foreground-rgb: 0, 0, 0;
7
- --background-start-rgb: 214, 219, 220;
8
- --background-end-rgb: 255, 255, 255;
9
- }
10
-
11
- @media (prefers-color-scheme: dark) {
12
- :root {
13
- --foreground-rgb: 255, 255, 255;
14
- --background-start-rgb: 0, 0, 0;
15
- --background-end-rgb: 0, 0, 0;
16
- }
17
  }
18
 
 
19
  body {
20
- color: rgb(var(--foreground-rgb));
21
- background: linear-gradient(
22
- to bottom,
23
- transparent,
24
- rgb(var(--background-end-rgb))
25
- )
26
- rgb(var(--background-start-rgb));
27
  }
 
2
  @tailwind components;
3
  @tailwind utilities;
4
 
5
+ * {
6
+ box-sizing: border-box;
 
 
 
 
 
 
 
 
 
 
7
  }
8
 
9
+ html,
10
  body {
11
+ -webkit-font-smoothing: antialiased;
12
+ -moz-osx-font-smoothing: grayscale;
13
+ @apply text-black;
 
 
 
 
14
  }
frontend/app/layout.js CHANGED
@@ -1,17 +1,21 @@
1
- import { Inter } from 'next/font/google'
2
- import './globals.css'
3
 
4
- const inter = Inter({ subsets: ['latin'] })
5
 
6
  export const metadata = {
7
- title: 'Create Next App',
8
- description: 'Generated by create next app',
9
- }
10
 
11
  export default function RootLayout({ children }) {
12
  return (
13
- <html lang="en">
14
- <body className={inter.className}>{children}</body>
 
 
 
 
15
  </html>
16
- )
17
  }
 
1
+ import { Inter } from "next/font/google";
2
+ import "./globals.css";
3
 
4
+ const inter = Inter({ subsets: ["latin"] });
5
 
6
  export const metadata = {
7
+ title: "Real-time SDTurbo + WebRTC",
8
+ description: "",
9
+ };
10
 
11
  export default function RootLayout({ children }) {
12
  return (
13
+ <html lang="en" className="bg-gray-100">
14
+ <body className={inter.className}>
15
+ <div className="container flex align-center min-h-screen">
16
+ <div className="self-center w-full">{children}</div>
17
+ </div>
18
+ </body>
19
  </html>
20
+ );
21
  }
frontend/app/page.js CHANGED
@@ -1,54 +1,22 @@
1
  "use client";
2
 
3
- import Link from "next/link";
4
- import { useState } from "react";
 
 
5
 
6
  export default function Home() {
7
- const [starting, setStarting] = useState(false);
8
- const [roomUrl, setRoomUrl] = useState();
9
 
10
- async function start() {
11
- setStarting(true);
12
 
13
- const apiUrl = `${
14
- window.location.protocol === "https:" ? "https" : "http"
15
- }:${window.location.host}`;
16
-
17
- const resp = await fetch(`${process.env.API_URL || apiUrl}/start`, {
18
- method: "POST",
19
- mode: "cors",
20
- cache: "no-cache",
21
- credentials: "same-origin",
22
- headers: {
23
- "Content-Type": "application/json",
24
- },
25
- body: JSON.stringify({}),
26
- });
27
-
28
- const data = await resp.json();
29
-
30
- setRoomUrl(data.room_url);
31
- }
32
 
33
  return (
34
- <main className="flex min-h-screen flex-col items-center justify-between p-24">
35
- {!starting ? (
36
- <button
37
- onClick={() => start()}
38
- disabled={starting}
39
- className="bg-white text-black rounded-xl p-4 px-6"
40
- >
41
- Connect
42
- </button>
43
- ) : (
44
- <div>
45
- {roomUrl ? (
46
- <Link href={roomUrl}>Open Room</Link>
47
- ) : (
48
- "Waiting for bot to load..."
49
- )}
50
- </div>
51
- )}
52
- </main>
53
  );
54
  }
 
1
  "use client";
2
 
3
+ import { useEffect, useState } from "react";
4
+ import { DailyProvider } from "@daily-co/daily-react";
5
+ import Daily from "@daily-co/daily-js";
6
+ import Call from "./components/Call";
7
 
8
  export default function Home() {
9
+ const [daily, setDaily] = useState();
 
10
 
11
+ useEffect(() => {
12
+ if (daily) return;
13
 
14
+ setDaily(Daily.createCallObject());
15
+ }, [daily]);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
 
17
  return (
18
+ <DailyProvider callObject={daily}>
19
+ <Call />
20
+ </DailyProvider>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21
  );
22
  }
frontend/app/test/page.js DELETED
@@ -1,7 +0,0 @@
1
- export default function Test() {
2
- return (
3
- <main className="flex min-h-screen flex-col items-center justify-between p-24">
4
- Hi
5
- </main>
6
- );
7
- }
 
 
 
 
 
 
 
 
frontend/app/utils.js ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ export const apiUrl =
2
+ process.env.NEXT_PUBLIC_API_URL ||
3
+ `${window.location.protocol === "https:" ? "https" : "http"}://${
4
+ window.location.host
5
+ }`;
frontend/env.example ADDED
@@ -0,0 +1 @@
 
 
1
+ NEXT_PUBLIC_API_URL=
frontend/next.config.js CHANGED
@@ -1,6 +1,5 @@
1
  /** @type {import('next').NextConfig} */
2
- const nextConfig = {
 
3
  output: "export",
4
  };
5
-
6
- module.exports = nextConfig;
 
1
  /** @type {import('next').NextConfig} */
2
+ module.exports = {
3
+ reactStrictMode: false,
4
  output: "export",
5
  };
 
 
frontend/package.json CHANGED
@@ -9,15 +9,20 @@
9
  "lint": "next lint"
10
  },
11
  "dependencies": {
 
 
 
 
 
12
  "react": "^18",
13
  "react-dom": "^18",
14
- "next": "14.0.3"
15
  },
16
  "devDependencies": {
17
  "autoprefixer": "^10.0.1",
18
- "postcss": "^8",
19
- "tailwindcss": "^3.3.0",
20
  "eslint": "^8",
21
- "eslint-config-next": "14.0.3"
 
 
22
  }
23
  }
 
9
  "lint": "next lint"
10
  },
11
  "dependencies": {
12
+ "@daily-co/daily-js": "^0.55.1",
13
+ "@daily-co/daily-react": "^0.16.0",
14
+ "@headlessui/react": "^1.7.17",
15
+ "@heroicons/react": "^2.0.18",
16
+ "next": "14.0.3",
17
  "react": "^18",
18
  "react-dom": "^18",
19
+ "recoil": "^0.7.7"
20
  },
21
  "devDependencies": {
22
  "autoprefixer": "^10.0.1",
 
 
23
  "eslint": "^8",
24
+ "eslint-config-next": "14.0.3",
25
+ "postcss": "^8",
26
+ "tailwindcss": "^3.3.0"
27
  }
28
  }
frontend/tailwind.config.js CHANGED
@@ -1,18 +1,28 @@
1
  /** @type {import('tailwindcss').Config} */
2
  module.exports = {
3
  content: [
4
- './pages/**/*.{js,ts,jsx,tsx,mdx}',
5
- './components/**/*.{js,ts,jsx,tsx,mdx}',
6
- './app/**/*.{js,ts,jsx,tsx,mdx}',
7
  ],
8
  theme: {
9
  extend: {
 
 
 
 
 
 
 
 
 
 
10
  backgroundImage: {
11
- 'gradient-radial': 'radial-gradient(var(--tw-gradient-stops))',
12
- 'gradient-conic':
13
- 'conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))',
14
  },
15
  },
16
  },
17
  plugins: [],
18
- }
 
1
  /** @type {import('tailwindcss').Config} */
2
  module.exports = {
3
  content: [
4
+ "./pages/**/*.{js,ts,jsx,tsx,mdx}",
5
+ "./components/**/*.{js,ts,jsx,tsx,mdx}",
6
+ "./app/**/*.{js,ts,jsx,tsx,mdx}",
7
  ],
8
  theme: {
9
  extend: {
10
+ container: {
11
+ center: true,
12
+ screens: {
13
+ sm: "640px",
14
+ md: "768px",
15
+ lg: "1024px",
16
+ xl: "1280px",
17
+ "2xl": "1280px",
18
+ },
19
+ },
20
  backgroundImage: {
21
+ "gradient-radial": "radial-gradient(var(--tw-gradient-stops))",
22
+ "gradient-conic":
23
+ "conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))",
24
  },
25
  },
26
  },
27
  plugins: [],
28
+ };
frontend/yarn.lock CHANGED
@@ -12,13 +12,34 @@
12
  resolved "https://registry.yarnpkg.com/@alloc/quick-lru/-/quick-lru-5.2.0.tgz#7bf68b20c0a350f936915fcae06f58e32007ce30"
13
  integrity sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==
14
 
15
- "@babel/runtime@^7.23.2":
16
  version "7.23.5"
17
  resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.23.5.tgz#11edb98f8aeec529b82b211028177679144242db"
18
  integrity sha512-NdUTHcPe4C99WxPub+K9l9tK5/lV4UXIoaHSYgzco9BCyjKAAwzdBI+wWtYqHt7LJdbo74ZjRPJgzVweq1sz0w==
19
  dependencies:
20
  regenerator-runtime "^0.14.0"
21
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22
  "@eslint-community/eslint-utils@^4.2.0":
23
  version "4.4.0"
24
  resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz#a23514e8fb9af1269d5f7788aa556798d61c6b59"
@@ -51,6 +72,18 @@
51
  resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.55.0.tgz#b721d52060f369aa259cf97392403cb9ce892ec6"
52
  integrity sha512-qQfo2mxH5yVom1kacMtZZJFVdW+E70mqHMJvVg6WTLo+VBuQJ4TojZlfWBjK0ve5BdEeNAVxOsl/nvNMpJOaJA==
53
 
 
 
 
 
 
 
 
 
 
 
 
 
54
  "@humanwhocodes/config-array@^0.11.13":
55
  version "0.11.13"
56
  resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.13.tgz#075dc9684f40a531d9b26b0822153c1e832ee297"
@@ -185,6 +218,66 @@
185
  resolved "https://registry.yarnpkg.com/@rushstack/eslint-patch/-/eslint-patch-1.6.0.tgz#1898e7a7b943680d757417a47fb10f5fcc230b39"
186
  integrity sha512-2/U3GXA6YiPYQDLGwtGlnNgKYBSwCFIHf8Y9LUY5VATHdtbLlU0Y1R3QoBnT0aB4qv/BEiVVsj7LJXoQCgJ2vA==
187
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
188
  "@swc/helpers@0.5.2":
189
  version "0.5.2"
190
  resolved "https://registry.yarnpkg.com/@swc/helpers/-/helpers-0.5.2.tgz#85ea0c76450b61ad7d10a37050289eded783c27d"
@@ -439,6 +532,11 @@ binary-extensions@^2.0.0:
439
  resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d"
440
  integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==
441
 
 
 
 
 
 
442
  brace-expansion@^1.1.7:
443
  version "1.1.11"
444
  resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
@@ -518,7 +616,7 @@ chokidar@^3.5.3:
518
  optionalDependencies:
519
  fsevents "~2.3.2"
520
 
521
- client-only@0.0.1:
522
  version "0.0.1"
523
  resolved "https://registry.yarnpkg.com/client-only/-/client-only-0.0.1.tgz#38bba5d403c41ab150bff64a95c85013cf73bca1"
524
  integrity sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==
@@ -961,11 +1059,21 @@ esutils@^2.0.2:
961
  resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64"
962
  integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==
963
 
 
 
 
 
 
964
  fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3:
965
  version "3.1.3"
966
  resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525"
967
  integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==
968
 
 
 
 
 
 
969
  fast-glob@^3.2.9, fast-glob@^3.3.0, fast-glob@^3.3.1:
970
  version "3.3.2"
971
  resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.2.tgz#a904501e57cfdd2ffcded45e99a54fef55e46129"
@@ -1195,6 +1303,11 @@ graphemer@^1.4.0:
1195
  resolved "https://registry.yarnpkg.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6"
1196
  integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==
1197
 
 
 
 
 
 
1198
  has-bigints@^1.0.1, has-bigints@^1.0.2:
1199
  version "1.0.2"
1200
  resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.2.tgz#0871bd3e3d51626f6ca0966668ba35d5602d6eaa"
@@ -1571,6 +1684,16 @@ lodash.merge@^4.6.2:
1571
  resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a"
1572
  integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==
1573
 
 
 
 
 
 
 
 
 
 
 
1574
  loose-envify@^1.1.0, loose-envify@^1.4.0:
1575
  version "1.4.0"
1576
  resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf"
@@ -1957,6 +2080,13 @@ readdirp@~3.6.0:
1957
  dependencies:
1958
  picomatch "^2.2.1"
1959
 
 
 
 
 
 
 
 
1960
  reflect.getprototypeof@^1.0.4:
1961
  version "1.0.4"
1962
  resolved "https://registry.yarnpkg.com/reflect.getprototypeof/-/reflect.getprototypeof-1.0.4.tgz#aaccbf41aca3821b87bb71d9dcbc7ad0ba50a3f3"
 
12
  resolved "https://registry.yarnpkg.com/@alloc/quick-lru/-/quick-lru-5.2.0.tgz#7bf68b20c0a350f936915fcae06f58e32007ce30"
13
  integrity sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==
14
 
15
+ "@babel/runtime@^7.12.5", "@babel/runtime@^7.23.2":
16
  version "7.23.5"
17
  resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.23.5.tgz#11edb98f8aeec529b82b211028177679144242db"
18
  integrity sha512-NdUTHcPe4C99WxPub+K9l9tK5/lV4UXIoaHSYgzco9BCyjKAAwzdBI+wWtYqHt7LJdbo74ZjRPJgzVweq1sz0w==
19
  dependencies:
20
  regenerator-runtime "^0.14.0"
21
 
22
+ "@daily-co/daily-js@^0.55.1":
23
+ version "0.55.1"
24
+ resolved "https://registry.yarnpkg.com/@daily-co/daily-js/-/daily-js-0.55.1.tgz#e4c8199d141c52f829f6ec1002fb514793b798d1"
25
+ integrity sha512-UaTFBHeGfeR+169uTuRSkcv0Sj9n2q5mORNs3Gez/rq0by9UHosnK7uO56AKvXCH/fR0dx/yLIR7p9Lamv2mkQ==
26
+ dependencies:
27
+ "@babel/runtime" "^7.12.5"
28
+ "@sentry/browser" "^7.60.1"
29
+ bowser "^2.8.1"
30
+ dequal "^2.0.3"
31
+ events "^3.1.0"
32
+ fast-equals "^1.6.3"
33
+ lodash "^4.17.15"
34
+
35
+ "@daily-co/daily-react@^0.16.0":
36
+ version "0.16.0"
37
+ resolved "https://registry.yarnpkg.com/@daily-co/daily-react/-/daily-react-0.16.0.tgz#02189d596999a0b3b1f208c8f19323637293f276"
38
+ integrity sha512-EP5QZs8WUBxrMI5Kzqdr8HYV+cbPZVMhYeMY1ycYHcZTb+p9V4ay4bSKYsYGCsH0Fut2sXOQc8p7UWl/mxmbXw==
39
+ dependencies:
40
+ fast-deep-equal "^3.1.3"
41
+ lodash.throttle "^4.1.1"
42
+
43
  "@eslint-community/eslint-utils@^4.2.0":
44
  version "4.4.0"
45
  resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz#a23514e8fb9af1269d5f7788aa556798d61c6b59"
 
72
  resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.55.0.tgz#b721d52060f369aa259cf97392403cb9ce892ec6"
73
  integrity sha512-qQfo2mxH5yVom1kacMtZZJFVdW+E70mqHMJvVg6WTLo+VBuQJ4TojZlfWBjK0ve5BdEeNAVxOsl/nvNMpJOaJA==
74
 
75
+ "@headlessui/react@^1.7.17":
76
+ version "1.7.17"
77
+ resolved "https://registry.yarnpkg.com/@headlessui/react/-/react-1.7.17.tgz#a0ec23af21b527c030967245fd99776aa7352bc6"
78
+ integrity sha512-4am+tzvkqDSSgiwrsEpGWqgGo9dz8qU5M3znCkC4PgkpY4HcCZzEDEvozltGGGHIKl9jbXbZPSH5TWn4sWJdow==
79
+ dependencies:
80
+ client-only "^0.0.1"
81
+
82
+ "@heroicons/react@^2.0.18":
83
+ version "2.0.18"
84
+ resolved "https://registry.yarnpkg.com/@heroicons/react/-/react-2.0.18.tgz#f80301907c243df03c7e9fd76c0286e95361f7c1"
85
+ integrity sha512-7TyMjRrZZMBPa+/5Y8lN0iyvUU/01PeMGX2+RE7cQWpEUIcb4QotzUObFkJDejj/HUH4qjP/eQ0gzzKs2f+6Yw==
86
+
87
  "@humanwhocodes/config-array@^0.11.13":
88
  version "0.11.13"
89
  resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.13.tgz#075dc9684f40a531d9b26b0822153c1e832ee297"
 
218
  resolved "https://registry.yarnpkg.com/@rushstack/eslint-patch/-/eslint-patch-1.6.0.tgz#1898e7a7b943680d757417a47fb10f5fcc230b39"
219
  integrity sha512-2/U3GXA6YiPYQDLGwtGlnNgKYBSwCFIHf8Y9LUY5VATHdtbLlU0Y1R3QoBnT0aB4qv/BEiVVsj7LJXoQCgJ2vA==
220
 
221
+ "@sentry-internal/feedback@7.86.0":
222
+ version "7.86.0"
223
+ resolved "https://registry.yarnpkg.com/@sentry-internal/feedback/-/feedback-7.86.0.tgz#01c7b509a3adc9cdd03658082daf29a6cae9cc8f"
224
+ integrity sha512-6rl0JYjmAKnhm4/fuFaROh4Ht8oi9f6ZeIcViCuGJcrGICZJJY0s+R77XJI78rNa82PYFrSCcnWXcGji4T8E7g==
225
+ dependencies:
226
+ "@sentry/core" "7.86.0"
227
+ "@sentry/types" "7.86.0"
228
+ "@sentry/utils" "7.86.0"
229
+
230
+ "@sentry-internal/tracing@7.86.0":
231
+ version "7.86.0"
232
+ resolved "https://registry.yarnpkg.com/@sentry-internal/tracing/-/tracing-7.86.0.tgz#657e80eb7d08d1030393902c1a7bc47fc39ccb2d"
233
+ integrity sha512-b4dUsNWlPWRwakGwR7bhOkqiFlqQszH1hhVFwrm/8s3kqEBZ+E4CeIfCvuHBHQ1cM/fx55xpXX/BU163cy+3iQ==
234
+ dependencies:
235
+ "@sentry/core" "7.86.0"
236
+ "@sentry/types" "7.86.0"
237
+ "@sentry/utils" "7.86.0"
238
+
239
+ "@sentry/browser@^7.60.1":
240
+ version "7.86.0"
241
+ resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-7.86.0.tgz#9b828a444949f8fe4a47d830cc87b8b52275c24e"
242
+ integrity sha512-nfYWpVOmug+W7KJO7/xhA1JScMZcYHcoOVHLsUFm4znx51U4qZEk+zZDM11Q2Nw6MuDyEYg6bsH1QCwaoC6nLw==
243
+ dependencies:
244
+ "@sentry-internal/feedback" "7.86.0"
245
+ "@sentry-internal/tracing" "7.86.0"
246
+ "@sentry/core" "7.86.0"
247
+ "@sentry/replay" "7.86.0"
248
+ "@sentry/types" "7.86.0"
249
+ "@sentry/utils" "7.86.0"
250
+
251
+ "@sentry/core@7.86.0":
252
+ version "7.86.0"
253
+ resolved "https://registry.yarnpkg.com/@sentry/core/-/core-7.86.0.tgz#d01f538783dee9a0d79141a63145392ad2c1cb89"
254
+ integrity sha512-SbLvqd1bRYzhDS42u7GMnmbDMfth/zRiLElQWbLK/shmuZzTcfQSwNNdF4Yj+VfjOkqPFgGmICHSHVUc9dh01g==
255
+ dependencies:
256
+ "@sentry/types" "7.86.0"
257
+ "@sentry/utils" "7.86.0"
258
+
259
+ "@sentry/replay@7.86.0":
260
+ version "7.86.0"
261
+ resolved "https://registry.yarnpkg.com/@sentry/replay/-/replay-7.86.0.tgz#d001eac9687de3555efded9423d3cf00e8ae6d9f"
262
+ integrity sha512-YYZO8bfQSx1H87Te/zzyHPLHvExWiYwUfMWW68yGX+PPZIIzxaM81/iCQHkoucxlvuPCOtxCgf7RSMbsnqEa8g==
263
+ dependencies:
264
+ "@sentry-internal/tracing" "7.86.0"
265
+ "@sentry/core" "7.86.0"
266
+ "@sentry/types" "7.86.0"
267
+ "@sentry/utils" "7.86.0"
268
+
269
+ "@sentry/types@7.86.0":
270
+ version "7.86.0"
271
+ resolved "https://registry.yarnpkg.com/@sentry/types/-/types-7.86.0.tgz#56ed2f5b15e8130ea5ecfbbc4102d88eaa3b3a67"
272
+ integrity sha512-pGAt0+bMfWgo0KG2epthfNV4Wae03tURpoxNjGo5Fr4cXxvLTSijSAQ6rmmO4bXBJ7+rErEjX30g30o/eEdP9g==
273
+
274
+ "@sentry/utils@7.86.0":
275
+ version "7.86.0"
276
+ resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-7.86.0.tgz#356ec19bf1e3e5c40935dd987fd15bee8c6b37ba"
277
+ integrity sha512-6PejFtw9VTFFy5vu0ks+U7Ozkqz+eMt+HN8AZKBKErYzX5/xs0kpkOcSRpu3ETdTYcZf8VAmLVgFgE2BE+3WuQ==
278
+ dependencies:
279
+ "@sentry/types" "7.86.0"
280
+
281
  "@swc/helpers@0.5.2":
282
  version "0.5.2"
283
  resolved "https://registry.yarnpkg.com/@swc/helpers/-/helpers-0.5.2.tgz#85ea0c76450b61ad7d10a37050289eded783c27d"
 
532
  resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d"
533
  integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==
534
 
535
+ bowser@^2.8.1:
536
+ version "2.11.0"
537
+ resolved "https://registry.yarnpkg.com/bowser/-/bowser-2.11.0.tgz#5ca3c35757a7aa5771500c70a73a9f91ef420a8f"
538
+ integrity sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA==
539
+
540
  brace-expansion@^1.1.7:
541
  version "1.1.11"
542
  resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
 
616
  optionalDependencies:
617
  fsevents "~2.3.2"
618
 
619
+ client-only@0.0.1, client-only@^0.0.1:
620
  version "0.0.1"
621
  resolved "https://registry.yarnpkg.com/client-only/-/client-only-0.0.1.tgz#38bba5d403c41ab150bff64a95c85013cf73bca1"
622
  integrity sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==
 
1059
  resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64"
1060
  integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==
1061
 
1062
+ events@^3.1.0:
1063
+ version "3.3.0"
1064
+ resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400"
1065
+ integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==
1066
+
1067
  fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3:
1068
  version "3.1.3"
1069
  resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525"
1070
  integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==
1071
 
1072
+ fast-equals@^1.6.3:
1073
+ version "1.6.3"
1074
+ resolved "https://registry.yarnpkg.com/fast-equals/-/fast-equals-1.6.3.tgz#84839a1ce20627c463e1892f2ae316380c81b459"
1075
+ integrity sha512-4WKW0AL5+WEqO0zWavAfYGY1qwLsBgE//DN4TTcVEN2UlINgkv9b3vm2iHicoenWKSX9mKWmGOsU/iI5IST7pQ==
1076
+
1077
  fast-glob@^3.2.9, fast-glob@^3.3.0, fast-glob@^3.3.1:
1078
  version "3.3.2"
1079
  resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.2.tgz#a904501e57cfdd2ffcded45e99a54fef55e46129"
 
1303
  resolved "https://registry.yarnpkg.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6"
1304
  integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==
1305
 
1306
+ hamt_plus@1.0.2:
1307
+ version "1.0.2"
1308
+ resolved "https://registry.yarnpkg.com/hamt_plus/-/hamt_plus-1.0.2.tgz#e21c252968c7e33b20f6a1b094cd85787a265601"
1309
+ integrity sha512-t2JXKaehnMb9paaYA7J0BX8QQAY8lwfQ9Gjf4pg/mk4krt+cmwmU652HOoWonf+7+EQV97ARPMhhVgU1ra2GhA==
1310
+
1311
  has-bigints@^1.0.1, has-bigints@^1.0.2:
1312
  version "1.0.2"
1313
  resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.2.tgz#0871bd3e3d51626f6ca0966668ba35d5602d6eaa"
 
1684
  resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a"
1685
  integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==
1686
 
1687
+ lodash.throttle@^4.1.1:
1688
+ version "4.1.1"
1689
+ resolved "https://registry.yarnpkg.com/lodash.throttle/-/lodash.throttle-4.1.1.tgz#c23e91b710242ac70c37f1e1cda9274cc39bf2f4"
1690
+ integrity sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ==
1691
+
1692
+ lodash@^4.17.15:
1693
+ version "4.17.21"
1694
+ resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
1695
+ integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
1696
+
1697
  loose-envify@^1.1.0, loose-envify@^1.4.0:
1698
  version "1.4.0"
1699
  resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf"
 
2080
  dependencies:
2081
  picomatch "^2.2.1"
2082
 
2083
+ recoil@^0.7.7:
2084
+ version "0.7.7"
2085
+ resolved "https://registry.yarnpkg.com/recoil/-/recoil-0.7.7.tgz#c5f2c843224384c9c09e4a62c060fb4c1454dc8e"
2086
+ integrity sha512-8Og5KPQW9LwC577Vc7Ug2P0vQshkv1y3zG3tSSkWMqkWSwHmE+by06L8JtnGocjW6gcCvfwB3YtrJG6/tWivNQ==
2087
+ dependencies:
2088
+ hamt_plus "1.0.2"
2089
+
2090
  reflect.getprototypeof@^1.0.4:
2091
  version "1.0.4"
2092
  resolved "https://registry.yarnpkg.com/reflect.getprototypeof/-/reflect.getprototypeof-1.0.4.tgz#aaccbf41aca3821b87bb71d9dcbc7ad0ba50a3f3"
server.py CHANGED
@@ -1,4 +1,4 @@
1
- from fastapi import FastAPI, HTTPException
2
  from fastapi.middleware.cors import CORSMiddleware
3
  from fastapi.staticfiles import StaticFiles
4
  from fastapi.responses import FileResponse, JSONResponse
@@ -26,41 +26,49 @@ app.add_middleware(
26
  # Mount the static directory
27
  app.mount("/static", StaticFiles(directory="frontend/out", html=True), name="static")
28
 
29
- def _start_bot(bot_path, args=None):
30
- '''
31
  api_path = os.getenv("DAILY_API_PATH") or "https://api.daily.co/v1"
 
 
32
 
33
- res = requests.post(
34
- f"{api_path}/rooms",
35
- headers={"Authorization": f"Bearer {daily_api_key}"},
36
- json={
37
- "properties": {
38
- "exp": exp,
39
- "enable_chat": True,
40
- "enable_emoji_reactions": True,
41
- "eject_at_room_exp": True,
42
- "enable_prejoin_ui": False,
43
- }
44
- },
45
- )
46
- if res.status_code != 200:
47
- return (
48
- jsonify(
49
- {
50
- "error": "Unable to create room",
51
- "status_code": res.status_code,
52
- "text": res.text,
53
  }
54
- ),
55
- 500,
56
  )
57
- '''
58
-
59
- daily_room_url = os.getenv("DAILY_ROOM_URL") #res.json()["url"]
60
- daily_room_name = get_room_name(daily_room_url)
 
 
 
 
 
 
 
 
 
 
 
 
 
61
  daily_api_path = os.getenv("DAILY_API_PATH")
62
  daily_api_key = os.getenv("DAILY_API_KEY")
63
 
 
 
64
  if args:
65
  extra_args = " ".join([f'-{x[0]} "{x[1]}"' for x in args])
66
  else:
@@ -68,7 +76,7 @@ def _start_bot(bot_path, args=None):
68
 
69
  proc = subprocess.Popen(
70
  [
71
- f"python3 {bot_path} -u {daily_room_url} -k {daily_api_key} {extra_args}"
72
  ],
73
  shell=True,
74
  bufsize=1,
@@ -87,12 +95,17 @@ def _start_bot(bot_path, args=None):
87
  break
88
  print(f"Took {attempts} attempts to join room {daily_room_name}")
89
 
90
- return JSONResponse({"room_url": daily_room_url})
91
 
92
 
93
  @app.post("/start")
94
- async def start():
95
- return _start_bot("./app/bot.py")
 
 
 
 
 
96
 
97
  @app.get("/{path_name:path}", response_class=FileResponse)
98
  async def catch_all(path_name: str):
 
1
+ from fastapi import FastAPI, Request, HTTPException
2
  from fastapi.middleware.cors import CORSMiddleware
3
  from fastapi.staticfiles import StaticFiles
4
  from fastapi.responses import FileResponse, JSONResponse
 
26
  # Mount the static directory
27
  app.mount("/static", StaticFiles(directory="frontend/out", html=True), name="static")
28
 
29
+ def _create_room():
 
30
  api_path = os.getenv("DAILY_API_PATH") or "https://api.daily.co/v1"
31
+ expiry_time = os.getenv("BOT_MAX_DURATION", 300)
32
+ daily_api_key = os.getenv("DAILY_API_KEY", None)
33
 
34
+ try:
35
+ res = requests.post(
36
+ f"{api_path}/rooms",
37
+ headers={"Authorization": f"Bearer {daily_api_key}"},
38
+ json={
39
+ "properties": {
40
+ "exp": time.time() + int(expiry_time),
41
+ "eject_at_room_exp": True,
42
+ "enable_prejoin_ui": False,
43
+ "start_audio_off": True,
44
+ "permissions": {
45
+ "canSend": ["video"]
46
+ }
 
 
 
 
 
 
 
47
  }
48
+ }
 
49
  )
50
+ if res.status_code != 200:
51
+ return JSONResponse({
52
+ "error": "Unable to create room",
53
+ "status_code": res.status_code,
54
+ "text": res.text
55
+ }, 500)
56
+
57
+ data = res.json()
58
+ print(data)
59
+ return JSONResponse({"room_url": data["url"], "privacy": data["privacy"]})
60
+
61
+ except Exception:
62
+ return JSONResponse({"error": Exception})
63
+
64
+
65
+ def _start_bot(bot_path, room_url, args=None):
66
+ daily_room_name = get_room_name(room_url)
67
  daily_api_path = os.getenv("DAILY_API_PATH")
68
  daily_api_key = os.getenv("DAILY_API_KEY")
69
 
70
+ #@TODO error handling here
71
+
72
  if args:
73
  extra_args = " ".join([f'-{x[0]} "{x[1]}"' for x in args])
74
  else:
 
76
 
77
  proc = subprocess.Popen(
78
  [
79
+ f"python3 {bot_path} -u {room_url} -k {daily_api_key} {extra_args}"
80
  ],
81
  shell=True,
82
  bufsize=1,
 
95
  break
96
  print(f"Took {attempts} attempts to join room {daily_room_name}")
97
 
98
+ return JSONResponse({"started": True})
99
 
100
 
101
  @app.post("/start")
102
+ async def start(request: Request):
103
+ data = await request.json()
104
+ return _start_bot("./app/bot.py", data.room_url)
105
+
106
+ @app.post("/create")
107
+ async def create():
108
+ return _create_room()
109
 
110
  @app.get("/{path_name:path}", response_class=FileResponse)
111
  async def catch_all(path_name: str):