mirror of
https://github.com/cpvalente/ontime.git
synced 2026-09-05 14:29:20 +00:00
performance enhancements
This commit is contained in:
@@ -1,9 +1,8 @@
|
|||||||
import { useEffect, useState } from 'react';
|
import { memo, useEffect, useState } from 'react';
|
||||||
import { formatDisplay } from '../../dateConfig';
|
import { formatDisplay } from '../../dateConfig';
|
||||||
import styles from './Countdown.module.css';
|
import styles from './Countdown.module.css';
|
||||||
|
|
||||||
export default function Countdown(props) {
|
const Countdown = ({ time, small, hideZeroHours }) => {
|
||||||
const { time, small, hideZeroHours } = props;
|
|
||||||
const [clock, setClock] = useState(time);
|
const [clock, setClock] = useState(time);
|
||||||
let display = '-- : -- : --';
|
let display = '-- : -- : --';
|
||||||
|
|
||||||
@@ -20,4 +19,6 @@ export default function Countdown(props) {
|
|||||||
{display}
|
{display}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
|
export default memo(Countdown);
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
@import url('https://fonts.googleapis.com/css2?family=Open+Sans:wght@300;400;600;800&display=swap');
|
|
||||||
|
|
||||||
.entries {
|
.entries {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|||||||
@@ -0,0 +1,73 @@
|
|||||||
|
import { memo } from 'react';
|
||||||
|
import style from './PlaybackControl.module.css';
|
||||||
|
import StartIconBtn from '../../common/components/buttons/StartIconBtn';
|
||||||
|
import PauseIconBtn from '../../common/components/buttons/PauseIconBtn';
|
||||||
|
import PrevIconBtn from '../../common/components/buttons/PrevIconBtn';
|
||||||
|
import NextIconBtn from '../../common/components/buttons/NextIconBtn';
|
||||||
|
import RollIconBtn from '../../common/components/buttons/RollIconBtn';
|
||||||
|
import UnloadIconBtn from '../../common/components/buttons/UnloadIconBtn';
|
||||||
|
import ReloadIconButton from '../../common/components/buttons/ReloadIconBtn';
|
||||||
|
|
||||||
|
const areEqual = (prevProps, nextProps) => {
|
||||||
|
return (
|
||||||
|
prevProps.playback === nextProps.playback &&
|
||||||
|
prevProps.selectedId === nextProps.selectedId
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const Playback = ({ playback, selectedId, playbackControl }) => {
|
||||||
|
return (
|
||||||
|
<div className={style.playbackContainer}>
|
||||||
|
<StartIconBtn
|
||||||
|
active={playback === 'start'}
|
||||||
|
clickhandler={() => playbackControl('start')}
|
||||||
|
disabled={!selectedId}
|
||||||
|
/>
|
||||||
|
<PauseIconBtn
|
||||||
|
active={playback === 'pause'}
|
||||||
|
clickhandler={() => playbackControl('pause')}
|
||||||
|
disabled={!selectedId}
|
||||||
|
/>
|
||||||
|
<RollIconBtn
|
||||||
|
active={playback === 'roll'}
|
||||||
|
clickhandler={() => playbackControl('roll')}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const Transport = ({ selectedId, playbackControl }) => {
|
||||||
|
return (
|
||||||
|
<div className={style.playbackContainer}>
|
||||||
|
<PrevIconBtn clickhandler={() => playbackControl('previous')} />
|
||||||
|
<NextIconBtn clickhandler={() => playbackControl('next')} />
|
||||||
|
<UnloadIconBtn
|
||||||
|
clickhandler={() => playbackControl('unload')}
|
||||||
|
disabled={!selectedId}
|
||||||
|
/>
|
||||||
|
<ReloadIconButton
|
||||||
|
clickhandler={() => playbackControl('reload')}
|
||||||
|
disabled={!selectedId}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const PlaybackButtons = (props) => {
|
||||||
|
const { playback, selectedId } = props;
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Playback
|
||||||
|
playback={playback}
|
||||||
|
selectedId={selectedId}
|
||||||
|
playbackControl={props.playbackControl}
|
||||||
|
/>
|
||||||
|
<Transport
|
||||||
|
selectedId={selectedId}
|
||||||
|
playbackControl={props.playbackControl}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default memo(PlaybackButtons, areEqual);
|
||||||
@@ -4,13 +4,7 @@ import { stringFromMillis } from '../../common/dateConfig';
|
|||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import { useSocket } from '../../app/context/socketContext';
|
import { useSocket } from '../../app/context/socketContext';
|
||||||
import { Button } from '@chakra-ui/button';
|
import { Button } from '@chakra-ui/button';
|
||||||
import StartIconBtn from '../../common/components/buttons/StartIconBtn';
|
import PlaybackButtons from './PlaybackButtons';
|
||||||
import PauseIconBtn from '../../common/components/buttons/PauseIconBtn';
|
|
||||||
import PrevIconBtn from '../../common/components/buttons/PrevIconBtn';
|
|
||||||
import NextIconBtn from '../../common/components/buttons/NextIconBtn';
|
|
||||||
import RollIconBtn from '../../common/components/buttons/RollIconBtn';
|
|
||||||
import UnloadIconBtn from '../../common/components/buttons/UnloadIconBtn';
|
|
||||||
import ReloadIconButton from '../../common/components/buttons/ReloadIconBtn';
|
|
||||||
|
|
||||||
export default function PlaybackControl() {
|
export default function PlaybackControl() {
|
||||||
const socket = useSocket();
|
const socket = useSocket();
|
||||||
@@ -146,35 +140,11 @@ export default function PlaybackControl() {
|
|||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<PlaybackButtons
|
||||||
<div className={style.playbackContainer}>
|
playback={playback}
|
||||||
<StartIconBtn
|
selectedId={selectedId}
|
||||||
active={playback === 'start'}
|
playbackControl={playbackControl}
|
||||||
clickhandler={() => playbackControl('start')}
|
/>
|
||||||
disabled={!selectedId}
|
|
||||||
/>
|
|
||||||
<PauseIconBtn
|
|
||||||
active={playback === 'pause'}
|
|
||||||
clickhandler={() => playbackControl('pause')}
|
|
||||||
disabled={!selectedId}
|
|
||||||
/>
|
|
||||||
<RollIconBtn
|
|
||||||
active={playback === 'roll'}
|
|
||||||
clickhandler={() => playbackControl('roll')}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div className={style.playbackContainer}>
|
|
||||||
<PrevIconBtn clickhandler={() => playbackControl('previous')} />
|
|
||||||
<NextIconBtn clickhandler={() => playbackControl('next')} />
|
|
||||||
<UnloadIconBtn
|
|
||||||
clickhandler={() => playbackControl('unload')}
|
|
||||||
disabled={!selectedId}
|
|
||||||
/>
|
|
||||||
<ReloadIconButton
|
|
||||||
clickhandler={() => playbackControl('reload')}
|
|
||||||
disabled={!selectedId}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ export default function Editor() {
|
|||||||
</Heading>
|
</Heading>
|
||||||
<NumberedText number={4} text={'Realtime screen preview'} />
|
<NumberedText number={4} text={'Realtime screen preview'} />
|
||||||
<div className={styles.content}>
|
<div className={styles.content}>
|
||||||
<PreviewContainer />
|
{/* <PreviewContainer /> */}
|
||||||
</div>
|
</div>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { FiChevronDown, FiChevronUp, FiMoreVertical } from 'react-icons/fi';
|
import { FiChevronDown, FiChevronUp, FiMoreVertical } from 'react-icons/fi';
|
||||||
import { useState } from 'react';
|
import { memo, useEffect, useState } from 'react';
|
||||||
import EventTimes from '../../../common/components/eventTimes/EventTimes';
|
import EventTimes from '../../../common/components/eventTimes/EventTimes';
|
||||||
import { showErrorToast } from '../../../common/helpers/toastManager';
|
import { showErrorToast } from '../../../common/helpers/toastManager';
|
||||||
import style from './Block.module.css';
|
import style from './Block.module.css';
|
||||||
@@ -9,13 +9,30 @@ import ActionButtons from './ActionButtons';
|
|||||||
import VisibleIconBtn from '../../../common/components/buttons/VisibleIconBtn';
|
import VisibleIconBtn from '../../../common/components/buttons/VisibleIconBtn';
|
||||||
import DeleteIconBtn from '../../../common/components/buttons/DeleteIconBtn';
|
import DeleteIconBtn from '../../../common/components/buttons/DeleteIconBtn';
|
||||||
|
|
||||||
export default function EventBlock(props) {
|
const areEqual = (prevProps, nextProps) => {
|
||||||
|
let shouldNotRerender =
|
||||||
|
prevProps.data.revision === nextProps.data.revision &&
|
||||||
|
prevProps.selected === nextProps.selected &&
|
||||||
|
prevProps.next === nextProps.next;
|
||||||
|
console.log('debug memo2', shouldNotRerender);
|
||||||
|
return (
|
||||||
|
prevProps.data.revision === nextProps.data.revision &&
|
||||||
|
prevProps.selected === nextProps.selected &&
|
||||||
|
prevProps.next === nextProps.next
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const EventBlock = (props) => {
|
||||||
const { data, selected, next, delay, index, eventsHandler } = props;
|
const { data, selected, next, delay, index, eventsHandler } = props;
|
||||||
|
|
||||||
const [more, setMore] = useState(false);
|
const [more, setMore] = useState(false);
|
||||||
// NOTE: cheating to add responsiveness
|
|
||||||
const [visible, setVisible] = useState(data.isPublic || false);
|
const [visible, setVisible] = useState(data.isPublic || false);
|
||||||
|
|
||||||
|
// Set visibility indicator
|
||||||
|
useEffect(() => {
|
||||||
|
setVisible(data.isPublic);
|
||||||
|
}, [data.isPublic]);
|
||||||
|
|
||||||
const updateValues = (field, value) => {
|
const updateValues = (field, value) => {
|
||||||
// validate field
|
// validate field
|
||||||
if (field in data) {
|
if (field in data) {
|
||||||
@@ -56,7 +73,6 @@ export default function EventBlock(props) {
|
|||||||
|
|
||||||
const handleVisibleToggle = () => {
|
const handleVisibleToggle = () => {
|
||||||
let viz = !data.isPublic || !visible;
|
let viz = !data.isPublic || !visible;
|
||||||
setVisible(viz);
|
|
||||||
updateValues('isPublic', viz);
|
updateValues('isPublic', viz);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -85,13 +101,6 @@ export default function EventBlock(props) {
|
|||||||
submitHandler={handleTitleSubmit}
|
submitHandler={handleTitleSubmit}
|
||||||
underlined
|
underlined
|
||||||
/>
|
/>
|
||||||
<EditableText
|
|
||||||
label='Subtitle'
|
|
||||||
defaultValue={data.subtitle}
|
|
||||||
placeholder='Add Subtitle'
|
|
||||||
submitHandler={handleSubtitleSubmit}
|
|
||||||
underlined
|
|
||||||
/>
|
|
||||||
<EditableText
|
<EditableText
|
||||||
label='Presenter'
|
label='Presenter'
|
||||||
defaultValue={data.presenter}
|
defaultValue={data.presenter}
|
||||||
@@ -99,6 +108,13 @@ export default function EventBlock(props) {
|
|||||||
submitHandler={handlePresenterSubmit}
|
submitHandler={handlePresenterSubmit}
|
||||||
underlined
|
underlined
|
||||||
/>
|
/>
|
||||||
|
<EditableText
|
||||||
|
label='Subtitle'
|
||||||
|
defaultValue={data.subtitle}
|
||||||
|
placeholder='Add Subtitle'
|
||||||
|
submitHandler={handleSubtitleSubmit}
|
||||||
|
underlined
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div className={style.titleContainer}>
|
<div className={style.titleContainer}>
|
||||||
@@ -129,4 +145,6 @@ export default function EventBlock(props) {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
|
export default memo(EventBlock, areEqual);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import style from './List.module.css';
|
import style from './List.module.css';
|
||||||
|
|
||||||
import { useEffect, useState } from 'react';
|
import { Fragment, useEffect, useState } from 'react';
|
||||||
import { useSocket } from '../../../app/context/socketContext';
|
import { useSocket } from '../../../app/context/socketContext';
|
||||||
import tinykeys from 'tinykeys';
|
import tinykeys from 'tinykeys';
|
||||||
import Empty from '../../../common/state/Empty';
|
import Empty from '../../../common/state/Empty';
|
||||||
@@ -111,7 +111,7 @@ export default function EventList(props) {
|
|||||||
if (e.type === 'delay') cumulativeDelay += e.duration;
|
if (e.type === 'delay') cumulativeDelay += e.duration;
|
||||||
else if (e.type === 'block') cumulativeDelay = 0;
|
else if (e.type === 'block') cumulativeDelay = 0;
|
||||||
return (
|
return (
|
||||||
<div key={index}>
|
<Fragment key={index}>
|
||||||
<EventListItem
|
<EventListItem
|
||||||
type={e.type}
|
type={e.type}
|
||||||
index={index}
|
index={index}
|
||||||
@@ -132,7 +132,7 @@ export default function EventList(props) {
|
|||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</AnimatePresence>
|
</AnimatePresence>
|
||||||
</div>
|
</Fragment>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { memo, useCallback } from 'react';
|
||||||
import { FiChevronDown } from 'react-icons/fi';
|
import { FiChevronDown } from 'react-icons/fi';
|
||||||
import {
|
import {
|
||||||
Button,
|
Button,
|
||||||
@@ -9,9 +10,9 @@ import {
|
|||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
import AddIconBtn from '../../common/components/buttons/AddIconBtn';
|
import AddIconBtn from '../../common/components/buttons/AddIconBtn';
|
||||||
import style from './EventListMenu.module.css';
|
import style from './EventListMenu.module.css';
|
||||||
|
import MenuActionButtons from '../editors/list/MenuActionButtons';
|
||||||
|
|
||||||
export default function EventListMenu(props) {
|
const EventListMenu = ({ eventsHandler }) => {
|
||||||
const { eventsHandler } = props;
|
|
||||||
const buttonProps = {
|
const buttonProps = {
|
||||||
size: 'sm',
|
size: 'sm',
|
||||||
variant: 'outline',
|
variant: 'outline',
|
||||||
@@ -27,9 +28,9 @@ export default function EventListMenu(props) {
|
|||||||
backgroundColor: 'rgba(255,255,255,0.67)',
|
backgroundColor: 'rgba(255,255,255,0.67)',
|
||||||
};
|
};
|
||||||
|
|
||||||
const addHandler = () => {
|
const addHandler = useCallback(() => {
|
||||||
eventsHandler('add', { type: 'event', order: 0 });
|
eventsHandler('add', { type: 'event', order: 0 });
|
||||||
};
|
}, [eventsHandler]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={style.headerButtons}>
|
<div className={style.headerButtons}>
|
||||||
@@ -58,6 +59,9 @@ export default function EventListMenu(props) {
|
|||||||
</MenuList>
|
</MenuList>
|
||||||
</Menu>
|
</Menu>
|
||||||
<AddIconBtn clickhandler={addHandler} size='sm' />
|
<AddIconBtn clickhandler={addHandler} size='sm' />
|
||||||
|
{/* <MenuActionButtons size='sm' /> */}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
|
export default memo(EventListMenu);
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
const Timer = require('./Timer');
|
const Timer = require('./Timer');
|
||||||
const socketIo = require('socket.io');
|
const socketIo = require('socket.io');
|
||||||
|
// DEBUG
|
||||||
|
const { instrument } = require("@socket.io/admin-ui");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* EventTimer adds functions specific to APP
|
* EventTimer adds functions specific to APP
|
||||||
@@ -71,6 +73,11 @@ class EventTimer extends Timer {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// DEBUG
|
||||||
|
instrument(this.io, {
|
||||||
|
auth: false
|
||||||
|
});
|
||||||
|
|
||||||
// set recurrent emits
|
// set recurrent emits
|
||||||
this._interval = setInterval(
|
this._interval = setInterval(
|
||||||
() => this.broadcastTimer(),
|
() => this.broadcastTimer(),
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ function incrementFrom(start, incr = 1) {
|
|||||||
db.get('events')
|
db.get('events')
|
||||||
.find({ id: e.id })
|
.find({ id: e.id })
|
||||||
.assign({ order: e.order + incr })
|
.assign({ order: e.order + incr })
|
||||||
|
.update('revision', (n) => n + 1)
|
||||||
.write();
|
.write();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -163,6 +164,7 @@ exports.eventsPatch = async (req, res) => {
|
|||||||
db.get('events')
|
db.get('events')
|
||||||
.find({ id: req.body.id })
|
.find({ id: req.body.id })
|
||||||
.assign({ ...req.body })
|
.assign({ ...req.body })
|
||||||
|
.update('revision', (n) => n + 1)
|
||||||
.write();
|
.write();
|
||||||
|
|
||||||
// update timer
|
// update timer
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ const event = {
|
|||||||
timeEnd: 0,
|
timeEnd: 0,
|
||||||
isPublic: false,
|
isPublic: false,
|
||||||
type: 'event',
|
type: 'event',
|
||||||
|
revision: 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
const delay = {
|
const delay = {
|
||||||
|
|||||||
Reference in New Issue
Block a user