mirror of
https://github.com/yattee/yattee.git
synced 2025-01-09 14:27:11 +00:00
Merge pull request #671 from stonerl/snappy-ui
Snappy UI - Offloading non UI task to background threads
This commit is contained in:
commit
a12755ec4b
@ -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,13 +99,12 @@ 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()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -164,12 +166,15 @@ 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 }
|
|
||||||
visibleWatches.sort { $0.watchedAt ?? Date() > $1.watchedAt ?? Date() }
|
if watch == last {
|
||||||
|
visibleWatches.sort { $0.watchedAt ?? Date() > $1.watchedAt ?? Date() }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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,61 +150,74 @@ struct YatteeApp: App {
|
|||||||
}
|
}
|
||||||
configured = true
|
configured = true
|
||||||
|
|
||||||
#if DEBUG
|
DispatchQueue.main.async {
|
||||||
SiestaLog.Category.enabled = .common
|
#if DEBUG
|
||||||
#endif
|
SiestaLog.Category.enabled = .common
|
||||||
SDImageCodersManager.shared.addCoder(SDImageAWebPCoder.shared)
|
#endif
|
||||||
SDWebImageManager.defaultImageCache = PINCache(name: "stream.yattee.app")
|
SDImageCodersManager.shared.addCoder(SDImageAWebPCoder.shared)
|
||||||
|
SDWebImageManager.defaultImageCache = PINCache(name: "stream.yattee.app")
|
||||||
|
|
||||||
if !Defaults[.lastAccountIsPublic] {
|
if !Defaults[.lastAccountIsPublic] {
|
||||||
AccountsModel.shared.configureAccount()
|
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
|
|
||||||
}
|
}
|
||||||
#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)
|
DispatchQueue.global(qos: .userInitiated).async {
|
||||||
player.updateRemoteCommandCenter()
|
if !Defaults[.saveRecents] {
|
||||||
#endif
|
recents.clear()
|
||||||
|
|
||||||
if player.presentingPlayer {
|
|
||||||
player.presentingPlayer = false
|
|
||||||
}
|
|
||||||
|
|
||||||
#if os(iOS)
|
|
||||||
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
|
|
||||||
if Defaults[.lockPortraitWhenBrowsing] {
|
|
||||||
Orientation.lockOrientation(.portrait, andRotateTo: .portrait)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
URLBookmarkModel.shared.refreshAll()
|
let startupSection = Defaults[.startupSection]
|
||||||
|
var section: TabSelection? = startupSection.tabSelection
|
||||||
|
|
||||||
migrateHomeHistoryItems()
|
#if os(macOS)
|
||||||
migrateQualityProfiles()
|
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() {
|
func migrateHomeHistoryItems() {
|
||||||
|
Loading…
Reference in New Issue
Block a user