Ctrl K
ComunidadGuías…

src/renderer/store/audiobook-chapters.ts

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
import { LongFormChapter } from '/@/shared/api/long-form-types';

export interface AudiobookChapterListItem {
    chapter: LongFormChapter;
    duration: number;
    end: number;
    originalIndex: number;
    start: number;
}

/**
 * Single source of truth for "which chapter is the listener currently in?".
 */
export function getCurrentChapterIndex(
    chapters: LongFormChapter[],
    position: number,
    duration: number,
): number {
    if (chapters.length === 0) return -1;
    const max = duration > 0 ? duration : Number.POSITIVE_INFINITY;
    const clamped = Math.min(Math.max(position, 0), max);
    for (let i = chapters.length - 1; i >= 0; i--) {
        if (chapters[i].start <= clamped) return i;
    }
    return 0;
}

export function getOrderedAudiobookChapters(
    chapters: LongFormChapter[],
    duration: number,
): AudiobookChapterListItem[] {
    if (chapters.length <= 1 || !Number.isFinite(duration) || duration <= 0) return [];

    const orderedChapters = chapters
        .map((chapter, originalIndex) => ({ chapter, originalIndex }))
        .filter(
            ({ chapter }) =>
                Number.isFinite(chapter.start) && chapter.start >= 0 && chapter.start < duration,
        )
        .sort((a, b) => a.chapter.start - b.chapter.start)
        .filter(
            ({ chapter }, index, ordered) =>
                index === 0 || chapter.start !== ordered[index - 1].chapter.start,
        );

    if (orderedChapters.length <= 1 || orderedChapters[0].chapter.start > 0.5) return [];

    return orderedChapters
        .map(({ chapter, originalIndex }, index) => {
            const start = chapter.start;
            const end = Math.min(
                index === orderedChapters.length - 1
                    ? duration
                    : orderedChapters[index + 1].chapter.start,
                duration,
            );

            if (end <= start) return null;

            return {
                chapter,
                duration: end - start,
                end,
                originalIndex,
                start,
            };
        })
        .filter((chapter): chapter is AudiobookChapterListItem => chapter !== null);
}