mirror of
https://github.com/yattee/yattee.git
synced 2025-08-06 10:44:06 +00:00
Extract instance/account validation status view
This commit is contained in:
@@ -5,7 +5,7 @@ import SwiftUI
|
||||
struct AddToPlaylistView: View {
|
||||
@EnvironmentObject<PlaylistsModel> private var model
|
||||
|
||||
@State var video: Video
|
||||
let video: Video
|
||||
|
||||
@Environment(\.dismiss) private var dismiss
|
||||
|
||||
|
@@ -8,8 +8,9 @@ struct AccountFormView: View {
|
||||
@State private var name = ""
|
||||
@State private var sid = ""
|
||||
|
||||
@State private var valid = false
|
||||
@State private var validated = false
|
||||
@State private var isValid = false
|
||||
@State private var isValidated = false
|
||||
@State private var isValidating = false
|
||||
@State private var validationDebounce = Debounce()
|
||||
|
||||
@FocusState private var focused: Bool
|
||||
@@ -82,12 +83,12 @@ struct AccountFormView: View {
|
||||
|
||||
var footer: some View {
|
||||
HStack {
|
||||
validationStatus
|
||||
ValidationStatusView(isValid: $isValid, isValidated: $isValidated, isValidating: $isValidating, error: .constant(nil))
|
||||
|
||||
Spacer()
|
||||
|
||||
Button("Save", action: submitForm)
|
||||
.disabled(!valid)
|
||||
.disabled(!isValid)
|
||||
#if !os(tvOS)
|
||||
.keyboardShortcut(.defaultAction)
|
||||
#endif
|
||||
@@ -99,17 +100,6 @@ struct AccountFormView: View {
|
||||
.padding(.horizontal)
|
||||
}
|
||||
|
||||
var validationStatus: some View {
|
||||
HStack(spacing: 4) {
|
||||
Image(systemName: valid ? "checkmark.circle.fill" : "xmark.circle.fill")
|
||||
.foregroundColor(valid ? .green : .red)
|
||||
VStack(alignment: .leading) {
|
||||
Text(valid ? "Account found" : "Invalid account details")
|
||||
}
|
||||
}
|
||||
.opacity(validated ? 1 : 0)
|
||||
}
|
||||
|
||||
private func initializeForm() {
|
||||
focused = true
|
||||
}
|
||||
@@ -122,13 +112,15 @@ struct AccountFormView: View {
|
||||
return
|
||||
}
|
||||
|
||||
validationDebounce.debouncing(2) {
|
||||
isValidating = true
|
||||
|
||||
validationDebounce.debouncing(1) {
|
||||
validator.validateAccount()
|
||||
}
|
||||
}
|
||||
|
||||
private func submitForm() {
|
||||
guard valid else {
|
||||
guard isValid else {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -143,8 +135,9 @@ struct AccountFormView: View {
|
||||
url: instance.url,
|
||||
account: Instance.Account(instanceID: instance.id, url: instance.url, sid: sid),
|
||||
id: $sid,
|
||||
valid: $valid,
|
||||
validated: $validated
|
||||
isValid: $isValid,
|
||||
isValidated: $isValidated,
|
||||
isValidating: $isValidating
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@@ -16,7 +16,6 @@ struct InstanceDetailsSettingsView: View {
|
||||
List {
|
||||
Section(header: Text("Accounts")) {
|
||||
ForEach(instances.accounts(instanceID), id: \.self) { account in
|
||||
|
||||
#if !os(tvOS)
|
||||
HStack(spacing: 2) {
|
||||
Text(account.description)
|
||||
@@ -27,13 +26,13 @@ struct InstanceDetailsSettingsView: View {
|
||||
}
|
||||
.swipeActions(edge: .leading, allowsFullSwipe: true) {
|
||||
if instances.defaultAccount != account {
|
||||
Button("Make Default", action: { makeDefault(account) })
|
||||
Button("Make Default") { makeDefault(account) }
|
||||
} else {
|
||||
Button("Reset Default", action: resetDefaultAccount)
|
||||
}
|
||||
}
|
||||
.swipeActions(edge: .trailing, allowsFullSwipe: false) {
|
||||
Button("Remove", role: .destructive, action: { removeAccount(account) })
|
||||
Button("Remove", role: .destructive) { removeAccount(account) }
|
||||
}
|
||||
|
||||
#else
|
||||
@@ -47,8 +46,8 @@ struct InstanceDetailsSettingsView: View {
|
||||
}
|
||||
}
|
||||
.contextMenu {
|
||||
Button("Toggle Default", action: { toggleDefault(account) })
|
||||
Button("Remove", role: .destructive, action: { removeAccount(account) })
|
||||
Button("Toggle Default") { toggleDefault(account) }
|
||||
Button("Remove", role: .destructive) { removeAccount(account) }
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@@ -6,8 +6,9 @@ struct InstanceFormView: View {
|
||||
@State private var name = ""
|
||||
@State private var url = ""
|
||||
|
||||
@State private var valid = false
|
||||
@State private var validated = false
|
||||
@State private var isValid = false
|
||||
@State private var isValidated = false
|
||||
@State private var isValidating = false
|
||||
@State private var validationError: String?
|
||||
@State private var validationDebounce = Debounce()
|
||||
|
||||
@@ -73,21 +74,24 @@ struct InstanceFormView: View {
|
||||
private var formFields: some View {
|
||||
Group {
|
||||
TextField("Name", text: $name, prompt: Text("Instance Name (optional)"))
|
||||
|
||||
.focused($nameFieldFocused)
|
||||
|
||||
TextField("URL", text: $url, prompt: Text("https://invidious.home.net"))
|
||||
#if !os(macOS)
|
||||
.autocapitalization(.none)
|
||||
.keyboardType(.URL)
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
private var footer: some View {
|
||||
HStack(alignment: .center) {
|
||||
validationStatus
|
||||
ValidationStatusView(isValid: $isValid, isValidated: $isValidated, isValidating: $isValidating, error: $validationError)
|
||||
|
||||
Spacer()
|
||||
|
||||
Button("Save", action: submitForm)
|
||||
.disabled(!valid)
|
||||
.disabled(!isValid)
|
||||
#if !os(tvOS)
|
||||
.keyboardShortcut(.defaultAction)
|
||||
#endif
|
||||
@@ -98,31 +102,13 @@ struct InstanceFormView: View {
|
||||
.padding(.horizontal)
|
||||
}
|
||||
|
||||
private var validationStatus: some View {
|
||||
HStack(spacing: 4) {
|
||||
Image(systemName: valid ? "checkmark.circle.fill" : "xmark.circle.fill")
|
||||
.foregroundColor(valid ? .green : .red)
|
||||
VStack(alignment: .leading) {
|
||||
Text(valid ? "Connected successfully" : "Connection failed")
|
||||
if !valid {
|
||||
Text(validationError ?? "Unknown Error")
|
||||
.font(.caption2)
|
||||
.foregroundColor(.secondary)
|
||||
.truncationMode(.tail)
|
||||
.lineLimit(1)
|
||||
}
|
||||
}
|
||||
.frame(minHeight: 35)
|
||||
}
|
||||
.opacity(validated ? 1 : 0)
|
||||
}
|
||||
|
||||
var validator: AccountValidator {
|
||||
AccountValidator(
|
||||
url: url,
|
||||
id: $url,
|
||||
valid: $valid,
|
||||
validated: $validated,
|
||||
isValid: $isValid,
|
||||
isValidated: $isValidated,
|
||||
isValidating: $isValidating,
|
||||
error: $validationError
|
||||
)
|
||||
}
|
||||
@@ -135,6 +121,8 @@ struct InstanceFormView: View {
|
||||
return
|
||||
}
|
||||
|
||||
isValidating = true
|
||||
|
||||
validationDebounce.debouncing(2) {
|
||||
validator.validateInstance()
|
||||
}
|
||||
@@ -145,7 +133,7 @@ struct InstanceFormView: View {
|
||||
}
|
||||
|
||||
func submitForm() {
|
||||
guard valid else {
|
||||
guard isValid else {
|
||||
return
|
||||
}
|
||||
|
||||
|
48
Shared/Settings/ValidationStatusView.swift
Normal file
48
Shared/Settings/ValidationStatusView.swift
Normal file
@@ -0,0 +1,48 @@
|
||||
import Foundation
|
||||
import SwiftUI
|
||||
|
||||
struct ValidationStatusView: View {
|
||||
@Binding var isValid: Bool
|
||||
@Binding var isValidated: Bool
|
||||
@Binding var isValidating: Bool
|
||||
@Binding var error: String?
|
||||
|
||||
var body: some View {
|
||||
HStack(spacing: 4) {
|
||||
Image(systemName: validationStatusSystemImage)
|
||||
.foregroundColor(validationStatusColor)
|
||||
|
||||
.frame(minWidth: 35, minHeight: 35)
|
||||
.opacity(isValidating ? 1 : (isValidated ? 1 : 0))
|
||||
|
||||
VStack(alignment: .leading) {
|
||||
Text(isValid ? "Connected successfully" : "Connection failed")
|
||||
if !isValid && !error.isNil {
|
||||
Text(error!)
|
||||
.font(.caption2)
|
||||
.foregroundColor(.secondary)
|
||||
.truncationMode(.tail)
|
||||
.lineLimit(1)
|
||||
}
|
||||
}
|
||||
.frame(minHeight: 35)
|
||||
.opacity(isValidating ? 0 : (isValidated ? 1 : 0))
|
||||
}
|
||||
}
|
||||
|
||||
var validationStatusSystemImage: String {
|
||||
if isValidating {
|
||||
return "bolt.horizontal.fill"
|
||||
} else {
|
||||
return isValid ? "checkmark.circle.fill" : "xmark.circle.fill"
|
||||
}
|
||||
}
|
||||
|
||||
var validationStatusColor: Color {
|
||||
if isValidating {
|
||||
return .accentColor
|
||||
} else {
|
||||
return isValid ? .green : .red
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user