Merge pull request #671 from stonerl/snappy-ui

Snappy UI - Offloading non UI task to background threads
This commit is contained in:
Arkadiusz Fal 2024-05-18 11:41:09 +02:00 committed by GitHub
commit a12755ec4b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 110 additions and 58 deletions

View File

@ -10,7 +10,7 @@ import SwiftUI
final class MPVBackend: PlayerBackend { final class MPVBackend: PlayerBackend {
static var timeUpdateInterval = 0.5 static var timeUpdateInterval = 0.5
static var networkStateUpdateInterval = 1.0 static var networkStateUpdateInterval = 0.1
private var logger = Logger(label: "mpv-backend") private var logger = Logger(label: "mpv-backend")

View File

@ -89,6 +89,9 @@ struct FavoriteItemView: View {
loadCacheAndResource() loadCacheAndResource()
} }
} }
.onDisappear {
resource?.removeObservers(ownedBy: store)
}
.onChange(of: player.currentVideo) { _ in reloadVisibleWatches() } .onChange(of: player.currentVideo) { _ in reloadVisibleWatches() }
.onChange(of: hideShorts) { _ in reloadVisibleWatches() } .onChange(of: hideShorts) { _ in reloadVisibleWatches() }
.onChange(of: hideWatched) { _ in reloadVisibleWatches() } .onChange(of: hideWatched) { _ in reloadVisibleWatches() }
@ -96,15 +99,14 @@ struct FavoriteItemView: View {
} }
.id(watchModel.historyToken) .id(watchModel.historyToken)
.onChange(of: accounts.current) { _ in .onChange(of: accounts.current) { _ in
resource?.removeObservers(ownedBy: store)
resource?.addObserver(store) resource?.addObserver(store)
loadCacheAndResource(force: true) loadCacheAndResource(force: true)
} }
.onChange(of: watchModel.historyToken) { _ in .onChange(of: watchModel.historyToken) { _ in
Delay.by(0.5) {
reloadVisibleWatches() reloadVisibleWatches()
} }
} }
}
var emptyItemsText: String { var emptyItemsText: String {
var filterText = "" var filterText = ""
@ -164,15 +166,18 @@ struct FavoriteItemView: View {
.prefix(favoritesModel.limit(item)) .prefix(favoritesModel.limit(item))
) )
let last = watches.last let last = watches.last
for watch in watches { for watch in watches {
player.loadHistoryVideoDetails(watch) { player.loadHistoryVideoDetails(watch) {
guard let video = player.historyVideo(watch.videoID), itemVisible(.init(video: video)) else { return } guard let video = player.historyVideo(watch.videoID), itemVisible(.init(video: video)) else { return }
visibleWatches.append(watch) visibleWatches.append(watch)
guard watch == last else { return }
if watch == last {
visibleWatches.sort { $0.watchedAt ?? Date() > $1.watchedAt ?? Date() } visibleWatches.sort { $0.watchedAt ?? Date() > $1.watchedAt ?? Date() }
} }
} }
} }
}
var limitedItems: [ContentItem] { var limitedItems: [ContentItem] {
var items: [ContentItem] var items: [ContentItem]

View File

@ -5,18 +5,52 @@ final class FavoriteResourceObserver: ObservableObject, ResourceObserver {
@Published var contentItems = [ContentItem]() @Published var contentItems = [ContentItem]()
func resourceChanged(_ resource: Resource, event _: ResourceEvent) { func resourceChanged(_ resource: Resource, event _: ResourceEvent) {
// swiftlint:disable discouraged_optional_collection
var newVideos: [Video]?
var newItems: [ContentItem]?
// swiftlint:enable discouraged_optional_collection
var newChannel: Channel?
var newChannelPlaylist: ChannelPlaylist?
var newPlaylist: Playlist?
var newPage: SearchPage?
if let videos: [Video] = resource.typedContent() { if let videos: [Video] = resource.typedContent() {
contentItems = videos.map { ContentItem(video: $0) } newVideos = videos
} else if let channel: Channel = resource.typedContent() { } else if let channel: Channel = resource.typedContent() {
contentItems = channel.videos.map { ContentItem(video: $0) } newChannel = channel
} else if let playlist: ChannelPlaylist = resource.typedContent() { } else if let playlist: ChannelPlaylist = resource.typedContent() {
contentItems = playlist.videos.map { ContentItem(video: $0) } newChannelPlaylist = playlist
} else if let playlist: Playlist = resource.typedContent() { } else if let playlist: Playlist = resource.typedContent() {
contentItems = playlist.videos.map { ContentItem(video: $0) } newPlaylist = playlist
} else if let page: SearchPage = resource.typedContent() { } else if let page: SearchPage = resource.typedContent() {
contentItems = page.results newPage = page
} else if let items: [ContentItem] = resource.typedContent() { } else if let items: [ContentItem] = resource.typedContent() {
contentItems = items newItems = items
}
DispatchQueue.global(qos: .userInitiated).async {
var newContentItems: [ContentItem] = []
if let videos = newVideos {
newContentItems = videos.map { ContentItem(video: $0) }
} else if let channel = newChannel {
newContentItems = channel.videos.map { ContentItem(video: $0) }
} else if let playlist = newChannelPlaylist {
newContentItems = playlist.videos.map { ContentItem(video: $0) }
} else if let playlist = newPlaylist {
newContentItems = playlist.videos.map { ContentItem(video: $0) }
} else if let page = newPage {
newContentItems = page.results
} else if let items = newItems {
newContentItems = items
}
DispatchQueue.main.async {
if !newContentItems.isEmpty {
self.contentItems = newContentItems
}
}
} }
} }
} }

View File

@ -150,6 +150,7 @@ struct YatteeApp: App {
} }
configured = true configured = true
DispatchQueue.main.async {
#if DEBUG #if DEBUG
SiestaLog.Category.enabled = .common SiestaLog.Category.enabled = .common
#endif #endif
@ -168,9 +169,11 @@ struct YatteeApp: App {
player.restoreQueue() player.restoreQueue()
} }
DispatchQueue.global(qos: .userInitiated).async {
if !Defaults[.saveRecents] { if !Defaults[.saveRecents] {
recents.clear() recents.clear()
} }
}
let startupSection = Defaults[.startupSection] let startupSection = Defaults[.startupSection]
var section: TabSelection? = startupSection.tabSelection var section: TabSelection? = startupSection.tabSelection
@ -183,7 +186,9 @@ struct YatteeApp: App {
NavigationModel.shared.tabSelection = section ?? .search NavigationModel.shared.tabSelection = section ?? .search
DispatchQueue.global(qos: .userInitiated).async {
playlists.load() playlists.load()
}
#if !os(macOS) #if !os(macOS)
player.updateRemoteCommandCenter() player.updateRemoteCommandCenter()
@ -196,15 +201,23 @@ struct YatteeApp: App {
#if os(iOS) #if os(iOS)
DispatchQueue.main.asyncAfter(deadline: .now() + 1) { DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
if Defaults[.lockPortraitWhenBrowsing] { if Defaults[.lockPortraitWhenBrowsing] {
Orientation.lockOrientation(.portrait, andRotateTo: .portrait) Orientation.lockOrientation(.all, andRotateTo: .portrait)
} }
} }
#endif #endif
DispatchQueue.global(qos: .userInitiated).async {
URLBookmarkModel.shared.refreshAll() URLBookmarkModel.shared.refreshAll()
}
migrateHomeHistoryItems() DispatchQueue.global(qos: .userInitiated).async {
migrateQualityProfiles() self.migrateHomeHistoryItems()
}
DispatchQueue.global(qos: .userInitiated).async {
self.migrateQualityProfiles()
}
}
} }
func migrateHomeHistoryItems() { func migrateHomeHistoryItems() {