mirror of
https://github.com/yattee/yattee.git
synced 2024-12-22 13:33:42 +00:00
Instance and account form and validation improvements
This commit is contained in:
parent
9f3a94137c
commit
cf0572a94b
@ -82,14 +82,24 @@ final class AccountValidator: Service {
|
|||||||
}
|
}
|
||||||
|
|
||||||
guard !response.json.isEmpty else {
|
guard !response.json.isEmpty else {
|
||||||
guard let app = self.appsToValidateInstance.popLast() else {
|
if app == .piped {
|
||||||
|
if response.text.contains("property=\"og:title\" content=\"Piped\"") {
|
||||||
|
self.isValid.wrappedValue = false
|
||||||
|
self.isValidated.wrappedValue = true
|
||||||
|
self.isValidating.wrappedValue = false
|
||||||
|
self.error?.wrappedValue = "Trying to use Piped front-end URL, you need to use URL for Piped API instead"
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
guard let nextApp = self.appsToValidateInstance.popLast() else {
|
||||||
self.isValid.wrappedValue = false
|
self.isValid.wrappedValue = false
|
||||||
self.isValidated.wrappedValue = true
|
self.isValidated.wrappedValue = true
|
||||||
self.isValidating.wrappedValue = false
|
self.isValidating.wrappedValue = false
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
self.tryValidatingUsing(app)
|
self.tryValidatingUsing(nextApp)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -128,15 +138,15 @@ final class AccountValidator: Service {
|
|||||||
|
|
||||||
switch app.wrappedValue {
|
switch app.wrappedValue {
|
||||||
case .invidious:
|
case .invidious:
|
||||||
invidiousValidation()
|
validateInvidiousAccount()
|
||||||
case .piped:
|
case .piped:
|
||||||
pipedValidation()
|
validatePipedAccount()
|
||||||
default:
|
default:
|
||||||
setValidationResult(false)
|
setValidationResult(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func invidiousValidation() {
|
func validateInvidiousAccount() {
|
||||||
guard let username = account?.username,
|
guard let username = account?.username,
|
||||||
let password = account?.password
|
let password = account?.password
|
||||||
else {
|
else {
|
||||||
@ -177,7 +187,7 @@ final class AccountValidator: Service {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func pipedValidation() {
|
func validatePipedAccount() {
|
||||||
guard let request = accountRequest else {
|
guard let request = accountRequest else {
|
||||||
setValidationResult(false)
|
setValidationResult(false)
|
||||||
|
|
||||||
|
@ -24,6 +24,13 @@ struct AccountForm: View {
|
|||||||
Group {
|
Group {
|
||||||
header
|
header
|
||||||
form
|
form
|
||||||
|
#if os(macOS)
|
||||||
|
VStack {
|
||||||
|
validationStatus
|
||||||
|
}
|
||||||
|
.frame(minHeight: 60, alignment: .topLeading)
|
||||||
|
.padding(.horizontal, 15)
|
||||||
|
#endif
|
||||||
footer
|
footer
|
||||||
}
|
}
|
||||||
.frame(maxWidth: 1000)
|
.frame(maxWidth: 1000)
|
||||||
@ -34,7 +41,8 @@ struct AccountForm: View {
|
|||||||
.frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity)
|
.frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity)
|
||||||
.background(Color.background(scheme: colorScheme))
|
.background(Color.background(scheme: colorScheme))
|
||||||
#else
|
#else
|
||||||
.frame(width: 400, height: 145)
|
.frame(width: 400, height: 180)
|
||||||
|
.padding(.vertical)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,32 +80,36 @@ struct AccountForm: View {
|
|||||||
.onChange(of: password) { _ in validate() }
|
.onChange(of: password) { _ in validate() }
|
||||||
}
|
}
|
||||||
|
|
||||||
var formFields: some View {
|
@ViewBuilder var formFields: some View {
|
||||||
Group {
|
TextField("Username", text: $username)
|
||||||
TextField("Username", text: $username)
|
SecureField("Password", text: $password)
|
||||||
SecureField("Password", text: $password)
|
|
||||||
}
|
#if os(tvOS)
|
||||||
|
VStack {
|
||||||
|
validationStatus
|
||||||
|
}
|
||||||
|
.frame(minHeight: 100)
|
||||||
|
#elseif os(iOS)
|
||||||
|
validationStatus
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
var usernamePrompt: String {
|
@ViewBuilder var validationStatus: some View {
|
||||||
switch instance.app {
|
if !username.isEmpty && !password.isEmpty {
|
||||||
case .invidious:
|
Section {
|
||||||
return "SID Cookie"
|
AccountValidationStatus(
|
||||||
default:
|
app: .constant(instance.app),
|
||||||
return "Username"
|
isValid: $isValid,
|
||||||
|
isValidated: $isValidated,
|
||||||
|
isValidating: $isValidating,
|
||||||
|
error: $validationError
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var footer: some View {
|
var footer: some View {
|
||||||
HStack {
|
HStack {
|
||||||
AccountValidationStatus(
|
|
||||||
app: .constant(instance.app),
|
|
||||||
isValid: $isValid,
|
|
||||||
isValidated: $isValidated,
|
|
||||||
isValidating: $isValidating,
|
|
||||||
error: $validationError
|
|
||||||
)
|
|
||||||
|
|
||||||
Spacer()
|
Spacer()
|
||||||
|
|
||||||
Button("Save", action: submitForm)
|
Button("Save", action: submitForm)
|
||||||
|
@ -9,28 +9,41 @@ struct AccountValidationStatus: View {
|
|||||||
@Binding var error: String?
|
@Binding var error: String?
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
HStack(spacing: 4) {
|
VStack(alignment: .leading) {
|
||||||
Image(systemName: validationStatusSystemImage)
|
HStack {
|
||||||
.foregroundColor(validationStatusColor)
|
Image(systemName: validationStatusSystemImage)
|
||||||
|
.foregroundColor(validationStatusColor)
|
||||||
|
.imageScale(.medium)
|
||||||
|
.opacity(isValidating ? 1 : (isValidated ? 1 : 0))
|
||||||
|
|
||||||
.frame(minWidth: 35, minHeight: 35)
|
|
||||||
.opacity(isValidating ? 1 : (isValidated ? 1 : 0))
|
|
||||||
|
|
||||||
VStack(alignment: .leading) {
|
|
||||||
Text(isValid ? "Connected successfully (\(app?.name ?? "Unknown"))" : "Connection failed")
|
Text(isValid ? "Connected successfully (\(app?.name ?? "Unknown"))" : "Connection failed")
|
||||||
if let error, !isValid {
|
.opacity(isValidated && !isValidating ? 1 : 0)
|
||||||
Text(error)
|
}
|
||||||
.font(.caption2)
|
if errorVisible {
|
||||||
.foregroundColor(.secondary)
|
Text(error ?? "")
|
||||||
.truncationMode(.tail)
|
.frame(maxWidth: .infinity, alignment: .leading)
|
||||||
.lineLimit(1)
|
.lineLimit(nil)
|
||||||
}
|
.multilineTextAlignment(.leading)
|
||||||
|
.font(.footnote)
|
||||||
|
.foregroundColor(.secondary)
|
||||||
|
.padding(.top, 5)
|
||||||
|
.opacity(errorTextVisible ? 1 : 0)
|
||||||
}
|
}
|
||||||
.frame(minHeight: 35)
|
|
||||||
.opacity(isValidating ? 0 : (isValidated ? 1 : 0))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var errorVisible: Bool {
|
||||||
|
#if !os(iOS)
|
||||||
|
true
|
||||||
|
#else
|
||||||
|
errorTextVisible
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
var errorTextVisible: Bool {
|
||||||
|
error != nil && isValidated && !isValid && !isValidating
|
||||||
|
}
|
||||||
|
|
||||||
var validationStatusSystemImage: String {
|
var validationStatusSystemImage: String {
|
||||||
if isValidating {
|
if isValidating {
|
||||||
return "bolt.horizontal.fill"
|
return "bolt.horizontal.fill"
|
||||||
|
@ -22,9 +22,14 @@ struct InstanceForm: View {
|
|||||||
VStack(alignment: .leading) {
|
VStack(alignment: .leading) {
|
||||||
Group {
|
Group {
|
||||||
header
|
header
|
||||||
|
|
||||||
form
|
form
|
||||||
|
#if os(macOS)
|
||||||
|
VStack {
|
||||||
|
validationStatus
|
||||||
|
}
|
||||||
|
.frame(minHeight: 60, alignment: .topLeading)
|
||||||
|
.padding(.horizontal, 15)
|
||||||
|
#endif
|
||||||
footer
|
footer
|
||||||
}
|
}
|
||||||
.frame(maxWidth: 1000)
|
.frame(maxWidth: 1000)
|
||||||
@ -36,7 +41,8 @@ struct InstanceForm: View {
|
|||||||
.frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity)
|
.frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity)
|
||||||
.background(Color.background(scheme: colorScheme))
|
.background(Color.background(scheme: colorScheme))
|
||||||
#else
|
#else
|
||||||
.frame(width: 400, height: 150)
|
.frame(width: 400, height: 180)
|
||||||
|
.padding(.vertical)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -80,19 +86,34 @@ struct InstanceForm: View {
|
|||||||
.autocapitalization(.none)
|
.autocapitalization(.none)
|
||||||
.keyboardType(.URL)
|
.keyboardType(.URL)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if os(tvOS)
|
||||||
|
VStack {
|
||||||
|
validationStatus
|
||||||
|
}
|
||||||
|
.frame(minHeight: 100)
|
||||||
|
#elseif os(iOS)
|
||||||
|
validationStatus
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ViewBuilder var validationStatus: some View {
|
||||||
|
if !url.isEmpty {
|
||||||
|
Section {
|
||||||
|
AccountValidationStatus(
|
||||||
|
app: $app,
|
||||||
|
isValid: $isValid,
|
||||||
|
isValidated: $isValidated,
|
||||||
|
isValidating: $isValidating,
|
||||||
|
error: $validationError
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private var footer: some View {
|
private var footer: some View {
|
||||||
HStack {
|
HStack {
|
||||||
AccountValidationStatus(
|
|
||||||
app: $app,
|
|
||||||
isValid: $isValid,
|
|
||||||
isValidated: $isValidated,
|
|
||||||
isValidating: $isValidating,
|
|
||||||
error: $validationError
|
|
||||||
)
|
|
||||||
|
|
||||||
Spacer()
|
Spacer()
|
||||||
|
|
||||||
Button("Save", action: submitForm)
|
Button("Save", action: submitForm)
|
||||||
|
Loading…
Reference in New Issue
Block a user