mirror of
https://github.com/yattee/yattee.git
synced 2024-12-23 05:53:41 +00:00
Merge pull request #559 from stonerl/collapsable-details
make description collapsible
This commit is contained in:
commit
fb5e86c2cb
@ -147,6 +147,7 @@ extension Defaults.Keys {
|
|||||||
static let expandVideoDescriptionDefault = true
|
static let expandVideoDescriptionDefault = true
|
||||||
#endif
|
#endif
|
||||||
static let expandVideoDescription = Key<Bool>("expandVideoDescription", default: expandVideoDescriptionDefault)
|
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 showChannelAvatarInChannelsLists = Key<Bool>("showChannelAvatarInChannelsLists", default: true)
|
||||||
static let showChannelAvatarInVideosListing = Key<Bool>("showChannelAvatarInVideosListing", default: true)
|
static let showChannelAvatarInVideosListing = Key<Bool>("showChannelAvatarInVideosListing", default: true)
|
||||||
|
@ -6,11 +6,10 @@ import Foundation
|
|||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
struct VideoDescription: View {
|
struct VideoDescription: View {
|
||||||
static let collapsedLines = 5
|
|
||||||
|
|
||||||
private var search: SearchModel { .shared }
|
private var search: SearchModel { .shared }
|
||||||
@Default(.showKeywords) private var showKeywords
|
@Default(.showKeywords) private var showKeywords
|
||||||
@Default(.expandVideoDescription) private var expandVideoDescription
|
@Default(.expandVideoDescription) private var expandVideoDescription
|
||||||
|
@Default(.collapsedLinesDescription) private var collapsedLinesDescription
|
||||||
|
|
||||||
var video: Video
|
var video: Video
|
||||||
var detailsSize: CGSize?
|
var detailsSize: CGSize?
|
||||||
@ -21,28 +20,19 @@ struct VideoDescription: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
Group {
|
descriptionView.id(video.videoID)
|
||||||
if !expandVideoDescription && !expand {
|
|
||||||
Button {
|
|
||||||
expand = true
|
|
||||||
} label: {
|
|
||||||
descriptionView
|
|
||||||
}
|
|
||||||
.buttonStyle(.plain)
|
|
||||||
} else {
|
|
||||||
descriptionView
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.id(video.videoID)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var descriptionView: some View {
|
@ViewBuilder var descriptionView: some View {
|
||||||
|
if !expand && collapsedLinesDescription == 0 {
|
||||||
|
EmptyView()
|
||||||
|
} else {
|
||||||
VStack {
|
VStack {
|
||||||
#if os(iOS)
|
#if os(iOS)
|
||||||
ActiveLabelDescriptionRepresentable(
|
ActiveLabelDescriptionRepresentable(
|
||||||
description: description,
|
description: description,
|
||||||
detailsSize: detailsSize,
|
detailsSize: detailsSize,
|
||||||
expand: shouldExpand
|
expand: expand
|
||||||
)
|
)
|
||||||
#else
|
#else
|
||||||
textDescription
|
textDescription
|
||||||
@ -51,26 +41,37 @@ struct VideoDescription: View {
|
|||||||
keywords
|
keywords
|
||||||
}
|
}
|
||||||
.contentShape(Rectangle())
|
.contentShape(Rectangle())
|
||||||
|
.overlay(
|
||||||
|
Group {
|
||||||
|
#if canImport(UIKit)
|
||||||
|
if !expand {
|
||||||
|
Button(action: { expand.toggle() }) {
|
||||||
|
Rectangle()
|
||||||
|
.foregroundColor(.clear)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var shouldExpand: Bool {
|
var shouldExpand: Bool {
|
||||||
expandVideoDescription || expand
|
expand
|
||||||
}
|
}
|
||||||
|
|
||||||
@ViewBuilder var textDescription: some View {
|
@ViewBuilder var textDescription: some View {
|
||||||
#if !os(iOS)
|
#if canImport(AppKit)
|
||||||
Group {
|
Group {
|
||||||
if #available(macOS 12, *) {
|
if #available(macOS 12, *) {
|
||||||
DescriptionWithLinks(description: description, detailsSize: detailsSize)
|
DescriptionWithLinks(description: description, detailsSize: detailsSize)
|
||||||
.frame(maxWidth: .infinity, alignment: .leading)
|
.frame(maxWidth: .infinity, alignment: .leading)
|
||||||
.lineLimit(shouldExpand ? 500 : Self.collapsedLines)
|
.lineLimit(shouldExpand ? 500 : collapsedLinesDescription)
|
||||||
#if !os(tvOS)
|
|
||||||
.textSelection(.enabled)
|
.textSelection(.enabled)
|
||||||
#endif
|
|
||||||
} else {
|
} else {
|
||||||
Text(description)
|
Text(description)
|
||||||
.frame(maxWidth: .infinity, alignment: .leading)
|
.frame(maxWidth: .infinity, alignment: .leading)
|
||||||
.lineLimit(shouldExpand ? 500 : Self.collapsedLines)
|
.lineLimit(shouldExpand ? 500 : collapsedLinesDescription)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.multilineTextAlignment(.leading)
|
.multilineTextAlignment(.leading)
|
||||||
@ -80,7 +81,7 @@ struct VideoDescription: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If possibe convert URLs to clickable links
|
// If possibe convert URLs to clickable links
|
||||||
#if os(macOS)
|
#if canImport(AppKit)
|
||||||
@available(macOS 12, *)
|
@available(macOS 12, *)
|
||||||
struct DescriptionWithLinks: View {
|
struct DescriptionWithLinks: View {
|
||||||
let description: String
|
let description: String
|
||||||
@ -136,7 +137,7 @@ struct VideoDescription: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var showScrollIndicators: Bool {
|
var showScrollIndicators: Bool {
|
||||||
#if os(macOS)
|
#if canImport(AppKit)
|
||||||
false
|
false
|
||||||
#else
|
#else
|
||||||
true
|
true
|
||||||
@ -154,6 +155,8 @@ struct VideoDescription: View {
|
|||||||
|
|
||||||
@Environment(\.openURL) private var openURL
|
@Environment(\.openURL) private var openURL
|
||||||
|
|
||||||
|
@Default(.collapsedLinesDescription) private var collapsedLinesDescription
|
||||||
|
|
||||||
var player = PlayerModel.shared
|
var player = PlayerModel.shared
|
||||||
|
|
||||||
func makeUIView(context _: Context) -> some UIView {
|
func makeUIView(context _: Context) -> some UIView {
|
||||||
@ -187,7 +190,12 @@ struct VideoDescription: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func updateNumberOfLines() {
|
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) {
|
func urlTapHandler(_ url: URL) {
|
||||||
|
@ -243,6 +243,9 @@ struct VideoDetails: View {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
.background(colorScheme == .dark ? Color.black : .white)
|
.background(colorScheme == .dark ? Color.black : .white)
|
||||||
|
.onAppear {
|
||||||
|
descriptionExpanded = expandVideoDescription
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if os(iOS)
|
#if os(iOS)
|
||||||
@ -407,18 +410,34 @@ struct VideoDetails: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var descriptionHeader: some View {
|
var descriptionHeader: some View {
|
||||||
|
#if canImport(UIKit)
|
||||||
|
Button(action: {
|
||||||
|
descriptionExpanded.toggle()
|
||||||
|
}) {
|
||||||
HStack {
|
HStack {
|
||||||
Text("Description".localized())
|
Text("Description".localized())
|
||||||
|
|
||||||
if !expandVideoDescription, !descriptionExpanded {
|
|
||||||
Spacer()
|
Spacer()
|
||||||
Image(systemName: "arrow.up.and.down")
|
Image(systemName: descriptionExpanded ? "chevron.up" : "chevron.down")
|
||||||
|
.imageScale(.small)
|
||||||
|
}
|
||||||
|
.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)
|
.imageScale(.small)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.padding(.horizontal)
|
.padding(.horizontal)
|
||||||
.font(.caption)
|
.font(.caption)
|
||||||
.foregroundColor(.secondary)
|
.foregroundColor(.secondary)
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
var chaptersHeader: some View {
|
var chaptersHeader: some View {
|
||||||
|
@ -10,6 +10,7 @@ struct PlayerSettings: View {
|
|||||||
@Default(.showKeywords) private var showKeywords
|
@Default(.showKeywords) private var showKeywords
|
||||||
#if !os(tvOS)
|
#if !os(tvOS)
|
||||||
@Default(.showScrollToTopInComments) private var showScrollToTopInComments
|
@Default(.showScrollToTopInComments) private var showScrollToTopInComments
|
||||||
|
@Default(.collapsedLinesDescription) private var collapsedLinesDescription
|
||||||
#endif
|
#endif
|
||||||
@Default(.expandVideoDescription) private var expandVideoDescription
|
@Default(.expandVideoDescription) private var expandVideoDescription
|
||||||
@Default(.pauseOnHidingPlayer) private var pauseOnHidingPlayer
|
@Default(.pauseOnHidingPlayer) private var pauseOnHidingPlayer
|
||||||
@ -77,6 +78,7 @@ struct PlayerSettings: View {
|
|||||||
#if !os(tvOS)
|
#if !os(tvOS)
|
||||||
Section(header: SettingsHeader(text: "Info".localized())) {
|
Section(header: SettingsHeader(text: "Info".localized())) {
|
||||||
expandVideoDescriptionToggle
|
expandVideoDescriptionToggle
|
||||||
|
collapsedLineDescriptionStepper
|
||||||
showChaptersToggle
|
showChaptersToggle
|
||||||
showRelatedToggle
|
showRelatedToggle
|
||||||
#if os(macOS)
|
#if os(macOS)
|
||||||
@ -194,6 +196,24 @@ struct PlayerSettings: View {
|
|||||||
Toggle("Open video description expanded", isOn: $expandVideoDescription)
|
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 {
|
private var returnYouTubeDislikeToggle: some View {
|
||||||
Toggle("Enable Return YouTube Dislike", isOn: $enableReturnYouTubeDislike)
|
Toggle("Enable Return YouTube Dislike", isOn: $enableReturnYouTubeDislike)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user