abstracted tray and added ability to pass custom component
This commit is contained in:
parent
9b79d2a510
commit
dadd8c6d2b
|
|
@ -8,11 +8,11 @@ import { Asides } from './Asides';
|
||||||
import { Modals } from './Modals';
|
import { Modals } from './Modals';
|
||||||
|
|
||||||
export const App = () => {
|
export const App = () => {
|
||||||
const { state, leave } = useCallState();
|
const { state } = useCallState();
|
||||||
|
|
||||||
const componentForState = useCallUI({
|
const componentForState = useCallUI({
|
||||||
state,
|
state,
|
||||||
room: () => <Room onLeave={() => leave()} />,
|
room: () => <Room />,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Memoize children to avoid unnecassary renders from HOC
|
// Memoize children to avoid unnecassary renders from HOC
|
||||||
|
|
|
||||||
|
|
@ -1,48 +1,23 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Audio } from '@dailyjs/shared/components/Audio';
|
import { Audio } from '@dailyjs/shared/components/Audio';
|
||||||
import { Tray, TrayButton } from '@dailyjs/shared/components/Tray';
|
import { BasicTray } from '@dailyjs/shared/components/Tray';
|
||||||
import {
|
import {
|
||||||
WaitingRoomModal,
|
WaitingRoomModal,
|
||||||
WaitingRoomNotification,
|
WaitingRoomNotification,
|
||||||
} from '@dailyjs/shared/components/WaitingRoom';
|
} from '@dailyjs/shared/components/WaitingRoom';
|
||||||
import { useCallState } from '@dailyjs/shared/contexts/CallProvider';
|
|
||||||
import { useMediaDevices } from '@dailyjs/shared/contexts/MediaDeviceProvider';
|
|
||||||
import { useParticipants } from '@dailyjs/shared/contexts/ParticipantsProvider';
|
import { useParticipants } from '@dailyjs/shared/contexts/ParticipantsProvider';
|
||||||
import { useUIState } from '@dailyjs/shared/contexts/UIStateProvider';
|
|
||||||
import { useWaitingRoom } from '@dailyjs/shared/contexts/WaitingRoomProvider';
|
import { useWaitingRoom } from '@dailyjs/shared/contexts/WaitingRoomProvider';
|
||||||
import useJoinSound from '@dailyjs/shared/hooks/useJoinSound';
|
import useJoinSound from '@dailyjs/shared/hooks/useJoinSound';
|
||||||
import { ReactComponent as IconCameraOff } from '@dailyjs/shared/icons/camera-off-md.svg';
|
|
||||||
import { ReactComponent as IconCameraOn } from '@dailyjs/shared/icons/camera-on-md.svg';
|
|
||||||
import { ReactComponent as IconLeave } from '@dailyjs/shared/icons/leave-md.svg';
|
|
||||||
import { ReactComponent as IconMicOff } from '@dailyjs/shared/icons/mic-off-md.svg';
|
|
||||||
import { ReactComponent as IconMicOn } from '@dailyjs/shared/icons/mic-on-md.svg';
|
|
||||||
import { ReactComponent as IconPeople } from '@dailyjs/shared/icons/people-md.svg';
|
|
||||||
import { ReactComponent as IconSettings } from '@dailyjs/shared/icons/settings-md.svg';
|
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
|
|
||||||
import { PEOPLE_ASIDE } from '../../../shared/components/Aside/PeopleAside';
|
|
||||||
import { VideoGrid } from '../VideoGrid';
|
import { VideoGrid } from '../VideoGrid';
|
||||||
import { Header } from './Header';
|
import { Header } from './Header';
|
||||||
|
|
||||||
export const Room = ({ onLeave }) => {
|
export const Room = () => {
|
||||||
const { callObject } = useCallState();
|
|
||||||
const { setShowDeviceModal, setShowAside } = useUIState();
|
|
||||||
const { isCamMuted, isMicMuted } = useMediaDevices();
|
|
||||||
const { setShowModal, showModal } = useWaitingRoom();
|
const { setShowModal, showModal } = useWaitingRoom();
|
||||||
const { localParticipant } = useParticipants();
|
const { localParticipant } = useParticipants();
|
||||||
|
|
||||||
useJoinSound();
|
useJoinSound();
|
||||||
|
|
||||||
const toggleCamera = (newState) => {
|
|
||||||
if (!callObject) return false;
|
|
||||||
return callObject.setLocalVideo(newState);
|
|
||||||
};
|
|
||||||
|
|
||||||
const toggleMic = (newState) => {
|
|
||||||
if (!callObject) return false;
|
|
||||||
return callObject.setLocalAudio(newState);
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="room">
|
<div className="room">
|
||||||
<Header />
|
<Header />
|
||||||
|
|
@ -61,39 +36,7 @@ export const Room = ({ onLeave }) => {
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<Tray>
|
<BasicTray />
|
||||||
<TrayButton
|
|
||||||
label="Camera"
|
|
||||||
onClick={() => toggleCamera(isCamMuted)}
|
|
||||||
orange={isCamMuted}
|
|
||||||
>
|
|
||||||
{isCamMuted ? <IconCameraOff /> : <IconCameraOn />}
|
|
||||||
</TrayButton>
|
|
||||||
<TrayButton
|
|
||||||
label="Mic"
|
|
||||||
onClick={() => toggleMic(isMicMuted)}
|
|
||||||
orange={isMicMuted}
|
|
||||||
>
|
|
||||||
{isMicMuted ? <IconMicOff /> : <IconMicOn />}
|
|
||||||
</TrayButton>
|
|
||||||
<TrayButton label="Settings" onClick={() => setShowDeviceModal(true)}>
|
|
||||||
<IconSettings />
|
|
||||||
</TrayButton>
|
|
||||||
|
|
||||||
<TrayButton
|
|
||||||
label="People"
|
|
||||||
onClick={() => setShowAside((p) => (p ? null : PEOPLE_ASIDE))}
|
|
||||||
>
|
|
||||||
<IconPeople />
|
|
||||||
</TrayButton>
|
|
||||||
|
|
||||||
<span className="divider" />
|
|
||||||
|
|
||||||
<TrayButton label="Leave" onClick={onLeave} orange>
|
|
||||||
<IconLeave />
|
|
||||||
</TrayButton>
|
|
||||||
</Tray>
|
|
||||||
|
|
||||||
<Audio />
|
<Audio />
|
||||||
|
|
||||||
<style jsx>{`
|
<style jsx>{`
|
||||||
|
|
@ -118,8 +61,4 @@ export const Room = ({ onLeave }) => {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
Room.propTypes = {
|
|
||||||
onLeave: PropTypes.func.isRequired,
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Room;
|
export default Room;
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,11 @@ function App({ Component, pageProps }) {
|
||||||
</Head>
|
</Head>
|
||||||
<GlobalHead />
|
<GlobalHead />
|
||||||
<GlobalStyle />
|
<GlobalStyle />
|
||||||
<Component asides={App.asides} {...pageProps} />
|
<Component
|
||||||
|
asides={App.asides}
|
||||||
|
customTrayComponent={App.customTrayComponent}
|
||||||
|
{...pageProps}
|
||||||
|
/>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -28,5 +32,6 @@ App.propTypes = {
|
||||||
};
|
};
|
||||||
|
|
||||||
App.asides = [];
|
App.asides = [];
|
||||||
|
App.customTrayComponent = null;
|
||||||
|
|
||||||
export default App;
|
export default App;
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,12 @@ import { Intro, NotConfigured } from '../components/Intro';
|
||||||
* - Set call owner status
|
* - Set call owner status
|
||||||
* - Finally, renders the main application loop
|
* - Finally, renders the main application loop
|
||||||
*/
|
*/
|
||||||
export default function Index({ domain, isConfigured = false, asides }) {
|
export default function Index({
|
||||||
|
domain,
|
||||||
|
isConfigured = false,
|
||||||
|
asides,
|
||||||
|
customTrayComponent,
|
||||||
|
}) {
|
||||||
const [roomName, setRoomName] = useState('');
|
const [roomName, setRoomName] = useState('');
|
||||||
const [fetchingToken, setFetchingToken] = useState(false);
|
const [fetchingToken, setFetchingToken] = useState(false);
|
||||||
const [token, setToken] = useState();
|
const [token, setToken] = useState();
|
||||||
|
|
@ -92,7 +97,7 @@ export default function Index({ domain, isConfigured = false, asides }) {
|
||||||
* Main call UI
|
* Main call UI
|
||||||
*/
|
*/
|
||||||
return (
|
return (
|
||||||
<UIStateProvider asides={asides}>
|
<UIStateProvider asides={asides} customTrayComponent={customTrayComponent}>
|
||||||
<CallProvider domain={domain} room={roomName} token={token}>
|
<CallProvider domain={domain} room={roomName} token={token}>
|
||||||
<ParticipantsProvider>
|
<ParticipantsProvider>
|
||||||
<TracksProvider>
|
<TracksProvider>
|
||||||
|
|
@ -112,6 +117,7 @@ Index.propTypes = {
|
||||||
isConfigured: PropTypes.bool.isRequired,
|
isConfigured: PropTypes.bool.isRequired,
|
||||||
domain: PropTypes.string,
|
domain: PropTypes.string,
|
||||||
asides: PropTypes.arrayOf(PropTypes.func),
|
asides: PropTypes.arrayOf(PropTypes.func),
|
||||||
|
customTrayComponent: PropTypes.node,
|
||||||
};
|
};
|
||||||
|
|
||||||
export async function getStaticProps() {
|
export async function getStaticProps() {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,68 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { PEOPLE_ASIDE } from '@dailyjs/shared/components/Aside/PeopleAside';
|
||||||
|
import { useCallState } from '@dailyjs/shared/contexts/CallProvider';
|
||||||
|
import { useMediaDevices } from '@dailyjs/shared/contexts/MediaDeviceProvider';
|
||||||
|
import { useUIState } from '@dailyjs/shared/contexts/UIStateProvider';
|
||||||
|
import { ReactComponent as IconCameraOff } from '@dailyjs/shared/icons/camera-off-md.svg';
|
||||||
|
import { ReactComponent as IconCameraOn } from '@dailyjs/shared/icons/camera-on-md.svg';
|
||||||
|
import { ReactComponent as IconLeave } from '@dailyjs/shared/icons/leave-md.svg';
|
||||||
|
import { ReactComponent as IconMicOff } from '@dailyjs/shared/icons/mic-off-md.svg';
|
||||||
|
import { ReactComponent as IconMicOn } from '@dailyjs/shared/icons/mic-on-md.svg';
|
||||||
|
import { ReactComponent as IconPeople } from '@dailyjs/shared/icons/people-md.svg';
|
||||||
|
import { ReactComponent as IconSettings } from '@dailyjs/shared/icons/settings-md.svg';
|
||||||
|
import { Tray, TrayButton } from './Tray';
|
||||||
|
|
||||||
|
export const BasicTray = () => {
|
||||||
|
const { callObject, leave } = useCallState();
|
||||||
|
const { customTrayComponent, setShowDeviceModal, setShowAside } =
|
||||||
|
useUIState();
|
||||||
|
const { isCamMuted, isMicMuted } = useMediaDevices();
|
||||||
|
|
||||||
|
const toggleCamera = (newState) => {
|
||||||
|
if (!callObject) return false;
|
||||||
|
return callObject.setLocalVideo(newState);
|
||||||
|
};
|
||||||
|
|
||||||
|
const toggleMic = (newState) => {
|
||||||
|
if (!callObject) return false;
|
||||||
|
return callObject.setLocalAudio(newState);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Tray>
|
||||||
|
<TrayButton
|
||||||
|
label="Camera"
|
||||||
|
onClick={() => toggleCamera(isCamMuted)}
|
||||||
|
orange={isCamMuted}
|
||||||
|
>
|
||||||
|
{isCamMuted ? <IconCameraOff /> : <IconCameraOn />}
|
||||||
|
</TrayButton>
|
||||||
|
<TrayButton
|
||||||
|
label="Mic"
|
||||||
|
onClick={() => toggleMic(isMicMuted)}
|
||||||
|
orange={isMicMuted}
|
||||||
|
>
|
||||||
|
{isMicMuted ? <IconMicOff /> : <IconMicOn />}
|
||||||
|
</TrayButton>
|
||||||
|
<TrayButton label="Settings" onClick={() => setShowDeviceModal(true)}>
|
||||||
|
<IconSettings />
|
||||||
|
</TrayButton>
|
||||||
|
|
||||||
|
<TrayButton
|
||||||
|
label="People"
|
||||||
|
onClick={() => setShowAside((p) => (p ? null : PEOPLE_ASIDE))}
|
||||||
|
>
|
||||||
|
<IconPeople />
|
||||||
|
</TrayButton>
|
||||||
|
|
||||||
|
{customTrayComponent}
|
||||||
|
|
||||||
|
<span className="divider" />
|
||||||
|
|
||||||
|
<TrayButton label="Leave" onClick={() => leave()} orange>
|
||||||
|
<IconLeave />
|
||||||
|
</TrayButton>
|
||||||
|
</Tray>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
export default BasicTray;
|
||||||
|
|
@ -1,2 +1,3 @@
|
||||||
export { Tray as default } from './Tray';
|
export { Tray as default } from './Tray';
|
||||||
export { Tray, TrayButton } from './Tray';
|
export { Tray, TrayButton } from './Tray';
|
||||||
|
export { BasicTray } from './BasicTray';
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
|
||||||
|
|
||||||
export const UIStateContext = createContext();
|
export const UIStateContext = createContext();
|
||||||
|
|
||||||
export const UIStateProvider = ({ asides, children }) => {
|
export const UIStateProvider = ({ asides, customTrayComponent, children }) => {
|
||||||
const [showDeviceModal, setShowDeviceModal] = useState(false);
|
const [showDeviceModal, setShowDeviceModal] = useState(false);
|
||||||
const [showAside, setShowAside] = useState();
|
const [showAside, setShowAside] = useState();
|
||||||
|
|
||||||
|
|
@ -11,6 +11,7 @@ export const UIStateProvider = ({ asides, children }) => {
|
||||||
<UIStateContext.Provider
|
<UIStateContext.Provider
|
||||||
value={{
|
value={{
|
||||||
asides,
|
asides,
|
||||||
|
customTrayComponent,
|
||||||
showDeviceModal,
|
showDeviceModal,
|
||||||
setShowDeviceModal,
|
setShowDeviceModal,
|
||||||
showAside,
|
showAside,
|
||||||
|
|
@ -25,6 +26,7 @@ export const UIStateProvider = ({ asides, children }) => {
|
||||||
UIStateProvider.propTypes = {
|
UIStateProvider.propTypes = {
|
||||||
children: PropTypes.node,
|
children: PropTypes.node,
|
||||||
asides: PropTypes.arrayOf(PropTypes.func),
|
asides: PropTypes.arrayOf(PropTypes.func),
|
||||||
|
customTrayComponent: PropTypes.node,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useUIState = () => useContext(UIStateContext);
|
export const useUIState = () => useContext(UIStateContext);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><title>comments</title><g stroke-linecap="round" stroke-linejoin="round" stroke-width="2" fill="none" stroke="currentColor"><path d="M23,5V16a2,2,0,0,1-2,2H19v4l-6-4H12" stroke="currentColor"></path><path d="M17,2H3A2,2,0,0,0,1,4v8a2,2,0,0,0,2,2H5v5l7-5h5a2,2,0,0,0,2-2V4A2,2,0,0,0,17,2Z"></path></g></svg>
|
||||||
|
After Width: | Height: | Size: 389 B |
|
|
@ -0,0 +1,14 @@
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import { TrayButton } from '@dailyjs/shared/components/Tray';
|
||||||
|
import { ReactComponent as IconChat } from '@dailyjs/shared/icons/chat-md.svg';
|
||||||
|
|
||||||
|
export const Tray = () => (
|
||||||
|
<>
|
||||||
|
<TrayButton label="Chat">
|
||||||
|
<IconChat />
|
||||||
|
</TrayButton>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
|
||||||
|
export default Tray;
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
export { Tray as default } from './Tray';
|
||||||
|
|
@ -1,5 +1,9 @@
|
||||||
|
import React from 'react';
|
||||||
import App from '@dailyjs/basic-call/pages/_app';
|
import App from '@dailyjs/basic-call/pages/_app';
|
||||||
|
|
||||||
|
import Tray from '../components/Tray';
|
||||||
|
|
||||||
App.asides = [];
|
App.asides = [];
|
||||||
|
App.customTrayComponent = <Tray />;
|
||||||
|
|
||||||
export default App;
|
export default App;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue