highlight current chapter

This commit is contained in:
Toni Förster 2023-11-28 16:45:36 +01:00
parent fb5cd0f681
commit 4ec6f35c5d
No known key found for this signature in database
GPG Key ID: 292F3E5086C83FC7
3 changed files with 40 additions and 10 deletions

View File

@ -131,6 +131,9 @@ final class PlayerModel: ObservableObject {
@Default(.rotateToLandscapeOnEnterFullScreen) private var rotateToLandscapeOnEnterFullScreen @Default(.rotateToLandscapeOnEnterFullScreen) private var rotateToLandscapeOnEnterFullScreen
#endif #endif
@Published var playedChapters: [Int] = []
@Published var currentChapterIndex: Int?
var accounts: AccountsModel { .shared } var accounts: AccountsModel { .shared }
var comments: CommentsModel { .shared } var comments: CommentsModel { .shared }
var controls: PlayerControlsModel { .shared } var controls: PlayerControlsModel { .shared }

View File

@ -1,16 +1,27 @@
import CoreMedia
import Foundation import Foundation
import SDWebImageSwiftUI import SDWebImageSwiftUI
import SwiftUI import SwiftUI
struct ChapterView: View { struct ChapterView: View {
var chapter: Chapter var chapter: Chapter
var nextChapterStart: Double?
var player = PlayerModel.shared var chapterIndex: Int
@ObservedObject private var player = PlayerModel.shared
var isCurrentChapter: Bool {
player.currentChapterIndex == chapterIndex
}
var hasBeenPlayed: Bool {
player.playedChapters.contains(chapterIndex)
}
var body: some View { var body: some View {
Button { Button(action: {
player.backend.seek(to: chapter.start, seekType: .userInteracted) player.backend.seek(to: chapter.start, seekType: .userInteracted)
} label: { }) {
Group { Group {
#if os(tvOS) #if os(tvOS)
horizontalChapter horizontalChapter
@ -21,6 +32,15 @@ struct ChapterView: View {
.contentShape(Rectangle()) .contentShape(Rectangle())
} }
.buttonStyle(.plain) .buttonStyle(.plain)
.onReceive(PlayerTimeModel.shared.$currentTime) { cmTime in
let time = CMTimeGetSeconds(cmTime)
if time >= self.chapter.start, self.nextChapterStart == nil || time < self.nextChapterStart! {
player.currentChapterIndex = self.chapterIndex
if !player.playedChapters.contains(self.chapterIndex) {
player.playedChapters.append(self.chapterIndex)
}
}
}
} }
#if os(tvOS) #if os(tvOS)
@ -52,6 +72,7 @@ struct ChapterView: View {
.lineLimit(3) .lineLimit(3)
.multilineTextAlignment(.leading) .multilineTextAlignment(.leading)
.font(.headline) .font(.headline)
.foregroundColor(isCurrentChapter ? .detailBadgeOutstandingStyleBackground : .primary)
Text(chapter.start.formattedAsPlaybackTime(allowZero: true) ?? "") Text(chapter.start.formattedAsPlaybackTime(allowZero: true) ?? "")
.font(.system(.subheadline).monospacedDigit()) .font(.system(.subheadline).monospacedDigit())
.foregroundColor(.secondary) .foregroundColor(.secondary)
@ -87,7 +108,7 @@ struct ChapterView: View {
struct ChapterView_Preview: PreviewProvider { struct ChapterView_Preview: PreviewProvider {
static var previews: some View { static var previews: some View {
ChapterView(chapter: .init(title: "Chapter", start: 30)) ChapterView(chapter: .init(title: "Chapter", start: 30), chapterIndex: 0)
.injectFixtureEnvironmentObjects() .injectFixtureEnvironmentObjects()
} }
} }

View File

@ -30,8 +30,10 @@ struct ChaptersView: View {
#else #else
ScrollView(.horizontal) { ScrollView(.horizontal) {
LazyHStack(spacing: 20) { LazyHStack(spacing: 20) {
ForEach(chapters) { chapter in ForEach(Array(chapters.indices), id: \.self) { index in
ChapterView(chapter: chapter) let chapter = chapters[index]
let nextChapterStart: Double? = index < chapters.count - 1 ? chapters[index + 1].start : nil
ChapterView(chapter: chapter, nextChapterStart: nextChapterStart, chapterIndex: index)
} }
} }
.padding(.horizontal, 15) .padding(.horizontal, 15)
@ -39,8 +41,10 @@ struct ChaptersView: View {
#endif #endif
} else if expand { } else if expand {
Section { Section {
ForEach(chapters) { chapter in ForEach(Array(chapters.indices), id: \.self) { index in
ChapterView(chapter: chapter) let chapter = chapters[index]
let nextChapterStart: Double? = index < chapters.count - 1 ? chapters[index + 1].start : nil
ChapterView(chapter: chapter, nextChapterStart: nextChapterStart, chapterIndex: index)
} }
} }
.padding(.horizontal) .padding(.horizontal)
@ -60,8 +64,10 @@ struct ChaptersView: View {
var contents: some View { var contents: some View {
Section { Section {
ForEach(chapters.prefix(3).indices, id: \.self) { index in ForEach(Array(chapters.prefix(3).indices), id: \.self) { index in
ChapterView(chapter: chapters[index]) let chapter = chapters[index]
let nextChapterStart: Double? = index < chapters.count - 1 ? chapters[index + 1].start : nil
ChapterView(chapter: chapter, nextChapterStart: nextChapterStart, chapterIndex: index)
.allowsHitTesting(expand) .allowsHitTesting(expand)
.opacity(index == 0 ? 1.0 : 0.3) .opacity(index == 0 ? 1.0 : 0.3)
} }