mirror of
https://github.com/cpvalente/ontime.git
synced 2026-09-03 13:29:06 +00:00
refactor(operator): improvements to editing
This commit is contained in:
committed by
Carlos Valente
parent
aaeadd13cf
commit
1f2706a063
@@ -32,11 +32,11 @@
|
|||||||
margin-left: 0.25rem;
|
margin-left: 0.25rem;
|
||||||
width: 0.75em;
|
width: 0.75em;
|
||||||
height: 0.75em;
|
height: 0.75em;
|
||||||
background: var(--user-bg);
|
background: var(--user-bg, $gray-900);
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.empty {
|
.empty {
|
||||||
color: $ui-white;
|
color: $ui-white;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ export function makeCustomFieldSelectOptions(customFields: CustomFields, filterI
|
|||||||
options.push({
|
options.push({
|
||||||
value: key,
|
value: key,
|
||||||
label: value.label,
|
label: value.label,
|
||||||
colour: value.colour || 'transparent',
|
colour: value.colour,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,95 @@
|
|||||||
|
import React, { useEffect, useMemo, useRef } from 'react';
|
||||||
|
|
||||||
|
import { throttle } from '../utils/throttle';
|
||||||
|
|
||||||
|
export interface UseLongPressOptions {
|
||||||
|
/** Time in milliseconds to trigger the long press, default is 400ms */
|
||||||
|
threshold?: number;
|
||||||
|
|
||||||
|
/** Callback triggered when the long press starts */
|
||||||
|
onStart?: (event: React.MouseEvent | React.TouchEvent) => void;
|
||||||
|
|
||||||
|
/** Callback triggered when the long press finishes */
|
||||||
|
onFinish?: (event: React.MouseEvent | React.TouchEvent) => void;
|
||||||
|
|
||||||
|
/** Callback triggered when the long press is canceled */
|
||||||
|
onCancel?: (event: React.MouseEvent | React.TouchEvent) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface UseLongPressReturnValue {
|
||||||
|
onMouseDown: (event: React.MouseEvent) => void;
|
||||||
|
onMouseUp: (event: React.MouseEvent) => void;
|
||||||
|
onMouseLeave: (event: React.MouseEvent) => void;
|
||||||
|
onTouchStart: (event: React.TouchEvent) => void;
|
||||||
|
onTouchEnd: (event: React.TouchEvent) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useLongPress(
|
||||||
|
onLongPress: (event: React.MouseEvent | React.TouchEvent) => void,
|
||||||
|
options: UseLongPressOptions = {},
|
||||||
|
): UseLongPressReturnValue {
|
||||||
|
const { threshold = 700, onStart, onFinish, onCancel } = options;
|
||||||
|
const isLongPressActive = useRef(false);
|
||||||
|
const isPressed = useRef(false);
|
||||||
|
const timeout = useRef<number>(-1);
|
||||||
|
|
||||||
|
useEffect(() => () => window.clearTimeout(timeout.current), []);
|
||||||
|
|
||||||
|
return useMemo(() => {
|
||||||
|
if (typeof onLongPress !== 'function') {
|
||||||
|
return {} as UseLongPressReturnValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const start = (event: React.MouseEvent | React.TouchEvent) => {
|
||||||
|
if (!isMouseEvent(event) && !isTouchEvent(event)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (onStart) {
|
||||||
|
onStart(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
isPressed.current = true;
|
||||||
|
timeout.current = window.setTimeout(() => {
|
||||||
|
onLongPress(event);
|
||||||
|
isLongPressActive.current = true;
|
||||||
|
}, threshold);
|
||||||
|
};
|
||||||
|
|
||||||
|
const cancel = (event: React.MouseEvent | React.TouchEvent) => {
|
||||||
|
if (!isMouseEvent(event) && !isTouchEvent(event)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isLongPressActive.current) {
|
||||||
|
onFinish?.(event);
|
||||||
|
} else if (isPressed.current) {
|
||||||
|
onCancel?.(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
isLongPressActive.current = false;
|
||||||
|
isPressed.current = false;
|
||||||
|
|
||||||
|
if (timeout.current) {
|
||||||
|
window.clearTimeout(timeout.current);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
onMouseDown: start,
|
||||||
|
onMouseUp: cancel,
|
||||||
|
onMouseLeave: cancel,
|
||||||
|
onTouchStart: start,
|
||||||
|
onTouchEnd: cancel,
|
||||||
|
onTouchMove: throttle(cancel, 150),
|
||||||
|
};
|
||||||
|
}, [onLongPress, threshold, onCancel, onFinish, onStart]);
|
||||||
|
}
|
||||||
|
|
||||||
|
function isTouchEvent(event: React.MouseEvent | React.TouchEvent): event is React.TouchEvent {
|
||||||
|
return window.TouchEvent ? event.nativeEvent instanceof TouchEvent : 'touches' in event.nativeEvent;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isMouseEvent(event: React.MouseEvent | React.TouchEvent): event is React.MouseEvent {
|
||||||
|
return event.nativeEvent instanceof MouseEvent;
|
||||||
|
}
|
||||||
@@ -30,12 +30,12 @@
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 0.5rem;
|
gap: 0.5rem;
|
||||||
|
|
||||||
max-height: min(80vh, 600px);
|
max-height: min(60vh, 600px);
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.label {
|
.label {
|
||||||
background-color: var(--user-bg);
|
background-color: var(--user-bg, $gray-900);
|
||||||
width: fit-content;
|
width: fit-content;
|
||||||
padding-inline: 1rem;
|
padding-inline: 1rem;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import { memo, RefObject, SyntheticEvent } from 'react';
|
import { memo, RefObject, SyntheticEvent } from 'react';
|
||||||
import { useLongPress } from '@mantine/hooks';
|
|
||||||
import { MILLIS_PER_MINUTE, MILLIS_PER_SECOND } from 'ontime-utils';
|
import { MILLIS_PER_MINUTE, MILLIS_PER_SECOND } from 'ontime-utils';
|
||||||
|
|
||||||
import DelayIndicator from '../../../common/components/delay-indicator/DelayIndicator';
|
import DelayIndicator from '../../../common/components/delay-indicator/DelayIndicator';
|
||||||
|
import { useLongPress } from '../../../common/hooks/useLongPress';
|
||||||
import { cx, getAccessibleColour } from '../../../common/utils/styleUtils';
|
import { cx, getAccessibleColour } from '../../../common/utils/styleUtils';
|
||||||
import { formatDuration, formatTime, useTimeUntilExpectedStart } from '../../../common/utils/time';
|
import { formatDuration, formatTime, useTimeUntilExpectedStart } from '../../../common/utils/time';
|
||||||
import RunningTime from '../../viewers/common/running-time/RunningTime';
|
import RunningTime from '../../viewers/common/running-time/RunningTime';
|
||||||
@@ -55,8 +55,10 @@ function OperatorEvent({
|
|||||||
* gather behaviour for long press and context menu
|
* gather behaviour for long press and context menu
|
||||||
*/
|
*/
|
||||||
const handleLongPress = (event?: SyntheticEvent) => {
|
const handleLongPress = (event?: SyntheticEvent) => {
|
||||||
// we dont have an event out of useLongPress
|
// prevent default if the event is cancelable to avoid browser intervention warnings
|
||||||
event?.preventDefault();
|
if (event && event.cancelable) {
|
||||||
|
event.preventDefault();
|
||||||
|
}
|
||||||
if (subscribed) {
|
if (subscribed) {
|
||||||
onLongPress({ id, cue, subscriptions: subscribed });
|
onLongPress({ id, cue, subscriptions: subscribed });
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user