Track the active chapter in PlayerState instead of per-tick time reads

Chapter lists highlighted the active row by reading currentTime in the
view body, re-rendering every row many times per second during
playback. PlayerState now stores a change-guarded activeChapterID
updated when time or chapters change, so views observe only chapter
transitions.
This commit is contained in:
Arkadiusz Fal
2026-09-23 23:47:21 +02:00
parent e7458ba629
commit 4a85f7355a
4 changed files with 27 additions and 15 deletions

View File

@@ -226,7 +226,9 @@ final class PlayerState {
// MARK: - Time & Progress
/// Current playback time in seconds.
var currentTime: TimeInterval = 0
var currentTime: TimeInterval = 0 {
didSet { updateActiveChapter() }
}
/// Total duration in seconds.
var duration: TimeInterval = 0
@@ -356,11 +358,27 @@ final class PlayerState {
// MARK: - Chapters
/// Video chapters if available.
var chapters: [VideoChapter] = []
var chapters: [VideoChapter] = [] {
didSet { updateActiveChapter() }
}
/// ID of the chapter containing the current playback time. Stored and
/// change-guarded so views highlighting the active chapter observe only
/// chapter transitions, not every time-pos tick — reading `currentTime`
/// from a panel body re-renders it many times per second during playback.
private(set) var activeChapterID: UUID?
/// Current chapter based on playback time.
var currentChapter: VideoChapter? {
chapters.last { $0.startTime <= currentTime }
guard let activeChapterID else { return nil }
return chapters.first { $0.id == activeChapterID }
}
private func updateActiveChapter() {
let id = chapters.last { $0.startTime <= currentTime }?.id
if activeChapterID != id {
activeChapterID = id
}
}
// MARK: - Storyboards