Use two-column layout for tvOS video info view

Reworks VideoInfoView on tvOS into a persistent 30% left sidebar
(thumbnail, title, channel, Play / Add to Playlist / Bookmark) with a
scrollable right pane for description, stats, comments, related, and
watch history. Reuses the player's TVScrollableDescription (refactored
to self-manage focus) so the description supports click-to-lock
scrolling, and the outer ScrollView is disabled while locked. Comments
full-screen on tvOS, with commenter avatars no longer tappable and
accent-colored link text replaced with the default foreground.
This commit is contained in:
Arkadiusz Fal
2026-04-16 02:26:51 +02:00
parent 6a45ed7d0f
commit 0aac9168cb
3 changed files with 284 additions and 30 deletions

View File

@@ -67,29 +67,38 @@ struct CommentView: View {
@ViewBuilder
private var authorAvatar: some View {
#if os(tvOS)
authorAvatarImage
#else
Button {
navigateToChannel()
} label: {
LazyImage(url: comment.author.thumbnailURL) { state in
if let image = state.image {
image
.resizable()
.aspectRatio(contentMode: .fill)
} else {
Circle()
.fill(.quaternary)
.overlay {
Text(String(comment.author.name.prefix(1)))
.font(.caption)
.fontWeight(.medium)
.foregroundStyle(.secondary)
}
}
}
.frame(width: 32, height: 32)
.clipShape(Circle())
authorAvatarImage
}
.buttonStyle(.plain)
#endif
}
@ViewBuilder
private var authorAvatarImage: some View {
LazyImage(url: comment.author.thumbnailURL) { state in
if let image = state.image {
image
.resizable()
.aspectRatio(contentMode: .fill)
} else {
Circle()
.fill(.quaternary)
.overlay {
Text(String(comment.author.name.prefix(1)))
.font(.caption)
.fontWeight(.medium)
.foregroundStyle(.secondary)
}
}
}
.frame(width: 32, height: 32)
.clipShape(Circle())
}
@ViewBuilder
@@ -178,7 +187,9 @@ struct CommentView: View {
.font(.caption)
.fontWeight(.medium)
}
#if !os(tvOS)
.foregroundStyle(accentColor)
#endif
}
.buttonStyle(.plain)
.padding(.leading, 44) // Align with comment content (avatar width + spacing)
@@ -213,7 +224,9 @@ struct CommentView: View {
Text(String(localized: "comments.loadMoreReplies"))
.font(.caption)
.fontWeight(.medium)
#if !os(tvOS)
.foregroundStyle(accentColor)
#endif
}
.buttonStyle(.plain)
.padding(.leading, 44)