Page MenuHomeMusing Studio

No OneTemporary

diff --git a/Shared/Account/AccountModel.swift b/Shared/Account/AccountModel.swift
index 4ce81b2..25683a5 100644
--- a/Shared/Account/AccountModel.swift
+++ b/Shared/Account/AccountModel.swift
@@ -1,66 +1,62 @@
-import Foundation
+import SwiftUI
import WriteFreely
enum AccountError: Error {
case invalidPassword
case usernameNotFound
case serverNotFound
}
extension AccountError: LocalizedError {
public var errorDescription: String? {
switch self {
case .serverNotFound:
return NSLocalizedString(
"The server could not be found. Please check the information you've entered and try again.",
comment: ""
)
case .invalidPassword:
return NSLocalizedString(
"Invalid password. Please check that you've entered your password correctly and try logging in again.",
comment: ""
)
case .usernameNotFound:
return NSLocalizedString(
"Username not found. Did you use your email address by mistake?",
comment: ""
)
}
}
}
struct AccountModel {
+ @AppStorage("isLoggedIn") var isLoggedIn: Bool = false
private let defaults = UserDefaults.standard
- let isLoggedInFlag = "isLoggedInFlag"
let usernameStringKey = "usernameStringKey"
let serverStringKey = "serverStringKey"
var server: String = ""
var username: String = ""
private(set) var user: WFUser?
- private(set) var isLoggedIn: Bool = false
mutating func login(_ user: WFUser) {
self.user = user
self.username = user.username ?? ""
self.isLoggedIn = true
- defaults.set(true, forKey: isLoggedInFlag)
defaults.set(user.username, forKey: usernameStringKey)
defaults.set(server, forKey: serverStringKey)
}
mutating func logout() {
self.user = nil
self.isLoggedIn = false
- defaults.set(false, forKey: isLoggedInFlag)
defaults.removeObject(forKey: usernameStringKey)
defaults.removeObject(forKey: serverStringKey)
}
mutating func restoreState() {
- isLoggedIn = defaults.bool(forKey: isLoggedInFlag)
server = defaults.string(forKey: serverStringKey) ?? ""
username = defaults.string(forKey: usernameStringKey) ?? ""
}
}
diff --git a/Shared/Navigation/ContentView.swift b/Shared/Navigation/ContentView.swift
index f270ca8..bc5e6ce 100644
--- a/Shared/Navigation/ContentView.swift
+++ b/Shared/Navigation/ContentView.swift
@@ -1,144 +1,145 @@
import SwiftUI
struct ContentView: View {
@EnvironmentObject var model: WriteFreelyModel
@Binding var sidebarIsHidden: Bool
var body: some View {
NavigationView {
#if os(macOS)
SidebarView()
.toolbar {
Button(
action: {
NSApp.keyWindow?.contentViewController?.tryToPerform(
#selector(NSSplitViewController.toggleSidebar(_:)), with: nil
)
withAnimation { self.sidebarIsHidden.toggle() }
},
label: { Image(systemName: "sidebar.left") }
)
Spacer()
Button(action: {
withAnimation {
self.model.selectedPost = nil
}
let managedPost = WFAPost(context: LocalStorageManager.persistentContainer.viewContext)
managedPost.createdDate = Date()
managedPost.title = ""
managedPost.body = ""
managedPost.status = PostStatus.local.rawValue
managedPost.collectionAlias = nil
switch model.preferences.font {
case 1:
managedPost.appearance = "sans"
case 2:
managedPost.appearance = "wrap"
default:
managedPost.appearance = "serif"
}
if let languageCode = Locale.current.languageCode {
managedPost.language = languageCode
managedPost.rtl = Locale.characterDirection(forLanguage: languageCode) == .rightToLeft
}
withAnimation {
self.model.selectedPost = managedPost
}
}, label: { Image(systemName: "square.and.pencil") })
}
#else
SidebarView()
#endif
#if os(macOS)
PostListView(selectedCollection: nil, showAllPosts: model.account.isLoggedIn)
.toolbar {
ToolbarItem(placement: .navigation) {
Button(action: {
DispatchQueue.main.async {
model.fetchUserCollections()
model.fetchUserPosts()
}
}, label: { Image(systemName: "arrow.clockwise") })
- .padding(.leading, sidebarIsHidden ? 8 : 0)
- .animation(.linear)
+ .disabled(!model.account.isLoggedIn)
+ .padding(.leading, sidebarIsHidden ? 8 : 0)
+ .animation(.linear)
}
ToolbarItem(placement: .status) {
if let selectedPost = model.selectedPost {
PostStatusBadgeView(post: selectedPost)
}
}
ToolbarItemGroup(placement: .primaryAction) {
if let selectedPost = model.selectedPost {
Button(action: {
DispatchQueue.main.async {
LocalStorageManager().saveContext()
model.publish(post: selectedPost)
}
}, label: { Image(systemName: "paperplane") })
.disabled(selectedPost.body.isEmpty || selectedPost.status == PostStatus.published.rawValue)
Button(action: {}, label: { Image(systemName: "square.and.arrow.up") })
.disabled(selectedPost.status == PostStatus.local.rawValue)
}
}
}
#else
PostListView(selectedCollection: nil, showAllPosts: model.account.isLoggedIn)
#endif
Text("Select a post, or create a new local draft.")
.foregroundColor(.secondary)
}
.environmentObject(model)
.alert(isPresented: $model.isPresentingDeleteAlert) {
Alert(
title: Text("Delete Post?"),
message: Text("This action cannot be undone."),
primaryButton: .destructive(Text("Delete"), action: {
if let postToDelete = model.postToDelete {
model.selectedPost = nil
DispatchQueue.main.async {
model.posts.remove(postToDelete)
}
model.postToDelete = nil
}
}),
secondaryButton: .cancel() {
model.postToDelete = nil
}
)
}
.alert(isPresented: $model.isPresentingNetworkErrorAlert, content: {
Alert(
title: Text("Connection Error"),
message: Text("There is no internet connection at the moment. Please reconnect or try again later"),
dismissButton: .default(Text("OK"), action: {
model.isPresentingNetworkErrorAlert = false
})
)
})
#if os(iOS)
EmptyView()
.sheet(
isPresented: $model.isPresentingSettingsView,
onDismiss: { model.isPresentingSettingsView = false },
content: {
SettingsView()
.environmentObject(model)
}
)
#endif
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
let context = LocalStorageManager.persistentContainer.viewContext
let model = WriteFreelyModel()
return ContentView(sidebarIsHidden: .constant(false))
.environment(\.managedObjectContext, context)
.environmentObject(model)
}
}
diff --git a/Shared/WriteFreely_MultiPlatformApp.swift b/Shared/WriteFreely_MultiPlatformApp.swift
index 0221e4d..f0918c5 100644
--- a/Shared/WriteFreely_MultiPlatformApp.swift
+++ b/Shared/WriteFreely_MultiPlatformApp.swift
@@ -1,105 +1,106 @@
import SwiftUI
@main
struct WriteFreely_MultiPlatformApp: App {
@StateObject private var model = WriteFreelyModel()
@State private var sidebarIsHidden: Bool = false
#if os(macOS)
@State private var selectedTab = 0
#endif
var body: some Scene {
WindowGroup {
ContentView(sidebarIsHidden: $sidebarIsHidden)
.onAppear(perform: {
if let lastDraft = model.editor.fetchLastDraftFromUserDefaults() {
self.model.selectedPost = lastDraft
} else {
createNewLocalPost()
}
})
.environmentObject(model)
.environment(\.managedObjectContext, LocalStorageManager.persistentContainer.viewContext)
// .preferredColorScheme(preferences.selectedColorScheme) // See PreferencesModel for info.
}
.commands {
CommandGroup(replacing: .newItem, addition: {
Button("New Local Draft") {
createNewLocalPost()
}
.keyboardShortcut("n", modifiers: [.command])
})
CommandGroup(after: .newItem) {
Button("Reload From Server") {
DispatchQueue.main.async {
model.fetchUserCollections()
model.fetchUserPosts()
}
}
+ .disabled(!model.account.isLoggedIn)
.keyboardShortcut("r", modifiers: [.command])
}
#if os(macOS)
CommandGroup(after: .sidebar) {
Button("Toggle Sidebar") {
NSApp.keyWindow?.contentViewController?.tryToPerform(
#selector(NSSplitViewController.toggleSidebar(_:)), with: nil
)
withAnimation { self.sidebarIsHidden.toggle() }
}
.keyboardShortcut("s", modifiers: [.command, .option])
}
#endif
}
#if os(macOS)
Settings {
TabView(selection: $selectedTab) {
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
}
private func createNewLocalPost() {
withAnimation {
self.model.selectedPost = nil
}
let managedPost = WFAPost(context: LocalStorageManager.persistentContainer.viewContext)
managedPost.createdDate = Date()
managedPost.title = ""
managedPost.body = ""
managedPost.status = PostStatus.local.rawValue
managedPost.collectionAlias = nil
switch model.preferences.font {
case 1:
managedPost.appearance = "sans"
case 2:
managedPost.appearance = "wrap"
default:
managedPost.appearance = "serif"
}
if let languageCode = Locale.current.languageCode {
managedPost.language = languageCode
managedPost.rtl = Locale.characterDirection(forLanguage: languageCode) == .rightToLeft
}
withAnimation {
self.model.selectedPost = managedPost
}
}
}

File Metadata

Mime Type
text/x-diff
Expires
Thu, Mar 6, 3:12 AM (1 d, 12 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
3168178

Event Timeline