mirror of
https://github.com/writeas/writefreely-swiftui-multiplatform.git
synced 2024-11-15 01:11:02 +00:00
Refactor login/logout to implement WriteFreely package
This commit is contained in:
parent
d402ccd472
commit
0c20fea0e6
@ -1,65 +1,66 @@
|
||||
import SwiftUI
|
||||
|
||||
struct AccountLoginView: View {
|
||||
@ObservedObject var account: AccountModel
|
||||
@EnvironmentObject var model: WriteFreelyModel
|
||||
|
||||
@State private var isShowingAlert: Bool = false
|
||||
@State private var alertMessage: String = ""
|
||||
|
||||
@State private var username: String = ""
|
||||
@State private var password: String = ""
|
||||
@State private var server: String = ""
|
||||
var body: some View {
|
||||
VStack {
|
||||
HStack {
|
||||
Image(systemName: "person.circle")
|
||||
.foregroundColor(.gray)
|
||||
#if os(iOS)
|
||||
TextField("Username", text: $account.username)
|
||||
TextField("Username", text: $username)
|
||||
.autocapitalization(.none)
|
||||
.disableAutocorrection(true)
|
||||
.textFieldStyle(RoundedBorderTextFieldStyle())
|
||||
#else
|
||||
TextField("Username", text: $account.username)
|
||||
TextField("Username", text: $username)
|
||||
#endif
|
||||
}
|
||||
HStack {
|
||||
Image(systemName: "lock.circle")
|
||||
.foregroundColor(.gray)
|
||||
#if os(iOS)
|
||||
SecureField("Password", text: $account.password)
|
||||
SecureField("Password", text: $password)
|
||||
.autocapitalization(.none)
|
||||
.disableAutocorrection(true)
|
||||
.textFieldStyle(RoundedBorderTextFieldStyle())
|
||||
#else
|
||||
SecureField("Password", text: $account.password)
|
||||
SecureField("Password", text: $password)
|
||||
#endif
|
||||
}
|
||||
HStack {
|
||||
Image(systemName: "link.circle")
|
||||
.foregroundColor(.gray)
|
||||
#if os(iOS)
|
||||
TextField("Server URL", text: $account.server)
|
||||
TextField("Server URL", text: $server)
|
||||
.keyboardType(.URL)
|
||||
.autocapitalization(.none)
|
||||
.disableAutocorrection(true)
|
||||
.textFieldStyle(RoundedBorderTextFieldStyle())
|
||||
#else
|
||||
TextField("Server URL", text: $account.server)
|
||||
TextField("Server URL", text: $server)
|
||||
#endif
|
||||
}
|
||||
Spacer()
|
||||
if account.isLoggingIn {
|
||||
if model.isLoggingIn {
|
||||
ProgressView("Logging in...")
|
||||
.padding()
|
||||
} else {
|
||||
Button(action: {
|
||||
account.login(
|
||||
to: account.server,
|
||||
as: account.username, password: account.password,
|
||||
completion: loginHandler
|
||||
model.login(
|
||||
to: URL(string: server)!,
|
||||
as: username, password: password
|
||||
)
|
||||
}, label: {
|
||||
Text("Login")
|
||||
})
|
||||
.disabled(account.isLoggedIn)
|
||||
.disabled(model.account.isLoggedIn)
|
||||
.padding()
|
||||
}
|
||||
}
|
||||
@ -99,6 +100,7 @@ struct AccountLoginView: View {
|
||||
|
||||
struct AccountLoginView_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
AccountLoginView(account: AccountModel())
|
||||
AccountLoginView()
|
||||
.environmentObject(WriteFreelyModel())
|
||||
}
|
||||
}
|
||||
|
@ -1,14 +1,14 @@
|
||||
import SwiftUI
|
||||
|
||||
struct AccountLogoutView: View {
|
||||
@ObservedObject var account: AccountModel
|
||||
@EnvironmentObject var model: WriteFreelyModel
|
||||
|
||||
var body: some View {
|
||||
VStack {
|
||||
Spacer()
|
||||
VStack {
|
||||
Text("Logged in as \(account.username)")
|
||||
Text("on \(account.server)")
|
||||
Text("Logged in as \(model.account.user?.username ?? "Anonymous")")
|
||||
Text("on \(model.account.server)")
|
||||
}
|
||||
Spacer()
|
||||
Button(action: logoutHandler, label: {
|
||||
@ -18,12 +18,13 @@ struct AccountLogoutView: View {
|
||||
}
|
||||
|
||||
func logoutHandler() {
|
||||
account.logout()
|
||||
model.logout()
|
||||
}
|
||||
}
|
||||
|
||||
struct AccountLogoutView_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
AccountLogoutView(account: AccountModel())
|
||||
AccountLogoutView()
|
||||
.environmentObject(WriteFreelyModel())
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
import Foundation
|
||||
import WriteFreely
|
||||
|
||||
enum AccountError: Error {
|
||||
case invalidPassword
|
||||
@ -6,66 +7,18 @@ enum AccountError: Error {
|
||||
case serverNotFound
|
||||
}
|
||||
|
||||
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 = ""
|
||||
struct AccountModel {
|
||||
var server: String = ""
|
||||
private(set) var user: WFUser?
|
||||
private(set) var isLoggedIn: Bool = false
|
||||
|
||||
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 {
|
||||
result = .failure(.serverNotFound)
|
||||
} else if username != validCredentials["username"] {
|
||||
result = .failure(.usernameNotFound)
|
||||
} else if password != validCredentials["password"] {
|
||||
result = .failure(.invalidPassword)
|
||||
} else {
|
||||
self.id = UUID()
|
||||
self.username = username
|
||||
self.password = password
|
||||
self.server = server
|
||||
result = .success(self.id!)
|
||||
}
|
||||
|
||||
#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
|
||||
mutating func login(_ user: WFUser) {
|
||||
self.user = user
|
||||
self.isLoggedIn = true
|
||||
}
|
||||
|
||||
func logout() {
|
||||
id = nil
|
||||
isLoggedIn = false
|
||||
isLoggingIn = false
|
||||
username = ""
|
||||
password = ""
|
||||
server = ""
|
||||
mutating func logout() {
|
||||
self.user = nil
|
||||
self.isLoggedIn = false
|
||||
}
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
let validCredentials = [
|
||||
"username": "test-writer",
|
||||
"password": "12345"
|
||||
]
|
||||
let validServer = "https://test.server.url"
|
||||
#endif
|
||||
|
@ -1,18 +1,18 @@
|
||||
import SwiftUI
|
||||
|
||||
struct AccountView: View {
|
||||
@ObservedObject var account: AccountModel
|
||||
@EnvironmentObject var model: WriteFreelyModel
|
||||
|
||||
var body: some View {
|
||||
if account.isLoggedIn {
|
||||
if model.account.isLoggedIn {
|
||||
HStack {
|
||||
Spacer()
|
||||
AccountLogoutView(account: account)
|
||||
AccountLogoutView()
|
||||
Spacer()
|
||||
}
|
||||
.padding()
|
||||
} else {
|
||||
AccountLoginView(account: account)
|
||||
AccountLoginView()
|
||||
.padding()
|
||||
}
|
||||
}
|
||||
@ -20,6 +20,7 @@ struct AccountView: View {
|
||||
|
||||
struct AccountLogin_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
AccountView(account: AccountModel())
|
||||
AccountView()
|
||||
.environmentObject(WriteFreelyModel())
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
import Foundation
|
||||
import WriteFreely
|
||||
|
||||
// MARK: - WriteFreelyModel
|
||||
|
||||
@ -7,6 +8,9 @@ class WriteFreelyModel: ObservableObject {
|
||||
@Published var preferences = PreferencesModel()
|
||||
@Published var store = PostStore()
|
||||
@Published var post: Post?
|
||||
@Published var isLoggingIn: Bool = false
|
||||
|
||||
private var client: WFClient?
|
||||
|
||||
init() {
|
||||
#if DEBUG
|
||||
@ -18,5 +22,44 @@ class WriteFreelyModel: ObservableObject {
|
||||
// MARK: - WriteFreelyModel API
|
||||
|
||||
extension WriteFreelyModel {
|
||||
// API goes here
|
||||
func login(
|
||||
to server: URL,
|
||||
as username: String,
|
||||
password: String
|
||||
) {
|
||||
isLoggingIn = true
|
||||
account.server = server.absoluteString
|
||||
client = WFClient(for: server)
|
||||
client?.login(username: username, password: password, completion: loginHandler)
|
||||
}
|
||||
|
||||
func logout () {
|
||||
guard let loggedInClient = client else { return }
|
||||
loggedInClient.logout(completion: logoutHandler)
|
||||
}
|
||||
}
|
||||
|
||||
private extension WriteFreelyModel {
|
||||
func loginHandler(result: Result<WFUser, Error>) {
|
||||
isLoggingIn = false
|
||||
do {
|
||||
let user = try result.get()
|
||||
account.login(user)
|
||||
dump(user)
|
||||
} catch {
|
||||
dump(error)
|
||||
}
|
||||
}
|
||||
|
||||
func logoutHandler(result: Result<Bool, Error>) {
|
||||
do {
|
||||
let loggedOut = try result.get()
|
||||
if loggedOut {
|
||||
client = nil
|
||||
account.logout()
|
||||
}
|
||||
} catch {
|
||||
dump(error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -18,7 +18,8 @@ struct WriteFreely_MultiPlatformApp: App {
|
||||
#if os(macOS)
|
||||
Settings {
|
||||
TabView(selection: $selectedTab) {
|
||||
MacAccountView(account: model.account)
|
||||
MacAccountView()
|
||||
.environmentObject(model)
|
||||
.tabItem {
|
||||
Image(systemName: "person.crop.circle")
|
||||
Text("Account")
|
||||
|
@ -10,7 +10,7 @@ struct SettingsView: View {
|
||||
SettingsHeaderView(isPresented: $isPresented)
|
||||
Form {
|
||||
Section(header: Text("Login Details")) {
|
||||
AccountView(account: model.account)
|
||||
AccountView()
|
||||
}
|
||||
Section(header: Text("Appearance")) {
|
||||
PreferencesView(preferences: model.preferences)
|
||||
|
@ -1,12 +1,12 @@
|
||||
import SwiftUI
|
||||
|
||||
struct MacAccountView: View {
|
||||
@ObservedObject var account: AccountModel
|
||||
@EnvironmentObject var model: WriteFreelyModel
|
||||
|
||||
var body: some View {
|
||||
Form {
|
||||
Section(header: Text("Login Details")) {
|
||||
AccountView(account: account)
|
||||
AccountView()
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -14,6 +14,7 @@ struct MacAccountView: View {
|
||||
|
||||
struct MacAccountView_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
MacAccountView(account: AccountModel())
|
||||
MacAccountView()
|
||||
.environmentObject(WriteFreelyModel())
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user