From f13e0ba86a81641312336c50479fa5c8ca9d4cc0 Mon Sep 17 00:00:00 2001 From: Bruno Muniz Azevedo Filho <bruno@elixxir.io> Date: Fri, 22 Jul 2022 21:35:51 -0300 Subject: [PATCH] Added contact list indexing --- .../Controllers/ContactListController.swift | 39 ++++++-------- .../Helpers/IndexedListCollator.swift | 53 ------------------- .../Utils/IndexedContactList.swift | 26 +++++++++ 3 files changed, 43 insertions(+), 75 deletions(-) delete mode 100644 Sources/ContactListFeature/Helpers/IndexedListCollator.swift create mode 100644 Sources/ContactListFeature/Utils/IndexedContactList.swift diff --git a/Sources/ContactListFeature/Controllers/ContactListController.swift b/Sources/ContactListFeature/Controllers/ContactListController.swift index b0957b62..34612913 100644 --- a/Sources/ContactListFeature/Controllers/ContactListController.swift +++ b/Sources/ContactListFeature/Controllers/ContactListController.swift @@ -11,9 +11,9 @@ public final class ContactListController: UIViewController { lazy private var screenView = ContactListView() + private var dataSource: IndexedContactList! private let viewModel = ContactListViewModel() private var cancellables = Set<AnyCancellable>() - private var dataSource: UICollectionViewDiffableDataSource<Int, Contact>! public override func loadView() { view = screenView @@ -38,8 +38,9 @@ public final class ContactListController: UIViewController { screenView.collectionView.delegate = self screenView.collectionView.register(AvatarCell.self) screenView.collectionView.dataSource = dataSource + screenView.collectionView.tintColor = Asset.neutralDark.color - dataSource = UICollectionViewDiffableDataSource<Int, Contact>( + dataSource = IndexedContactList( collectionView: screenView.collectionView ) { collectionView, indexPath, contact in let cell: AvatarCell = collectionView.dequeueReusableCell(forIndexPath: indexPath) @@ -125,15 +126,25 @@ public final class ContactListController: UIViewController { viewModel.snapshotPublisher .receive(on: DispatchQueue.main) - .sink { [unowned self] in - screenView.emptyView.isHidden = $0.numberOfItems > 0 + .sink { [unowned self] snapshot in + screenView.emptyView.isHidden = snapshot.numberOfItems > 0 - if $0.numberOfItems == 0 { + if snapshot.numberOfItems == 0 { screenView.bringSubviewToFront(screenView.emptyView) } let animatingDifferences = dataSource.snapshot().numberOfItems > 0 - dataSource.apply($0, animatingDifferences: animatingDifferences) + dataSource.apply(snapshot, animatingDifferences: animatingDifferences) { [weak self] in + guard let self = self else { return } + + self.dataSource.set(indexTitles: snapshot.itemIdentifiers.map { contact -> String in + let name = (contact.nickname ?? contact.username) ?? "" + return "\(name.first!)" + }) + + self.screenView.collectionView.reloadData() + } + }.store(in: &cancellables) } @@ -157,19 +168,3 @@ extension ContactListController: UICollectionViewDelegate { } } } - - -//final class ContactListTableController: UITableViewController { -// private var collation = UILocalizedIndexedCollation.current() -// -// override func sectionIndexTitles(for: UITableView) -> [String]? { -// collation.sectionIndexTitles -// } -// -// override func tableView(_: UITableView, titleForHeaderInSection section: Int) -> String? { -// collation.sectionTitles[section] -// } -// -// override func tableView(_: UITableView, sectionForSectionIndexTitle: String, at index: Int) -> Int { -// collation.section(forSectionIndexTitle: index) -// } diff --git a/Sources/ContactListFeature/Helpers/IndexedListCollator.swift b/Sources/ContactListFeature/Helpers/IndexedListCollator.swift deleted file mode 100644 index 249af6fa..00000000 --- a/Sources/ContactListFeature/Helpers/IndexedListCollator.swift +++ /dev/null @@ -1,53 +0,0 @@ -import UIKit -import XXModels - -public protocol IndexableItem { - var indexedOn: NSString { get } -} - -class IndexedListCollator<Item: IndexableItem> { - private final class CollationWrapper: NSObject { - let value: Any - @objc let indexedOn: NSString - - init(value: Any, indexedOn: NSString) { - self.value = value - self.indexedOn = indexedOn - } - - func unwrappedValue<UnwrappedType>() -> UnwrappedType { - return value as! UnwrappedType - } - } - - public init() {} - - public func sectioned(items: [Item]) -> (sections: [[Item]], collation: UILocalizedIndexedCollation) { - let collation = UILocalizedIndexedCollation.current() - let selector = #selector(getter: CollationWrapper.indexedOn) - - let wrappedItems = items.map { item in - CollationWrapper(value: item, indexedOn: item.indexedOn) - } - - let sortedObjects = collation.sortedArray(from: wrappedItems, collationStringSelector: selector) as! [CollationWrapper] - - var sections = collation.sectionIndexTitles.map { _ in [Item]() } - sortedObjects.forEach { item in - let sectionNumber = collation.section(for: item, collationStringSelector: selector) - sections[sectionNumber].append(item.unwrappedValue()) - } - - return (sections: sections.filter { !$0.isEmpty }, collation: collation) - } -} - -extension Contact: IndexableItem { - public var indexedOn: NSString { - guard let nickname = nickname else { - return "\(username!.first!)" as NSString - } - - return "\(nickname.first!)" as NSString - } -} diff --git a/Sources/ContactListFeature/Utils/IndexedContactList.swift b/Sources/ContactListFeature/Utils/IndexedContactList.swift new file mode 100644 index 00000000..262618bd --- /dev/null +++ b/Sources/ContactListFeature/Utils/IndexedContactList.swift @@ -0,0 +1,26 @@ +import UIKit +import XXModels + +final class IndexedContactList: UICollectionViewDiffableDataSource<Int, Contact> { + private var indexTitles: [String] = [] + + func set(indexTitles: [String]) { + self.indexTitles = indexTitles + } + + override func indexTitles(for collectionView: UICollectionView) -> [String]? { + indexTitles + } + + override func collectionView( + _ collectionView: UICollectionView, + indexPathForIndexTitle title: String, + at index: Int + ) -> IndexPath { + guard let index = indexTitles.firstIndex(where: { $0 == title }) else { + return IndexPath(item: 0, section: 0) + } + + return IndexPath(item: index, section: 0) + } +} -- GitLab