mirror of
https://github.com/yattee/yattee.git
synced 2025-08-04 01:34:10 +00:00
Channel view and other small improvements
This commit is contained in:
@@ -40,6 +40,7 @@ struct FavoriteItemView: View {
|
||||
#endif
|
||||
|
||||
HorizontalCells(items: store.contentItems)
|
||||
.environment(\.inChannelView, inChannelView)
|
||||
}
|
||||
.contentShape(Rectangle())
|
||||
.onAppear {
|
||||
@@ -62,6 +63,15 @@ struct FavoriteItemView: View {
|
||||
}
|
||||
}
|
||||
|
||||
var inChannelView: Bool {
|
||||
switch item.section {
|
||||
case .channel:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
var itemControl: some View {
|
||||
VStack {
|
||||
#if os(tvOS)
|
||||
|
@@ -21,6 +21,13 @@ struct ChannelsView: View {
|
||||
}
|
||||
}
|
||||
}
|
||||
.contextMenu {
|
||||
Button {
|
||||
subscriptions.unsubscribe(channel.id)
|
||||
} label: {
|
||||
Label("Unsubscribe", systemImage: "xmark.circle")
|
||||
}
|
||||
}
|
||||
}
|
||||
#if os(tvOS)
|
||||
.padding(.horizontal, 50)
|
||||
|
56
Shared/Views/ChannelAvatarView.swift
Normal file
56
Shared/Views/ChannelAvatarView.swift
Normal file
@@ -0,0 +1,56 @@
|
||||
import SwiftUI
|
||||
|
||||
struct ChannelAvatarView: View {
|
||||
var channel: Channel?
|
||||
var video: Video?
|
||||
|
||||
@ObservedObject private var accounts = AccountsModel.shared
|
||||
@ObservedObject private var subscribedChannels = SubscribedChannelsModel.shared
|
||||
|
||||
var body: some View {
|
||||
ZStack(alignment: .bottomTrailing) {
|
||||
Group {
|
||||
Group {
|
||||
if let url = channel?.thumbnailURL {
|
||||
ThumbnailView(url: url)
|
||||
} else {
|
||||
ZStack {
|
||||
Color(white: 0.6)
|
||||
.opacity(0.5)
|
||||
|
||||
Group {
|
||||
if let video, video.isLocal {
|
||||
Image(systemName: video.localStreamImageSystemName)
|
||||
} else {
|
||||
Image(systemName: "play.rectangle")
|
||||
}
|
||||
}
|
||||
.foregroundColor(.accentColor)
|
||||
.font(.system(size: 20))
|
||||
.contentShape(Rectangle())
|
||||
}
|
||||
}
|
||||
}
|
||||
.clipShape(Circle())
|
||||
|
||||
if accounts.app.supportsSubscriptions,
|
||||
accounts.signedIn,
|
||||
let channel,
|
||||
subscribedChannels.isSubscribing(channel.id)
|
||||
{
|
||||
Image(systemName: "star.circle.fill")
|
||||
.background(Color.black)
|
||||
.clipShape(Circle())
|
||||
.foregroundColor(.secondary)
|
||||
}
|
||||
}
|
||||
}
|
||||
.imageScale(.small)
|
||||
}
|
||||
}
|
||||
|
||||
struct ChannelAvatarView_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
ChannelAvatarView(channel: Video.fixture.channel)
|
||||
}
|
||||
}
|
@@ -47,7 +47,7 @@ struct ChannelPlaylistView: View {
|
||||
|
||||
Spacer()
|
||||
|
||||
FavoriteButton(item: FavoriteItem(section: .channelPlaylist(playlist.id, playlist.title)))
|
||||
FavoriteButton(item: FavoriteItem(section: .channelPlaylist(accounts.app.appType.rawValue, playlist.id, playlist.title)))
|
||||
.labelStyle(.iconOnly)
|
||||
}
|
||||
|
||||
|
@@ -58,7 +58,7 @@ struct ChannelVideosView: View {
|
||||
subscriptionToggleButton
|
||||
|
||||
if let channel = presentedChannel {
|
||||
FavoriteButton(item: FavoriteItem(section: .channel(channel.id, channel.name)))
|
||||
FavoriteButton(item: FavoriteItem(section: .channel(accounts.app.appType.rawValue, channel.id, channel.name)))
|
||||
.labelStyle(.iconOnly)
|
||||
}
|
||||
}
|
||||
@@ -124,7 +124,7 @@ struct ChannelVideosView: View {
|
||||
|
||||
ToolbarItem {
|
||||
if let presentedChannel {
|
||||
FavoriteButton(item: FavoriteItem(section: .channel(presentedChannel.id, presentedChannel.name)))
|
||||
FavoriteButton(item: FavoriteItem(section: .channel(accounts.app.appType.rawValue, presentedChannel.id, presentedChannel.name)))
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -159,28 +159,12 @@ struct ChannelVideosView: View {
|
||||
}
|
||||
|
||||
var thumbnail: some View {
|
||||
Group {
|
||||
if let thumbnail = store.item?.thumbnailURL {
|
||||
WebImage(url: thumbnail)
|
||||
.resizable()
|
||||
} else {
|
||||
ZStack {
|
||||
Color(white: 0.6)
|
||||
.opacity(0.5)
|
||||
|
||||
Image(systemName: "play.rectangle")
|
||||
.foregroundColor(.accentColor)
|
||||
.imageScale(.small)
|
||||
.contentShape(Rectangle())
|
||||
}
|
||||
}
|
||||
}
|
||||
ChannelAvatarView(channel: store.item)
|
||||
#if os(tvOS)
|
||||
.frame(width: 80, height: 80, alignment: .trailing)
|
||||
.frame(width: 80, height: 80, alignment: .trailing)
|
||||
#else
|
||||
.frame(width: 30, height: 30, alignment: .trailing)
|
||||
.frame(width: 30, height: 30, alignment: .trailing)
|
||||
#endif
|
||||
.clipShape(Circle())
|
||||
}
|
||||
|
||||
@ViewBuilder var banner: some View {
|
||||
@@ -250,7 +234,8 @@ struct ChannelVideosView: View {
|
||||
subscriptionsLabel
|
||||
|
||||
if presentedChannel?.verified ?? false {
|
||||
Text("Verified")
|
||||
Image(systemName: "checkmark.seal.fill")
|
||||
.imageScale(.small)
|
||||
}
|
||||
|
||||
viewsLabel
|
||||
@@ -308,7 +293,7 @@ struct ChannelVideosView: View {
|
||||
subscriptionToggleButtonDisabled = false
|
||||
}
|
||||
} label: {
|
||||
Label("Unsubscribe", systemImage: "star.circle")
|
||||
Label("Unsubscribe", systemImage: "xmark.circle")
|
||||
#if os(iOS)
|
||||
.labelStyle(.automatic)
|
||||
#else
|
||||
|
@@ -144,22 +144,11 @@ struct ControlsBar: View {
|
||||
)
|
||||
}
|
||||
} label: {
|
||||
ZStack(alignment: .bottomTrailing) {
|
||||
authorAvatar
|
||||
|
||||
if accounts.app.supportsSubscriptions,
|
||||
accounts.signedIn,
|
||||
let video = model.currentVideo,
|
||||
subscriptions.isSubscribing(video.channel.id)
|
||||
{
|
||||
Image(systemName: "star.circle.fill")
|
||||
#if !os(tvOS)
|
||||
.background(Color.background)
|
||||
#endif
|
||||
.clipShape(Circle())
|
||||
.foregroundColor(.secondary)
|
||||
}
|
||||
}
|
||||
ChannelAvatarView(
|
||||
channel: model.currentVideo?.channel,
|
||||
video: model.currentVideo
|
||||
)
|
||||
.frame(width: barHeight - 10, height: barHeight - 10)
|
||||
}
|
||||
.contextMenu {
|
||||
if let video = model.currentVideo {
|
||||
@@ -207,7 +196,7 @@ struct ControlsBar: View {
|
||||
navigation.presentUnsubscribeAlert(video.channel, subscriptions: subscriptions)
|
||||
#endif
|
||||
} label: {
|
||||
Label("Unsubscribe", systemImage: "xmark.circle")
|
||||
Label("Unsubscribe", systemImage: "star.circle")
|
||||
}
|
||||
} else {
|
||||
Button {
|
||||
@@ -275,38 +264,6 @@ struct ControlsBar: View {
|
||||
Spacer()
|
||||
}
|
||||
}
|
||||
|
||||
private var authorAvatar: some View {
|
||||
Group {
|
||||
if let url = model.currentItem?.video?.channel.thumbnailURL {
|
||||
WebImage(url: url, options: [.lowPriority])
|
||||
.resizable()
|
||||
.placeholder {
|
||||
Rectangle().fill(Color("PlaceholderColor"))
|
||||
}
|
||||
.retryOnAppear(true)
|
||||
.indicator(.activity)
|
||||
} else {
|
||||
ZStack {
|
||||
Color(white: 0.6)
|
||||
.opacity(0.5)
|
||||
|
||||
Group {
|
||||
if let video = model.currentItem?.video, video.isLocal {
|
||||
Image(systemName: video.localStreamImageSystemName)
|
||||
} else {
|
||||
Image(systemName: "play.rectangle")
|
||||
}
|
||||
}
|
||||
.foregroundColor(.accentColor)
|
||||
.font(.system(size: 20))
|
||||
.contentShape(Rectangle())
|
||||
}
|
||||
}
|
||||
}
|
||||
.frame(width: 44, height: 44, alignment: .leading)
|
||||
.clipShape(Circle())
|
||||
}
|
||||
}
|
||||
|
||||
struct ControlsBar_Previews: PreviewProvider {
|
||||
|
Reference in New Issue
Block a user