Fix favorites view redrawing

This commit is contained in:
Arkadiusz Fal 2021-11-05 23:44:52 +01:00
parent ef9143263f
commit 9a4e404389
5 changed files with 75 additions and 71 deletions

View File

@ -273,6 +273,9 @@
37B17DA0268A1F89006AEE9B /* VideoContextMenuView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37B17D9F268A1F25006AEE9B /* VideoContextMenuView.swift */; };
37B17DA1268A1F89006AEE9B /* VideoContextMenuView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37B17D9F268A1F25006AEE9B /* VideoContextMenuView.swift */; };
37B17DA2268A1F8A006AEE9B /* VideoContextMenuView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37B17D9F268A1F25006AEE9B /* VideoContextMenuView.swift */; };
37B2631A2735EAAB00FE0D40 /* FavoriteResourceObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37B263192735EAAB00FE0D40 /* FavoriteResourceObserver.swift */; };
37B2631B2735EAAB00FE0D40 /* FavoriteResourceObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37B263192735EAAB00FE0D40 /* FavoriteResourceObserver.swift */; };
37B2631C2735EAAB00FE0D40 /* FavoriteResourceObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37B263192735EAAB00FE0D40 /* FavoriteResourceObserver.swift */; };
37B767DB2677C3CA0098BAA8 /* PlayerModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37B767DA2677C3CA0098BAA8 /* PlayerModel.swift */; };
37B767DC2677C3CA0098BAA8 /* PlayerModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37B767DA2677C3CA0098BAA8 /* PlayerModel.swift */; };
37B767DD2677C3CA0098BAA8 /* PlayerModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37B767DA2677C3CA0098BAA8 /* PlayerModel.swift */; };
@ -607,6 +610,7 @@
37AAF29F26741C97007FC770 /* SubscriptionsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SubscriptionsView.swift; sourceTree = "<group>"; };
37B044B626F7AB9000E1419D /* SettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsView.swift; sourceTree = "<group>"; };
37B17D9F268A1F25006AEE9B /* VideoContextMenuView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VideoContextMenuView.swift; sourceTree = "<group>"; };
37B263192735EAAB00FE0D40 /* FavoriteResourceObserver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FavoriteResourceObserver.swift; sourceTree = "<group>"; };
37B767DA2677C3CA0098BAA8 /* PlayerModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayerModel.swift; sourceTree = "<group>"; };
37B81AF826D2C9A700675966 /* VideoPlayerSizeModifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VideoPlayerSizeModifier.swift; sourceTree = "<group>"; };
37B81AFB26D2C9C900675966 /* VideoDetailsPaddingModifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VideoDetailsPaddingModifier.swift; sourceTree = "<group>"; };
@ -957,9 +961,10 @@
3788AC2126F683AB00F6BAA9 /* Favorites */ = {
isa = PBXGroup;
children = (
37BF661E27308884008CCFB0 /* DropFavoriteOutside.swift */,
37BF661B27308859008CCFB0 /* DropFavorite.swift */,
37BF661E27308884008CCFB0 /* DropFavoriteOutside.swift */,
3788AC2626F6840700F6BAA9 /* FavoriteItemView.swift */,
37B263192735EAAB00FE0D40 /* FavoriteResourceObserver.swift */,
37A9965D26D6F9B9006E3224 /* FavoritesView.swift */,
);
path = Favorites;
@ -1756,6 +1761,7 @@
37C3A24927235FAA0087A57A /* ChannelPlaylistCell.swift in Sources */,
373CFACB26966264003CB2C6 /* SearchQuery.swift in Sources */,
37141673267A8E10006CA35D /* Country.swift in Sources */,
37B2631A2735EAAB00FE0D40 /* FavoriteResourceObserver.swift in Sources */,
3748186E26A769D60084E870 /* DetailBadge.swift in Sources */,
376BE50B27349108009AD608 /* BrowsingSettings.swift in Sources */,
37AAF2A026741C97007FC770 /* SubscriptionsView.swift in Sources */,
@ -1887,6 +1893,7 @@
37732FF12703A26300F04329 /* AccountValidationStatus.swift in Sources */,
37BA794C26DC30EC002A0235 /* AppSidebarPlaylists.swift in Sources */,
37CC3F46270CE30600608308 /* PlayerQueueItem.swift in Sources */,
37B2631B2735EAAB00FE0D40 /* FavoriteResourceObserver.swift in Sources */,
3700155C271B0D4D0049C794 /* PipedAPI.swift in Sources */,
376BE50C27349108009AD608 /* BrowsingSettings.swift in Sources */,
37D4B19826717E1500C925CA /* Video.swift in Sources */,
@ -2016,6 +2023,7 @@
37484C3326FCB8F900287258 /* AccountValidator.swift in Sources */,
37CEE4C32677B697005A1EFE /* Stream.swift in Sources */,
37F64FE626FE70A60081B69E /* RedrawOnModifier.swift in Sources */,
37B2631C2735EAAB00FE0D40 /* FavoriteResourceObserver.swift in Sources */,
37484C2B26FC83FF00287258 /* AccountForm.swift in Sources */,
37FB2860272225E800A57617 /* ContentItemView.swift in Sources */,
374C053727242D9F009BDDBE /* ServicesSettings.swift in Sources */,

View File

@ -3,42 +3,24 @@ import Siesta
import SwiftUI
import UniformTypeIdentifiers
final class FavoriteResourceObserver: ObservableObject, ResourceObserver {
@Published var videos = [Video]()
func resourceChanged(_ resource: Resource, event _: ResourceEvent) {
if let videos: [Video] = resource.typedContent() {
self.videos = videos
} else if let channel: Channel = resource.typedContent() {
videos = channel.videos
} else if let playlist: ChannelPlaylist = resource.typedContent() {
videos = playlist.videos
} else if let playlist: Playlist = resource.typedContent() {
videos = playlist.videos
}
}
}
struct FavoriteItemView: View {
let item: FavoriteItem
let resource: Resource?
@StateObject private var store = FavoriteResourceObserver()
@Binding private var favorites: [FavoriteItem]
@Default(.favorites) private var favorites
@Binding private var dragging: FavoriteItem?
@EnvironmentObject<PlaylistsModel> private var playlistsModel
@EnvironmentObject<AccountsModel> private var accounts
@EnvironmentObject<PlaylistsModel> private var playlists
private var favoritesModel = FavoritesModel.shared
init(
item: FavoriteItem,
resource: Resource?,
favorites: Binding<[FavoriteItem]>,
dragging: Binding<FavoriteItem?>
) {
self.item = item
self.resource = resource
_favorites = favorites
_dragging = dragging
}
@ -47,10 +29,9 @@ struct FavoriteItemView: View {
Text(label)
.font(.title3.bold())
.foregroundColor(.secondary)
.contextMenu {
Button {
FavoritesModel.shared.remove(item)
favoritesModel.remove(item)
} label: {
Label("Remove from Favorites", systemImage: "trash")
}
@ -62,7 +43,7 @@ struct FavoriteItemView: View {
.padding(.leading, 15)
#endif
HorizontalCells(items: store.videos.map { ContentItem(video: $0) })
HorizontalCells(items: store.contentItems)
}
.contentShape(Rectangle())
@ -83,9 +64,40 @@ struct FavoriteItemView: View {
#endif
}
var label: String {
private var resource: Resource? {
switch item.section {
case .subscriptions:
if accounts.app.supportsSubscriptions {
return accounts.api.feed
}
case .popular:
if accounts.app.supportsPopular {
return accounts.api.popular
}
case let .trending(country, category):
let trendingCountry = Country(rawValue: country)!
let trendingCategory = category.isNil ? nil : TrendingCategory(rawValue: category!)!
return accounts.api.trending(country: trendingCountry, category: trendingCategory)
case let .channel(id, _):
return accounts.api.channelVideos(id)
case let .channelPlaylist(id, _):
return accounts.api.channelPlaylist(id)
case let .playlist(id):
return accounts.api.playlist(id)
}
return nil
}
private var label: String {
if case let .playlist(id) = item.section {
return playlistsModel.find(id: id)?.title ?? "Playlist"
return playlists.find(id: id)?.title ?? "Playlist"
}
return item.section.label

View File

@ -0,0 +1,22 @@
import Foundation
import Siesta
final class FavoriteResourceObserver: ObservableObject, ResourceObserver {
@Published var videos = [Video]()
func resourceChanged(_ resource: Resource, event _: ResourceEvent) {
if let videos: [Video] = resource.typedContent() {
self.videos = videos
} else if let channel: Channel = resource.typedContent() {
videos = channel.videos
} else if let playlist: ChannelPlaylist = resource.typedContent() {
videos = playlist.videos
} else if let playlist: Playlist = resource.typedContent() {
videos = playlist.videos
}
}
var contentItems: [ContentItem] {
videos.map { ContentItem(video: $0) }
}
}

View File

@ -10,20 +10,12 @@ struct FavoritesView: View {
@State private var dragging: FavoriteItem?
@State private var presentingEditFavorites = false
@Default(.favorites) private var favorites
var body: some View {
PlayerControlsView {
ScrollView(.vertical, showsIndicators: false) {
if !accounts.current.isNil {
VStack(alignment: .leading, spacing: 0) {
ForEach(favorites) { item in
VStack {
if let resource = resource(item) {
FavoriteItemView(item: item, resource: resource, favorites: $favorites, dragging: $dragging)
}
}
}
ForEach(Defaults[.favorites]) { item in
FavoriteItemView(item: item, dragging: $dragging)
}
#if os(tvOS)
@ -35,6 +27,7 @@ struct FavoritesView: View {
#endif
}
}
.redrawOn(change: presentingEditFavorites)
#if os(tvOS)
.sheet(isPresented: $presentingEditFavorites) {
EditFavorites()
@ -50,37 +43,6 @@ struct FavoritesView: View {
#endif
}
}
func resource(_ item: FavoriteItem) -> Resource? {
switch item.section {
case .subscriptions:
if accounts.app.supportsSubscriptions {
return accounts.api.feed
}
case .popular:
if accounts.app.supportsPopular {
return accounts.api.popular
}
case let .trending(country, category):
let trendingCountry = Country(rawValue: country)!
let trendingCategory = category.isNil ? nil : TrendingCategory(rawValue: category!)!
return accounts.api.trending(country: trendingCountry, category: trendingCategory)
case let .channel(id, _):
return accounts.api.channelVideos(id)
case let .channelPlaylist(id, _):
return accounts.api.channelPlaylist(id)
case let .playlist(id):
return accounts.api.playlist(id)
}
return nil
}
}
struct Favorites_Previews: PreviewProvider {

View File

@ -267,7 +267,7 @@ struct VideoCell: View {
}
.retryOnAppear(false)
.onFailure { _ in
thumbnails.insertUnloadable(url)
thumbnails.insertUnloadable(url)
}
.indicator(.activity)