mirror of
https://github.com/mediacms-io/mediacms.git
synced 2026-01-21 15:52:58 -05:00
feat: Improve Visual Distinction Between Trim and Chapters Editors (#1445)
* Update .gitignore * feat: Improve Visual Distinction Between Trim and Chapters Editors * fix: Convert timeline header styles to CSS classes Moved inline styles for timeline headers in chapters and video editors to dedicated CSS classes for better maintainability and consistency. * Bump version to 7.3.0 Update the VERSION in cms/version.py to 7.3.0 for the new release. * build assets * Update segment color schemes in video and chapters editor. * build assets * build assets * fix: Prevent Safari from resetting segments after drag operations Prevent Safari from resetting segments when loadedmetadata fires multiple times and fix stale state issues in click handlers by using refs instead of closure variables. * build assets * Bump version to 7.3.0-beta.3 Update the VERSION string in cms/version.py to reflect the new pre-release version 7.3.0-beta.3.
This commit is contained in:
committed by
GitHub
parent
aeef8284bf
commit
d9b1d6cab1
@@ -60,6 +60,9 @@ const useVideoChapters = () => {
|
||||
const [duration, setDuration] = useState(0);
|
||||
const [isPlaying, setIsPlaying] = useState(false);
|
||||
const [isMuted, setIsMuted] = useState(false);
|
||||
|
||||
// Track if editor has been initialized to prevent re-initialization on Safari metadata events
|
||||
const isInitializedRef = useRef<boolean>(false);
|
||||
|
||||
// Timeline state
|
||||
const [trimStart, setTrimStart] = useState(0);
|
||||
@@ -108,11 +111,7 @@ const useVideoChapters = () => {
|
||||
// Detect Safari browser
|
||||
const isSafari = () => {
|
||||
const userAgent = navigator.userAgent || navigator.vendor || (window as any).opera;
|
||||
const isSafariBrowser = /Safari/.test(userAgent) && !/Chrome/.test(userAgent) && !/Chromium/.test(userAgent);
|
||||
if (isSafariBrowser) {
|
||||
logger.debug('Safari browser detected, enabling audio support fallbacks');
|
||||
}
|
||||
return isSafariBrowser;
|
||||
return /Safari/.test(userAgent) && !/Chrome/.test(userAgent) && !/Chromium/.test(userAgent);
|
||||
};
|
||||
|
||||
// Initialize video event listeners
|
||||
@@ -121,7 +120,15 @@ const useVideoChapters = () => {
|
||||
if (!video) return;
|
||||
|
||||
const handleLoadedMetadata = () => {
|
||||
logger.debug('Video loadedmetadata event fired, duration:', video.duration);
|
||||
// CRITICAL: Prevent re-initialization if editor has already been initialized
|
||||
// Safari fires loadedmetadata multiple times, which was resetting segments
|
||||
if (isInitializedRef.current) {
|
||||
// Still update duration and trimEnd in case they changed
|
||||
setDuration(video.duration);
|
||||
setTrimEnd(video.duration);
|
||||
return;
|
||||
}
|
||||
|
||||
setDuration(video.duration);
|
||||
setTrimEnd(video.duration);
|
||||
|
||||
@@ -173,7 +180,7 @@ const useVideoChapters = () => {
|
||||
setHistory([initialState]);
|
||||
setHistoryPosition(0);
|
||||
setClipSegments(initialSegments);
|
||||
logger.debug('Editor initialized with segments:', initialSegments.length);
|
||||
isInitializedRef.current = true; // Mark as initialized
|
||||
};
|
||||
|
||||
initializeEditor();
|
||||
@@ -181,20 +188,18 @@ const useVideoChapters = () => {
|
||||
|
||||
// Safari-specific fallback for audio files
|
||||
const handleCanPlay = () => {
|
||||
logger.debug('Video canplay event fired');
|
||||
// If loadedmetadata hasn't fired yet but we have duration, trigger initialization
|
||||
if (video.duration && duration === 0) {
|
||||
logger.debug('Safari fallback: Using canplay event to initialize');
|
||||
// Also check if already initialized to prevent re-initialization
|
||||
if (video.duration && duration === 0 && !isInitializedRef.current) {
|
||||
handleLoadedMetadata();
|
||||
}
|
||||
};
|
||||
|
||||
// Additional Safari fallback for audio files
|
||||
const handleLoadedData = () => {
|
||||
logger.debug('Video loadeddata event fired');
|
||||
// If we still don't have duration, try again
|
||||
if (video.duration && duration === 0) {
|
||||
logger.debug('Safari fallback: Using loadeddata event to initialize');
|
||||
// Also check if already initialized to prevent re-initialization
|
||||
if (video.duration && duration === 0 && !isInitializedRef.current) {
|
||||
handleLoadedMetadata();
|
||||
}
|
||||
};
|
||||
@@ -226,14 +231,12 @@ const useVideoChapters = () => {
|
||||
|
||||
// Safari-specific fallback event listeners for audio files
|
||||
if (isSafari()) {
|
||||
logger.debug('Adding Safari-specific event listeners for audio support');
|
||||
video.addEventListener('canplay', handleCanPlay);
|
||||
video.addEventListener('loadeddata', handleLoadedData);
|
||||
|
||||
// Additional timeout fallback for Safari audio files
|
||||
const safariTimeout = setTimeout(() => {
|
||||
if (video.duration && duration === 0) {
|
||||
logger.debug('Safari timeout fallback: Force initializing editor');
|
||||
if (video.duration && duration === 0 && !isInitializedRef.current) {
|
||||
handleLoadedMetadata();
|
||||
}
|
||||
}, 1000);
|
||||
|
||||
Reference in New Issue
Block a user