diff --git a/Shared/PostList/PostListFilteredView.swift b/Shared/PostList/PostListFilteredView.swift index bb42ba3..6b37511 100644 --- a/Shared/PostList/PostListFilteredView.swift +++ b/Shared/PostList/PostListFilteredView.swift @@ -1,101 +1,114 @@ import SwiftUI struct PostListFilteredView: View { @EnvironmentObject var model: WriteFreelyModel - + @Binding var postCount: Int @FetchRequest(entity: WFACollection.entity(), sortDescriptors: []) var collections: FetchedResults var fetchRequest: FetchRequest var showAllPosts: Bool - init(filter: String?, showAllPosts: Bool) { + init(filter: String?, showAllPosts: Bool, postCount: Binding) { self.showAllPosts = showAllPosts if showAllPosts { fetchRequest = FetchRequest( entity: WFAPost.entity(), sortDescriptors: [NSSortDescriptor(key: "createdDate", ascending: false)] ) } else { if let filter = filter { fetchRequest = FetchRequest( entity: WFAPost.entity(), sortDescriptors: [NSSortDescriptor(key: "createdDate", ascending: false)], predicate: NSPredicate(format: "collectionAlias == %@", filter) ) } 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 { ForEach(fetchRequest.wrappedValue, id: \.self) { post in NavigationLink( destination: PostEditorView(post: post), tag: post, selection: $model.selectedPost ) { if 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 + }) + .onChange(of: fetchRequest.wrappedValue.count, perform: { value in + self.postCount = value + }) #else List { ForEach(fetchRequest.wrappedValue, id: \.self) { post in NavigationLink( destination: PostEditorView(post: post), tag: post, selection: $model.selectedPost ) { 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 + }) + .onChange(of: fetchRequest.wrappedValue.count, perform: { value in + self.postCount = value + }) .onDeleteCommand(perform: { guard let selectedPost = model.selectedPost else { return } if selectedPost.status == PostStatus.local.rawValue { model.postToDelete = selectedPost model.isPresentingDeleteAlert = true } }) #endif } func delete(_ post: WFAPost) { model.posts.remove(post) } } struct PostListFilteredView_Previews: PreviewProvider { static var previews: some View { - return PostListFilteredView(filter: nil, showAllPosts: false) + return PostListFilteredView(filter: nil, showAllPosts: false, postCount: .constant(999)) } } diff --git a/Shared/PostList/PostListView.swift b/Shared/PostList/PostListView.swift index 928ec7a..dddca79 100644 --- a/Shared/PostList/PostListView.swift +++ b/Shared/PostList/PostListView.swift @@ -1,143 +1,125 @@ import SwiftUI +import Combine struct PostListView: View { @EnvironmentObject var model: WriteFreelyModel @Environment(\.managedObjectContext) var managedObjectContext @State var selectedCollection: WFACollection? @State var showAllPosts: Bool = false + @State private var postCount: Int = 0 var body: some View { #if os(iOS) GeometryReader { geometry in - PostListFilteredView(filter: selectedCollection?.alias, showAllPosts: showAllPosts) + PostListFilteredView(filter: selectedCollection?.alias, showAllPosts: showAllPosts, postCount: $postCount) .navigationTitle( showAllPosts ? "All Posts" : selectedCollection?.title ?? ( model.account.server == "https://write.as" ? "Anonymous" : "Drafts" ) ) .toolbar { ToolbarItem(placement: .primaryAction) { Button(action: { createNewLocalDraft() }, label: { Image(systemName: "square.and.pencil") }) } ToolbarItem(placement: .bottomBar) { HStack { Button(action: { model.isPresentingSettingsView = true }, label: { Image(systemName: "gear") }) Spacer() - Text(pluralizedPostCount(for: showPosts(for: selectedCollection))) + Text(postCount == 1 ? "\(postCount) post" : "\(postCount) posts") .foregroundColor(.secondary) Spacer() if model.isProcessingRequest { ProgressView() } else { Button(action: { reloadFromServer() }, label: { Image(systemName: "arrow.clockwise") }) .disabled(!model.account.isLoggedIn) } } .padding() .frame(width: geometry.size.width) } } } #else //if os(macOS) - PostListFilteredView(filter: selectedCollection?.alias, showAllPosts: showAllPosts) - .navigationTitle( - showAllPosts ? "All Posts" : selectedCollection?.title ?? ( - model.account.server == "https://write.as" ? "Anonymous" : "Drafts" + PostListFilteredView(filter: selectedCollection?.alias, showAllPosts: showAllPosts, postCount: $postCount) + .navigationTitle( + showAllPosts ? "All Posts" : selectedCollection?.title ?? ( + model.account.server == "https://write.as" ? "Anonymous" : "Drafts" + ) ) - ) - .navigationSubtitle(pluralizedPostCount(for: showPosts(for: selectedCollection))) - .toolbar { - Button(action: { - createNewLocalDraft() - }, label: { - Image(systemName: "square.and.pencil") - }) - Button(action: { - reloadFromServer() - }, label: { - Image(systemName: "arrow.clockwise") - }) - .disabled(!model.account.isLoggedIn) - } - #endif - } - - private func pluralizedPostCount(for posts: [WFAPost]) -> String { - if posts.count == 1 { - return "1 post" - } else { - return "\(posts.count) posts" - } - } - - private func showPosts(for collection: WFACollection?) -> [WFAPost] { - if showAllPosts { - return model.posts.userPosts - } else { - if let selectedCollection = collection { - return model.posts.userPosts.filter { $0.collectionAlias == selectedCollection.alias } - } else { - return model.posts.userPosts.filter { $0.collectionAlias == nil } + .navigationSubtitle(postCount == 1 ? "\(postCount) post" : "\(postCount) posts") + .toolbar { + Button(action: { + createNewLocalDraft() + }, label: { + Image(systemName: "square.and.pencil") + }) + Button(action: { + reloadFromServer() + }, label: { + Image(systemName: "arrow.clockwise") + }) + .disabled(!model.account.isLoggedIn) } - } + #endif } private func reloadFromServer() { DispatchQueue.main.async { model.fetchUserCollections() model.fetchUserPosts() } } private func createNewLocalDraft() { let managedPost = WFAPost(context: self.managedObjectContext) managedPost.createdDate = Date() managedPost.title = "" managedPost.body = "" managedPost.status = PostStatus.local.rawValue managedPost.collectionAlias = nil switch model.preferences.font { case 1: managedPost.appearance = "sans" case 2: managedPost.appearance = "wrap" default: managedPost.appearance = "serif" } if let languageCode = Locale.current.languageCode { managedPost.language = languageCode managedPost.rtl = Locale.characterDirection(forLanguage: languageCode) == .rightToLeft } DispatchQueue.main.async { self.selectedCollection = nil self.showAllPosts = false withAnimation { self.model.selectedPost = managedPost } } } } struct PostListView_Previews: PreviewProvider { static var previews: some View { let context = LocalStorageManager.persistentContainer.viewContext let model = WriteFreelyModel() return PostListView() .environment(\.managedObjectContext, context) .environmentObject(model) } }