From 7b09805b8116092afb6d3679e8507065e7871840 Mon Sep 17 00:00:00 2001
From: Arkadiusz Fal <arek@arekf.net>
Date: Sat, 25 Jun 2022 01:32:21 +0200
Subject: [PATCH] Improve network state updates

---
 Model/Player/Backends/AVPlayerBackend.swift |  2 +-
 Model/Player/Backends/MPVBackend.swift      | 24 +++----
 Model/Player/Backends/PlayerBackend.swift   |  2 +-
 Model/Player/PlayerModel.swift              |  2 +-
 Shared/Player/VideoDetails.swift            | 71 ---------------------
 5 files changed, 16 insertions(+), 85 deletions(-)

diff --git a/Model/Player/Backends/AVPlayerBackend.swift b/Model/Player/Backends/AVPlayerBackend.swift
index a51c4fa0..46019b53 100644
--- a/Model/Player/Backends/AVPlayerBackend.swift
+++ b/Model/Player/Backends/AVPlayerBackend.swift
@@ -589,5 +589,5 @@ final class AVPlayerBackend: PlayerBackend {
     func stopControlsUpdates() {}
     func setNeedsDrawing(_: Bool) {}
     func setSize(_: Double, _: Double) {}
-    func updateNetworkState() {}
+    func setNeedsNetworkStateUpdates() {}
 }
diff --git a/Model/Player/Backends/MPVBackend.swift b/Model/Player/Backends/MPVBackend.swift
index 1e7c4a70..9bcc52f8 100644
--- a/Model/Player/Backends/MPVBackend.swift
+++ b/Model/Player/Backends/MPVBackend.swift
@@ -7,6 +7,7 @@ import SwiftUI
 
 final class MPVBackend: PlayerBackend {
     static var controlsUpdateInterval = 0.5
+    static var networkStateUpdateInterval = 0.1
 
     private var logger = Logger(label: "mpv-backend")
 
@@ -27,7 +28,7 @@ final class MPVBackend: PlayerBackend {
             }
 
             self.controls?.isLoadingVideo = self.isLoadingVideo
-            self.updateNetworkState()
+            self.setNeedsNetworkStateUpdates()
 
             if !self.isLoadingVideo {
                 DispatchQueue.main.asyncAfter(deadline: .now() + 2) { [weak self] in
@@ -40,7 +41,7 @@ final class MPVBackend: PlayerBackend {
     }}
 
     var isPlaying = true { didSet {
-        updateNetworkState()
+        networkStateTimer.resume()
 
         if isPlaying {
             startClientUpdates()
@@ -73,6 +74,7 @@ final class MPVBackend: PlayerBackend {
     var client: MPVClient! { didSet { client.backend = self } }
 
     private var clientTimer: RepeatingTimer!
+    private var networkStateTimer: RepeatingTimer!
 
     private var handleEOF = false
     private var onFileLoaded: (() -> Void)?
@@ -117,6 +119,9 @@ final class MPVBackend: PlayerBackend {
 
         clientTimer = .init(timeInterval: Self.controlsUpdateInterval)
         clientTimer.eventHandler = getClientUpdates
+
+        networkStateTimer = .init(timeInterval: Self.networkStateUpdateInterval)
+        networkStateTimer.eventHandler = updateNetworkState
     }
 
     typealias AreInIncreasingOrder = (Stream, Stream) -> Bool
@@ -396,12 +401,12 @@ final class MPVBackend: PlayerBackend {
             onFileLoaded = nil
 
         case MPV_EVENT_PAUSE:
-            updateNetworkState()
+            networkStateTimer.resume()
 
         case MPV_EVENT_UNPAUSE:
             isLoadingVideo = false
             isSeeking = false
-            updateNetworkState()
+            networkStateTimer.resume()
 
         case MPV_EVENT_SEEK:
             isSeeking = true
@@ -466,15 +471,12 @@ final class MPVBackend: PlayerBackend {
             networkState.bufferingState = client.bufferingState
         }
 
-        if networkState.needsUpdates {
-            dispatchNetworkUpdate()
+        if !networkState.needsUpdates {
+            networkStateTimer.suspend()
         }
     }
 
-    func dispatchNetworkUpdate() {
-        print("dispatching network update")
-        DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) { [weak self] in
-            self?.updateNetworkState()
-        }
+    func setNeedsNetworkStateUpdates() {
+        networkStateTimer.resume()
     }
 }
diff --git a/Model/Player/Backends/PlayerBackend.swift b/Model/Player/Backends/PlayerBackend.swift
index 0f63105e..ac809517 100644
--- a/Model/Player/Backends/PlayerBackend.swift
+++ b/Model/Player/Backends/PlayerBackend.swift
@@ -52,7 +52,7 @@ protocol PlayerBackend {
     func startControlsUpdates()
     func stopControlsUpdates()
 
-    func updateNetworkState()
+    func setNeedsNetworkStateUpdates()
 
     func setNeedsDrawing(_ needsDrawing: Bool)
     func setSize(_ width: Double, _ height: Double)
diff --git a/Model/Player/PlayerModel.swift b/Model/Player/PlayerModel.swift
index b7f235f0..4ef97d4e 100644
--- a/Model/Player/PlayerModel.swift
+++ b/Model/Player/PlayerModel.swift
@@ -67,7 +67,7 @@ final class PlayerModel: ObservableObject {
     @Published var returnYouTubeDislike = ReturnYouTubeDislikeAPI()
 
     @Published var isSeeking = false { didSet {
-        backend.updateNetworkState()
+        backend.setNeedsNetworkStateUpdates()
     }}
 
     #if os(iOS)
diff --git a/Shared/Player/VideoDetails.swift b/Shared/Player/VideoDetails.swift
index 868ab39f..57dc571b 100644
--- a/Shared/Player/VideoDetails.swift
+++ b/Shared/Player/VideoDetails.swift
@@ -122,19 +122,6 @@ struct VideoDetails: View {
     var body: some View {
         VStack(alignment: .leading) {
             Group {
-//                Group {
-//                    subscriptionsSection
-//                        .border(.red, width: 4)
-//
-//                        .onChange(of: video) { video in
-//                            if let video = video {
-//                                subscribed = subscriptions.isSubscribing(video.channel.id)
-//                            }
-//                        }
-//                }
-//                .padding(.top, 4)
-//                .padding(.horizontal)
-
                 HStack(spacing: 4) {
                     pageButton("Info", "info.circle", .info)
                     pageButton("Chapters", "bookmark", .chapters)
@@ -188,64 +175,6 @@ struct VideoDetails: View {
         accounts.app.supportsUserPlaylists && accounts.signedIn
     }
 
-    var subscriptionsSection: some View {
-        Group {
-            if let video = video {
-                HStack(alignment: .center) {
-                    HStack(spacing: 10) {
-                        Group {
-//                            ZStack(alignment: .bottomTrailing) {
-//                                authorAvatar
-//
-//                                if subscribed {
-//                                    Image(systemName: "star.circle.fill")
-//                                        .background(Color.background)
-//                                        .clipShape(Circle())
-//                                        .foregroundColor(.secondary)
-//                                }
-//                            }
-
-//                            VStack(alignment: .leading, spacing: 4) {
-//                                Text(video.title)
-//                                    .font(.system(size: 11))
-//                                    .fontWeight(.bold)
-//
-//                                HStack(spacing: 4) {
-//                                    Text(video.channel.name)
-//
-//                                    if let subscribers = video.channel.subscriptionsString {
-//                                        Text("•")
-//                                            .foregroundColor(.secondary)
-//                                            .opacity(0.3)
-//
-//                                        Text("\(subscribers) subscribers")
-//                                    }
-//                                }
-//                                .foregroundColor(.secondary)
-//                                .font(.caption2)
-//                            }
-                        }
-                    }
-                    .contentShape(RoundedRectangle(cornerRadius: 12))
-                    .contextMenu {
-                        if let video = video {
-                            Button(action: {
-                                NavigationModel.openChannel(
-                                    video.channel,
-                                    player: player,
-                                    recents: recents,
-                                    navigation: navigation
-                                )
-                            }) {
-                                Label("\(video.channel.name) Channel", systemImage: "rectangle.stack.fill.badge.person.crop")
-                            }
-                        }
-                    }
-                }
-            }
-        }
-    }
-
     var publishedDateSection: some View {
         Group {
             if let video = player.currentVideo {