Skip to content

Commit

Permalink
Feat: Settings Component Integration (#2828)
Browse files Browse the repository at this point in the history
* feat: add settings in meet livekit

* fix: remove this method settingsCloseButton in file css

---------

Co-authored-by: Ruslan Konviser <[email protected]>
  • Loading branch information
Innocent-Akim and evereq authored Aug 4, 2024
1 parent 56cafad commit e79eb6d
Show file tree
Hide file tree
Showing 11 changed files with 249 additions and 34 deletions.
1 change: 1 addition & 0 deletions .cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,7 @@
"sentryclirc",
"setrole",
"Settingfilter",
"settingsCloseButton",
"setuptools",
"setwin",
"setwork",
Expand Down
6 changes: 4 additions & 2 deletions apps/web/app/[locale]/meet/livekit/component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,15 @@ function LiveKitPage() {
const params = useSearchParams();

const onLeave = useCallback(() => {
window.localStorage.removeItem('current-room-live-kit');
router.push('/');
}, [router]);

useEffect(() => {
const room = params.get("roomName");
if (room) {
setRoomName(room);
window.localStorage.setItem('current-room-live-kit', room);
}
}, [params]);

Expand All @@ -36,7 +38,7 @@ function LiveKitPage() {
});

return (
<>
<div >
<Meta title="Meet" />
{token && roomName && <LiveKit
token={token!}
Expand All @@ -51,7 +53,7 @@ function LiveKitPage() {
videoDeviceId: ''
}}
/>}
</>
</div>
);
}

Expand Down
19 changes: 11 additions & 8 deletions apps/web/components/shared/collaborate/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,15 @@ const Collaborate = () => {
[collaborativeMembers, members, setCollaborativeMembers]
);

const handleAction = (actionCallback: () => void) => () => {
closeModal();
actionCallback();
};

const handleMeetClick = handleAction(onMeetClick);
const handleBoardClick = handleAction(onBoardClick);


return (
<div>
<JitsuAnalytics user={user} />
Expand Down Expand Up @@ -197,10 +206,7 @@ const Collaborate = () => {

<div className="flex space-x-3 ">
<Button
onClick={() => {
closeModal();
onMeetClick();
}}
onClick={handleMeetClick}
className={clsxm('rounded-xl flex min-w-0 w-28 h-12', 'gap-1 items-center')}
variant="outline"
>
Expand All @@ -209,10 +215,7 @@ const Collaborate = () => {
</Button>

<Button
onClick={() => {
closeModal();
onBoardClick();
}}
onClick={handleBoardClick}
className={clsxm('rounded-xl flex min-w-0 w-28 h-12', 'gap-1 items-center')}
>
<BrushSquareIcon className="w-4 h-4" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,12 @@ export function DailyPlanCompareEstimatedModal({

return (
<Modal isOpen={open} closeModal={closeModal}>
<div className="w-[98%] md:w-[550px] relative">
<Card className="w-full h-[620px] flex flex-col justify-start bg-gray-50" shadow="custom">
<div className="flex flex-col items-center justify-between">
<div className='w-[98%] md:w-[550px] relative'>
<Card className="w-full h-[620px] flex flex-col justify-start bg-gray-50" shadow='custom'>
<div className='flex flex-col items-center justify-between'>
<DailyPlanCompareHeader />
</div>
<div className="flex items-start flex-col justify-start w-full px-2">
<div className='flex items-start flex-col justify-start w-full px-2'>
<TimePicker
defaultValue={{
hours: hour,
Expand All @@ -69,29 +69,31 @@ export function DailyPlanCompareEstimatedModal({
/>
<DailyPlanWorkTimeInput />
</div>
<div className="flex h-full w-full p-2">

<ScrollArea className='flex h-full w-full p-2 flex-col'>
{todayPlan.map((plan, i) => {
return (
<div key={i}>
{plan.tasks?.map((data, index) => {
return (
<div key={index} className="p-1">
<DailyPlanTask key={index} task={data} profile={profile} />
</div>
);
})}
</div>
);
return <div key={i}>
{plan.tasks?.map((data, index) => {
return <div key={index} className='p-1'>
<DailyPlanTask
key={index}
task={data}
profile={profile}
/>
</div>
})}
</div>
})}
</div>
<div className="flex flex-col">
<div className="flex items-center pb-2 text-red-500 text-[12px]">
</ScrollArea>
<div className='flex flex-col'>
<div className='flex items-center pb-2 text-red-500 text-[12px]'>
{!difference && !estimated?.every(Boolean) && (
<>
<PiWarningCircleFill className="text-[14px]" />
<PiWarningCircleFill className='text-[14px]' />
<span>Please correct planned work hours or re-estimate task(s)</span>
</>
)}
)
}
</div>
<DailyPlanCompareActionButton
loading={updateDailyPlanLoading}
Expand All @@ -105,6 +107,7 @@ export function DailyPlanCompareEstimatedModal({
</Modal>
);
}

export function DailyPlanTask({ task, profile }: { task?: ITeamTask; profile: any }) {
const taskEdition = useTMCardTaskEdit(task);
const member = task?.selectedTeam?.members.find((member) => {
Expand Down
5 changes: 3 additions & 2 deletions apps/web/lib/features/integrations/livekit/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
} from '@livekit/components-react';
import { RoomConnectOptions } from 'livekit-client';
import "@livekit/components-styles";
import { SettingsMenu } from './settings-livekit';

type ActiveRoomProps = {
userChoices: LocalUserChoices;
Expand All @@ -30,7 +31,7 @@ export default function LiveKitPage({
const LiveKitRoomComponent = LiveKitRoom as React.ElementType;
return (
<LiveKitRoomComponent
className='!bg-dark--theme-light'
className='!bg-light--theme-dark dark:!bg-dark--theme-light'
connectOptions={connectOptions}
audio={userChoices.audioEnabled}
video={userChoices.videoEnabled}
Expand All @@ -43,7 +44,7 @@ export default function LiveKitPage({
>
<VideoConference
chatMessageFormatter={formatChatMessageLinks}
SettingsComponent={undefined} // or provide an actual component if needed
SettingsComponent={SettingsMenu}
/>
</LiveKitRoomComponent>
);
Expand Down
172 changes: 172 additions & 0 deletions apps/web/lib/features/integrations/livekit/settings-livekit.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
'use client';
import * as React from 'react';
import { LocalAudioTrack, Track } from 'livekit-client';
import {
useMaybeLayoutContext,
useLocalParticipant,
MediaDeviceMenu,
TrackToggle,

} from '@livekit/components-react';
import { Button } from '@components/ui/button';
import { GoCopy } from "react-icons/go";
import styles from '../../../../styles/settings.module.css'
import { shortenLink } from 'lib/utils';
import { BiLoaderCircle } from "react-icons/bi";



export interface SettingsMenuProps extends React.HTMLAttributes<HTMLDivElement> { }

export function SettingsMenu(props: SettingsMenuProps) {
const layoutContext = useMaybeLayoutContext();
const [copied, setCopied] = React.useState<boolean>(false);

const getTeamLink = React.useCallback(() => {
if (typeof window !== 'undefined') {
return `${window.location.origin}/meet/livekit?roomName=${window.localStorage.getItem('current-room-live-kit')}`;
}
return '';
}, []);

const settings = React.useMemo(() => {
return {
media: { camera: true, microphone: true, label: 'Media Devices', speaker: true },
effects: { label: 'Effects' },
};
}, []);

const tabs = React.useMemo(
() => Object.keys(settings) as Array<keyof typeof settings>,
[settings],
);
const { microphoneTrack } = useLocalParticipant();
const [activeTab, setActiveTab] = React.useState(tabs[0]);
const [isNoiseFilterEnabled, setIsNoiseFilterEnabled] = React.useState(true);
React.useEffect(() => {
const micPublication = microphoneTrack;
if (micPublication && micPublication.track instanceof LocalAudioTrack) {
const currentProcessor = micPublication.track.getProcessor();
if (currentProcessor && !isNoiseFilterEnabled) {
micPublication.track.stopProcessor();
} else if (!currentProcessor && isNoiseFilterEnabled) {
import('@livekit/krisp-noise-filter')

Check warning on line 53 in apps/web/lib/features/integrations/livekit/settings-livekit.tsx

View workflow job for this annotation

GitHub Actions / Cspell

Unknown word (krisp)
.then(({ KrispNoiseFilter, isKrispNoiseFilterSupported }) => {

Check warning on line 54 in apps/web/lib/features/integrations/livekit/settings-livekit.tsx

View workflow job for this annotation

GitHub Actions / Cspell

Unknown word (Krisp)

Check warning on line 54 in apps/web/lib/features/integrations/livekit/settings-livekit.tsx

View workflow job for this annotation

GitHub Actions / Cspell

Unknown word (Krisp)
if (!isKrispNoiseFilterSupported()) {

Check warning on line 55 in apps/web/lib/features/integrations/livekit/settings-livekit.tsx

View workflow job for this annotation

GitHub Actions / Cspell

Unknown word (Krisp)
console.error('Enhanced noise filter is not supported for this browser');
setIsNoiseFilterEnabled(false);
return;
}
micPublication?.track
// @ts-ignore
?.setProcessor(KrispNoiseFilter())

Check warning on line 62 in apps/web/lib/features/integrations/livekit/settings-livekit.tsx

View workflow job for this annotation

GitHub Actions / Cspell

Unknown word (Krisp)
.then(() => console.log('successfully set noise filter'));
})
.catch((e) => console.error('Failed to load noise filter', e));
}
}
}, [isNoiseFilterEnabled, microphoneTrack]);

return (
<div className="bg-light--theme-light dark:bg-dark--theme-light indent-0 inset-0 items-center justify-cent fixed" style={{ width: '100%', height: '100%' }} {...props}>
<div className={`${styles.tabs} p-5`}>
{tabs.map(
(tab) =>
settings[tab] && (
<button
className={`${styles.tab} lk-button`}
key={tab}
onClick={() => setActiveTab(tab)}
aria-pressed={tab === activeTab}>
{
// @ts-ignore
settings[tab].label
}
</button>
),
)}
</div>
<div className="tab-content p-5">
{activeTab === 'media' && (
<>
{settings.media && settings.media.camera && (
<>
<h3>Camera</h3>
<section className="lk-button-group">
<TrackToggle source={Track.Source.Camera}>Camera</TrackToggle>
<div className="lk-button-group-menu">
<MediaDeviceMenu kind="videoinput" />
</div>
</section>
</>
)}
{settings.media && settings.media.microphone && (
<>
<h3>Microphone</h3>
<section className="lk-button-group">
<TrackToggle source={Track.Source.Microphone}>Microphone</TrackToggle>
<div className="lk-button-group-menu">
<MediaDeviceMenu kind="audioinput" />
</div>
</section>
</>
)}
{settings.media && settings.media.speaker && (
<>
<h3>Speaker & Headphones</h3>
<section className="lk-button-group">
<span className="lk-button">Audio Output</span>
<div className="lk-button-group-menu">
<MediaDeviceMenu kind="audiooutput"></MediaDeviceMenu>
</div>
</section>
</>
)}
</>
)}
{activeTab === 'effects' && (
<>
<h3>Audio</h3>
<section>
<label htmlFor="noise-filter"> Enhanced Noise Cancellation</label>
<input
type="checkbox"
id="noise-filter"
onChange={(ev) => setIsNoiseFilterEnabled(ev.target.checked)}
checked={isNoiseFilterEnabled}
></input>
</section>
</>
)}
</div>
<div style={{
position: 'absolute',
right: 'var(--lk-grid-gap)',
bottom: 'var(--lk-grid-gap)'
}} className={`flex items-center w-full justify-between`}>
<div className='flex items-start flex-col'>
<span className='px-7 text-gray-600 dark:text-gray-400'>You can invite your colleagues to join the meeting by sharing this link.</span>
<button
className='px-7 text-primary-light flex items-center'
onClick={() => {
navigator.clipboard.writeText(getTeamLink());
setCopied(true);
setTimeout(() => {
setCopied(false);
}, 1000 * 10 /** 10 Seconds */);
}} >
{copied ? < BiLoaderCircle className='animate-spine' /> : <GoCopy />}
{shortenLink(getTeamLink())}
</button>
</div>

<Button
className={`lk-button !bg-primary`}
onClick={() => layoutContext?.widget.dispatch?.({ msg: 'toggle_settings' })}
>
Close
</Button>
</div>
</div>
);
}
9 changes: 9 additions & 0 deletions apps/web/lib/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,12 @@ export function chunk<T>(array: T[], size: number): T[][] {

return result;
}

export const shortenLink = (value: any): string => {
if (typeof value !== 'string' || value.length <= 19) {
return value;
}
const start = value.substring(0, window.location.origin.length);
const end = value.substring(value.length - 10);
return `${start}...${end}`;
};
1 change: 1 addition & 0 deletions apps/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
"@jitsu/jitsu-react": "^1.3.0",
"@livekit/components-react": "^2.4.1",
"@livekit/components-styles": "^1.0.12",
"@livekit/krisp-noise-filter": "^0.2.5",

Check warning on line 38 in apps/web/package.json

View workflow job for this annotation

GitHub Actions / Cspell

Unknown word (krisp)
"@nivo/calendar": "^0.87.0",
"@nivo/core": "^0.87.0",
"@opentelemetry/api": "^1.7.0",
Expand Down
17 changes: 17 additions & 0 deletions apps/web/styles/settings.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
.tabs {
position: relative;
display: flex;
align-content: space-between;
}

.tabs>.tab {
padding: 0.5rem;
border-radius: 0;
padding-bottom: 0.5rem;
border-bottom: 3px solid;
border-color: var(--bg5);
}

.tabs>.tab[aria-pressed='true'] {
border-color: #3826a6;
}
Loading

0 comments on commit e79eb6d

Please sign in to comment.