From 2f205bcb552feeb19110c726d9d977613690c30d Mon Sep 17 00:00:00 2001 From: cv <34649812+cpvalente@users.noreply.github.com> Date: Tue, 20 Apr 2021 12:16:43 +0200 Subject: [PATCH] cleanup --- .../myProgressBar/MyProgressBar.jsx | 2 +- .../myProgressBar/MyProgressBar.module.css | 6 +- .../components/text/NumberedText.module.css | 2 +- client/src/features/editors/Editor.jsx | 242 +++++++++--------- client/src/features/modals/SettingsModal.jsx | 6 +- .../src/features/viewers/DefaultPresenter.jsx | 163 ++++++++---- .../viewers/DefaultPresenter.module.css | 18 ++ .../features/viewers/backstage/Paginator.jsx | 8 +- .../features/viewers/backstage/TodayItem.jsx | 2 +- .../presenter/PresenterView.module.css | 5 +- client/src/index.js | 3 +- server/controllers/eventsController.js | 9 +- server/data/dataModel.json | 15 +- server/routes/eventsRouter.js | 4 +- 14 files changed, 291 insertions(+), 194 deletions(-) create mode 100644 client/src/features/viewers/DefaultPresenter.module.css diff --git a/client/src/common/components/myProgressBar/MyProgressBar.jsx b/client/src/common/components/myProgressBar/MyProgressBar.jsx index 9f0115b0d..840af36e0 100644 --- a/client/src/common/components/myProgressBar/MyProgressBar.jsx +++ b/client/src/common/components/myProgressBar/MyProgressBar.jsx @@ -3,7 +3,7 @@ import styles from './MyProgressBar.module.css'; export default function MyProgressBar(props) { const { now, complete } = props; - const percentComplete = clamp((now * 100) / complete, 0, 100); + const percentComplete = clamp((now * 100) / complete - 1, 0, 100); return (
diff --git a/client/src/common/components/myProgressBar/MyProgressBar.module.css b/client/src/common/components/myProgressBar/MyProgressBar.module.css index be451f8af..6cfcb0c25 100644 --- a/client/src/common/components/myProgressBar/MyProgressBar.module.css +++ b/client/src/common/components/myProgressBar/MyProgressBar.module.css @@ -5,10 +5,10 @@ } .progressBar { - width: 30%; + width: 100%; height: 2vh; background-color: rgba(255, 255, 255, 0.79); border-radius: 4px; - transition: 0.4s linear; - transition-property: width, background-color; + transition: 1s linear; + transition-property: width; } diff --git a/client/src/common/components/text/NumberedText.module.css b/client/src/common/components/text/NumberedText.module.css index 0c2a7e0cf..16d6f39ca 100644 --- a/client/src/common/components/text/NumberedText.module.css +++ b/client/src/common/components/text/NumberedText.module.css @@ -5,7 +5,7 @@ font-weight: 600; background-color: #ff5b7e; - border: 1px solid rgba(255,255,255,0.47); + border: 1px solid rgba(255,255,255,0.17); width: 1.5em; border-radius: 1em; diff --git a/client/src/features/editors/Editor.jsx b/client/src/features/editors/Editor.jsx index 6f8bf0562..a5420bc30 100644 --- a/client/src/features/editors/Editor.jsx +++ b/client/src/features/editors/Editor.jsx @@ -1,5 +1,5 @@ import { IconButton } from '@chakra-ui/button'; -import { FiSettings } from "react-icons/fi"; +import { FiSettings } from 'react-icons/fi'; import { Grid, GridItem, Heading } from '@chakra-ui/layout'; import { Box } from '@chakra-ui/layout'; import NumberedText from '../../common/components/text/NumberedText'; @@ -8,130 +8,142 @@ import MessageControl from '../control/MessageControl'; import PreviewContainer from '../viewers/PreviewContainer'; import styles from './Editor.module.css'; import EventListWrapper from './list/EventListWrapper'; +import { useDisclosure } from '@chakra-ui/hooks'; +import SettingsModal from '../modals/SettingsModal'; export default function Editor() { + const { isOpen, onOpen, onClose } = useDisclosure(); return ( - - - - - Event List - - -
- -
-
-
+ <> + - - - - Preview Displays - - -
- -
-
-
+ + + + + Event List + + +
+ +
+
+
- - - - Display Messages - - -
- -
-
-
+ + + + Preview Displays + + +
+ +
+
+
- - - - Time Control - - -
- -
-
-
+ + + + Display Messages + + +
+ +
+
+
- - -
- } isRound variant='outline' /> + + + + Time Control + + +
+ +
+
+
+ + +
-
-
-
-
-
-
- - - + > + } + isRound + variant='outline' + onClick={onOpen} + /> +
+
+
+
+
+
+
+ + + + ); } diff --git a/client/src/features/modals/SettingsModal.jsx b/client/src/features/modals/SettingsModal.jsx index b19e3aecf..d831181bc 100644 --- a/client/src/features/modals/SettingsModal.jsx +++ b/client/src/features/modals/SettingsModal.jsx @@ -164,11 +164,7 @@ export default function SettingsModal(props) { > Save - diff --git a/client/src/features/viewers/DefaultPresenter.jsx b/client/src/features/viewers/DefaultPresenter.jsx index d8275f1ab..d41c44176 100644 --- a/client/src/features/viewers/DefaultPresenter.jsx +++ b/client/src/features/viewers/DefaultPresenter.jsx @@ -1,62 +1,129 @@ -import { differenceInSeconds, format, subMinutes } from 'date-fns'; -import addMinutes from 'date-fns/addMinutes'; -import { useContext, useEffect, useState } from 'react'; -import { EventContext } from '../../app/context/eventContext'; -import { PresenterMessagesContext } from '../../app/context/presenterMessageContext'; -import Countdown from '../../common/components/countdown/Countdown'; -import MyProgressBar from '../../common/components/myProgressBar/MyProgressBar'; -import SmallTimer from '../../common/components/smallTimer/SmallTimer'; -import './viewers.css'; +import { useEffect, useState } from 'react'; +import { useSocket } from '../../app/context/socketContext'; +import style from './DefaultPresenter.module.css'; export default function DefaultPresenter() { - const [event] = useContext(EventContext); - const [presMessage] = useContext(PresenterMessagesContext); - const [initialValues, setInitialValues] = useState(null); - - const now = new Date(); - let values = event ?? { - title: 'Presentation Title', - subtitle: 'Presentation Subtitle', - presenter: 'Presenter Name', - timerDuration: 10, - timeStart: now, - timeEnd: now, - }; + 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(() => { - values = event; - }, [event]); + if (socket == null) return; - useEffect(() => { - setInitialValues(event); - }, [event]); + // Handle presenter messages + socket.on('messages-presenter', (data) => { + setPres({ ...data }); + }); - // NOTE: test only - const clockStarted = addMinutes(now, 6); + // Handle public messages + socket.on('messages-public', (data) => { + setPubl({ ...data }); + }); - const timer = differenceInSeconds( - now, - subMinutes(clockStarted, values.duration) - ); + // Handle lower third messages + socket.on('messages-lower', (data) => { + setLower({ ...data }); + }); - const timeStart = format(values.timeStart, 'HH:mm'); - const currentTime = format(now, 'HH:mm'); - const timeEnd = format(values.timeEnd, 'HH:mm'); - const elapsed = timer / (values.duration * 60); + // 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]); return ( -
-
{values.title}
-
{values.subtitle}
- - {!presMessage.show && } -
- {presMessage.text} +
+
+ Clock: + {timer.clock} + Timer: + {timer.currentSeconds} + Started: + {timer.startedAt} + Finish: + {timer.expectedFinish}
-
- - - +
+ Presenter Message: + {pres.text} + Vis: + {pres.visible ? 'visible' : 'invisible'} +
+
+ Public Message: + {publ.text} + Vis: + {publ.visible ? 'visible' : 'invisible'} +
+
+ Lower third Message: + {lower.text} + Vis: + {lower.visible ? 'visible' : 'invisible'} +
+
+ Title Now: + {titles.titleNow} + Subtitle Now: + {titles.subtitleNow} + Presenter Now: + {titles.presenterNow} +
+
+ Title Next: + {titles.titleNext} + Subtitle Next: + {titles.subtitleNext} + Presenter Next: + {titles.presenterNext}
); diff --git a/client/src/features/viewers/DefaultPresenter.module.css b/client/src/features/viewers/DefaultPresenter.module.css new file mode 100644 index 000000000..1f35c8eda --- /dev/null +++ b/client/src/features/viewers/DefaultPresenter.module.css @@ -0,0 +1,18 @@ +.mainContainer { + color: white; + display: flex; + flex-direction: rows; + flex-wrap: wrap; + font-size: 28px; + gap: 2em +} + +.container { + flex: 1 0 56%; + display: flex; +} + +.label { + padding: 0 1em; + color: #fff5; +} diff --git a/client/src/features/viewers/backstage/Paginator.jsx b/client/src/features/viewers/backstage/Paginator.jsx index ccf7ab0ad..395b8aeab 100644 --- a/client/src/features/viewers/backstage/Paginator.jsx +++ b/client/src/features/viewers/backstage/Paginator.jsx @@ -1,7 +1,6 @@ import TodayItem from './TodayItem'; import style from './Paginator.module.css'; import { useEffect, useState } from 'react'; -import { useTimeout } from '../../../app/hooks/useTimeout'; import { useInterval } from '../../../app/hooks/useInterval'; export default function Paginator(props) { @@ -23,24 +22,19 @@ export default function Paginator(props) { useEffect(() => { if (events == null) return; - console.log('debug events', events); - // how many events in list let n = events.length; setNumEvents(n); - console.log('debug ne', n); // how many paginated views let p = Math.ceil(n / LIMIT_PER_PAGE); setPages(p); - console.log('debug np', p); // divide events in parts of LIMIT_PER_PAGE const eventStart = LIMIT_PER_PAGE * selPage; const eventEnd = LIMIT_PER_PAGE * (selPage + 1); let e = events.slice(eventStart, eventEnd); setPage(e); - console.log('debug show', e); // if array is completely in past, show depending on SCROLL_PAST }, [events, selPage]); @@ -58,6 +52,7 @@ export default function Paginator(props) {
{[...Array(pages)].map((p, i) => (
))} @@ -69,6 +64,7 @@ export default function Paginator(props) { else if (selectedYet === 1) selectedYet = 2; return ( +
{start}
{end}
{title}
diff --git a/client/src/features/viewers/presenter/PresenterView.module.css b/client/src/features/viewers/presenter/PresenterView.module.css index ad5ff7517..7a8d7d67b 100644 --- a/client/src/features/viewers/presenter/PresenterView.module.css +++ b/client/src/features/viewers/presenter/PresenterView.module.css @@ -1,7 +1,6 @@ .container__gray, .container__grayFinished { margin: 0; - padding: 0; box-sizing: border-box; /* reset */ overflow: hidden; width: 100%; /* restrict the page width to viewport */ @@ -113,7 +112,7 @@ right: 0; bottom: 0; background-color: rgba(0, 0, 0, 0.85); - z-index: 2; + z-index: -1; opacity: 0; transition: 0.5s; } @@ -121,6 +120,8 @@ .messageOverlayActive { opacity: 1; transition: 0.5s; + transition-property: opacity; + z-index: 2; } .message { diff --git a/client/src/index.js b/client/src/index.js index 1d4dcadd9..0ba311676 100644 --- a/client/src/index.js +++ b/client/src/index.js @@ -6,12 +6,13 @@ import reportWebVitals from './reportWebVitals'; import { BrowserRouter } from 'react-router-dom'; // 1. import `ChakraProvider` component -import { ChakraProvider } from '@chakra-ui/react'; +import { ChakraProvider, CSSReset } from '@chakra-ui/react'; ReactDOM.render( + diff --git a/server/controllers/eventsController.js b/server/controllers/eventsController.js index 359bf8710..7bdfee6f1 100644 --- a/server/controllers/eventsController.js +++ b/server/controllers/eventsController.js @@ -109,7 +109,6 @@ exports.eventsPost = async (req, res) => { res.sendStatus(201); } catch (error) { res.status(400).send(error); - console.log('debug', error); } }; @@ -119,19 +118,14 @@ exports.eventsPut = async (req, res) => { // no valid params if (!req.body) { res.status(400).send(`No object found`); - console.log('error here', 'noobj'); - return; } let eventId = req.body.id; if (!eventId) { - res.status(400).send(`No id found`); - console.log('error here', 'noid'); - + res.status(400).send(`Object malformed: id missing`); return; } - try { db.get('events') .find({ id: req.body.id }) @@ -141,7 +135,6 @@ exports.eventsPut = async (req, res) => { .then(res.sendStatus(200)); } catch (error) { res.status(400).send(error); - console.log('error here', error); } }; diff --git a/server/data/dataModel.json b/server/data/dataModel.json index 6cc4cc517..456ff7846 100644 --- a/server/data/dataModel.json +++ b/server/data/dataModel.json @@ -1,3 +1,16 @@ { - "events": [] + "events": [], + "event": { + "title": "", + "url": "", + "publicInfo": "", + "backStageInfo": "" + }, + "settings": { + "app": "ontime", + "version": 1, + "osc_enabled": false, + "osc_port": 8008, + "lock": false + } } \ No newline at end of file diff --git a/server/routes/eventsRouter.js b/server/routes/eventsRouter.js index cc16adb1e..52099a1bb 100644 --- a/server/routes/eventsRouter.js +++ b/server/routes/eventsRouter.js @@ -1,8 +1,8 @@ const express = require('express'); const router = express.Router(); -// import playback controller - const eventsController = require('../controllers/eventsController'); +// import events controller +const eventsController = require('../controllers/eventsController'); // create route between controller and '/events' endpoint router.get('/', eventsController.eventsGetAll);