mirror of
https://github.com/yattee/yattee.git
synced 2024-11-15 02:28:23 +00:00
7c50db426f
Chapters have their own section is the settings. The users can decide if chapter thumbnails should be shown or not. Also they can decide to only show thumbnails if they are not the same. The VideoDetailsView had to be modified, to avoid compiler type-checking errors.
136 lines
4.2 KiB
Swift
136 lines
4.2 KiB
Swift
import Foundation
|
|
import SDWebImageSwiftUI
|
|
import SwiftUI
|
|
|
|
#if !os(tvOS)
|
|
struct ChapterView: View {
|
|
var chapter: Chapter
|
|
|
|
var chapterIndex: Int
|
|
@ObservedObject private var player = PlayerModel.shared
|
|
|
|
var showThumbnail: Bool
|
|
|
|
var isCurrentChapter: Bool {
|
|
player.currentChapterIndex == chapterIndex
|
|
}
|
|
|
|
var body: some View {
|
|
Button(action: {
|
|
player.backend.seek(to: chapter.start, seekType: .userInteracted)
|
|
}) {
|
|
Group {
|
|
verticalChapter
|
|
}
|
|
.contentShape(Rectangle())
|
|
}
|
|
.buttonStyle(.plain)
|
|
}
|
|
|
|
var verticalChapter: some View {
|
|
VStack(spacing: 12) {
|
|
if !chapter.image.isNil, showThumbnail {
|
|
smallImage(chapter)
|
|
}
|
|
VStack(alignment: .leading, spacing: 4) {
|
|
Text(chapter.title)
|
|
.lineLimit(3)
|
|
.multilineTextAlignment(.leading)
|
|
.font(.headline)
|
|
.foregroundColor(isCurrentChapter ? Color("AppRedColor") : .primary)
|
|
Text(chapter.start.formattedAsPlaybackTime(allowZero: true) ?? "")
|
|
.font(.system(.subheadline).monospacedDigit())
|
|
.foregroundColor(.secondary)
|
|
}
|
|
.frame(maxWidth: !chapter.image.isNil && showThumbnail ? Self.thumbnailWidth : nil, alignment: .leading)
|
|
}
|
|
}
|
|
|
|
@ViewBuilder func smallImage(_ chapter: Chapter) -> some View {
|
|
WebImage(url: chapter.image, options: [.lowPriority])
|
|
.resizable()
|
|
.placeholder {
|
|
ProgressView()
|
|
}
|
|
.indicator(.activity)
|
|
.frame(width: Self.thumbnailWidth, height: Self.thumbnailHeight)
|
|
|
|
.mask(RoundedRectangle(cornerRadius: 6))
|
|
}
|
|
|
|
static var thumbnailWidth: Double {
|
|
250
|
|
}
|
|
|
|
static var thumbnailHeight: Double {
|
|
thumbnailWidth / 1.7777
|
|
}
|
|
}
|
|
|
|
#else
|
|
struct ChapterViewTVOS: View {
|
|
var chapter: Chapter
|
|
var player = PlayerModel.shared
|
|
|
|
var body: some View {
|
|
Button {
|
|
player.backend.seek(to: chapter.start, seekType: .userInteracted)
|
|
} label: {
|
|
Group {
|
|
horizontalChapter
|
|
}
|
|
.contentShape(Rectangle())
|
|
}
|
|
.buttonStyle(.plain)
|
|
}
|
|
|
|
var horizontalChapter: some View {
|
|
HStack(spacing: 12) {
|
|
if !chapter.image.isNil {
|
|
smallImage(chapter)
|
|
}
|
|
|
|
VStack(alignment: .leading, spacing: 4) {
|
|
Text(chapter.title)
|
|
.font(.headline)
|
|
Text(chapter.start.formattedAsPlaybackTime(allowZero: true) ?? "")
|
|
.font(.system(.subheadline).monospacedDigit())
|
|
.foregroundColor(.secondary)
|
|
}
|
|
}
|
|
.frame(maxWidth: .infinity, alignment: .leading)
|
|
}
|
|
|
|
@ViewBuilder func smallImage(_ chapter: Chapter) -> some View {
|
|
WebImage(url: chapter.image, options: [.lowPriority])
|
|
.resizable()
|
|
.placeholder {
|
|
ProgressView()
|
|
}
|
|
.indicator(.activity)
|
|
.frame(width: Self.thumbnailWidth, height: Self.thumbnailHeight)
|
|
.mask(RoundedRectangle(cornerRadius: 12))
|
|
}
|
|
|
|
static var thumbnailWidth: Double {
|
|
250
|
|
}
|
|
|
|
static var thumbnailHeight: Double {
|
|
thumbnailWidth / 1.7777
|
|
}
|
|
}
|
|
#endif
|
|
|
|
struct ChapterView_Preview: PreviewProvider {
|
|
static var previews: some View {
|
|
#if os(tvOS)
|
|
ChapterViewTVOS(chapter: .init(title: "Chapter", start: 30))
|
|
.injectFixtureEnvironmentObjects()
|
|
#else
|
|
ChapterView(chapter: .init(title: "Chapter", start: 30), chapterIndex: 0, showThumbnail: true)
|
|
.injectFixtureEnvironmentObjects()
|
|
#endif
|
|
}
|
|
}
|