feat: add livekit meeting context and

chore/devcontainer
moonrailgun 1 year ago
parent 7e239ead86
commit c937178956

@ -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();
@ -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>

@ -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 = {
@ -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)`
);
@ -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 && (

@ -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
@ -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(
[
@ -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>
)}

@ -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);
}

@ -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>;
Loading…
Cancel
Save