Merge branch 'master' into wip/migratedb

This commit is contained in:
cv
2021-05-28 14:46:54 +02:00
27 changed files with 284 additions and 110 deletions
+1 -1
View File
@@ -7,6 +7,6 @@ body,
html,
.App {
margin: 0px auto;
overflow: hidden;
overflow: clip;
height: 100vh;
}
-9
View File
@@ -58,12 +58,3 @@ export const BatchOperation = atom(null, (get, set, payload) => {
localStorage.setItem(PATH, JSON.stringify(options));
});
// change collapsed in all items
export const setAll = async (items, isCollapsed) => {
// clear storage
localStorage.removeItem(PATH);
// call batch
BatchOperation({ items: items, isCollapsed: isCollapsed });
};
+1
View File
@@ -5,6 +5,7 @@ export const useFetch = (namespace, fn) => {
const { data, status, isError, refetch } = useQuery(namespace, fn, {
refetchInterval: refetchIntervalMs,
cacheTime: Infinity,
notifyOnChangeProps: 'tracked',
});
return { data, status, isError, refetch };
@@ -10,8 +10,9 @@ export default function LockIconBtn(props) {
ref={ref}
size={props.size || 'xs'}
icon={<FiTarget />}
colorScheme='pink'
color={'pink.300'}
color={active ? 'pink.100' : 'pink.300'}
borderColor={active ? undefined : 'pink.300'}
backgroundColor={active ? 'pink.300' : undefined}
variant={active ? 'solid' : 'outline'}
onClick={clickhandler}
_focus={{ boxShadow: 'none' }}
@@ -12,7 +12,6 @@ export default function RollIconBtn(props) {
width={120}
_focus={{ boxShadow: 'none' }}
{...rest}
disabled
/>
);
}
@@ -6,7 +6,7 @@ import { useInterval } from 'app/hooks/useInterval';
export default function Paginator(props) {
const { events, selectedId } = props;
const LIMIT_PER_PAGE = props.limit || 8;
const SCROLL_TIME = props.time * 1000 || 5000;
const SCROLL_TIME = props.time * 1000 || 10000;
const SCROLL_PAST = false;
const [numEvents, setNumEvents] = useState(0);
const [page, setPage] = useState([]);
+2 -2
View File
@@ -33,9 +33,9 @@ export default function EditableText(props) {
>
<EditablePreview
color={text === '' ? '#666' : 'inherit'}
maxWidth='20em'
maxWidth='75%'
/>
<EditableInput overflowX='hidden' maxWidth='20em' />
<EditableInput overflowX='hidden' maxWidth='75%' />
</Editable>
</div>
);
+2 -8
View File
@@ -34,12 +34,12 @@ export default function EditableTimer(props) {
if (value === '') return false;
// Time now and time submitedVal
const original = stringFromMillis(time, false);
const original = stringFromMillis(time + delay, false);
// check if time is different from before
if (value === original) return false;
// conver to millis object
// convert to millis object
const millis = timeStringToMillis(value, timeFormat);
// validate with parent
@@ -51,14 +51,8 @@ export default function EditableTimer(props) {
return true;
};
const showOriginal = () => {
setValue(stringFromMillis(time, false));
};
return (
<Editable
onFocus={() => showOriginal}
onEdit={() => showOriginal}
onChange={(v) => setValue(v)}
onSubmit={(v) => validateValue(v)}
value={value}
@@ -41,10 +41,7 @@ const Transport = ({ selectedId, playbackControl }) => {
<div className={style.playbackContainer}>
<PrevIconBtn clickhandler={() => playbackControl('previous')} />
<NextIconBtn clickhandler={() => playbackControl('next')} />
<UnloadIconBtn
clickhandler={() => playbackControl('unload')}
disabled={!selectedId}
/>
<UnloadIconBtn clickhandler={() => playbackControl('unload')} />
<ReloadIconButton
clickhandler={() => playbackControl('reload')}
disabled={!selectedId}
@@ -90,6 +90,7 @@ export default function PlaybackControl() {
<div className={style.mainContainer}>
<PlaybackTimer
timer={timer}
playback={playback}
handleIncrement={(amount) => socket.emit('increment-timer', amount)}
/>
<PlaybackButtons
@@ -35,18 +35,19 @@
height: 100%;
display: flex;
flex-direction: column;
justify-content: space-around;
justify-content: space-evenly;
}
.indRoll,
.indDelay,
.indNegative {
background-color: rgba(0, 0, 0, 0.05);
margin: 0 auto;
}
.indRoll,
.indRollActive,
.indDelay {
margin: 0 auto;
border-radius: 50%;
width: 0.8em;
height: 0.8em;
@@ -60,7 +61,7 @@
.indNegativeActive {
margin: 0 auto;
width: 90%;
height: 0.3em
height: 0.3em;
}
.indNegativeActive {
+26 -8
View File
@@ -8,16 +8,18 @@ const areEqual = (prevProps, nextProps) => {
return (
prevProps.timer.running === nextProps.timer.running &&
prevProps.timer.expectedFinish === nextProps.timer.expectedFinish &&
prevProps.timer.startedAt === nextProps.timer.startedAt
prevProps.timer.startedAt === nextProps.timer.startedAt &&
prevProps.playback === nextProps.playback
);
};
const PlaybackTimer = ({ timer, handleIncrement }) => {
const PlaybackTimer = (props) => {
const { timer, playback, handleIncrement } = props;
const started = stringFromMillis(timer.startedAt, true);
const finish = stringFromMillis(timer.expectedFinish, true);
const isNegative = timer.running < 0;
const isDelayed = false;
const isRolling = false;
const isRolling = playback === 'roll';
const incrementProps = {
size: 'sm',
@@ -31,7 +33,7 @@ const PlaybackTimer = ({ timer, handleIncrement }) => {
<>
<div className={style.timeContainer}>
<div className={style.indicators}>
<div className={style.indRoll} />
<div className={isRolling ? style.indRollActive : style.indRoll} />
<div
className={isNegative ? style.indNegativeActive : style.indNegative}
/>
@@ -49,16 +51,32 @@ const PlaybackTimer = ({ timer, handleIncrement }) => {
<span className={style.time}>{finish}</span>
</div>
<div className={style.btn}>
<Button {...incrementProps} onClick={() => handleIncrement(-1)}>
<Button
{...incrementProps}
disabled={isRolling}
onClick={() => handleIncrement(-1)}
>
-1
</Button>
<Button {...incrementProps} onClick={() => handleIncrement(1)}>
<Button
{...incrementProps}
disabled={isRolling}
onClick={() => handleIncrement(1)}
>
+1
</Button>
<Button {...incrementProps} onClick={() => handleIncrement(-5)}>
<Button
{...incrementProps}
disabled={isRolling}
onClick={() => handleIncrement(-5)}
>
-5
</Button>
<Button {...incrementProps} onClick={() => handleIncrement(5)}>
<Button
{...incrementProps}
disabled={isRolling}
onClick={() => handleIncrement(5)}
>
+5
</Button>
</div>
@@ -18,11 +18,12 @@
/* 2/3 window, hide previews */
@media (max-width: 1250px) and (min-height: 700px) {
.mainContainer {
height: 100%;
grid-template-rows: 1fr 1fr;
grid-template-columns: 48em 1fr 1fr;
grid-template-areas:
/* grid-template-areas:
'even play sett'
'even mess sett';
'even mess sett'; */
}
.info {
@@ -40,6 +41,11 @@
'play';
}
.messages,
.playback {
min-width: 31em;
}
.editor,
.info,
.settings {
@@ -17,7 +17,7 @@ export default function ActionButtons(props) {
aria-label='Options'
size='xs'
icon={<FiZap />}
_expanded={{ bg: 'pink.300', color: 'white' }}
_expanded={{ bg: 'orange.300', color: 'white' }}
_focus={{ boxShadow: 'none' }}
backgroundColor={'orange.200'}
color={'orange.500'}
@@ -14,7 +14,8 @@ import { SelectCollapse, HandleCollapse } from 'app/context/collapseAtom';
import { useAtom } from 'jotai';
const ExpandedBlock = (props) => {
const { provided, data, next, delay, delayValue, actionHandler } = props;
const { provided, data, eventIndex, next, delay, delayValue, actionHandler } =
props;
const oscid = data.id.length > 4 ? '...' : data.id;
@@ -80,7 +81,9 @@ const ExpandedBlock = (props) => {
actionHandler('update', { field: 'note', value: v })
}
/>
<span className={style.oscLabel}>{`OSC ID: ${oscid}`}</span>
<span className={style.oscLabel}>
{`/ontime/goto ${eventIndex + 1} << OSC >> /ontime/gotoid ${oscid}`}
</span>
</div>
<Icon
className={style.more}
@@ -156,7 +159,7 @@ const CollapsedBlock = (props) => {
};
export default function EventBlock(props) {
const { data, selected, delay, index, actionHandler } = props;
const { data, selected, delay, index, eventIndex, actionHandler } = props;
// const [collapsed, setCollapsed] = useState(checkLocalStorage(data.id));
@@ -200,6 +203,7 @@ export default function EventBlock(props) {
) : (
<ExpandedBlock
provided={provided}
eventIndex={eventIndex}
data={data}
next={props.next}
delay={delay}
+26 -13
View File
@@ -27,7 +27,7 @@ export default function EventList(props) {
},
'Alt+ArrowUp': () => {
if (cursor == null) setCursor(0);
else if (cursor >= 0) setCursor(cursor - 1);
else if (cursor > 0) setCursor(cursor - 1);
},
'Alt+KeyE': (event) => {
event.preventDefault();
@@ -49,7 +49,7 @@ export default function EventList(props) {
return () => {
unsubscribe();
};
}, [cursor, events.length, eventsHandler]);
}, [cursor, events, eventsHandler]);
// handle incoming messages
useEffect(() => {
@@ -62,7 +62,6 @@ export default function EventList(props) {
// Handle playstate
socket.on('selected', (data) => {
setSelected(data);
console.log('debug cursor setted', data);
});
socket.on('next-id', (data) => {
setNext(data);
@@ -80,13 +79,20 @@ export default function EventList(props) {
if (cursorSettings !== 'locked' || selected == null) return;
if (selected.index == null) return;
setCursor(selected.index);
}, [selected, cursorSettings]);
let eventIndex = -1;
let gotoIndex = -1;
for (const e of events) {
gotoIndex++;
if (e.type === 'event') eventIndex++;
if (eventIndex === selected.index) break;
}
setCursor(gotoIndex);
}, [events, selected, cursorSettings]);
// attach scroll to cursor
useEffect(() => {
if (cursor == null || cursorRef.current == null) return;
console.log('debug cursor scrolling');
cursorRef.current.scrollIntoView({
behavior: 'smooth',
@@ -117,8 +123,7 @@ export default function EventList(props) {
console.log('EventList: events in event list', events);
let cumulativeDelay = 0;
console.log('debug selected', selected);
let eventIndex = -1;
return (
<div className={style.eventContainer}>
@@ -131,20 +136,28 @@ export default function EventList(props) {
ref={provided.innerRef}
>
{events.map((e, index) => {
let isCursor = cursor === index;
if (index === 0) cumulativeDelay = 0;
if (index === 0) {
cumulativeDelay = 0;
eventIndex = -1;
}
if (e.type === 'delay' && e.duration != null) {
cumulativeDelay += e.duration;
} else if (e.type === 'block') cumulativeDelay = 0;
} else if (e.type === 'block') {
cumulativeDelay = 0;
} else if (e.type === 'event') {
eventIndex++;
}
return (
<div
ref={isCursor ? cursorRef : undefined}
ref={cursor === index ? cursorRef : undefined}
key={e.id}
className={isCursor ? style.cursor : undefined}
className={cursor === index ? style.cursor : undefined}
>
<EventListItem
type={e.type}
index={index}
eventIndex={eventIndex}
data={e}
selected={selected?.id === e.id}
next={next === e.id}
@@ -18,6 +18,7 @@ const EventListItem = (props) => {
const {
type,
index,
eventIndex,
data,
selected,
next,
@@ -71,6 +72,7 @@ const EventListItem = (props) => {
return (
<EventBlock
index={index}
eventIndex={eventIndex}
data={data}
selected={selected}
next={next}
@@ -23,7 +23,7 @@ export default function MenuActionButtons(props) {
aria-label='Options'
size={props.size || 'xs'}
icon={<FiZap />}
_expanded={{ bg: 'pink.300', color: 'white' }}
_expanded={{ bg: 'orange.300', color: 'white' }}
_focus={{ boxShadow: 'none' }}
backgroundColor={'orange.200'}
color={'orange.500'}
+2 -2
View File
@@ -37,7 +37,7 @@ const withSocket = (Component) => {
});
const [timer, setTimer] = useState({
clock: null,
currentSeconds: null,
running: null,
startedAt: null,
expectedFinish: null,
});
@@ -221,7 +221,7 @@ const withSocket = (Component) => {
// get clock string
const timeManager = {
...timer,
finished: timer.running <= 0 && timer.startedAt,
finished: playback === 'start' && timer.running <= 0 && timer.startedAt,
clock: stringFromMillis(timer.clock),
playstate: playback,
};
@@ -42,7 +42,7 @@ export default function StageManager(props) {
// Format messages
const showPubl = publ.text !== '' && publ.visible;
let stageTimer = formatDisplay(Math.abs(time.running), true);
if (time.running < 0) stageTimer = '-' + stageTimer;
if (time.running < 0) stageTimer = `-${stageTimer}`;
// motion
const titleVariants = {
@@ -14,10 +14,9 @@ export default function PresenterView(props) {
document.title = 'ontime - Speaker Screen';
}, []);
const showOverlay = pres.text !== '' && pres.visible;
const isPlaying = time.playstate === 'start';
const isPlaying = time.playstate !== 'pause';
const normalisedTime = Math.max(time.running, 0);
// motion
const titleVariants = {
@@ -61,7 +60,7 @@ export default function PresenterView(props) {
<div className={style.finished}>TIME UP</div>
) : (
<div className={isPlaying ? style.countdown : style.countdownPaused}>
<Countdown time={time.currentSeconds} hideZeroHours />
<Countdown time={normalisedTime} hideZeroHours />
</div>
)}
</div>
@@ -73,7 +72,7 @@ export default function PresenterView(props) {
}
>
<MyProgressBar
now={time.currentSeconds}
now={normalisedTime}
complete={time.durationSeconds}
showElapsed
/>
@@ -51,11 +51,8 @@ export default function Pip(props) {
// Format messages
const showInfo =
general.backstageInfo !== '' && general.backstageInfo != null;
const stageTimer =
time.currentSeconds != null && !isNaN(time.currentSeconds)
? formatDisplay(time.currentSeconds, true)
: '';
let stageTimer = formatDisplay(Math.abs(time.running), true);
if (time.running < 0) stageTimer = `-${stageTimer}`;
return (
<div className={style.container__gray}>