mirror of
https://github.com/writeas/writefreely-swiftui-multiplatform.git
synced 2024-11-15 01:11:02 +00:00
Refactor account views and AccountModel
This commit is contained in:
parent
54d1d64e0e
commit
6dba087295
@ -1,70 +1,67 @@
|
||||
import SwiftUI
|
||||
|
||||
struct AccountLoginView: View {
|
||||
@State private var username: String = ""
|
||||
@State private var password: String = ""
|
||||
@State private var server: String = ""
|
||||
@ObservedObject var account: AccountModel
|
||||
|
||||
@State private var isShowingAlert: Bool = false
|
||||
@State private var alertMessage: String = ""
|
||||
|
||||
@Binding var accountModel: AccountModel
|
||||
@Binding var isLoggedIn: Bool
|
||||
@Binding var isLoggingIn: Bool
|
||||
|
||||
var body: some View {
|
||||
VStack {
|
||||
HStack {
|
||||
Image(systemName: "person.circle")
|
||||
.foregroundColor(.gray)
|
||||
#if os(iOS)
|
||||
TextField("Username", text: $username)
|
||||
TextField("Username", text: $account.username)
|
||||
.keyboardType(.emailAddress)
|
||||
.autocapitalization(.none)
|
||||
.disableAutocorrection(true)
|
||||
.textFieldStyle(RoundedBorderTextFieldStyle())
|
||||
#else
|
||||
TextField("Username", text: $username)
|
||||
TextField("Username", text: $account.username)
|
||||
#endif
|
||||
}
|
||||
HStack {
|
||||
Image(systemName: "lock.circle")
|
||||
.foregroundColor(.gray)
|
||||
#if os(iOS)
|
||||
SecureField("Password", text: $password)
|
||||
SecureField("Password", text: $account.password)
|
||||
.autocapitalization(.none)
|
||||
.disableAutocorrection(true)
|
||||
.textFieldStyle(RoundedBorderTextFieldStyle())
|
||||
#else
|
||||
SecureField("Password", text: $password)
|
||||
SecureField("Password", text: $account.password)
|
||||
#endif
|
||||
}
|
||||
HStack {
|
||||
Image(systemName: "link.circle")
|
||||
.foregroundColor(.gray)
|
||||
#if os(iOS)
|
||||
TextField("Server URL", text: $server)
|
||||
TextField("Server URL", text: $account.server)
|
||||
.keyboardType(.URL)
|
||||
.autocapitalization(.none)
|
||||
.disableAutocorrection(true)
|
||||
.textFieldStyle(RoundedBorderTextFieldStyle())
|
||||
#else
|
||||
TextField("Server URL", text: $server)
|
||||
TextField("Server URL", text: $account.server)
|
||||
#endif
|
||||
}
|
||||
Spacer()
|
||||
if isLoggingIn {
|
||||
if account.isLoggingIn {
|
||||
ProgressView("Logging in...")
|
||||
.padding()
|
||||
} else {
|
||||
Button(action: {
|
||||
accountModel.login(
|
||||
to: server,
|
||||
as: username, password: password,
|
||||
account.login(
|
||||
to: account.server,
|
||||
as: account.username, password: account.password,
|
||||
completion: loginHandler
|
||||
)
|
||||
isLoggingIn = true
|
||||
}, label: {
|
||||
Text("Login")
|
||||
}).disabled(isLoggedIn)
|
||||
})
|
||||
.disabled(account.isLoggedIn)
|
||||
.padding()
|
||||
}
|
||||
}
|
||||
.alert(isPresented: $isShowingAlert) {
|
||||
@ -79,26 +76,18 @@ struct AccountLoginView: View {
|
||||
func loginHandler(result: Result<UUID, AccountError>) {
|
||||
do {
|
||||
_ = try result.get()
|
||||
isLoggedIn = true
|
||||
isLoggingIn = false
|
||||
} catch AccountError.serverNotFound {
|
||||
alertMessage = """
|
||||
The server could not be found. Please check that you've entered the information correctly and try again.
|
||||
"""
|
||||
isLoggedIn = false
|
||||
isLoggingIn = false
|
||||
isShowingAlert = true
|
||||
} catch AccountError.invalidCredentials {
|
||||
alertMessage = """
|
||||
Invalid username or password. Please check that you've entered the information correctly and try again.
|
||||
"""
|
||||
isLoggedIn = false
|
||||
isLoggingIn = false
|
||||
isShowingAlert = true
|
||||
} catch {
|
||||
alertMessage = "An unknown error occurred. Please try again."
|
||||
isLoggedIn = false
|
||||
isLoggingIn = false
|
||||
isShowingAlert = true
|
||||
}
|
||||
}
|
||||
@ -106,20 +95,12 @@ The server could not be found. Please check that you've entered the information
|
||||
|
||||
struct AccountLoginView_LoggedOutPreviews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
AccountLoginView(
|
||||
accountModel: .constant(AccountModel()),
|
||||
isLoggedIn: .constant(false),
|
||||
isLoggingIn: .constant(false)
|
||||
)
|
||||
AccountLoginView(account: AccountModel())
|
||||
}
|
||||
}
|
||||
|
||||
struct AccountLoginView_LoggingInPreviews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
AccountLoginView(
|
||||
accountModel: .constant(AccountModel()),
|
||||
isLoggedIn: .constant(false),
|
||||
isLoggingIn: .constant(true)
|
||||
)
|
||||
AccountLoginView(account: AccountModel())
|
||||
}
|
||||
}
|
||||
|
@ -1,16 +1,14 @@
|
||||
import SwiftUI
|
||||
|
||||
struct AccountLogoutView: View {
|
||||
@Binding var accountModel: AccountModel
|
||||
@Binding var isLoggedIn: Bool
|
||||
@Binding var isLoggingIn: Bool
|
||||
@ObservedObject var account: AccountModel
|
||||
|
||||
var body: some View {
|
||||
VStack {
|
||||
Spacer()
|
||||
VStack {
|
||||
Text("Logged in as \(accountModel.username ?? "UNKNOWN")")
|
||||
Text("on \(accountModel.server ?? "UNKNOWN")")
|
||||
Text("Logged in as \(account.username)")
|
||||
Text("on \(account.server)")
|
||||
}
|
||||
Spacer()
|
||||
Button(action: logoutHandler, label: {
|
||||
@ -20,17 +18,12 @@ struct AccountLogoutView: View {
|
||||
}
|
||||
|
||||
func logoutHandler() {
|
||||
isLoggedIn = false
|
||||
isLoggingIn = false
|
||||
account.logout()
|
||||
}
|
||||
}
|
||||
|
||||
struct AccountLogoutView_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
AccountLogoutView(
|
||||
accountModel: .constant(AccountModel()),
|
||||
isLoggedIn: .constant(true),
|
||||
isLoggingIn: .constant(false)
|
||||
)
|
||||
AccountLogoutView(account: AccountModel())
|
||||
}
|
||||
}
|
||||
|
@ -5,18 +5,21 @@ enum AccountError: Error {
|
||||
case serverNotFound
|
||||
}
|
||||
|
||||
struct AccountModel {
|
||||
private(set) var id: UUID?
|
||||
var username: String?
|
||||
var password: String?
|
||||
var server: String?
|
||||
class AccountModel: ObservableObject {
|
||||
@Published private(set) var id: UUID?
|
||||
@Published private(set) var isLoggedIn: Bool = false
|
||||
@Published private(set) var isLoggingIn: Bool = false
|
||||
@Published var username: String = ""
|
||||
@Published var password: String = ""
|
||||
@Published var server: String = ""
|
||||
|
||||
mutating func login(
|
||||
func login(
|
||||
to server: String,
|
||||
as username: String,
|
||||
password: String,
|
||||
completion: @escaping (Result<UUID, AccountError>) -> Void
|
||||
) {
|
||||
self.isLoggingIn = true
|
||||
let result: Result<UUID, AccountError>
|
||||
|
||||
if server != validServer {
|
||||
@ -34,10 +37,26 @@ struct AccountModel {
|
||||
#if DEBUG
|
||||
// Delay to simulate async network call
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
|
||||
self.isLoggingIn = false
|
||||
do {
|
||||
_ = try result.get()
|
||||
self.isLoggedIn = true
|
||||
} catch {
|
||||
self.isLoggedIn = false
|
||||
}
|
||||
completion(result)
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
func logout() {
|
||||
id = nil
|
||||
isLoggedIn = false
|
||||
isLoggingIn = false
|
||||
username = ""
|
||||
password = ""
|
||||
server = ""
|
||||
}
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
|
@ -1,25 +1,25 @@
|
||||
import SwiftUI
|
||||
|
||||
struct AccountView: View {
|
||||
@State private var accountModel = AccountModel()
|
||||
@State private var isLoggingIn: Bool = false
|
||||
@State private var isLoggedIn: Bool = false
|
||||
@ObservedObject var account: AccountModel
|
||||
|
||||
var body: some View {
|
||||
if isLoggedIn {
|
||||
if account.isLoggedIn {
|
||||
HStack {
|
||||
Spacer()
|
||||
AccountLogoutView(accountModel: $accountModel, isLoggedIn: $isLoggedIn, isLoggingIn: $isLoggingIn)
|
||||
AccountLogoutView(account: account)
|
||||
Spacer()
|
||||
}
|
||||
.padding()
|
||||
} else {
|
||||
AccountLoginView(accountModel: $accountModel, isLoggedIn: $isLoggedIn, isLoggingIn: $isLoggingIn)
|
||||
AccountLoginView(account: account)
|
||||
.padding()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct AccountLogin_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
AccountView()
|
||||
AccountView(account: AccountModel())
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ import SwiftUI
|
||||
struct ContentView: View {
|
||||
@ObservedObject var postStore: PostStore
|
||||
@ObservedObject var preferences: PreferencesModel
|
||||
@ObservedObject var account: AccountModel
|
||||
|
||||
var body: some View {
|
||||
NavigationView {
|
||||
@ -15,11 +16,12 @@ struct ContentView: View {
|
||||
}
|
||||
.environmentObject(postStore)
|
||||
.environmentObject(preferences)
|
||||
.environmentObject(account)
|
||||
}
|
||||
}
|
||||
|
||||
struct ContentView_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
ContentView(postStore: testPostStore, preferences: PreferencesModel())
|
||||
ContentView(postStore: testPostStore, preferences: PreferencesModel(), account: AccountModel())
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ import SwiftUI
|
||||
@main
|
||||
struct WriteFreely_MultiPlatformApp: App {
|
||||
@StateObject private var preferences = PreferencesModel()
|
||||
@StateObject private var account = AccountModel()
|
||||
|
||||
#if DEBUG
|
||||
@StateObject private var store = testPostStore
|
||||
@ -12,7 +13,7 @@ struct WriteFreely_MultiPlatformApp: App {
|
||||
|
||||
var body: some Scene {
|
||||
WindowGroup {
|
||||
ContentView(postStore: store, preferences: preferences)
|
||||
ContentView(postStore: store, preferences: preferences, account: account)
|
||||
.preferredColorScheme(preferences.preferredColorScheme)
|
||||
}
|
||||
|
||||
@ -21,6 +22,7 @@ struct WriteFreely_MultiPlatformApp: App {
|
||||
SettingsView(preferences: preferences)
|
||||
.frame(minWidth: 300, maxWidth: 300, minHeight: 200, maxHeight: 200)
|
||||
.padding()
|
||||
.preferredColorScheme(preferences.preferredColorScheme)
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ import SwiftUI
|
||||
|
||||
struct SettingsView: View {
|
||||
@EnvironmentObject var preferences: PreferencesModel
|
||||
@EnvironmentObject var account: AccountModel
|
||||
|
||||
@Binding var isPresented: Bool
|
||||
|
||||
@ -10,7 +11,7 @@ struct SettingsView: View {
|
||||
SettingsHeaderView(isPresented: $isPresented)
|
||||
Form {
|
||||
Section(header: Text("Login Details")) {
|
||||
AccountView()
|
||||
AccountView(account: account)
|
||||
}
|
||||
Section(header: Text("Appearance")) {
|
||||
PreferencesView(preferences: preferences)
|
||||
|
Loading…
Reference in New Issue
Block a user