diff --git a/package-lock.json b/package-lock.json index e2c205c..f26f66b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6317,6 +6317,7 @@ } }, "samples/active-speaker-ui": { + "name": "active-speaker-ui-sample", "version": "0.0.0", "dependencies": { "@dytesdk/react-ui-kit": "^1.61.4", @@ -6674,6 +6675,7 @@ } }, "samples/chat-widget": { + "name": "dyte-chat-widget-demo", "version": "0.1.0", "dependencies": { "@dytesdk/react-ui-kit": "1.59.0", diff --git a/samples/active-speaker-ui/README.md b/samples/active-speaker-ui/README.md index 580ce06..6361c72 100644 --- a/samples/active-speaker-ui/README.md +++ b/samples/active-speaker-ui/README.md @@ -1,6 +1,6 @@ # Active speaker UI Sample -This sample showcases how you can build a UI to display only the active speaker while screenshare with Dyte's React UI Kit! +This sample showcases how you can build a UI to display only the active speaker while screenshare in an webinar meeting with Dyte's React UI Kit! --- diff --git a/samples/active-speaker-ui/index.html b/samples/active-speaker-ui/index.html index 8a65689..4977945 100644 --- a/samples/active-speaker-ui/index.html +++ b/samples/active-speaker-ui/index.html @@ -9,7 +9,7 @@ -
+
diff --git a/samples/active-speaker-ui/src/App.tsx b/samples/active-speaker-ui/src/App.tsx index ddd634a..3799606 100644 --- a/samples/active-speaker-ui/src/App.tsx +++ b/samples/active-speaker-ui/src/App.tsx @@ -1,12 +1,12 @@ import Meeting from './components/Meeting'; -import { DyteDialogManager, DyteParticipantsAudio } from '@dytesdk/react-ui-kit'; +import { DyteDialogManager, DyteParticipantsAudio, DyteNotifications } from '@dytesdk/react-ui-kit'; import { DyteProvider, useDyteClient } from '@dytesdk/react-web-core'; import { useEffect } from 'react'; export default function App() { const [meeting, initMeeting] = useDyteClient(); const url = new URL(window.location.href); - let queryToken = url.searchParams.get('authToken')!; + const queryToken = url.searchParams.get('authToken')!; if (!queryToken) { alert('Please add authToken to url query params'); @@ -22,7 +22,7 @@ export default function App() { }).then((meeting) => { meeting?.join(); }); - }, []); + }, []); // don't add dependencies to execute just once if (!meeting) return
Connecting...
; @@ -31,6 +31,7 @@ export default function App() { + ); diff --git a/samples/active-speaker-ui/src/components/Meeting.tsx b/samples/active-speaker-ui/src/components/Meeting.tsx index 7a89ff0..56416d5 100644 --- a/samples/active-speaker-ui/src/components/Meeting.tsx +++ b/samples/active-speaker-ui/src/components/Meeting.tsx @@ -1,15 +1,22 @@ -import { DyteParticipantTile, DyteScreenshareView, DyteSettingsToggle } from '@dytesdk/react-ui-kit'; +import SidebarOverlay from './SidebarOverlay'; import { + defaultIconPack, DyteCameraToggle, DyteChat, + DyteControlbarButton, DyteGrid, DyteLeaveButton, DyteMicToggle, + DyteParticipants, + DyteParticipantTile, DyteScreenShareToggle, + DyteStageToggle, + DyteScreenshareView, + DyteSettingsToggle, } from '@dytesdk/react-ui-kit'; import { useDyteMeeting, useDyteSelector } from '@dytesdk/react-web-core'; import { useThrottle } from '@uidotdev/usehooks'; -import { useEffect, useState } from 'react'; +import { useEffect, useState, useCallback } from 'react'; const ACTIVE_SPEAKER_CHANGE_DELAY = 3000; @@ -27,10 +34,23 @@ export default function Meeting() { return meeting.participants.joined.toArray().find((p) => p.screenShareEnabled); }); const lastActiveSpeaker = useDyteSelector((meeting) => meeting.participants.lastActiveSpeaker); + const isOnStage = useDyteSelector((meeting) => meeting.self.stageStatus === 'ON_STAGE'); + const requestCount = useDyteSelector( + (meeting) => + meeting.participants.joined.toArray().filter((p) => p.stageStatus === 'REQUESTED_TO_JOIN_STAGE').length + + meeting.participants.waitlisted.size, + ); + // eslint-disable-next-line @typescript-eslint/no-explicit-any const [activeSpeakerInternal, setActiveSpeaker] = useState(); + const [participantListVisible, setParticipantListVisible] = useState(false); + const activeSpeaker = useThrottle(activeSpeakerInternal, ACTIVE_SPEAKER_CHANGE_DELAY); + const toggleParticipantList = useCallback(() => { + setParticipantListVisible(!participantListVisible); + }, [participantListVisible]); + useEffect(() => { const activeParticipants = meeting.participants.active.toArray(); @@ -53,18 +73,37 @@ export default function Meeting() { )}
- - - + {isOnStage && } + {isOnStage && } + {isOnStage && } + - + {isOnStage && } +
+ + {requestCount !== 0 && ( +
+ {requestCount} +
+ )} +
); diff --git a/samples/active-speaker-ui/src/components/SidebarOverlay.tsx b/samples/active-speaker-ui/src/components/SidebarOverlay.tsx new file mode 100644 index 0000000..d0d62fb --- /dev/null +++ b/samples/active-speaker-ui/src/components/SidebarOverlay.tsx @@ -0,0 +1,13 @@ +import { ReactElement } from 'react'; + +export default function SidebarOverlay({ show, children }: { show: boolean; children: ReactElement | null }) { + return ( +
+ {children} +
+ ); +} diff --git a/samples/active-speaker-ui/src/index.css b/samples/active-speaker-ui/src/index.css index 08d553b..6ca00f3 100644 --- a/samples/active-speaker-ui/src/index.css +++ b/samples/active-speaker-ui/src/index.css @@ -2,10 +2,10 @@ @tailwind components; @tailwind utilities; -#root { +.bg-1000 { background: rgb(var(--dyte-colors-background-1000)); } -.sidebar { +.bg-900 { background: rgb(var(--dyte-colors-background-900)); }