Source code for the WriteFreely SwiftUI app for iOS, iPadOS, and macOS
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

156 lines
5.5 KiB

  1. import SwiftUI
  2. #if os(macOS)
  3. import Sparkle
  4. #endif
  5. @main
  6. struct CheckForDebugModifier {
  7. static func main() {
  8. #if os(macOS)
  9. if NSEvent.modifierFlags.contains(.shift) {
  10. // Clear the launch-to-last-draft values to load a new draft.
  11. UserDefaults.standard.setValue(false, forKey: "showAllPostsFlag")
  12. UserDefaults.standard.setValue(nil, forKey: "selectedCollectionURL")
  13. UserDefaults.standard.setValue(nil, forKey: "lastDraftURL")
  14. } else {
  15. // No-op
  16. }
  17. #endif
  18. WriteFreely_MultiPlatformApp.main()
  19. }
  20. }
  21. struct WriteFreely_MultiPlatformApp: App {
  22. @StateObject private var model = WriteFreelyModel.shared
  23. #if os(macOS)
  24. // swiftlint:disable:next weak_delegate
  25. @NSApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
  26. @State private var selectedTab = 0
  27. #endif
  28. var body: some Scene {
  29. WindowGroup {
  30. ContentView()
  31. .onAppear(perform: {
  32. if model.editor.showAllPostsFlag {
  33. DispatchQueue.main.async {
  34. self.model.selectedCollection = nil
  35. self.model.showAllPosts = true
  36. showLastDraftOrCreateNewLocalPost()
  37. }
  38. } else {
  39. DispatchQueue.main.async {
  40. self.model.selectedCollection = model.editor.fetchSelectedCollectionFromAppStorage()
  41. self.model.showAllPosts = false
  42. showLastDraftOrCreateNewLocalPost()
  43. }
  44. }
  45. // DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
  46. // if model.editor.lastDraftURL != nil {
  47. // self.model.selectedPost = model.editor.fetchLastDraftFromAppStorage()
  48. // } else {
  49. // createNewLocalPost()
  50. // }
  51. // }
  52. })
  53. .environmentObject(model)
  54. .environment(\.managedObjectContext, LocalStorageManager.standard.container.viewContext)
  55. // .preferredColorScheme(preferences.selectedColorScheme) // See PreferencesModel for info.
  56. }
  57. .commands {
  58. #if os(macOS)
  59. CommandGroup(after: .appInfo, addition: {
  60. Button("Check For Updates") {
  61. SUUpdater.shared()?.checkForUpdates(self)
  62. }
  63. })
  64. #endif
  65. CommandGroup(replacing: .newItem, addition: {
  66. Button("New Post") {
  67. createNewLocalPost()
  68. }
  69. .keyboardShortcut("n", modifiers: [.command])
  70. })
  71. CommandGroup(after: .newItem) {
  72. Button("Refresh Posts") {
  73. DispatchQueue.main.async {
  74. model.fetchUserCollections()
  75. model.fetchUserPosts()
  76. }
  77. }
  78. .disabled(!model.account.isLoggedIn)
  79. .keyboardShortcut("r", modifiers: [.command])
  80. }
  81. SidebarCommands()
  82. #if os(macOS)
  83. PostCommands(model: model)
  84. #endif
  85. CommandGroup(after: .help) {
  86. Button("Visit Support Forum") {
  87. #if os(macOS)
  88. NSWorkspace().open(model.helpURL)
  89. #else
  90. UIApplication.shared.open(model.helpURL)
  91. #endif
  92. }
  93. }
  94. ToolbarCommands()
  95. TextEditingCommands()
  96. }
  97. #if os(macOS)
  98. Settings {
  99. TabView(selection: $selectedTab) {
  100. MacAccountView()
  101. .environmentObject(model)
  102. .tabItem {
  103. Image(systemName: "person.crop.circle")
  104. Text("Account")
  105. }
  106. .tag(0)
  107. MacPreferencesView(preferences: model.preferences)
  108. .tabItem {
  109. Image(systemName: "gear")
  110. Text("Preferences")
  111. }
  112. .tag(1)
  113. MacUpdatesView()
  114. .tabItem {
  115. Image(systemName: "arrow.down.circle")
  116. Text("Updates")
  117. }
  118. .tag(2)
  119. }
  120. .frame(minWidth: 500, maxWidth: 500, minHeight: 200)
  121. .padding()
  122. // .preferredColorScheme(preferences.selectedColorScheme) // See PreferencesModel for info.
  123. }
  124. #endif
  125. }
  126. private func showLastDraftOrCreateNewLocalPost() {
  127. if model.editor.lastDraftURL != nil {
  128. self.model.selectedPost = model.editor.fetchLastDraftFromAppStorage()
  129. } else {
  130. createNewLocalPost()
  131. }
  132. }
  133. private func createNewLocalPost() {
  134. withAnimation {
  135. // Un-set the currently selected post
  136. self.model.selectedPost = nil
  137. }
  138. // Create the new-post managed object
  139. let managedPost = model.editor.generateNewLocalPost(withFont: model.preferences.font)
  140. withAnimation {
  141. // Set it as the selectedPost
  142. DispatchQueue.main.asyncAfter(deadline: .now()) {
  143. self.model.selectedPost = managedPost
  144. }
  145. }
  146. }
  147. }