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 {
static var timeUpdateInterval = 0.5
static var networkStateUpdateInterval = 1.0
static var networkStateUpdateInterval = 0.1
private var logger = Logger(label: "mpv-backend")

View File

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

View File

@ -5,18 +5,52 @@ final class FavoriteResourceObserver: ObservableObject, ResourceObserver {
@Published var contentItems = [ContentItem]()
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() {
contentItems = videos.map { ContentItem(video: $0) }
newVideos = videos
} else if let channel: Channel = resource.typedContent() {
contentItems = channel.videos.map { ContentItem(video: $0) }
newChannel = channel
} else if let playlist: ChannelPlaylist = resource.typedContent() {
contentItems = playlist.videos.map { ContentItem(video: $0) }
newChannelPlaylist = playlist
} else if let playlist: Playlist = resource.typedContent() {
contentItems = playlist.videos.map { ContentItem(video: $0) }
newPlaylist = playlist
} else if let page: SearchPage = resource.typedContent() {
contentItems = page.results
newPage = page
} 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,61 +150,74 @@ struct YatteeApp: App {
}
configured = true
#if DEBUG
SiestaLog.Category.enabled = .common
#endif
SDImageCodersManager.shared.addCoder(SDImageAWebPCoder.shared)
SDWebImageManager.defaultImageCache = PINCache(name: "stream.yattee.app")
DispatchQueue.main.async {
#if DEBUG
SiestaLog.Category.enabled = .common
#endif
SDImageCodersManager.shared.addCoder(SDImageAWebPCoder.shared)
SDWebImageManager.defaultImageCache = PINCache(name: "stream.yattee.app")
if !Defaults[.lastAccountIsPublic] {
AccountsModel.shared.configureAccount()
}
if let countryOfPublicInstances = Defaults[.countryOfPublicInstances] {
InstancesManifest.shared.setPublicAccount(countryOfPublicInstances, asCurrent: AccountsModel.shared.current.isNil)
}
if !AccountsModel.shared.current.isNil {
player.restoreQueue()
}
if !Defaults[.saveRecents] {
recents.clear()
}
let startupSection = Defaults[.startupSection]
var section: TabSelection? = startupSection.tabSelection
#if os(macOS)
if section == .playlists {
section = .search
if !Defaults[.lastAccountIsPublic] {
AccountsModel.shared.configureAccount()
}
#endif
NavigationModel.shared.tabSelection = section ?? .search
if let countryOfPublicInstances = Defaults[.countryOfPublicInstances] {
InstancesManifest.shared.setPublicAccount(countryOfPublicInstances, asCurrent: AccountsModel.shared.current.isNil)
}
playlists.load()
if !AccountsModel.shared.current.isNil {
player.restoreQueue()
}
#if !os(macOS)
player.updateRemoteCommandCenter()
#endif
if player.presentingPlayer {
player.presentingPlayer = false
}
#if os(iOS)
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
if Defaults[.lockPortraitWhenBrowsing] {
Orientation.lockOrientation(.portrait, andRotateTo: .portrait)
DispatchQueue.global(qos: .userInitiated).async {
if !Defaults[.saveRecents] {
recents.clear()
}
}
#endif
URLBookmarkModel.shared.refreshAll()
let startupSection = Defaults[.startupSection]
var section: TabSelection? = startupSection.tabSelection
migrateHomeHistoryItems()
migrateQualityProfiles()
#if os(macOS)
if section == .playlists {
section = .search
}
#endif
NavigationModel.shared.tabSelection = section ?? .search
DispatchQueue.global(qos: .userInitiated).async {
playlists.load()
}
#if !os(macOS)
player.updateRemoteCommandCenter()
#endif
if player.presentingPlayer {
player.presentingPlayer = false
}
#if os(iOS)
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
if Defaults[.lockPortraitWhenBrowsing] {
Orientation.lockOrientation(.all, andRotateTo: .portrait)
}
}
#endif
DispatchQueue.global(qos: .userInitiated).async {
URLBookmarkModel.shared.refreshAll()
}
DispatchQueue.global(qos: .userInitiated).async {
self.migrateHomeHistoryItems()
}
DispatchQueue.global(qos: .userInitiated).async {
self.migrateQualityProfiles()
}
}
}
func migrateHomeHistoryItems() {