Show menu right away (#690)

This was a nice bug: The menu for signup-speed/language was attached too late. The entire button-delegate-stuff was obsolete in the end
This commit is contained in:
Nathan Mattes 2023-01-06 14:36:14 +01:00
parent c8e0419dec
commit 0cfe0041df
5 changed files with 78 additions and 84 deletions

View File

@ -17,26 +17,69 @@ extension CategoryPickerSection {
static func collectionViewDiffableDataSource(
for collectionView: UICollectionView,
dependency: NeedsDependency,
buttonDelegate: PickServerCategoryCollectionViewCellDelegate?
viewModel: MastodonPickServerViewModel
) -> UICollectionViewDiffableDataSource<CategoryPickerSection, CategoryPickerItem> {
UICollectionViewDiffableDataSource(collectionView: collectionView) { [weak dependency] collectionView, indexPath, item -> UICollectionViewCell? in
guard let _ = dependency else { return nil }
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: PickServerCategoryCollectionViewCell.reuseIdentifier, for: indexPath) as! PickServerCategoryCollectionViewCell
cell.titleLabel.text = item.title
cell.delegate = buttonDelegate
cell.item = item
let isLanguage = (item == .language(language: nil))
let isSignupSpeed = (item == .signupSpeed(manuallyReviewed: nil))
if isLanguage || isSignupSpeed {
cell.chevron.isHidden = false
cell.menuButton.isUserInteractionEnabled = true
cell.menuButton.isHidden = false
} else {
switch item {
case .category(_):
cell.chevron.isHidden = true
cell.menuButton.isUserInteractionEnabled = false
cell.menuButton.isHidden = true
cell.menuButton.menu = nil
case .language(_):
guard viewModel.allLanguages.value.isNotEmpty else { break }
let allLanguagesAction = UIAction(title: L10n.Scene.ServerPicker.Language.all) { _ in
viewModel.selectedLanguage.value = nil
cell.titleLabel.text = L10n.Scene.ServerPicker.Button.language
}
let languageActions = viewModel.allLanguages.value.compactMap { language in
UIAction(title: language.language ?? language.locale) { action in
viewModel.selectedLanguage.value = language.locale
cell.titleLabel.text = language.language
}
}
var allActions = [allLanguagesAction]
allActions.append(contentsOf: languageActions)
let languageMenu = UIMenu(title: L10n.Scene.ServerPicker.Button.language,
children: allActions)
cell.chevron.isHidden = false
cell.menuButton.isUserInteractionEnabled = true
cell.menuButton.isHidden = false
cell.menuButton.menu = languageMenu
case .signupSpeed(_):
let doesntMatterAction = UIAction(title: L10n.Scene.ServerPicker.SignupSpeed.all) { _ in
viewModel.manualApprovalRequired.value = nil
cell.titleLabel.text = L10n.Scene.ServerPicker.Button.signupSpeed
}
let manualApprovalAction = UIAction(title: L10n.Scene.ServerPicker.SignupSpeed.manuallyReviewed) { action in
viewModel.manualApprovalRequired.value = true
cell.titleLabel.text = action.title
}
let instantSignupAction = UIAction(title: L10n.Scene.ServerPicker.SignupSpeed.instant) { action in
viewModel.manualApprovalRequired.value = false
cell.titleLabel.text = action.title
}
let signupSpeedMenu = UIMenu(title: L10n.Scene.ServerPicker.Button.signupSpeed,
children: [doesntMatterAction, manualApprovalAction, instantSignupAction])
cell.chevron.isHidden = false
cell.menuButton.isUserInteractionEnabled = true
cell.menuButton.isHidden = false
cell.menuButton.menu = signupSpeedMenu
}
cell.observe(\.isSelected, options: [.initial, .new]) { cell, _ in

View File

@ -11,16 +11,9 @@ import MastodonAsset
import MastodonUI
import MastodonLocalization
protocol PickServerCategoryCollectionViewCellDelegate: AnyObject {
func didPressMenuButton(in cell: PickServerCategoryCollectionViewCell) //TODO: Add item
}
class PickServerCategoryCollectionViewCell: UICollectionViewCell {
static let reuseIdentifier = "PickServerCategoryCollectionViewCell"
weak var delegate: PickServerCategoryCollectionViewCellDelegate?
var item: CategoryPickerItem?
let titleLabel: UILabel = {
let label = UILabel()
@ -98,7 +91,6 @@ class PickServerCategoryCollectionViewCell: UICollectionViewCell {
//MARK: - Actions
@objc func didPressButton(_ sender: Any) {
delegate?.didPressMenuButton(in: self)
invalidateIntrinsicContentSize()
}

View File

@ -207,6 +207,23 @@ extension MastodonPickServerViewController {
onboardingNextView.nextButton.addTarget(self, action: #selector(MastodonPickServerViewController.next(_:)), for: .touchUpInside)
viewModel.allLanguages
.receive(on: DispatchQueue.main)
.sink { [weak self] _ in
guard let snapshot = self?.viewModel.serverSectionHeaderView.diffableDataSource?.snapshot() else { return }
self?.viewModel.serverSectionHeaderView.diffableDataSource?.applySnapshotUsingReloadData(snapshot) {
guard let self = self, let viewModel = self.viewModel else { return }
guard let indexPath = viewModel.serverSectionHeaderView.diffableDataSource?.indexPath(for: .category(category: .init(category: Mastodon.Entity.Category.Kind.general.rawValue, serversCount: 0))) else { return }
viewModel.serverSectionHeaderView.collectionView.selectItem(at: indexPath, animated: false, scrollPosition: .right)
let firstIndex = IndexPath(item: 0, section: 0)
viewModel.serverSectionHeaderView.collectionView.scrollToItem(at: firstIndex, at: .left, animated: false)
}
}
.store(in: &disposeBag)
title = L10n.Scene.ServerPicker.title
navigationItem.searchController = searchController
@ -395,16 +412,14 @@ extension MastodonPickServerViewController: UITableViewDelegate {
extension MastodonPickServerViewController: PickServerServerSectionTableHeaderViewDelegate {
func pickServerServerSectionTableHeaderView(_ headerView: PickServerServerSectionTableHeaderView, collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
guard let diffableDataSource = headerView.diffableDataSource,
let item = diffableDataSource.itemIdentifier(for: indexPath),
let cell = collectionView.cellForItem(at: indexPath) as? PickServerCategoryCollectionViewCell else { return }
let item = diffableDataSource.itemIdentifier(for: indexPath) else { return }
if case let .language(_) = item {
viewModel.didPressMenuButton(in: cell)
} else if case let .signupSpeed(_) = item {
// gets also handled by button
viewModel.didPressMenuButton(in: cell)
} else {
switch item {
case .category(_):
viewModel.selectCategoryItem.value = item
case .language(_), .signupSpeed(_):
break
// gets handled by button
}
}
}

View File

@ -20,7 +20,7 @@ extension MastodonPickServerViewModel {
serverSectionHeaderView.diffableDataSource = CategoryPickerSection.collectionViewDiffableDataSource(
for: serverSectionHeaderView.collectionView,
dependency: dependency,
buttonDelegate: self
viewModel: self
)
var sectionHeaderSnapshot = NSDiffableDataSourceSnapshot<CategoryPickerSection, CategoryPickerItem>()
sectionHeaderSnapshot.appendSections([.main])

View File

@ -301,59 +301,3 @@ extension MastodonPickServerViewModel: TMBarDataSource {
return barItem
}
}
extension MastodonPickServerViewModel: PickServerCategoryCollectionViewCellDelegate {
func didPressMenuButton(in cell: PickServerCategoryCollectionViewCell) {
guard let item = cell.item else { return }
switch item {
case .category(_):
return
case .language(_):
guard allLanguages.value.isNotEmpty else { return }
let allLanguagesAction = UIAction(title: L10n.Scene.ServerPicker.Language.all) { _ in
self.selectedLanguage.value = nil
cell.titleLabel.text = L10n.Scene.ServerPicker.Button.language
}
let languageActions = allLanguages.value.compactMap { language in
UIAction(title: language.language ?? language.locale) { action in
self.selectedLanguage.value = language.locale
cell.titleLabel.text = language.language
}
}
var allActions = [allLanguagesAction]
allActions.append(contentsOf: languageActions)
let languageMenu = UIMenu(title: L10n.Scene.ServerPicker.Button.language,
children: allActions)
cell.menuButton.menu = languageMenu
case .signupSpeed(_):
let doesntMatterAction = UIAction(title: L10n.Scene.ServerPicker.SignupSpeed.all) { _ in
self.manualApprovalRequired.value = nil
cell.titleLabel.text = L10n.Scene.ServerPicker.Button.signupSpeed
}
let manualApprovalAction = UIAction(title: L10n.Scene.ServerPicker.SignupSpeed.manuallyReviewed) { action in
self.manualApprovalRequired.value = true
cell.titleLabel.text = action.title
}
let instantSignupAction = UIAction(title: L10n.Scene.ServerPicker.SignupSpeed.instant) { action in
self.manualApprovalRequired.value = false
cell.titleLabel.text = action.title
}
let signupSpeedMenu = UIMenu(title: L10n.Scene.ServerPicker.Button.signupSpeed,
children: [doesntMatterAction, manualApprovalAction, instantSignupAction])
cell.menuButton.menu = signupSpeedMenu
}
}
}