move logic to HOC

This commit is contained in:
cv
2021-04-18 13:33:26 +02:00
parent 8e95b06b8c
commit 2d9d330fe3
3 changed files with 161 additions and 88 deletions
+20 -5
View File
@@ -1,20 +1,35 @@
import { Route } from 'react-router';
import { Route, Switch } from 'react-router-dom';
import './App.css';
import Editor from './features/editors/Editor';
import DefaultPresenter from './features/viewers/DefaultPresenter';
import PresenterView from './features/viewers/presenter/PresenterView';
import { QueryClient, QueryClientProvider } from 'react-query';
import SocketProvider from './app/context/socketContext';
import PresenterSimple from './features/viewers/presenter/PresenterSimple';
import StageManager from './features/viewers/backstage/StageManager';
import withSocket from './features/viewers/ViewWrapper';
const queryClient = new QueryClient();
const SDefault = withSocket(DefaultPresenter);
const SSpeaker = withSocket(PresenterView);
const SSpeakerSimple = withSocket(PresenterSimple);
const SStageManager = withSocket(StageManager);
function App() {
return (
<SocketProvider>
<div className='App'>
<Route path='/' exact component={DefaultPresenter} />
<QueryClientProvider client={queryClient}>
<Route path='/editor' exact component={Editor} />
</QueryClientProvider>
<Switch>
<Route exact path='/' component={SDefault} />
<Route path='/sm' component={SStageManager} />
<Route path='/speaker' component={SSpeaker} />
<Route path='/speakersimple' component={SSpeakerSimple} />
<QueryClientProvider client={queryClient}>
<Route path='/editor' component={Editor} />
</QueryClientProvider>
</Switch>
</div>
</SocketProvider>
);
+124
View File
@@ -0,0 +1,124 @@
import { useEffect, useState } from 'react';
import { useSocket } from '../../app/context/socketContext';
import { stringFromMillis } from '../../common/dateConfig';
const withSocket = (Component) => {
const WrappedComponent = (props) => {
const socket = useSocket();
const [pres, setPres] = useState({
text: '',
visible: false,
});
const [publ, setPubl] = useState({
text: '',
visible: false,
});
const [lower, setLower] = useState({
text: '',
visible: false,
});
const [timer, setTimer] = useState({
clock: null,
currentSeconds: null,
startedAt: null,
expectedFinish: null,
});
const [titles, setTitles] = useState({
titleNow: '',
subtitleNow: '',
presenterNow: '',
titleNext: '',
subtitleNext: '',
presenterNext: '',
});
// Ask for update on load
useEffect(() => {
if (socket == null) return;
// Handle presenter messages
socket.on('messages-presenter', (data) => {
setPres({ ...data });
});
// Handle public messages
socket.on('messages-public', (data) => {
setPubl({ ...data });
});
// Handle lower third messages
socket.on('messages-lower', (data) => {
setLower({ ...data });
});
// Handle timer
socket.on('timer', (data) => {
setTimer({ ...data });
});
// Handle timer
socket.on('titles', (data) => {
setTitles({ ...data });
});
// Ask for up to date data
socket.emit('get-messages');
// Ask for up to data
socket.emit('get-presenter');
// Ask for up titles
socket.emit('get-titles');
// Clear listeners
return () => {
socket.off('messages-public');
socket.off('messages-presenter');
socket.off('messages-lower');
socket.off('timer');
socket.off('titles');
};
}, [socket]);
/********************************************/
/*** + titleManager ***/
/*** WRAP INFORMATION RELATED TO TITLES ***/
/*** ---------------------------------- ***/
/********************************************/
// is there a next field?
let showNext = true;
if (!titles.titleNext && !titles.subtitleNext && !titles.presenterNext)
showNext = false;
const titleManager = { ...titles, showNext: showNext };
/******************************************/
/*** + timeManager ***/
/*** WRAP INFORMATION RELATED TO TIME ***/
/*** -------------------------------- ***/
/******************************************/
// is timer finished
let finished = timer.currentSeconds <= 0;
// get clock
let clock = stringFromMillis(timer.clock);
const timeManager = { ...timer, finished: finished, clock: clock };
return (
<Component
{...props}
pres={pres}
publ={publ}
lower={lower}
title={titleManager}
time={timeManager}
/>
);
};
return WrappedComponent;
};
export default withSocket;
@@ -1,82 +1,16 @@
import { useEffect, useState } from 'react';
import { useSocket } from '../../../app/context/socketContext';
import Countdown from '../../../common/components/countdown/Countdown';
import MyProgressBar from '../../../common/components/myProgressBar/MyProgressBar';
import { stringFromMillis } from '../../../common/dateConfig';
import style from './PresenterView.module.css';
export default function PresenterView() {
const socket = useSocket();
const [pres, setPres] = useState({
text: '',
visible: false,
});
const [timer, setTimer] = useState({
clock: null,
currentSeconds: null,
durationSeconds: null,
startedAt: null,
expectedFinish: null,
});
const [titles, setTitles] = useState({
titleNow: '',
subtitleNow: '',
presenterNow: '',
titleNext: '',
subtitleNext: '',
presenterNext: '',
});
// Ask for update on load
useEffect(() => {
if (socket == null) return;
export default function PresenterView(props) {
const { pres, publ, lower, title, time } = props;
// Handle presenter messages
socket.on('messages-presenter', (data) => {
setPres({ ...data });
});
// Handle timer
socket.on('timer', (data) => {
setTimer({ ...data });
});
// Handle timer
socket.on('titles', (data) => {
setTitles({ ...data });
});
// Ask for up to data
socket.emit('get-presenter');
// Ask for up titles
socket.emit('get-titles');
// Clear listeners
return () => {
socket.off('messages-presenter');
socket.off('timer');
socket.off('titles');
};
}, [socket]);
// is there a next field?
let showNext = true;
if (!titles.titleNext && !titles.subtitleNext && !titles.presenterNext)
showNext = false;
// should show message overlay
let showOverlay = pres.visible && pres.text !== '';
// is timer finished
let finished = timer.currentSeconds <= 0;
// get clock
let clock = stringFromMillis(timer.clock);
let showOverlay = pres.text !== '' && pres.visible;
return (
<div
className={
finished ? style.container__grayFinished : style.container__gray
time.finished ? style.container__grayFinished : style.container__gray
}
>
<div
@@ -89,41 +23,41 @@ export default function PresenterView() {
<div className={style.clockContainer}>
<div className={style.label}>Time Now</div>
<div className={style.clock}>{clock}</div>
<div className={style.clock}>{time.clock}</div>
</div>
<div className={style.timerContainer}>
{finished ? (
{time.finished ? (
<div className={style.finished}>TIME UP</div>
) : (
<div className={style.countdown}>
<Countdown time={timer.currentSeconds} hideZeroHours />
<Countdown time={time.currentSeconds} hideZeroHours />
</div>
)}
</div>
{!finished && (
{!time.finished && (
<div className={style.progressContainer}>
<MyProgressBar
now={timer.currentSeconds}
complete={timer.durationSeconds}
now={time.currentSeconds}
complete={time.durationSeconds}
/>
</div>
)}
<div className={style.nowContainer}>
<div className={style.label}>Now</div>
<div className={style.title}>{titles.titleNow}</div>
<div className={style.subtitle}>{titles.subtitleNow}</div>
<div className={style.presenter}>{titles.presenterNow}</div>
<div className={style.title}>{title.titleNow}</div>
<div className={style.subtitle}>{title.subtitleNow}</div>
<div className={style.presenter}>{title.presenterNow}</div>
</div>
{showNext && (
{title.showNext && (
<div className={style.nextContainer}>
<div className={style.label}>Next</div>
<div className={style.title}>{titles.titleNext}</div>
<div className={style.subtitle}>{titles.subtitleNext}</div>
<div className={style.presenter}>{titles.presenterNext}</div>
<div className={style.title}>{title.titleNext}</div>
<div className={style.subtitle}>{title.subtitleNext}</div>
<div className={style.presenter}>{title.presenterNext}</div>
</div>
)}
</div>