File size: 3,947 Bytes
1e8ff3b
 
fc610e2
 
b3de037
fc610e2
 
 
b3de037
 
 
 
 
 
1e8ff3b
 
 
 
 
 
 
 
 
 
 
 
b3de037
 
1e8ff3b
fc610e2
b3de037
 
 
1e8ff3b
 
76b9248
 
1e8ff3b
 
 
 
 
 
 
 
 
 
 
 
76b9248
1e8ff3b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
b3de037
 
1e8ff3b
76b9248
1e8ff3b
 
 
 
 
 
b3de037
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1e8ff3b
 
76b9248
1e8ff3b
 
fc610e2
 
 
 
 
1e8ff3b
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
"use client";

import {
  DailyVideo,
  useAppMessage,
  useLocalSessionId,
  useParticipantIds,
} from "@daily-co/daily-react";
import { useCallback, useEffect, useState } from "react";
import Avatar from "../components/Avatar";
import Card from "../components/Card";
import CreateRoom from "../components/CreateRoom";
import Join from "../components/Joining";
import { apiUrl } from "../utils";

const STATE_IDLE = "idle";
const STATE_JOINING = "joining";
const STATE_JOINED = "joined";
const STATE_LEFT = "left";
const BOT_STATE_STARTING = "bot_starting";
const BOT_STATE_STARTED = "bot_started";

export default function Call() {
  const [callState, setCallState] = useState(STATE_IDLE);
  const [roomUrl, setRoomUrl] = useState();
  const [botState, setBotState] = useState(BOT_STATE_STARTING);
  const [params, setParams] = useState({});

  const localSessionId = useLocalSessionId();
  const participantIds = useParticipantIds({ filter: "remote" });
  const sendAppMessage = useAppMessage({
    onAppMessage: useCallback((ev) => setParams(ev.data), []),
  });

  const start = useCallback(async () => {
    if (!process.env.NEXT_PUBLIC_DISABLE_LOCAL_AGENT) return;

    const resp = await fetch(`${apiUrl}/start`, {
      method: "POST",
      mode: "cors",
      cache: "no-cache",
      credentials: "same-origin",
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify({ room_url: roomUrl }),
    });

    const data = await resp.json();
    return data;
  }, [roomUrl]);

  useEffect(() => {
    if (callState !== STATE_JOINED || botState === BOT_STATE_STARTED) return;
    start();
  }, [callState, botState, start]);

  if (callState === STATE_IDLE) {
    return (
      <CreateRoom
        onCreateRoom={(roomUrl) => {
          setRoomUrl(roomUrl);
          setCallState(STATE_JOINING);
        }}
      />
    );
  }

  if (callState === STATE_JOINING) {
    return <Join roomUrl={roomUrl} onJoin={() => setCallState(STATE_JOINED)} />;
  }

  // Main call loop
  return (
    <main className="container py-12">
      <div className="grid grid-cols-2 grid-flow-col gap-12">
        <div>
          <Card headerText="Local Webcam">
            <div className="overflow-hidden bg-gray-50 sm:rounded-lg">
              <div className="aspect-video flex items-center justify-center">
                <DailyVideo automirror sessionId={localSessionId} />
              </div>
            </div>
          </Card>
          <div className="relative">
            <div>
              <label
                htmlFor="comment"
                className="block text-sm font-medium leading-6 text-gray-900"
              >
                Add your comment
              </label>
              <div className="mt-2">
                <textarea
                  rows={4}
                  name="comment"
                  id="comment"
                  className="block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6"
                  defaultValue={params.prompt || ""}
                />
              </div>
            </div>
            Config - Resolution, Mbps, FPS
            <button
              onClick={() => sendAppMessage({ prompt: "Big ol' car" }, "*")}
            >
              Send test app message
            </button>
          </div>
        </div>
        <div>
          <Card headerText="Inference">
            <div className="overflow-hidden bg-gray-50 sm:rounded-lg">
              <div className="aspect-video flex items-center justify-center">
                {participantIds.length ? (
                  <DailyVideo sessionId={participantIds[0]} />
                ) : (
                  <Avatar />
                )}
              </div>
            </div>
          </Card>
        </div>
      </div>
    </main>
  );
}