Do not connect TV profile on server selection (#1030)

You may still connect manually, but iOS/macOS apps mainly serve as
remote to switch servers on the TV.
This commit is contained in:
Davide 2024-12-20 10:30:57 +01:00 committed by GitHub
parent f8e623e1fe
commit 42bf392fff
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 42 additions and 4 deletions

View File

@ -191,6 +191,7 @@ extension AppCoordinator {
ProviderEntitySelector( ProviderEntitySelector(
module: module, module: module,
errorHandler: errorHandler, errorHandler: errorHandler,
selectTitle: profile.providerServerSelectionTitle,
onSelect: { onSelect: {
try await onSelectProviderEntity(with: $0, in: profile, force: force) try await onSelectProviderEntity(with: $0, in: profile, force: force)
} }
@ -270,6 +271,11 @@ private extension AppCoordinator {
let wasConnected = newProfile.id == tunnel.currentProfile?.id && tunnel.status == .active let wasConnected = newProfile.id == tunnel.currentProfile?.id && tunnel.status == .active
try await profileManager.save(newProfile, isLocal: true) try await profileManager.save(newProfile, isLocal: true)
guard profile.shouldConnectToProviderServer else {
return
}
if !wasConnected { if !wasConnected {
pp_log(.app, .info, "Profile \(newProfile.id) was not connected, will connect to new provider entity") pp_log(.app, .info, "Profile \(newProfile.id) was not connected, will connect to new provider entity")
await onConnect(newProfile, force: force) await onConnect(newProfile, force: force)
@ -313,6 +319,21 @@ private extension AppCoordinator {
} }
} }
private extension Profile {
var providerServerSelectionTitle: String {
attributes.isAvailableForTV == true ? Strings.Views.Providers.selectEntity : Strings.Global.Actions.connect
}
var shouldConnectToProviderServer: Bool {
#if os(tvOS)
true
#else
// do not connect TV profiles on server selection
attributes.isAvailableForTV != true
#endif
}
}
// MARK: - Previews // MARK: - Previews
#Preview { #Preview {

View File

@ -88,14 +88,14 @@ private extension ProfileContextMenu {
} }
var providerConnectToButton: some View { var providerConnectToButton: some View {
profile.map { profile.map { profile in
ProviderConnectToButton( ProviderConnectToButton(
profile: $0, profile: profile,
onTap: { onTap: {
flow?.connectionFlow?.onProviderEntityRequired($0) flow?.connectionFlow?.onProviderEntityRequired($0)
}, },
label: { label: {
ThemeImageLabel(Strings.Views.App.ProfileContext.connectTo.withTrailingDots, .profileProvider) ThemeImageLabel(profile.providerServerSelectionTitle, .profileProvider)
} }
) )
.uiAccessibility(.App.ProfileMenu.connectTo) .uiAccessibility(.App.ProfileMenu.connectTo)
@ -143,6 +143,13 @@ private extension ProfileContextMenu {
} }
} }
private extension Profile {
var providerServerSelectionTitle: String {
(attributes.isAvailableForTV == true ?
Strings.Views.Providers.selectEntity : Strings.Views.App.ProfileContext.connectTo).withTrailingDots
}
}
#Preview { #Preview {
List { List {
Menu("Menu") { Menu("Menu") {

View File

@ -37,6 +37,7 @@ extension OpenVPNModule.Builder: ModuleViewProviding {
extension OpenVPNModule: ProviderEntityViewProviding { extension OpenVPNModule: ProviderEntityViewProviding {
public func providerEntityView( public func providerEntityView(
errorHandler: ErrorHandler, errorHandler: ErrorHandler,
selectTitle: String,
onSelect: @escaping (Module) async throws -> Void onSelect: @escaping (Module) async throws -> Void
) -> some View { ) -> some View {
providerSelection.map { providerSelection.map {
@ -44,6 +45,7 @@ extension OpenVPNModule: ProviderEntityViewProviding {
moduleId: id, moduleId: id,
providerId: $0.id, providerId: $0.id,
selectedEntity: $0.entity, selectedEntity: $0.entity,
selectTitle: selectTitle,
onSelect: { onSelect: {
var newBuilder = builder() var newBuilder = builder()
newBuilder.providerEntity = $0 newBuilder.providerEntity = $0

View File

@ -37,6 +37,7 @@ extension WireGuardModule.Builder: ModuleViewProviding {
extension WireGuardModule: ProviderEntityViewProviding { extension WireGuardModule: ProviderEntityViewProviding {
public func providerEntityView( public func providerEntityView(
errorHandler: ErrorHandler, errorHandler: ErrorHandler,
selectTitle: String,
onSelect: @escaping (Module) async throws -> Void onSelect: @escaping (Module) async throws -> Void
) -> some View { ) -> some View {
providerSelection.map { providerSelection.map {
@ -44,6 +45,7 @@ extension WireGuardModule: ProviderEntityViewProviding {
moduleId: id, moduleId: id,
providerId: $0.id, providerId: $0.id,
selectedEntity: $0.entity, selectedEntity: $0.entity,
selectTitle: selectTitle,
onSelect: { onSelect: {
var newBuilder = builder() var newBuilder = builder()
newBuilder.providerEntity = $0 newBuilder.providerEntity = $0

View File

@ -33,12 +33,15 @@ struct ProviderEntitySelector: View {
let errorHandler: ErrorHandler let errorHandler: ErrorHandler
let selectTitle: String
let onSelect: (Module) async throws -> Void let onSelect: (Module) async throws -> Void
var body: some View { var body: some View {
if let viewProvider = module as? any ProviderEntityViewProviding { if let viewProvider = module as? any ProviderEntityViewProviding {
AnyView(viewProvider.providerEntityView( AnyView(viewProvider.providerEntityView(
errorHandler: errorHandler, errorHandler: errorHandler,
selectTitle: selectTitle,
onSelect: onSelect onSelect: onSelect
)) ))
} else { } else {

View File

@ -38,6 +38,8 @@ struct VPNProviderServerCoordinator<Configuration>: View where Configuration: Id
let selectedEntity: VPNEntity<Configuration>? let selectedEntity: VPNEntity<Configuration>?
let selectTitle: String
let onSelect: (VPNEntity<Configuration>) async throws -> Void let onSelect: (VPNEntity<Configuration>) async throws -> Void
@ObservedObject @ObservedObject
@ -49,7 +51,7 @@ struct VPNProviderServerCoordinator<Configuration>: View where Configuration: Id
providerId: providerId, providerId: providerId,
selectedEntity: selectedEntity, selectedEntity: selectedEntity,
filtersWithSelection: false, filtersWithSelection: false,
selectTitle: Strings.Global.Actions.connect, selectTitle: selectTitle,
onSelect: onSelect onSelect: onSelect
) )
.themeNavigationStack(closable: true) .themeNavigationStack(closable: true)

View File

@ -33,6 +33,7 @@ public protocol ProviderEntityViewProviding {
@MainActor @MainActor
func providerEntityView( func providerEntityView(
errorHandler: ErrorHandler, errorHandler: ErrorHandler,
selectTitle: String,
onSelect: @escaping (Module) async throws -> Void onSelect: @escaping (Module) async throws -> Void
) -> EntityContent ) -> EntityContent
} }