diff --git a/Flixy/Resources/Localizable.xcstrings b/Flixy/Resources/Localizable.xcstrings index 713e0f4..17025d0 100644 --- a/Flixy/Resources/Localizable.xcstrings +++ b/Flixy/Resources/Localizable.xcstrings @@ -4856,6 +4856,23 @@ } } }, + "settings.qualityUnlimitedHint" : { + "extractionState" : "manual", + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Zuletzt hat die Wiedergabe gehakt. Ohne Grenze überträgt der Server das Original — gibt die Leitung das nicht her, kann nichts ausweichen. Eine Stufe darunter läuft dann ruhiger." + } + }, + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Playback stalled recently. Without a limit the server sends the original — if the connection cannot carry it, there is nothing to fall back to. One step down plays more smoothly." + } + } + } + }, "settings.qualityWifi" : { "extractionState" : "stale", "localizations" : { diff --git a/Flixy/Session/PlaybackSettings.swift b/Flixy/Session/PlaybackSettings.swift index 4e01696..e59938b 100644 --- a/Flixy/Session/PlaybackSettings.swift +++ b/Flixy/Session/PlaybackSettings.swift @@ -45,6 +45,7 @@ final class PlaybackSettings { static let remembersQuality = "flixy.playback.remembersQuality" static let rememberedQuality = "flixy.playback.rememberedQuality" static let showsBitrate = "flixy.playback.showsBitrate" + static let lastPlaybackStruggled = "flixy.playback.struggled" } /// Die Sprünge, die es zur Auswahl gibt. @@ -113,6 +114,20 @@ final class PlaybackSettings { set { defaults.set(newValue ?? 0, forKey: Key.rememberedQuality) } } + /// Ob die letzte Wiedergabe von der Leitung nicht getragen wurde. + /// + /// **Ein Beleg, keine Vermutung.** Der Hinweis bei „ohne Grenze" soll nur + /// erscheinen, wenn es tatsächlich gehakt hat — eine Warnung, die immer + /// dasteht, liest nach dem zweiten Mal niemand mehr. + /// + /// Gesetzt vom Player, wenn im gleitenden Fenster ein Viertel der Zeit + /// fürs Warten draufging oder ein einzelner Rückler über fünfzehn + /// Sekunden dauerte. + var lastPlaybackStruggled: Bool { + get { defaults.bool(forKey: Key.lastPlaybackStruggled) } + set { defaults.set(newValue, forKey: Key.lastPlaybackStruggled) } + } + init(defaults: UserDefaults = .standard) { self.defaults = defaults diff --git a/Flixy/Views/Player/PlayerModel.swift b/Flixy/Views/Player/PlayerModel.swift index 0fb0d94..ed64410 100644 --- a/Flixy/Views/Player/PlayerModel.swift +++ b/Flixy/Views/Player/PlayerModel.swift @@ -884,6 +884,10 @@ final class PlayerModel { guard struggling != isConnectionStruggling else { return } isConnectionStruggling = struggling + // Über diese Wiedergabe hinaus merken: der Hinweis in den + // Einstellungen soll sich auf einen Beleg stützen können, und dort + // ist der Player längst zu. + if struggling { settings.lastPlaybackStruggled = true } if struggling { diagnostics.note(String( diff --git a/Flixy/Views/Settings/PlaybackSettingsView.swift b/Flixy/Views/Settings/PlaybackSettingsView.swift index aa61776..d9d714e 100644 --- a/Flixy/Views/Settings/PlaybackSettingsView.swift +++ b/Flixy/Views/Settings/PlaybackSettingsView.swift @@ -36,7 +36,29 @@ struct PlaybackSettingsView: View { } header: { Text("settings.quality") } footer: { - Text("settings.qualityExplanation") + VStack(alignment: .leading, spacing: FlixySpacing.snug) { + Text("settings.qualityExplanation") + + // **Nur mit Beleg.** Eine Warnung, die immer dasteht, + // liest nach dem zweiten Mal niemand mehr. Sie erscheint, + // wenn „ohne Grenze" eingestellt ist **und** die letzte + // Wiedergabe tatsächlich gehakt hat. + // + // Ohne Grenze kommt die Entscheidung oft bei direkter + // Wiedergabe heraus — und dann gibt es keine Stufe, auf + // die irgendetwas ausweichen könnte. Die Voreinstellung + // bleibt trotzdem, wie sie ist: zuhause am Kabel ist sie + // die richtige, und still umstellen wäre nicht in Ordnung. + if settings.wifiQuality == .original, settings.lastPlaybackStruggled { + Label { + Text("settings.qualityUnlimitedHint") + } icon: { + Image(systemName: "exclamationmark.triangle") + } + .font(.flixyCaption) + .foregroundStyle(Color.flixyTextSecondary) + } + } } Section {