From 7719630cdd2488c3a82259ef7c68bdc567905a80 Mon Sep 17 00:00:00 2001 From: Davide Date: Sun, 10 Nov 2024 19:39:43 +0100 Subject: [PATCH] Limit tunnel updates (#843) - Do not observe tunnel in grid/list - Only observe .$currentProfile for grid selection - Move row tunnel updates to MarkerView - Debug InstalledProfileView --- .../Views/App/InstalledProfileView.swift | 3 +- .../AppUIMain/Views/App/ProfileGridView.swift | 11 ++-- .../AppUIMain/Views/App/ProfileListView.swift | 3 +- .../AppUIMain/Views/App/ProfileRowView.swift | 54 ++++++++++++------- .../Business/ExtendedTunnel.swift | 6 +++ 5 files changed, 52 insertions(+), 25 deletions(-) diff --git a/Passepartout/Library/Sources/AppUIMain/Views/App/InstalledProfileView.swift b/Passepartout/Library/Sources/AppUIMain/Views/App/InstalledProfileView.swift index 08fc3872..298605d0 100644 --- a/Passepartout/Library/Sources/AppUIMain/Views/App/InstalledProfileView.swift +++ b/Passepartout/Library/Sources/AppUIMain/Views/App/InstalledProfileView.swift @@ -163,7 +163,8 @@ private struct StatusText: View { let isOpaque: Bool var body: some View { - ConnectionStatusText(tunnel: tunnel) + debugChanges() + return ConnectionStatusText(tunnel: tunnel) .font(.body) .foregroundStyle(tunnel.statusColor(theme)) .opaque(isOpaque) diff --git a/Passepartout/Library/Sources/AppUIMain/Views/App/ProfileGridView.swift b/Passepartout/Library/Sources/AppUIMain/Views/App/ProfileGridView.swift index bd784cbb..891fa946 100644 --- a/Passepartout/Library/Sources/AppUIMain/Views/App/ProfileGridView.swift +++ b/Passepartout/Library/Sources/AppUIMain/Views/App/ProfileGridView.swift @@ -36,8 +36,7 @@ struct ProfileGridView: View, Routable, TunnelInstallationProviding { @ObservedObject var profileManager: ProfileManager - @ObservedObject - var tunnel: ExtendedTunnel + let tunnel: ExtendedTunnel let interactiveManager: InteractiveManager @@ -48,6 +47,9 @@ struct ProfileGridView: View, Routable, TunnelInstallationProviding { @State private var nextProfileId: Profile.ID? + @State + private var currentProfile: TunnelCurrentProfile? + private let columns: [GridItem] = [GridItem(.adaptive(minimum: 300.0))] var body: some View { @@ -73,6 +75,9 @@ struct ProfileGridView: View, Routable, TunnelInstallationProviding { .padding(.horizontal) } } + .onReceive(tunnel.currentProfilePublisher) { + currentProfile = $0 + } #if os(macOS) .padding(.top) #endif @@ -124,7 +129,7 @@ private extension ProfileGridView { withMarker: true, flow: flow ) - .themeGridCell(isSelected: header.id == nextProfileId ?? tunnel.currentProfile?.id) + .themeGridCell(isSelected: header.id == nextProfileId ?? currentProfile?.id) .contextMenu { ProfileContextMenu( profileManager: profileManager, diff --git a/Passepartout/Library/Sources/AppUIMain/Views/App/ProfileListView.swift b/Passepartout/Library/Sources/AppUIMain/Views/App/ProfileListView.swift index 60aacbce..423d789c 100644 --- a/Passepartout/Library/Sources/AppUIMain/Views/App/ProfileListView.swift +++ b/Passepartout/Library/Sources/AppUIMain/Views/App/ProfileListView.swift @@ -42,8 +42,7 @@ struct ProfileListView: View, Routable, TunnelInstallationProviding { @ObservedObject var profileManager: ProfileManager - @ObservedObject - var tunnel: ExtendedTunnel + let tunnel: ExtendedTunnel let interactiveManager: InteractiveManager diff --git a/Passepartout/Library/Sources/AppUIMain/Views/App/ProfileRowView.swift b/Passepartout/Library/Sources/AppUIMain/Views/App/ProfileRowView.swift index 79384b1d..f5eb9f04 100644 --- a/Passepartout/Library/Sources/AppUIMain/Views/App/ProfileRowView.swift +++ b/Passepartout/Library/Sources/AppUIMain/Views/App/ProfileRowView.swift @@ -38,8 +38,7 @@ struct ProfileRowView: View, Routable { @ObservedObject var profileManager: ProfileManager - @ObservedObject - var tunnel: ExtendedTunnel + let tunnel: ExtendedTunnel let header: ProfileHeader @@ -74,13 +73,43 @@ struct ProfileRowView: View, Routable { } } -// MARK: - Layout +// MARK: - Subviews (observing) + +private struct MarkerView: View { + let headerId: Profile.ID + + let nextProfileId: Profile.ID? + + @ObservedObject + var tunnel: ExtendedTunnel + + var body: some View { + ThemeImage(headerId == nextProfileId ? .pending : statusImage) + .opaque(headerId == nextProfileId || headerId == tunnel.currentProfile?.id) + .frame(width: 24.0) + } + + var statusImage: Theme.ImageName { + switch tunnel.connectionStatus { + case .active: + return .marked + + case .activating, .deactivating: + return .pending + + case .inactive: + return .sleeping + } + } +} private extension ProfileRowView { var markerView: some View { - ThemeImage(header.id == nextProfileId ? .pending : statusImage) - .opaque(header.id == nextProfileId || header.id == tunnel.currentProfile?.id) - .frame(width: 24.0) + MarkerView( + headerId: header.id, + nextProfileId: nextProfileId, + tunnel: tunnel + ) } var cardView: some View { @@ -102,19 +131,6 @@ private extension ProfileRowView { ) .foregroundStyle(.primary) } - - var statusImage: Theme.ImageName { - switch tunnel.connectionStatus { - case .active: - return .marked - - case .activating, .deactivating: - return .pending - - case .inactive: - return .sleeping - } - } } // MARK: - Attributes diff --git a/Passepartout/Library/Sources/CommonLibrary/Business/ExtendedTunnel.swift b/Passepartout/Library/Sources/CommonLibrary/Business/ExtendedTunnel.swift index 7065ae9a..dd0bf992 100644 --- a/Passepartout/Library/Sources/CommonLibrary/Business/ExtendedTunnel.swift +++ b/Passepartout/Library/Sources/CommonLibrary/Business/ExtendedTunnel.swift @@ -98,6 +98,12 @@ extension ExtendedTunnel { tunnel.currentProfile } + public var currentProfilePublisher: AnyPublisher { + tunnel + .$currentProfile + .eraseToAnyPublisher() + } + public func install(_ profile: Profile) async throws { pp_log(.app, .notice, "Install profile \(profile.id)...") let newProfile = try processedProfile(profile)