diff --git a/Model/Applications/VideosAPI.swift b/Model/Applications/VideosAPI.swift index 98e6500f..c2f55baf 100644 --- a/Model/Applications/VideosAPI.swift +++ b/Model/Applications/VideosAPI.swift @@ -58,14 +58,22 @@ protocol VideosAPI { func channelPlaylist(_ id: String) -> Resource? - func loadDetails(_ item: PlayerQueueItem, completionHandler: @escaping (PlayerQueueItem) -> Void) + func loadDetails( + _ item: PlayerQueueItem, + failureHandler: ((RequestError) -> Void)?, + completionHandler: @escaping (PlayerQueueItem) -> Void + ) func shareURL(_ item: ContentItem, frontendHost: String?, time: CMTime?) -> URL? func comments(_ id: Video.ID, page: String?) -> Resource? } extension VideosAPI { - func loadDetails(_ item: PlayerQueueItem, completionHandler: @escaping (PlayerQueueItem) -> Void = { _ in }) { + func loadDetails( + _ item: PlayerQueueItem, + failureHandler: ((RequestError) -> Void)? = nil, + completionHandler: @escaping (PlayerQueueItem) -> Void = { _ in } + ) { guard (item.video?.streams ?? []).isEmpty else { completionHandler(item) return @@ -80,7 +88,7 @@ extension VideosAPI { newItem.video = video completionHandler(newItem) - } + }.onFailure { failureHandler?($0) } } func shareURL(_ item: ContentItem, frontendHost: String? = nil, time: CMTime? = nil) -> URL? { diff --git a/Model/Player/PlayerModel.swift b/Model/Player/PlayerModel.swift index 6091e21b..efd6f074 100644 --- a/Model/Player/PlayerModel.swift +++ b/Model/Player/PlayerModel.swift @@ -98,6 +98,8 @@ final class PlayerModel: ObservableObject { backend.networkState.player = self } }} + var navigation: NavigationModel + var context: NSManagedObjectContext = PersistenceController.shared.container.viewContext var backgroundContext = PersistenceController.shared.container.newBackgroundContext() @@ -134,12 +136,14 @@ final class PlayerModel: ObservableObject { accounts: AccountsModel = AccountsModel(), comments: CommentsModel = CommentsModel(), controls: PlayerControlsModel = PlayerControlsModel(), + navigation: NavigationModel = NavigationModel(), playerTime: PlayerTimeModel = PlayerTimeModel(), networkState: NetworkStateModel = NetworkStateModel() ) { self.accounts = accounts self.comments = comments self.controls = controls + self.navigation = navigation self.playerTime = playerTime self.networkState = networkState diff --git a/Model/Player/PlayerQueue.swift b/Model/Player/PlayerQueue.swift index 08b78b7a..e84ad63e 100644 --- a/Model/Player/PlayerQueue.swift +++ b/Model/Player/PlayerQueue.swift @@ -93,7 +93,7 @@ extension PlayerModel { currentItem = newItem - accounts.api.loadDetails(newItem) { newItem in + accounts.api.loadDetails(newItem, failureHandler: videoLoadFailureHandler) { newItem in self.playItem(newItem, at: time) } } @@ -136,7 +136,7 @@ extension PlayerModel { } if loadDetails { - accounts.api.loadDetails(item) { [weak self] newItem in + accounts.api.loadDetails(item, failureHandler: videoLoadFailureHandler) { [weak self] newItem in guard let self = self else { return } videoDetailsLoadHandler(newItem.video, newItem) @@ -197,10 +197,16 @@ extension PlayerModel { func loadQueueVideoDetails(_ item: PlayerQueueItem) { guard !accounts.current.isNil, !item.hasDetailsLoaded else { return } - accounts.api.loadDetails(item) { newItem in + accounts.api.loadDetails(item, completionHandler: { newItem in if let index = self.queue.firstIndex(where: { $0.id == item.id }) { self.queue[index] = newItem } - } + }) + } + + private func videoLoadFailureHandler(_ error: RequestError) { + navigation.presentAlert(title: "Could not load video", message: error.userMessage) + videoBeingOpened = nil + currentItem = nil } } diff --git a/Model/Player/PlayerStreams.swift b/Model/Player/PlayerStreams.swift index 0e3bc516..0df73db7 100644 --- a/Model/Player/PlayerStreams.swift +++ b/Model/Player/PlayerStreams.swift @@ -47,6 +47,10 @@ extension PlayerModel { } } .onCompletion(onCompletion) + .onFailure { [weak self] responseError in + self?.navigation.presentAlert(title: "Could not load streams", message: responseError.userMessage) + self?.videoBeingOpened = nil + } } func streamsWithInstance(instance: Instance, streams: [Stream]) -> [Stream] { diff --git a/Shared/YatteeApp.swift b/Shared/YatteeApp.swift index 0edafb3b..4a598c6f 100644 --- a/Shared/YatteeApp.swift +++ b/Shared/YatteeApp.swift @@ -196,6 +196,7 @@ struct YatteeApp: App { player.accounts = accounts player.comments = comments player.controls = playerControls + player.navigation = navigation player.networkState = networkState player.playerTime = playerTime