diff --git a/Model/Player/PlayerModel.swift b/Model/Player/PlayerModel.swift index e6c33702..d91ae3eb 100644 --- a/Model/Player/PlayerModel.swift +++ b/Model/Player/PlayerModel.swift @@ -131,7 +131,7 @@ final class PlayerModel: ObservableObject { @Default(.rotateToLandscapeOnEnterFullScreen) private var rotateToLandscapeOnEnterFullScreen #endif - @Published var currentChapter: Int? + @Published var currentChapterIndex: Int? var accounts: AccountsModel { .shared } var comments: CommentsModel { .shared } @@ -1114,4 +1114,36 @@ final class PlayerModel: ObservableObject { onPlayStream.forEach { $0(stream) } onPlayStream.removeAll() } + + func updateTime(_ cmTime: CMTime) { + let time = CMTimeGetSeconds(cmTime) + let newChapterIndex = chapterForTime(time) + if currentChapterIndex != newChapterIndex { + DispatchQueue.main.async { + self.currentChapterIndex = newChapterIndex + } + } + } + + private func chapterForTime(_ time: Double) -> Int? { + guard let chapters = self.videoForDisplay?.chapters else { + return nil + } + + for (index, chapter) in chapters.enumerated() { + let nextChapterStartTime = index < (chapters.count - 1) ? chapters[index + 1].start : nil + + if let nextChapterStart = nextChapterStartTime { + if time >= chapter.start, time < nextChapterStart { + return index + } + } else { + if time >= chapter.start { + return index + } + } + } + + return nil + } } diff --git a/Shared/Player/Video Details/ChapterView.swift b/Shared/Player/Video Details/ChapterView.swift index 216cd5e2..f2646a64 100644 --- a/Shared/Player/Video Details/ChapterView.swift +++ b/Shared/Player/Video Details/ChapterView.swift @@ -6,13 +6,12 @@ import SwiftUI #if !os(tvOS) struct ChapterView: View { var chapter: Chapter - var nextChapterStart: Double? var chapterIndex: Int @ObservedObject private var player = PlayerModel.shared var isCurrentChapter: Bool { - player.currentChapter == chapterIndex + player.currentChapterIndex == chapterIndex } var body: some View { @@ -31,7 +30,7 @@ import SwiftUI .receive(on: DispatchQueue.main) ) { notification in if let cmTime = notification.object as? CMTime { - self.handleTimeUpdate(cmTime) + player.updateTime(cmTime) } } } @@ -74,13 +73,6 @@ import SwiftUI static var thumbnailHeight: Double { thumbnailWidth / 1.7777 } - - private func handleTimeUpdate(_ cmTime: CMTime) { - let time = CMTimeGetSeconds(cmTime) - if time >= chapter.start, nextChapterStart == nil || time < nextChapterStart! { - player.currentChapter = chapterIndex - } - } } #else @@ -144,7 +136,7 @@ struct ChapterView_Preview: PreviewProvider { ChapterViewTVOS(chapter: .init(title: "Chapter", start: 30)) .injectFixtureEnvironmentObjects() #else - ChapterView(chapter: .init(title: "Chapter", start: 30), nextChapterStart: nil, chapterIndex: 0) + ChapterView(chapter: .init(title: "Chapter", start: 30), chapterIndex: 0) .injectFixtureEnvironmentObjects() #endif } diff --git a/Shared/Player/Video Details/ChaptersView.swift b/Shared/Player/Video Details/ChaptersView.swift index 36f369ea..65baa874 100644 --- a/Shared/Player/Video Details/ChaptersView.swift +++ b/Shared/Player/Video Details/ChaptersView.swift @@ -70,8 +70,7 @@ struct ChaptersView: View { private func chapterViews(for chaptersToShow: ArraySlice, opacity: Double = 1.0, clickable: Bool = true) -> some View { ForEach(Array(chaptersToShow.indices), id: \.self) { index in let chapter = chaptersToShow[index] - let nextChapterStart: Double? = index < chaptersToShow.count - 1 ? chaptersToShow[index + 1].start : nil - ChapterView(chapter: chapter, nextChapterStart: nextChapterStart, chapterIndex: index) + ChapterView(chapter: chapter, chapterIndex: index) .opacity(index == 0 ? 1.0 : opacity) .allowsHitTesting(clickable) }