From 593e4e03fdf390eb2c4b18f99e8c42172fefae2e Mon Sep 17 00:00:00 2001 From: Tarush Date: Fri, 28 Mar 2025 20:01:05 +0530 Subject: [PATCH] fix: code runner formatting --- .../build-your-own/add-custom-sidebar.mdx | 478 ++++++++++-------- .../build-your-own/customize-control-bar.mdx | 84 +-- .../build-your-own/customize-header.mdx | 210 ++++---- .../handling-states-and-configs.mdx | 309 +++++------ .../stage-ui-using-dyte-grid.mdx | 112 ++-- .../build-your-own/states based UI Split.mdx | 327 ++++++------ .../build-in-call-ui/default-meeting-ui.mdx | 55 +- .../add-audio-video-preview.mdx | 79 +-- .../build-your-own/edit-user-name.mdx | 86 ++-- .../build-your-own/initial-code-skeleton.mdx | 8 +- .../default-setup-screen.mdx | 18 +- .../components/dyte-participant-tile.mdx | 14 +- docs/react-ui-kit/quickstart.mdx | 21 +- docs/ui-kit/quickstart.mdx | 10 +- 14 files changed, 931 insertions(+), 880 deletions(-) diff --git a/docs/react-ui-kit/build-in-call-ui/build-your-own/add-custom-sidebar.mdx b/docs/react-ui-kit/build-in-call-ui/build-your-own/add-custom-sidebar.mdx index 7f3e16d342..f98c449dd4 100644 --- a/docs/react-ui-kit/build-in-call-ui/build-your-own/add-custom-sidebar.mdx +++ b/docs/react-ui-kit/build-in-call-ui/build-your-own/add-custom-sidebar.mdx @@ -21,113 +21,151 @@ import { useDyteMeeting, useDyteSelector } from '@dytesdk/react-web-core'; import { useEffect, useState } from 'react'; function SidebarWithCustomUI({ -meeting, states, config, setStates, -}: { meeting: DyteClient, config: UIConfig, states: CustomStates, setStates: SetStates } -){ -const [tabs, setTabs] = useState([ -{ id: 'chat', name: 'chat' }, -{ id: 'polls', name: 'polls' }, -{ id: 'participants', name: 'participants' }, -{ id: 'plugins', name: 'plugins' }, -{ id: 'guidelines', name: 'Guidelines' } -]); -const [view, setView] = useState('sidebar'); - - if(!states.activeSidebar || (!states.sidebar && !states.customSidebar)){ - return null; - } - - const currentTab = states.sidebar || states.customSidebar; - - return ( + meeting, + states, + config, + setStates, +}: { + meeting: DyteClient; + config: UIConfig; + states: CustomStates; + setStates: SetStates; +}) { + const [tabs, setTabs] = useState([ + { id: 'chat', name: 'chat' }, + { id: 'polls', name: 'polls' }, + { id: 'participants', name: 'participants' }, + { id: 'plugins', name: 'plugins' }, + { id: 'guidelines', name: 'Guidelines' }, + ]); + + const [view, setView] = useState('sidebar'); + + if (!states.activeSidebar || (!states.sidebar && !states.customSidebar)) { + return null; + } + + const currentTab = states.sidebar || states.customSidebar; + + return ( { - setStates((oldState) => { + tabs={tabs} + currentTab={currentTab} + view={view} + onTabChange={(e) => { + setStates((oldState) => { + return { + ...oldState, + activeSidebar: true, + customSidebar: e.detail, + sidebar: e.detail, + }; + }); + }} + className="w-80" + onSidebarClose={() => { + setStates((oldState) => { + return { + ...oldState, + activeSidebar: false, + sidebar: null, + customSidebar: null, + }; + }); + }} + > + {currentTab === 'chat' && } + {currentTab === 'polls' && } + {currentTab === 'participants' && ( + + )} + {currentTab === 'plugins' && } + {currentTab === 'guidelines' && ( +
+
+

1. Ensure active participation and professionalism by muting your microphone when not speaking.

+
+

2. Utilize the chat feature for questions or comments during the meeting.

+
+
+ )} +
+ ); +} + +function MeetingStage({ + meeting, + config, + states, + setStates, +}: { + meeting: DyteClient; + config: UIConfig; + states: CustomStates; + setStates: SetStates; +}) { + return ( +
+ + + + {states.activeSidebar && ( + + )} + + + +
+ { + if ( + states.activeSidebar && + !states.sidebar && + states.customSidebar === 'guidelines' + ) { + setStates((oldState) => { return { - ...oldState, - activeSidebar: true, - customSidebar: e.detail, - sidebar: e.detail, - } - }); - }} - className="w-80 " - onSidebarClose={() => { - setStates((oldState) => { + ...oldState, + activeSidebar: false, + sidebar: null, + customSidebar: null, + }; + }); + } else { + setStates((oldState) => { return { - ...oldState, - activeSidebar: false, - sidebar: null, - customSidebar: null, - } - }); - }}> - {currentTab === 'chat' && } - {currentTab === 'polls' && } - {currentTab === 'participants' && } - {currentTab === 'plugins' && } - {currentTab === 'guidelines' &&
-
-

1. Ensure active participation and professionalism by muting your microphone when not speaking.

-

-

2. Utilize the chat feature for questions or comments during the meeting.

-
-
} - ); - + ...oldState, + activeSidebar: true, + sidebar: null, + customSidebar: 'guidelines', + }; + }); + } + }} + icon={defaultIconPack.add} + label={'Open Custom SideBar'} + /> +
+
+ ); } -function MeetingStage({ meeting, config, states, setStates }: { meeting: DyteClient, config: UIConfig, states: CustomStates, setStates: SetStates}) { - -return ( - -
- - - - {states.activeSidebar && ( - - )} - - - -
- { - if(states.activeSidebar && !states.sidebar && states.customSidebar === 'guidelines'){ - setStates( (oldState) => { return { ...oldState, activeSidebar: false, sidebar: null, customSidebar: null }}); - } else { - setStates( (oldState) => { return { ...oldState, activeSidebar: true, sidebar: null, customSidebar: 'guidelines' }}); - } - }} - icon={defaultIconPack.add} - label={'Open Custom SideBar'} - /> -
- -
-); } - export default function Meeting() { -const { meeting } = useDyteMeeting(); -const [config, setConfig] = useState(defaultConfig); -const [states, setStates] = useState({ - meeting: 'setup', - sidebar: 'chat' -}); - -useEffect(() => { -async function setupMeetingConfigs(){ -const theme = meeting!.self.config; -const { config } = generateConfig(theme, meeting!); + const { meeting } = useDyteMeeting(); + const [config, setConfig] = useState(defaultConfig); + const [states, setStates] = useState({ + meeting: 'setup', + sidebar: 'chat', + }); + useEffect(() => { + async function setupMeetingConfigs() { + const theme = meeting!.self.config; + const { config } = generateConfig(theme, meeting!); /** * Full screen by default requests dyte-meeting/DyteMeeting element to be in full screen. @@ -136,137 +174,156 @@ const { config } = generateConfig(theme, meeting!); */ // setFullScreenToggleTargetElement({config, targetElementId: 'root'}); - setConfig({...config}); + setConfig({ ...config }); - /** - * Add listeners on meeting & self to monitor leave meeting, join meeting and so on. - * This work was earlier done by DyteMeeting component internally. - */ - const stateListenersUtils = new DyteStateListenersUtils(() => meeting, () => states, () => setStates); + /** + * Add listeners on meeting & self to monitor leave meeting, join meeting and so on. + * This work was earlier done by DyteMeeting component internally. + */ + const stateListenersUtils = new DyteStateListenersUtils( + () => meeting, + () => states, + () => setStates + ); stateListenersUtils.addDyteEventListeners(); - try{ + try { await meeting.join(); - } catch(e){ + } catch (e) { // do nothing } } - if(meeting){ - /** - * During development phase, make sure to expose meeting object to window, - * for debugging purposes. - */ + if (meeting) { + /** + * During development phase, make sure to expose meeting object to window, + * for debugging purposes. + */ Object.assign(window, { meeting, - }) + }); setupMeetingConfigs(); } - -}, [meeting]); - -return ( - -
{ - el?.addEventListener('dyteStateUpdate', (e) => { - const { detail: newStateUpdate } = e as unknown as { detail: CustomStates }; - console.log('dyteStateUpdateSetup:: ', newStateUpdate); - setStates((oldState: CustomStates) => { return { - ...oldState, - ...newStateUpdate, - }}); - }); - }}> + }, [meeting]); + + return ( +
{ + el?.addEventListener('dyteStateUpdate', (e) => { + const { detail: newStateUpdate } = e as unknown as { + detail: CustomStates; + }; + console.log('dyteStateUpdateSetup:: ', newStateUpdate); + setStates((oldState: CustomStates) => { + return { + ...oldState, + ...newStateUpdate, + }; + }); + }); + }} + > -
-) - +
+ ); } -export class DyteStateListenersUtils{ - - getStates: () => CustomStates; +export class DyteStateListenersUtils { + getStates: () => CustomStates; - getStateSetter: () => (newState: CustomStates) => void; + getStateSetter: () => (newState: CustomStates) => void; - getMeeting: () => DyteClient; + getMeeting: () => DyteClient; - get states(){ - return this.getStates(); - } - - get setGlobalStates(){ - return this.getStateSetter(); - }; - - get meeting(){ - return this.getMeeting(); - } + get states() { + return this.getStates(); + } - constructor(getMeeting: () => DyteClient, getGlobalStates: () => CustomStates, getGlobalStateSetter: () => (newState: CustomStates) => void){ - this.getMeeting = getMeeting; - this.getStates = getGlobalStates; - this.getStateSetter = getGlobalStateSetter; - } - private updateStates(newState: CustomStates){ - this.setGlobalStates((oldState: CustomStates) => { return { - ...oldState, - ...newState, - }}); - console.log(newState); - } - private roomJoinedListener = () => { - this.updateStates({ meeting: 'joined' }); - }; - - private socketServiceRoomJoinedListener = () => { - if (this.meeting.stage.status === 'ON_STAGE' || this.meeting.stage.status === undefined) return; - this.updateStates({ meeting: 'joined' }); - }; + get setGlobalStates() { + return this.getStateSetter(); + } - private waitlistedListener = () => { - this.updateStates({ meeting: 'waiting' }); - }; + get meeting() { + return this.getMeeting(); + } - private roomLeftListener = ({ state }: { state: RoomLeftState }) => { - const states = this.states; - if (states?.roomLeftState === 'disconnected') { - this.updateStates({ meeting: 'ended', roomLeftState: state }); - return; - } - this.updateStates({ meeting: 'ended', roomLeftState: state }); - }; + constructor( + getMeeting: () => DyteClient, + getGlobalStates: () => CustomStates, + getGlobalStateSetter: () => (newState: CustomStates) => void + ) { + this.getMeeting = getMeeting; + this.getStates = getGlobalStates; + this.getStateSetter = getGlobalStateSetter; + } - private mediaPermissionUpdateListener = ({ kind, message }: { - kind: PermissionSettings['kind'], - message: string, - }) => { - if (['audio', 'video'].includes(kind!)) { - if (message === 'ACCEPTED' || message === 'NOT_REQUESTED' || this.states.activeDebugger) - return; - const permissionModalSettings: PermissionSettings = { - enabled: true, - kind, - }; - this.updateStates({ activePermissionsMessage: permissionModalSettings }); - } + private updateStates(newState: CustomStates) { + this.setGlobalStates((oldState: CustomStates) => { + return { + ...oldState, + ...newState, }; - - private joinStateAcceptedListener = () => { - this.updateStates({ activeJoinStage: true }); + }); + console.log(newState); + } + + private roomJoinedListener = () => { + this.updateStates({ meeting: 'joined' }); + }; + + private socketServiceRoomJoinedListener = () => { + if (this.meeting.stage.status === 'ON_STAGE' || this.meeting.stage.status === undefined) + return; + this.updateStates({ meeting: 'joined' }); + }; + + private waitlistedListener = () => { + this.updateStates({ meeting: 'waiting' }); + }; + + private roomLeftListener = ({ state }: { state: RoomLeftState }) => { + const states = this.states; + if (states?.roomLeftState === 'disconnected') { + this.updateStates({ meeting: 'ended', roomLeftState: state }); + return; + } + this.updateStates({ meeting: 'ended', roomLeftState: state }); + }; + + private mediaPermissionUpdateListener = ({ + kind, + message, + }: { + kind: PermissionSettings['kind']; + message: string; + }) => { + if (['audio', 'video'].includes(kind!)) { + if (message === 'ACCEPTED' || message === 'NOT_REQUESTED' || this.states.activeDebugger) + return; + const permissionModalSettings: PermissionSettings = { + enabled: true, + kind, }; - - private handleChangingMeeting(destinationMeetingId: string) { - this.updateStates({ - activeBreakoutRoomsManager: { - ...this.states.activeBreakoutRoomsManager, - active: this.states.activeBreakoutRoomsManager!.active, - destinationMeetingId, - } - }); + this.updateStates({ activePermissionsMessage: permissionModalSettings }); } - - addDyteEventListeners(){ + }; + + private joinStateAcceptedListener = () => { + this.updateStates({ activeJoinStage: true }); + }; + + private handleChangingMeeting(destinationMeetingId: string) { + this.updateStates({ + activeBreakoutRoomsManager: { + ...this.states.activeBreakoutRoomsManager, + active: this.states.activeBreakoutRoomsManager!.active, + destinationMeetingId, + }, + }); + } + + addDyteEventListeners(){ if (this.meeting.meta.viewType === 'LIVESTREAM') { this.meeting.self.addListener('socketServiceRoomJoined', this.socketServiceRoomJoinedListener); } @@ -282,11 +339,8 @@ export class DyteStateListenersUtils{ } } - cleanupDyteEventListeners(){ - - } - -} + cleanupDyteEventListeners() + } ` } /> Let's say, we want to show some meeting guidelines to all the participants in a side bar. To do so, in the below code snippet, we have added `guidelines` sidebar section. diff --git a/docs/react-ui-kit/build-in-call-ui/build-your-own/customize-control-bar.mdx b/docs/react-ui-kit/build-in-call-ui/build-your-own/customize-control-bar.mdx index 70a276296c..4f02e1bc9d 100644 --- a/docs/react-ui-kit/build-in-call-ui/build-your-own/customize-control-bar.mdx +++ b/docs/react-ui-kit/build-in-call-ui/build-your-own/customize-control-bar.mdx @@ -22,16 +22,16 @@ file={` import { defaultConfig, generateConfig, DyteBreakoutRoomsToggle, DyteCameraToggle, DyteChatToggle, DyteControlbar, DyteControlbarButton, DyteDebuggerToggle, DyteFullscreenToggle, DyteLeaveButton, DyteMicToggle, DyteMoreToggle, DyteMuteAllButton, DyteParticipantsToggle, DytePipToggle, DytePluginsToggle, DytePoll, DytePollsToggle, DyteRecordingToggle, DyteScreenShareToggle, DyteSettingsToggle, DyteStageToggle } from '@dytesdk/react-ui-kit'; import { useDyteMeeting, useDyteSelector } from '@dytesdk/react-web-core'; import { useEffect, useState } from 'react'; - function ControlBarWithCustomUI({ -meeting, states, config, setStates, + meeting, states, config, setStates, }: { meeting: DyteClient, config: UIConfig, states: CustomStates, setStates: SetStates } ){ // Change selector as per your needs. const fullScreenTargetElement = document.querySelector('document') as HTMLElement; - return
+ return ( +
@@ -59,7 +59,7 @@ meeting, states, config, setStates,
- + ) } export default function Meeting() { @@ -74,39 +74,39 @@ export default function Meeting() { sidebar: 'chat' }); -useEffect(() => { -async function setupMeetingConfigs(){ -const theme = meeting!.self.config; -const { config } = generateConfig(theme, meeting!); + useEffect(() => { + async function setupMeetingConfigs(){ + const theme = meeting!.self.config; + const { config } = generateConfig(theme, meeting!); + + /** + * Full screen toggle, by default requests dyte-meeting/DyteMeeting element to be in full screen. + * Since DyteMeeting element is not here, + * we need to pass dyte-fullscreen-toggle, an targetElementId through config. + */ + setFullScreenToggleTargetElement({config, targetElementId: 'root'}); + + setConfig({...config}); /** - * Full screen toggle, by default requests dyte-meeting/DyteMeeting element to be in full screen. - * Since DyteMeeting element is not here, - * we need to pass dyte-fullscreen-toggle, an targetElementId through config. - */ - setFullScreenToggleTargetElement({config, targetElementId: 'root'}); - - setConfig({...config}); - - /** - * Add listeners on meeting & self to monitor leave meeting, join meeting and so on. - * This work was earlier done by DyteMeeting component internally. - */ - const stateListenersUtils = new DyteStateListenersUtils(() => meeting, () => states, () => setStates); - stateListenersUtils.addDyteEventListeners(); - - try{ - await meeting.join(); - } catch(e){ - // do nothing + * Add listeners on meeting & self to monitor leave meeting, join meeting and so on. + * This work was earlier done by DyteMeeting component internally. + */ + const stateListenersUtils = new DyteStateListenersUtils(() => meeting, () => states, () => setStates); + stateListenersUtils.addDyteEventListeners(); + + try{ + await meeting.join(); + } catch(e){ + // do nothing + } } - } - if(meeting){ - setupMeetingConfigs(); - } + if(meeting){ + setupMeetingConfigs(); + } -}, [meeting]); + }, [meeting]); return ( /\*\* @@ -115,16 +115,16 @@ return ( - so that we can listen to child component's internal state changes. \*/
{ - el?.addEventListener('dyteStateUpdate', (e) => { - const { detail: newStateUpdate } = e as unknown as { detail: CustomStates }; - setStates((oldState: CustomStates) => { return { - ...oldState, - ...newStateUpdate, - }}); - }); - }}> - -
+ el?.addEventListener('dyteStateUpdate', (e) => { + const { detail: newStateUpdate } = e as unknown as { detail: CustomStates }; + setStates((oldState: CustomStates) => { return { + ...oldState, + ...newStateUpdate, + }}); + }); + }}> + +
); } diff --git a/docs/react-ui-kit/build-in-call-ui/build-your-own/customize-header.mdx b/docs/react-ui-kit/build-in-call-ui/build-your-own/customize-header.mdx index 54aeb86aae..2ea2e87b50 100644 --- a/docs/react-ui-kit/build-in-call-ui/build-your-own/customize-header.mdx +++ b/docs/react-ui-kit/build-in-call-ui/build-your-own/customize-header.mdx @@ -19,102 +19,97 @@ import CodeRunner from '@site/src/components/CodeRunner/CodeRunner'; hide={[{start:1, end: 5}, {start:29, end: 227}]} highlight={[{start:6, end: 27}]} file={` -import { defaultConfig, generateConfig, DyteLogo, DyteRecordingIndicator, DyteLivestreamIndicator, DyteMeetingTitle, DyteGridPagination, DyteParticipantCount, DyteViewerCount, DyteClock } from '@dytesdk/react-ui-kit'; -import { useDyteMeeting, useDyteSelector } from '@dytesdk/react-web-core'; -import { useEffect, useState } from 'react'; - -function HeaderWithCustomUI({ -meeting, states, config, -}: { meeting: DyteClient, config: UIConfig, states: CustomStates, setStates: SetStates } -){ - - return
-
- - - + import { defaultConfig, generateConfig, DyteLogo, DyteRecordingIndicator, DyteLivestreamIndicator, DyteMeetingTitle, DyteGridPagination, DyteParticipantCount, DyteViewerCount, DyteClock } from '@dytesdk/react-ui-kit'; + import { useDyteMeeting, useDyteSelector } from '@dytesdk/react-web-core'; + import { useEffect, useState } from 'react'; + + function HeaderWithCustomUI({ + meeting, states, config, + }: { meeting: DyteClient, config: UIConfig, states: CustomStates, setStates: SetStates } + ){ + + return
+
+ + + +
+
+ +
+
+ + + + +
-
- -
-
- - - - -
-
- -} -export default function Meeting() { - const { meeting } = useDyteMeeting(); - const [config, setConfig] = useState(defaultConfig); - /** - * We need setStates method to add custom functionalities, - * as well as to ensure that web-core & ui-kit are in Sync. - */ - const [states, setStates] = useState({ - meeting: 'setup', - sidebar: 'chat' - }); - -useEffect(() => { -async function setupMeetingConfigs(){ -const theme = meeting!.self.config; -const { config } = generateConfig(theme, meeting!); + } + export default function Meeting() { + const { meeting } = useDyteMeeting(); + const [config, setConfig] = useState(defaultConfig); /** - * Full screen toggle, by default requests dyte-meeting/DyteMeeting element to be in full screen. - * Since DyteMeeting element is not here, - * we need to pass dyte-fullscreen-toggle, an targetElementId through config. - */ - setFullScreenToggleTargetElement({config, targetElementId: 'root'}); + * We need setStates method to add custom functionalities, + * as well as to ensure that web-core & ui-kit are in Sync. + */ + const [states, setStates] = useState({ + meeting: 'setup', + sidebar: 'chat' + }); + + useEffect(() => { + async function setupMeetingConfigs(){ + const theme = meeting!.self.config; + const { config } = generateConfig(theme, meeting!); + + /** + * Full screen toggle, by default requests dyte-meeting/DyteMeeting element to be in full screen. + * Since DyteMeeting element is not here, + * we need to pass dyte-fullscreen-toggle, an targetElementId through config. + */ + setFullScreenToggleTargetElement({config, targetElementId: 'root'}); + + setConfig({...config}); + + /** + * Add listeners on meeting & self to monitor leave meeting, join meeting and so on. + * This work was earlier done by DyteMeeting component internally. + */ + const stateListenersUtils = new DyteStateListenersUtils(() => meeting, () => states, () => setStates); + stateListenersUtils.addDyteEventListeners(); + + try{ + await meeting.join(); + } catch(e){ + // do nothing + } + } - setConfig({...config}); + if(meeting){ + setupMeetingConfigs(); + } + }, [meeting]); + + return ( /** - * Add listeners on meeting & self to monitor leave meeting, join meeting and so on. - * This work was earlier done by DyteMeeting component internally. + * Using a ref hack, we are adding "dyteStateUpdate" listener, + * so that we can listen to child component's internal state changes. */ - const stateListenersUtils = new DyteStateListenersUtils(() => meeting, () => states, () => setStates); - stateListenersUtils.addDyteEventListeners(); - - try{ - await meeting.join(); - } catch(e){ - // do nothing - } - } - - if(meeting){ - setupMeetingConfigs(); - } - -}, [meeting]); - -return ( -/\*\* - -- Using a ref hack, we are adding "dyteStateUpdate" listener, -- so that we can listen to child component's internal state changes. - \*/ -
{ +
{ el?.addEventListener('dyteStateUpdate', (e) => { - const { detail: newStateUpdate } = e as unknown as { detail: CustomStates }; - setStates((oldState: CustomStates) => { return { - ...oldState, - ...newStateUpdate, - }}); + const { detail: newStateUpdate } = e as unknown as { detail: CustomStates }; + setStates((oldState: CustomStates) => { return { + ...oldState, + ...newStateUpdate, + }}); }); - }}> - -
-); - -} - -/\*\* + }}> + +
+ ); - DyteStateListenersUtils is a class that listens to web-core changes and syncs them with ui-kit \*/ @@ -223,29 +218,30 @@ return ( } -/\*\* + /\*\* -- setFullScreenToggleTargetElement updates the ui-kit config, -- to set targetElement to full screen toggle. - \*/ + /** + - setFullScreenToggleTargetElement updates the ui-kit config, + - to set targetElement to full screen toggle. + */ function setFullScreenToggleTargetElement({config, targetElementId}: { config: UIConfig, targetElementId: string }){ - if (config.root && Array.isArray(config.root['div#controlbar-left'])) { - const fullScreenToggleIndex = config.root['div#controlbar-left'].indexOf('dyte-fullscreen-toggle'); - if(fullScreenToggleIndex > -1){ - config.root['div#controlbar-left'][fullScreenToggleIndex] = ['dyte-fullscreen-toggle', { - variant: 'vertical', - targetElement: document.querySelector("#"+targetElementId), - }]; - } - } - ['dyte-more-toggle.activeMoreMenu', 'dyte-more-toggle.activeMoreMenu.md', 'dyte-more-toggle.activeMoreMenu.sm'].forEach((configElemKey) => { - const configElem = config?.root?.[configElemKey] as any; - configElem?.forEach((dyteElemConfigSet: any) => { - if (dyteElemConfigSet[0] === 'dyte-fullscreen-toggle') { - dyteElemConfigSet[1].targetElement = document.querySelector("#"+targetElementId); - } - }); - }); + if (config.root && Array.isArray(config.root['div#controlÚÚbar-left'])) { + const fullScreenToggleIndex = config.root['div#controlbar-left'].indexOf('dyte-fullscreen-toggle'); + if(fullScreenToggleIndex > -1){ + config.root['div#controlbar-left'][fullScreenToggleIndex] = ['dyte-fullscreen-toggle', { + variant: 'vertical', + targetElement: document.querySelector("#"+targetElementId), + }]; + } + } + ['dyte-more-toggle.activeMoreMenu', 'dyte-more-toggle.activeMoreMenu.md', 'dyte-more-toggle.activeMoreMenu.sm'].forEach((configElemKey) => { + const configElem = config?.root?.[configElemKey] as any; + configElem?.forEach((dyteElemConfigSet: any) => { + if (dyteElemConfigSet[0] === 'dyte-fullscreen-toggle') { + dyteElemConfigSet[1].targetElement = document.querySelector("#"+targetElementId); + } + }); + }); } ` } /> diff --git a/docs/react-ui-kit/build-in-call-ui/build-your-own/handling-states-and-configs.mdx b/docs/react-ui-kit/build-in-call-ui/build-your-own/handling-states-and-configs.mdx index 282a2dc510..b0dc1ea157 100644 --- a/docs/react-ui-kit/build-in-call-ui/build-your-own/handling-states-and-configs.mdx +++ b/docs/react-ui-kit/build-in-call-ui/build-your-own/handling-states-and-configs.mdx @@ -33,206 +33,215 @@ export default function Meeting() { const { meeting } = useDyteMeeting(); const [config, setConfig] = useState(defaultConfig); /** - * We need setStates method to add custom functionalities, - * as well as to ensure that web-core & ui-kit are in Sync. - */ + * We need setStates method to add custom functionalities, + * as well as to ensure that web-core & ui-kit are in Sync. + */ const [states, setStates] = useState({ meeting: 'setup', sidebar: 'chat' }); -useEffect(() => { -async function setupMeetingConfigs(){ -const theme = meeting!.self.config; -const { config } = generateConfig(theme, meeting!); + useEffect(() => { + async function setupMeetingConfigs() { + const theme = meeting!.self.config; + const { config } = generateConfig(theme, meeting!); /** * Full screen toggle, by default requests dyte-meeting/DyteMeeting element to be in full screen. * Since DyteMeeting element is not here, * we need to pass dyte-fullscreen-toggle, an targetElementId through config. */ - setFullScreenToggleTargetElement({config, targetElementId: 'root'}); + setFullScreenToggleTargetElement({ config, targetElementId: 'root' }); - setConfig({...config}); + setConfig({ ...config }); - /** - * Add listeners on meeting & self to monitor leave meeting, join meeting and so on. - * This work was earlier done by DyteMeeting component internally. - */ + /** + * Add listeners on meeting & self to monitor leave meeting, join meeting and so on. + * This work was earlier done by DyteMeeting component internally. + */ const stateListenersUtils = new DyteStateListenersUtils(() => meeting, () => states, () => setStates); stateListenersUtils.addDyteEventListeners(); - try{ + try { await meeting.join(); - } catch(e){ + } catch (e) { // do nothing } } - if(meeting){ + if (meeting) { setupMeetingConfigs(); } + }, [meeting]); -}, [meeting]); - -return ( -/\*\* - -- Using a ref hack, we are adding "dyteStateUpdate" listener, -- so that we can listen to child component's internal state changes. - \*/ -
{ - el?.addEventListener('dyteStateUpdate', (e) => { - const { detail: newStateUpdate } = e as unknown as { detail: CustomStates }; - setStates((oldState: CustomStates) => { return { - ...oldState, - ...newStateUpdate, - }}); - }); - }}> + return ( + /** + * Using a ref hack, we are adding "dyteStateUpdate" listener, + * so that we can listen to child component's internal state changes. + */ +
{ + el?.addEventListener('dyteStateUpdate', (e) => { + const { detail: newStateUpdate } = e as unknown as { detail: CustomStates }; + setStates((oldState: CustomStates) => { + return { + ...oldState, + ...newStateUpdate, + }; + }); + }); + }} + > -
-); - +
+ ); } -function CustomDyteMeetingUI({ meeting, config, states, setStates }: { meeting: DyteClient, config: UIConfig, states: CustomStates, setStates: SetStates}) { -return
Your Custom UI will come here
; +function CustomDyteMeetingUI({ meeting, config, states, setStates }: { meeting: DyteClient; config: UIConfig; states: CustomStates; setStates: SetStates }) { + return
Your Custom UI will come here
; } -/\*\* +/** + * DyteStateListenersUtils is a class that listens to web-core changes and syncs them with ui-kit + */ +class DyteStateListenersUtils { + getStates: () => CustomStates; + + getStateSetter: () => (newState: CustomStates) => void; -- DyteStateListenersUtils is a class that listens to web-core changes and syncs them with ui-kit - \*/ - class DyteStateListenersUtils{ + getMeeting: () => DyteClient; - getStates: () => CustomStates; + get states() { + return this.getStates(); + } - getStateSetter: () => (newState: CustomStates) => void; + get setGlobalStates() { + return this.getStateSetter(); + } - getMeeting: () => DyteClient; + get meeting() { + return this.getMeeting(); + } - get states(){ - return this.getStates(); - } + constructor( + getMeeting: () => DyteClient, + getGlobalStates: () => CustomStates, + getGlobalStateSetter: () => (newState: CustomStates) => void + ) { + this.getMeeting = getMeeting; + this.getStates = getGlobalStates; + this.getStateSetter = getGlobalStateSetter; + } - get setGlobalStates(){ - return this.getStateSetter(); + private updateStates(newState: CustomStates) { + this.setGlobalStates((oldState: CustomStates) => { + return { + ...oldState, + ...newState, }; + }); + console.log(newState); + } - get meeting(){ - return this.getMeeting(); - } + private roomJoinedListener = () => { + this.updateStates({ meeting: 'joined' }); + }; - constructor(getMeeting: () => DyteClient, getGlobalStates: () => CustomStates, getGlobalStateSetter: () => (newState: CustomStates) => void){ - this.getMeeting = getMeeting; - this.getStates = getGlobalStates; - this.getStateSetter = getGlobalStateSetter; - } - private updateStates(newState: CustomStates){ - this.setGlobalStates((oldState: CustomStates) => { return { - ...oldState, - ...newState, - }}); - console.log(newState); - } - private roomJoinedListener = () => { - this.updateStates({ meeting: 'joined' }); - }; - - private socketServiceRoomJoinedListener = () => { - if (this.meeting.stage.status === 'ON_STAGE' || this.meeting.stage.status === undefined) return; - this.updateStates({ meeting: 'joined' }); - }; - - private waitlistedListener = () => { - this.updateStates({ meeting: 'waiting' }); - }; - - private roomLeftListener = ({ state }: { state: RoomLeftState }) => { - const states = this.states; - if (states?.roomLeftState === 'disconnected') { - this.updateStates({ meeting: 'ended', roomLeftState: state }); - return; - } - this.updateStates({ meeting: 'ended', roomLeftState: state }); - }; - - private mediaPermissionUpdateListener = ({ kind, message }: { - kind: PermissionSettings['kind'], - message: string, - }) => { - if (['audio', 'video'].includes(kind!)) { - if (message === 'ACCEPTED' || message === 'NOT_REQUESTED' || this.states.activeDebugger) - return; - const permissionModalSettings: PermissionSettings = { - enabled: true, - kind, - }; - this.updateStates({ activePermissionsMessage: permissionModalSettings }); - } - }; - - private joinStateAcceptedListener = () => { - this.updateStates({ activeJoinStage: true }); - }; - - private handleChangingMeeting(destinationMeetingId: string) { - this.updateStates({ - activeBreakoutRoomsManager: { - ...this.states.activeBreakoutRoomsManager, - active: this.states.activeBreakoutRoomsManager!.active, - destinationMeetingId, - } - }); - } + private socketServiceRoomJoinedListener = () => { + if (this.meeting.stage.status === 'ON_STAGE' || this.meeting.stage.status === undefined) return; + this.updateStates({ meeting: 'joined' }); + }; - addDyteEventListeners(){ - if (this.meeting.meta.viewType === 'LIVESTREAM') { - this.meeting.self.addListener('socketServiceRoomJoined', this.socketServiceRoomJoinedListener); - } - this.meeting.self.addListener('roomJoined', this.roomJoinedListener); + private waitlistedListener = () => { + this.updateStates({ meeting: 'waiting' }); + }; - this.meeting.self.addListener('waitlisted', this.waitlistedListener); - this.meeting.self.addListener('roomLeft', this.roomLeftListener); - this.meeting.self.addListener('mediaPermissionUpdate', this.mediaPermissionUpdateListener); - this.meeting.self.addListener('joinStageRequestAccepted', this.joinStateAcceptedListener); + private roomLeftListener = ({ state }: { state: RoomLeftState }) => { + const states = this.states; + if (states?.roomLeftState === 'disconnected') { + this.updateStates({ meeting: 'ended', roomLeftState: state }); + return; + } + this.updateStates({ meeting: 'ended', roomLeftState: state }); + }; + + private mediaPermissionUpdateListener = ({ + kind, + message, + }: { + kind: PermissionSettings['kind']; + message: string; + }) => { + if (['audio', 'video'].includes(kind!)) { + if (message === 'ACCEPTED' || message === 'NOT_REQUESTED' || this.states.activeDebugger) + return; + const permissionModalSettings: PermissionSettings = { + enabled: true, + kind, + }; + this.updateStates({ activePermissionsMessage: permissionModalSettings }); + } + }; + + private joinStateAcceptedListener = () => { + this.updateStates({ activeJoinStage: true }); + }; + + private handleChangingMeeting(destinationMeetingId: string) { + this.updateStates({ + activeBreakoutRoomsManager: { + ...this.states.activeBreakoutRoomsManager, + active: this.states.activeBreakoutRoomsManager!.active, + destinationMeetingId, + } + }); + } - if (this.meeting.connectedMeetings.supportsConnectedMeetings) { - this.meeting.connectedMeetings.once('changingMeeting', this.handleChangingMeeting); - } + addDyteEventListeners() { + if (this.meeting.meta.viewType === 'LIVESTREAM') { + this.meeting.self.addListener('socketServiceRoomJoined', this.socketServiceRoomJoinedListener); + } + this.meeting.self.addListener('roomJoined', this.roomJoinedListener); - } - cleanupDyteEventListeners(){ + this.meeting.self.addListener('waitlisted', this.waitlistedListener); + this.meeting.self.addListener('roomLeft', this.roomLeftListener); + this.meeting.self.addListener('mediaPermissionUpdate', this.mediaPermissionUpdateListener); + this.meeting.self.addListener('joinStageRequestAccepted', this.joinStateAcceptedListener); - } + if (this.meeting.connectedMeetings.supportsConnectedMeetings) { + this.meeting.connectedMeetings.once('changingMeeting', this.handleChangingMeeting); + } + } -} + cleanupDyteEventListeners() { -/\*\* + } +} -- setFullScreenToggleTargetElement updates the ui-kit config, -- to set targetElement to full screen toggle. - \*/ - function setFullScreenToggleTargetElement({config, targetElementId}: { config: UIConfig, targetElementId: string }){ +/** + * setFullScreenToggleTargetElement updates the ui-kit config, + * to set targetElement to full screen toggle. + */ +function setFullScreenToggleTargetElement({ config, targetElementId }: { config: UIConfig, targetElementId: string }) { if (config.root && Array.isArray(config.root['div#controlbar-left'])) { - const fullScreenToggleIndex = config.root['div#controlbar-left'].indexOf('dyte-fullscreen-toggle'); - if(fullScreenToggleIndex > -1){ - config.root['div#controlbar-left'][fullScreenToggleIndex] = ['dyte-fullscreen-toggle', { - variant: 'vertical', - targetElement: document.querySelector("#"+targetElementId), - }]; - } + const fullScreenToggleIndex = config.root['div#controlbar-left'].indexOf('dyte-fullscreen-toggle'); + if (fullScreenToggleIndex > -1) { + config.root['div#controlbar-left'][fullScreenToggleIndex] = ['dyte-fullscreen-toggle', { + variant: 'vertical', + targetElement: document.querySelector("#" + targetElementId), + }]; + } } ['dyte-more-toggle.activeMoreMenu', 'dyte-more-toggle.activeMoreMenu.md', 'dyte-more-toggle.activeMoreMenu.sm'].forEach((configElemKey) => { - const configElem = config?.root?.[configElemKey] as any; - configElem?.forEach((dyteElemConfigSet: any) => { - if (dyteElemConfigSet[0] === 'dyte-fullscreen-toggle') { - dyteElemConfigSet[1].targetElement = document.querySelector("#"+targetElementId); - } - }); + const configElem = config?.root?.[configElemKey] as any; + configElem?.forEach((dyteElemConfigSet: any) => { + if (dyteElemConfigSet[0] === 'dyte-fullscreen-toggle') { + dyteElemConfigSet[1].targetElement = document.querySelector("#" + targetElementId); + } + }); }); - } +} ` } /> diff --git a/docs/react-ui-kit/build-in-call-ui/build-your-own/stage-ui-using-dyte-grid.mdx b/docs/react-ui-kit/build-in-call-ui/build-your-own/stage-ui-using-dyte-grid.mdx index 680d8b761f..c895ba133e 100644 --- a/docs/react-ui-kit/build-in-call-ui/build-your-own/stage-ui-using-dyte-grid.mdx +++ b/docs/react-ui-kit/build-in-call-ui/build-your-own/stage-ui-using-dyte-grid.mdx @@ -18,40 +18,39 @@ import { useDyteMeeting, useDyteSelector } from '@dytesdk/react-web-core'; import { useEffect, useState } from 'react'; function MeetingStage({ meeting, config, states, setStates }: { meeting: DyteClient, config: UIConfig, states: CustomStates, setStates: SetStates}) { - -return ( - -
- - - - {states.activeSidebar && ( - - )} - - - - -
-); } + return ( +
+ + + + {states.activeSidebar && ( + + )} + + + + +
+ ); +} export default function Meeting() { -const { meeting } = useDyteMeeting(); -const [config, setConfig] = useState(defaultConfig); -const [states, setStates] = useState({ - meeting: 'setup', - sidebar: 'chat' -}); - -useEffect(() => { -async function setupMeetingConfigs(){ -const theme = meeting!.self.config; -const { config } = generateConfig(theme, meeting!); + const { meeting } = useDyteMeeting(); + const [config, setConfig] = useState(defaultConfig); + const [states, setStates] = useState({ + meeting: 'setup', + sidebar: 'chat' + }); + + useEffect(() => { + async function setupMeetingConfigs(){ + const theme = meeting!.self.config; + const { config } = generateConfig(theme, meeting!); /** * Full screen by default requests dyte-meeting/DyteMeeting element to be in full screen. @@ -62,10 +61,10 @@ const { config } = generateConfig(theme, meeting!); setConfig({...config}); - /** - * Add listeners on meeting & self to monitor leave meeting, join meeting and so on. - * This work was earlier done by DyteMeeting component internally. - */ + /** + * Add listeners on meeting & self to monitor leave meeting, join meeting and so on. + * This work was earlier done by DyteMeeting component internally. + */ const stateListenersUtils = new DyteStateListenersUtils(() => meeting, () => states, () => setStates); stateListenersUtils.addDyteEventListeners(); @@ -77,34 +76,31 @@ const { config } = generateConfig(theme, meeting!); } if(meeting){ - /** - * During development phase, make sure to expose meeting object to window, - * for debugging purposes. - */ + /** + * During development phase, make sure to expose meeting object to window, + * for debugging purposes. + */ Object.assign(window, { meeting, }) setupMeetingConfigs(); } - -}, [meeting]); - -return ( - -
{ - el?.addEventListener('dyteStateUpdate', (e) => { - const { detail: newStateUpdate } = e as unknown as { detail: CustomStates }; - console.log('dyteStateUpdateSetup:: ', newStateUpdate); - setStates((oldState: CustomStates) => { return { - ...oldState, - ...newStateUpdate, - }}); - }); - }}> + }, [meeting]); + + return ( +
{ + el?.addEventListener('dyteStateUpdate', (e) => { + const { detail: newStateUpdate } = e as unknown as { detail: CustomStates }; + console.log('dyteStateUpdateSetup:: ', newStateUpdate); + setStates((oldState: CustomStates) => { return { + ...oldState, + ...newStateUpdate, + }}); + }); + }}> -
-) - +
+ ) } export class DyteStateListenersUtils{ diff --git a/docs/react-ui-kit/build-in-call-ui/build-your-own/states based UI Split.mdx b/docs/react-ui-kit/build-in-call-ui/build-your-own/states based UI Split.mdx index d1b0afcbb1..680630d83a 100644 --- a/docs/react-ui-kit/build-in-call-ui/build-your-own/states based UI Split.mdx +++ b/docs/react-ui-kit/build-in-call-ui/build-your-own/states based UI Split.mdx @@ -19,229 +19,224 @@ import { defaultConfig, generateConfig } from '@dytesdk/react-ui-kit'; import { useDyteMeeting, useDyteSelector } from '@dytesdk/react-web-core'; import { useEffect, useState } from 'react'; -function CustomDyteMeeting({ meeting, config, states, setStates }: { meeting: DyteClient, config: UIConfig, states: CustomStates, setStates: SetStates}){ -if (!meeting) { -return
A loading screen comes here
; -} - - if (states.meeting === 'setup') { - return
Pre-call UI comes here
; - } +function CustomDyteMeeting({ meeting, config, states, setStates }: { meeting: DyteClient, config: UIConfig, states: CustomStates, setStates: SetStates}) { + if (!meeting) { + return
A loading screen comes here
; + } - if(states.meeting === 'ended'){ - return
Post-call UI comes here
; - } + if (states.meeting === 'setup') { + return
Pre-call UI comes here
; + } - if(states.meeting === 'waiting'){ - return
Waiting room UI comes here
; - } + if (states.meeting === 'ended') { + return
Post-call UI comes here
; + } - if(states.meeting === 'joined'){ - return
In-call UI comes here
; - } + if (states.meeting === 'waiting') { + return
Waiting room UI comes here
; + } + if (states.meeting === 'joined') { + return
In-call UI comes here
; + } } export default function Meeting() { const { meeting } = useDyteMeeting(); const [config, setConfig] = useState(defaultConfig); /** - * We need setStates method to add custom functionalities, - * as well as to ensure that web-core & ui-kit are in Sync. - */ + * We need setStates method to add custom functionalities, + * as well as to ensure that web-core & ui-kit are in Sync. + */ const [states, setStates] = useState({ meeting: 'setup', sidebar: 'chat' }); -useEffect(() => { -async function setupMeetingConfigs(){ -const theme = meeting!.self.config; -const { config } = generateConfig(theme, meeting!); + useEffect(() => { + async function setupMeetingConfigs() { + const theme = meeting!.self.config; + const { config } = generateConfig(theme, meeting!); /** * Full screen toggle, by default requests dyte-meeting/DyteMeeting element to be in full screen. * Since DyteMeeting element is not here, * we need to pass dyte-fullscreen-toggle, an targetElementId through config. */ - setFullScreenToggleTargetElement({config, targetElementId: 'root'}); + setFullScreenToggleTargetElement({ config, targetElementId: 'root' }); - setConfig({...config}); + setConfig({ ...config }); - /** - * Add listeners on meeting & self to monitor leave meeting, join meeting and so on. - * This work was earlier done by DyteMeeting component internally. - */ + /** + * Add listeners on meeting & self to monitor leave meeting, join meeting and so on. + * This work was earlier done by DyteMeeting component internally. + */ const stateListenersUtils = new DyteStateListenersUtils(() => meeting, () => states, () => setStates); stateListenersUtils.addDyteEventListeners(); - try{ + try { await meeting.join(); - } catch(e){ + } catch (e) { // do nothing } } - if(meeting){ + if (meeting) { setupMeetingConfigs(); } + }, [meeting]); -}, [meeting]); - -return ( -/\*\* - -- Using a ref hack, we are adding "dyteStateUpdate" listener, -- so that we can listen to child component's internal state changes. - \*/ + return ( + /** + * Using a ref hack, we are adding "dyteStateUpdate" listener, + * so that we can listen to child component's internal state changes. + */
{ - el?.addEventListener('dyteStateUpdate', (e) => { - const { detail: newStateUpdate } = e as unknown as { detail: CustomStates }; - setStates((oldState: CustomStates) => { return { - ...oldState, - ...newStateUpdate, - }}); - }); - }}> + el?.addEventListener('dyteStateUpdate', (e) => { + const { detail: newStateUpdate } = e as unknown as { detail: CustomStates }; + setStates((oldState: CustomStates) => { + return { + ...oldState, + ...newStateUpdate, + }; + }); + }); + }}> -
-); - +
+ ); } -/\*\* - -- DyteStateListenersUtils is a class that listens to web-core changes and syncs them with ui-kit - \*/ - class DyteStateListenersUtils{ +/** + * DyteStateListenersUtils is a class that listens to web-core changes and syncs them with ui-kit + */ +class DyteStateListenersUtils { + getStates: () => CustomStates; + getStateSetter: () => (newState: CustomStates) => void; + getMeeting: () => DyteClient; - getStates: () => CustomStates; + get states() { + return this.getStates(); + } - getStateSetter: () => (newState: CustomStates) => void; + get setGlobalStates() { + return this.getStateSetter(); + } - getMeeting: () => DyteClient; + get meeting() { + return this.getMeeting(); + } - get states(){ - return this.getStates(); - } + constructor(getMeeting: () => DyteClient, getGlobalStates: () => CustomStates, getGlobalStateSetter: () => (newState: CustomStates) => void) { + this.getMeeting = getMeeting; + this.getStates = getGlobalStates; + this.getStateSetter = getGlobalStateSetter; + } - get setGlobalStates(){ - return this.getStateSetter(); + private updateStates(newState: CustomStates) { + this.setGlobalStates((oldState: CustomStates) => { + return { + ...oldState, + ...newState, }; + }); + console.log(newState); + } - get meeting(){ - return this.getMeeting(); - } - - constructor(getMeeting: () => DyteClient, getGlobalStates: () => CustomStates, getGlobalStateSetter: () => (newState: CustomStates) => void){ - this.getMeeting = getMeeting; - this.getStates = getGlobalStates; - this.getStateSetter = getGlobalStateSetter; - } - private updateStates(newState: CustomStates){ - this.setGlobalStates((oldState: CustomStates) => { return { - ...oldState, - ...newState, - }}); - console.log(newState); - } - private roomJoinedListener = () => { - this.updateStates({ meeting: 'joined' }); - }; - - private socketServiceRoomJoinedListener = () => { - if (this.meeting.stage.status === 'ON_STAGE' || this.meeting.stage.status === undefined) return; - this.updateStates({ meeting: 'joined' }); - }; - - private waitlistedListener = () => { - this.updateStates({ meeting: 'waiting' }); - }; - - private roomLeftListener = ({ state }: { state: RoomLeftState }) => { - const states = this.states; - if (states?.roomLeftState === 'disconnected') { - this.updateStates({ meeting: 'ended', roomLeftState: state }); - return; - } - this.updateStates({ meeting: 'ended', roomLeftState: state }); - }; - - private mediaPermissionUpdateListener = ({ kind, message }: { - kind: PermissionSettings['kind'], - message: string, - }) => { - if (['audio', 'video'].includes(kind!)) { - if (message === 'ACCEPTED' || message === 'NOT_REQUESTED' || this.states.activeDebugger) - return; - const permissionModalSettings: PermissionSettings = { - enabled: true, - kind, - }; - this.updateStates({ activePermissionsMessage: permissionModalSettings }); - } - }; - - private joinStateAcceptedListener = () => { - this.updateStates({ activeJoinStage: true }); - }; - - private handleChangingMeeting(destinationMeetingId: string) { - this.updateStates({ - activeBreakoutRoomsManager: { - ...this.states.activeBreakoutRoomsManager, - active: this.states.activeBreakoutRoomsManager!.active, - destinationMeetingId, - } - }); - } - - addDyteEventListeners(){ - if (this.meeting.meta.viewType === 'LIVESTREAM') { - this.meeting.self.addListener('socketServiceRoomJoined', this.socketServiceRoomJoinedListener); - } - this.meeting.self.addListener('roomJoined', this.roomJoinedListener); + private roomJoinedListener = () => { + this.updateStates({ meeting: 'joined' }); + }; - this.meeting.self.addListener('waitlisted', this.waitlistedListener); - this.meeting.self.addListener('roomLeft', this.roomLeftListener); - this.meeting.self.addListener('mediaPermissionUpdate', this.mediaPermissionUpdateListener); - this.meeting.self.addListener('joinStageRequestAccepted', this.joinStateAcceptedListener); + private socketServiceRoomJoinedListener = () => { + if (this.meeting.stage.status === 'ON_STAGE' || this.meeting.stage.status === undefined) return; + this.updateStates({ meeting: 'joined' }); + }; - if (this.meeting.connectedMeetings.supportsConnectedMeetings) { - this.meeting.connectedMeetings.once('changingMeeting', this.handleChangingMeeting); - } + private waitlistedListener = () => { + this.updateStates({ meeting: 'waiting' }); + }; + private roomLeftListener = ({ state }: { state: RoomLeftState }) => { + const states = this.states; + if (states?.roomLeftState === 'disconnected') { + this.updateStates({ meeting: 'ended', roomLeftState: state }); + return; + } + this.updateStates({ meeting: 'ended', roomLeftState: state }); + }; + + private mediaPermissionUpdateListener = ({ kind, message }: { + kind: PermissionSettings['kind'], + message: string, + }) => { + if (['audio', 'video'].includes(kind!)) { + if (message === 'ACCEPTED' || message === 'NOT_REQUESTED' || this.states.activeDebugger) + return; + const permissionModalSettings: PermissionSettings = { + enabled: true, + kind, + }; + this.updateStates({ activePermissionsMessage: permissionModalSettings }); + } + }; + + private joinStateAcceptedListener = () => { + this.updateStates({ activeJoinStage: true }); + }; + + private handleChangingMeeting(destinationMeetingId: string) { + this.updateStates({ + activeBreakoutRoomsManager: { + ...this.states.activeBreakoutRoomsManager, + active: this.states.activeBreakoutRoomsManager!.active, + destinationMeetingId, } - cleanupDyteEventListeners(){ + }); + } - } + addDyteEventListeners() { + if (this.meeting.meta.viewType === 'LIVESTREAM') { + this.meeting.self.addListener('socketServiceRoomJoined', this.socketServiceRoomJoinedListener); + } + this.meeting.self.addListener('roomJoined', this.roomJoinedListener); + this.meeting.self.addListener('waitlisted', this.waitlistedListener); + this.meeting.self.addListener('roomLeft', this.roomLeftListener); + this.meeting.self.addListener('mediaPermissionUpdate', this.mediaPermissionUpdateListener); + this.meeting.self.addListener('joinStageRequestAccepted', this.joinStateAcceptedListener); + + if (this.meeting.connectedMeetings.supportsConnectedMeetings) { + this.meeting.connectedMeetings.once('changingMeeting', this.handleChangingMeeting); + } + } + cleanupDyteEventListeners() { + // Cleanup logic here + } } -/\*\* - -- setFullScreenToggleTargetElement updates the ui-kit config, -- to set targetElement to full screen toggle. - \*/ - function setFullScreenToggleTargetElement({config, targetElementId}: { config: UIConfig, targetElementId: string }){ +/** + * setFullScreenToggleTargetElement updates the ui-kit config, + * to set targetElement to full screen toggle. + */ +function setFullScreenToggleTargetElement({ config, targetElementId }: { config: UIConfig, targetElementId: string }) { if (config.root && Array.isArray(config.root['div#controlbar-left'])) { - const fullScreenToggleIndex = config.root['div#controlbar-left'].indexOf('dyte-fullscreen-toggle'); - if(fullScreenToggleIndex > -1){ - config.root['div#controlbar-left'][fullScreenToggleIndex] = ['dyte-fullscreen-toggle', { - variant: 'vertical', - targetElement: document.querySelector("#"+targetElementId), - }]; - } + const fullScreenToggleIndex = config.root['div#controlbar-left'].indexOf('dyte-fullscreen-toggle'); + if (fullScreenToggleIndex > -1) { + config.root['div#controlbar-left'][fullScreenToggleIndex] = ['dyte-fullscreen-toggle', { + variant: 'vertical', + targetElement: document.querySelector("#" + targetElementId), + }]; + } } ['dyte-more-toggle.activeMoreMenu', 'dyte-more-toggle.activeMoreMenu.md', 'dyte-more-toggle.activeMoreMenu.sm'].forEach((configElemKey) => { - const configElem = config?.root?.[configElemKey] as any; - configElem?.forEach((dyteElemConfigSet: any) => { - if (dyteElemConfigSet[0] === 'dyte-fullscreen-toggle') { - dyteElemConfigSet[1].targetElement = document.querySelector("#"+targetElementId); - } - }); + const configElem = config?.root?.[configElemKey] as any; + configElem?.forEach((dyteElemConfigSet: any) => { + if (dyteElemConfigSet[0] === 'dyte-fullscreen-toggle') { + dyteElemConfigSet[1].targetElement = document.querySelector("#" + targetElementId); + } + }); }); - } +} ` } /> diff --git a/docs/react-ui-kit/build-in-call-ui/default-meeting-ui.mdx b/docs/react-ui-kit/build-in-call-ui/default-meeting-ui.mdx index 33ee8c37c1..0114657d51 100644 --- a/docs/react-ui-kit/build-in-call-ui/default-meeting-ui.mdx +++ b/docs/react-ui-kit/build-in-call-ui/default-meeting-ui.mdx @@ -27,33 +27,32 @@ export default function MyMeeting() { const { meeting } = useDyteMeeting(); const roomState = useDyteSelector((m) => m.self.roomState); -return ( - -
- {roomState === 'init' && } - {roomState === 'joined' && ( -
-
- -
- -
- Custom in-call UI - -
- -
- -
-
- -)} -{roomState === 'ended' && ()} - -
-); }` } /> + return ( +
+ {roomState === 'init' && } + {roomState === 'joined' && ( +
+
+ +
+ +
+ Custom in-call UI + +
+ +
+ +
+
+ )} + {roomState === 'ended' && } +
+ ); +} +`} /> Since `DyteMeeting` is a complex component and provides a lot more than just the UI, let's go to the next page and start splitting it to uncover what it does. diff --git a/docs/react-ui-kit/build-pre-call-ui/build-your-own/add-audio-video-preview.mdx b/docs/react-ui-kit/build-pre-call-ui/build-your-own/add-audio-video-preview.mdx index 5ef6ca4f3f..86ff8151c6 100644 --- a/docs/react-ui-kit/build-pre-call-ui/build-your-own/add-audio-video-preview.mdx +++ b/docs/react-ui-kit/build-pre-call-ui/build-your-own/add-audio-video-preview.mdx @@ -37,7 +37,7 @@ highlight={[{start: 18, end: 22}, {start: 31, end: 32}, {start: 34, end: 34}]} hide={[{start:1, end: 6}]} file={` import { - DyteParticipantTile, DyteAvatar,DyteNameTag, + DyteParticipantTile, DyteAvatar, DyteNameTag, DyteAudioVisualizer, DyteMicToggle, DyteCameraToggle, DyteButton, } from '@dytesdk/react-ui-kit'; import { useDyteMeeting } from '@dytesdk/react-web-core'; @@ -45,44 +45,47 @@ import { useDyteMeeting } from '@dytesdk/react-web-core'; export default function CustomMeetingPreview() { const { meeting } = useDyteMeeting(); -return ( -
-
-
- - - - - -
+
+
+ + + + + +
- - -
-
-
-
-
-

Joining as {meeting.self.name}

-
- { -await meeting.join(); -}} > -Join - -
-
-
-); + }} + > + + +
+ +
+
+
+

Joining as {meeting.self.name}

+
+ { + await meeting.join(); + }} + > + Join + +
+
+ + ); } `} /> diff --git a/docs/react-ui-kit/build-pre-call-ui/build-your-own/edit-user-name.mdx b/docs/react-ui-kit/build-pre-call-ui/build-your-own/edit-user-name.mdx index 8dbf7bf0df..0d9b283712 100644 --- a/docs/react-ui-kit/build-pre-call-ui/build-your-own/edit-user-name.mdx +++ b/docs/react-ui-kit/build-pre-call-ui/build-your-own/edit-user-name.mdx @@ -36,48 +36,50 @@ export default function CustomMeetingPreview() { const permissions = useDyteSelector((m) => m.self.permissions); const [participantName, setParticipantName] = useState(""); -useEffect(() => { -if (!meeting) { -return; -} -setParticipantName(meeting.self.name); -}, [meeting]); + useEffect(() => { + if (!meeting) { + return; + } + setParticipantName(meeting.self.name); + }, [meeting]); -return ( -
-
-
-
-
-

Joining as

-
-{permissions.canEditDisplayName && ( - setParticipantName(event.target.value)} -/> -)} - { -if (participantName) { -if (permissions.canEditDisplayName) { -await meeting.self.setName(participantName); -} -await meeting.join(); -} -}} > -Join - -
-
-
-); + return ( +
+
+
+
+
+

Joining as

+
+ {permissions.canEditDisplayName && ( + setParticipantName(event.target.value)} + /> + )} + { + if (participantName) { + if (permissions.canEditDisplayName) { + await meeting.self.setName(participantName); + } + await meeting.join(); + } + }} + > + Join + +
+
+
+ ); } `} /> diff --git a/docs/react-ui-kit/build-pre-call-ui/build-your-own/initial-code-skeleton.mdx b/docs/react-ui-kit/build-pre-call-ui/build-your-own/initial-code-skeleton.mdx index 54c8f05133..982d2b8090 100644 --- a/docs/react-ui-kit/build-pre-call-ui/build-your-own/initial-code-skeleton.mdx +++ b/docs/react-ui-kit/build-pre-call-ui/build-your-own/initial-code-skeleton.mdx @@ -64,15 +64,13 @@ function MyMeeting() { highlight={[{start: 12, end: 12}, {start: 18, end: 18}]} hide={[{start: 1, end: 3}]} file={` -import { useDyteMeeting } from "@dytesdk/react-web-core"; -import { DyteButton } from "@dytesdk/react-ui-kit"; +import { useDyteMeeting } from '@dytesdk/react-web-core'; +import { DyteButton } from '@dytesdk/react-ui-kit'; export default function CustomMeetingPreview() { const { meeting } = useDyteMeeting(); return ( -
+

Joining as {meeting.self.name}

diff --git a/docs/react-ui-kit/build-pre-call-ui/default-setup-screen.mdx b/docs/react-ui-kit/build-pre-call-ui/default-setup-screen.mdx index 724e4f3f97..5a1ae70d76 100644 --- a/docs/react-ui-kit/build-pre-call-ui/default-setup-screen.mdx +++ b/docs/react-ui-kit/build-pre-call-ui/default-setup-screen.mdx @@ -26,14 +26,14 @@ export default function MyMeeting() { const { meeting } = useDyteMeeting(); const roomState = useDyteSelector((m) => m.self.roomState); -return ( -
-{roomState === 'init' && } -{roomState === 'joined' &&
Custom in-meeting UI
} -{roomState === 'ended' &&
Custom post-meeting UI
} -
-); -}` -} /> + return ( +
+ {roomState === 'init' && } + {roomState === 'joined' &&
Custom in-meeting UI
} + {roomState === 'ended' &&
Custom post-meeting UI
} +
+ ); +} +`}/> If you want to build a custom pre-call UI, let's go to the next page to start building one. diff --git a/docs/react-ui-kit/components/dyte-participant-tile.mdx b/docs/react-ui-kit/components/dyte-participant-tile.mdx index 6ef1614d60..afe2660ab3 100644 --- a/docs/react-ui-kit/components/dyte-participant-tile.mdx +++ b/docs/react-ui-kit/components/dyte-participant-tile.mdx @@ -73,17 +73,17 @@ import { useDyteMeeting } from "@dytesdk/react-web-core"; export default function MyMeetingUI() { const { meeting } = useDyteMeeting(); -return ( - - - - - -); + + + + + ); } `} /> diff --git a/docs/react-ui-kit/quickstart.mdx b/docs/react-ui-kit/quickstart.mdx index 3cf54de05f..0d9349f253 100644 --- a/docs/react-ui-kit/quickstart.mdx +++ b/docs/react-ui-kit/quickstart.mdx @@ -114,20 +114,19 @@ For more information on the other props of `DyteMeeting`, see import CodeRunner from '@site/src/components/CodeRunner/CodeRunner'; - -); } `} /> + const { meeting } = useDyteMeeting(); + return ( + + ); +}`} +/> React UI Kit Quickstart diff --git a/docs/ui-kit/quickstart.mdx b/docs/ui-kit/quickstart.mdx index d9debff933..26c4285602 100644 --- a/docs/ui-kit/quickstart.mdx +++ b/docs/ui-kit/quickstart.mdx @@ -102,10 +102,11 @@ import CodeRunner from '@site/src/components/CodeRunner/CodeRunner'; highlight={[{start: 10, end: 10}]} hide={[{start:1, end: 8}]} framework='static' -file={` +file={` + @@ -127,8 +128,7 @@ file={` document.getElementById('my-meeting').meeting = meeting; }; -init(); - + init(); `}