mirror of
https://github.com/mediacms-io/mediacms.git
synced 2025-11-11 09:58:53 -05:00
feat: In Preview mode, you can jump in timeline to review the edits
In Preview mode, you can jump in timeline to review the edits, without having to listen to the full video.
This commit is contained in:
parent
c989b1515e
commit
321287d009
@ -1201,10 +1201,40 @@ const TimelineControls = ({
|
|||||||
setActiveSegment(segmentAtClickedTime);
|
setActiveSegment(segmentAtClickedTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resume playback in two cases:
|
// Resume playback based on the current mode
|
||||||
|
if (videoRef.current) {
|
||||||
|
// Special handling for segments playback mode
|
||||||
|
if (isPlayingSegments && wasPlaying) {
|
||||||
|
// Update the current segment index if we clicked into a segment
|
||||||
|
if (segmentAtClickedTime) {
|
||||||
|
const orderedSegments = [...clipSegments].sort((a, b) => a.startTime - b.startTime);
|
||||||
|
const targetSegmentIndex = orderedSegments.findIndex(seg => seg.id === segmentAtClickedTime.id);
|
||||||
|
|
||||||
|
if (targetSegmentIndex !== -1) {
|
||||||
|
// Dispatch a custom event to update the current segment index
|
||||||
|
const updateSegmentIndexEvent = new CustomEvent('update-segment-index', {
|
||||||
|
detail: { segmentIndex: targetSegmentIndex }
|
||||||
|
});
|
||||||
|
document.dispatchEvent(updateSegmentIndexEvent);
|
||||||
|
logger.debug(`Segments playback mode: updating segment index to ${targetSegmentIndex} for timeline click in segment ${segmentAtClickedTime.id}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.debug("Segments playback mode: resuming playback after timeline click");
|
||||||
|
videoRef.current.play()
|
||||||
|
.then(() => {
|
||||||
|
setIsPlayingSegment(true);
|
||||||
|
logger.debug("Resumed segments playback after timeline seeking");
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
console.error("Error resuming segments playback:", err);
|
||||||
|
setIsPlayingSegment(false);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// Resume playback in two cases (but not during segments playback):
|
||||||
// 1. If it was playing before (regular playback)
|
// 1. If it was playing before (regular playback)
|
||||||
// 2. If we're in preview mode (regardless of previous playing state)
|
// 2. If we're in preview mode (regardless of previous playing state)
|
||||||
if ((wasPlaying || isPreviewMode) && videoRef.current) {
|
else if ((wasPlaying || isPreviewMode) && !isPlayingSegments) {
|
||||||
logger.debug("Resuming playback after timeline click");
|
logger.debug("Resuming playback after timeline click");
|
||||||
videoRef.current.play()
|
videoRef.current.play()
|
||||||
.then(() => {
|
.then(() => {
|
||||||
@ -1216,6 +1246,7 @@ const TimelineControls = ({
|
|||||||
setIsPlayingSegment(false);
|
setIsPlayingSegment(false);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Only process tooltip display if clicked on the timeline background or thumbnails, not on other UI elements
|
// Only process tooltip display if clicked on the timeline background or thumbnails, not on other UI elements
|
||||||
if (e.target === timelineRef.current || (e.target as HTMLElement).classList.contains('timeline-thumbnail')) {
|
if (e.target === timelineRef.current || (e.target as HTMLElement).classList.contains('timeline-thumbnail')) {
|
||||||
@ -1678,8 +1709,37 @@ const TimelineControls = ({
|
|||||||
// Seek to this position (this will update the video's current time)
|
// Seek to this position (this will update the video's current time)
|
||||||
onSeek(boundedTime);
|
onSeek(boundedTime);
|
||||||
|
|
||||||
// If video was playing before OR we're in preview mode, ensure it continues playing
|
// Handle playback continuation based on the current mode
|
||||||
if ((wasPlaying || isPreviewMode) && videoRef.current) {
|
if (videoRef.current) {
|
||||||
|
// Special handling for segments playback mode
|
||||||
|
if (isPlayingSegments && wasPlaying) {
|
||||||
|
// Update the current segment index for segments playback mode
|
||||||
|
const orderedSegments = [...clipSegments].sort((a, b) => a.startTime - b.startTime);
|
||||||
|
const targetSegmentIndex = orderedSegments.findIndex(seg => seg.id === segmentId);
|
||||||
|
|
||||||
|
if (targetSegmentIndex !== -1) {
|
||||||
|
// Dispatch a custom event to update the current segment index
|
||||||
|
const updateSegmentIndexEvent = new CustomEvent('update-segment-index', {
|
||||||
|
detail: { segmentIndex: targetSegmentIndex }
|
||||||
|
});
|
||||||
|
document.dispatchEvent(updateSegmentIndexEvent);
|
||||||
|
logger.debug(`Segments playback mode: updating segment index to ${targetSegmentIndex} for segment ${segmentId}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// In segments playback mode, we want to continue the segments playback from the new position
|
||||||
|
// The segments playback will naturally handle continuing to the next segments
|
||||||
|
logger.debug("Segments playback mode: continuing playback from new position");
|
||||||
|
videoRef.current.play()
|
||||||
|
.then(() => {
|
||||||
|
setIsPlayingSegment(true);
|
||||||
|
logger.debug("Continued segments playback after segment click");
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
console.error("Error continuing segments playback after segment click:", err);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// If video was playing before OR we're in preview mode, ensure it continues playing (but not in segments mode)
|
||||||
|
else if ((wasPlaying || isPreviewMode) && !isPlayingSegments) {
|
||||||
// Set current segment as active segment for boundary checking
|
// Set current segment as active segment for boundary checking
|
||||||
setActiveSegment(segment);
|
setActiveSegment(segment);
|
||||||
// Reset the continuePastBoundary flag when clicking on a segment to ensure boundaries work
|
// Reset the continuePastBoundary flag when clicking on a segment to ensure boundaries work
|
||||||
@ -1694,9 +1754,8 @@ const TimelineControls = ({
|
|||||||
console.error("Error resuming playback after segment click:", err);
|
console.error("Error resuming playback after segment click:", err);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
// Always continue playback in preview mode, even if video was paused when clicking (but not in segments mode)
|
||||||
// Always continue playback in preview mode, even if video was paused when clicking
|
else if (isPreviewMode && !isPlayingSegments) {
|
||||||
if (isPreviewMode && videoRef.current) {
|
|
||||||
setActiveSegment(segment);
|
setActiveSegment(segment);
|
||||||
videoRef.current.play()
|
videoRef.current.play()
|
||||||
.then(() => {
|
.then(() => {
|
||||||
@ -1707,6 +1766,7 @@ const TimelineControls = ({
|
|||||||
console.error("Error continuing preview playback:", err);
|
console.error("Error continuing preview playback:", err);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Calculate tooltip position directly above click point
|
// Calculate tooltip position directly above click point
|
||||||
const tooltipX = e.clientX;
|
const tooltipX = e.clientX;
|
||||||
|
|||||||
@ -1035,6 +1035,23 @@ const useVideoTrimmer = () => {
|
|||||||
};
|
};
|
||||||
}, [isPlayingSegments, currentSegmentIndex, clipSegments]);
|
}, [isPlayingSegments, currentSegmentIndex, clipSegments]);
|
||||||
|
|
||||||
|
// Effect to handle manual segment index updates during segments playback
|
||||||
|
useEffect(() => {
|
||||||
|
const handleSegmentIndexUpdate = (event: CustomEvent) => {
|
||||||
|
const { segmentIndex } = event.detail;
|
||||||
|
if (isPlayingSegments && segmentIndex !== currentSegmentIndex) {
|
||||||
|
logger.debug(`Updating current segment index from ${currentSegmentIndex} to ${segmentIndex}`);
|
||||||
|
setCurrentSegmentIndex(segmentIndex);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
document.addEventListener('update-segment-index', handleSegmentIndexUpdate as EventListener);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
document.removeEventListener('update-segment-index', handleSegmentIndexUpdate as EventListener);
|
||||||
|
};
|
||||||
|
}, [isPlayingSegments, currentSegmentIndex]);
|
||||||
|
|
||||||
// Handle play segments
|
// Handle play segments
|
||||||
const handlePlaySegments = () => {
|
const handlePlaySegments = () => {
|
||||||
const video = videoRef.current;
|
const video = videoRef.current;
|
||||||
|
|||||||
@ -852,30 +852,23 @@
|
|||||||
background-color: inherit !important;
|
background-color: inherit !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Segments playback mode styles */
|
/* Segments playback mode styles - minimal functional styling */
|
||||||
.segments-playback-mode {
|
|
||||||
}
|
|
||||||
|
|
||||||
.segments-playback-mode .timeline-container,
|
|
||||||
.segments-playback-mode .clip-segment,
|
|
||||||
.segments-playback-mode .clip-segment-handle,
|
|
||||||
.segments-playback-mode .timeline-marker-head,
|
|
||||||
.segments-playback-mode .timeline-marker-drag,
|
|
||||||
.segments-playback-mode .trim-handle {
|
|
||||||
}
|
|
||||||
|
|
||||||
.segments-playback-mode .tooltip-action-btn {
|
|
||||||
opacity: 0.5;
|
|
||||||
}
|
|
||||||
|
|
||||||
.segments-playback-mode .tooltip-time-btn {
|
.segments-playback-mode .tooltip-time-btn {
|
||||||
opacity: 0.5;
|
opacity: 1;
|
||||||
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.segments-playback-mode .clip-segment:hover {
|
.segments-playback-mode .tooltip-action-btn.set-in,
|
||||||
box-shadow: none;
|
.segments-playback-mode .tooltip-action-btn.set-out,
|
||||||
border-color: rgba(0, 0, 0, 0.15);
|
.segments-playback-mode .tooltip-action-btn.play-from-start {
|
||||||
background-color: inherit !important;
|
opacity: 0.5;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.segments-playback-mode .tooltip-action-btn.play,
|
||||||
|
.segments-playback-mode .tooltip-action-btn.pause {
|
||||||
|
opacity: 1;
|
||||||
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Show segments playback message */
|
/* Show segments playback message */
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user