mirror of
https://github.com/yattee/yattee.git
synced 2025-08-06 10:44:06 +00:00
Show channel thumbnail in player
This commit is contained in:
@@ -33,6 +33,7 @@ extension Defaults.Keys {
|
||||
static let playerSidebar = Key<PlayerSidebarSetting>("playerSidebar", default: PlayerSidebarSetting.defaultValue)
|
||||
static let playerInstanceID = Key<Instance.ID?>("playerInstance")
|
||||
static let showKeywords = Key<Bool>("showKeywords", default: false)
|
||||
static let showChannelSubscribers = Key<Bool>("showChannelSubscribers", default: true)
|
||||
static let commentsInstanceID = Key<Instance.ID?>("commentsInstance", default: kavinPipedInstanceID)
|
||||
#if !os(tvOS)
|
||||
static let commentsPlacement = Key<CommentsPlacement>("commentsPlacement", default: .separate)
|
||||
|
@@ -5,6 +5,7 @@ struct Player: UIViewControllerRepresentable {
|
||||
@EnvironmentObject<CommentsModel> private var comments
|
||||
@EnvironmentObject<NavigationModel> private var navigation
|
||||
@EnvironmentObject<PlayerModel> private var player
|
||||
@EnvironmentObject<SubscriptionsModel> private var subscriptions
|
||||
|
||||
var controller: PlayerViewController?
|
||||
|
||||
@@ -22,6 +23,7 @@ struct Player: UIViewControllerRepresentable {
|
||||
controller.commentsModel = comments
|
||||
controller.navigationModel = navigation
|
||||
controller.playerModel = player
|
||||
controller.subscriptionsModel = subscriptions
|
||||
player.controller = controller
|
||||
|
||||
return controller
|
||||
|
@@ -1,5 +1,4 @@
|
||||
import AVKit
|
||||
import Logging
|
||||
import SwiftUI
|
||||
|
||||
final class PlayerViewController: UIViewController {
|
||||
@@ -7,6 +6,7 @@ final class PlayerViewController: UIViewController {
|
||||
var commentsModel: CommentsModel!
|
||||
var navigationModel: NavigationModel!
|
||||
var playerModel: PlayerModel!
|
||||
var subscriptionsModel: SubscriptionsModel!
|
||||
var playerViewController = AVPlayerViewController()
|
||||
|
||||
#if !os(tvOS)
|
||||
@@ -71,6 +71,7 @@ final class PlayerViewController: UIViewController {
|
||||
.frame(maxHeight: 600)
|
||||
.environmentObject(commentsModel)
|
||||
.environmentObject(playerModel)
|
||||
.environmentObject(subscriptionsModel)
|
||||
)
|
||||
)
|
||||
|
||||
|
@@ -1,5 +1,6 @@
|
||||
import Defaults
|
||||
import Foundation
|
||||
import SDWebImageSwiftUI
|
||||
import SwiftUI
|
||||
|
||||
struct VideoDetails: View {
|
||||
@@ -20,11 +21,15 @@ struct VideoDetails: View {
|
||||
|
||||
@Environment(\.presentationMode) private var presentationMode
|
||||
@Environment(\.inNavigationView) private var inNavigationView
|
||||
@Environment(\.navigationStyle) private var navigationStyle
|
||||
|
||||
@EnvironmentObject<AccountsModel> private var accounts
|
||||
@EnvironmentObject<NavigationModel> private var navigation
|
||||
@EnvironmentObject<PlayerModel> private var player
|
||||
@EnvironmentObject<RecentsModel> private var recents
|
||||
@EnvironmentObject<SubscriptionsModel> private var subscriptions
|
||||
|
||||
@Default(.showChannelSubscribers) private var showChannelSubscribers
|
||||
@Default(.showKeywords) private var showKeywords
|
||||
|
||||
init(
|
||||
@@ -65,7 +70,9 @@ struct VideoDetails: View {
|
||||
}
|
||||
.padding(.horizontal)
|
||||
|
||||
if CommentsModel.enabled, CommentsModel.placement == .separate {
|
||||
if !sidebarQueue ||
|
||||
(CommentsModel.enabled && CommentsModel.placement == .separate)
|
||||
{
|
||||
pagePicker
|
||||
.padding(.horizontal)
|
||||
}
|
||||
@@ -178,21 +185,52 @@ struct VideoDetails: View {
|
||||
Group {
|
||||
if video != nil {
|
||||
HStack(alignment: .center) {
|
||||
HStack(spacing: 4) {
|
||||
if subscribed {
|
||||
Image(systemName: "star.circle.fill")
|
||||
}
|
||||
VStack(alignment: .leading) {
|
||||
Text(video!.channel.name)
|
||||
.font(.system(size: 13))
|
||||
.bold()
|
||||
if let subscribers = video!.channel.subscriptionsString {
|
||||
Text("\(subscribers) subscribers")
|
||||
HStack(spacing: 10) {
|
||||
Group {
|
||||
ZStack(alignment: .bottomTrailing) {
|
||||
authorAvatar
|
||||
|
||||
if subscribed {
|
||||
Image(systemName: "star.circle.fill")
|
||||
.background(Color.background)
|
||||
.clipShape(Circle())
|
||||
.foregroundColor(.secondary)
|
||||
}
|
||||
}
|
||||
|
||||
VStack(alignment: .leading) {
|
||||
Text(video!.channel.name)
|
||||
.font(.system(size: 14))
|
||||
.bold()
|
||||
|
||||
if showChannelSubscribers {
|
||||
Group {
|
||||
if let subscribers = video!.channel.subscriptionsString {
|
||||
Text("\(subscribers) subscribers")
|
||||
}
|
||||
}
|
||||
.foregroundColor(.secondary)
|
||||
.font(.caption2)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.contentShape(RoundedRectangle(cornerRadius: 12))
|
||||
.contextMenu {
|
||||
if let video = video {
|
||||
Button(action: {
|
||||
NavigationModel.openChannel(
|
||||
video.channel,
|
||||
player: player,
|
||||
recents: recents,
|
||||
navigation: navigation,
|
||||
navigationStyle: navigationStyle
|
||||
)
|
||||
}) {
|
||||
Label("\(video.channel.name) Channel", systemImage: "rectangle.stack.fill.badge.person.crop")
|
||||
}
|
||||
}
|
||||
}
|
||||
.foregroundColor(.secondary)
|
||||
|
||||
if accounts.app.supportsSubscriptions {
|
||||
Spacer()
|
||||
@@ -209,7 +247,7 @@ struct VideoDetails: View {
|
||||
.alert(isPresented: $presentingUnsubscribeAlert) {
|
||||
Alert(
|
||||
title: Text(
|
||||
"Are you you want to unsubscribe from \(video!.channel.name)?"
|
||||
"Are you sure you want to unsubscribe from \(video!.channel.name)?"
|
||||
),
|
||||
primaryButton: .destructive(Text("Unsubscribe")) {
|
||||
subscriptions.unsubscribe(video!.channel.id)
|
||||
@@ -364,6 +402,22 @@ struct VideoDetails: View {
|
||||
ContentItem(video: player.currentVideo!)
|
||||
}
|
||||
|
||||
private var authorAvatar: some View {
|
||||
Group {
|
||||
if let video = video, let url = video.channel.thumbnailURL {
|
||||
WebImage(url: url)
|
||||
.resizable()
|
||||
.placeholder {
|
||||
Rectangle().fill(Color("PlaceholderColor"))
|
||||
}
|
||||
.retryOnAppear(false)
|
||||
.indicator(.activity)
|
||||
.clipShape(Circle())
|
||||
.frame(width: 45, height: 45, alignment: .leading)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var detailsPage: some View {
|
||||
Group {
|
||||
Group {
|
||||
|
@@ -7,6 +7,7 @@ struct PlaybackSettings: View {
|
||||
@Default(.quality) private var quality
|
||||
@Default(.playerSidebar) private var playerSidebar
|
||||
@Default(.showKeywords) private var showKeywords
|
||||
@Default(.showChannelSubscribers) private var channelSubscribers
|
||||
@Default(.saveHistory) private var saveHistory
|
||||
|
||||
#if os(iOS)
|
||||
@@ -27,6 +28,7 @@ struct PlaybackSettings: View {
|
||||
}
|
||||
|
||||
keywordsToggle
|
||||
channelSubscribersToggle
|
||||
}
|
||||
#else
|
||||
Section(header: SettingsHeader(text: "Source")) {
|
||||
@@ -44,6 +46,7 @@ struct PlaybackSettings: View {
|
||||
#endif
|
||||
|
||||
keywordsToggle
|
||||
channelSubscribersToggle
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -107,6 +110,10 @@ struct PlaybackSettings: View {
|
||||
private var keywordsToggle: some View {
|
||||
Toggle("Show video keywords", isOn: $showKeywords)
|
||||
}
|
||||
|
||||
private var channelSubscribersToggle: some View {
|
||||
Toggle("Show channel subscribers count", isOn: $channelSubscribers)
|
||||
}
|
||||
}
|
||||
|
||||
struct PlaybackSettings_Previews: PreviewProvider {
|
||||
|
Reference in New Issue
Block a user