hint for no goal when filtering and ptr on empty list#506
hint for no goal when filtering and ptr on empty list#506krugerk wants to merge 4 commits intobeeminder:masterfrom
Conversation
3da3a0d to
6781c47
Compare
|
|
||
| func numberOfSections(in collectionView: UICollectionView) -> Int { | ||
| return 1 | ||
| switch (filteredGoals.isEmpty, goals.isEmpty) { |
There was a problem hiding this comment.
numberOfSections seems like it should be a pure function which just returns a number and doesn't have side effects like updating the background. Maybe updateGoals() is a better place for this to live?
There was a problem hiding this comment.
I am not sure I understand. With this change the background is set according to the number of sections and is being set in the numberOfSections. So yeah, that method has the side effect of setting the background.
As is, updateGoals() does not seem to be an ideal spot for the change either.
I made a change; take a look
ddf0553 to
5a582e2
Compare
5a582e2 to
d99fc1d
Compare
| } | ||
|
|
||
| func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { | ||
| return ServiceLocator.versionManager.lastChckedUpdateState() == .UpdateRequired ? 0 : self.filteredGoals.count |
There was a problem hiding this comment.
- include 'update required' as one of the reasons for an empty list (show need upgrade in the background view)
theospears
left a comment
There was a problem hiding this comment.
I agree using BackgroundView on CollectionView is a reasonable way to handle this.
This PR will conflict with #542. Given you opened it first I don't want to put the work on fixing all the merge conflicts on you, so added some feedback about what updates are necessary for this to be merged. If you're happy to follow up on them in the next week I'll hold off on #542 and fix it up to be compatible after this is merged.
|
|
||
| func numberOfSections(in collectionView: UICollectionView) -> Int { | ||
| return 1 | ||
| [filteredGoals.isEmpty, goals.isEmpty].contains(true) ? 0 : 1 |
There was a problem hiding this comment.
| [filteredGoals.isEmpty, goals.isEmpty].contains(true) ? 0 : 1 | |
| filteredGoals.isEmpty ? 0 : 1 |
If goals is empty then filtered goals will always be, right?
There was a problem hiding this comment.
Yes, if goals is empty, then any subset of it would also be empty, including the one known as filteredGoals.
I see what you mean: we are always using the combination of the filter applied to the goals and thus the set in filteredGoals. When the searchBar.text the filtered is considered off and all goals are in filteredGoals.
There was a problem hiding this comment.
Perhaps these names are unclear. Something like allGoals and visibleGoals might have been a better choice?
| var goals : [Goal] = [] | ||
| var filteredGoals : [Goal] = [] | ||
| var goals : [Goal] = [] { | ||
| didSet { |
There was a problem hiding this comment.
[Do] Move this logic (and filteredGoals.didSet) to didUpdateGoals which contains all the other logic/view invalidation which is run when the set of goals update.
| var view: UIView? { | ||
| switch (filteredGoals.isEmpty, goals.isEmpty) { | ||
| case (true, false): | ||
| return self.makeViewForEmptyCollection(when: .noGoalsMatchingFilter) |
There was a problem hiding this comment.
[Do] Remove the enum and the multiple views, just pass in a string here.
I've marked this as a Do, but I'm open to being convinced otherwise. At the moment I don't see the benefit to justify the additional complexity.
There was a problem hiding this comment.
Currently collectionView?.backgroundView is being set to a UIView which is just a container, containing a BSLabel with the reason no goals are shown, and, below it, another UIView acting as a spacer.
The intent was to show the text/label "above the fold" for better visibility and to not have it sit in the middle, which would be covered by the MBProgressHUD activity indicator.
Your proposal is just to set the backgroundView to the label directly?
There was a problem hiding this comment.
I'm happy either to set it to the view, or the label directly. I just don't think we get much from having the NoGoalReason enum - makeViewForEmptyCollection could just take the string to show.
Thanks for the consideration. (some amount of) Updating the MR so that it is mergable with its target is to be expected. And I would update it accordingly. |
bfee8d4 to
04a0479
Compare
| } | ||
|
|
||
| func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { | ||
| let row = (indexPath as NSIndexPath).row |
There was a problem hiding this comment.
| let row = (indexPath as NSIndexPath).row | |
| let row = indexPath.row |
| func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { | ||
| let row = (indexPath as NSIndexPath).row | ||
| if row < self.filteredGoals.count { self.openGoal(self.filteredGoals[row]) } | ||
| if row < self.visibleGoals.count { self.openGoal(self.visibleGoals[row]) } |
There was a problem hiding this comment.
| if row < self.visibleGoals.count { self.openGoal(self.visibleGoals[row]) } | |
| if row < self.visibleGoals.count { | |
| self.openGoal(self.visibleGoals[row]) | |
| } |
9aabc04 to
3f5dad5
Compare
| matchingGoal = self.allGoals.filter({ (goal) -> Bool in | ||
| return goal.slug == slug | ||
| }).last |
There was a problem hiding this comment.
| matchingGoal = self.allGoals.filter({ (goal) -> Bool in | |
| return goal.slug == slug | |
| }).last | |
| matchingGoal = self.allGoals.last(where: { $0.slug == slug }) |
There was a problem hiding this comment.
unrelated to this PR though
@objc func openGoalFromNotification(_ notification: Notification) {
var goalFromIdentifier: Goal? {
guard
let identifier = notification.userInfo?["identifier"] as? String,
let url = URL(string: identifier),
let objectID = viewContext.persistentStoreCoordinator?.managedObjectID(forURIRepresentation: url)
else { return nil }
return viewContext.object(with: objectID) as? Goal
}
var goalFromSlug: Goal? {
guard
let slug = notification.userInfo?["slug"] as? String
else { return nil }
return self.allGoals.last(where: { $0.slug == slug })
}
if let matchingGoal = goalFromIdentifier ?? goalFromSlug {
self.navigationController?.popToRootViewController(animated: false)
self.openGoal(matchingGoal)
}
}| case (true, false): | ||
| return self.makeViewForEmptyCollection(when: .noGoalsMatchingFilter) | ||
| case (true, true): | ||
| return self.makeViewForEmptyCollection(when: .noActiveGoals) | ||
| default: | ||
| return nil |
There was a problem hiding this comment.
| case (true, false): | |
| return self.makeViewForEmptyCollection(when: .noGoalsMatchingFilter) | |
| case (true, true): | |
| return self.makeViewForEmptyCollection(when: .noActiveGoals) | |
| default: | |
| return nil | |
| case (true, false): | |
| self.makeViewForEmptyCollection(when: .noGoalsMatchingFilter) | |
| case (true, true): | |
| self.makeViewForEmptyCollection(when: .noActiveGoals) | |
| default: | |
| nil |
| let cell:GoalCollectionViewCell = self.collectionView!.dequeueReusableCell(withReuseIdentifier: self.cellReuseIdentifier, for: indexPath) as! GoalCollectionViewCell | ||
|
|
||
| let goal:Goal = self.filteredGoals[(indexPath as NSIndexPath).row] | ||
| let goal:Goal = self.visibleGoals[(indexPath as NSIndexPath).row] |
There was a problem hiding this comment.
| let goal:Goal = self.visibleGoals[(indexPath as NSIndexPath).row] | |
| let goal:Goal = self.visibleGoals[indexPath.row] |
| @@ -429,20 +416,20 @@ class GalleryViewController: UIViewController, UICollectionViewDelegateFlowLayou | |||
| func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { | |||
| let cell:GoalCollectionViewCell = self.collectionView!.dequeueReusableCell(withReuseIdentifier: self.cellReuseIdentifier, for: indexPath) as! GoalCollectionViewCell | |||
There was a problem hiding this comment.
why self.collectionView with ! and not merely the collectionView passed into this method?
| var allGoals : [Goal] = [] | ||
| var visibleGoals : [Goal] = [] |
There was a problem hiding this comment.
| var allGoals : [Goal] = [] | |
| var visibleGoals : [Goal] = [] | |
| var allGoals = [Goal]() | |
| var visibleGoals = [Goal]() |
| var deadbeatView = UIView() | ||
| var outofdateView = UIView() |
There was a problem hiding this comment.
| var deadbeatView = UIView() | |
| var outofdateView = UIView() | |
| let deadbeatView = UIView() | |
| let outOfDateView = UIView() |
af1943c to
c86c79e
Compare
c86c79e to
9607a6c
Compare
uses the common technique of setting the backgroundView of the CollectionView when no items would be displayed fixes beeminder#226
9607a6c to
747fa81
Compare
uses the common technique of setting the backgroundView of the CollectionView when no items would be displayed
fixes #226
fixes #604
new notice screen:

and now with pull-to-refresh:

and the new hint:
