fix Format segments data for API request - use ref to get latest segments and sort by start time

This commit is contained in:
Yiannis Christodoulou 2025-10-16 18:38:46 +03:00
parent 41771442d9
commit 4772c11305
7 changed files with 92 additions and 69 deletions

View File

@ -190,12 +190,14 @@ const TimelineControls = ({
try { try {
setIsAutoSaving(true); setIsAutoSaving(true);
// Format segments data for API request - use ref to get latest segments // Format segments data for API request - use ref to get latest segments and sort by start time
const chapters = clipSegmentsRef.current.map((chapter) => ({ const chapters = clipSegmentsRef.current
startTime: formatDetailedTime(chapter.startTime), .sort((a, b) => a.startTime - b.startTime) // Sort by start time chronologically
endTime: formatDetailedTime(chapter.endTime), .map((chapter) => ({
chapterTitle: chapter.chapterTitle, startTime: formatDetailedTime(chapter.startTime),
})); endTime: formatDetailedTime(chapter.endTime),
chapterTitle: chapter.chapterTitle,
}));
logger.debug('chapters', chapters); logger.debug('chapters', chapters);
@ -496,9 +498,10 @@ const TimelineControls = ({
setSaveType('chapters'); setSaveType('chapters');
try { try {
// Format chapters data for API request // Format chapters data for API request - sort by start time first
const chapters = clipSegments const chapters = clipSegments
.filter((segment) => segment.chapterTitle && segment.chapterTitle.trim()) .filter((segment) => segment.chapterTitle && segment.chapterTitle.trim())
.sort((a, b) => a.startTime - b.startTime) // Sort by start time chronologically
.map((segment) => ({ .map((segment) => ({
chapterTitle: segment.chapterTitle || `Chapter ${segment.id}`, chapterTitle: segment.chapterTitle || `Chapter ${segment.id}`,
from: formatDetailedTime(segment.startTime), from: formatDetailedTime(segment.startTime),

View File

@ -24,6 +24,18 @@ const useVideoChapters = () => {
return `Chapter ${chapterIndex + 1}`; return `Chapter ${chapterIndex + 1}`;
}; };
// Helper function to renumber all segments in chronological order
const renumberAllSegments = (segments: Segment[]): Segment[] => {
// Sort segments by start time
const sortedSegments = [...segments].sort((a, b) => a.startTime - b.startTime);
// Renumber each segment based on its chronological position
return sortedSegments.map((segment, index) => ({
...segment,
chapterTitle: `Chapter ${index + 1}`
}));
};
// Helper function to parse time string (HH:MM:SS.mmm) to seconds // Helper function to parse time string (HH:MM:SS.mmm) to seconds
const parseTimeToSeconds = (timeString: string): number => { const parseTimeToSeconds = (timeString: string): number => {
const parts = timeString.split(':'); const parts = timeString.split(':');
@ -632,19 +644,16 @@ const useVideoChapters = () => {
newSegments.splice(segmentIndex, 1); newSegments.splice(segmentIndex, 1);
// Remove the original segment first to get accurate positioning for new segments
const segmentsWithoutOriginal = newSegments;
const firstHalf: Segment = { const firstHalf: Segment = {
id: Date.now(), id: Date.now(),
chapterTitle: generateChapterName(segmentToSplit.startTime, segmentsWithoutOriginal), chapterTitle: '', // Temporary title, will be set by renumberAllSegments
startTime: segmentToSplit.startTime, startTime: segmentToSplit.startTime,
endTime: timeToSplit, endTime: timeToSplit,
}; };
const secondHalf: Segment = { const secondHalf: Segment = {
id: Date.now() + 1, id: Date.now() + 1,
chapterTitle: generateChapterName(timeToSplit, [...segmentsWithoutOriginal, firstHalf]), chapterTitle: '', // Temporary title, will be set by renumberAllSegments
startTime: timeToSplit, startTime: timeToSplit,
endTime: segmentToSplit.endTime, endTime: segmentToSplit.endTime,
}; };
@ -652,11 +661,11 @@ const useVideoChapters = () => {
// Add the new segments // Add the new segments
newSegments.push(firstHalf, secondHalf); newSegments.push(firstHalf, secondHalf);
// Sort segments by start time // Renumber all segments to ensure proper chronological naming
newSegments.sort((a, b) => a.startTime - b.startTime); const renumberedSegments = renumberAllSegments(newSegments);
// Update state // Update state
setClipSegments(newSegments); setClipSegments(renumberedSegments);
saveState('split_segment'); saveState('split_segment');
} }
}; };
@ -687,8 +696,9 @@ const useVideoChapters = () => {
setSplitPoints([]); setSplitPoints([]);
setClipSegments([defaultSegment]); setClipSegments([defaultSegment]);
} else { } else {
// Just update the segments normally // Renumber remaining segments to ensure proper chronological naming
setClipSegments(newSegments); const renumberedSegments = renumberAllSegments(newSegments);
setClipSegments(renumberedSegments);
} }
saveState('delete_segment'); saveState('delete_segment');
} }
@ -907,12 +917,19 @@ const useVideoChapters = () => {
return; return;
} }
// Convert chapters to backend expected format // Convert chapters to backend expected format and sort by start time
const backendChapters = chapters.map((chapter) => ({ const backendChapters = chapters
startTime: chapter.from, .map((chapter) => ({
endTime: chapter.to, startTime: chapter.from,
chapterTitle: chapter.chapterTitle, endTime: chapter.to,
})); chapterTitle: chapter.chapterTitle,
}))
.sort((a, b) => {
// Parse time strings to seconds for proper comparison
const aStartSeconds = parseTimeToSeconds(a.startTime);
const bStartSeconds = parseTimeToSeconds(b.startTime);
return aStartSeconds - bStartSeconds;
});
// Create the API request body // Create the API request body
const requestData = { const requestData = {

View File

@ -1,6 +1,9 @@
button { button {
cursor: pointer; cursor: pointer;
} }
.playlist-items a {
text-decoration: none !important;
}
.video-js, .video-js,
.video-js[tabindex], .video-js[tabindex],

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long