Spaces:
Sleeping
Sleeping
Jon Taylor
commited on
Commit
•
1e8ff3b
1
Parent(s):
2bca5f7
added UI
Browse files- env.example +2 -1
- frontend/app/components/Avatar.js +13 -0
- frontend/app/components/Call.js +87 -0
- frontend/app/components/Card.js +11 -0
- frontend/app/components/CreateRoom.js +54 -0
- frontend/app/components/Joining.js +22 -0
- frontend/app/components/PresetPrompts.js +178 -0
- frontend/app/globals.css +6 -19
- frontend/app/layout.js +13 -9
- frontend/app/page.js +12 -44
- frontend/app/test/page.js +0 -7
- frontend/app/utils.js +5 -0
- frontend/env.example +1 -0
- frontend/next.config.js +2 -3
- frontend/package.json +9 -4
- frontend/tailwind.config.js +17 -7
- frontend/yarn.lock +132 -2
- server.py +46 -33
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 |
-
|
6 |
-
|
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 |
-
|
21 |
-
|
22 |
-
|
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
|
2 |
-
import
|
3 |
|
4 |
-
const inter = Inter({ subsets: [
|
5 |
|
6 |
export const metadata = {
|
7 |
-
title:
|
8 |
-
description:
|
9 |
-
}
|
10 |
|
11 |
export default function RootLayout({ children }) {
|
12 |
return (
|
13 |
-
<html lang="en">
|
14 |
-
<body className={inter.className}>
|
|
|
|
|
|
|
|
|
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
|
4 |
-
import {
|
|
|
|
|
5 |
|
6 |
export default function Home() {
|
7 |
-
const [
|
8 |
-
const [roomUrl, setRoomUrl] = useState();
|
9 |
|
10 |
-
|
11 |
-
|
12 |
|
13 |
-
|
14 |
-
|
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 |
-
<
|
35 |
-
|
36 |
-
|
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 |
-
|
|
|
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 |
-
"
|
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 |
-
|
5 |
-
|
6 |
-
|
7 |
],
|
8 |
theme: {
|
9 |
extend: {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
10 |
backgroundImage: {
|
11 |
-
|
12 |
-
|
13 |
-
|
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/[email protected]":
|
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 | |
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/[email protected]":
|
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/[email protected]":
|
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/[email protected]":
|
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/[email protected]":
|
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/[email protected]":
|
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/[email protected]":
|
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/[email protected]":
|
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 |
+
[email protected], 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 | |
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
|
30 |
-
'''
|
31 |
api_path = os.getenv("DAILY_API_PATH") or "https://api.daily.co/v1"
|
|
|
|
|
32 |
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
"
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
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 |
-
|
60 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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 {
|
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({"
|
91 |
|
92 |
|
93 |
@app.post("/start")
|
94 |
-
async def start():
|
95 |
-
|
|
|
|
|
|
|
|
|
|
|
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):
|