v2 alpha5 (#315)

* fix: fetch in offline environments (#295)

* add arm platforms to docker build

---------

Co-authored-by: Fabian Posenau <fabian@fphome.de>

* fix: docker build (#298)

Co-authored-by: Fabian Posenau <fabian@fphome.de>

* Timer: fix too many renders error when using ?progress (#305)

* ux: remove duplicate showing of selected event

* several small fixes and UX improvements
---------

Co-authored-by: Fabian Posenau <fabian.p99@gmx.de>
Co-authored-by: Fabian Posenau <fabian@fphome.de>
Co-authored-by: Marks Polakovs <github@markspolakovs.me>
This commit is contained in:
Carlos Valente
2023-03-24 08:19:47 +01:00
committed by GitHub
parent e937af62b1
commit bca7ad30b1
44 changed files with 434 additions and 799 deletions
+6 -5
View File
@@ -2,14 +2,13 @@ import { createRef, Fragment, useCallback, useContext, useEffect } from 'react';
import { DragDropContext, Droppable, DropResult } from 'react-beautiful-dnd';
import { Button } from '@chakra-ui/react';
import { IoAdd } from '@react-icons/all-files/io5/IoAdd';
import { useAtomValue } from 'jotai';
import { OntimeRundown, SupportedEvent } from 'ontime-types';
import { defaultPublicAtom, showQuickEntryAtom, startTimeIsLastEndAtom } from '../../common/atoms/LocalEventSettings';
import Empty from '../../common/components/state/Empty';
import { CursorContext } from '../../common/context/CursorContext';
import { useEventAction } from '../../common/hooks/useEventAction';
import { useRundownEditor } from '../../common/hooks/useSocket';
import { useLocalEvent } from '../../common/stores/localEvent';
import { cloneEvent } from '../../common/utils/eventsManager';
import QuickAddBlock from './quick-add-block/QuickAddBlock';
@@ -25,11 +24,13 @@ export default function Rundown(props: RundownProps) {
const { entries } = props;
const data = useRundownEditor();
const { cursor, moveCursorUp, moveCursorDown, moveCursorTo, isCursorLocked } = useContext(CursorContext);
const startTimeIsLastEnd = useAtomValue(startTimeIsLastEndAtom);
const defaultPublic = useAtomValue(defaultPublicAtom);
const { addEvent, reorderEvent } = useEventAction();
const cursorRef = createRef<HTMLDivElement>();
const showQuickEntry = useAtomValue(showQuickEntryAtom);
const { eventSettings } = useLocalEvent();
const defaultPublic = eventSettings.defaultPublic;
const startTimeIsLastEnd = eventSettings.startTimeIsLastEnd;
const showQuickEntry = eventSettings.showQuickEntry;
const insertAtCursor = useCallback(
(type: SupportedEvent | 'clone', cursor: number) => {
@@ -1,10 +1,10 @@
import { useCallback, useContext } from 'react';
import { useAtom, useAtomValue } from 'jotai';
import { OntimeEvent, OntimeRundownEntry, Playback, SupportedEvent } from 'ontime-types';
import { defaultPublicAtom, editorEventId, startTimeIsLastEndAtom } from '../../common/atoms/LocalEventSettings';
import { CursorContext } from '../../common/context/CursorContext';
import { useEventAction } from '../../common/hooks/useEventAction';
import { useEventEditorStore } from '../../common/stores/eventEditor';
import { useLocalEvent } from '../../common/stores/localEvent';
import { useEmitLog } from '../../common/stores/logger';
import { cloneEvent } from '../../common/utils/eventsManager';
import { calculateDuration } from '../../common/utils/timesManager';
@@ -32,11 +32,13 @@ interface RundownEntryProps {
export default function RundownEntry(props: RundownEntryProps) {
const { index, eventIndex, data, selected, hasCursor, next, delay, previousEnd, previousEventId, playback } = props;
const { emitError } = useEmitLog();
const startTimeIsLastEnd = useAtomValue(startTimeIsLastEndAtom);
const defaultPublic = useAtomValue(defaultPublicAtom);
const { openId, removeOpenEvent } = useEventEditorStore();
const { addEvent, updateEvent, deleteEvent } = useEventAction();
const { moveCursorTo } = useContext(CursorContext);
const [openId, setOpenId] = useAtom(editorEventId);
const { eventSettings } = useLocalEvent();
const defaultPublic = eventSettings.defaultPublic;
const startTimeIsLastEnd = eventSettings.startTimeIsLastEnd;
// Create / delete new events
type FieldValue = {
@@ -71,7 +73,7 @@ export default function RundownEntry(props: RundownEntryProps) {
}
case 'delete': {
if (openId === data.id) {
setOpenId(null);
removeOpenEvent();
}
deleteEvent(data.id);
break;
@@ -122,7 +124,7 @@ export default function RundownEntry(props: RundownEntryProps) {
moveCursorTo,
openId,
previousEventId,
setOpenId,
removeOpenEvent,
startTimeIsLastEnd,
updateEvent,
],
@@ -10,13 +10,12 @@ import { IoReload } from '@react-icons/all-files/io5/IoReload';
import { IoRemoveCircle } from '@react-icons/all-files/io5/IoRemoveCircle';
import { IoRemoveCircleOutline } from '@react-icons/all-files/io5/IoRemoveCircleOutline';
import { IoReorderTwo } from '@react-icons/all-files/io5/IoReorderTwo';
import { useAtom } from 'jotai';
import { Playback } from 'ontime-types';
import { editorEventId } from '../../../common/atoms/LocalEventSettings';
import TooltipActionBtn from '../../../common/components/buttons/TooltipActionBtn';
import { useEventAction } from '../../../common/hooks/useEventAction';
import { setEventPlayback } from '../../../common/hooks/useSocket';
import { useEventEditorStore } from '../../../common/stores/eventEditor';
import { cx, getAccessibleColour } from '../../../common/utils/styleUtils';
import { tooltipDelayMid } from '../../../ontimeConfig';
import { EventItemActions } from '../RundownEntry';
@@ -78,7 +77,7 @@ export default function EventBlock(props: EventBlockProps) {
actionHandler,
} = props;
const [openId, setOpenId] = useAtom(editorEventId);
const { openId, setOpenEvent, removeOpenEvent } = useEventEditorStore();
const { updateEvent } = useEventAction();
const [blockTitle, setBlockTitle] = useState<string>(title || '');
const onFocusRef = useRef<null | HTMLSpanElement>(null);
@@ -111,6 +110,14 @@ export default function EventBlock(props: EventBlockProps) {
[title, updateEvent, eventId],
);
const toggleOpenEvent = useCallback(() => {
if (openId === eventId) {
removeOpenEvent();
} else {
setOpenEvent(eventId);
}
}, [eventId, openId, removeOpenEvent, setOpenEvent]);
const eventIsPlaying = selected && playback === Playback.Play;
const playBtnStyles = { _hover: {} };
if (!skip && eventIsPlaying) {
@@ -221,7 +228,7 @@ export default function EventBlock(props: EventBlockProps) {
variant='ontime-subtle-white'
size='sm'
icon={<IoOptions />}
clickHandler={() => setOpenId((prev) => (prev === eventId ? null : eventId))}
clickHandler={toggleOpenEvent}
tooltip='Event options'
aria-label='Event options'
tabIndex={-1}
@@ -11,25 +11,16 @@ interface EventBlockProgressBarProps {
export default function EventBlockProgressBar(props: EventBlockProgressBarProps) {
const { playback } = props;
const { data: timer } = useTimer();
const timer = useTimer();
const now = Math.floor(Math.max((timer?.current ?? 1) / 1000, 0));
const complete = (timer?.duration ?? 1) / 1000;
const elapsed = clamp(100 - (now * 100) / complete, 0, 100);
const progress = `${elapsed}%`;
if ((timer?.current ?? 0) < 0) {
return (
<div
className={`${style.progressBar} ${style.overtime}`}
style={{ width: '100%' }}
/>
);
return <div className={`${style.progressBar} ${style.overtime}`} style={{ width: '100%' }} />;
}
return (
<div
className={`${style.progressBar} ${playback ? style[playback] : ''}`}
style={{ width: progress }}
/>
);
return <div className={`${style.progressBar} ${playback ? style[playback] : ''}`} style={{ width: progress }} />;
}
@@ -1,10 +1,9 @@
import { useCallback, useRef } from 'react';
import { Button, Checkbox, Tooltip } from '@chakra-ui/react';
import { useAtomValue } from 'jotai';
import { SupportedEvent } from 'ontime-types';
import { defaultPublicAtom, startTimeIsLastEndAtom } from '../../../common/atoms/LocalEventSettings';
import { useEventAction } from '../../../common/hooks/useEventAction';
import { useLocalEvent } from '../../../common/stores/localEvent';
import { useEmitLog } from '../../../common/stores/logger';
import { tooltipDelayMid } from '../../../ontimeConfig';
@@ -22,11 +21,14 @@ export default function QuickAddBlock(props: QuickAddBlockProps) {
const { showKbd, eventId, previousEventId, disableAddDelay = true, disableAddBlock } = props;
const { addEvent } = useEventAction();
const { emitError } = useEmitLog();
const startTimeIsLastEnd = useAtomValue(startTimeIsLastEndAtom);
const defaultPublic = useAtomValue(defaultPublicAtom);
const doStartTime = useRef<HTMLInputElement | null>(null);
const doPublic = useRef<HTMLInputElement | null>(null);
const { eventSettings } = useLocalEvent();
const defaultPublic = eventSettings.defaultPublic;
const startTimeIsLastEnd = eventSettings.startTimeIsLastEnd;
const handleCreateEvent = useCallback(
(eventType: SupportedEvent) => {
switch (eventType) {