Replace Post type with WFAPost managed object

This commit is contained in:
Angelo Stavrow 2020-09-08 16:17:58 -04:00
parent 6728e20821
commit ca8e74b2dc
No known key found for this signature in database
GPG Key ID: 1A49C7064E060EEE
11 changed files with 426 additions and 391 deletions

View File

@ -19,6 +19,7 @@
<attribute name="body" attributeType="String"/>
<attribute name="collectionAlias" optional="YES" attributeType="String"/>
<attribute name="createdDate" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
<attribute name="hasNewerRemoteCopy" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
<attribute name="language" optional="YES" attributeType="String"/>
<attribute name="postId" optional="YES" attributeType="String"/>
<attribute name="rtl" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
@ -34,6 +35,6 @@
</entity>
<elements>
<element name="WFACollection" positionX="14.806640625" positionY="202.9156341552734" width="128" height="148"/>
<element name="WFAPost" positionX="287.377197265625" positionY="243.2452697753906" width="128" height="194"/>
<element name="WFAPost" positionX="287.377197265625" positionY="243.2452697753906" width="128" height="209"/>
</elements>
</model>

View File

@ -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<WFPost, Error>) {
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<WFPost, Error>) {
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)

View File

@ -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)
// }
//}

View File

@ -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

View File

@ -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())
// }
//}

View File

@ -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)
// }
//}

View File

@ -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<NSFetchRequestResult> = 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)
// }
// }
// }
}

View File

@ -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<WFAPost>
@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)
// }
// }
//}

View File

@ -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])
// }
//}

View File

@ -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
}

View File

@ -7,12 +7,12 @@
<key>WriteFreely-MultiPlatform (iOS).xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>0</integer>
<integer>1</integer>
</dict>
<key>WriteFreely-MultiPlatform (macOS).xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>1</integer>
<integer>0</integer>
</dict>
</dict>
</dict>