Merge pull request #559 from stonerl/collapsable-details

make description collapsible
This commit is contained in:
Arkadiusz Fal 2023-11-26 18:57:27 +01:00 committed by GitHub
commit fb5e86c2cb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 96 additions and 48 deletions

View File

@ -147,6 +147,7 @@ extension Defaults.Keys {
static let expandVideoDescriptionDefault = true
#endif
static let expandVideoDescription = Key<Bool>("expandVideoDescription", default: expandVideoDescriptionDefault)
static let collapsedLinesDescription = Key<Int>("collapsedLinesDescription", default: 5)
static let showChannelAvatarInChannelsLists = Key<Bool>("showChannelAvatarInChannelsLists", default: true)
static let showChannelAvatarInVideosListing = Key<Bool>("showChannelAvatarInVideosListing", default: true)

View File

@ -6,11 +6,10 @@ import Foundation
import SwiftUI
struct VideoDescription: View {
static let collapsedLines = 5
private var search: SearchModel { .shared }
@Default(.showKeywords) private var showKeywords
@Default(.expandVideoDescription) private var expandVideoDescription
@Default(.collapsedLinesDescription) private var collapsedLinesDescription
var video: Video
var detailsSize: CGSize?
@ -21,56 +20,58 @@ struct VideoDescription: View {
}
var body: some View {
Group {
if !expandVideoDescription && !expand {
Button {
expand = true
} label: {
descriptionView
}
.buttonStyle(.plain)
} else {
descriptionView
}
}
.id(video.videoID)
descriptionView.id(video.videoID)
}
var descriptionView: some View {
VStack {
#if os(iOS)
ActiveLabelDescriptionRepresentable(
description: description,
detailsSize: detailsSize,
expand: shouldExpand
)
#else
textDescription
#endif
@ViewBuilder var descriptionView: some View {
if !expand && collapsedLinesDescription == 0 {
EmptyView()
} else {
VStack {
#if os(iOS)
ActiveLabelDescriptionRepresentable(
description: description,
detailsSize: detailsSize,
expand: expand
)
#else
textDescription
#endif
keywords
keywords
}
.contentShape(Rectangle())
.overlay(
Group {
#if canImport(UIKit)
if !expand {
Button(action: { expand.toggle() }) {
Rectangle()
.foregroundColor(.clear)
}
}
#endif
}
)
}
.contentShape(Rectangle())
}
var shouldExpand: Bool {
expandVideoDescription || expand
expand
}
@ViewBuilder var textDescription: some View {
#if !os(iOS)
#if canImport(AppKit)
Group {
if #available(macOS 12, *) {
DescriptionWithLinks(description: description, detailsSize: detailsSize)
.frame(maxWidth: .infinity, alignment: .leading)
.lineLimit(shouldExpand ? 500 : Self.collapsedLines)
#if !os(tvOS)
.lineLimit(shouldExpand ? 500 : collapsedLinesDescription)
.textSelection(.enabled)
#endif
} else {
Text(description)
.frame(maxWidth: .infinity, alignment: .leading)
.lineLimit(shouldExpand ? 500 : Self.collapsedLines)
.lineLimit(shouldExpand ? 500 : collapsedLinesDescription)
}
}
.multilineTextAlignment(.leading)
@ -80,7 +81,7 @@ struct VideoDescription: View {
}
// If possibe convert URLs to clickable links
#if os(macOS)
#if canImport(AppKit)
@available(macOS 12, *)
struct DescriptionWithLinks: View {
let description: String
@ -136,7 +137,7 @@ struct VideoDescription: View {
}
var showScrollIndicators: Bool {
#if os(macOS)
#if canImport(AppKit)
false
#else
true
@ -154,6 +155,8 @@ struct VideoDescription: View {
@Environment(\.openURL) private var openURL
@Default(.collapsedLinesDescription) private var collapsedLinesDescription
var player = PlayerModel.shared
func makeUIView(context _: Context) -> some UIView {
@ -187,7 +190,12 @@ struct VideoDescription: View {
}
func updateNumberOfLines() {
label.numberOfLines = expand ? 0 : VideoDescription.collapsedLines
if expand || collapsedLinesDescription > 0 {
label.numberOfLines = expand ? 0 : collapsedLinesDescription
label.isHidden = false
} else {
label.isHidden = true
}
}
func urlTapHandler(_ url: URL) {

View File

@ -243,6 +243,9 @@ struct VideoDetails: View {
}
})
.background(colorScheme == .dark ? Color.black : .white)
.onAppear {
descriptionExpanded = expandVideoDescription
}
}
#if os(iOS)
@ -407,18 +410,34 @@ struct VideoDetails: View {
}
var descriptionHeader: some View {
HStack {
Text("Description".localized())
if !expandVideoDescription, !descriptionExpanded {
Spacer()
Image(systemName: "arrow.up.and.down")
.imageScale(.small)
#if canImport(UIKit)
Button(action: {
descriptionExpanded.toggle()
}) {
HStack {
Text("Description".localized())
Spacer()
Image(systemName: descriptionExpanded ? "chevron.up" : "chevron.down")
.imageScale(.small)
}
.padding(.horizontal)
.font(.caption)
.foregroundColor(.secondary)
}
}
.padding(.horizontal)
.font(.caption)
.foregroundColor(.secondary)
#elseif canImport(AppKit)
HStack {
Text("Description".localized())
Spacer()
Button { descriptionExpanded.toggle()
} label: {
Image(systemName: descriptionExpanded ? "chevron.up" : "chevron.down")
.imageScale(.small)
}
}
.padding(.horizontal)
.font(.caption)
.foregroundColor(.secondary)
#endif
}
var chaptersHeader: some View {

View File

@ -10,6 +10,7 @@ struct PlayerSettings: View {
@Default(.showKeywords) private var showKeywords
#if !os(tvOS)
@Default(.showScrollToTopInComments) private var showScrollToTopInComments
@Default(.collapsedLinesDescription) private var collapsedLinesDescription
#endif
@Default(.expandVideoDescription) private var expandVideoDescription
@Default(.pauseOnHidingPlayer) private var pauseOnHidingPlayer
@ -77,6 +78,7 @@ struct PlayerSettings: View {
#if !os(tvOS)
Section(header: SettingsHeader(text: "Info".localized())) {
expandVideoDescriptionToggle
collapsedLineDescriptionStepper
showChaptersToggle
showRelatedToggle
#if os(macOS)
@ -194,6 +196,24 @@ struct PlayerSettings: View {
Toggle("Open video description expanded", isOn: $expandVideoDescription)
}
#if !os(tvOS)
private var collapsedLineDescriptionStepper: some View {
LazyVStack {
Stepper(value: $collapsedLinesDescription, in: 0 ... 10) {
Text("Description preview")
#if os(macOS)
Spacer()
#endif
if collapsedLinesDescription == 0 {
Text("No preview")
} else {
Text("\(collapsedLinesDescription) lines")
}
}
}
}
#endif
private var returnYouTubeDislikeToggle: some View {
Toggle("Enable Return YouTube Dislike", isOn: $enableReturnYouTubeDislike)
}