Restore updateFromServer functionality when remote copy is newer

This commit is contained in:
Angelo Stavrow 2020-09-08 17:29:55 -04:00
parent ca8e74b2dc
commit 12723fbaea
No known key found for this signature in database
GPG Key ID: 1A49C7064E060EEE
7 changed files with 46 additions and 103 deletions

View File

@ -19,13 +19,6 @@ class WriteFreelyModel: ObservableObject {
// Set the color scheme based on what's been saved in UserDefaults.
DispatchQueue.main.async {
self.preferences.appearance = self.defaults.integer(forKey: self.preferences.colorSchemeIntegerKey)
}
#if DEBUG
// for post in testPostData { store.add(post) }
#endif
DispatchQueue.main.async {
self.account.restoreState()
if self.account.isLoggedIn {
guard let serverURL = URL(string: self.account.server) else {
@ -88,8 +81,8 @@ extension WriteFreelyModel {
guard let loggedInClient = client else { return }
var wfPost = WFPost(
body: post.body ?? "",
title: post.title,
body: post.body,
title: post.title.isEmpty ? "" : post.title,
appearance: post.appearance,
language: post.language,
rtl: post.rtl,
@ -227,18 +220,31 @@ private extension WriteFreelyModel {
do {
let fetchedPosts = try result.get()
for fetchedPost in fetchedPosts {
let managedPost = WFAPost(context: PersistenceManager.persistentContainer.viewContext)
managedPost.postId = fetchedPost.postId
managedPost.slug = fetchedPost.slug
managedPost.appearance = fetchedPost.appearance
managedPost.language = fetchedPost.language
managedPost.rtl = fetchedPost.rtl ?? false
managedPost.createdDate = fetchedPost.createdDate
managedPost.updatedDate = fetchedPost.updatedDate
managedPost.title = fetchedPost.title
managedPost.body = fetchedPost.body
managedPost.collectionAlias = fetchedPost.collectionAlias
managedPost.status = PostStatus.published.rawValue
// For each fetched post, we
// 1. check to see if a matching post exists
if let managedPost = store.posts.first(where: { $0.postId == fetchedPost.postId }) {
// If it exists, we set the hasNewerRemoteCopy flag as appropriate.
if let fetchedPostUpdatedDate = fetchedPost.updatedDate,
let localPostUpdatedDate = managedPost.updatedDate {
managedPost.hasNewerRemoteCopy = fetchedPostUpdatedDate > localPostUpdatedDate
} else {
print("Error: could not determine which copy of post is newer")
}
} else {
// If it doesn't exist, we create the managed object.
let managedPost = WFAPost(context: PersistenceManager.persistentContainer.viewContext)
managedPost.postId = fetchedPost.postId
managedPost.slug = fetchedPost.slug
managedPost.appearance = fetchedPost.appearance
managedPost.language = fetchedPost.language
managedPost.rtl = fetchedPost.rtl ?? false
managedPost.createdDate = fetchedPost.createdDate
managedPost.updatedDate = fetchedPost.updatedDate
managedPost.title = fetchedPost.title ?? ""
managedPost.body = fetchedPost.body
managedPost.collectionAlias = fetchedPost.collectionAlias
managedPost.status = PostStatus.published.rawValue
}
}
DispatchQueue.main.async {
PersistenceManager().saveContext()
@ -265,7 +271,7 @@ private extension WriteFreelyModel {
cachedPost.rtl = fetchedPost.rtl ?? false
cachedPost.slug = fetchedPost.slug
cachedPost.status = PostStatus.published.rawValue
cachedPost.title = fetchedPost.title
cachedPost.title = fetchedPost.title ?? ""
cachedPost.updatedDate = fetchedPost.updatedDate
DispatchQueue.main.async {
PersistenceManager().saveContext()
@ -288,8 +294,9 @@ private extension WriteFreelyModel {
cachedPost.rtl = fetchedPost.rtl ?? false
cachedPost.slug = fetchedPost.slug
cachedPost.status = PostStatus.published.rawValue
cachedPost.title = fetchedPost.title
cachedPost.title = fetchedPost.title ?? ""
cachedPost.updatedDate = fetchedPost.updatedDate
cachedPost.hasNewerRemoteCopy = false
DispatchQueue.main.async {
PersistenceManager().saveContext()
}

View File

@ -19,7 +19,7 @@ struct PostEditorStatusToolbarView: View {
.font(.caption)
.foregroundColor(.secondary)
Button(action: {
model.updateFromServer(post: post)
model.updateFromServer(post: post) // FIXME: This shouldn't change post status after update
}, label: {
Image(systemName: "square.and.arrow.down")
})

View File

@ -2,31 +2,25 @@ import SwiftUI
struct PostEditorView: View {
@EnvironmentObject var model: WriteFreelyModel
@Environment(\.managedObjectContext) var moc
@ObservedObject var post: WFAPost
@State private var postTitle = ""
@State private var postBody = ""
var body: some View {
VStack {
TextEditor(text: $postTitle)
TextEditor(text: $post.title)
.font(.title)
.frame(height: 100)
.onChange(of: postTitle) { _ in
if post.status == PostStatus.published.rawValue && post.title != postTitle {
post.status = PostStatus.edited.rawValue
}
post.title = postTitle
}
TextEditor(text: $postBody)
.font(.body)
.onChange(of: postBody) { _ in
.onChange(of: post.title) { _ in
if post.status == PostStatus.published.rawValue {
post.status = PostStatus.edited.rawValue
}
}
TextEditor(text: $post.body)
.font(.body)
.onChange(of: post.body) { _ in
if post.status == PostStatus.published.rawValue {
post.status = PostStatus.edited.rawValue
}
post.body = postBody
}
}
.padding()
@ -43,10 +37,6 @@ struct PostEditorView: View {
})
}
}
.onAppear(perform: {
postTitle = post.title ?? ""
postBody = post.body ?? ""
})
.onDisappear(perform: {
if post.status == PostStatus.edited.rawValue {
DispatchQueue.main.async {

View File

@ -6,7 +6,7 @@ struct PostCellView: View {
var body: some View {
HStack {
VStack(alignment: .leading) {
Text(post.title ?? "")
Text(post.title)
.font(.headline)
.lineLimit(1)
Text(buildDateString(from: post.createdDate ?? Date()))

View File

@ -36,56 +36,4 @@ class PostListModel: ObservableObject {
print("Error: Failed to purge cached posts.")
}
}
// func add(_ post: WFAPost) {
// posts.append(post)
// }
// func update(_ post: WFAPost) {
// // Find the local copy in the store
// let localCopy = posts.first(where: { $0.id == post.id })
//
// // If there's a local copy, update the updatedDate property of its WFPost
// if let localCopy = localCopy {
// localCopy.wfPost.updatedDate = Date()
// } else {
// print("Error: Local copy not found")
// }
// }
// func replace(post: Post, with fetchedPost: WFPost) {
// // Find the local copy in the store.
// let localCopy = posts.first(where: { $0.id == post.id })
//
// // Replace the local copy's wfPost property with the fetched copy.
// if let localCopy = localCopy {
// localCopy.wfPost = fetchedPost
// DispatchQueue.main.async {
// localCopy.hasNewerRemoteCopy = false
// localCopy.status = .published
// }
// } else {
// print("Error: Local copy not found")
// }
// }
// func updateStore(with fetchedPosts: [Post]) {
// for fetchedPost in fetchedPosts {
// // Find the local copy in the store.
// let localCopy = posts.first(where: { $0.wfPost.postId == fetchedPost.wfPost.postId })
//
// // If there's a local copy, check which is newer; if not, add the fetched post to the store.
// if let localCopy = localCopy {
// // We do not discard the local copy; we simply set the hasNewerRemoteCopy flag accordingly.
// if let remoteCopyUpdatedDate = fetchedPost.wfPost.updatedDate,
// let localCopyUpdatedDate = localCopy.wfPost.updatedDate {
// localCopy.hasNewerRemoteCopy = remoteCopyUpdatedDate > localCopyUpdatedDate
// } else {
// print("Error: could not determine which copy of post is newer")
// }
// } else {
// add(fetchedPost)
// }
// }
// }
}

View File

@ -131,14 +131,12 @@ struct PostListView: View {
}
private func createNewLocalDraft() {
let post = Post()
let managedPost = WFAPost(context: PersistenceManager.persistentContainer.viewContext)
managedPost.createdDate = post.wfPost.createdDate
managedPost.title = post.wfPost.title
managedPost.body = post.wfPost.body
managedPost.createdDate = Date()
managedPost.title = ""
managedPost.body = ""
managedPost.status = PostStatus.local.rawValue
DispatchQueue.main.async {
// model.store.add(post)
PersistenceManager().saveContext()
}
}

View File

@ -16,7 +16,7 @@ extension WFAPost {
}
@NSManaged public var appearance: String?
@NSManaged public var body: String?
@NSManaged public var body: String
@NSManaged public var collectionAlias: String?
@NSManaged public var createdDate: Date?
@NSManaged public var language: String?
@ -24,7 +24,7 @@ extension WFAPost {
@NSManaged public var rtl: Bool
@NSManaged public var slug: String?
@NSManaged public var status: Int32
@NSManaged public var title: String?
@NSManaged public var title: String
@NSManaged public var updatedDate: Date?
@NSManaged public var hasNewerRemoteCopy: Bool