New chapters layout

This commit is contained in:
Arkadiusz Fal
2023-04-22 20:06:30 +02:00
parent d52ccf2ce6
commit 6596a440a5
7 changed files with 142 additions and 39 deletions

View File

@@ -11,25 +11,53 @@ struct ChapterView: View {
Button {
player.backend.seek(to: chapter.start, seekType: .userInteracted)
} label: {
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)
}
Group {
#if os(tvOS)
horizontalChapter
#else
verticalChapter
#endif
}
.frame(maxWidth: .infinity, alignment: .leading)
.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)
}
var verticalChapter: some View {
VStack(spacing: 12) {
if !chapter.image.isNil {
smallImage(chapter)
}
VStack(alignment: .leading, spacing: 4) {
Text(chapter.title)
.lineLimit(2)
.multilineTextAlignment(.leading)
.font(.headline)
Text(chapter.start.formattedAsPlaybackTime(allowZero: true) ?? "")
.font(.system(.subheadline).monospacedDigit())
.foregroundColor(.secondary)
}
.frame(maxWidth: Self.thumbnailWidth, alignment: .leading)
}
}
@ViewBuilder func smallImage(_ chapter: Chapter) -> some View {
WebImage(url: chapter.image, options: [.lowPriority])
.resizable()
@@ -37,21 +65,20 @@ struct ChapterView: View {
ProgressView()
}
.indicator(.activity)
.frame(width: Self.thumbnailWidth, height: Self.thumbnailHeight)
#if os(tvOS)
.frame(width: thumbnailWidth, height: 140)
.mask(RoundedRectangle(cornerRadius: 12))
#else
.frame(width: thumbnailWidth, height: 60)
.mask(RoundedRectangle(cornerRadius: 6))
#endif
}
private var thumbnailWidth: Double {
#if os(tvOS)
250
#else
100
#endif
static var thumbnailWidth: Double {
250
}
static var thumbnailHeight: Double {
thumbnailWidth / 1.7777
}
}

View File

@@ -5,24 +5,32 @@ import SwiftUI
struct ChaptersView: View {
@ObservedObject private var player = PlayerModel.shared
var chapters: [Chapter] {
player.videoForDisplay?.chapters ?? []
}
var body: some View {
if let chapters = player.currentVideo?.chapters, !chapters.isEmpty {
List {
Section {
ForEach(chapters) { chapter in
ChapterView(chapter: chapter)
if !chapters.isEmpty {
#if os(tvOS)
List {
Section {
ForEach(chapters) { chapter in
ChapterView(chapter: chapter)
}
}
.listRowBackground(Color.clear)
}
.listRowBackground(Color.clear)
}
#if os(macOS)
.listStyle(.inset)
#elseif os(iOS)
.listStyle(.grouped)
.backport
.scrollContentBackground(false)
.listStyle(.plain)
#else
.listStyle(.plain)
ScrollView(.horizontal) {
LazyHStack(spacing: 20) {
ForEach(chapters) { chapter in
ChapterView(chapter: chapter)
}
}
.padding(.horizontal, 15)
}
.frame(minHeight: ChapterView.thumbnailHeight + 100)
#endif
} else {
NoCommentsView(text: "No chapters information available".localized(), systemImage: "xmark.circle.fill")

View File

@@ -50,6 +50,7 @@ struct VideoDescription: View {
keywords
}
.contentShape(Rectangle())
}
var shouldExpand: Bool {

View File

@@ -285,21 +285,37 @@ struct VideoDetails: View {
} else if let description = video.description, !description.isEmpty {
Section(header: descriptionHeader) {
VideoDescription(video: video, detailsSize: detailsSize, expand: $descriptionExpanded)
.padding(.horizontal)
}
} else if !video.isLocal {
Text("No description")
.font(.caption)
.foregroundColor(.secondary)
.padding(.horizontal)
}
if video.isLocal || showInspector == .always {
if player.videoBeingOpened.isNil,
!video.isLocal,
!video.chapters.isEmpty
{
Section(header: chaptersHeader) {
ChaptersView()
}
}
if player.videoBeingOpened.isNil,
video.isLocal || showInspector == .always
{
InspectorView(video: player.videoForDisplay)
.padding(.horizontal)
}
if !sidebarQueue,
if player.videoBeingOpened.isNil,
!sidebarQueue,
!(player.videoForDisplay?.related.isEmpty ?? true)
{
RelatedView()
.padding(.horizontal)
.padding(.top, 20)
}
}
@@ -313,7 +329,6 @@ struct VideoDetails: View {
}
.transition(.opacity)
.animation(nil, value: player.currentItem)
.padding(.horizontal)
#if os(iOS)
.frame(maxWidth: YatteeApp.isForPreviews ? .infinity : maxWidth)
#endif
@@ -360,9 +375,17 @@ struct VideoDetails: View {
.imageScale(.small)
}
}
.padding(.horizontal)
.font(.caption)
.foregroundColor(.secondary)
}
var chaptersHeader: some View {
Text("Chapters".localized())
.padding(.horizontal)
.font(.caption)
.foregroundColor(.secondary)
}
}
struct VideoDetails_Previews: PreviewProvider {