import { AlignedSegment } from '../services/transcriptionApi'; export interface SegmentWithTrack extends AlignedSegment { track: number; } /** * Assigns track numbers to segments to avoid overlaps * Segments always try to use the lowest available track (starting from track 0) */ export function assignTracksToSegments(segments: AlignedSegment[]): SegmentWithTrack[] { if (segments.length === 0) return []; // Sort segments by start time to process them in chronological order const sortedSegments = [...segments].sort((a, b) => a.start - b.start); // Track the end time of the last segment on each track const trackEndTimes: number[] = []; const segmentsWithTracks: SegmentWithTrack[] = sortedSegments.map((segment) => { // Find the lowest available track (starting from track 0) let assignedTrack = 0; // Check each existing track to see if this segment can fit for (let i = 0; i < trackEndTimes.length; i++) { if (trackEndTimes[i] <= segment.start) { // This track is available (previous segment has ended) assignedTrack = i; break; } } // If no existing track is available, use a new track if (assignedTrack === 0 && trackEndTimes.length > 0 && trackEndTimes[0] > segment.start) { assignedTrack = trackEndTimes.length; } // Update the end time for the assigned track if (assignedTrack >= trackEndTimes.length) { trackEndTimes.push(segment.end); } else { trackEndTimes[assignedTrack] = segment.end; } return { ...segment, track: assignedTrack, }; }); // Sort back to original order (by index in the original array) return segmentsWithTracks.sort((a, b) => { const aIndex = segments.findIndex(s => s === a); const bIndex = segments.findIndex(s => s === b); return aIndex - bIndex; }); } /** * Calculate the total number of tracks needed */ export function getMaxTrackCount(segmentsWithTracks: SegmentWithTrack[]): number { if (segmentsWithTracks.length === 0) return 1; return Math.max(...segmentsWithTracks.map(s => s.track)) + 1; } /** * Calculate the height needed for the timeline based on track count */ export function getTimelineHeight(trackCount: number, isEditMode: boolean): number { const baseHeight = 60; // Minimum height for timeline controls const trackHeight = isEditMode ? 40 : 32; // Height per track const padding = 16; // Top and bottom padding return baseHeight + (trackCount * trackHeight) + padding; }