diff --git a/samples/active-speaker-ui/src/components/MainArea.tsx b/samples/active-speaker-ui/src/components/MainArea.tsx index 269db55..a952a9f 100644 --- a/samples/active-speaker-ui/src/components/MainArea.tsx +++ b/samples/active-speaker-ui/src/components/MainArea.tsx @@ -15,6 +15,10 @@ import type { DyteParticipant, DytePlugin, DyteSelf } from '@dytesdk/web-core'; import clsx from 'clsx'; import { useState, useEffect, useRef } from 'react'; +type ActiveTab = + | { type: 'plugin'; plugin: DytePlugin } + | { type: 'screenshare'; participant: DyteParticipant | DyteSelf }; + function ActiveSpeakerView({ screenshares, plugins, @@ -24,27 +28,70 @@ function ActiveSpeakerView({ }) { const { meeting } = useDyteMeeting(); - const [selectedTab, setSelectedTab] = useState< - DyteParticipant | DyteSelf | DytePlugin - >(); + const [selectedTab, setSelectedTab] = useState(); + const pluginsRef = useRef([]); + const screensharesRef = useRef<(DyteParticipant | DyteSelf)[]>([]); const showTabBar = screenshares.length + plugins.length > 1; - const [isImmersiveMode, toggleImmersiveMode] = useMeetingStore((s) => [ - s.isImmersiveMode, - s.toggleImmersiveMode, - ]); - const size = useMeetingStore((s) => s.size); + const isImmersiveMode = useMeetingStore((s) => s.isImmersiveMode); + const [states, setStates] = useMeetingStore((s) => [s.states, s.setStates]); + + const activeTab = useDyteSelector((m) => m.meta.selfActiveTab); + + useEffect(() => { + if (activeTab) { + if (activeTab.type === 'plugin') { + const plugin = meeting.plugins.active.get(activeTab.id); + + if (plugin) { + setSelectedTab({ + type: 'plugin', + plugin, + }); + } + } else { + const participant = meeting.participants.joined.get(activeTab.id); + + if (participant) { + setSelectedTab({ + type: 'screenshare', + participant, + }); + } + } + } + }, [activeTab]); const onFallback = () => { if (screenshares.length > 0) { - setSelectedTab(screenshares.at(0)); + setSelectedTab({ type: 'screenshare', participant: screenshares[0] }); } else if (plugins.length > 0) { - setSelectedTab(plugins.at(0)); + setSelectedTab({ type: 'plugin', plugin: plugins[0] }); } }; + useEffect(() => { + if (screenshares.length > screensharesRef.current.length) { + setActiveTab({ + type: 'screenshare', + participant: screenshares.at(-1)!, + }); + } + screensharesRef.current = screenshares; + }, [screenshares]); + + useEffect(() => { + if (plugins.length > pluginsRef.current.length) { + setActiveTab({ + type: 'plugin', + plugin: plugins.at(-1)!, + }); + } + pluginsRef.current = plugins; + }, [plugins]); + useEffect(() => { if (selectedTab) return; onFallback(); @@ -53,16 +100,34 @@ function ActiveSpeakerView({ useEffect(() => { if (!selectedTab) return; - const id = selectedTab.id; + if ( + selectedTab.type === 'screenshare' && + !screenshares.find((s) => s.id === selectedTab.participant.id) + ) { + onFallback(); + } if ( - !screenshares.find((s) => s.id === id) && - !plugins.find((p) => p.id === id) + selectedTab.type === 'plugin' && + !plugins.find((p) => p.id === selectedTab.plugin.id) ) { onFallback(); } }, [screenshares, plugins]); + const setActiveTab = (tab: ActiveTab) => { + if (meeting.self.permissions.canSpotlight) { + meeting.meta.setSelfActiveTab( + { + type: tab.type, + id: tab.type === 'plugin' ? tab.plugin.id : tab.participant.id, + }, + 0 + ); + } + setSelectedTab(tab); + }; + return (
{showTabBar && ( @@ -72,11 +137,16 @@ function ActiveSpeakerView({ {screenshares.map((participant) => (
)} - {selectedTab && 'audioEnabled' in selectedTab && ( - - - - - - )} + > + + + + )} {plugins.map((plugin) => (
- - { - toggleImmersiveMode(); - }} - > - - + + + {states.activeSidebar && ( + { + setStates({ activeSidebar: false, sidebar: undefined }); + }} + > + + + )}
))} diff --git a/samples/active-speaker-ui/src/components/Sidebar.tsx b/samples/active-speaker-ui/src/components/Sidebar.tsx index 4e03e59..1590f48 100644 --- a/samples/active-speaker-ui/src/components/Sidebar.tsx +++ b/samples/active-speaker-ui/src/components/Sidebar.tsx @@ -42,7 +42,11 @@ export default function Sidebar() { return null; } - if (!isHost && !sidebar && isActiveMode) { + if (!isHost && !sidebar && !isActiveMode) { + return null; + } + + if (!isHost && !sidebar && isMobile) { return null; }