From 28a7b6e981a78934df4d334ca3c97b421f928c60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toni=20F=C3=B6rster?= Date: Tue, 10 Sep 2024 11:04:05 +0200 Subject: [PATCH] auto retry loading the video before showing error MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Toni Förster --- .../AdvancedSettingsGroupExporter.swift | 1 + .../AdvancedSettingsGroupImporter.swift | 4 +++ Model/Player/PlayerModel.swift | 3 +++ Model/Player/PlayerQueue.swift | 25 +++++++++++++++++++ Shared/Defaults.swift | 1 + Shared/Settings/AdvancedSettings.swift | 15 +++++++++++ 6 files changed, 49 insertions(+) diff --git a/Model/Import Export Settings/Exporters/AdvancedSettingsGroupExporter.swift b/Model/Import Export Settings/Exporters/AdvancedSettingsGroupExporter.swift index 9aa5145b..6228f644 100644 --- a/Model/Import Export Settings/Exporters/AdvancedSettingsGroupExporter.swift +++ b/Model/Import Export Settings/Exporters/AdvancedSettingsGroupExporter.swift @@ -5,6 +5,7 @@ final class AdvancedSettingsGroupExporter: SettingsGroupExporter { override var globalJSON: JSON { [ "showPlayNowInBackendContextMenu": Defaults[.showPlayNowInBackendContextMenu], + "videoLoadingRetryCount": Defaults[.videoLoadingRetryCount], "showMPVPlaybackStats": Defaults[.showMPVPlaybackStats], "mpvEnableLogging": Defaults[.mpvEnableLogging], "mpvCacheSecs": Defaults[.mpvCacheSecs], diff --git a/Model/Import Export Settings/Importers/AdvancedSettingsGroupImporter.swift b/Model/Import Export Settings/Importers/AdvancedSettingsGroupImporter.swift index 5c2b2113..ca47e4e5 100644 --- a/Model/Import Export Settings/Importers/AdvancedSettingsGroupImporter.swift +++ b/Model/Import Export Settings/Importers/AdvancedSettingsGroupImporter.swift @@ -9,6 +9,10 @@ struct AdvancedSettingsGroupImporter { Defaults[.showPlayNowInBackendContextMenu] = showPlayNowInBackendContextMenu } + if let videoLoadingRetryCount = json["videoLoadingRetryCount"].int { + Defaults[.videoLoadingRetryCount] = videoLoadingRetryCount + } + if let showMPVPlaybackStats = json["showMPVPlaybackStats"].bool { Defaults[.showMPVPlaybackStats] = showMPVPlaybackStats } diff --git a/Model/Player/PlayerModel.swift b/Model/Player/PlayerModel.swift index a7ba1c11..e2311f43 100644 --- a/Model/Player/PlayerModel.swift +++ b/Model/Player/PlayerModel.swift @@ -201,6 +201,9 @@ final class PlayerModel: ObservableObject { var rateToRestore: Float? private var remoteCommandCenterConfigured = false + // Used in the PlayerModel extension in PlayerQueue + var retryAttempts = [String: Int]() + #if os(macOS) var keyPressMonitor: Any? #endif diff --git a/Model/Player/PlayerQueue.swift b/Model/Player/PlayerQueue.swift index 0180884d..9609a2f9 100644 --- a/Model/Player/PlayerQueue.swift +++ b/Model/Player/PlayerQueue.swift @@ -359,6 +359,31 @@ extension PlayerModel { } private func videoLoadFailureHandler(_ error: RequestError, video: Video? = nil) { + guard let video else { + presentErrorAlert(error) + return + } + + let videoID = video.videoID + let currentRetry = retryAttempts[videoID] ?? 0 + + if currentRetry < Defaults[.videoLoadingRetryCount] { + retryAttempts[videoID] = currentRetry + 1 + + logger.info("Retry attempt \(currentRetry + 1) for video \(videoID) due to error: \(error)") + + DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { [weak self] in + guard let self else { return } + self.enqueueVideo(video, play: true, prepending: true, loadDetails: true) + } + return + } + + retryAttempts[videoID] = 0 + presentErrorAlert(error, video: video) + } + + private func presentErrorAlert(_ error: RequestError, video: Video? = nil) { var message = error.userMessage if let errorDictionary = error.json.dictionaryObject, let errorMessage = errorDictionary["message"] ?? errorDictionary["error"], diff --git a/Shared/Defaults.swift b/Shared/Defaults.swift index 05cf1844..54e5d594 100644 --- a/Shared/Defaults.swift +++ b/Shared/Defaults.swift @@ -358,6 +358,7 @@ extension Defaults.Keys { // MARK: Group - Advanced static let showPlayNowInBackendContextMenu = Key("showPlayNowInBackendContextMenu", default: false) + static let videoLoadingRetryCount = Key("videoLoadingRetryCount", default: 10) static let showMPVPlaybackStats = Key("showMPVPlaybackStats", default: false) static let mpvEnableLogging = Key("mpvEnableLogging", default: false) diff --git a/Shared/Settings/AdvancedSettings.swift b/Shared/Settings/AdvancedSettings.swift index 0e1d25f3..79df92a4 100644 --- a/Shared/Settings/AdvancedSettings.swift +++ b/Shared/Settings/AdvancedSettings.swift @@ -14,6 +14,7 @@ struct AdvancedSettings: View { @Default(.showCacheStatus) private var showCacheStatus @Default(.feedCacheSize) private var feedCacheSize @Default(.showPlayNowInBackendContextMenu) private var showPlayNowInBackendContextMenu + @Default(.videoLoadingRetryCount) private var videoLoadingRetryCount @State private var filesToShare = [MPVClient.logFile] @State private var presentingShareSheet = false @@ -64,6 +65,7 @@ struct AdvancedSettings: View { @ViewBuilder var advancedSettings: some View { Section(header: SettingsHeader(text: "Advanced")) { showPlayNowInBackendButtonsToggle + videoLoadingRetryCountField } Section(header: SettingsHeader(text: "MPV"), footer: mpvFooter) { @@ -281,6 +283,19 @@ struct AdvancedSettings: View { Toggle("Show video context menu options to force selected backend", isOn: $showPlayNowInBackendContextMenu) } + private var videoLoadingRetryCountField: some View { + HStack { + Text("Maximum retries for video loading") + .frame(minWidth: 200, alignment: .leading) + .multilineTextAlignment(.leading) + TextField("Limit", value: $videoLoadingRetryCount, formatter: NumberFormatter()) + .multilineTextAlignment(.trailing) + #if !os(macOS) + .keyboardType(.numberPad) + #endif + } + } + var showMPVPlaybackStatsToggle: some View { Toggle("Show playback statistics", isOn: $showMPVPlaybackStats) }