Skip to content

Commit

Permalink
Merge pull request #28 from dyte-io/active-speaker-ui
Browse files Browse the repository at this point in the history
fix: bugs and added features
  • Loading branch information
vaibhavshn authored Jan 18, 2024
2 parents 62ff0fd + 58ea7e7 commit adf5154
Show file tree
Hide file tree
Showing 10 changed files with 203 additions and 68 deletions.
32 changes: 16 additions & 16 deletions package-lock.json

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

4 changes: 2 additions & 2 deletions samples/active-speaker-ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
"preview": "vite preview"
},
"dependencies": {
"@dytesdk/react-ui-kit": "^1.61.5-staging.1",
"@dytesdk/react-web-core": "^1.35.16-staging.1",
"@dytesdk/react-ui-kit": "^1.61.5-staging.3",
"@dytesdk/react-web-core": "^1.35.16-staging.2",
"clsx": "^2.1.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
Expand Down
11 changes: 10 additions & 1 deletion samples/active-speaker-ui/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import Meeting from './components/Meeting';
import { DyteSpinner } from '@dytesdk/react-ui-kit';
import { DyteProvider, useDyteClient } from '@dytesdk/react-web-core';
import { useEffect } from 'react';

Expand Down Expand Up @@ -32,7 +33,15 @@ function App() {
// To avoid that and to make it fill a parent container, pass the prop:
// `mode="fill"` to the component.
return (
<DyteProvider value={meeting}>
<DyteProvider
value={meeting}
fallback={
<div className="size-full flex flex-col gap-3 place-items-center justify-center">
<DyteSpinner className="w-12 h-12 text-blue-600" />
<p className="text-lg">Joining...</p>
</div>
}
>
<Meeting />
</DyteProvider>
);
Expand Down
6 changes: 4 additions & 2 deletions samples/active-speaker-ui/src/components/ActiveSpeaker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ import { useDyteMeeting } from '@dytesdk/react-web-core';
import { HTMLAttributes } from 'react';

export default function ActiveSpeaker(
props: Omit<HTMLAttributes<HTMLDyteParticipantTileElement>, 'style'>
props: Omit<HTMLAttributes<HTMLDyteParticipantTileElement>, 'style'> & {
isSmall?: true;
}
) {
const activeSpeaker = useActiveSpeaker();
const { meeting } = useDyteMeeting();
Expand All @@ -18,7 +20,7 @@ export default function ActiveSpeaker(
<DyteParticipantTile
participant={activeSpeaker}
meeting={meeting}
size={size}
size={props.isSmall ? 'sm' : size}
states={states}
{...props}
/>
Expand Down
77 changes: 62 additions & 15 deletions samples/active-speaker-ui/src/components/Controlbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,24 @@ import {
DytePollsToggle,
DyteChatToggle,
DytePluginsToggle,
defaultIconPack,
IconPack,
} from '@dytesdk/react-ui-kit';
import { useDyteMeeting } from '@dytesdk/react-web-core';

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>';

const iconPack: IconPack = {
...defaultIconPack,
join_stage: HAND_RAISE_ICON,
};

export default function Controlbar() {
const { meeting } = useDyteMeeting();
const size = useMeetingStore((s) => s.size);
const isMobile = useMeetingStore((s) => s.isMobile);
const states = useMeetingStore((s) => s.states);

const buttonSize = size === 'lg' ? 'lg' : 'sm';

Expand All @@ -28,24 +39,44 @@ export default function Controlbar() {
<div className="flex flex-col lg:flex-row items-center">
{isHost && (
<>
<DyteParticipantsToggle meeting={meeting} size={buttonSize} />
<DytePluginsToggle meeting={meeting} size={buttonSize} />
<DyteParticipantsToggle
meeting={meeting}
size={buttonSize}
states={states}
/>
<DytePluginsToggle
meeting={meeting}
size={buttonSize}
states={states}
/>
</>
)}
<DyteChatToggle meeting={meeting} size={buttonSize} />
<DytePollsToggle meeting={meeting} size={buttonSize} />
<DyteChatToggle meeting={meeting} size={buttonSize} states={states} />
<DytePollsToggle
meeting={meeting}
size={buttonSize}
states={states}
/>
</div>

<div className="flex flex-col lg:flex-row items-center justify-center">
<DyteMicToggle meeting={meeting} size={buttonSize} />
<DyteCameraToggle meeting={meeting} size={buttonSize} />
<DyteScreenShareToggle meeting={meeting} size={buttonSize} />
<DyteScreenShareToggle
meeting={meeting}
size={buttonSize}
states={states}
/>
</div>

<div className="flex flex-col lg:flex-row items-center">
<DyteStageToggle meeting={meeting} size={buttonSize} />
<div className="flex flex-col lg:flex-row items-center justify-end">
<DyteStageToggle
meeting={meeting}
size={buttonSize}
iconPack={isHost ? undefined : iconPack}
/>
<DyteLeaveButton size={buttonSize} />
<DyteSettingsToggle size={buttonSize} />
<DyteSettingsToggle size={buttonSize} states={states} />
</div>
</>
);
Expand All @@ -54,12 +85,20 @@ export default function Controlbar() {
return (
<>
<div className="flex flex-col lg:flex-row items-center">
<DyteSettingsToggle size={buttonSize} />
<DyteScreenShareToggle meeting={meeting} size={buttonSize} />
<DyteSettingsToggle size={buttonSize} states={states} />
<DyteScreenShareToggle
meeting={meeting}
size={buttonSize}
states={states}
/>
</div>

<div className="flex flex-col lg:flex-row items-center justify-center">
<DyteStageToggle meeting={meeting} size={buttonSize} />
<DyteStageToggle
meeting={meeting}
size={buttonSize}
iconPack={isHost ? undefined : iconPack}
/>
<DyteMicToggle meeting={meeting} size={buttonSize} />
<DyteCameraToggle meeting={meeting} size={buttonSize} />
<DyteLeaveButton size={buttonSize} />
Expand All @@ -68,12 +107,20 @@ export default function Controlbar() {
<div className="flex flex-col lg:flex-row items-center justify-end">
{isHost && (
<>
<DyteParticipantsToggle meeting={meeting} size={buttonSize} />
<DytePluginsToggle meeting={meeting} size={buttonSize} />
<DyteParticipantsToggle
meeting={meeting}
size={buttonSize}
states={states}
/>
<DytePluginsToggle
meeting={meeting}
size={buttonSize}
states={states}
/>
</>
)}
<DyteChatToggle meeting={meeting} size={buttonSize} />
<DytePollsToggle meeting={meeting} size={buttonSize} />
<DyteChatToggle meeting={meeting} size={buttonSize} states={states} />
<DytePollsToggle meeting={meeting} size={buttonSize} states={states} />
</div>
</>
);
Expand Down
44 changes: 44 additions & 0 deletions samples/active-speaker-ui/src/components/Grid.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { useMeetingStore } from '../lib/meeting-store';
import {
DyteGrid,
DyteSimpleGrid,
DyteSpotlightGrid,
} from '@dytesdk/react-ui-kit';
import { useDyteMeeting, useDyteSelector } from '@dytesdk/react-web-core';

export default function Grid() {
const { meeting } = useDyteMeeting();

const size = useMeetingStore((s) => s.size);
const stageStatus = useDyteSelector((m) => m.stage.status);
const isPinned = useDyteSelector((m) => m.self.isPinned);

const activeParticipants = useDyteSelector((m) =>
m.participants.active.toArray()
);

const participants =
stageStatus === 'ON_STAGE' && !isPinned
? [...activeParticipants, meeting.self]
: activeParticipants;

const pinned = useDyteSelector((m) => m.participants.pinned.toArray());

const pinnedParticipants =
isPinned && stageStatus === 'ON_STAGE' ? [...pinned, meeting.self] : pinned;

if (pinnedParticipants.length > 0) {
return (
<DyteSpotlightGrid
participants={participants}
pinnedParticipants={pinnedParticipants}
meeting={meeting}
size={size}
/>
);
}

return (
<DyteSimpleGrid participants={participants} meeting={meeting} size={size} />
);
}
9 changes: 6 additions & 3 deletions samples/active-speaker-ui/src/components/MainArea.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
import { useDyteMeeting, useDyteSelector } from '@dytesdk/react-web-core';
import type { DyteParticipant, DytePlugin, DyteSelf } from '@dytesdk/web-core';
import clsx from 'clsx';
import { useState, useEffect } from 'react';
import { useState, useEffect, useRef } from 'react';

function ActiveSpeakerView({
screenshares,
Expand Down Expand Up @@ -130,7 +130,7 @@ function ActiveSpeakerView({
size={size}
variant="secondary"
kind="icon"
className="absolute bottom-3 right-3 z-10"
className="absolute bottom-3 right-3 z-40"
onClick={() => {
toggleImmersiveMode();
}}
Expand Down Expand Up @@ -198,7 +198,10 @@ export default function MainArea() {
)}

{isMobile && (
<ActiveSpeaker className="absolute bottom-3 left-3 w-36 z-50 h-auto aspect-square" />
<ActiveSpeaker
className="absolute bottom-3 left-3 w-24 z-50 h-auto aspect-square"
isSmall
/>
)}
</div>
);
Expand Down
15 changes: 8 additions & 7 deletions samples/active-speaker-ui/src/components/Meeting.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,10 @@ function UI() {
<div className="flex flex-1 h-full">
<main className="flex-[2]">
<MainArea />
<DyteParticipantsAudio meeting={meeting} className="" />
<DyteParticipantsAudio meeting={meeting} />
</main>
{!isImmersiveMode && (
<aside className="flex-1 lg:flex-auto lg:w-full lg:max-w-sm -ml-2">
<Sidebar />
</aside>
)}

{!isImmersiveMode && <Sidebar />}
</div>

<div className="grid p-2 pl-0 lg:pl-2 grid-rows-3 lg:grid-rows-1 lg:grid-cols-3 lg:pt-0">
Expand Down Expand Up @@ -95,7 +92,11 @@ export default function Meeting() {
return (
<div className="w-full h-full bg-black" ref={$parent} data-size={size}>
{children}
<DyteDialogManager meeting={meeting} states={states} />
<DyteDialogManager
size={size === 'lg' ? 'lg' : 'sm'}
meeting={meeting}
states={states}
/>
</div>
);
}
Loading

0 comments on commit adf5154

Please sign in to comment.