Skip to content

Commit

Permalink
Merge pull request #26 from dyte-io/fix/mobile-layout-changes
Browse files Browse the repository at this point in the history
fix: mobile layout with webinar
  • Loading branch information
madhugb authored Jan 12, 2024
2 parents d861ade + 6cb86e9 commit 0e1ae3d
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 41 deletions.
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion samples/active-speaker-ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"preview": "vite preview"
},
"dependencies": {
"@dytesdk/react-ui-kit": "^1.61.4",
"@dytesdk/react-ui-kit": "^1.61.3-staging.20",
"@dytesdk/react-web-core": "^1.35.12",
"@uidotdev/usehooks": "^2.4.1",
"react": "^18.2.0",
Expand Down
7 changes: 2 additions & 5 deletions samples/active-speaker-ui/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import Meeting from './components/Meeting';
import { DyteDialogManager, DyteParticipantsAudio, DyteNotifications } from '@dytesdk/react-ui-kit';
import { DyteParticipantsAudio, DyteNotifications } from '@dytesdk/react-ui-kit';
import { DyteProvider, useDyteClient } from '@dytesdk/react-web-core';
import { useEffect } from 'react';
import MeetingProvider from './components/MeetingContext';
Expand All @@ -20,8 +20,6 @@ export default function App() {
audio: false,
video: false,
},
}).then((meeting) => {
meeting?.join();
});
}, []); // don't add dependencies to execute just once

Expand All @@ -31,9 +29,8 @@ export default function App() {
return (
<DyteProvider value={meeting}>
<DyteParticipantsAudio meeting={meeting} />
<DyteDialogManager meeting={meeting} />
<DyteNotifications meeting={meeting} />
<MeetingProvider>
<DyteNotifications meeting={meeting} />
<Meeting />
</MeetingProvider>
</DyteProvider>
Expand Down
65 changes: 41 additions & 24 deletions samples/active-speaker-ui/src/components/Meeting.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,21 @@ import {
DytePluginMain,
DyteParticipants,
DyteParticipantsToggle,
DyteSetupScreen,
DyteStageToggle,
DyteDialogManager,
defaultIconPack,
} from '@dytesdk/react-ui-kit';
import { useContext } from 'react';
import { MeetingContext } from './MeetingContext';
import { DyteWaitingScreen } from '@dytesdk/react-ui-kit';

const HAND_RAISE_ICON = '<svg fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path d="M4 12.02c0 1.06.2 2.1.6 3.08l.6 1.42c.22.55.64 1.01 1.17 1.29.27.14.56.21.86.21h2.55c.77 0 1.49-.41 1.87-1.08.5-.87 1.02-1.7 1.72-2.43l1.32-1.39c.44-.46.97-.84 1.49-1.23l.59-.45a.6.6 0 0 0 .23-.47c0-.75-.54-1.57-1.22-1.79a3.34 3.34 0 0 0-2.78.29V4.5a1.5 1.5 0 0 0-2.05-1.4 1.5 1.5 0 0 0-2.9 0A1.5 1.5 0 0 0 6 4.5v.09A1.5 1.5 0 0 0 4 6v6.02ZM8 4.5v4a.5.5 0 0 0 1 0v-5a.5.5 0 0 1 1 0v5a.5.5 0 0 0 1 0v-4a.5.5 0 0 1 1 0v6a.5.5 0 0 0 .85.37h.01c.22-.22.44-.44.72-.58.7-.35 2.22-.57 2.4.5l-.53.4c-.52.4-1.04.78-1.48 1.24l-1.33 1.38c-.75.79-1.31 1.7-1.85 2.63-.21.36-.6.58-1.01.58H7.23a.87.87 0 0 1-.4-.1 1.55 1.55 0 0 1-.71-.78l-.59-1.42a7.09 7.09 0 0 1-.53-2.7V6a.5.5 0 0 1 1 0v3.5a.5.5 0 0 0 1 0v-5a.5.5 0 0 1 1 0Z" fill="currentColor"></path></svg>';

export default function Meeting() {
const {
meeting,
isHost,
states,
updateStates,
roomState,
Expand All @@ -36,23 +43,26 @@ export default function Meeting() {
breakpoint,
showSpotlight,
} = useContext(MeetingContext)!;

const iconSize = ['sm', 'md'].includes(breakpoint) ? 'sm' : 'md';
const showChat = states.sidebar === 'chat' || (
!states.activeSidebar && showSpotlight && !['sm', 'md'].includes(breakpoint)
);

const isMobile = ['sm', 'md'].includes(breakpoint);
const iconSize = isMobile ? 'sm' : 'md';
const showChat = states.sidebar === 'chat';
const showPolls = states.sidebar === 'polls';
const showPlugins = states.sidebar === 'plugins';
const showParticipants = states.sidebar === 'participants';
const showSidebar = showChat || showPolls || showPlugins || showParticipants;
const updatedIconPack = { ...defaultIconPack, join_stage: HAND_RAISE_ICON };

if (roomState === 'ended') {
return <main className="flex min-h-screen text-gray-50 items-center justify-center">Meeting ended</main>;
}

if (roomState === 'init') {
return <main className="flex min-h-screen text-gray-50 items-center justify-center">Joining...</main>;
return <main className="flex min-h-screen text-gray-50 items-center justify-center">
<DyteSetupScreen
meeting={meeting}
states={{ meeting: 'setup' }}
/>
</main>;
}

if (['left', 'kicked', 'disconnected', 'rejected'].includes(roomState)) {
Expand All @@ -68,30 +78,34 @@ export default function Meeting() {
}

return (
<main className="flex min-h-screen flex-row md:flex-col" ref={(el) => {
el?.addEventListener(
'dyteStateUpdate',
(e) => {
if (!(e instanceof CustomEvent)) return;
updateStates(e.detail);
},
);
}}>
<main
className="flex min-h-screen flex-row md:flex-col"
ref={(el) => {
el?.addEventListener(
'dyteStateUpdate',
(e) => {
if (!(e instanceof CustomEvent)) return;
updateStates(e.detail);
},
);
}}
>
<section className="flex flex-1 grow m-4 gap-4">
{ (isScreenShareEnabled && activeScreenshares.length === 1 && !isPluginsEnabled) ? (
{ ((showSidebar || isMobile) && isScreenShareEnabled && activeScreenshares.length === 1 && !isPluginsEnabled) ? (
<DyteScreenshareView className='h-auto' meeting={meeting} participant={activeScreenshares[0]} />
) : (isPluginsEnabled && !isScreenShareEnabled && activePlugins.length === 1 ) ? (
) : ((showSidebar || isMobile) && isPluginsEnabled && !isScreenShareEnabled && activePlugins.length === 1 ) ? (
<DytePluginMain className='h-auto' meeting={meeting} plugin={activePlugins[0]} />
) : (
<DyteGrid meeting={meeting} className='h-auto' />
<DyteGrid meeting={meeting} className='h-auto' states={states} />
)}

{(showSidebar) && <aside className="flex md:flex-col gap-4 w-80">
{showSidebar && <aside className="flex md:flex-col gap-4 w-80">
{showSpotlight && activeSpeaker && (
<div className='hidden md:flex'>
<DyteParticipantTile
participant={activeSpeaker}
meeting={meeting}
states={states}
size="md"
/>
</div>
Expand All @@ -107,6 +121,7 @@ export default function Meeting() {
className='h-[80px] w-[130px]'
participant={activeSpeaker}
meeting={meeting}
states={states}
size="sm"
/>
</div>
Expand All @@ -117,18 +132,20 @@ export default function Meeting() {
<DyteSettingsToggle size={iconSize} />
</div>
<div className='flex basis-1/3 justify-center flex-col md:flex-row'>
{!['sm', 'md'].includes(breakpoint) && <DyteScreenShareToggle meeting={meeting} size={iconSize} />}
{isHost && !isMobile && <DyteScreenShareToggle meeting={meeting} size={iconSize} />}
<DyteStageToggle meeting={meeting} size={iconSize} iconPack={updatedIconPack}/>
<DyteMicToggle meeting={meeting} size={iconSize} />
<DyteCameraToggle meeting={meeting} size={iconSize} />
<DyteLeaveButton size={iconSize}/>
<DyteLeaveButton size={iconSize} />
</div>
<div className='flex basis-1/3 justify-start flex-col md:flex-row md:justify-end'>
<DyteChatToggle meeting={meeting} size={iconSize} />
<DytePollsToggle meeting={meeting} size={iconSize} />
<DyteParticipantsToggle meeting={meeting} size={iconSize} />
{!['sm', 'md'].includes(breakpoint) && <DytePluginsToggle meeting={meeting} size={iconSize} />}
{isHost && <DyteParticipantsToggle meeting={meeting} size={iconSize} />}
{isHost && !isMobile && <DytePluginsToggle meeting={meeting} size={iconSize} />}
</div>
</footer>
<DyteDialogManager meeting={meeting} states={states} />
</main>
);
}
17 changes: 7 additions & 10 deletions samples/active-speaker-ui/src/components/MeetingContext.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
import React, { createContext, useReducer } from 'react';
import { useDyteMeeting, useDyteSelector } from '@dytesdk/react-web-core';
import { useThrottle } from '@uidotdev/usehooks';
// import { useThrottle } from '@uidotdev/usehooks';
import type { States } from '@dytesdk/ui-kit/dist/types';
import type { Peer, Size } from '@dytesdk/ui-kit';
import type { leaveRoomState, DytePlugin } from '@dytesdk/web-core';
import useBreakpoint from '../utils/breakpoint';

const ACTIVE_SPEAKER_CHANGE_DELAY = 3000;
// const ACTIVE_SPEAKER_CHANGE_DELAY = 3000;
type RoomState = 'init' | 'joined' | 'waitlisted' | leaveRoomState;
export interface ContextValue {
meeting: ReturnType<typeof useDyteMeeting>['meeting'];
isHost: boolean;
states: States;
breakpoint: Size;
roomState: RoomState;
Expand Down Expand Up @@ -37,6 +38,7 @@ const MeetingProvider = ({ children }: Props) => {
}),
{ meeting: 'joined' },
);

const roomState = useDyteSelector((meeting) => meeting.self.roomState as RoomState);
const activeScreenshares = useDyteSelector(
(meeting) =>
Expand All @@ -52,32 +54,27 @@ const MeetingProvider = ({ children }: Props) => {
const showSpotlight = activeScreenshares.length > 0 || activePlugins.length > 0;

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,
);

const activeSpeakerInternal = meeting.participants.active
.toArray()
.find((participant) =>
participant.id === lastActiveSpeaker
) ?? meeting.self;
const activeSpeaker = useThrottle(activeSpeakerInternal, ACTIVE_SPEAKER_CHANGE_DELAY);

return (
<MeetingContext.Provider
value={{
meeting,
states,
isHost: meeting.self.presetName === 'webinar_presenter',
updateStates,
roomState,
isScreenShareEnabled: activeScreenshares.length > 0,
isPluginsEnabled: activePlugins.length > 0,
activeScreenshares,
activePlugins,
activeSpeaker,
activeSpeaker: (meeting.participants.active.get(lastActiveSpeaker) ?? meeting.self) as Peer,
breakpoint,
showSpotlight,
requestCount,
Expand Down

0 comments on commit 0e1ae3d

Please sign in to comment.