From 9b7fab43702401b5c399b133de2adacf626d15de Mon Sep 17 00:00:00 2001 From: Angelo Stavrow Date: Mon, 14 Dec 2020 14:09:49 -0500 Subject: [PATCH 1/9] Add picker to toolbar for moving non-local posts --- macOS/Navigation/ActivePostToolbarView.swift | 35 +++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/macOS/Navigation/ActivePostToolbarView.swift b/macOS/Navigation/ActivePostToolbarView.swift index 68b9d93..d6b83dd 100644 --- a/macOS/Navigation/ActivePostToolbarView.swift +++ b/macOS/Navigation/ActivePostToolbarView.swift @@ -4,9 +4,29 @@ struct ActivePostToolbarView: View { @EnvironmentObject var model: WriteFreelyModel @ObservedObject var activePost: WFAPost + @State private var selectedCollection: WFACollection? + + @FetchRequest( + entity: WFACollection.entity(), + sortDescriptors: [NSSortDescriptor(keyPath: \WFACollection.title, ascending: true)] + ) var collections: FetchedResults + var body: some View { - HStack(spacing: 16) { + HStack { + if model.account.isLoggedIn && activePost.status != PostStatus.local.rawValue { + Section(header: Text("Move To:")) { + Picker(selection: $selectedCollection, label: Text("Move To…"), content: { + Text("\(model.account.server == "https://write.as" ? "Anonymous" : "Drafts")") + .tag(nil as WFACollection?) + Divider() + ForEach(collections) { collection in + Text("\(collection.title)").tag(collection as WFACollection?) + } + }) + } + } PostEditorStatusToolbarView(post: activePost) + .layoutPriority(1) HStack(spacing: 4) { Button(action: {}, label: { Image(systemName: "square.and.arrow.up") }) .disabled(activePost.status == PostStatus.local.rawValue) @@ -14,6 +34,19 @@ struct ActivePostToolbarView: View { .disabled(activePost.body.isEmpty || activePost.status == PostStatus.published.rawValue) } } + .onAppear(perform: { + self.selectedCollection = collections.first { $0.alias == activePost.collectionAlias } + }) + .onChange(of: selectedCollection, perform: { [selectedCollection] newCollection in + if activePost.collectionAlias == newCollection?.alias { + return + } else { + withAnimation { + activePost.collectionAlias = newCollection?.alias + model.move(post: activePost, from: selectedCollection, to: newCollection) + } + } + }) } private func publishPost(_ post: WFAPost) { From 82dbaba32b83d884e13f82c24726b791e6932e00 Mon Sep 17 00:00:00 2001 From: Angelo Stavrow Date: Tue, 15 Dec 2020 13:33:22 -0500 Subject: [PATCH 2/9] Adjust spacing between post-related toolbar items --- macOS/Navigation/ActivePostToolbarView.swift | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/macOS/Navigation/ActivePostToolbarView.swift b/macOS/Navigation/ActivePostToolbarView.swift index d6b83dd..ce9603d 100644 --- a/macOS/Navigation/ActivePostToolbarView.swift +++ b/macOS/Navigation/ActivePostToolbarView.swift @@ -12,7 +12,7 @@ struct ActivePostToolbarView: View { ) var collections: FetchedResults var body: some View { - HStack { + HStack(spacing: 4) { if model.account.isLoggedIn && activePost.status != PostStatus.local.rawValue { Section(header: Text("Move To:")) { Picker(selection: $selectedCollection, label: Text("Move To…"), content: { @@ -27,12 +27,11 @@ struct ActivePostToolbarView: View { } PostEditorStatusToolbarView(post: activePost) .layoutPriority(1) - HStack(spacing: 4) { - Button(action: {}, label: { Image(systemName: "square.and.arrow.up") }) - .disabled(activePost.status == PostStatus.local.rawValue) - Button(action: { publishPost(activePost) }, label: { Image(systemName: "paperplane") }) - .disabled(activePost.body.isEmpty || activePost.status == PostStatus.published.rawValue) - } + .padding(.horizontal) + Button(action: {}, label: { Image(systemName: "square.and.arrow.up") }) + .disabled(activePost.status == PostStatus.local.rawValue) + Button(action: { publishPost(activePost) }, label: { Image(systemName: "paperplane") }) + .disabled(activePost.body.isEmpty || activePost.status == PostStatus.published.rawValue) } .onAppear(perform: { self.selectedCollection = collections.first { $0.alias == activePost.collectionAlias } From f52fae335b648234fd7b7298d9763be625638fa8 Mon Sep 17 00:00:00 2001 From: Angelo Stavrow Date: Tue, 15 Dec 2020 14:53:18 -0500 Subject: [PATCH 3/9] Present publish-to menu for new local posts --- macOS/Navigation/ActivePostToolbarView.swift | 53 +++++++++++++++++--- 1 file changed, 47 insertions(+), 6 deletions(-) diff --git a/macOS/Navigation/ActivePostToolbarView.swift b/macOS/Navigation/ActivePostToolbarView.swift index ce9603d..ef1ca42 100644 --- a/macOS/Navigation/ActivePostToolbarView.swift +++ b/macOS/Navigation/ActivePostToolbarView.swift @@ -12,8 +12,10 @@ struct ActivePostToolbarView: View { ) var collections: FetchedResults var body: some View { - HStack(spacing: 4) { - if model.account.isLoggedIn && activePost.status != PostStatus.local.rawValue { + HStack { + if model.account.isLoggedIn && + activePost.status != PostStatus.local.rawValue && + !(activePost.wasDeletedFromServer || activePost.hasNewerRemoteCopy) { Section(header: Text("Move To:")) { Picker(selection: $selectedCollection, label: Text("Move To…"), content: { Text("\(model.account.server == "https://write.as" ? "Anonymous" : "Drafts")") @@ -26,12 +28,51 @@ struct ActivePostToolbarView: View { } } PostEditorStatusToolbarView(post: activePost) + .frame(minWidth: 50, alignment: .center) .layoutPriority(1) .padding(.horizontal) - Button(action: {}, label: { Image(systemName: "square.and.arrow.up") }) - .disabled(activePost.status == PostStatus.local.rawValue) - Button(action: { publishPost(activePost) }, label: { Image(systemName: "paperplane") }) - .disabled(activePost.body.isEmpty || activePost.status == PostStatus.published.rawValue) + if activePost.status == PostStatus.local.rawValue { + Menu(content: { + Label("Publish To:", systemImage: "paperplane") + Divider() + Button(action: { + if model.account.isLoggedIn { + withAnimation { + activePost.collectionAlias = nil + publishPost(activePost) + } + } else { + // present login screen + } + }, label: { + Text("\(model.account.server == "https://write.as" ? "Anonymous" : "Drafts")") + }) + ForEach(collections) { collection in + Button(action: { + if model.account.isLoggedIn { + withAnimation { + activePost.collectionAlias = collection.alias + publishPost(activePost) + } + } else { + // present login screen + } + }, label: { + Text("\(collection.title)") + }) + } + }, label: { + Label("Publish…", systemImage: "paperplane") + }) + .disabled(activePost.body.isEmpty) + } else { + HStack(spacing: 4) { + Button(action: {}, label: { Image(systemName: "square.and.arrow.up") }) + .disabled(activePost.status == PostStatus.local.rawValue) + Button(action: { publishPost(activePost) }, label: { Image(systemName: "paperplane") }) + .disabled(activePost.body.isEmpty || activePost.status == PostStatus.published.rawValue) + } + } } .onAppear(perform: { self.selectedCollection = collections.first { $0.alias == activePost.collectionAlias } From 851a0b6465be46bb69912649dc9ef16f3edc314e Mon Sep 17 00:00:00 2001 From: Angelo Stavrow Date: Tue, 15 Dec 2020 15:10:26 -0500 Subject: [PATCH 4/9] Open app prefs window if not logged in on publish --- macOS/Navigation/ActivePostToolbarView.swift | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/macOS/Navigation/ActivePostToolbarView.swift b/macOS/Navigation/ActivePostToolbarView.swift index ef1ca42..3674d5b 100644 --- a/macOS/Navigation/ActivePostToolbarView.swift +++ b/macOS/Navigation/ActivePostToolbarView.swift @@ -42,7 +42,7 @@ struct ActivePostToolbarView: View { publishPost(activePost) } } else { - // present login screen + openSettingsWindow() } }, label: { Text("\(model.account.server == "https://write.as" ? "Anonymous" : "Drafts")") @@ -55,7 +55,7 @@ struct ActivePostToolbarView: View { publishPost(activePost) } } else { - // present login screen + openSettingsWindow() } }, label: { Text("\(collection.title)") @@ -95,4 +95,9 @@ struct ActivePostToolbarView: View { model.publish(post: post) } } + + private func openSettingsWindow() { + guard let menuItem = NSApplication.shared.mainMenu?.item(at: 0)?.submenu?.item(at: 2) else { return } + NSApplication.shared.sendAction(menuItem.action!, to: menuItem.target, from: nil) + } } From 09131d58730cecb3920b6b2f8d65d8edb52195ce Mon Sep 17 00:00:00 2001 From: Angelo Stavrow Date: Wed, 16 Dec 2020 11:35:04 -0500 Subject: [PATCH 5/9] Remove duplicate ToolbarItemGroup in Mac app --- Shared/PostList/PostListView.swift | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/Shared/PostList/PostListView.swift b/Shared/PostList/PostListView.swift index 8199e17..0e3fd42 100644 --- a/Shared/PostList/PostListView.swift +++ b/Shared/PostList/PostListView.swift @@ -84,24 +84,6 @@ struct PostListView: View { showAllPosts: showAllPosts, postCount: $postCount ) - .toolbar { - ToolbarItemGroup(placement: .primaryAction) { - if let selectedPost = model.selectedPost { - ActivePostToolbarView(activePost: selectedPost) - .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 - }) - ) - }) - } - } - } .onDisappear { DispatchQueue.main.async { self.model.selectedCollection = nil From 6164ceeb99cc1056d94cbeaaaee26f32113ea2d8 Mon Sep 17 00:00:00 2001 From: Angelo Stavrow Date: Wed, 16 Dec 2020 11:35:40 -0500 Subject: [PATCH 6/9] Add PostCommands menu to Mac app --- Shared/WriteFreely_MultiPlatformApp.swift | 1 + .../project.pbxproj | 4 ++++ macOS/Navigation/PostCommands.swift | 19 +++++++++++++++++++ 3 files changed, 24 insertions(+) create mode 100644 macOS/Navigation/PostCommands.swift diff --git a/Shared/WriteFreely_MultiPlatformApp.swift b/Shared/WriteFreely_MultiPlatformApp.swift index 4bc9109..5b71d5d 100644 --- a/Shared/WriteFreely_MultiPlatformApp.swift +++ b/Shared/WriteFreely_MultiPlatformApp.swift @@ -55,6 +55,7 @@ struct WriteFreely_MultiPlatformApp: App { .keyboardShortcut("r", modifiers: [.command]) } SidebarCommands() + PostCommands(post: model.selectedPost) CommandGroup(after: .help) { Button("Visit Support Forum") { #if os(macOS) diff --git a/WriteFreely-MultiPlatform.xcodeproj/project.pbxproj b/WriteFreely-MultiPlatform.xcodeproj/project.pbxproj index 489cd38..378491a 100644 --- a/WriteFreely-MultiPlatform.xcodeproj/project.pbxproj +++ b/WriteFreely-MultiPlatform.xcodeproj/project.pbxproj @@ -49,6 +49,7 @@ 1765F62A24E18EA200C9EBF0 /* SidebarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1765F62924E18EA200C9EBF0 /* SidebarView.swift */; }; 1765F62B24E18EA200C9EBF0 /* SidebarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1765F62924E18EA200C9EBF0 /* SidebarView.swift */; }; 17681E412519410E00D394AE /* UINavigationController+Appearance.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17681E402519410E00D394AE /* UINavigationController+Appearance.swift */; }; + 1780F6EF25895EDB00FE45FF /* PostCommands.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1780F6EE25895EDB00FE45FF /* PostCommands.swift */; }; 17A5388824DDA31F00DEFF9A /* MacAccountView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17A5388724DDA31F00DEFF9A /* MacAccountView.swift */; }; 17A5388C24DDC83F00DEFF9A /* AccountModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17A5388B24DDC83F00DEFF9A /* AccountModel.swift */; }; 17A5388F24DDEC7400DEFF9A /* AccountView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17A5388D24DDEC7400DEFF9A /* AccountView.swift */; }; @@ -141,6 +142,7 @@ 1756DC0024FEE18400207AB8 /* WFACollection+CoreDataProperties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "WFACollection+CoreDataProperties.swift"; sourceTree = SOURCE_ROOT; }; 1765F62924E18EA200C9EBF0 /* SidebarView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SidebarView.swift; sourceTree = ""; }; 17681E402519410E00D394AE /* UINavigationController+Appearance.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UINavigationController+Appearance.swift"; sourceTree = ""; }; + 1780F6EE25895EDB00FE45FF /* PostCommands.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PostCommands.swift; sourceTree = ""; }; 17A5388724DDA31F00DEFF9A /* MacAccountView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MacAccountView.swift; sourceTree = ""; }; 17A5388B24DDC83F00DEFF9A /* AccountModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountModel.swift; sourceTree = ""; }; 17A5388D24DDEC7400DEFF9A /* AccountView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountView.swift; sourceTree = ""; }; @@ -322,6 +324,7 @@ isa = PBXGroup; children = ( 17BC617825715068003363CA /* ActivePostToolbarView.swift */, + 1780F6EE25895EDB00FE45FF /* PostCommands.swift */, ); path = Navigation; sourceTree = ""; @@ -777,6 +780,7 @@ 1756DC0224FEE18400207AB8 /* WFACollection+CoreDataClass.swift in Sources */, 1756DBB424FECDBB00207AB8 /* PostEditorStatusToolbarView.swift in Sources */, 17A5388F24DDEC7400DEFF9A /* AccountView.swift in Sources */, + 1780F6EF25895EDB00FE45FF /* PostCommands.swift in Sources */, 170DFA35251BBC44001D82A0 /* PostEditorModel.swift in Sources */, 1756AE7524CB26FA00FD7257 /* PostCellView.swift in Sources */, 17A5388824DDA31F00DEFF9A /* MacAccountView.swift in Sources */, diff --git a/macOS/Navigation/PostCommands.swift b/macOS/Navigation/PostCommands.swift new file mode 100644 index 0000000..2ba460b --- /dev/null +++ b/macOS/Navigation/PostCommands.swift @@ -0,0 +1,19 @@ +import SwiftUI + +struct PostCommands: Commands { + @State var post: WFAPost? + + var body: some Commands { + CommandMenu("Post") { + Button("Publish…") { + print("Published active post (not really): '\(post?.title ?? "untitled")'") + } + Button("Move…") { + print("Moved active post (not really): '\(post?.title ?? "untitled")'") + } + Button("Copy Link To Post") { + print("Copied URL to post (not really): '\(post?.title ?? "untitled")'") + } + } + } +} From 96472c260449400e64682b24b508d66474554e38 Mon Sep 17 00:00:00 2001 From: Angelo Stavrow Date: Wed, 16 Dec 2020 14:25:56 -0500 Subject: [PATCH 7/9] Add copy-published-post-link to Post command menu --- Shared/WriteFreely_MultiPlatformApp.swift | 2 +- macOS/Navigation/PostCommands.swift | 37 +++++++++++++++++------ 2 files changed, 29 insertions(+), 10 deletions(-) diff --git a/Shared/WriteFreely_MultiPlatformApp.swift b/Shared/WriteFreely_MultiPlatformApp.swift index 5b71d5d..2b249d3 100644 --- a/Shared/WriteFreely_MultiPlatformApp.swift +++ b/Shared/WriteFreely_MultiPlatformApp.swift @@ -55,7 +55,7 @@ struct WriteFreely_MultiPlatformApp: App { .keyboardShortcut("r", modifiers: [.command]) } SidebarCommands() - PostCommands(post: model.selectedPost) + PostCommands(model: model) CommandGroup(after: .help) { Button("Visit Support Forum") { #if os(macOS) diff --git a/macOS/Navigation/PostCommands.swift b/macOS/Navigation/PostCommands.swift index 2ba460b..8b81d07 100644 --- a/macOS/Navigation/PostCommands.swift +++ b/macOS/Navigation/PostCommands.swift @@ -1,19 +1,38 @@ import SwiftUI struct PostCommands: Commands { - @State var post: WFAPost? + @ObservedObject var model: WriteFreelyModel + + @FetchRequest( + entity: WFACollection.entity(), + sortDescriptors: [NSSortDescriptor(keyPath: \WFACollection.title, ascending: true)] + ) var collections: FetchedResults var body: some Commands { CommandMenu("Post") { - Button("Publish…") { - print("Published active post (not really): '\(post?.title ?? "untitled")'") - } - Button("Move…") { - print("Moved active post (not really): '\(post?.title ?? "untitled")'") - } - Button("Copy Link To Post") { - print("Copied URL to post (not really): '\(post?.title ?? "untitled")'") + Group { + Button("Publish…") { + print("Clicked 'Publish…' for post '\(model.selectedPost?.title ?? "untitled")'") + } + .disabled(true) + Button("Move…") { + print("Clicked 'Move…' for post '\(model.selectedPost?.title ?? "untitled")'") + } + .disabled(true) + Button(action: sendPostUrlToPasteboard, label: { Text("Copy Link To Published Post") }) + .disabled(model.selectedPost?.status == PostStatus.local.rawValue) } + .disabled(model.selectedPost == nil || !model.account.isLoggedIn) } } + + private func sendPostUrlToPasteboard() { + guard let activePost = model.selectedPost else { return } + guard let postId = activePost.postId else { return } + guard let urlString = activePost.slug != nil ? + "\(model.account.server)/\((activePost.collectionAlias)!)/\((activePost.slug)!)" : + "\(model.account.server)/\((postId))" else { return } + NSPasteboard.general.clearContents() + NSPasteboard.general.setString(urlString, forType: .string) + } } From c4e9089e76b8df026a3396927d19507cd575b7fc Mon Sep 17 00:00:00 2001 From: Angelo Stavrow Date: Thu, 17 Dec 2020 11:15:23 -0500 Subject: [PATCH 8/9] Remove unimplemented menu commands --- macOS/Navigation/PostCommands.swift | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/macOS/Navigation/PostCommands.swift b/macOS/Navigation/PostCommands.swift index 8b81d07..2b2d45a 100644 --- a/macOS/Navigation/PostCommands.swift +++ b/macOS/Navigation/PostCommands.swift @@ -3,22 +3,9 @@ import SwiftUI struct PostCommands: Commands { @ObservedObject var model: WriteFreelyModel - @FetchRequest( - entity: WFACollection.entity(), - sortDescriptors: [NSSortDescriptor(keyPath: \WFACollection.title, ascending: true)] - ) var collections: FetchedResults - var body: some Commands { CommandMenu("Post") { Group { - Button("Publish…") { - print("Clicked 'Publish…' for post '\(model.selectedPost?.title ?? "untitled")'") - } - .disabled(true) - Button("Move…") { - print("Clicked 'Move…' for post '\(model.selectedPost?.title ?? "untitled")'") - } - .disabled(true) Button(action: sendPostUrlToPasteboard, label: { Text("Copy Link To Published Post") }) .disabled(model.selectedPost?.status == PostStatus.local.rawValue) } From 0b0fdd81a1bfb91d46dcc6b55805fa293b8efc95 Mon Sep 17 00:00:00 2001 From: Angelo Stavrow Date: Thu, 17 Dec 2020 11:27:58 -0500 Subject: [PATCH 9/9] Move toolbar from ContentView to PostLIstView --- Shared/Navigation/ContentView.swift | 19 ------------------- Shared/PostList/PostListView.swift | 19 +++++++++++++++++++ 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/Shared/Navigation/ContentView.swift b/Shared/Navigation/ContentView.swift index d5c1e4d..327cdfa 100644 --- a/Shared/Navigation/ContentView.swift +++ b/Shared/Navigation/ContentView.swift @@ -53,25 +53,6 @@ struct ContentView: View { #if os(macOS) ZStack { PostListView(selectedCollection: nil, showAllPosts: model.account.isLoggedIn) - .toolbar { - ToolbarItemGroup(placement: .primaryAction) { - if let selectedPost = model.selectedPost { - ActivePostToolbarView(activePost: selectedPost) - .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 model.isProcessingRequest { ZStack { Color(NSColor.controlBackgroundColor).opacity(0.75) diff --git a/Shared/PostList/PostListView.swift b/Shared/PostList/PostListView.swift index 0e3fd42..e20651a 100644 --- a/Shared/PostList/PostListView.swift +++ b/Shared/PostList/PostListView.swift @@ -84,6 +84,25 @@ struct PostListView: View { showAllPosts: showAllPosts, postCount: $postCount ) + .toolbar { + ToolbarItemGroup(placement: .primaryAction) { + if let selectedPost = model.selectedPost { + ActivePostToolbarView(activePost: selectedPost) + .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 + }) + ) + }) + } + } + } .onDisappear { DispatchQueue.main.async { self.model.selectedCollection = nil