fix: avoid unbounded HTTP throttling and make buffer readout opt-in

This commit is contained in:
2026-10-11 11:52:48 +02:00
parent 13554a1574
commit 537e8e2624
6 changed files with 118 additions and 28 deletions
+18 -5
View File
@@ -17,6 +17,7 @@ final class PlayerModel: ObservableObject {
@Published private(set) var youtubeHeight: Int?
@Published private(set) var youtubeQuality: Int?
@Published private(set) var automaticYouTubeQuality = false
@Published private(set) var showsBufferInfo = false
@Published var seekPosition = 0.0
@Published var isSeeking = false
@Published private(set) var volume = 1.0
@@ -65,6 +66,7 @@ final class PlayerModel: ObservableObject {
self.defaults = defaults
self.qualityClock = qualityClock
automaticYouTubeQuality = defaults.bool(forKey: "automaticYouTubeQuality")
showsBufferInfo = defaults.bool(forKey: "showsBufferInfo")
playbackProgress = PlaybackProgress(defaults: defaults)
let player = player_create()
handle = player
@@ -158,6 +160,12 @@ final class PlayerModel: ObservableObject {
resolveYouTube(url, height: nil)
}
func setShowsBufferInfo(_ enabled: Bool) {
showsBufferInfo = enabled
defaults.set(enabled, forKey: "showsBufferInfo")
revealControls()
}
func setAutomaticYouTubeQuality(_ enabled: Bool) {
automaticYouTubeQuality = enabled
defaults.set(enabled, forKey: "automaticYouTubeQuality")
@@ -822,8 +830,9 @@ private struct PlayerContent: View {
@State private var controlOffset = CGSize.zero
@State private var dragOrigin = CGSize.zero
private var controlHeight: CGFloat { model.isNetworkMedia ? 88 : 68 }
private var compactControlHeight: CGFloat { model.isNetworkMedia ? 52 : 40 }
private var showsBufferReadout: Bool { model.isNetworkMedia && model.showsBufferInfo }
private var controlHeight: CGFloat { showsBufferReadout ? 88 : 68 }
private var compactControlHeight: CGFloat { showsBufferReadout ? 52 : 40 }
private var bufferedStatus: String? {
model.bufferedRange.map {
@@ -931,6 +940,10 @@ private struct PlayerContent: View {
Text(model.youtubeHeight.map { "Current: \($0)p" } ?? "Current resolution unknown")
}
Divider()
Toggle("Show Buffer Info", isOn: Binding(
get: { model.showsBufferInfo },
set: { model.setShowsBufferInfo($0) }))
Divider()
Button(model.isCompact ? "Exit Compact Mode" : "Enter Compact Mode", action: model.toggleCompact)
.disabled(!model.canToggleCompact)
Toggle("Snap to Screen Edges", isOn: Binding(
@@ -959,10 +972,10 @@ private struct PlayerContent: View {
.disabled(model.compactWindow.isTransitioning)
actionsMenu
}
if model.isNetworkMedia { bufferReadout }
if showsBufferReadout { bufferReadout }
}
.padding(.horizontal, 12)
.padding(.vertical, model.isNetworkMedia ? 6 : 8)
.padding(.vertical, showsBufferReadout ? 6 : 8)
.foregroundStyle(.white.opacity(0.85))
.background(PlayerGlass().clipShape(RoundedRectangle(cornerRadius: 10)))
.onHover(perform: model.setControlsHovered)
@@ -1040,7 +1053,7 @@ private struct PlayerContent: View {
}
.font(.system(size: 11).monospacedDigit())
.padding(.horizontal, 16)
if model.isNetworkMedia { bufferReadout }
if showsBufferReadout { bufferReadout }
}
.padding(.vertical, 11)
// Optical centering accounts for symbol insets and the native seek thumb.