display class state in the header

This commit is contained in:
harshithpabbati 2022-01-10 22:11:55 +05:30
parent 41b7f8e7e2
commit c052ff45a0
7 changed files with 90 additions and 78 deletions

View File

@ -5,9 +5,9 @@ import { useCallUI } from '@custom/shared/hooks/useCallUI';
import PropTypes from 'prop-types';
import { ChatProvider } from '../../contexts/ChatProvider';
import { ClassStateProvider } from '../../contexts/ClassStateProvider';
import { LiveStreamingProvider } from '../../contexts/LiveStreamingProvider';
import { RecordingProvider } from '../../contexts/RecordingProvider';
import { ViewProvider } from '../../contexts/ViewProvider';
import Room from '../Call/Room';
import { Asides } from './Asides';
import { Modals } from './Modals';
@ -28,7 +28,7 @@ export const App = ({ customComponentForState }) => {
<ChatProvider>
<RecordingProvider>
<LiveStreamingProvider>
<ViewProvider>
<ClassStateProvider>
{roomExp && <ExpiryTimer expiry={roomExp} />}
<div className="app">
{componentForState()}
@ -46,7 +46,7 @@ export const App = ({ customComponentForState }) => {
}
`}</style>
</div>
</ViewProvider>
</ClassStateProvider>
</LiveStreamingProvider>
</RecordingProvider>
</ChatProvider>

View File

@ -1,15 +1,44 @@
import React, { useMemo } from 'react';
import React, { useMemo, useCallback } from 'react';
import Button from '@custom/shared/components/Button';
import HeaderCapsule from '@custom/shared/components/HeaderCapsule';
import { useCallState } from '@custom/shared/contexts/CallProvider';
import { useParticipants } from '@custom/shared/contexts/ParticipantsProvider';
import { useUIState } from '@custom/shared/contexts/UIStateProvider';
import { ReactComponent as IconLock } from '@custom/shared/icons/lock-md.svg';
import { ReactComponent as IconPlay } from '@custom/shared/icons/play-sm.svg';
import { slugify } from '@custom/shared/lib/slugify';
import { useClassState, PRE_CLASS_LOBBY, CLASS_IN_SESSION } from '../../contexts/ClassStateProvider';
export const Header = () => {
const { roomInfo } = useCallState();
const { participantCount } = useParticipants();
const { participantCount, localParticipant } = useParticipants();
const { customCapsule } = useUIState();
const { classType, setClassType } = useClassState();
const capsuleLabel = useCallback(() => {
if (!localParticipant.isOwner) return;
if (classType === PRE_CLASS_LOBBY)
return (
<Button
IconBefore={IconPlay}
size="tiny"
variant="success"
onClick={setClassType}
>
Start Class
</Button>
)
if (classType === CLASS_IN_SESSION)
return (
<Button
size="tiny"
variant="error-light"
onClick={setClassType}
>
End Class
</Button>
)
}, [classType, localParticipant.isOwner, setClassType]);
return useMemo(
() => (
@ -37,6 +66,10 @@ export const Header = () => {
{customCapsule.label}
</HeaderCapsule>
)}
<HeaderCapsule>
{classType}
{capsuleLabel()}
</HeaderCapsule>
<style jsx>{`
.room-header {
@ -56,7 +89,7 @@ export const Header = () => {
`}</style>
</header>
),
[roomInfo.privacy, roomInfo.name, participantCount, customCapsule]
[roomInfo.privacy, roomInfo.name, participantCount, customCapsule, classType, capsuleLabel]
);
};

View File

@ -1,30 +0,0 @@
import React from 'react';
import { TrayButton } from '@custom/shared/components/Tray';
import { useParticipants } from '@custom/shared/contexts/ParticipantsProvider';
import { VIEW_MODE_GRID, VIEW_MODE_SPEAKER } from '@custom/shared/contexts/UIStateProvider';
import { ReactComponent as IconGridView } from '@custom/shared/icons/grid-md.svg';
import { ReactComponent as IconSpeakerView } from '@custom/shared/icons/speaker-view-md.svg';
import { useView } from '../../contexts/ViewProvider';
export const ViewTray = () => {
const { participants, localParticipant } = useParticipants();
const { view, setView } = useView();
const onViewClick = () =>
setView(view === VIEW_MODE_SPEAKER ? VIEW_MODE_GRID : VIEW_MODE_SPEAKER);
if (!localParticipant.isOwner) return null;
return (
<TrayButton
label={view === VIEW_MODE_GRID ? 'Speaker': 'Grid'}
disabled={participants.length < 2}
onClick={onViewClick}
>
{view === VIEW_MODE_SPEAKER ? <IconGridView />: <IconSpeakerView />}
</TrayButton>
);
};
export default ViewTray;

View File

@ -3,7 +3,6 @@ import ChatTray from './Chat';
import RecordTray from './Record';
import ScreenShareTray from './ScreenShare';
import StreamTray from './Stream';
import ViewTray from './View';
export const Tray = () => {
return (
@ -12,7 +11,6 @@ export const Tray = () => {
<ScreenShareTray />
<RecordTray />
<StreamTray />
<ViewTray />
</>
);
};

View File

@ -0,0 +1,48 @@
import React, {
createContext,
useContext,
useCallback,
useMemo,
useEffect,
} from 'react';
import { useUIState, VIEW_MODE_SPEAKER, VIEW_MODE_GRID } from '@custom/shared/contexts/UIStateProvider';
import { useSharedState } from '@custom/shared/hooks/useSharedState';
import PropTypes from 'prop-types';
export const PRE_CLASS_LOBBY = 'Pre-class lobby';
export const CLASS_IN_SESSION = 'Class-in session';
export const POST_CLASS_LOBBY = 'Post-class lobby';
export const ClassStateContext = createContext();
export const ClassStateProvider = ({ children }) => {
const { setPreferredViewMode } = useUIState();
const { sharedState, setSharedState } = useSharedState({
initialValues: { type: PRE_CLASS_LOBBY },
});
const classType = useMemo(() => sharedState.type, [sharedState.type]);
const setClassType = useCallback(() => {
if (sharedState.type === PRE_CLASS_LOBBY) setSharedState({ type: CLASS_IN_SESSION });
if (sharedState.type === CLASS_IN_SESSION) setSharedState({ type: POST_CLASS_LOBBY });
}, [sharedState.type, setSharedState]);
useEffect(() => {
if (sharedState.type === CLASS_IN_SESSION) setPreferredViewMode(VIEW_MODE_SPEAKER);
else setPreferredViewMode(VIEW_MODE_GRID);
}, [setPreferredViewMode, sharedState.type]);
return (
<ClassStateContext.Provider value={{ classType, setClassType }}>
{children}
</ClassStateContext.Provider>
);
};
ClassStateProvider.propTypes = {
children: PropTypes.node,
};
export const useClassState = () => useContext(ClassStateContext);

View File

@ -1,40 +0,0 @@
import React, {
createContext,
useContext,
useCallback,
useMemo,
useEffect,
} from 'react';
import { useUIState } from '@custom/shared/contexts/UIStateProvider';
import { useSharedState } from '@custom/shared/hooks/useSharedState';
import PropTypes from 'prop-types';
export const ViewContext = createContext();
export const ViewProvider = ({ children }) => {
const { viewMode, setPreferredViewMode } = useUIState();
const { sharedState, setSharedState } = useSharedState({
initialValues: { viewMode },
});
const view = useMemo(() => sharedState.viewMode, [sharedState.viewMode]);
const setView = useCallback((view) => setSharedState({ viewMode: view }), [setSharedState]);
useEffect(() => {
if (viewMode === sharedState.viewMode) return;
setPreferredViewMode(sharedState.viewMode);
}, [setPreferredViewMode, sharedState.viewMode, viewMode]);
return (
<ViewContext.Provider value={{ view, setView }}>
{children}
</ViewContext.Provider>
);
};
ViewProvider.propTypes = {
children: PropTypes.node,
};
export const useView = () => useContext(ViewContext);

View File

@ -0,0 +1,3 @@
<svg width="9" height="12" viewBox="0 0 9 12" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M0.783 0.0880035C0.707928 0.0364627 0.620207 0.00640194 0.529301 0.00106545C0.438396 -0.00427103 0.34776 0.0153194 0.267173 0.0577225C0.186587 0.100126 0.11911 0.163731 0.0720258 0.241675C0.0249413 0.319619 3.68967e-05 0.408942 0 0.500004V11.5C0.000167265 11.5911 0.02522 11.6804 0.0724523 11.7583C0.119685 11.8362 0.187301 11.8997 0.268 11.942C0.339356 11.9802 0.419063 12.0001 0.5 12C0.601059 11.9999 0.699728 11.9693 0.783 11.912L8.783 6.412C8.84983 6.36605 8.90447 6.30454 8.94222 6.23276C8.97998 6.16098 8.99971 6.0811 8.99971 6C8.99971 5.9189 8.97998 5.83902 8.94222 5.76725C8.90447 5.69547 8.84983 5.63395 8.783 5.588L0.783 0.0880035Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 768 B