mirror of
https://github.com/mediacms-io/mediacms.git
synced 2025-11-06 07:28:53 -05:00
fix: Delete the 500ms when you want to extend the segment and there is no space to create new segment
This commit is contained in:
parent
ef3b93995a
commit
95fdfdbcc8
@ -1010,35 +1010,42 @@ const TimelineControls = ({
|
|||||||
|
|
||||||
// Helper function to calculate available space for a new segment
|
// Helper function to calculate available space for a new segment
|
||||||
const calculateAvailableSpace = (startTime: number): number => {
|
const calculateAvailableSpace = (startTime: number): number => {
|
||||||
|
// Always return at least 0.1 seconds to ensure tooltip shows
|
||||||
|
const MIN_SPACE = 0.1;
|
||||||
|
|
||||||
// Determine the amount of available space:
|
// Determine the amount of available space:
|
||||||
// 1. Check remaining space until the end of video
|
// 1. Check remaining space until the end of video
|
||||||
const remainingDuration = Math.max(0, duration - startTime);
|
const remainingDuration = Math.max(0, duration - startTime);
|
||||||
|
|
||||||
// Special case: If we're very close to the end of the video (within 300ms)
|
// Special case: If we're very close to the end of the video (within 300ms)
|
||||||
// return a small value to ensure the tooltip can still be shown
|
|
||||||
if (duration - startTime < 0.3) {
|
if (duration - startTime < 0.3) {
|
||||||
logger.debug("Very close to end of video, ensuring tooltip can show:",
|
logger.debug("Very close to end of video, ensuring tooltip can show:",
|
||||||
formatDetailedTime(startTime), "video end:", formatDetailedTime(duration));
|
formatDetailedTime(startTime), "video end:", formatDetailedTime(duration));
|
||||||
return Math.max(0.5, remainingDuration); // Use actual remaining duration if larger
|
return Math.max(MIN_SPACE, remainingDuration);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. Find the next segment (if any)
|
// 2. Find the next segment (if any)
|
||||||
const sortedSegments = [...clipSegments].sort((a, b) => a.startTime - b.startTime);
|
const sortedSegments = [...clipSegments].sort((a, b) => a.startTime - b.startTime);
|
||||||
|
|
||||||
// Check if we're in a cutaway area near a segment boundary
|
// Special case: If we're before the first segment
|
||||||
// Use a larger tolerance (100ms) for boundary detection
|
if (sortedSegments.length > 0 && startTime < sortedSegments[0].startTime) {
|
||||||
const isNearSegmentBoundary = sortedSegments.some(seg => {
|
const spaceUntilFirstSegment = sortedSegments[0].startTime - startTime;
|
||||||
|
logger.debug("Before first segment, space available:", formatDetailedTime(spaceUntilFirstSegment));
|
||||||
|
return Math.max(MIN_SPACE, spaceUntilFirstSegment);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if we're in a cutaway area near any segment boundary
|
||||||
|
const isNearSegment = sortedSegments.some(seg => {
|
||||||
const distanceToStart = Math.abs(startTime - seg.startTime);
|
const distanceToStart = Math.abs(startTime - seg.startTime);
|
||||||
const distanceToEnd = Math.abs(startTime - seg.endTime);
|
const distanceToEnd = Math.abs(startTime - seg.endTime);
|
||||||
// Consider both start and end boundaries with different tolerances
|
// Use a larger tolerance (300ms) for boundary detection
|
||||||
return (distanceToStart < 0.1 && distanceToStart > 0) || // Near start but not exactly at it
|
return distanceToStart < 0.3 || distanceToEnd < 0.3;
|
||||||
(distanceToEnd < 0.1 && distanceToEnd > 0); // Near end but not exactly at it
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// If we're near a segment boundary in cutaway area, ensure tooltip shows
|
// If we're near any segment, ensure tooltip shows
|
||||||
if (isNearSegmentBoundary) {
|
if (isNearSegment) {
|
||||||
logger.debug("Near segment boundary in cutaway area:", formatDetailedTime(startTime));
|
logger.debug("Near segment boundary:", formatDetailedTime(startTime));
|
||||||
return 0.5; // Minimum value to show tooltip
|
return MIN_SPACE;
|
||||||
}
|
}
|
||||||
|
|
||||||
const nextSegment = sortedSegments.find(seg => seg.startTime > startTime);
|
const nextSegment = sortedSegments.find(seg => seg.startTime > startTime);
|
||||||
@ -1047,22 +1054,15 @@ const TimelineControls = ({
|
|||||||
if (nextSegment) {
|
if (nextSegment) {
|
||||||
// Space available until the next segment starts
|
// Space available until the next segment starts
|
||||||
const spaceUntilNextSegment = Math.max(0, nextSegment.startTime - startTime);
|
const spaceUntilNextSegment = Math.max(0, nextSegment.startTime - startTime);
|
||||||
// If we're very close to the next segment, ensure tooltip still shows
|
// Always ensure minimum space to show tooltip
|
||||||
if (spaceUntilNextSegment < 0.1) {
|
return Math.max(MIN_SPACE, Math.min(30, spaceUntilNextSegment));
|
||||||
return 0.5;
|
|
||||||
}
|
|
||||||
return Math.min(30, spaceUntilNextSegment); // Take either 30s or available space, whichever is smaller
|
|
||||||
} else if (prevSegment) {
|
} else if (prevSegment) {
|
||||||
// We're after the last segment, use remaining duration
|
// We're after the last segment, use remaining duration
|
||||||
const spaceAfterPrevSegment = Math.max(0, duration - startTime);
|
const spaceAfterPrevSegment = Math.max(0, duration - startTime);
|
||||||
// If we're very close to the previous segment's end, ensure tooltip shows
|
return Math.max(MIN_SPACE, Math.min(30, spaceAfterPrevSegment));
|
||||||
if (startTime - prevSegment.endTime < 0.1) {
|
|
||||||
return 0.5;
|
|
||||||
}
|
|
||||||
return Math.min(30, spaceAfterPrevSegment);
|
|
||||||
} else {
|
} else {
|
||||||
// No segments at all, use remaining duration
|
// No segments at all, use remaining duration
|
||||||
return Math.min(30, remainingDuration);
|
return Math.max(MIN_SPACE, Math.min(30, remainingDuration));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1083,14 +1083,9 @@ const TimelineControls = ({
|
|||||||
const availableSpace = calculateAvailableSpace(currentPosition);
|
const availableSpace = calculateAvailableSpace(currentPosition);
|
||||||
setAvailableSegmentDuration(availableSpace);
|
setAvailableSegmentDuration(availableSpace);
|
||||||
|
|
||||||
// Only show tooltip if there's enough space for a minimal segment
|
// Always show tooltip in empty spaces
|
||||||
if (availableSpace >= 0.5) {
|
setSelectedSegmentId(null);
|
||||||
setSelectedSegmentId(null);
|
setShowEmptySpaceTooltip(true);
|
||||||
setShowEmptySpaceTooltip(true);
|
|
||||||
} else {
|
|
||||||
setSelectedSegmentId(null);
|
|
||||||
setShowEmptySpaceTooltip(false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update tooltip position
|
// Update tooltip position
|
||||||
@ -2054,30 +2049,7 @@ const TimelineControls = ({
|
|||||||
isDraggingRef.current = true; // Use ref for immediate value access
|
isDraggingRef.current = true; // Use ref for immediate value access
|
||||||
|
|
||||||
// Show tooltip immediately when starting to drag
|
// Show tooltip immediately when starting to drag
|
||||||
// Find the segment at the current time using improved matching
|
updateTooltipForPosition(currentTime);
|
||||||
const segmentAtCurrentTime = clipSegments.find(seg => {
|
|
||||||
const isWithinSegment = currentTime >= seg.startTime && currentTime <= seg.endTime;
|
|
||||||
const isAtExactStart = Math.abs(currentTime - seg.startTime) < 0.001; // Within 1ms of start
|
|
||||||
const isAtExactEnd = Math.abs(currentTime - seg.endTime) < 0.001; // Within 1ms of end
|
|
||||||
return isWithinSegment || isAtExactStart || isAtExactEnd;
|
|
||||||
});
|
|
||||||
|
|
||||||
if (segmentAtCurrentTime) {
|
|
||||||
// Show segment tooltip
|
|
||||||
setSelectedSegmentId(segmentAtCurrentTime.id);
|
|
||||||
setShowEmptySpaceTooltip(false);
|
|
||||||
} else {
|
|
||||||
// Calculate available space for new segment before showing tooltip
|
|
||||||
const availableSpace = calculateAvailableSpace(currentTime);
|
|
||||||
setAvailableSegmentDuration(availableSpace);
|
|
||||||
|
|
||||||
// Only show tooltip if there's enough space for a minimal segment
|
|
||||||
if (availableSpace >= 0.5) {
|
|
||||||
// Show empty space tooltip
|
|
||||||
setSelectedSegmentId(null);
|
|
||||||
setShowEmptySpaceTooltip(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle mouse events
|
// Handle mouse events
|
||||||
const handleMouseMove = (moveEvent: MouseEvent) => {
|
const handleMouseMove = (moveEvent: MouseEvent) => {
|
||||||
@ -2103,7 +2075,7 @@ const TimelineControls = ({
|
|||||||
// Convert to time and seek
|
// Convert to time and seek
|
||||||
const newTime = position * duration;
|
const newTime = position * duration;
|
||||||
|
|
||||||
// Update both clicked time and display time to show the current position in tooltip
|
// Update both clicked time and display time
|
||||||
setClickedTime(newTime);
|
setClickedTime(newTime);
|
||||||
setDisplayTime(newTime);
|
setDisplayTime(newTime);
|
||||||
|
|
||||||
@ -2119,85 +2091,6 @@ const TimelineControls = ({
|
|||||||
onSeek(newTime);
|
onSeek(newTime);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Handle touch move events
|
|
||||||
const handleTouchMove = (moveEvent: TouchEvent) => {
|
|
||||||
if (!timelineRef.current || !scrollContainerRef.current || !moveEvent.touches[0]) return;
|
|
||||||
|
|
||||||
// Calculate the position based on touch coordinates
|
|
||||||
const rect = timelineRef.current.getBoundingClientRect();
|
|
||||||
let position;
|
|
||||||
|
|
||||||
if (zoomLevel > 1) {
|
|
||||||
// When zoomed, account for scroll position
|
|
||||||
const scrollLeft = scrollContainerRef.current.scrollLeft;
|
|
||||||
const totalWidth = timelineRef.current.clientWidth;
|
|
||||||
position = (moveEvent.touches[0].clientX - rect.left + scrollLeft) / totalWidth;
|
|
||||||
} else {
|
|
||||||
// Normal calculation for 1x zoom
|
|
||||||
position = (moveEvent.touches[0].clientX - rect.left) / rect.width;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Constrain position between 0 and 1
|
|
||||||
position = Math.max(0, Math.min(1, position));
|
|
||||||
|
|
||||||
// Convert to time and seek
|
|
||||||
const newTime = position * duration;
|
|
||||||
|
|
||||||
// Update both clicked time and display time to show the current position in tooltip
|
|
||||||
setClickedTime(newTime);
|
|
||||||
setDisplayTime(newTime);
|
|
||||||
|
|
||||||
// Check if we're in a segment to show the appropriate tooltip
|
|
||||||
const segmentAtTime = clipSegments.find(
|
|
||||||
seg => newTime >= seg.startTime && newTime <= seg.endTime
|
|
||||||
);
|
|
||||||
|
|
||||||
// Calculate available space for new segment if needed
|
|
||||||
const availableSpace = segmentAtTime ? 0 : calculateAvailableSpace(newTime);
|
|
||||||
|
|
||||||
if (segmentAtTime) {
|
|
||||||
// Show segment tooltip
|
|
||||||
setSelectedSegmentId(segmentAtTime.id);
|
|
||||||
setShowEmptySpaceTooltip(false);
|
|
||||||
} else if (availableSpace >= 0.5) {
|
|
||||||
// Only show tooltip if there's enough space for a minimal segment
|
|
||||||
// Show empty space tooltip
|
|
||||||
setSelectedSegmentId(null);
|
|
||||||
setShowEmptySpaceTooltip(true);
|
|
||||||
setAvailableSegmentDuration(availableSpace);
|
|
||||||
} else {
|
|
||||||
// Not enough space, don't show tooltip
|
|
||||||
setSelectedSegmentId(null);
|
|
||||||
setShowEmptySpaceTooltip(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Calculate and update tooltip position
|
|
||||||
if ((segmentAtTime || availableSpace >= 0.5) && timelineRef.current) {
|
|
||||||
const timelineRect = timelineRef.current.getBoundingClientRect();
|
|
||||||
let xPos = moveEvent.touches[0].clientX; // Default to touch position
|
|
||||||
|
|
||||||
if (zoomLevel > 1 && scrollContainerRef.current) {
|
|
||||||
// For zoomed timeline, adjust for scroll position
|
|
||||||
const visibleTimelineLeft = timelineRect.left - scrollContainerRef.current.scrollLeft;
|
|
||||||
const percentPos = newTime / duration;
|
|
||||||
xPos = visibleTimelineLeft + (timelineRect.width * percentPos);
|
|
||||||
}
|
|
||||||
|
|
||||||
setTooltipPosition({
|
|
||||||
x: xPos,
|
|
||||||
y: timelineRect.top - 10
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Store position globally for mobile browsers
|
|
||||||
if (typeof window !== 'undefined') {
|
|
||||||
(window as any).lastSeekedPosition = newTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Seek to the new position
|
|
||||||
onSeek(newTime);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Handle mouse up to stop dragging
|
// Handle mouse up to stop dragging
|
||||||
const handleMouseUp = () => {
|
const handleMouseUp = () => {
|
||||||
setIsDragging(false);
|
setIsDragging(false);
|
||||||
@ -2209,10 +2102,6 @@ const TimelineControls = ({
|
|||||||
// Add event listeners to track movement and release
|
// Add event listeners to track movement and release
|
||||||
document.addEventListener('mousemove', handleMouseMove);
|
document.addEventListener('mousemove', handleMouseMove);
|
||||||
document.addEventListener('mouseup', handleMouseUp);
|
document.addEventListener('mouseup', handleMouseUp);
|
||||||
// Remove these incorrect event listeners that were causing linter errors
|
|
||||||
// document.addEventListener('touchmove', handleTouchMove, { passive: false });
|
|
||||||
// document.addEventListener('touchend', handleTouchEnd);
|
|
||||||
// document.addEventListener('touchcancel', handleTouchEnd);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Handle touch events for mobile devices
|
// Handle touch events for mobile devices
|
||||||
@ -2223,35 +2112,13 @@ const TimelineControls = ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
e.stopPropagation(); // Don't trigger the timeline click
|
e.stopPropagation(); // Don't trigger the timeline click
|
||||||
|
e.preventDefault(); // Prevent text selection during drag
|
||||||
|
|
||||||
setIsDragging(true);
|
setIsDragging(true);
|
||||||
isDraggingRef.current = true; // Use ref for immediate value access
|
isDraggingRef.current = true; // Use ref for immediate value access
|
||||||
|
|
||||||
// Show tooltip immediately when starting to drag
|
// Show tooltip immediately when starting to drag
|
||||||
// Find the segment at the current time using improved matching
|
updateTooltipForPosition(currentTime);
|
||||||
const segmentAtCurrentTime = clipSegments.find(seg => {
|
|
||||||
const isWithinSegment = currentTime >= seg.startTime && currentTime <= seg.endTime;
|
|
||||||
const isAtExactStart = Math.abs(currentTime - seg.startTime) < 0.001; // Within 1ms of start
|
|
||||||
const isAtExactEnd = Math.abs(currentTime - seg.endTime) < 0.001; // Within 1ms of end
|
|
||||||
return isWithinSegment || isAtExactStart || isAtExactEnd;
|
|
||||||
});
|
|
||||||
|
|
||||||
if (segmentAtCurrentTime) {
|
|
||||||
// Show segment tooltip
|
|
||||||
setSelectedSegmentId(segmentAtCurrentTime.id);
|
|
||||||
setShowEmptySpaceTooltip(false);
|
|
||||||
} else {
|
|
||||||
// Calculate available space for new segment before showing tooltip
|
|
||||||
const availableSpace = calculateAvailableSpace(currentTime);
|
|
||||||
setAvailableSegmentDuration(availableSpace);
|
|
||||||
|
|
||||||
// Only show tooltip if there's enough space for a minimal segment
|
|
||||||
if (availableSpace >= 0.5) {
|
|
||||||
// Show empty space tooltip
|
|
||||||
setSelectedSegmentId(null);
|
|
||||||
setShowEmptySpaceTooltip(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle touch move events
|
// Handle touch move events
|
||||||
const handleTouchMove = (moveEvent: TouchEvent) => {
|
const handleTouchMove = (moveEvent: TouchEvent) => {
|
||||||
@ -2277,7 +2144,7 @@ const TimelineControls = ({
|
|||||||
// Convert to time and seek
|
// Convert to time and seek
|
||||||
const newTime = position * duration;
|
const newTime = position * duration;
|
||||||
|
|
||||||
// Update both clicked time and display time to show the current position in tooltip
|
// Update both clicked time and display time
|
||||||
setClickedTime(newTime);
|
setClickedTime(newTime);
|
||||||
setDisplayTime(newTime);
|
setDisplayTime(newTime);
|
||||||
|
|
||||||
@ -3341,7 +3208,7 @@ const TimelineControls = ({
|
|||||||
<button
|
<button
|
||||||
className={`tooltip-action-btn ${isPlaying ? 'pause' : 'play'}`}
|
className={`tooltip-action-btn ${isPlaying ? 'pause' : 'play'}`}
|
||||||
data-tooltip={isPlaying ? "Pause playback" : "Play from here until next segment"}
|
data-tooltip={isPlaying ? "Pause playback" : "Play from here until next segment"}
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
|
|
||||||
if (isPlaying) {
|
if (isPlaying) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user