Page MenuHomeMusing Studio

No OneTemporary

diff --git a/Shared/Account/AccountLoginView.swift b/Shared/Account/AccountLoginView.swift
index cab3827..dfaeb99 100644
--- a/Shared/Account/AccountLoginView.swift
+++ b/Shared/Account/AccountLoginView.swift
@@ -1,104 +1,106 @@
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()
}
}
.alert(isPresented: $isShowingAlert) {
Alert(
title: Text("Error Logging In"),
message: Text(alertMessage),
dismissButton: .default(Text("OK"))
)
}
}
func loginHandler(result: Result<UUID, AccountError>) {
do {
_ = try result.get()
} catch AccountError.serverNotFound {
alertMessage = """
The server could not be found. Please check that you've entered the information correctly and try again.
"""
isShowingAlert = true
} catch AccountError.invalidPassword {
alertMessage = """
Invalid password. Please check that you've entered your password correctly and try logging in again.
"""
isShowingAlert = true
} catch AccountError.usernameNotFound {
alertMessage = """
Username not found. Did you use your email address by mistake?
"""
isShowingAlert = true
} catch {
alertMessage = "An unknown error occurred. Please try again."
isShowingAlert = true
}
}
}
struct AccountLoginView_Previews: PreviewProvider {
static var previews: some View {
- AccountLoginView(account: AccountModel())
+ AccountLoginView()
+ .environmentObject(WriteFreelyModel())
}
}
diff --git a/Shared/Account/AccountLogoutView.swift b/Shared/Account/AccountLogoutView.swift
index bc84b50..16b9fd0 100644
--- a/Shared/Account/AccountLogoutView.swift
+++ b/Shared/Account/AccountLogoutView.swift
@@ -1,29 +1,30 @@
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: {
Text("Logout")
})
}
}
func logoutHandler() {
- account.logout()
+ model.logout()
}
}
struct AccountLogoutView_Previews: PreviewProvider {
static var previews: some View {
- AccountLogoutView(account: AccountModel())
+ AccountLogoutView()
+ .environmentObject(WriteFreelyModel())
}
}
diff --git a/Shared/Account/AccountModel.swift b/Shared/Account/AccountModel.swift
index 9d26b3c..c1ee3c8 100644
--- a/Shared/Account/AccountModel.swift
+++ b/Shared/Account/AccountModel.swift
@@ -1,71 +1,24 @@
import Foundation
+import WriteFreely
enum AccountError: Error {
case invalidPassword
case usernameNotFound
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
diff --git a/Shared/Account/AccountView.swift b/Shared/Account/AccountView.swift
index a0382d7..64f23a5 100644
--- a/Shared/Account/AccountView.swift
+++ b/Shared/Account/AccountView.swift
@@ -1,25 +1,26 @@
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()
}
}
}
struct AccountLogin_Previews: PreviewProvider {
static var previews: some View {
- AccountView(account: AccountModel())
+ AccountView()
+ .environmentObject(WriteFreelyModel())
}
}
diff --git a/Shared/Models/WriteFreelyModel.swift b/Shared/Models/WriteFreelyModel.swift
index e84d65c..d926ee1 100644
--- a/Shared/Models/WriteFreelyModel.swift
+++ b/Shared/Models/WriteFreelyModel.swift
@@ -1,22 +1,65 @@
import Foundation
+import WriteFreely
// MARK: - WriteFreelyModel
class WriteFreelyModel: ObservableObject {
@Published var account = AccountModel()
@Published var preferences = PreferencesModel()
@Published var store = PostStore()
@Published var post: Post?
+ @Published var isLoggingIn: Bool = false
+
+ private var client: WFClient?
init() {
#if DEBUG
for post in testPostData { store.add(post) }
#endif
}
}
// 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)
+ }
+ }
}
diff --git a/Shared/WriteFreely_MultiPlatformApp.swift b/Shared/WriteFreely_MultiPlatformApp.swift
index 804f6b1..63c1182 100644
--- a/Shared/WriteFreely_MultiPlatformApp.swift
+++ b/Shared/WriteFreely_MultiPlatformApp.swift
@@ -1,40 +1,41 @@
import SwiftUI
@main
struct WriteFreely_MultiPlatformApp: App {
@StateObject private var model = WriteFreelyModel()
#if os(macOS)
@State private var selectedTab = 0
#endif
var body: some Scene {
WindowGroup {
ContentView()
.environmentObject(model)
// .preferredColorScheme(preferences.selectedColorScheme) // See PreferencesModel for info.
}
#if os(macOS)
Settings {
TabView(selection: $selectedTab) {
- MacAccountView(account: model.account)
+ MacAccountView()
+ .environmentObject(model)
.tabItem {
Image(systemName: "person.crop.circle")
Text("Account")
}
.tag(0)
MacPreferencesView(preferences: model.preferences)
.tabItem {
Image(systemName: "gear")
Text("Preferences")
}
.tag(1)
}
.frame(minWidth: 300, maxWidth: 300, minHeight: 200, maxHeight: 200)
.padding()
// .preferredColorScheme(preferences.selectedColorScheme) // See PreferencesModel for info.
}
#endif
}
}
diff --git a/iOS/Settings/SettingsView.swift b/iOS/Settings/SettingsView.swift
index 0de3734..c4718c5 100644
--- a/iOS/Settings/SettingsView.swift
+++ b/iOS/Settings/SettingsView.swift
@@ -1,29 +1,29 @@
import SwiftUI
struct SettingsView: View {
@EnvironmentObject var model: WriteFreelyModel
@Binding var isPresented: Bool
var body: some View {
VStack {
SettingsHeaderView(isPresented: $isPresented)
Form {
Section(header: Text("Login Details")) {
- AccountView(account: model.account)
+ AccountView()
}
Section(header: Text("Appearance")) {
PreferencesView(preferences: model.preferences)
}
}
}
// .preferredColorScheme(preferences.selectedColorScheme) // See PreferencesModel for info.
}
}
struct SettingsView_Previews: PreviewProvider {
static var previews: some View {
SettingsView(isPresented: .constant(true))
.environmentObject(WriteFreelyModel())
}
}
diff --git a/macOS/Settings/MacAccountView.swift b/macOS/Settings/MacAccountView.swift
index b37b6da..e51dfd7 100644
--- a/macOS/Settings/MacAccountView.swift
+++ b/macOS/Settings/MacAccountView.swift
@@ -1,19 +1,20 @@
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()
}
}
}
}
struct MacAccountView_Previews: PreviewProvider {
static var previews: some View {
- MacAccountView(account: AccountModel())
+ MacAccountView()
+ .environmentObject(WriteFreelyModel())
}
}

File Metadata

Mime Type
text/x-diff
Expires
Thu, Mar 6, 10:41 AM (1 d, 9 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
3168322

Event Timeline