diff --git a/Shared/PostCollection/CollectionListView.swift b/Shared/PostCollection/CollectionListView.swift index 8096584..79d7047 100644 --- a/Shared/PostCollection/CollectionListView.swift +++ b/Shared/PostCollection/CollectionListView.swift @@ -1,120 +1,115 @@ import SwiftUI struct CollectionListView: View { @EnvironmentObject var model: WriteFreelyModel - @AppStorage("showAllPostsFlag") var showAllPostsFlag: Bool = false - @AppStorage("selectedCollectionURL") var selectedCollectionURL: URL? @FetchRequest( entity: WFACollection.entity(), sortDescriptors: [NSSortDescriptor(keyPath: \WFACollection.title, ascending: true)] ) var collections: FetchedResults var body: some View { List(selection: $model.selectedCollection) { if model.account.isLoggedIn { NavigationLink( destination: PostListView(), isActive: Binding( get: { () -> Bool in model.selectedCollection == nil && model.showAllPosts }, set: { newValue in if newValue { self.model.showAllPosts = true self.model.selectedCollection = nil } else { // No-op } } ), label: { Text("All Posts") }) NavigationLink( destination: PostListView(), isActive: Binding( get: { () -> Bool in model.selectedCollection == nil && !model.showAllPosts }, set: { newValue in if newValue { self.model.showAllPosts = false self.model.selectedCollection = nil } else { // No-op } } ), label: { Text(model.account.server == "https://write.as" ? "Anonymous" : "Drafts") }) Section(header: Text("Your Blogs")) { ForEach(collections, id: \.self) { collection in NavigationLink( destination: PostListView(), isActive: Binding( get: { () -> Bool in model.selectedCollection == collection && !model.showAllPosts }, set: { newValue in if newValue { self.model.showAllPosts = false self.model.selectedCollection = collection } else { // No-op } } ), label: { Text(collection.title) } ) } } } else { NavigationLink(destination: PostListView()) { Text("Drafts") } } } .navigationTitle( model.account.isLoggedIn ? "\(URL(string: model.account.server)?.host ?? "WriteFreely")" : "WriteFreely" ) .listStyle(SidebarListStyle()) .onAppear(perform: { #if os(iOS) - DispatchQueue.main.async { - self.model.showAllPosts = showAllPostsFlag - self.model.selectedCollection = fetchSelectedCollectionFromAppStorage() + if model.editor.showAllPostsFlag { + DispatchQueue.main.async { + self.model.selectedCollection = nil + self.model.showAllPosts = true + } + } else { + DispatchQueue.main.async { + self.model.selectedCollection = model.editor.fetchSelectedCollectionFromAppStorage() + self.model.showAllPosts = false + } } #endif }) .onChange(of: model.selectedCollection) { collection in - if collection != fetchSelectedCollectionFromAppStorage() { - self.selectedCollectionURL = collection?.objectID.uriRepresentation() + if collection != model.editor.fetchSelectedCollectionFromAppStorage() { + self.model.editor.selectedCollectionURL = collection?.objectID.uriRepresentation() } } .onChange(of: model.showAllPosts) { value in - if value != showAllPostsFlag { - self.showAllPostsFlag = model.showAllPosts + if value != model.editor.showAllPostsFlag { + self.model.editor.showAllPostsFlag = model.showAllPosts } } } - - private func fetchSelectedCollectionFromAppStorage() -> WFACollection? { - guard let objectURL = selectedCollectionURL else { return nil } - let coordinator = LocalStorageManager.persistentContainer.persistentStoreCoordinator - guard let managedObjectID = coordinator.managedObjectID(forURIRepresentation: objectURL) else { return nil } - guard let object = LocalStorageManager.persistentContainer.viewContext.object( - with: managedObjectID - ) as? WFACollection else { return nil } - return object - } } struct CollectionListView_LoggedOutPreviews: PreviewProvider { static var previews: some View { let context = LocalStorageManager.persistentContainer.viewContext let model = WriteFreelyModel() return CollectionListView() .environment(\.managedObjectContext, context) .environmentObject(model) } } diff --git a/Shared/PostList/PostListFilteredView.swift b/Shared/PostList/PostListFilteredView.swift index d6b35ac..dd11691 100644 --- a/Shared/PostList/PostListFilteredView.swift +++ b/Shared/PostList/PostListFilteredView.swift @@ -1,168 +1,157 @@ import SwiftUI struct PostListFilteredView: View { @EnvironmentObject var model: WriteFreelyModel - @AppStorage("selectedPostURL") var selectedPostURL: URL? @Binding var postCount: Int @FetchRequest(entity: WFACollection.entity(), sortDescriptors: []) var collections: FetchedResults var fetchRequest: FetchRequest init(collection: WFACollection?, showAllPosts: Bool, postCount: Binding) { if showAllPosts { fetchRequest = FetchRequest( entity: WFAPost.entity(), sortDescriptors: [NSSortDescriptor(key: "createdDate", ascending: false)] ) } else { if let collectionAlias = collection?.alias { fetchRequest = FetchRequest( entity: WFAPost.entity(), sortDescriptors: [NSSortDescriptor(key: "createdDate", ascending: false)], predicate: NSPredicate(format: "collectionAlias == %@", collectionAlias) ) } else { fetchRequest = FetchRequest( entity: WFAPost.entity(), sortDescriptors: [NSSortDescriptor(key: "createdDate", ascending: false)], predicate: NSPredicate(format: "collectionAlias == nil") ) } } _postCount = postCount } var body: some View { #if os(iOS) List(selection: $model.selectedPost) { ForEach(fetchRequest.wrappedValue, id: \.self) { post in NavigationLink( destination: PostEditorView(post: post), tag: post, selection: $model.selectedPost, label: { if model.showAllPosts { if let collection = collections.filter { $0.alias == post.collectionAlias }.first { PostCellView(post: post, collectionName: collection.title) } else { let collectionName = model.account.server == "https://write.as" ? "Anonymous" : "Drafts" PostCellView(post: post, collectionName: collectionName) } } else { PostCellView(post: post) } }) .deleteDisabled(post.status != PostStatus.local.rawValue) } .onDelete(perform: { indexSet in for index in indexSet { let post = fetchRequest.wrappedValue[index] delete(post) } }) } .onAppear(perform: { self.postCount = fetchRequest.wrappedValue.count DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { - self.model.selectedPost = fetchSelectedPostFromAppStorage() + self.model.selectedPost = model.editor.fetchSelectedPostFromAppStorage() } }) .onChange(of: fetchRequest.wrappedValue.count, perform: { value in self.postCount = value }) .onChange(of: model.selectedPost) { post in - if post != fetchSelectedPostFromAppStorage() { + if post != model.editor.fetchSelectedPostFromAppStorage() { saveSelectedPostURL(post) } } #else List(selection: $model.selectedPost) { ForEach(fetchRequest.wrappedValue, id: \.self) { post in NavigationLink( destination: PostEditorView(post: post), tag: post, selection: $model.selectedPost, label: { if model.showAllPosts { if let collection = collections.filter { $0.alias == post.collectionAlias }.first { PostCellView(post: post, collectionName: collection.title) } else { let collectionName = model.account.server == "https://write.as" ? "Anonymous" : "Drafts" PostCellView(post: post, collectionName: collectionName) } } else { PostCellView(post: post) } }) .deleteDisabled(post.status != PostStatus.local.rawValue) } .onDelete(perform: { indexSet in for index in indexSet { let post = fetchRequest.wrappedValue[index] delete(post) } }) } .alert(isPresented: $model.isPresentingDeleteAlert) { Alert( title: Text("Delete Post?"), message: Text("This action cannot be undone."), primaryButton: .cancel() { model.postToDelete = nil }, secondaryButton: .destructive(Text("Delete"), action: { if let postToDelete = model.postToDelete { model.selectedPost = nil DispatchQueue.main.async { model.editor.clearLastDraft() model.posts.remove(postToDelete) } model.postToDelete = nil } }) ) } .onDeleteCommand(perform: { guard let selectedPost = model.selectedPost else { return } if selectedPost.status == PostStatus.local.rawValue { model.postToDelete = selectedPost model.isPresentingDeleteAlert = true } }) .onChange(of: model.selectedPost) { post in if post != fetchSelectedPostFromAppStorage() { saveSelectedPostURL(post) } } #endif } private func saveSelectedPostURL(_ post: WFAPost?) { - self.selectedPostURL = post?.objectID.uriRepresentation() - } - - private func fetchSelectedPostFromAppStorage() -> WFAPost? { - guard let objectURL = selectedPostURL else { return nil } - let coordinator = LocalStorageManager.persistentContainer.persistentStoreCoordinator - guard let managedObjectID = coordinator.managedObjectID(forURIRepresentation: objectURL) else { return nil } - guard let object = LocalStorageManager.persistentContainer.viewContext.object( - with: managedObjectID - ) as? WFAPost else { return nil } - return object + self.model.editor.selectedPostURL = post?.objectID.uriRepresentation() } func delete(_ post: WFAPost) { DispatchQueue.main.async { if post == model.selectedPost { model.selectedPost = nil model.editor.clearLastDraft() } model.posts.remove(post) } } } struct PostListFilteredView_Previews: PreviewProvider { static var previews: some View { return PostListFilteredView(collection: nil, showAllPosts: false, postCount: .constant(999)) } }