|
import React, { useState } from "react"; |
|
import { |
|
useDaily, |
|
useParticipantIds, |
|
useAppMessage, |
|
DailyAudio, |
|
} from "@daily-co/daily-react"; |
|
import { IconLogout, IconLoader2 } from "@tabler/icons-react"; |
|
|
|
import VideoTile from "@/components/VideoTile"; |
|
import { Button } from "@/components/ui/button"; |
|
import UserInputIndicator from "@/components/UserInputIndicator"; |
|
import WaveText from "@/components/WaveText"; |
|
|
|
interface StoryProps { |
|
handleLeave: () => void; |
|
} |
|
|
|
const Story: React.FC<StoryProps> = ({ handleLeave }) => { |
|
const daily = useDaily(); |
|
const participantIds = useParticipantIds({ filter: "remote" }); |
|
const [storyState, setStoryState] = useState<"user" | "assistant">( |
|
"assistant" |
|
); |
|
|
|
useAppMessage({ |
|
onAppMessage: (e) => { |
|
if (!daily || !e.data?.cue) return; |
|
|
|
|
|
if (e.data?.cue === "user_turn") { |
|
|
|
setTimeout(() => daily.setLocalAudio(true), 500); |
|
setStoryState("user"); |
|
} else { |
|
daily.setLocalAudio(false); |
|
setStoryState("assistant"); |
|
} |
|
}, |
|
}); |
|
|
|
return ( |
|
<div className="w-full flex flex-col flex-1 self-stretch"> |
|
{/* Absolute elements */} |
|
<div className="absolute top-20 w-full text-center z-50"> |
|
<WaveText active={storyState === "user"} /> |
|
</div> |
|
<header className="flex absolute top-0 w-full z-50 p-6 justify-end"> |
|
<Button variant="secondary" onClick={() => handleLeave()}> |
|
<IconLogout size={21} className="mr-2" /> |
|
Exit |
|
</Button> |
|
</header> |
|
<div className="absolute inset-0 bg-gray-800 bg-opacity-90 z-10 fade-in"></div> |
|
|
|
{/* Static elements */} |
|
<div className="relative z-20 flex-1 flex items-center justify-center"> |
|
{participantIds.length >= 1 ? ( |
|
<VideoTile |
|
sessionId={participantIds[0]} |
|
inactive={storyState === "user"} |
|
/> |
|
) : ( |
|
<span className="p-3 rounded-full bg-gray-900/60 animate-pulse"> |
|
<IconLoader2 |
|
size={42} |
|
stroke={2} |
|
className="animate-spin text-white z-20 self-center" |
|
/> |
|
</span> |
|
)} |
|
<DailyAudio /> |
|
</div> |
|
<UserInputIndicator active={storyState === "user"} /> |
|
</div> |
|
); |
|
}; |
|
|
|
export default Story; |
|
|