mirror of
https://github.com/yattee/yattee.git
synced 2026-05-12 18:35:05 +00:00
Use macOS-native styling and larger text in video info view
This commit is contained in:
@@ -45,7 +45,11 @@ struct CommentView: View {
|
|||||||
|
|
||||||
// Comment content — render with clickable URLs and timestamps
|
// Comment content — render with clickable URLs and timestamps
|
||||||
Text(DescriptionText.attributed(comment.content, linkColor: accentColor))
|
Text(DescriptionText.attributed(comment.content, linkColor: accentColor))
|
||||||
|
#if os(macOS)
|
||||||
|
.font(.body)
|
||||||
|
#else
|
||||||
.font(.subheadline)
|
.font(.subheadline)
|
||||||
|
#endif
|
||||||
.foregroundStyle(.primary)
|
.foregroundStyle(.primary)
|
||||||
.fixedSize(horizontal: false, vertical: true)
|
.fixedSize(horizontal: false, vertical: true)
|
||||||
#if !os(tvOS)
|
#if !os(tvOS)
|
||||||
@@ -106,7 +110,11 @@ struct CommentView: View {
|
|||||||
private var authorInfo: some View {
|
private var authorInfo: some View {
|
||||||
HStack(spacing: 4) {
|
HStack(spacing: 4) {
|
||||||
Text(comment.author.name)
|
Text(comment.author.name)
|
||||||
|
#if os(macOS)
|
||||||
|
.font(.subheadline)
|
||||||
|
#else
|
||||||
.font(.caption)
|
.font(.caption)
|
||||||
|
#endif
|
||||||
.fontWeight(.semibold)
|
.fontWeight(.semibold)
|
||||||
.foregroundStyle(comment.isCreatorComment ? accentColor : .primary)
|
.foregroundStyle(comment.isCreatorComment ? accentColor : .primary)
|
||||||
|
|
||||||
@@ -138,7 +146,11 @@ struct CommentView: View {
|
|||||||
// Published time
|
// Published time
|
||||||
if let publishedText = comment.formattedPublishedDate {
|
if let publishedText = comment.formattedPublishedDate {
|
||||||
Text(publishedText)
|
Text(publishedText)
|
||||||
|
#if os(macOS)
|
||||||
|
.font(.subheadline)
|
||||||
|
#else
|
||||||
.font(.caption)
|
.font(.caption)
|
||||||
|
#endif
|
||||||
.foregroundStyle(.secondary)
|
.foregroundStyle(.secondary)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -146,9 +158,17 @@ struct CommentView: View {
|
|||||||
if let likeCount = comment.formattedLikeCount {
|
if let likeCount = comment.formattedLikeCount {
|
||||||
HStack(spacing: 2) {
|
HStack(spacing: 2) {
|
||||||
Image(systemName: "hand.thumbsup")
|
Image(systemName: "hand.thumbsup")
|
||||||
.font(.caption2)
|
#if os(macOS)
|
||||||
Text(likeCount)
|
|
||||||
.font(.caption)
|
.font(.caption)
|
||||||
|
#else
|
||||||
|
.font(.caption2)
|
||||||
|
#endif
|
||||||
|
Text(likeCount)
|
||||||
|
#if os(macOS)
|
||||||
|
.font(.subheadline)
|
||||||
|
#else
|
||||||
|
.font(.caption)
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
.foregroundStyle(.secondary)
|
.foregroundStyle(.secondary)
|
||||||
}
|
}
|
||||||
@@ -185,7 +205,11 @@ struct CommentView: View {
|
|||||||
.font(.caption2)
|
.font(.caption2)
|
||||||
.rotationEffect(.degrees(showReplies ? -180 : 0))
|
.rotationEffect(.degrees(showReplies ? -180 : 0))
|
||||||
Text(String(localized: "comments.showReplies \(comment.replyCount)"))
|
Text(String(localized: "comments.showReplies \(comment.replyCount)"))
|
||||||
|
#if os(macOS)
|
||||||
|
.font(.subheadline)
|
||||||
|
#else
|
||||||
.font(.caption)
|
.font(.caption)
|
||||||
|
#endif
|
||||||
.fontWeight(.medium)
|
.fontWeight(.medium)
|
||||||
}
|
}
|
||||||
#if !os(tvOS)
|
#if !os(tvOS)
|
||||||
@@ -223,7 +247,11 @@ struct CommentView: View {
|
|||||||
Task { await loadReplies() }
|
Task { await loadReplies() }
|
||||||
} label: {
|
} label: {
|
||||||
Text(String(localized: "comments.loadMoreReplies"))
|
Text(String(localized: "comments.loadMoreReplies"))
|
||||||
|
#if os(macOS)
|
||||||
|
.font(.subheadline)
|
||||||
|
#else
|
||||||
.font(.caption)
|
.font(.caption)
|
||||||
|
#endif
|
||||||
.fontWeight(.medium)
|
.fontWeight(.medium)
|
||||||
#if !os(tvOS)
|
#if !os(tvOS)
|
||||||
.foregroundStyle(accentColor)
|
.foregroundStyle(accentColor)
|
||||||
|
|||||||
@@ -1086,6 +1086,12 @@ struct VideoInfoView: View {
|
|||||||
action: @escaping () -> Void
|
action: @escaping () -> Void
|
||||||
) -> some View {
|
) -> some View {
|
||||||
Button(action: action) {
|
Button(action: action) {
|
||||||
|
#if os(macOS)
|
||||||
|
Label(label, systemImage: icon)
|
||||||
|
.font(.body)
|
||||||
|
.frame(maxWidth: .infinity)
|
||||||
|
.padding(.vertical, 4)
|
||||||
|
#else
|
||||||
VStack(spacing: 6) {
|
VStack(spacing: 6) {
|
||||||
Image(systemName: icon)
|
Image(systemName: icon)
|
||||||
.font(.system(size: 18))
|
.font(.system(size: 18))
|
||||||
@@ -1093,8 +1099,13 @@ struct VideoInfoView: View {
|
|||||||
.font(.caption)
|
.font(.caption)
|
||||||
}
|
}
|
||||||
.frame(maxWidth: .infinity, minHeight: 50)
|
.frame(maxWidth: .infinity, minHeight: 50)
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
#if os(macOS)
|
||||||
|
.buttonStyle(.bordered)
|
||||||
|
#else
|
||||||
.buttonStyle(.borderedProminent)
|
.buttonStyle(.borderedProminent)
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
private var actionButtons: some View {
|
private var actionButtons: some View {
|
||||||
@@ -1108,6 +1119,9 @@ struct VideoInfoView: View {
|
|||||||
label: String(localized: "video.context.play"),
|
label: String(localized: "video.context.play"),
|
||||||
action: playVideo
|
action: playVideo
|
||||||
)
|
)
|
||||||
|
#if os(macOS)
|
||||||
|
.tint(.accentColor)
|
||||||
|
#endif
|
||||||
|
|
||||||
// Download button
|
// Download button
|
||||||
verticalDownloadActionButton
|
verticalDownloadActionButton
|
||||||
@@ -1115,6 +1129,12 @@ struct VideoInfoView: View {
|
|||||||
// Share button
|
// Share button
|
||||||
if let video = displayedVideo {
|
if let video = displayedVideo {
|
||||||
ShareLink(item: video.shareURL) {
|
ShareLink(item: video.shareURL) {
|
||||||
|
#if os(macOS)
|
||||||
|
Label(String(localized: "video.share"), systemImage: "square.and.arrow.up")
|
||||||
|
.font(.body)
|
||||||
|
.frame(maxWidth: .infinity)
|
||||||
|
.padding(.vertical, 4)
|
||||||
|
#else
|
||||||
VStack(spacing: 6) {
|
VStack(spacing: 6) {
|
||||||
Image(systemName: "square.and.arrow.up")
|
Image(systemName: "square.and.arrow.up")
|
||||||
.font(.system(size: 18))
|
.font(.system(size: 18))
|
||||||
@@ -1122,8 +1142,13 @@ struct VideoInfoView: View {
|
|||||||
.font(.caption)
|
.font(.caption)
|
||||||
}
|
}
|
||||||
.frame(maxWidth: .infinity, minHeight: 50)
|
.frame(maxWidth: .infinity, minHeight: 50)
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
#if os(macOS)
|
||||||
|
.buttonStyle(.bordered)
|
||||||
|
#else
|
||||||
.buttonStyle(.borderedProminent)
|
.buttonStyle(.borderedProminent)
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.fixedSize(horizontal: false, vertical: true)
|
.fixedSize(horizontal: false, vertical: true)
|
||||||
@@ -1153,7 +1178,9 @@ struct VideoInfoView: View {
|
|||||||
.buttonStyle(.bordered)
|
.buttonStyle(.bordered)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#if !os(macOS)
|
||||||
.fontWeight(.semibold)
|
.fontWeight(.semibold)
|
||||||
|
#endif
|
||||||
.frame(maxWidth: 400)
|
.frame(maxWidth: 400)
|
||||||
.frame(maxWidth: .infinity)
|
.frame(maxWidth: .infinity)
|
||||||
.padding(.horizontal)
|
.padding(.horizontal)
|
||||||
@@ -1172,6 +1199,12 @@ struct VideoInfoView: View {
|
|||||||
Button(role: .destructive) {
|
Button(role: .destructive) {
|
||||||
showingRemoveDownloadConfirmation = true
|
showingRemoveDownloadConfirmation = true
|
||||||
} label: {
|
} label: {
|
||||||
|
#if os(macOS)
|
||||||
|
Label(String(localized: "video.downloaded"), systemImage: "checkmark.circle.fill")
|
||||||
|
.font(.body)
|
||||||
|
.frame(maxWidth: .infinity)
|
||||||
|
.padding(.vertical, 4)
|
||||||
|
#else
|
||||||
VStack(spacing: 6) {
|
VStack(spacing: 6) {
|
||||||
Image(systemName: "checkmark.circle.fill")
|
Image(systemName: "checkmark.circle.fill")
|
||||||
.font(.system(size: 18))
|
.font(.system(size: 18))
|
||||||
@@ -1179,13 +1212,39 @@ struct VideoInfoView: View {
|
|||||||
.font(.caption)
|
.font(.caption)
|
||||||
}
|
}
|
||||||
.frame(maxWidth: .infinity, minHeight: 50)
|
.frame(maxWidth: .infinity, minHeight: 50)
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
#if os(macOS)
|
||||||
|
.buttonStyle(.bordered)
|
||||||
|
#else
|
||||||
.buttonStyle(.borderedProminent)
|
.buttonStyle(.borderedProminent)
|
||||||
|
#endif
|
||||||
} else if isDownloading || isEnqueuingDownload {
|
} else if isDownloading || isEnqueuingDownload {
|
||||||
// Downloading/enqueueing state - shows progress
|
// Downloading/enqueueing state - shows progress
|
||||||
Button {
|
Button {
|
||||||
// No action while downloading
|
// No action while downloading
|
||||||
} label: {
|
} label: {
|
||||||
|
#if os(macOS)
|
||||||
|
HStack(spacing: 6) {
|
||||||
|
ProgressView()
|
||||||
|
.controlSize(.small)
|
||||||
|
if isEnqueuingDownload {
|
||||||
|
Text(String(localized: "video.downloading"))
|
||||||
|
.allowsTightening(true)
|
||||||
|
} else if let video = displayedVideo,
|
||||||
|
let progress = downloadManager?.downloadProgressByVideo[video.id],
|
||||||
|
!progress.isIndeterminate {
|
||||||
|
Text("\(Int(progress.progress * 100))%")
|
||||||
|
.monospacedDigit()
|
||||||
|
} else {
|
||||||
|
Text(String(localized: "video.downloading"))
|
||||||
|
.allowsTightening(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.font(.body)
|
||||||
|
.frame(maxWidth: .infinity)
|
||||||
|
.padding(.vertical, 4)
|
||||||
|
#else
|
||||||
VStack(spacing: 6) {
|
VStack(spacing: 6) {
|
||||||
ProgressView()
|
ProgressView()
|
||||||
.controlSize(.regular)
|
.controlSize(.regular)
|
||||||
@@ -1206,14 +1265,25 @@ struct VideoInfoView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
.frame(maxWidth: .infinity, minHeight: 50)
|
.frame(maxWidth: .infinity, minHeight: 50)
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
#if os(macOS)
|
||||||
|
.buttonStyle(.bordered)
|
||||||
|
#else
|
||||||
.buttonStyle(.borderedProminent)
|
.buttonStyle(.borderedProminent)
|
||||||
|
#endif
|
||||||
.disabled(true)
|
.disabled(true)
|
||||||
} else if let video = displayedVideo {
|
} else if let video = displayedVideo {
|
||||||
// Default state - download button
|
// Default state - download button
|
||||||
Button {
|
Button {
|
||||||
startDownload(for: video)
|
startDownload(for: video)
|
||||||
} label: {
|
} label: {
|
||||||
|
#if os(macOS)
|
||||||
|
Label(String(localized: "video.download"), systemImage: "arrow.down.circle")
|
||||||
|
.font(.body)
|
||||||
|
.frame(maxWidth: .infinity)
|
||||||
|
.padding(.vertical, 4)
|
||||||
|
#else
|
||||||
VStack(spacing: 6) {
|
VStack(spacing: 6) {
|
||||||
Image(systemName: "arrow.down.circle")
|
Image(systemName: "arrow.down.circle")
|
||||||
.font(.system(size: 18))
|
.font(.system(size: 18))
|
||||||
@@ -1221,8 +1291,13 @@ struct VideoInfoView: View {
|
|||||||
.font(.caption)
|
.font(.caption)
|
||||||
}
|
}
|
||||||
.frame(maxWidth: .infinity, minHeight: 50)
|
.frame(maxWidth: .infinity, minHeight: 50)
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
#if os(macOS)
|
||||||
|
.buttonStyle(.bordered)
|
||||||
|
#else
|
||||||
.buttonStyle(.borderedProminent)
|
.buttonStyle(.borderedProminent)
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1618,11 +1693,19 @@ struct VideoInfoView: View {
|
|||||||
private func infoRow(label: String, value: String) -> some View {
|
private func infoRow(label: String, value: String) -> some View {
|
||||||
VStack(alignment: .leading, spacing: 2) {
|
VStack(alignment: .leading, spacing: 2) {
|
||||||
Text(label)
|
Text(label)
|
||||||
|
#if os(macOS)
|
||||||
|
.font(.subheadline)
|
||||||
|
#else
|
||||||
.font(.caption)
|
.font(.caption)
|
||||||
|
#endif
|
||||||
.foregroundStyle(.secondary)
|
.foregroundStyle(.secondary)
|
||||||
|
|
||||||
Text(value)
|
Text(value)
|
||||||
|
#if os(macOS)
|
||||||
|
.font(.body)
|
||||||
|
#else
|
||||||
.font(.subheadline)
|
.font(.subheadline)
|
||||||
|
#endif
|
||||||
.fontWeight(.medium)
|
.fontWeight(.medium)
|
||||||
}
|
}
|
||||||
.frame(maxWidth: .infinity, alignment: .leading)
|
.frame(maxWidth: .infinity, alignment: .leading)
|
||||||
@@ -1643,7 +1726,11 @@ struct VideoInfoView: View {
|
|||||||
} else if let description = displayedVideo?.description, !description.isEmpty {
|
} else if let description = displayedVideo?.description, !description.isEmpty {
|
||||||
// Description available
|
// Description available
|
||||||
Text(DescriptionText.attributed(description, linkColor: accentColor))
|
Text(DescriptionText.attributed(description, linkColor: accentColor))
|
||||||
|
#if os(macOS)
|
||||||
|
.font(.body)
|
||||||
|
#else
|
||||||
.font(.subheadline)
|
.font(.subheadline)
|
||||||
|
#endif
|
||||||
.foregroundStyle(.secondary)
|
.foregroundStyle(.secondary)
|
||||||
.tint(accentColor)
|
.tint(accentColor)
|
||||||
.handleTimestampLinks(using: playerService)
|
.handleTimestampLinks(using: playerService)
|
||||||
@@ -1660,7 +1747,11 @@ struct VideoInfoView: View {
|
|||||||
CollapsibleSection(title: String(localized: "video.originalTitle"), isExpanded: $isOriginalTitleExpanded) {
|
CollapsibleSection(title: String(localized: "video.originalTitle"), isExpanded: $isOriginalTitleExpanded) {
|
||||||
if let title = displayedVideo?.title {
|
if let title = displayedVideo?.title {
|
||||||
Text(title)
|
Text(title)
|
||||||
|
#if os(macOS)
|
||||||
|
.font(.body)
|
||||||
|
#else
|
||||||
.font(.subheadline)
|
.font(.subheadline)
|
||||||
|
#endif
|
||||||
.foregroundStyle(.secondary)
|
.foregroundStyle(.secondary)
|
||||||
#if !os(tvOS)
|
#if !os(tvOS)
|
||||||
.textSelection(.enabled)
|
.textSelection(.enabled)
|
||||||
@@ -1727,7 +1818,11 @@ struct VideoInfoView: View {
|
|||||||
.font(.title2)
|
.font(.title2)
|
||||||
.foregroundStyle(.secondary)
|
.foregroundStyle(.secondary)
|
||||||
Text(String(localized: "videoInfo.comments.disabled"))
|
Text(String(localized: "videoInfo.comments.disabled"))
|
||||||
|
#if os(macOS)
|
||||||
|
.font(.body)
|
||||||
|
#else
|
||||||
.font(.subheadline)
|
.font(.subheadline)
|
||||||
|
#endif
|
||||||
.foregroundStyle(.secondary)
|
.foregroundStyle(.secondary)
|
||||||
}
|
}
|
||||||
Spacer()
|
Spacer()
|
||||||
@@ -1742,7 +1837,11 @@ struct VideoInfoView: View {
|
|||||||
.font(.title2)
|
.font(.title2)
|
||||||
.foregroundStyle(.secondary)
|
.foregroundStyle(.secondary)
|
||||||
Text(String(localized: "videoInfo.comments.error"))
|
Text(String(localized: "videoInfo.comments.error"))
|
||||||
|
#if os(macOS)
|
||||||
|
.font(.body)
|
||||||
|
#else
|
||||||
.font(.subheadline)
|
.font(.subheadline)
|
||||||
|
#endif
|
||||||
.foregroundStyle(.secondary)
|
.foregroundStyle(.secondary)
|
||||||
}
|
}
|
||||||
Spacer()
|
Spacer()
|
||||||
@@ -1754,7 +1853,11 @@ struct VideoInfoView: View {
|
|||||||
HStack {
|
HStack {
|
||||||
Spacer()
|
Spacer()
|
||||||
Text(String(localized: "videoInfo.comments.empty"))
|
Text(String(localized: "videoInfo.comments.empty"))
|
||||||
|
#if os(macOS)
|
||||||
|
.font(.body)
|
||||||
|
#else
|
||||||
.font(.subheadline)
|
.font(.subheadline)
|
||||||
|
#endif
|
||||||
.foregroundStyle(.secondary)
|
.foregroundStyle(.secondary)
|
||||||
Spacer()
|
Spacer()
|
||||||
}
|
}
|
||||||
@@ -1782,7 +1885,11 @@ struct VideoInfoView: View {
|
|||||||
.fontWeight(.medium)
|
.fontWeight(.medium)
|
||||||
Image(systemName: "chevron.right")
|
Image(systemName: "chevron.right")
|
||||||
}
|
}
|
||||||
|
#if os(macOS)
|
||||||
|
.font(.body)
|
||||||
|
#else
|
||||||
.font(.subheadline)
|
.font(.subheadline)
|
||||||
|
#endif
|
||||||
#if !os(tvOS)
|
#if !os(tvOS)
|
||||||
.foregroundStyle(accentColor)
|
.foregroundStyle(accentColor)
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user