Skip to content

Commit

Permalink
feat: add livekit meeting context and
Browse files Browse the repository at this point in the history
  • Loading branch information
moonrailgun committed Nov 18, 2023
1 parent 7e239ea commit c937178
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { useLivekitState } from '../store/useLivekitState';
import { useServerUrl } from '../utils/useServerUrl';
import { useToken } from '../utils/useToken';
import { VideoConference } from './lib/VideoConference';
import { MeetingContextProvider } from '../context/MeetingContext';

const UpdateRoom: React.FC = React.memo(() => {
const room = useRoomContext();
Expand Down Expand Up @@ -71,7 +72,9 @@ export const ActiveRoom: React.FC<ActiveRoomProps> = React.memo((props) => {
audio={userChoices.audioEnabled}
onDisconnected={onLeave}
>
<VideoConference chatMessageFormatter={formatChatMessageLinks} />
<MeetingContextProvider>
<VideoConference chatMessageFormatter={formatChatMessageLinks} />
</MeetingContextProvider>

<UpdateRoom />
</LiveKitRoom>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { Translate } from '../../translate';
import { useMediaQuery } from '../../utils/useMediaQuery';
import { ChatIcon } from './icons/ChatIcon';
import { LeaveIcon } from './icons/LeaveIcon';
import { useMeetingContextState } from '../../context/MeetingContext';

/** @public */
export type ControlBarControls = {
Expand Down Expand Up @@ -55,6 +56,7 @@ export function ControlBar({ variation, controls, ...props }: ControlBarProps) {
setIsChatOpen(layoutContext?.widget.state?.showChat);
}
}, [layoutContext?.widget.state?.showChat]);
const setRightPanel = useMeetingContextState((state) => state.setRightPanel);
const isTooLittleSpace = useMediaQuery(
`(max-width: ${isChatOpen ? 1000 : 760}px)`
);
Expand Down Expand Up @@ -134,10 +136,10 @@ export function ControlBar({ variation, controls, ...props }: ControlBarProps) {
)}

{visibleControls.chat && (
<ChatToggle>
<button className="lk-button" onClick={() => setRightPanel('chat')}>
{showIcon && <ChatIcon />}
{showText && Translate.chat}
</ChatToggle>
</button>
)}

{visibleControls.leave && (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import { CarouselLayout } from './CarouselLayout';
import { ControlBar } from './ControlBar';
import { Chat } from './Chat';
import { FocusLayout } from './FocusLayout';
import { useMeetingContextState } from '../../context/MeetingContext';

/**
* @public
Expand Down Expand Up @@ -60,6 +61,7 @@ export const VideoConference: React.FC<VideoConferenceProps> = React.memo(
});
const lastAutoFocusedScreenShareTrack =
React.useRef<TrackReferenceOrPlaceholder | null>(null);
const rightPanel = useMeetingContextState((state) => state.rightPanel);

const tracks = useTracks(
[
Expand Down Expand Up @@ -146,10 +148,9 @@ export const VideoConference: React.FC<VideoConferenceProps> = React.memo(
<ControlBar controls={{ chat: true }} />
</div>

<Chat
style={{ display: widgetState.showChat ? 'flex' : 'none' }}
messageFormatter={chatMessageFormatter}
/>
{rightPanel === 'chat' && (
<Chat messageFormatter={chatMessageFormatter} />
)}
</LayoutContextProvider>
)}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import React, { PropsWithChildren, useContext, useMemo } from 'react';
import {
MeetingState,
MeetingStateStoreType,
createMeetingStateStore,
} from '../store/meeting';
import { useStore } from 'zustand';

const MeetingContext = React.createContext<MeetingStateStoreType>(null);

export const MeetingContextProvider: React.FC<PropsWithChildren> = React.memo(
(props) => {
const store = useMemo(() => createMeetingStateStore(), []);

return (
<MeetingContext.Provider value={store}>
{props.children}
</MeetingContext.Provider>
);
}
);
MeetingContextProvider.displayName = 'MeetingContextProvider';

export function useMeetingContextState<T>(selector: (s: MeetingState) => T) {
const context = useContext(MeetingContext);

return useStore(context, selector);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { createStore } from 'zustand';
import { immer } from 'zustand/middleware/immer';

export interface MeetingState {
rightPanel: 'chat' | 'member' | null;
setRightPanel: (panel: 'chat' | 'member' | null) => void;
}

export function createMeetingStateStore() {
return createStore<MeetingState>()(
immer((set, get) => ({
rightPanel: null,
setRightPanel: (rightPanel) => {
if (get().rightPanel === rightPanel) {
// toggle
set({ rightPanel: null });
} else {
set({ rightPanel });
}
},
}))
);
}

export type MeetingStateStoreType = ReturnType<typeof createMeetingStateStore>;

0 comments on commit c937178

Please sign in to comment.