Resolve some focus issues (#802)
- [x] tvOS: When profile selector appears, if it's closed without selecting any profile, it instantly reopens - [x] Set initial focus in OpenVPN credentials
This commit is contained in:
parent
8aff3bedbc
commit
15959d2422
|
@ -31,8 +31,6 @@ import SwiftUI
|
||||||
struct ActiveProfileView: View {
|
struct ActiveProfileView: View {
|
||||||
let profile: Profile?
|
let profile: Profile?
|
||||||
|
|
||||||
let firstProfileId: Profile.ID?
|
|
||||||
|
|
||||||
@ObservedObject
|
@ObservedObject
|
||||||
var tunnel: ExtendedTunnel
|
var tunnel: ExtendedTunnel
|
||||||
|
|
||||||
|
@ -95,9 +93,6 @@ private extension ActiveProfileView {
|
||||||
|
|
||||||
var switchProfileButton: some View {
|
var switchProfileButton: some View {
|
||||||
Button {
|
Button {
|
||||||
if let focus = tunnel.currentProfile?.id ?? firstProfileId {
|
|
||||||
focusedField = .profile(focus)
|
|
||||||
}
|
|
||||||
isSwitching.toggle()
|
isSwitching.toggle()
|
||||||
} label: {
|
} label: {
|
||||||
Text(Strings.Global.select)
|
Text(Strings.Global.select)
|
||||||
|
|
|
@ -131,7 +131,6 @@ private extension ProfileView {
|
||||||
var activeView: some View {
|
var activeView: some View {
|
||||||
ActiveProfileView(
|
ActiveProfileView(
|
||||||
profile: currentProfile,
|
profile: currentProfile,
|
||||||
firstProfileId: profileManager.headers.first?.id,
|
|
||||||
tunnel: tunnel,
|
tunnel: tunnel,
|
||||||
isSwitching: $isSwitching,
|
isSwitching: $isSwitching,
|
||||||
focusedField: $focusedField,
|
focusedField: $focusedField,
|
||||||
|
|
|
@ -29,6 +29,13 @@ import PassepartoutKit
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
public struct OpenVPNCredentialsView: View {
|
public struct OpenVPNCredentialsView: View {
|
||||||
|
private enum Field: Hashable {
|
||||||
|
case username
|
||||||
|
|
||||||
|
case password
|
||||||
|
|
||||||
|
case otp
|
||||||
|
}
|
||||||
|
|
||||||
@EnvironmentObject
|
@EnvironmentObject
|
||||||
private var iapManager: IAPManager
|
private var iapManager: IAPManager
|
||||||
|
@ -47,6 +54,9 @@ public struct OpenVPNCredentialsView: View {
|
||||||
@State
|
@State
|
||||||
private var paywallReason: PaywallReason?
|
private var paywallReason: PaywallReason?
|
||||||
|
|
||||||
|
@FocusState
|
||||||
|
private var focusedField: Field?
|
||||||
|
|
||||||
public init(
|
public init(
|
||||||
isInteractive: Binding<Bool>,
|
isInteractive: Binding<Bool>,
|
||||||
credentials: Binding<OpenVPN.Credentials?>,
|
credentials: Binding<OpenVPN.Credentials?>,
|
||||||
|
@ -66,6 +76,15 @@ public struct OpenVPNCredentialsView: View {
|
||||||
.onLoad {
|
.onLoad {
|
||||||
builder = credentials?.builder() ?? OpenVPN.Credentials.Builder()
|
builder = credentials?.builder() ?? OpenVPN.Credentials.Builder()
|
||||||
builder.otp = nil
|
builder.otp = nil
|
||||||
|
if isAuthenticating {
|
||||||
|
switch builder.otpMethod {
|
||||||
|
case .none:
|
||||||
|
focusedField = .username
|
||||||
|
|
||||||
|
default:
|
||||||
|
focusedField = .otp
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.onChange(of: builder) {
|
.onChange(of: builder) {
|
||||||
var copy = $0
|
var copy = $0
|
||||||
|
@ -137,8 +156,11 @@ private extension OpenVPNCredentialsView {
|
||||||
if !isAuthenticating || builder.otpMethod == .none {
|
if !isAuthenticating || builder.otpMethod == .none {
|
||||||
ThemeTextField(Strings.Global.username, text: $builder.username, placeholder: Strings.Placeholders.username)
|
ThemeTextField(Strings.Global.username, text: $builder.username, placeholder: Strings.Placeholders.username)
|
||||||
.textContentType(.username)
|
.textContentType(.username)
|
||||||
|
.focused($focusedField, equals: .username)
|
||||||
|
|
||||||
ThemeSecureField(title: Strings.Global.password, text: $builder.password, placeholder: Strings.Placeholders.secret)
|
ThemeSecureField(title: Strings.Global.password, text: $builder.password, placeholder: Strings.Placeholders.secret)
|
||||||
.textContentType(.password)
|
.textContentType(.password)
|
||||||
|
.focused($focusedField, equals: .password)
|
||||||
}
|
}
|
||||||
if isEligibleForInteractiveLogin, isAuthenticating, builder.otpMethod != .none {
|
if isEligibleForInteractiveLogin, isAuthenticating, builder.otpMethod != .none {
|
||||||
ThemeSecureField(
|
ThemeSecureField(
|
||||||
|
@ -147,6 +169,7 @@ private extension OpenVPNCredentialsView {
|
||||||
placeholder: Strings.Placeholders.secret
|
placeholder: Strings.Placeholders.secret
|
||||||
)
|
)
|
||||||
.textContentType(.oneTimeCode)
|
.textContentType(.oneTimeCode)
|
||||||
|
.focused($focusedField, equals: .otp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.themeSection(footer: inputFooter)
|
.themeSection(footer: inputFooter)
|
||||||
|
|
Loading…
Reference in New Issue