2020-08-18 18:06:02 +00:00
|
|
|
|
import Foundation
|
2020-08-18 21:20:16 +00:00
|
|
|
|
import WriteFreely
|
2020-08-24 18:38:35 +00:00
|
|
|
|
import Security
|
2020-09-16 20:39:01 +00:00
|
|
|
|
import Network
|
2020-08-18 18:06:02 +00:00
|
|
|
|
|
|
|
|
|
// MARK: - WriteFreelyModel
|
|
|
|
|
|
2021-02-01 19:27:15 +00:00
|
|
|
|
final class WriteFreelyModel: ObservableObject {
|
2022-05-09 12:55:43 +00:00
|
|
|
|
|
|
|
|
|
// MARK: - Models
|
2020-08-18 18:06:02 +00:00
|
|
|
|
@Published var account = AccountModel()
|
|
|
|
|
@Published var preferences = PreferencesModel()
|
2020-09-09 14:56:23 +00:00
|
|
|
|
@Published var posts = PostListModel()
|
2020-09-23 19:36:54 +00:00
|
|
|
|
@Published var editor = PostEditorModel()
|
2021-02-10 20:01:23 +00:00
|
|
|
|
|
2022-05-09 12:55:43 +00:00
|
|
|
|
// MARK: - Error handling
|
|
|
|
|
@Published var hasError: Bool = false
|
2022-05-01 16:06:36 +00:00
|
|
|
|
var currentError: Error? {
|
|
|
|
|
didSet {
|
2023-10-23 21:15:41 +00:00
|
|
|
|
if let localizedErrorDescription = currentError?.localizedDescription,
|
|
|
|
|
localizedErrorDescription == "The operation couldn’t be completed. (WriteFreely.WFError error -2.)",
|
|
|
|
|
!hasNetworkConnection {
|
|
|
|
|
#if DEBUG
|
|
|
|
|
print("⚠️ currentError is WriteFreely.WFError -2 and there is no network connection.")
|
|
|
|
|
#endif
|
|
|
|
|
currentError = NetworkError.noConnectionError
|
|
|
|
|
}
|
2022-05-01 16:06:36 +00:00
|
|
|
|
#if DEBUG
|
2022-05-08 14:18:21 +00:00
|
|
|
|
print("⚠️ currentError -> didSet \(currentError?.localizedDescription ?? "nil")")
|
2022-05-01 16:06:36 +00:00
|
|
|
|
print(" > hasError was: \(self.hasError)")
|
|
|
|
|
#endif
|
|
|
|
|
DispatchQueue.main.async {
|
|
|
|
|
#if DEBUG
|
|
|
|
|
print(" > self.currentError != nil: \(self.currentError != nil)")
|
|
|
|
|
#endif
|
|
|
|
|
self.hasError = self.currentError != nil
|
|
|
|
|
#if DEBUG
|
|
|
|
|
print(" > hasError is now: \(self.hasError)")
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-09-25 15:00:51 +00:00
|
|
|
|
|
2022-05-09 12:55:43 +00:00
|
|
|
|
// MARK: - State
|
|
|
|
|
@Published var isLoggingIn: Bool = false
|
|
|
|
|
@Published var isProcessingRequest: Bool = false
|
|
|
|
|
@Published var hasNetworkConnection: Bool = true
|
|
|
|
|
@Published var selectedPost: WFAPost?
|
|
|
|
|
@Published var selectedCollection: WFACollection?
|
|
|
|
|
@Published var showAllPosts: Bool = true
|
|
|
|
|
@Published var isPresentingDeleteAlert: Bool = false
|
|
|
|
|
@Published var postToDelete: WFAPost?
|
|
|
|
|
#if os(iOS)
|
|
|
|
|
@Published var isPresentingSettingsView: Bool = false
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
static var shared = WriteFreelyModel()
|
|
|
|
|
|
2020-09-18 19:33:04 +00:00
|
|
|
|
// swiftlint:disable line_length
|
2020-09-16 15:34:11 +00:00
|
|
|
|
let helpURL = URL(string: "https://discuss.write.as/c/help/5")!
|
2020-10-21 20:54:25 +00:00
|
|
|
|
let howToURL = URL(string: "https://discuss.write.as/t/using-the-writefreely-ios-app/1946")!
|
2021-01-04 19:25:02 +00:00
|
|
|
|
let reviewURL = URL(string: "https://apps.apple.com/app/id1531530896?action=write-review")!
|
2020-09-18 19:33:04 +00:00
|
|
|
|
let licensesURL = URL(string: "https://github.com/writeas/writefreely-swiftui-multiplatform/tree/main/Shared/Resources/Licenses")!
|
|
|
|
|
// swiftlint:enable line_length
|
2020-09-16 15:34:11 +00:00
|
|
|
|
|
2021-02-01 18:46:25 +00:00
|
|
|
|
internal var client: WFClient?
|
2021-11-05 18:18:36 +00:00
|
|
|
|
private let defaults = UserDefaults.shared
|
2020-09-16 20:39:01 +00:00
|
|
|
|
private let monitor = NWPathMonitor()
|
|
|
|
|
private let queue = DispatchQueue(label: "NetworkMonitor")
|
2021-02-01 18:46:25 +00:00
|
|
|
|
internal var postToUpdate: WFAPost?
|
2020-08-18 18:06:02 +00:00
|
|
|
|
|
|
|
|
|
init() {
|
2020-08-24 14:12:48 +00:00
|
|
|
|
DispatchQueue.main.async {
|
2021-11-19 20:41:54 +00:00
|
|
|
|
self.preferences.appearance = self.defaults.integer(forKey: WFDefaults.colorSchemeIntegerKey)
|
|
|
|
|
self.preferences.font = self.defaults.integer(forKey: WFDefaults.defaultFontIntegerKey)
|
2020-08-24 20:53:01 +00:00
|
|
|
|
self.account.restoreState()
|
2023-10-23 21:15:41 +00:00
|
|
|
|
|
|
|
|
|
// Set the appearance
|
|
|
|
|
self.preferences.updateAppearance(to: Appearance(rawValue: self.preferences.appearance) ?? .system)
|
|
|
|
|
|
2020-08-31 15:24:38 +00:00
|
|
|
|
if self.account.isLoggedIn {
|
|
|
|
|
guard let serverURL = URL(string: self.account.server) else {
|
2022-05-01 16:06:36 +00:00
|
|
|
|
self.currentError = AccountError.invalidServerURL
|
2020-08-31 15:24:38 +00:00
|
|
|
|
return
|
|
|
|
|
}
|
2021-08-20 21:13:41 +00:00
|
|
|
|
do {
|
|
|
|
|
guard let token = try self.fetchTokenFromKeychain(
|
|
|
|
|
username: self.account.username,
|
|
|
|
|
server: self.account.server
|
|
|
|
|
) else {
|
2022-05-01 16:06:36 +00:00
|
|
|
|
self.currentError = KeychainError.couldNotFetchAccessToken
|
2021-08-20 21:13:41 +00:00
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
self.account.login(WFUser(token: token, username: self.account.username))
|
|
|
|
|
self.client = WFClient(for: serverURL)
|
|
|
|
|
self.client?.user = self.account.user
|
|
|
|
|
self.fetchUserCollections()
|
|
|
|
|
self.fetchUserPosts()
|
|
|
|
|
} catch {
|
2022-05-01 16:06:36 +00:00
|
|
|
|
self.currentError = KeychainError.couldNotFetchAccessToken
|
2022-05-23 19:12:33 +00:00
|
|
|
|
return
|
2020-08-31 15:24:38 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2020-08-24 20:53:01 +00:00
|
|
|
|
}
|
2020-09-16 20:39:01 +00:00
|
|
|
|
|
|
|
|
|
monitor.pathUpdateHandler = { path in
|
|
|
|
|
DispatchQueue.main.async {
|
|
|
|
|
self.hasNetworkConnection = path.status == .satisfied
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
monitor.start(queue: queue)
|
2020-08-18 18:06:02 +00:00
|
|
|
|
}
|
|
|
|
|
}
|