Преглед изворни кода

Refactor login/logout to implement WriteFreely package

pull/7/head
Angelo Stavrow пре 3 година
родитељ
комит
0c20fea0e6
No known key found for this signature in database GPG Key ID: 1A49C7064E060EEE
8 измењених фајлова са 91 додато и 89 уклоњено
  1. +17
    -15
      Shared/Account/AccountLoginView.swift
  2. +6
    -5
      Shared/Account/AccountLogoutView.swift
  3. +11
    -58
      Shared/Account/AccountModel.swift
  4. +6
    -5
      Shared/Account/AccountView.swift
  5. +44
    -1
      Shared/Models/WriteFreelyModel.swift
  6. +2
    -1
      Shared/WriteFreely_MultiPlatformApp.swift
  7. +1
    -1
      iOS/Settings/SettingsView.swift
  8. +4
    -3
      macOS/Settings/MacAccountView.swift

+ 17
- 15
Shared/Account/AccountLoginView.swift Прегледај датотеку

@@ -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())
}
}

+ 6
- 5
Shared/Account/AccountLogoutView.swift Прегледај датотеку

@@ -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())
}
}

+ 11
- 58
Shared/Account/AccountModel.swift Прегледај датотеку

@@ -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

+ 6
- 5
Shared/Account/AccountView.swift Прегледај датотеку

@@ -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())
}
}

+ 44
- 1
Shared/Models/WriteFreelyModel.swift Прегледај датотеку

@@ -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)
}
}
}

+ 2
- 1
Shared/WriteFreely_MultiPlatformApp.swift Прегледај датотеку

@@ -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")


+ 1
- 1
iOS/Settings/SettingsView.swift Прегледај датотеку

@@ -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)


+ 4
- 3
macOS/Settings/MacAccountView.swift Прегледај датотеку

@@ -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…
Откажи
Сачувај