diff --git a/.env.example b/.env.example index 4bae6ab..7b20efa 100644 --- a/.env.example +++ b/.env.example @@ -1,9 +1,11 @@ # 1. Copy this file and rename it to .env.local # 2. Update the enviroment variables below. -# URL pointing to the LiveKit server. -LIVEKIT_URL=wss://your-host - # API key and secret. If you use LiveKit Cloud this can be generated via the cloud dashboard. -LIVEKIT_API_KEY=<____key_goes_here____> -LIVEKIT_API_SECRET=<____secret_goes_here____> \ No newline at end of file +LIVEKIT_API_KEY=devkey +LIVEKIT_API_SECRET=secret + + +## PUBLIC +NEXT_PUBLIC_LK_TOKEN_ENDPOINT=/api/token +NEXT_PUBLIC_LK_SERVER_URL=wss://my-livekit-project.livekit.cloud diff --git a/README.md b/README.md index 2f3b09b..24663a8 100644 --- a/README.md +++ b/README.md @@ -2,10 +2,12 @@ This project is home for a simple video conferencing app built with LiveKit. +> There's a new meet example app available! Redesigned from the ground up! Check its building blocks out [here](https://github.com/livekit/components-js) + ## Tech Stack - This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app). -- App is built with [livekit-react](https://github.com/livekit/livekit-react/) library +- App is built with [@livekit/components-react](https://github.com/livekit/components-js/) library ## Demo diff --git a/components/ActiveRoom.tsx b/components/ActiveRoom.tsx deleted file mode 100644 index 18166c3..0000000 --- a/components/ActiveRoom.tsx +++ /dev/null @@ -1,140 +0,0 @@ -import { Box, useToast } from '@chakra-ui/react'; -import { DisplayContext, DisplayOptions, LiveKitRoom } from '@livekit/react-components'; -import { Room, RoomEvent, VideoPresets } from 'livekit-client'; -import { useRouter } from 'next/router'; -import { useCallback, useEffect, useState } from 'react'; -import 'react-aspect-ratio/aspect-ratio.css'; -import tinykeys from 'tinykeys'; -import { SessionProps, TokenResult } from '../lib/types'; -import Controls from './Controls'; -import DebugOverlay from './DebugOverlay'; - -const ActiveRoom = ({ - roomName, - identity, - region, - audioTrack, - videoTrack, - turnServer, - forceRelay, -}: SessionProps) => { - const [tokenResult, setTokenResult] = useState(); - const [room, setRoom] = useState(); - const [displayOptions, setDisplayOptions] = useState({ - stageLayout: 'grid', - }); - const router = useRouter(); - const toast = useToast(); - - useEffect(() => { - // cleanup - return () => { - audioTrack?.stop(); - videoTrack?.stop(); - }; - }, []); - - const onLeave = () => { - router.push('/'); - }; - - const onConnected = useCallback( - (room: Room) => { - setRoom(room); - /* @ts-ignore */ - window.currentRoom = room; - if (audioTrack) { - room.localParticipant.publishTrack(audioTrack); - } - if (videoTrack) { - room.localParticipant.publishTrack(videoTrack); - } - room.on(RoomEvent.Disconnected, (reason) => { - toast({ - title: 'Disconnected', - description: `You've been disconnected from the room`, - duration: 4000, - onCloseComplete: () => { - onLeave(); - }, - }); - }); - }, - [audioTrack, videoTrack], - ); - - useEffect(() => { - const params: { [key: string]: string } = { - roomName, - identity, - }; - if (region) { - params.region = region; - } - fetch('/api/token?' + new URLSearchParams(params)) - .then((res) => res.json()) - .then((data: TokenResult) => { - setTokenResult(data); - }); - }, []); - - useEffect(() => { - if (window) { - let unsubscribe = tinykeys(window, { - 'Shift+S': () => { - displayOptions.showStats = displayOptions.showStats ? false : true; - setDisplayOptions(displayOptions); - }, - }); - return () => { - unsubscribe(); - }; - } - }, [displayOptions]); - - if (!tokenResult) { - return ; - } - - let rtcConfig: RTCConfiguration | undefined; - if (turnServer) { - rtcConfig = { - iceServers: [turnServer], - iceTransportPolicy: 'relay', - }; - } else if (forceRelay) { - rtcConfig = { - iceTransportPolicy: 'relay', - }; - } - - return ( - - - - {room && } - - - ); -}; - -export default ActiveRoom; diff --git a/components/ChatEntry.tsx b/components/ChatEntry.tsx deleted file mode 100644 index 50be0be..0000000 --- a/components/ChatEntry.tsx +++ /dev/null @@ -1,19 +0,0 @@ -import { HStack, Text } from '@chakra-ui/react'; -import { Participant } from 'livekit-client'; - -export interface ChatData { - sentAt: Date; - message: string; - from?: Participant; -} - -const ChatEntry = ({ message, from }: ChatData) => { - return ( - - {from ? {`${from.name || from.identity}`}: : null} - {message} - - ); -}; - -export default ChatEntry; diff --git a/components/ChatOverlay.tsx b/components/ChatOverlay.tsx deleted file mode 100644 index f252a39..0000000 --- a/components/ChatOverlay.tsx +++ /dev/null @@ -1,113 +0,0 @@ -import { - Button, - Drawer, - DrawerBody, - DrawerCloseButton, - DrawerContent, - DrawerHeader, - DrawerOverlay, - Grid, - GridItem, - HStack, - Textarea, - useDisclosure, -} from '@chakra-ui/react'; -import { DataPacket_Kind, Participant, Room, RoomEvent } from 'livekit-client'; -import { useEffect, useState } from 'react'; -import ChatEntry, { ChatData } from './ChatEntry'; - -interface ChatProps { - room: Room; - isOpen: boolean; - onClose: () => void; - onUnreadChanged?: (num: number) => void; -} - -const encoder = new TextEncoder(); -const decoder = new TextDecoder(); - -const ChatOverlay = ({ - room, - isOpen: extIsOpen, - onClose: extOnClose, - onUnreadChanged, -}: ChatProps) => { - const { isOpen, onClose } = useDisclosure({ isOpen: extIsOpen, onClose: extOnClose }); - const [input, setInput] = useState(); - const [messages, setMessages] = useState([]); - const [numUnread, setNumUnread] = useState(0); - - useEffect(() => { - const onDataReceived = (payload: Uint8Array, participant?: Participant) => { - const data = decoder.decode(payload); - setMessages((messages) => [ - ...messages, - { - sentAt: new Date(), - message: data, - from: participant, - }, - ]); - setNumUnread((numUnread) => numUnread + 1); - }; - room.on(RoomEvent.DataReceived, onDataReceived); - return () => { - room.off(RoomEvent.DataReceived, onDataReceived); - }; - }, [room]); - - useEffect(() => { - if (isOpen) { - setNumUnread(0); - } - }, [isOpen]); - - useEffect(() => { - if (onUnreadChanged) { - onUnreadChanged(numUnread); - } - }, [numUnread, onUnreadChanged]); - - const sendMessage = () => { - if (!input) { - return; - } - room.localParticipant.publishData(encoder.encode(input), DataPacket_Kind.RELIABLE); - setMessages((messages) => [ - ...messages, - { - sentAt: new Date(), - message: input, - from: room.localParticipant, - }, - ]); - setInput(''); - }; - - return ( - - - - - Chat - - - - {messages.map((message, idx) => ( - - ))} - - - -