mirror of
https://github.com/mediacms-io/mediacms.git
synced 2025-10-06 22:32:41 +07:00
Fix segment playback flow, icon consistency, dynamic popups, and iOS/desktop timeline issues
- Fixed segment and cutaway playback to properly stop at the end and resume correctly after user interaction - Ensured playback continues seamlessly from cutaway to next segment when clicking Play - Updated start and end bracket icons for both segment and cutaway popup menus to correct designs - Fixed dynamic updates of popup menus when dragging segment boundaries past the playhead - Fixed issue where deleting a segment did not trigger correct switch to cutaway popup menu - Synced playback icons between popup menu and video controls under various playback scenarios - Replaced browser-native unload confirmation with a custom, unified message to warn about unsaved edits - Ensured timeline-based editing now works reliably on iPhone/iPad (iOS Safari) - Fixed issue where clicking at the end of a cutaway area closed the popup and prevented re-opening on desktop browsers
This commit is contained in:
@@ -185,13 +185,26 @@ const useVideoTrimmer = () => {
|
||||
if (isPlaying) {
|
||||
video.pause();
|
||||
} else {
|
||||
// iOS Safari fix: Use the last seeked position if available
|
||||
if (!isPlaying && typeof window !== 'undefined' && window.lastSeekedPosition > 0) {
|
||||
// Only apply this if the video is not at the same position already
|
||||
// This avoids unnecessary seeking which might cause playback issues
|
||||
if (Math.abs(video.currentTime - window.lastSeekedPosition) > 0.1) {
|
||||
video.currentTime = window.lastSeekedPosition;
|
||||
}
|
||||
}
|
||||
// If at the end of the trim range, reset to the beginning
|
||||
if (video.currentTime >= trimEnd) {
|
||||
else if (video.currentTime >= trimEnd) {
|
||||
video.currentTime = trimStart;
|
||||
}
|
||||
|
||||
video.play()
|
||||
.then(() => {
|
||||
// Play started successfully
|
||||
// Reset the last seeked position after successfully starting playback
|
||||
if (typeof window !== 'undefined') {
|
||||
window.lastSeekedPosition = 0;
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
console.error("Error starting playback:", err);
|
||||
@@ -215,6 +228,12 @@ const useVideoTrimmer = () => {
|
||||
video.currentTime = time;
|
||||
setCurrentTime(time);
|
||||
|
||||
// Store the position in a global state accessible to iOS Safari
|
||||
// This ensures when play is pressed later, it remembers the position
|
||||
if (typeof window !== 'undefined') {
|
||||
window.lastSeekedPosition = time;
|
||||
}
|
||||
|
||||
// Find segment at this position for preview mode playback
|
||||
if (wasInPreviewMode) {
|
||||
const segmentAtPosition = clipSegments.find(
|
||||
@@ -784,10 +803,23 @@ const useVideoTrimmer = () => {
|
||||
video.pause();
|
||||
setIsPlaying(false);
|
||||
} else {
|
||||
// iOS Safari fix: Check for lastSeekedPosition
|
||||
if (typeof window !== 'undefined' && window.lastSeekedPosition > 0) {
|
||||
// Only seek if the position is significantly different
|
||||
if (Math.abs(video.currentTime - window.lastSeekedPosition) > 0.1) {
|
||||
console.log("handlePlay: Using lastSeekedPosition", window.lastSeekedPosition);
|
||||
video.currentTime = window.lastSeekedPosition;
|
||||
}
|
||||
}
|
||||
|
||||
// Play the video from current position with proper promise handling
|
||||
video.play()
|
||||
.then(() => {
|
||||
setIsPlaying(true);
|
||||
// Reset lastSeekedPosition after successful play
|
||||
if (typeof window !== 'undefined') {
|
||||
window.lastSeekedPosition = 0;
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
console.error("Error playing video:", err);
|
||||
@@ -820,7 +852,9 @@ const useVideoTrimmer = () => {
|
||||
};
|
||||
|
||||
// Display JSON in alert (for demonstration purposes)
|
||||
alert(JSON.stringify(saveData, null, 2));
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
console.debug("Saving data:", saveData);
|
||||
}
|
||||
|
||||
// Mark as saved - no unsaved changes
|
||||
setHasUnsavedChanges(false);
|
||||
@@ -852,7 +886,9 @@ const useVideoTrimmer = () => {
|
||||
};
|
||||
|
||||
// Display JSON in alert (for demonstration purposes)
|
||||
alert(JSON.stringify(saveData, null, 2));
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
console.debug("Saving data as copy:", saveData);
|
||||
}
|
||||
|
||||
// Mark as saved - no unsaved changes
|
||||
setHasUnsavedChanges(false);
|
||||
@@ -882,7 +918,9 @@ const useVideoTrimmer = () => {
|
||||
};
|
||||
|
||||
// Display JSON in alert (for demonstration purposes)
|
||||
alert(JSON.stringify(saveData, null, 2));
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
console.debug("Saving data as segments:", saveData);
|
||||
}
|
||||
|
||||
// Mark as saved - no unsaved changes
|
||||
setHasUnsavedChanges(false);
|
||||
|
||||
Reference in New Issue
Block a user