From d2a41cd563c2435fb504b11c8c9aeaaf9e3dab20 Mon Sep 17 00:00:00 2001 From: Maxime Mongeau Date: Sat, 13 Oct 2018 22:32:15 -0400 Subject: [PATCH 1/5] Add clear button to the labels and milestone action menu --- .../IssueManagingContextController.swift | 2 + Classes/Labels/LabelSectionController.swift | 7 ++++ Classes/Labels/LabelsViewController.swift | 39 ++++++++++++++++++- .../Milestones/MilestonesViewController.swift | 22 ++++++++++- Classes/People/PeopleViewController.swift | 13 +++++++ 5 files changed, 80 insertions(+), 3 deletions(-) diff --git a/Classes/Issues/IssueManagingContextController.swift b/Classes/Issues/IssueManagingContextController.swift index ddadc475d..adfc945cc 100644 --- a/Classes/Issues/IssueManagingContextController.swift +++ b/Classes/Issues/IssueManagingContextController.swift @@ -81,6 +81,8 @@ final class IssueManagingContextController: NSObject, ContextMenuDelegate { } var actions: [Action] { + // TODO: Remove me! + return [ .labels, .milestone, .assignees ] if case .none = permissions { return [] } guard let result = self.result else { return [] } diff --git a/Classes/Labels/LabelSectionController.swift b/Classes/Labels/LabelSectionController.swift index db376f534..93e1ad9ac 100644 --- a/Classes/Labels/LabelSectionController.swift +++ b/Classes/Labels/LabelSectionController.swift @@ -8,8 +8,14 @@ import IGListKit +protocol LabelSectionControllerDelegate: class { + func didSelect(controller: LabelSectionController) +} + final class LabelSectionController: ListSwiftSectionController { + public weak var delegate: LabelSectionControllerDelegate? + public private(set) var selected: Bool init(selected: Bool) { @@ -41,6 +47,7 @@ final class LabelSectionController: ListSwiftSectionController strongSelf.selected = !strongSelf.selected context.deselect() context.cell?.setSelected(strongSelf.selected) + strongSelf.delegate?.didSelect(controller: strongSelf) }) ] } diff --git a/Classes/Labels/LabelsViewController.swift b/Classes/Labels/LabelsViewController.swift index 74eebc8af..6eccb326e 100644 --- a/Classes/Labels/LabelsViewController.swift +++ b/Classes/Labels/LabelsViewController.swift @@ -10,7 +10,13 @@ import UIKit import IGListKit import Squawk -final class LabelsViewController: BaseListViewController2, BaseListViewController2DataSource { +protocol LabelsViewControllerDelegate { + func didSelect() +} + +final class LabelsViewController: BaseListViewController2, +BaseListViewController2DataSource, +LabelSectionControllerDelegate { private let selectedLabels: Set private var labels = [RepositoryLabel]() @@ -42,6 +48,7 @@ final class LabelsViewController: BaseListViewController2, BaseListViewC super.viewDidLoad() navigationController?.navigationBar.titleTextAttributes = [.foregroundColor: UIColor.white] addMenuDoneButton() + addMenuClearButton() } // MARK: Public API @@ -55,6 +62,25 @@ final class LabelsViewController: BaseListViewController2, BaseListViewC } } + func addMenuClearButton() { + navigationItem.leftBarButtonItem = UIBarButtonItem(title: "Clear", style: .plain, target: self, action: #selector(onMenuClear)) + navigationItem.leftBarButtonItem?.tintColor = Styles.Colors.Gray.light.color + } + + func updateClearButtonEnabled() { + navigationItem.leftBarButtonItem?.isEnabled = selected.count > 0 + } + + @objc func onMenuClear() { + self.selected.forEach { + if let sectionController: LabelSectionController = feed.swiftAdapter.sectionController(for: $0) { + sectionController.didSelectItem(at: 0) + } + } + + updateClearButtonEnabled() + } + // MARK: Overrides override func fetch(page: String?) { @@ -78,8 +104,17 @@ final class LabelsViewController: BaseListViewController2, BaseListViewC func models(adapter: ListSwiftAdapter) -> [ListSwiftPair] { return labels.map { [selectedLabels] label in - ListSwiftPair.pair(label) { LabelSectionController(selected: selectedLabels.contains(label)) } + ListSwiftPair.pair(label) { + let controller = LabelSectionController(selected: selectedLabels.contains(label)) + controller.delegate = self + return controller + } } } + // MARK: LabelSectionControllerDelegate + + func didSelect(controller: LabelSectionController) { + updateClearButtonEnabled() + } } diff --git a/Classes/Milestones/MilestonesViewController.swift b/Classes/Milestones/MilestonesViewController.swift index 6f463e3f1..1b96893f5 100644 --- a/Classes/Milestones/MilestonesViewController.swift +++ b/Classes/Milestones/MilestonesViewController.swift @@ -14,7 +14,11 @@ final class MilestonesViewController: BaseListViewController2, BaseListViewController2DataSource, MilestoneSectionControllerDelegate { - public private(set) var selected: Milestone? + public private(set) var selected: Milestone? = nil { + didSet { + self.updateClearButtonEnabled() + } + } private var owner: String! private var repo: String! @@ -55,6 +59,22 @@ MilestoneSectionControllerDelegate { super.viewDidLoad() navigationController?.navigationBar.titleTextAttributes = [.foregroundColor: UIColor.white] addMenuDoneButton() + addMenuClearButton() + } + + func addMenuClearButton() { + navigationItem.leftBarButtonItem = UIBarButtonItem(title: "Clear", style: .plain, target: self, action: #selector(onMenuClear)) + navigationItem.leftBarButtonItem?.tintColor = Styles.Colors.Gray.light.color + updateClearButtonEnabled() + } + + func updateClearButtonEnabled() { + navigationItem.leftBarButtonItem?.isEnabled = selected != nil + } + + @objc func onMenuClear() { + selected = nil + update(animated: true) } // MARK: Overrides diff --git a/Classes/People/PeopleViewController.swift b/Classes/People/PeopleViewController.swift index 381fcb022..58e75dbee 100644 --- a/Classes/People/PeopleViewController.swift +++ b/Classes/People/PeopleViewController.swift @@ -68,6 +68,7 @@ PeopleSectionControllerDelegate { super.viewDidLoad() navigationController?.navigationBar.titleTextAttributes = [.foregroundColor: UIColor.white] addMenuDoneButton() +// addClearButton() } // MARK: Public API @@ -150,4 +151,16 @@ PeopleSectionControllerDelegate { updateSelectionCount() } + func addClearButton() { + navigationItem.leftBarButtonItem = UIBarButtonItem(title: "Clear", style: .plain, target: self, action: #selector(onMenuClear)) + navigationItem.leftBarButtonItem?.tintColor = Styles.Colors.Gray.light.color + } + + @objc func onMenuClear() { + self.selected.forEach { + if let sectionController: LabelSectionController = feed.swiftAdapter.sectionController(for: $0) { + sectionController.didSelectItem(at: 0) + } + } + } } From 820bc8e87ef2c76e11eee47d6fcfc3d500c1fcb3 Mon Sep 17 00:00:00 2001 From: Maxime Mongeau Date: Sat, 13 Oct 2018 23:26:00 -0400 Subject: [PATCH 2/5] Move the selection count in the PeopleViewController into the title Add a clear button to the people controller --- Classes/Labels/LabelsViewController.swift | 7 ++- .../Milestones/MilestonesViewController.swift | 7 ++- Classes/People/PeopleViewController.swift | 62 ++++++++++--------- 3 files changed, 45 insertions(+), 31 deletions(-) diff --git a/Classes/Labels/LabelsViewController.swift b/Classes/Labels/LabelsViewController.swift index 6eccb326e..55f8463a6 100644 --- a/Classes/Labels/LabelsViewController.swift +++ b/Classes/Labels/LabelsViewController.swift @@ -63,7 +63,12 @@ LabelSectionControllerDelegate { } func addMenuClearButton() { - navigationItem.leftBarButtonItem = UIBarButtonItem(title: "Clear", style: .plain, target: self, action: #selector(onMenuClear)) + navigationItem.leftBarButtonItem = UIBarButtonItem( + title: NSLocalizedString("Clear", comment: ""), + style: .plain, + target: self, + action: #selector(onMenuClear) + ) navigationItem.leftBarButtonItem?.tintColor = Styles.Colors.Gray.light.color } diff --git a/Classes/Milestones/MilestonesViewController.swift b/Classes/Milestones/MilestonesViewController.swift index 1b96893f5..fd1b4195b 100644 --- a/Classes/Milestones/MilestonesViewController.swift +++ b/Classes/Milestones/MilestonesViewController.swift @@ -63,7 +63,12 @@ MilestoneSectionControllerDelegate { } func addMenuClearButton() { - navigationItem.leftBarButtonItem = UIBarButtonItem(title: "Clear", style: .plain, target: self, action: #selector(onMenuClear)) + navigationItem.leftBarButtonItem = UIBarButtonItem( + title: NSLocalizedString("Clear", comment: ""), + style: .plain, + target: self, + action: #selector(onMenuClear) + ) navigationItem.leftBarButtonItem?.tintColor = Styles.Colors.Gray.light.color updateClearButtonEnabled() } diff --git a/Classes/People/PeopleViewController.swift b/Classes/People/PeopleViewController.swift index 58e75dbee..877260885 100644 --- a/Classes/People/PeopleViewController.swift +++ b/Classes/People/PeopleViewController.swift @@ -49,15 +49,10 @@ PeopleSectionControllerDelegate { self.dataSource = self - switch type { - case .assignee: title = NSLocalizedString("Assignees", comment: "") - case .reviewer: title = NSLocalizedString("Reviewers", comment: "") - } - feed.collectionView.backgroundColor = Styles.Colors.menuBackgroundColor.color feed.setLoadingSpinnerColor(to: .white) preferredContentSize = Styles.Sizes.contextMenuSize - updateSelectionCount() + updateTitle() } required init?(coder aDecoder: NSCoder) { @@ -68,7 +63,7 @@ PeopleSectionControllerDelegate { super.viewDidLoad() navigationController?.navigationBar.titleTextAttributes = [.foregroundColor: UIColor.white] addMenuDoneButton() -// addClearButton() + addMenuClearButton() } // MARK: Public API @@ -82,16 +77,38 @@ PeopleSectionControllerDelegate { } } + func updateClearButtonEnabled() { + navigationItem.leftBarButtonItem?.isEnabled = selected.count > 0 + } + + func addMenuClearButton() { + navigationItem.leftBarButtonItem = UIBarButtonItem( + title: NSLocalizedString("Clear", comment: ""), + style: .plain, + target: self, + action: #selector(onMenuClear) + ) + navigationItem.leftBarButtonItem?.tintColor = Styles.Colors.Gray.light.color + updateClearButtonEnabled() + } + + @objc func onMenuClear() { + self.selected.forEach { + if let sectionController: PeopleSectionController = feed.swiftAdapter.sectionController(for: $0) { + sectionController.didSelectItem(at: 0) + } + } + } + // MARK: Private API - func updateSelectionCount() { - let label = UILabel() - label.font = Styles.Text.body.preferredFont - label.backgroundColor = .clear - label.textColor = Styles.Colors.Gray.light.color - label.text = "\(selected.count)/\(selectionLimit)" - label.sizeToFit() - navigationItem.leftBarButtonItem = UIBarButtonItem(customView: label) + private func updateTitle() { + let selectedCount = "\(selected.count)/\(selectionLimit)" + switch type { + case .assignee: title = "\(NSLocalizedString("Assignees", comment: "")) \(selectedCount)" + case .reviewer: title = "\(NSLocalizedString("Reviewers", comment: "")) \(selectedCount)" + } + updateClearButtonEnabled() } // MARK: Overrides @@ -148,19 +165,6 @@ PeopleSectionControllerDelegate { // MARK: PeopleSectionControllerDelegate func didSelect(controller: PeopleSectionController) { - updateSelectionCount() - } - - func addClearButton() { - navigationItem.leftBarButtonItem = UIBarButtonItem(title: "Clear", style: .plain, target: self, action: #selector(onMenuClear)) - navigationItem.leftBarButtonItem?.tintColor = Styles.Colors.Gray.light.color - } - - @objc func onMenuClear() { - self.selected.forEach { - if let sectionController: LabelSectionController = feed.swiftAdapter.sectionController(for: $0) { - sectionController.didSelectItem(at: 0) - } - } + updateTitle() } } From fed0ceac5c730e8f12207570f305d04b7a2b65a2 Mon Sep 17 00:00:00 2001 From: Maxime Mongeau Date: Sat, 13 Oct 2018 23:29:54 -0400 Subject: [PATCH 3/5] Remove mock return for testing action menu --- Classes/Issues/IssueManagingContextController.swift | 2 -- 1 file changed, 2 deletions(-) diff --git a/Classes/Issues/IssueManagingContextController.swift b/Classes/Issues/IssueManagingContextController.swift index adfc945cc..ddadc475d 100644 --- a/Classes/Issues/IssueManagingContextController.swift +++ b/Classes/Issues/IssueManagingContextController.swift @@ -81,8 +81,6 @@ final class IssueManagingContextController: NSObject, ContextMenuDelegate { } var actions: [Action] { - // TODO: Remove me! - return [ .labels, .milestone, .assignees ] if case .none = permissions { return [] } guard let result = self.result else { return [] } From 3526da5fdc29dc439262f8110909b94b81dc8428 Mon Sep 17 00:00:00 2001 From: Maxime Mongeau Date: Sun, 14 Oct 2018 11:14:12 -0400 Subject: [PATCH 4/5] Add "Clear" string constant Remove unused Protocol --- Classes/Issues/IssueManagingContextController.swift | 1 + Classes/Labels/LabelsViewController.swift | 6 +----- Classes/Milestones/MilestonesViewController.swift | 2 +- Classes/People/PeopleViewController.swift | 6 +++--- Classes/Views/Constants.swift | 1 + 5 files changed, 7 insertions(+), 9 deletions(-) diff --git a/Classes/Issues/IssueManagingContextController.swift b/Classes/Issues/IssueManagingContextController.swift index ddadc475d..ba15e5ec9 100644 --- a/Classes/Issues/IssueManagingContextController.swift +++ b/Classes/Issues/IssueManagingContextController.swift @@ -81,6 +81,7 @@ final class IssueManagingContextController: NSObject, ContextMenuDelegate { } var actions: [Action] { + return [.labels, .milestone, .assignees, .reviewers] if case .none = permissions { return [] } guard let result = self.result else { return [] } diff --git a/Classes/Labels/LabelsViewController.swift b/Classes/Labels/LabelsViewController.swift index e4abed3ba..3ae065e9f 100644 --- a/Classes/Labels/LabelsViewController.swift +++ b/Classes/Labels/LabelsViewController.swift @@ -10,10 +10,6 @@ import UIKit import IGListKit import Squawk -protocol LabelsViewControllerDelegate { - func didSelect() -} - final class LabelsViewController: BaseListViewController2, BaseListViewController2DataSource, LabelSectionControllerDelegate { @@ -64,7 +60,7 @@ LabelSectionControllerDelegate { func addMenuClearButton() { navigationItem.leftBarButtonItem = UIBarButtonItem( - title: NSLocalizedString("Clear", comment: ""), + title: Constants.Strings.clear, style: .plain, target: self, action: #selector(onMenuClear) diff --git a/Classes/Milestones/MilestonesViewController.swift b/Classes/Milestones/MilestonesViewController.swift index 2d15deb66..3cdee204f 100644 --- a/Classes/Milestones/MilestonesViewController.swift +++ b/Classes/Milestones/MilestonesViewController.swift @@ -64,7 +64,7 @@ MilestoneSectionControllerDelegate { func addMenuClearButton() { navigationItem.leftBarButtonItem = UIBarButtonItem( - title: NSLocalizedString("Clear", comment: ""), + title: Constants.Strings.clear, style: .plain, target: self, action: #selector(onMenuClear) diff --git a/Classes/People/PeopleViewController.swift b/Classes/People/PeopleViewController.swift index 859f6d8c6..17c0d5da6 100644 --- a/Classes/People/PeopleViewController.swift +++ b/Classes/People/PeopleViewController.swift @@ -83,7 +83,7 @@ PeopleSectionControllerDelegate { func addMenuClearButton() { navigationItem.leftBarButtonItem = UIBarButtonItem( - title: NSLocalizedString("Clear", comment: ""), + title: Constants.Strings.clear, style: .plain, target: self, action: #selector(onMenuClear) @@ -115,8 +115,8 @@ PeopleSectionControllerDelegate { private func updateTitle() { let selectedCount = "\(selected.count)/\(selectionLimit)" switch type { - case .assignee: title = "\(NSLocalizedString("Assignees", comment: "")) \(selectedCount)" - case .reviewer: title = "\(NSLocalizedString("Reviewers", comment: "")) \(selectedCount)" + case .assignee: title = "\(Constants.Strings.assignees) \(selectedCount)" + case .reviewer: title = "\(Constants.Strings.reviewers) \(selectedCount)" } updateClearButtonEnabled() } diff --git a/Classes/Views/Constants.swift b/Classes/Views/Constants.swift index a2039fbb8..85b863c56 100644 --- a/Classes/Views/Constants.swift +++ b/Classes/Views/Constants.swift @@ -57,5 +57,6 @@ enum Constants { static let reviewers = NSLocalizedString("Reviewers", comment: "") static let reviewGitHubAccess = NSLocalizedString("Review GitHub Access", comment: "") static let tryAgain = NSLocalizedString("Try Again", comment: "") + static let clear = NSLocalizedString("Clear", comment: "") } } From 5c4c1373269b785de99468cbcce28f58c1f20a50 Mon Sep 17 00:00:00 2001 From: Maxime Mongeau Date: Sun, 14 Oct 2018 11:50:48 -0400 Subject: [PATCH 5/5] Setup the clear enabled state and the Poeple title correctly on init --- Classes/Issues/IssueManagingContextController.swift | 1 - Classes/Labels/LabelsViewController.swift | 1 + Classes/People/PeopleViewController.swift | 9 +++++---- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/Classes/Issues/IssueManagingContextController.swift b/Classes/Issues/IssueManagingContextController.swift index ba15e5ec9..ddadc475d 100644 --- a/Classes/Issues/IssueManagingContextController.swift +++ b/Classes/Issues/IssueManagingContextController.swift @@ -81,7 +81,6 @@ final class IssueManagingContextController: NSObject, ContextMenuDelegate { } var actions: [Action] { - return [.labels, .milestone, .assignees, .reviewers] if case .none = permissions { return [] } guard let result = self.result else { return [] } diff --git a/Classes/Labels/LabelsViewController.swift b/Classes/Labels/LabelsViewController.swift index 3ae065e9f..c4fc72be1 100644 --- a/Classes/Labels/LabelsViewController.swift +++ b/Classes/Labels/LabelsViewController.swift @@ -66,6 +66,7 @@ LabelSectionControllerDelegate { action: #selector(onMenuClear) ) navigationItem.leftBarButtonItem?.tintColor = Styles.Colors.Gray.light.color + navigationItem.leftBarButtonItem?.isEnabled = selectedLabels.count > 0 } func updateClearButtonEnabled() { diff --git a/Classes/People/PeopleViewController.swift b/Classes/People/PeopleViewController.swift index 17c0d5da6..70c77c8f8 100644 --- a/Classes/People/PeopleViewController.swift +++ b/Classes/People/PeopleViewController.swift @@ -89,7 +89,7 @@ PeopleSectionControllerDelegate { action: #selector(onMenuClear) ) navigationItem.leftBarButtonItem?.tintColor = Styles.Colors.Gray.light.color - updateClearButtonEnabled() + navigationItem.leftBarButtonItem?.isEnabled = self.selections.count > 0 } @objc func onMenuClear() { @@ -113,10 +113,11 @@ PeopleSectionControllerDelegate { // MARK: Private API private func updateTitle() { - let selectedCount = "\(selected.count)/\(selectionLimit)" + let selectedCount = users.count > 0 ? selected.count : selections.count + let counter = "\(selectedCount)/\(selectionLimit)" switch type { - case .assignee: title = "\(Constants.Strings.assignees) \(selectedCount)" - case .reviewer: title = "\(Constants.Strings.reviewers) \(selectedCount)" + case .assignee: title = "\(Constants.Strings.assignees) \(counter)" + case .reviewer: title = "\(Constants.Strings.reviewers) \(counter)" } updateClearButtonEnabled() }