From 0332570c63ce655fdeaf80c39ac8f3e9fc2fc13b Mon Sep 17 00:00:00 2001 From: Miltiadis Vasilakis Date: Sat, 19 Oct 2024 10:17:15 +0300 Subject: [PATCH] Fix collection context menu when collection size is not shown --- .../Views/CollectionsViewController.swift | 11 ++++++++- ...ableCollectionsCollectionViewHandler.swift | 23 ++++++++++++++++--- Zotero/Scenes/Master/MasterCoordinator.swift | 2 +- 3 files changed, 31 insertions(+), 5 deletions(-) diff --git a/Zotero/Scenes/Master/Collections/Views/CollectionsViewController.swift b/Zotero/Scenes/Master/Collections/Views/CollectionsViewController.swift index c4afded44..3cb9e755a 100644 --- a/Zotero/Scenes/Master/Collections/Views/CollectionsViewController.swift +++ b/Zotero/Scenes/Master/Collections/Views/CollectionsViewController.swift @@ -19,6 +19,7 @@ protocol SplitControllerDelegate: AnyObject { final class CollectionsViewController: UICollectionViewController { let viewModel: ViewModel + private unowned let dbStorage: DbStorage private unowned let syncScheduler: SynchronizationScheduler private unowned let dragDropController: DragDropController private let disposeBag: DisposeBag @@ -30,8 +31,15 @@ final class CollectionsViewController: UICollectionViewController { return self.viewModel.state.selectedCollectionId } - init(viewModel: ViewModel, dragDropController: DragDropController, syncScheduler: SynchronizationScheduler, coordinatorDelegate: MasterCollectionsCoordinatorDelegate) { + init( + viewModel: ViewModel, + dbStorage: DbStorage, + dragDropController: DragDropController, + syncScheduler: SynchronizationScheduler, + coordinatorDelegate: MasterCollectionsCoordinatorDelegate + ) { self.viewModel = viewModel + self.dbStorage = dbStorage self.syncScheduler = syncScheduler self.dragDropController = dragDropController self.coordinatorDelegate = coordinatorDelegate @@ -64,6 +72,7 @@ final class CollectionsViewController: UICollectionViewController { self.collectionViewHandler = ExpandableCollectionsCollectionViewHandler( collectionView: self.collectionView, + dbStorage: dbStorage, dragDropController: self.dragDropController, viewModel: self.viewModel, splitDelegate: self diff --git a/Zotero/Scenes/Master/Collections/Views/ExpandableCollectionsCollectionViewHandler.swift b/Zotero/Scenes/Master/Collections/Views/ExpandableCollectionsCollectionViewHandler.swift index 344539381..b0c4e9ea0 100644 --- a/Zotero/Scenes/Master/Collections/Views/ExpandableCollectionsCollectionViewHandler.swift +++ b/Zotero/Scenes/Master/Collections/Views/ExpandableCollectionsCollectionViewHandler.swift @@ -11,6 +11,7 @@ import UIKit final class ExpandableCollectionsCollectionViewHandler: NSObject { private let collectionsSection: Int = 0 private unowned let collectionView: UICollectionView + private unowned let dbStorage: DbStorage private unowned let dragDropController: DragDropController private unowned let viewModel: ViewModel @@ -31,8 +32,9 @@ final class ExpandableCollectionsCollectionViewHandler: NSObject { return self.dataSource.snapshot(for: self.collectionsSection).rootItems.contains(where: { $0.identifier == self.viewModel.state.selectedCollectionId }) } - init(collectionView: UICollectionView, dragDropController: DragDropController, viewModel: ViewModel, splitDelegate: SplitControllerDelegate?) { + init(collectionView: UICollectionView, dbStorage: DbStorage, dragDropController: DragDropController, viewModel: ViewModel, splitDelegate: SplitControllerDelegate?) { self.collectionView = collectionView + self.dbStorage = dbStorage self.dragDropController = dragDropController self.viewModel = viewModel self.splitDelegate = splitDelegate @@ -126,12 +128,12 @@ final class ExpandableCollectionsCollectionViewHandler: NSObject { actions.append(delete) } - if collection.itemCount > 0 { + if !isCollectionEmpty(collection, dbStorage: dbStorage) { actions.insert(contentsOf: [downloadAttachmentsAction(for: collection.identifier, in: viewModel), removeDownloadsAction(for: collection.identifier, in: viewModel)], at: 0) } case .custom(let type): - guard collection.itemCount > 0 else { break } + guard !isCollectionEmpty(collection, dbStorage: dbStorage) else { break } actions.append(removeDownloadsAction(for: collection.identifier, in: viewModel)) switch type { @@ -154,6 +156,21 @@ final class ExpandableCollectionsCollectionViewHandler: NSObject { guard !actions.isEmpty else { return nil } return UIMenu(children: actions) + func isCollectionEmpty(_ collection: Collection, dbStorage: DbStorage) -> Bool { + if Defaults.shared.showCollectionItemCounts { + return collection.itemCount == 0 + } + + switch collection.identifier { + case .collection, .custom: + let libraryId = viewModel.state.library.identifier + return (try? dbStorage.perform(request: ReadItemsDbRequest(collectionId: collection.identifier, libraryId: libraryId), on: .main))?.isEmpty ?? true + + case .search: + return false + } + } + func downloadAttachmentsAction(for identifier: CollectionIdentifier, in viewModel: ViewModel) -> UIAction { UIAction(title: L10n.Collections.downloadAttachments, image: UIImage(systemName: "arrow.down.to.line.compact")) { [weak viewModel] _ in viewModel?.process(action: .downloadAttachments(identifier)) diff --git a/Zotero/Scenes/Master/MasterCoordinator.swift b/Zotero/Scenes/Master/MasterCoordinator.swift index 51f2824b1..e2a925ff5 100644 --- a/Zotero/Scenes/Master/MasterCoordinator.swift +++ b/Zotero/Scenes/Master/MasterCoordinator.swift @@ -91,7 +91,7 @@ final class MasterCoordinator: NSObject, Coordinator { let handler = CollectionsActionHandler(dbStorage: dbStorage, fileStorage: controllers.fileStorage, attachmentDownloader: attachmentDownloader, fileCleanupController: fileCleanupController) let state = CollectionsState(libraryId: libraryId, selectedCollectionId: selectedCollectionId) let viewModel = ViewModel(initialState: state, handler: handler) - return CollectionsViewController(viewModel: viewModel, dragDropController: controllers.dragDropController, syncScheduler: syncScheduler, coordinatorDelegate: self) + return CollectionsViewController(viewModel: viewModel, dbStorage: dbStorage, dragDropController: controllers.dragDropController, syncScheduler: syncScheduler, coordinatorDelegate: self) } private func storeIfNeeded(libraryId: LibraryIdentifier, preselectedCollection collectionId: CollectionIdentifier? = nil) -> CollectionIdentifier {