diff --git a/Shared/Models/LocalStorageModel.xcdatamodeld/LocalStorageModel.xcdatamodel/contents b/Shared/Models/LocalStorageModel.xcdatamodeld/LocalStorageModel.xcdatamodel/contents index 92bd8c1..ff8b974 100644 --- a/Shared/Models/LocalStorageModel.xcdatamodeld/LocalStorageModel.xcdatamodel/contents +++ b/Shared/Models/LocalStorageModel.xcdatamodeld/LocalStorageModel.xcdatamodel/contents @@ -19,6 +19,7 @@ + @@ -34,6 +35,6 @@ - + \ No newline at end of file diff --git a/Shared/Models/WriteFreelyModel.swift b/Shared/Models/WriteFreelyModel.swift index 1fdb457..baf1dd3 100644 --- a/Shared/Models/WriteFreelyModel.swift +++ b/Shared/Models/WriteFreelyModel.swift @@ -10,7 +10,7 @@ class WriteFreelyModel: ObservableObject { @Published var store = PostListModel() @Published var collections = CollectionListModel() @Published var isLoggingIn: Bool = false - @Published var selectedPost: Post? + @Published var selectedPost: WFAPost? private var client: WFClient? private let defaults = UserDefaults.standard @@ -84,27 +84,41 @@ extension WriteFreelyModel { loggedInClient.getPosts(completion: fetchUserPostsHandler) } - func publish(post: Post) { + func publish(post: WFAPost) { guard let loggedInClient = client else { return } - if let existingPostId = post.wfPost.postId { + var wfPost = WFPost( + body: post.body ?? "", + title: post.title, + appearance: post.appearance, + language: post.language, + rtl: post.rtl, + createdDate: post.createdDate + ) + + if let existingPostId = post.postId { // This is an existing post. + wfPost.postId = post.postId + wfPost.slug = post.slug + wfPost.updatedDate = post.updatedDate + wfPost.collectionAlias = post.collectionAlias + loggedInClient.updatePost( postId: existingPostId, - updatedPost: post.wfPost, + updatedPost: wfPost, completion: publishHandler ) } else { // This is a new local draft. loggedInClient.createPost( - post: post.wfPost, in: post.collection?.alias, completion: publishHandler + post: wfPost, in: post.collectionAlias, completion: publishHandler ) } } - func updateFromServer(post: Post) { + func updateFromServer(post: WFAPost) { guard let loggedInClient = client else { return } - guard let postId = post.wfPost.postId else { return } + guard let postId = post.postId else { return } DispatchQueue.main.async { self.selectedPost = post } @@ -212,18 +226,7 @@ private extension WriteFreelyModel { func fetchUserPostsHandler(result: Result<[WFPost], Error>) { do { let fetchedPosts = try result.get() - var fetchedPostsArray: [Post] = [] for fetchedPost in fetchedPosts { - var post: Post - if let matchingAlias = fetchedPost.collectionAlias { - let matchingCachedCollection = ( - collections.userCollections.filter { $0.alias == matchingAlias } - ).first - post = Post(wfPost: fetchedPost, in: matchingCachedCollection) - } else { - post = Post(wfPost: fetchedPost) - } - fetchedPostsArray.append(post) let managedPost = WFAPost(context: PersistenceManager.persistentContainer.viewContext) managedPost.postId = fetchedPost.postId managedPost.slug = fetchedPost.slug @@ -235,10 +238,9 @@ private extension WriteFreelyModel { managedPost.title = fetchedPost.title managedPost.body = fetchedPost.body managedPost.collectionAlias = fetchedPost.collectionAlias - managedPost.status = PostStatus.published.rawValue // 0 = local, 1 = edited, 2 = published + managedPost.status = PostStatus.published.rawValue } DispatchQueue.main.async { - self.store.updateStore(with: fetchedPostsArray) PersistenceManager().saveContext() } } catch { @@ -248,13 +250,25 @@ private extension WriteFreelyModel { func publishHandler(result: Result) { do { - let wfPost = try result.get() + let fetchedPost = try result.get() let foundPostIndex = store.posts.firstIndex(where: { - $0.wfPost.title == wfPost.title && $0.wfPost.body == wfPost.body + $0.title == fetchedPost.title && $0.body == fetchedPost.body }) guard let index = foundPostIndex else { return } + let cachedPost = self.store.posts[index] + cachedPost.appearance = fetchedPost.appearance + cachedPost.body = fetchedPost.body + cachedPost.collectionAlias = fetchedPost.collectionAlias + 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 { - self.store.posts[index].wfPost = wfPost + PersistenceManager().saveContext() } } catch { print(error) @@ -264,9 +278,20 @@ private extension WriteFreelyModel { func updateFromServerHandler(result: Result) { do { let fetchedPost = try result.get() + guard let cachedPost = self.selectedPost else { return } + cachedPost.appearance = fetchedPost.appearance + cachedPost.body = fetchedPost.body + cachedPost.collectionAlias = fetchedPost.collectionAlias + 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 { - guard let selectedPost = self.selectedPost else { return } - self.store.replace(post: selectedPost, with: fetchedPost) + PersistenceManager().saveContext() } } catch { print(error) diff --git a/Shared/Navigation/ContentView.swift b/Shared/Navigation/ContentView.swift index d95911c..88e9cf6 100644 --- a/Shared/Navigation/ContentView.swift +++ b/Shared/Navigation/ContentView.swift @@ -16,23 +16,23 @@ struct ContentView: View { } } -struct ContentView_Previews: PreviewProvider { - static var previews: some View { - let userCollection1 = WFACollection(context: PersistenceManager.persistentContainer.viewContext) - let userCollection2 = WFACollection(context: PersistenceManager.persistentContainer.viewContext) - let userCollection3 = WFACollection(context: PersistenceManager.persistentContainer.viewContext) - userCollection1.title = "Collection 1" - userCollection2.title = "Collection 2" - userCollection3.title = "Collection 3" - - let model = WriteFreelyModel() - model.collections = CollectionListModel() - - for post in testPostData { - model.store.add(post) - } - return ContentView() - .environmentObject(model) - .environment(\.managedObjectContext, PersistenceManager.persistentContainer.viewContext) - } -} +//struct ContentView_Previews: PreviewProvider { +// static var previews: some View { +// let userCollection1 = WFACollection(context: PersistenceManager.persistentContainer.viewContext) +// let userCollection2 = WFACollection(context: PersistenceManager.persistentContainer.viewContext) +// let userCollection3 = WFACollection(context: PersistenceManager.persistentContainer.viewContext) +// userCollection1.title = "Collection 1" +// userCollection2.title = "Collection 2" +// userCollection3.title = "Collection 3" +// +// let model = WriteFreelyModel() +// model.collections = CollectionListModel() +// +// for post in testPostData { +// model.store.add(post) +// } +// return ContentView() +// .environmentObject(model) +// .environment(\.managedObjectContext, PersistenceManager.persistentContainer.viewContext) +// } +//} diff --git a/Shared/PostEditor/PostEditorStatusToolbarView.swift b/Shared/PostEditor/PostEditorStatusToolbarView.swift index 8c09962..85c5e65 100644 --- a/Shared/PostEditor/PostEditorStatusToolbarView.swift +++ b/Shared/PostEditor/PostEditorStatusToolbarView.swift @@ -6,7 +6,7 @@ struct PostEditorStatusToolbarView: View { #endif @EnvironmentObject var model: WriteFreelyModel - @ObservedObject var post: Post + @ObservedObject var post: WFAPost var body: some View { if post.hasNewerRemoteCopy { @@ -61,76 +61,76 @@ struct PostEditorStatusToolbarView: View { } } -#if DEBUG -let testPost = Post( - title: "Test Post Title", - body: """ - Here's some cool sample body text. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean ultrices \ - posuere dignissim. Vestibulum a libero tempor, lacinia nulla vitae, congue purus. Nunc ac nulla quam. Duis \ - tincidunt eros augue, et volutpat tortor pulvinar ut. Nullam sit amet maximus urna. Phasellus non dignissim lacus.\ - Nulla ac posuere ex. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec \ - non molestie mauris. Suspendisse potenti. Vivamus at erat turpis. - - Pellentesque porttitor gravida tincidunt. Sed vitae eros non metus aliquam hendrerit. Aliquam sed risus suscipit \ - turpis dictum dictum. Duis lacus lectus, dictum vel felis in, rhoncus fringilla felis. Nunc id dolor nisl. Aliquam \ - euismod purus elit. Nullam egestas neque leo, sed aliquet ligula ultrices nec. - """, - createdDate: Date() -) -#endif - -struct ToolbarView_LocalPreviews: PreviewProvider { - static var previews: some View { - let model = WriteFreelyModel() - let post = testPost - return PostEditorStatusToolbarView(post: post) - .environmentObject(model) - } -} - -struct ToolbarView_RemotePreviews: PreviewProvider { - static var previews: some View { - let model = WriteFreelyModel() - let newerRemotePost = Post( - title: testPost.wfPost.title ?? "", - body: testPost.wfPost.body, - createdDate: testPost.wfPost.createdDate ?? Date(), - status: testPost.status, - collection: testPost.collection - ) - newerRemotePost.hasNewerRemoteCopy = true - return PostEditorStatusToolbarView(post: newerRemotePost) - .environmentObject(model) - } -} - -#if os(iOS) -struct ToolbarView_CompactLocalPreviews: PreviewProvider { - static var previews: some View { - let model = WriteFreelyModel() - let post = testPost - return PostEditorStatusToolbarView(post: post) - .environmentObject(model) - .environment(\.horizontalSizeClass, .compact) - } -} -#endif - -#if os(iOS) -struct ToolbarView_CompactRemotePreviews: PreviewProvider { - static var previews: some View { - let model = WriteFreelyModel() - let newerRemotePost = Post( - title: testPost.wfPost.title ?? "", - body: testPost.wfPost.body, - createdDate: testPost.wfPost.createdDate ?? Date(), - status: testPost.status, - collection: testPost.collection - ) - newerRemotePost.hasNewerRemoteCopy = true - return PostEditorStatusToolbarView(post: newerRemotePost) - .environmentObject(model) - .environment(\.horizontalSizeClass, .compact) - } -} -#endif +//#if DEBUG +//let testPost = Post( +// title: "Test Post Title", +// body: """ +// Here's some cool sample body text. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean ultrices \ +// posuere dignissim. Vestibulum a libero tempor, lacinia nulla vitae, congue purus. Nunc ac nulla quam. Duis \ +// tincidunt eros augue, et volutpat tortor pulvinar ut. Nullam sit amet maximus urna. Phasellus non dignissim \ +// lacus. Nulla ac posuere ex. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus \ +// mus. Donec non molestie mauris. Suspendisse potenti. Vivamus at erat turpis. +// +// Pellentesque porttitor gravida tincidunt. Sed vitae eros non metus aliquam hendrerit. Aliquam sed risus suscipit \ +// turpis dictum dictum. Duis lacus lectus, dictum vel felis in, rhoncus fringilla felis. Nunc id dolor nisl. \ +// Aliquam euismod purus elit. Nullam egestas neque leo, sed aliquet ligula ultrices nec. +// """, +// createdDate: Date() +//) +//#endif +// +//struct ToolbarView_LocalPreviews: PreviewProvider { +// static var previews: some View { +// let model = WriteFreelyModel() +// let post = testPost +// return PostEditorStatusToolbarView(post: post) +// .environmentObject(model) +// } +//} +// +//struct ToolbarView_RemotePreviews: PreviewProvider { +// static var previews: some View { +// let model = WriteFreelyModel() +// let newerRemotePost = Post( +// title: testPost.wfPost.title ?? "", +// body: testPost.wfPost.body, +// createdDate: testPost.wfPost.createdDate ?? Date(), +// status: testPost.status, +// collection: testPost.collection +// ) +// newerRemotePost.hasNewerRemoteCopy = true +// return PostEditorStatusToolbarView(post: newerRemotePost) +// .environmentObject(model) +// } +//} +// +//#if os(iOS) +//struct ToolbarView_CompactLocalPreviews: PreviewProvider { +// static var previews: some View { +// let model = WriteFreelyModel() +// let post = testPost +// return PostEditorStatusToolbarView(post: post) +// .environmentObject(model) +// .environment(\.horizontalSizeClass, .compact) +// } +//} +//#endif +// +//#if os(iOS) +//struct ToolbarView_CompactRemotePreviews: PreviewProvider { +// static var previews: some View { +// let model = WriteFreelyModel() +// let newerRemotePost = Post( +// title: testPost.wfPost.title ?? "", +// body: testPost.wfPost.body, +// createdDate: testPost.wfPost.createdDate ?? Date(), +// status: testPost.status, +// collection: testPost.collection +// ) +// newerRemotePost.hasNewerRemoteCopy = true +// return PostEditorStatusToolbarView(post: newerRemotePost) +// .environmentObject(model) +// .environment(\.horizontalSizeClass, .compact) +// } +//} +//#endif diff --git a/Shared/PostEditor/PostEditorView.swift b/Shared/PostEditor/PostEditorView.swift index 6b9911b..9fcd55d 100644 --- a/Shared/PostEditor/PostEditorView.swift +++ b/Shared/PostEditor/PostEditorView.swift @@ -2,28 +2,31 @@ import SwiftUI struct PostEditorView: View { @EnvironmentObject var model: WriteFreelyModel + @Environment(\.managedObjectContext) var moc - @ObservedObject var post: Post + @ObservedObject var post: WFAPost + + @State private var postTitle = "" + @State private var postBody = "" - @State private var isNewPost = false - @State private var title = "" var body: some View { VStack { - TextEditor(text: $title) + TextEditor(text: $postTitle) .font(.title) .frame(height: 100) - .onChange(of: title) { _ in - if post.status == .published && post.wfPost.title != title { - post.status = .edited + .onChange(of: postTitle) { _ in + if post.status == PostStatus.published.rawValue && post.title != postTitle { + post.status = PostStatus.edited.rawValue } - post.wfPost.title = title + post.title = postTitle } - TextEditor(text: $post.wfPost.body) + TextEditor(text: $postBody) .font(.body) - .onChange(of: post.wfPost.body) { _ in - if post.status == .published { - post.status = .edited + .onChange(of: postBody) { _ in + if post.status == PostStatus.published.rawValue { + post.status = PostStatus.edited.rawValue } + post.body = postBody } } .padding() @@ -34,65 +37,51 @@ struct PostEditorView: View { ToolbarItem(placement: .primaryAction) { Button(action: { model.publish(post: post) - post.status = .published + post.status = PostStatus.published.rawValue }, label: { Image(systemName: "paperplane") }) } } .onAppear(perform: { - title = post.wfPost.title ?? "" - checkIfNewPost() - if self.isNewPost { - addNewPostToStore() - } + postTitle = post.title ?? "" + postBody = post.body ?? "" }) .onDisappear(perform: { - if post.status == .edited { + if post.status == PostStatus.edited.rawValue { DispatchQueue.main.async { - model.store.update(post) + PersistenceManager().saveContext() } } }) } - - private func checkIfNewPost() { - self.isNewPost = !model.store.posts.contains(where: { $0.id == post.id }) - } - - private func addNewPostToStore() { - withAnimation { - model.store.add(post) - self.isNewPost = false - } - } } -struct PostEditorView_NewLocalDraftPreviews: PreviewProvider { - static var previews: some View { - PostEditorView(post: Post()) - .environmentObject(WriteFreelyModel()) - } -} - -struct PostEditorView_NewerLocalPostPreviews: PreviewProvider { - static var previews: some View { - return PostEditorView(post: testPost) - .environmentObject(WriteFreelyModel()) - } -} - -struct PostEditorView_NewerRemotePostPreviews: PreviewProvider { - static var previews: some View { - let newerRemotePost = Post( - title: testPost.wfPost.title ?? "", - body: testPost.wfPost.body, - createdDate: testPost.wfPost.createdDate ?? Date(), - status: testPost.status, - collection: testPost.collection - ) - newerRemotePost.hasNewerRemoteCopy = true - return PostEditorView(post: newerRemotePost) - .environmentObject(WriteFreelyModel()) - } -} +//struct PostEditorView_NewLocalDraftPreviews: PreviewProvider { +// static var previews: some View { +// PostEditorView(post: Post()) +// .environmentObject(WriteFreelyModel()) +// } +//} +// +//struct PostEditorView_NewerLocalPostPreviews: PreviewProvider { +// static var previews: some View { +// return PostEditorView(post: testPost) +// .environmentObject(WriteFreelyModel()) +// } +//} +// +//struct PostEditorView_NewerRemotePostPreviews: PreviewProvider { +// static var previews: some View { +// let newerRemotePost = Post( +// title: testPost.wfPost.title ?? "", +// body: testPost.wfPost.body, +// createdDate: testPost.wfPost.createdDate ?? Date(), +// status: testPost.status, +// collection: testPost.collection +// ) +// newerRemotePost.hasNewerRemoteCopy = true +// return PostEditorView(post: newerRemotePost) +// .environmentObject(WriteFreelyModel()) +// } +//} diff --git a/Shared/PostList/PostCellView.swift b/Shared/PostList/PostCellView.swift index 00122ff..535260e 100644 --- a/Shared/PostList/PostCellView.swift +++ b/Shared/PostList/PostCellView.swift @@ -1,15 +1,15 @@ import SwiftUI struct PostCellView: View { - @ObservedObject var post: Post + @ObservedObject var post: WFAPost var body: some View { HStack { VStack(alignment: .leading) { - Text(post.wfPost.title ?? "") + Text(post.title ?? "") .font(.headline) .lineLimit(1) - Text(buildDateString(from: post.wfPost.createdDate ?? Date())) + Text(buildDateString(from: post.createdDate ?? Date())) .font(.caption) .lineLimit(1) } @@ -28,13 +28,13 @@ struct PostCellView: View { } } -struct PostCell_Previews: PreviewProvider { - static var previews: some View { - let testPost = Post( - title: "Test Post Title", - body: "Here's some cool sample body text.", - createdDate: Date() - ) - return PostCellView(post: testPost) - } -} +//struct PostCell_Previews: PreviewProvider { +// static var previews: some View { +// let testPost = Post( +// title: "Test Post Title", +// body: "Here's some cool sample body text.", +// createdDate: Date() +// ) +// return PostCellView(post: testPost) +// } +//} diff --git a/Shared/PostList/PostListModel.swift b/Shared/PostList/PostListModel.swift index 442c692..3f2d9c9 100644 --- a/Shared/PostList/PostListModel.swift +++ b/Shared/PostList/PostListModel.swift @@ -2,18 +2,28 @@ import Foundation import WriteFreely import CoreData -struct PostListModel { - var posts: [Post] +class PostListModel: ObservableObject { + @Published var posts = [WFAPost]() - init(posts: [Post] = []) { - self.posts = posts + init() { + loadCachedPosts() } - mutating func add(_ post: Post) { - posts.append(post) + func loadCachedPosts() { + let request = WFAPost.createFetchRequest() + let sort = NSSortDescriptor(key: "createdDate", ascending: false) + request.sortDescriptors = [sort] + + posts = [] + do { + let cachedPosts = try PersistenceManager.persistentContainer.viewContext.fetch(request) + posts.append(contentsOf: cachedPosts) + } catch { + print("Error: Failed to fetch cached posts.") + } } - mutating func purgeAllPosts() { + func purgeAllPosts() { posts = [] let fetchRequest: NSFetchRequest = NSFetchRequest(entityName: "WFAPost") let deleteRequest = NSBatchDeleteRequest(fetchRequest: fetchRequest) @@ -27,51 +37,55 @@ struct PostListModel { } } - mutating func update(_ post: Post) { - // Find the local copy in the store - let localCopy = posts.first(where: { $0.id == post.id }) +// func add(_ post: WFAPost) { +// posts.append(post) +// } - // 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 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") +// } +// } - mutating func replace(post: Post, with fetchedPost: WFPost) { - // Find the local copy in the store. - let localCopy = posts.first(where: { $0.id == post.id }) +// 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") +// } +// } - // 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") - } - } - - mutating 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) - } - } - } +// 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) +// } +// } +// } } diff --git a/Shared/PostList/PostListView.swift b/Shared/PostList/PostListView.swift index 48c5500..81d23b6 100644 --- a/Shared/PostList/PostListView.swift +++ b/Shared/PostList/PostListView.swift @@ -2,6 +2,13 @@ import SwiftUI struct PostListView: View { @EnvironmentObject var model: WriteFreelyModel + @Environment(\.managedObjectContext) var moc + + @FetchRequest( + entity: WFAPost.entity(), + sortDescriptors: [NSSortDescriptor(keyPath: \WFAPost.createdDate, ascending: true)] + ) var posts: FetchedResults + @State var selectedCollection: WFACollection? @State var showAllPosts: Bool = false @@ -14,12 +21,8 @@ struct PostListView: View { GeometryReader { geometry in List { ForEach(showPosts(for: selectedCollection)) { post in - NavigationLink( - destination: PostEditorView(post: post) - ) { - PostCellView( - post: post - ) + NavigationLink(destination: PostEditorView(post: post)) { + PostCellView(post: post) } } } @@ -72,12 +75,8 @@ struct PostListView: View { #else //if os(macOS) List { ForEach(showPosts(for: selectedCollection)) { post in - NavigationLink( - destination: PostEditorView(post: post) - ) { - PostCellView( - post: post - ) + NavigationLink(destination: PostEditorView(post: post)) { + PostCellView(post: post) } } } @@ -103,7 +102,7 @@ struct PostListView: View { #endif } - private func pluralizedPostCount(for posts: [Post]) -> String { + private func pluralizedPostCount(for posts: [WFAPost]) -> String { if posts.count == 1 { return "1 post" } else { @@ -111,17 +110,15 @@ struct PostListView: View { } } - private func showPosts(for collection: WFACollection?) -> [Post] { + private func showPosts(for collection: WFACollection?) -> [WFAPost] { if showAllPosts { return model.store.posts } else { - var posts: [Post] if let selectedCollection = collection { - posts = model.store.posts.filter { $0.wfPost.collectionAlias == selectedCollection.alias } + return model.store.posts.filter { $0.collectionAlias == selectedCollection.alias } } else { - posts = model.store.posts.filter { $0.wfPost.collectionAlias == nil } + return model.store.posts.filter { $0.collectionAlias == nil } } - return posts } } @@ -141,69 +138,69 @@ struct PostListView: View { managedPost.body = post.wfPost.body managedPost.status = PostStatus.local.rawValue DispatchQueue.main.async { - model.store.add(post) +// model.store.add(post) PersistenceManager().saveContext() } } } -struct PostList_Previews: PreviewProvider { - static var previews: some View { - let userCollection1 = WFACollection(context: PersistenceManager.persistentContainer.viewContext) - let userCollection2 = WFACollection(context: PersistenceManager.persistentContainer.viewContext) - let userCollection3 = WFACollection(context: PersistenceManager.persistentContainer.viewContext) - - userCollection1.title = "Collection 1" - userCollection2.title = "Collection 2" - userCollection3.title = "Collection 3" - - let testPostData = [ - Post( - title: "My First Post", - body: "Look at me, creating a first post! That's cool.", - createdDate: Date(timeIntervalSince1970: 1595429452), - status: .published, - collection: userCollection1 - ), - Post( - title: "Post 2: The Quickening", - body: "See, here's the rule about Highlander jokes: _there can be only one_.", - createdDate: Date(timeIntervalSince1970: 1595514125), - status: .edited, - collection: userCollection1 - ), - Post( - title: "The Post Revolutions", - body: "I can never keep the Matrix movie order straight. Why not just call them part 2 and part 3?", - createdDate: Date(timeIntervalSince1970: 1595600006) - ), - Post( - title: "Episode IV: A New Post", - body: "How many movies does this person watch? How many movie-title jokes will they make?", - createdDate: Date(timeIntervalSince1970: 1596219877), - status: .published, - collection: userCollection2 - ), - Post( - title: "Fast (Post) Five", - body: "Look, it was either a Fast and the Furious reference, or a Resident Evil reference." - ), - Post( - title: "Post: The Final Chapter", - body: "And there you have it, a Resident Evil movie reference.", - createdDate: Date(timeIntervalSince1970: 1596043684), - status: .edited, - collection: userCollection3 - ) - ] - - let model = WriteFreelyModel() - for post in testPostData { - model.store.add(post) - } - return Group { - PostListView(selectedCollection: userCollection1) - .environmentObject(model) - } - } -} +//struct PostList_Previews: PreviewProvider { +// static var previews: some View { +// let userCollection1 = WFACollection(context: PersistenceManager.persistentContainer.viewContext) +// let userCollection2 = WFACollection(context: PersistenceManager.persistentContainer.viewContext) +// let userCollection3 = WFACollection(context: PersistenceManager.persistentContainer.viewContext) +// +// userCollection1.title = "Collection 1" +// userCollection2.title = "Collection 2" +// userCollection3.title = "Collection 3" +// +// let testPostData = [ +// Post( +// title: "My First Post", +// body: "Look at me, creating a first post! That's cool.", +// createdDate: Date(timeIntervalSince1970: 1595429452), +// status: .published, +// collection: userCollection1 +// ), +// Post( +// title: "Post 2: The Quickening", +// body: "See, here's the rule about Highlander jokes: _there can be only one_.", +// createdDate: Date(timeIntervalSince1970: 1595514125), +// status: .edited, +// collection: userCollection1 +// ), +// Post( +// title: "The Post Revolutions", +// body: "I can never keep the Matrix movie order straight. Why not just call them part 2 and part 3?", +// createdDate: Date(timeIntervalSince1970: 1595600006) +// ), +// Post( +// title: "Episode IV: A New Post", +// body: "How many movies does this person watch? How many movie-title jokes will they make?", +// createdDate: Date(timeIntervalSince1970: 1596219877), +// status: .published, +// collection: userCollection2 +// ), +// Post( +// title: "Fast (Post) Five", +// body: "Look, it was either a Fast and the Furious reference, or a Resident Evil reference." +// ), +// Post( +// title: "Post: The Final Chapter", +// body: "And there you have it, a Resident Evil movie reference.", +// createdDate: Date(timeIntervalSince1970: 1596043684), +// status: .edited, +// collection: userCollection3 +// ) +// ] +// +// let model = WriteFreelyModel() +// for post in testPostData { +// model.store.add(post) +// } +// return Group { +// PostListView(selectedCollection: userCollection1) +// .environmentObject(model) +// } +// } +//} diff --git a/Shared/PostList/PostStatusBadgeView.swift b/Shared/PostList/PostStatusBadgeView.swift index d7f0ac9..6681ced 100644 --- a/Shared/PostList/PostStatusBadgeView.swift +++ b/Shared/PostList/PostStatusBadgeView.swift @@ -1,10 +1,10 @@ import SwiftUI struct PostStatusBadgeView: View { - @ObservedObject var post: Post + @ObservedObject var post: WFAPost var body: some View { - let (badgeLabel, badgeColor) = setupBadgeProperties(for: post.status) + let (badgeLabel, badgeColor) = setupBadgeProperties(for: PostStatus(rawValue: post.status)!) Text(badgeLabel) .font(.caption) .fontWeight(.semibold) @@ -36,68 +36,68 @@ struct PostStatusBadgeView: View { } } -#if DEBUG -let userCollection1 = WFACollection(context: PersistenceManager.persistentContainer.viewContext) -let userCollection2 = WFACollection(context: PersistenceManager.persistentContainer.viewContext) -let userCollection3 = WFACollection(context: PersistenceManager.persistentContainer.viewContext) - -let testPostData = [ - Post( - title: "My First Post", - body: "Look at me, creating a first post! That's cool.", - createdDate: Date(timeIntervalSince1970: 1595429452), - status: .published, - collection: userCollection1 - ), - Post( - title: "Post 2: The Quickening", - body: "See, here's the rule about Highlander jokes: _there can be only one_.", - createdDate: Date(timeIntervalSince1970: 1595514125), - status: .edited, - collection: userCollection1 - ), - Post( - title: "The Post Revolutions", - body: "I can never keep the Matrix movie order straight. Why not just call them part 2 and part 3?", - createdDate: Date(timeIntervalSince1970: 1595600006) - ), - Post( - title: "Episode IV: A New Post", - body: "How many movies does this person watch? How many movie-title jokes will they make?", - createdDate: Date(timeIntervalSince1970: 1596219877), - status: .published, - collection: userCollection2 - ), - Post( - title: "Fast (Post) Five", - body: "Look, it was either a Fast and the Furious reference, or a Resident Evil reference." - ), - Post( - title: "Post: The Final Chapter", - body: "And there you have it, a Resident Evil movie reference.", - createdDate: Date(timeIntervalSince1970: 1596043684), - status: .edited, - collection: userCollection3 - ) -] -#endif - -struct PostStatusBadge_LocalDraftPreviews: PreviewProvider { - static var previews: some View { - userCollection1.title = "Collection 1" - return PostStatusBadgeView(post: testPostData[2]) - } -} - -struct PostStatusBadge_EditedPreviews: PreviewProvider { - static var previews: some View { - userCollection1.title = "Collection 1" - return PostStatusBadgeView(post: testPostData[1]) - } -} - -struct PostStatusBadge_PublishedPreviews: PreviewProvider { - static var previews: some View { - PostStatusBadgeView(post: testPostData[0]) - } -} +//#if DEBUG +//let userCollection1 = WFACollection(context: PersistenceManager.persistentContainer.viewContext) +//let userCollection2 = WFACollection(context: PersistenceManager.persistentContainer.viewContext) +//let userCollection3 = WFACollection(context: PersistenceManager.persistentContainer.viewContext) +// +//let testPostData = [ +// Post( +// title: "My First Post", +// body: "Look at me, creating a first post! That's cool.", +// createdDate: Date(timeIntervalSince1970: 1595429452), +// status: .published, +// collection: userCollection1 +// ), +// Post( +// title: "Post 2: The Quickening", +// body: "See, here's the rule about Highlander jokes: _there can be only one_.", +// createdDate: Date(timeIntervalSince1970: 1595514125), +// status: .edited, +// collection: userCollection1 +// ), +// Post( +// title: "The Post Revolutions", +// body: "I can never keep the Matrix movie order straight. Why not just call them part 2 and part 3?", +// createdDate: Date(timeIntervalSince1970: 1595600006) +// ), +// Post( +// title: "Episode IV: A New Post", +// body: "How many movies does this person watch? How many movie-title jokes will they make?", +// createdDate: Date(timeIntervalSince1970: 1596219877), +// status: .published, +// collection: userCollection2 +// ), +// Post( +// title: "Fast (Post) Five", +// body: "Look, it was either a Fast and the Furious reference, or a Resident Evil reference." +// ), +// Post( +// title: "Post: The Final Chapter", +// body: "And there you have it, a Resident Evil movie reference.", +// createdDate: Date(timeIntervalSince1970: 1596043684), +// status: .edited, +// collection: userCollection3 +// ) +//] +//#endif +// +//struct PostStatusBadge_LocalDraftPreviews: PreviewProvider { +// static var previews: some View { +// userCollection1.title = "Collection 1" +// return PostStatusBadgeView(post: testPostData[2]) +// } +//} +// +//struct PostStatusBadge_EditedPreviews: PreviewProvider { +// static var previews: some View { +// userCollection1.title = "Collection 1" +// return PostStatusBadgeView(post: testPostData[1]) +// } +//} +// +//struct PostStatusBadge_PublishedPreviews: PreviewProvider { +// static var previews: some View { +// PostStatusBadgeView(post: testPostData[0]) +// } +//} diff --git a/WFAPost+CoreDataProperties.swift b/WFAPost+CoreDataProperties.swift index ba31720..d7ef424 100644 --- a/WFAPost+CoreDataProperties.swift +++ b/WFAPost+CoreDataProperties.swift @@ -1,3 +1,11 @@ +// +// WFAPost+CoreDataProperties.swift +// WriteFreely-MultiPlatform +// +// Created by Angelo Stavrow on 2020-09-08. +// +// + import Foundation import CoreData @@ -18,6 +26,7 @@ extension WFAPost { @NSManaged public var status: Int32 @NSManaged public var title: String? @NSManaged public var updatedDate: Date? + @NSManaged public var hasNewerRemoteCopy: Bool } diff --git a/WriteFreely-MultiPlatform.xcodeproj/xcuserdata/angelo.xcuserdatad/xcschemes/xcschememanagement.plist b/WriteFreely-MultiPlatform.xcodeproj/xcuserdata/angelo.xcuserdatad/xcschemes/xcschememanagement.plist index 2723ebe..6cd8075 100644 --- a/WriteFreely-MultiPlatform.xcodeproj/xcuserdata/angelo.xcuserdatad/xcschemes/xcschememanagement.plist +++ b/WriteFreely-MultiPlatform.xcodeproj/xcuserdata/angelo.xcuserdatad/xcschemes/xcschememanagement.plist @@ -7,12 +7,12 @@ WriteFreely-MultiPlatform (iOS).xcscheme_^#shared#^_ orderHint - 0 + 1 WriteFreely-MultiPlatform (macOS).xcscheme_^#shared#^_ orderHint - 1 + 0