Page MenuHomeMusing Studio

No OneTemporary

diff --git a/Shared/Account/AccountLoginView.swift b/Shared/Account/AccountLoginView.swift
index fc360ab..274eb45 100644
--- a/Shared/Account/AccountLoginView.swift
+++ b/Shared/Account/AccountLoginView.swift
@@ -1,125 +1,106 @@
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) {
Alert(
title: Text("Error Logging In"),
message: Text(alertMessage),
dismissButton: .default(Text("OK"))
)
}
}
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
}
}
}
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())
}
}
diff --git a/Shared/Account/AccountLogoutView.swift b/Shared/Account/AccountLogoutView.swift
index e59c46d..bc84b50 100644
--- a/Shared/Account/AccountLogoutView.swift
+++ b/Shared/Account/AccountLogoutView.swift
@@ -1,36 +1,29 @@
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: {
Text("Logout")
})
}
}
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())
}
}
diff --git a/Shared/Account/AccountModel.swift b/Shared/Account/AccountModel.swift
index e460f48..bde756f 100644
--- a/Shared/Account/AccountModel.swift
+++ b/Shared/Account/AccountModel.swift
@@ -1,49 +1,68 @@
import Foundation
enum AccountError: Error {
case invalidCredentials
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 {
result = .failure(.serverNotFound)
} else if username == validCredentials["username"] && password == validCredentials["password"] {
self.id = UUID()
self.username = username
self.password = password
self.server = server
result = .success(self.id!)
} else {
result = .failure(.invalidCredentials)
}
#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
let validCredentials = [
"username": "name@example.com",
"password": "12345"
]
let validServer = "https://test.server.url"
#endif
diff --git a/Shared/Account/AccountView.swift b/Shared/Account/AccountView.swift
index ef838c3..a0382d7 100644
--- a/Shared/Account/AccountView.swift
+++ b/Shared/Account/AccountView.swift
@@ -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())
}
}
diff --git a/Shared/Navigation/ContentView.swift b/Shared/Navigation/ContentView.swift
index b404072..c92177a 100644
--- a/Shared/Navigation/ContentView.swift
+++ b/Shared/Navigation/ContentView.swift
@@ -1,25 +1,27 @@
import SwiftUI
struct ContentView: View {
@ObservedObject var postStore: PostStore
@ObservedObject var preferences: PreferencesModel
+ @ObservedObject var account: AccountModel
var body: some View {
NavigationView {
SidebarView()
PostList(selectedCollection: allPostsCollection)
Text("Select a post, or create a new draft.")
.foregroundColor(.secondary)
}
.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())
}
}
diff --git a/Shared/WriteFreely_MultiPlatformApp.swift b/Shared/WriteFreely_MultiPlatformApp.swift
index feb4993..26834e3 100644
--- a/Shared/WriteFreely_MultiPlatformApp.swift
+++ b/Shared/WriteFreely_MultiPlatformApp.swift
@@ -1,27 +1,29 @@
import SwiftUI
@main
struct WriteFreely_MultiPlatformApp: App {
@StateObject private var preferences = PreferencesModel()
+ @StateObject private var account = AccountModel()
#if DEBUG
@StateObject private var store = testPostStore
#else
@StateObject private var store = PostStore()
#endif
var body: some Scene {
WindowGroup {
- ContentView(postStore: store, preferences: preferences)
+ ContentView(postStore: store, preferences: preferences, account: account)
.preferredColorScheme(preferences.preferredColorScheme)
}
#if os(macOS)
Settings {
SettingsView(preferences: preferences)
.frame(minWidth: 300, maxWidth: 300, minHeight: 200, maxHeight: 200)
.padding()
+ .preferredColorScheme(preferences.preferredColorScheme)
}
#endif
}
}
diff --git a/iOS/Settings/SettingsView.swift b/iOS/Settings/SettingsView.swift
index 50ad760..a9c1d26 100644
--- a/iOS/Settings/SettingsView.swift
+++ b/iOS/Settings/SettingsView.swift
@@ -1,28 +1,29 @@
import SwiftUI
struct SettingsView: View {
@EnvironmentObject var preferences: PreferencesModel
+ @EnvironmentObject var account: AccountModel
@Binding var isPresented: Bool
var body: some View {
VStack {
SettingsHeaderView(isPresented: $isPresented)
Form {
Section(header: Text("Login Details")) {
- AccountView()
+ AccountView(account: account)
}
Section(header: Text("Appearance")) {
PreferencesView(preferences: preferences)
}
}
}
.preferredColorScheme(preferences.preferredColorScheme)
}
}
struct SettingsView_Previews: PreviewProvider {
static var previews: some View {
SettingsView(isPresented: .constant(true))
}
}

File Metadata

Mime Type
text/x-diff
Expires
Fri, May 16, 1:13 AM (1 d, 8 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
3239947

Event Timeline