mirror of
https://github.com/writeas/writefreely-swiftui-multiplatform.git
synced 2024-11-15 01:11:02 +00:00
Merge branch 'main' into add-help-tooltips
This commit is contained in:
commit
725ff2eed9
@ -55,25 +55,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)
|
||||
|
@ -92,7 +92,8 @@ struct PostListView: View {
|
||||
Alert(
|
||||
title: Text("Connection Error"),
|
||||
message: Text("""
|
||||
There is no internet connection at the moment. Please reconnect or try again later.
|
||||
There is no internet connection at the moment. \
|
||||
Please reconnect or try again later.
|
||||
"""),
|
||||
dismissButton: .default(Text("OK"), action: {
|
||||
model.isPresentingNetworkErrorAlert = false
|
||||
|
@ -55,6 +55,7 @@ struct WriteFreely_MultiPlatformApp: App {
|
||||
.keyboardShortcut("r", modifiers: [.command])
|
||||
}
|
||||
SidebarCommands()
|
||||
PostCommands(model: model)
|
||||
CommandGroup(after: .help) {
|
||||
Button("Visit Support Forum") {
|
||||
#if os(macOS)
|
||||
|
@ -23,6 +23,7 @@
|
||||
173E19D1254318F600440F0F /* RemoteChangePromptView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 173E19D0254318F600440F0F /* RemoteChangePromptView.swift */; };
|
||||
173E19E3254329CC00440F0F /* PostTextEditingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 173E19E2254329CC00440F0F /* PostTextEditingView.swift */; };
|
||||
17466626256C0D0600629997 /* MacEditorTextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17466625256C0D0600629997 /* MacEditorTextView.swift */; };
|
||||
17479F152583D8E40072B7FB /* PostEditorSharingPicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17479F142583D8E40072B7FB /* PostEditorSharingPicker.swift */; };
|
||||
17480CA5251272EE00EB7765 /* Bundle+AppVersion.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17480CA4251272EE00EB7765 /* Bundle+AppVersion.swift */; };
|
||||
17480CA6251272EE00EB7765 /* Bundle+AppVersion.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17480CA4251272EE00EB7765 /* Bundle+AppVersion.swift */; };
|
||||
174D313224EC2831006CA9EE /* WriteFreelyModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 174D313124EC2831006CA9EE /* WriteFreelyModel.swift */; };
|
||||
@ -49,6 +50,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 */; };
|
||||
@ -126,6 +128,7 @@
|
||||
173E19D0254318F600440F0F /* RemoteChangePromptView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RemoteChangePromptView.swift; sourceTree = "<group>"; };
|
||||
173E19E2254329CC00440F0F /* PostTextEditingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PostTextEditingView.swift; sourceTree = "<group>"; };
|
||||
17466625256C0D0600629997 /* MacEditorTextView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MacEditorTextView.swift; sourceTree = "<group>"; };
|
||||
17479F142583D8E40072B7FB /* PostEditorSharingPicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PostEditorSharingPicker.swift; sourceTree = "<group>"; };
|
||||
17480CA4251272EE00EB7765 /* Bundle+AppVersion.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Bundle+AppVersion.swift"; sourceTree = "<group>"; };
|
||||
174D313124EC2831006CA9EE /* WriteFreelyModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WriteFreelyModel.swift; sourceTree = "<group>"; };
|
||||
1753F6AB24E431CC00309365 /* MacPreferencesView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MacPreferencesView.swift; sourceTree = "<group>"; };
|
||||
@ -141,6 +144,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 = "<group>"; };
|
||||
17681E402519410E00D394AE /* UINavigationController+Appearance.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UINavigationController+Appearance.swift"; sourceTree = "<group>"; };
|
||||
1780F6EE25895EDB00FE45FF /* PostCommands.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PostCommands.swift; sourceTree = "<group>"; };
|
||||
17A5388724DDA31F00DEFF9A /* MacAccountView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MacAccountView.swift; sourceTree = "<group>"; };
|
||||
17A5388B24DDC83F00DEFF9A /* AccountModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountModel.swift; sourceTree = "<group>"; };
|
||||
17A5388D24DDEC7400DEFF9A /* AccountView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountView.swift; sourceTree = "<group>"; };
|
||||
@ -311,6 +315,7 @@
|
||||
17A67CAC251A5D8D002F163D /* PostEditor */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
17479F142583D8E40072B7FB /* PostEditorSharingPicker.swift */,
|
||||
17A67CAE251A5DD7002F163D /* PostEditorView.swift */,
|
||||
17E5DF892543610700DCDC9B /* PostTextEditingView.swift */,
|
||||
17466625256C0D0600629997 /* MacEditorTextView.swift */,
|
||||
@ -322,6 +327,7 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
17BC617825715068003363CA /* ActivePostToolbarView.swift */,
|
||||
1780F6EE25895EDB00FE45FF /* PostCommands.swift */,
|
||||
);
|
||||
path = Navigation;
|
||||
sourceTree = "<group>";
|
||||
@ -755,6 +761,7 @@
|
||||
17D435E924E3128F0036B539 /* PreferencesModel.swift in Sources */,
|
||||
17120DAA24E1B2F5002B9F6C /* AccountLogoutView.swift in Sources */,
|
||||
17DF32D624C8CA3400BCE2E3 /* PostStatusBadgeView.swift in Sources */,
|
||||
17479F152583D8E40072B7FB /* PostEditorSharingPicker.swift in Sources */,
|
||||
17480CA6251272EE00EB7765 /* Bundle+AppVersion.swift in Sources */,
|
||||
17C42E662509237800072984 /* PostListFilteredView.swift in Sources */,
|
||||
17120DAD24E1B99F002B9F6C /* AccountLoginView.swift in Sources */,
|
||||
@ -777,6 +784,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 */,
|
||||
|
@ -3,20 +3,116 @@ import SwiftUI
|
||||
struct ActivePostToolbarView: View {
|
||||
@EnvironmentObject var model: WriteFreelyModel
|
||||
@ObservedObject var activePost: WFAPost
|
||||
@State private var isPresentingSharingServicePicker: Bool = false
|
||||
|
||||
@State private var selectedCollection: WFACollection?
|
||||
|
||||
@FetchRequest(
|
||||
entity: WFACollection.entity(),
|
||||
sortDescriptors: [NSSortDescriptor(keyPath: \WFACollection.title, ascending: true)]
|
||||
) var collections: FetchedResults<WFACollection>
|
||||
|
||||
var body: some View {
|
||||
HStack(spacing: 16) {
|
||||
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")")
|
||||
.tag(nil as WFACollection?)
|
||||
Divider()
|
||||
ForEach(collections) { collection in
|
||||
Text("\(collection.title)").tag(collection as WFACollection?)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
PostEditorStatusToolbarView(post: activePost)
|
||||
.frame(minWidth: 50, alignment: .center)
|
||||
.layoutPriority(1)
|
||||
.padding(.horizontal)
|
||||
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 {
|
||||
openSettingsWindow()
|
||||
}
|
||||
}, 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 {
|
||||
openSettingsWindow()
|
||||
}
|
||||
}, label: {
|
||||
Text("\(collection.title)")
|
||||
})
|
||||
}
|
||||
}, label: {
|
||||
Label("Publish…", systemImage: "paperplane")
|
||||
})
|
||||
.disabled(activePost.body.isEmpty)
|
||||
.help("Publish the post to the web.\(model.account.isLoggedIn ? "" : " You must be logged in to do this.")") // swiftlint:disable:this line_length
|
||||
} else {
|
||||
HStack(spacing: 4) {
|
||||
Button(action: {}, label: { Image(systemName: "square.and.arrow.up") })
|
||||
Button(
|
||||
action: {
|
||||
self.isPresentingSharingServicePicker = true
|
||||
},
|
||||
label: { Image(systemName: "square.and.arrow.up") }
|
||||
)
|
||||
.disabled(activePost.status == PostStatus.local.rawValue)
|
||||
.help("Copy the post's URL to your Mac's pasteboard.")
|
||||
.popover(isPresented: $isPresentingSharingServicePicker) {
|
||||
PostEditorSharingPicker(
|
||||
isPresented: $isPresentingSharingServicePicker,
|
||||
sharingItems: createPostUrl()
|
||||
)
|
||||
.frame(width: .zero, height: .zero)
|
||||
}
|
||||
Button(action: { publishPost(activePost) }, label: { Image(systemName: "paperplane") })
|
||||
.disabled(activePost.body.isEmpty || activePost.status == PostStatus.published.rawValue)
|
||||
.help("Publish the post to the web.\(model.account.isLoggedIn ? "" : " You must be logged in to do this.")") // swiftlint:disable:this line_length
|
||||
}
|
||||
}
|
||||
}
|
||||
.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 createPostUrl() -> [Any] {
|
||||
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 [] }
|
||||
guard let data = URL(string: urlString) else { return [] }
|
||||
return [data as NSURL]
|
||||
}
|
||||
|
||||
private func publishPost(_ post: WFAPost) {
|
||||
DispatchQueue.main.async {
|
||||
@ -24,4 +120,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)
|
||||
}
|
||||
}
|
||||
|
25
macOS/Navigation/PostCommands.swift
Normal file
25
macOS/Navigation/PostCommands.swift
Normal file
@ -0,0 +1,25 @@
|
||||
import SwiftUI
|
||||
|
||||
struct PostCommands: Commands {
|
||||
@ObservedObject var model: WriteFreelyModel
|
||||
|
||||
var body: some Commands {
|
||||
CommandMenu("Post") {
|
||||
Group {
|
||||
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)
|
||||
}
|
||||
}
|
39
macOS/PostEditor/PostEditorSharingPicker.swift
Normal file
39
macOS/PostEditor/PostEditorSharingPicker.swift
Normal file
@ -0,0 +1,39 @@
|
||||
import SwiftUI
|
||||
|
||||
struct PostEditorSharingPicker: NSViewRepresentable {
|
||||
@Binding var isPresented: Bool
|
||||
var sharingItems: [Any] = []
|
||||
|
||||
func makeNSView(context: Context) -> some NSView {
|
||||
let view = NSView()
|
||||
let picker = NSSharingServicePicker(items: sharingItems)
|
||||
picker.delegate = context.coordinator
|
||||
|
||||
DispatchQueue.main.async {
|
||||
picker.show(relativeTo: .zero, of: view, preferredEdge: .minY)
|
||||
}
|
||||
return view
|
||||
}
|
||||
|
||||
func updateNSView(_ nsView: NSViewType, context: Context) {
|
||||
}
|
||||
|
||||
func makeCoordinator() -> Coordinator {
|
||||
Coordinator(owner: self)
|
||||
}
|
||||
|
||||
class Coordinator: NSObject, NSSharingServicePickerDelegate {
|
||||
let owner: PostEditorSharingPicker
|
||||
init(owner: PostEditorSharingPicker) {
|
||||
self.owner = owner
|
||||
}
|
||||
|
||||
func sharingServicePicker(
|
||||
_ sharingServicePicker: NSSharingServicePicker,
|
||||
didChoose service: NSSharingService?
|
||||
) {
|
||||
sharingServicePicker.delegate = nil
|
||||
self.owner.isPresented = false
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user