mirror of
https://github.com/yattee/yattee.git
synced 2024-11-10 00:08:21 +00:00
Caching for favorites
This commit is contained in:
parent
a2c69e0fed
commit
b8f693e213
@ -40,7 +40,7 @@ struct Playlist: Identifiable, Equatable, Hashable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var json: JSON {
|
var json: JSON {
|
||||||
return [
|
[
|
||||||
"id": id,
|
"id": id,
|
||||||
"title": title,
|
"title": title,
|
||||||
"visibility": visibility.rawValue,
|
"visibility": visibility.rawValue,
|
||||||
@ -51,7 +51,7 @@ struct Playlist: Identifiable, Equatable, Hashable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static func from(_ json: JSON) -> Self {
|
static func from(_ json: JSON) -> Self {
|
||||||
return .init(
|
.init(
|
||||||
id: json["id"].stringValue,
|
id: json["id"].stringValue,
|
||||||
title: json["title"].stringValue,
|
title: json["title"].stringValue,
|
||||||
visibility: .init(rawValue: json["visibility"].stringValue) ?? .public,
|
visibility: .init(rawValue: json["visibility"].stringValue) ?? .public,
|
||||||
|
@ -38,13 +38,15 @@ final class PlaylistsModel: ObservableObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func load(force: Bool = false, onSuccess: @escaping () -> Void = {}) {
|
func load(force: Bool = false, onSuccess: @escaping () -> Void = {}) {
|
||||||
guard accounts.app.supportsUserPlaylists, accounts.signedIn, let account = accounts.current else {
|
guard accounts.app.supportsUserPlaylists, let account = accounts.current else {
|
||||||
playlists = []
|
playlists = []
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
loadCachedPlaylists(account)
|
loadCachedPlaylists(account)
|
||||||
|
|
||||||
|
guard accounts.signedIn else { return }
|
||||||
|
|
||||||
DispatchQueue.main.async { [weak self] in
|
DispatchQueue.main.async { [weak self] in
|
||||||
guard let self else { return }
|
guard let self else { return }
|
||||||
let request = force ? self.resource?.load() : self.resource?.loadIfNeeded()
|
let request = force ? self.resource?.load() : self.resource?.loadIfNeeded()
|
||||||
|
@ -67,12 +67,15 @@ struct ChannelPlaylistView: View {
|
|||||||
}
|
}
|
||||||
.environment(\.listingStyle, channelPlaylistListingStyle)
|
.environment(\.listingStyle, channelPlaylistListingStyle)
|
||||||
.onAppear {
|
.onAppear {
|
||||||
if navigationStyle == .tab {
|
if let playlist = presentedPlaylist,
|
||||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
|
let cache = ChannelPlaylistsCacheModel.shared.retrievePlaylist(playlist.id)
|
||||||
resource?.loadIfNeeded()
|
{
|
||||||
|
store.replace(cache)
|
||||||
|
}
|
||||||
|
resource?.loadIfNeeded()?.onSuccess { response in
|
||||||
|
if let playlist: ChannelPlaylist = response.typedContent() {
|
||||||
|
ChannelPlaylistsCacheModel.shared.storePlaylist(playlist: playlist)
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
resource?.loadIfNeeded()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#if os(tvOS)
|
#if os(tvOS)
|
||||||
|
@ -45,21 +45,73 @@ struct FavoriteItemView: View {
|
|||||||
.contentShape(Rectangle())
|
.contentShape(Rectangle())
|
||||||
.onAppear {
|
.onAppear {
|
||||||
resource?.addObserver(store)
|
resource?.addObserver(store)
|
||||||
if item.section == .subscriptions {
|
loadCacheAndResource()
|
||||||
cacheFeed(resource?.loadIfNeeded())
|
|
||||||
} else {
|
|
||||||
resource?.loadIfNeeded()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.onChange(of: accounts.current) { _ in
|
.onChange(of: accounts.current) { _ in
|
||||||
resource?.addObserver(store)
|
resource?.addObserver(store)
|
||||||
if item.section == .subscriptions {
|
loadCacheAndResource(force: true)
|
||||||
cacheFeed(resource?.load())
|
}
|
||||||
} else {
|
}
|
||||||
resource?.load()
|
|
||||||
|
func loadCacheAndResource(force: Bool = false) {
|
||||||
|
guard var resource else { return }
|
||||||
|
|
||||||
|
var onSuccess: (Entity<Any>) -> Void = { _ in }
|
||||||
|
var contentItems = [ContentItem]()
|
||||||
|
|
||||||
|
switch item.section {
|
||||||
|
case .subscriptions:
|
||||||
|
let feed = FeedCacheModel.shared.retrieveFeed(account: accounts.current)
|
||||||
|
contentItems = ContentItem.array(of: feed)
|
||||||
|
|
||||||
|
onSuccess = { response in
|
||||||
|
if let videos: [Video] = response.typedContent() {
|
||||||
|
FeedCacheModel.shared.storeFeed(account: accounts.current, videos: videos)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
case let .channel(_, id, name):
|
||||||
|
let channel = Channel(app: .invidious, id: id, name: name)
|
||||||
|
if let cache = ChannelsCacheModel.shared.retrieve(channel.cacheKey) {
|
||||||
|
contentItems = ContentItem.array(of: cache.videos)
|
||||||
|
}
|
||||||
|
|
||||||
|
onSuccess = { response in
|
||||||
|
if let channel: Channel = response.typedContent() {
|
||||||
|
ChannelsCacheModel.shared.store(channel)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case let .channelPlaylist(_, id, _):
|
||||||
|
if let cache = ChannelPlaylistsCacheModel.shared.retrievePlaylist(id),
|
||||||
|
!cache.videos.isEmpty
|
||||||
|
{
|
||||||
|
contentItems = ContentItem.array(of: cache.videos)
|
||||||
|
}
|
||||||
|
|
||||||
|
onSuccess = { response in
|
||||||
|
if let playlist: ChannelPlaylist = response.typedContent() {
|
||||||
|
ChannelPlaylistsCacheModel.shared.storePlaylist(playlist: playlist)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case let .playlist(_, id):
|
||||||
|
let playlists = PlaylistsCacheModel.shared.retrievePlaylists(account: accounts.current)
|
||||||
|
|
||||||
|
if let playlist = playlists.first(where: { $0.id == id }) {
|
||||||
|
contentItems = ContentItem.array(of: playlist.videos)
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
contentItems = []
|
||||||
|
}
|
||||||
|
|
||||||
|
if !contentItems.isEmpty {
|
||||||
|
store.contentItems = contentItems
|
||||||
|
}
|
||||||
|
|
||||||
|
if force {
|
||||||
|
resource.load().onSuccess(onSuccess)
|
||||||
|
} else {
|
||||||
|
resource.loadIfNeeded()?.onSuccess(onSuccess)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -173,18 +225,10 @@ struct FavoriteItemView: View {
|
|||||||
.padding(.trailing, 10)
|
.padding(.trailing, 10)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func cacheFeed(_ request: Request?) {
|
|
||||||
request?.onSuccess { response in
|
|
||||||
if let videos: [Video] = response.typedContent() {
|
|
||||||
FeedCacheModel.shared.storeFeed(account: accounts.current, videos: videos)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private var isVisible: Bool {
|
private var isVisible: Bool {
|
||||||
switch item.section {
|
switch item.section {
|
||||||
case .subscriptions:
|
case .subscriptions:
|
||||||
return accounts.app.supportsSubscriptions && accounts.signedIn
|
return accounts.app.supportsSubscriptions
|
||||||
case .popular:
|
case .popular:
|
||||||
return accounts.app.supportsPopular
|
return accounts.app.supportsPopular
|
||||||
case let .channel(appType, _, _):
|
case let .channel(appType, _, _):
|
||||||
|
Loading…
Reference in New Issue
Block a user