mirror of
https://github.com/writeas/writefreely-swiftui-multiplatform.git
synced 2024-11-15 01:11:02 +00:00
Merge pull request #167 from writeas/fix-post-status-bug
Fix post-status bug on publishing changes
This commit is contained in:
commit
849c093748
@ -37,6 +37,7 @@ class WriteFreelyModel: ObservableObject {
|
|||||||
private let defaults = UserDefaults.standard
|
private let defaults = UserDefaults.standard
|
||||||
private let monitor = NWPathMonitor()
|
private let monitor = NWPathMonitor()
|
||||||
private let queue = DispatchQueue(label: "NetworkMonitor")
|
private let queue = DispatchQueue(label: "NetworkMonitor")
|
||||||
|
private var postToUpdate: WFAPost?
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
@ -145,6 +146,8 @@ extension WriteFreelyModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func publish(post: WFAPost) {
|
func publish(post: WFAPost) {
|
||||||
|
postToUpdate = nil
|
||||||
|
|
||||||
if !hasNetworkConnection {
|
if !hasNetworkConnection {
|
||||||
DispatchQueue.main.async { self.isPresentingNetworkErrorAlert = true }
|
DispatchQueue.main.async { self.isPresentingNetworkErrorAlert = true }
|
||||||
return
|
return
|
||||||
@ -173,10 +176,8 @@ extension WriteFreelyModel {
|
|||||||
|
|
||||||
if let existingPostId = post.postId {
|
if let existingPostId = post.postId {
|
||||||
// This is an existing post.
|
// This is an existing post.
|
||||||
|
postToUpdate = post
|
||||||
wfPost.postId = post.postId
|
wfPost.postId = post.postId
|
||||||
wfPost.slug = post.slug
|
|
||||||
wfPost.updatedDate = post.updatedDate
|
|
||||||
wfPost.collectionAlias = post.collectionAlias
|
|
||||||
|
|
||||||
loggedInClient.updatePost(
|
loggedInClient.updatePost(
|
||||||
postId: existingPostId,
|
postId: existingPostId,
|
||||||
@ -407,37 +408,55 @@ private extension WriteFreelyModel {
|
|||||||
// See: https://github.com/writeas/writefreely-swift/issues/20
|
// See: https://github.com/writeas/writefreely-swift/issues/20
|
||||||
do {
|
do {
|
||||||
let fetchedPost = try result.get()
|
let fetchedPost = try result.get()
|
||||||
let request = WFAPost.createFetchRequest()
|
// If this is an updated post, check it against postToUpdate.
|
||||||
let matchBodyPredicate = NSPredicate(format: "body == %@", fetchedPost.body)
|
if let updatingPost = self.postToUpdate {
|
||||||
if let fetchedPostTitle = fetchedPost.title {
|
updatingPost.appearance = fetchedPost.appearance
|
||||||
let matchTitlePredicate = NSPredicate(format: "title == %@", fetchedPostTitle)
|
updatingPost.body = fetchedPost.body
|
||||||
request.predicate = NSCompoundPredicate(
|
updatingPost.createdDate = fetchedPost.createdDate
|
||||||
andPredicateWithSubpredicates: [
|
updatingPost.language = fetchedPost.language
|
||||||
matchTitlePredicate,
|
updatingPost.postId = fetchedPost.postId
|
||||||
matchBodyPredicate
|
updatingPost.rtl = fetchedPost.rtl ?? false
|
||||||
]
|
updatingPost.slug = fetchedPost.slug
|
||||||
)
|
updatingPost.status = PostStatus.published.rawValue
|
||||||
} else {
|
updatingPost.title = fetchedPost.title ?? ""
|
||||||
request.predicate = matchBodyPredicate
|
updatingPost.updatedDate = fetchedPost.updatedDate
|
||||||
}
|
|
||||||
do {
|
|
||||||
let cachedPostsResults = try LocalStorageManager.persistentContainer.viewContext.fetch(request)
|
|
||||||
guard let cachedPost = cachedPostsResults.first else { return }
|
|
||||||
cachedPost.appearance = fetchedPost.appearance
|
|
||||||
cachedPost.body = fetchedPost.body
|
|
||||||
cachedPost.createdDate = fetchedPost.createdDate
|
|
||||||
cachedPost.language = fetchedPost.language
|
|
||||||
cachedPost.postId = fetchedPost.postId
|
|
||||||
cachedPost.rtl = fetchedPost.rtl ?? false
|
|
||||||
cachedPost.slug = fetchedPost.slug
|
|
||||||
cachedPost.status = PostStatus.published.rawValue
|
|
||||||
cachedPost.title = fetchedPost.title ?? ""
|
|
||||||
cachedPost.updatedDate = fetchedPost.updatedDate
|
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
LocalStorageManager().saveContext()
|
LocalStorageManager().saveContext()
|
||||||
}
|
}
|
||||||
} catch {
|
} else {
|
||||||
print("Error: Failed to fetch cached posts")
|
// Otherwise if it's a newly-published post, find it in the local store.
|
||||||
|
let request = WFAPost.createFetchRequest()
|
||||||
|
let matchBodyPredicate = NSPredicate(format: "body == %@", fetchedPost.body)
|
||||||
|
if let fetchedPostTitle = fetchedPost.title {
|
||||||
|
let matchTitlePredicate = NSPredicate(format: "title == %@", fetchedPostTitle)
|
||||||
|
request.predicate = NSCompoundPredicate(
|
||||||
|
andPredicateWithSubpredicates: [
|
||||||
|
matchTitlePredicate,
|
||||||
|
matchBodyPredicate
|
||||||
|
]
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
request.predicate = matchBodyPredicate
|
||||||
|
}
|
||||||
|
do {
|
||||||
|
let cachedPostsResults = try LocalStorageManager.persistentContainer.viewContext.fetch(request)
|
||||||
|
guard let cachedPost = cachedPostsResults.first else { return }
|
||||||
|
cachedPost.appearance = fetchedPost.appearance
|
||||||
|
cachedPost.body = fetchedPost.body
|
||||||
|
cachedPost.createdDate = fetchedPost.createdDate
|
||||||
|
cachedPost.language = fetchedPost.language
|
||||||
|
cachedPost.postId = fetchedPost.postId
|
||||||
|
cachedPost.rtl = fetchedPost.rtl ?? false
|
||||||
|
cachedPost.slug = fetchedPost.slug
|
||||||
|
cachedPost.status = PostStatus.published.rawValue
|
||||||
|
cachedPost.title = fetchedPost.title ?? ""
|
||||||
|
cachedPost.updatedDate = fetchedPost.updatedDate
|
||||||
|
DispatchQueue.main.async {
|
||||||
|
LocalStorageManager().saveContext()
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
print("Error: Failed to fetch cached posts")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
print(error)
|
print(error)
|
||||||
|
@ -112,19 +112,21 @@ struct PostListView: View {
|
|||||||
)
|
)
|
||||||
.toolbar {
|
.toolbar {
|
||||||
ToolbarItemGroup(placement: .primaryAction) {
|
ToolbarItemGroup(placement: .primaryAction) {
|
||||||
ActivePostToolbarView()
|
if model.selectedPost != nil {
|
||||||
.alert(isPresented: $model.isPresentingNetworkErrorAlert, content: {
|
ActivePostToolbarView(activePost: model.selectedPost!)
|
||||||
Alert(
|
.alert(isPresented: $model.isPresentingNetworkErrorAlert, content: {
|
||||||
title: Text("Connection Error"),
|
Alert(
|
||||||
message: Text("""
|
title: Text("Connection Error"),
|
||||||
|
message: Text("""
|
||||||
There is no internet connection at the moment. \
|
There is no internet connection at the moment. \
|
||||||
Please reconnect or try again later.
|
Please reconnect or try again later.
|
||||||
"""),
|
"""),
|
||||||
dismissButton: .default(Text("OK"), action: {
|
dismissButton: .default(Text("OK"), action: {
|
||||||
model.isPresentingNetworkErrorAlert = false
|
model.isPresentingNetworkErrorAlert = false
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.navigationTitle(
|
.navigationTitle(
|
||||||
|
@ -2,6 +2,7 @@ import SwiftUI
|
|||||||
|
|
||||||
struct ActivePostToolbarView: View {
|
struct ActivePostToolbarView: View {
|
||||||
@EnvironmentObject var model: WriteFreelyModel
|
@EnvironmentObject var model: WriteFreelyModel
|
||||||
|
@ObservedObject var activePost: WFAPost
|
||||||
@State private var isPresentingSharingServicePicker: Bool = false
|
@State private var isPresentingSharingServicePicker: Bool = false
|
||||||
@State private var selectedCollection: WFACollection?
|
@State private var selectedCollection: WFACollection?
|
||||||
|
|
||||||
@ -11,100 +12,96 @@ struct ActivePostToolbarView: View {
|
|||||||
) var collections: FetchedResults<WFACollection>
|
) var collections: FetchedResults<WFACollection>
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
if let activePost = model.selectedPost {
|
HStack {
|
||||||
HStack {
|
if model.account.isLoggedIn &&
|
||||||
if model.account.isLoggedIn &&
|
activePost.status != PostStatus.local.rawValue &&
|
||||||
activePost.status != PostStatus.local.rawValue &&
|
!(activePost.wasDeletedFromServer || activePost.hasNewerRemoteCopy) {
|
||||||
!(activePost.wasDeletedFromServer || activePost.hasNewerRemoteCopy) {
|
Section(header: Text("Move To:")) {
|
||||||
Section(header: Text("Move To:")) {
|
Picker(selection: $selectedCollection, label: Text("Move To…"), content: {
|
||||||
Picker(selection: $selectedCollection, label: Text("Move To…"), content: {
|
Text("\(model.account.server == "https://write.as" ? "Anonymous" : "Drafts")")
|
||||||
Text("\(model.account.server == "https://write.as" ? "Anonymous" : "Drafts")")
|
.tag(nil as WFACollection?)
|
||||||
.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()
|
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: {
|
Button(action: {
|
||||||
if model.account.isLoggedIn {
|
if model.account.isLoggedIn {
|
||||||
withAnimation {
|
withAnimation {
|
||||||
activePost.collectionAlias = nil
|
activePost.collectionAlias = collection.alias
|
||||||
publishPost(activePost)
|
publishPost(activePost)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
openSettingsWindow()
|
openSettingsWindow()
|
||||||
}
|
}
|
||||||
}, label: {
|
}, label: {
|
||||||
Text("\(model.account.server == "https://write.as" ? "Anonymous" : "Drafts")")
|
Text("\(collection.title)")
|
||||||
})
|
})
|
||||||
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: {
|
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
}, label: {
|
||||||
|
Label("Publish…", systemImage: "paperplane")
|
||||||
|
})
|
||||||
|
.disabled(model.selectedPost?.body.isEmpty ?? true)
|
||||||
|
.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: {
|
||||||
|
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
EmptyView()
|
|
||||||
}
|
}
|
||||||
|
.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] {
|
private func createPostUrl() -> [Any] {
|
||||||
@ -117,6 +114,9 @@ struct ActivePostToolbarView: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private func publishPost(_ post: WFAPost) {
|
private func publishPost(_ post: WFAPost) {
|
||||||
|
if post != model.selectedPost {
|
||||||
|
return
|
||||||
|
}
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
LocalStorageManager().saveContext()
|
LocalStorageManager().saveContext()
|
||||||
model.publish(post: post)
|
model.publish(post: post)
|
||||||
|
Loading…
Reference in New Issue
Block a user