mirror of
https://github.com/yattee/yattee.git
synced 2024-12-22 21:43:41 +00:00
Snappy UI - Offloading non UI task to background threads
This gives a huge increase in perceived performance. The UI is now much more responsive since some tasks are run in the background and don't block the UI anymore.
This commit is contained in:
parent
1fe8a32fb8
commit
e35f8b7892
@ -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")
|
||||||
|
|
||||||
|
@ -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]
|
||||||
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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() {
|
||||||
|
Loading…
Reference in New Issue
Block a user