mirror of
https://github.com/mediacms-io/mediacms.git
synced 2025-11-09 17:08:58 -05:00
Update TimelineControls.tsx
This commit is contained in:
parent
c21a520a47
commit
4cdfdb8354
@ -145,29 +145,20 @@ const TimelineControls = ({
|
|||||||
const handleContinuousTimeAdjustment = (offsetSeconds: number) => {
|
const handleContinuousTimeAdjustment = (offsetSeconds: number) => {
|
||||||
// Fixed adjustment amount - exactly 50ms each time
|
// Fixed adjustment amount - exactly 50ms each time
|
||||||
const adjustmentValue = offsetSeconds;
|
const adjustmentValue = offsetSeconds;
|
||||||
// Hold timer
|
// Hold timer for continuous adjustment
|
||||||
let holdTimer: number | null = null;
|
let holdTimer: NodeJS.Timeout | null = null;
|
||||||
|
let continuousTimer: NodeJS.Timeout | null = null;
|
||||||
// Store the last time value to correctly calculate the next increment
|
// Store the last time value to correctly calculate the next increment
|
||||||
let lastTimeValue = clickedTime;
|
let lastTimeValue = clickedTime;
|
||||||
|
|
||||||
// Function to perform time adjustment
|
// Function to perform time adjustment
|
||||||
const adjustTime = () => {
|
const adjustTime = () => {
|
||||||
// Always use the last time value for calculations to prevent stalling
|
|
||||||
const currentTime = lastTimeValue;
|
|
||||||
|
|
||||||
// Calculate new time based on fixed offset (positive or negative)
|
// Calculate new time based on fixed offset (positive or negative)
|
||||||
const newTime = adjustmentValue < 0
|
const newTime = adjustmentValue < 0
|
||||||
? Math.max(0, currentTime + adjustmentValue) // For negative offsets (going back)
|
? Math.max(0, lastTimeValue + adjustmentValue) // For negative offsets (going back)
|
||||||
: Math.min(duration, currentTime + adjustmentValue); // For positive offsets (going forward)
|
: Math.min(duration, lastTimeValue + adjustmentValue); // For positive offsets (going forward)
|
||||||
|
|
||||||
// Check if we've reached a boundary
|
// Update our last time value for next adjustment
|
||||||
if ((adjustmentValue < 0 && newTime <= 0) ||
|
|
||||||
(adjustmentValue > 0 && newTime >= duration)) {
|
|
||||||
// If we hit a boundary, we'll still update the display but keep the same value
|
|
||||||
// Don't clear the timer - it allows for adjusting back from the boundary
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update our last time value
|
|
||||||
lastTimeValue = newTime;
|
lastTimeValue = newTime;
|
||||||
|
|
||||||
// Save the current playing state before seeking
|
// Save the current playing state before seeking
|
||||||
@ -180,7 +171,7 @@ const TimelineControls = ({
|
|||||||
setClickedTime(newTime);
|
setClickedTime(newTime);
|
||||||
setDisplayTime(newTime);
|
setDisplayTime(newTime);
|
||||||
|
|
||||||
// Update tooltip position and type during drag
|
// Update tooltip position
|
||||||
if (timelineRef.current) {
|
if (timelineRef.current) {
|
||||||
const rect = timelineRef.current.getBoundingClientRect();
|
const rect = timelineRef.current.getBoundingClientRect();
|
||||||
const positionPercent = (newTime / duration) * 100;
|
const positionPercent = (newTime / duration) * 100;
|
||||||
@ -190,25 +181,19 @@ const TimelineControls = ({
|
|||||||
y: rect.top - 10
|
y: rect.top - 10
|
||||||
});
|
});
|
||||||
|
|
||||||
// Create a temporary segment with the current drag position
|
// Find if we're in a segment at the new time
|
||||||
const draggedSegment = {
|
const segmentAtTime = clipSegments.find(
|
||||||
...segment,
|
seg => newTime >= seg.startTime && newTime <= seg.endTime
|
||||||
startTime: isLeft ? newTime : segment.startTime,
|
);
|
||||||
endTime: isLeft ? segment.endTime : newTime
|
|
||||||
};
|
|
||||||
|
|
||||||
// Check if the current marker position (currentTime) is within the dragged segment
|
if (segmentAtTime) {
|
||||||
const isMarkerInSegment = currentTime >= draggedSegment.startTime && currentTime <= draggedSegment.endTime;
|
// Show segment tooltip
|
||||||
|
setSelectedSegmentId(segmentAtTime.id);
|
||||||
if (isMarkerInSegment) {
|
|
||||||
// Show segment tooltip if marker is inside the segment
|
|
||||||
setSelectedSegmentId(segment.id);
|
|
||||||
setShowEmptySpaceTooltip(false);
|
setShowEmptySpaceTooltip(false);
|
||||||
} else {
|
} else {
|
||||||
// Show cutaway tooltip if marker is outside the segment
|
// Show cutaway tooltip
|
||||||
setSelectedSegmentId(null);
|
setSelectedSegmentId(null);
|
||||||
// Calculate available space for cutaway tooltip
|
const availableSpace = calculateAvailableSpace(newTime);
|
||||||
const availableSpace = calculateAvailableSpace(currentTime);
|
|
||||||
setAvailableSegmentDuration(availableSpace);
|
setAvailableSegmentDuration(availableSpace);
|
||||||
setShowEmptySpaceTooltip(true);
|
setShowEmptySpaceTooltip(true);
|
||||||
}
|
}
|
||||||
@ -221,7 +206,7 @@ const TimelineControls = ({
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Return mouse event handlers
|
// Return mouse event handlers with touch support
|
||||||
return {
|
return {
|
||||||
onMouseDown: (e: React.MouseEvent) => {
|
onMouseDown: (e: React.MouseEvent) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
@ -233,19 +218,22 @@ const TimelineControls = ({
|
|||||||
// Perform initial adjustment
|
// Perform initial adjustment
|
||||||
adjustTime();
|
adjustTime();
|
||||||
|
|
||||||
// Start continuous adjustment after a short delay
|
// Start continuous adjustment after 1.5s hold
|
||||||
holdTimer = window.setTimeout(() => {
|
holdTimer = setTimeout(() => {
|
||||||
// Start consistent intervals at a moderate pace (exactly 8 adjustments per second)
|
// After 1.5s delay, start adjusting at a slower pace (every 200ms)
|
||||||
// This ensures it adds/subtracts exactly 50ms at a steady, countable pace
|
continuousTimer = setInterval(adjustTime, 200);
|
||||||
holdTimer = window.setInterval(adjustTime, 125);
|
}, 750);
|
||||||
}, 250);
|
|
||||||
|
|
||||||
// Add mouse up and leave handlers to document to ensure we catch the release
|
// Add mouse up and leave handlers to document to ensure we catch the release
|
||||||
const clearTimers = () => {
|
const clearTimers = () => {
|
||||||
if (holdTimer) {
|
if (holdTimer) {
|
||||||
clearInterval(holdTimer);
|
clearTimeout(holdTimer);
|
||||||
holdTimer = null;
|
holdTimer = null;
|
||||||
}
|
}
|
||||||
|
if (continuousTimer) {
|
||||||
|
clearInterval(continuousTimer);
|
||||||
|
continuousTimer = null;
|
||||||
|
}
|
||||||
document.removeEventListener('mouseup', clearTimers);
|
document.removeEventListener('mouseup', clearTimers);
|
||||||
document.removeEventListener('mouseleave', clearTimers);
|
document.removeEventListener('mouseleave', clearTimers);
|
||||||
};
|
};
|
||||||
@ -253,6 +241,39 @@ const TimelineControls = ({
|
|||||||
document.addEventListener('mouseup', clearTimers);
|
document.addEventListener('mouseup', clearTimers);
|
||||||
document.addEventListener('mouseleave', clearTimers);
|
document.addEventListener('mouseleave', clearTimers);
|
||||||
},
|
},
|
||||||
|
onTouchStart: (e: React.TouchEvent) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
e.preventDefault();21
|
||||||
|
|
||||||
|
// Update the initial last time value
|
||||||
|
lastTimeValue = clickedTime;
|
||||||
|
|
||||||
|
// Perform initial adjustment
|
||||||
|
adjustTime();
|
||||||
|
|
||||||
|
// Start continuous adjustment after 1.5s hold
|
||||||
|
holdTimer = setTimeout(() => {
|
||||||
|
// After 1.5s delay, start adjusting at a slower pace (every 200ms)
|
||||||
|
continuousTimer = setInterval(adjustTime, 200);
|
||||||
|
}, 750);
|
||||||
|
|
||||||
|
// Add touch end handler to ensure we catch the release
|
||||||
|
const clearTimers = () => {
|
||||||
|
if (holdTimer) {
|
||||||
|
clearTimeout(holdTimer);
|
||||||
|
holdTimer = null;
|
||||||
|
}
|
||||||
|
if (continuousTimer) {
|
||||||
|
clearInterval(continuousTimer);
|
||||||
|
continuousTimer = null;
|
||||||
|
}
|
||||||
|
document.removeEventListener('touchend', clearTimers);
|
||||||
|
document.removeEventListener('touchcancel', clearTimers);
|
||||||
|
};
|
||||||
|
|
||||||
|
document.addEventListener('touchend', clearTimers);
|
||||||
|
document.addEventListener('touchcancel', clearTimers);
|
||||||
|
},
|
||||||
onClick: (e: React.MouseEvent) => {
|
onClick: (e: React.MouseEvent) => {
|
||||||
// This prevents the click event from firing twice
|
// This prevents the click event from firing twice
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
@ -2483,6 +2504,14 @@ const TimelineControls = ({
|
|||||||
className="tooltip-time-btn"
|
className="tooltip-time-btn"
|
||||||
data-tooltip="Decrease by 50ms (hold for continuous adjustment)"
|
data-tooltip="Decrease by 50ms (hold for continuous adjustment)"
|
||||||
{...handleContinuousTimeAdjustment(-0.05)}
|
{...handleContinuousTimeAdjustment(-0.05)}
|
||||||
|
style={{
|
||||||
|
userSelect: 'none',
|
||||||
|
WebkitUserSelect: 'none',
|
||||||
|
WebkitTouchCallout: 'none',
|
||||||
|
touchAction: 'manipulation',
|
||||||
|
cursor: 'pointer',
|
||||||
|
WebkitTapHighlightColor: 'transparent'
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
-50ms
|
-50ms
|
||||||
</button>
|
</button>
|
||||||
@ -2491,6 +2520,14 @@ const TimelineControls = ({
|
|||||||
className="tooltip-time-btn"
|
className="tooltip-time-btn"
|
||||||
data-tooltip="Increase by 50ms (hold for continuous adjustment)"
|
data-tooltip="Increase by 50ms (hold for continuous adjustment)"
|
||||||
{...handleContinuousTimeAdjustment(0.05)}
|
{...handleContinuousTimeAdjustment(0.05)}
|
||||||
|
style={{
|
||||||
|
userSelect: 'none',
|
||||||
|
WebkitUserSelect: 'none',
|
||||||
|
WebkitTouchCallout: 'none',
|
||||||
|
touchAction: 'manipulation',
|
||||||
|
cursor: 'pointer',
|
||||||
|
WebkitTapHighlightColor: 'transparent'
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
+50ms
|
+50ms
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user