-
Notifications
You must be signed in to change notification settings - Fork 7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
hint for no goal when filtering and ptr on empty list #506
base: master
Are you sure you want to change the base?
hint for no goal when filtering and ptr on empty list #506
Conversation
3da3a0d
to
6781c47
Compare
@@ -431,9 +414,19 @@ class GalleryViewController: UIViewController, UICollectionViewDelegateFlowLayou | |||
} | |||
|
|||
func numberOfSections(in collectionView: UICollectionView) -> Int { | |||
return 1 | |||
switch (filteredGoals.isEmpty, goals.isEmpty) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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
} | ||
let searchItem = UIBarButtonItem(barButtonSystemItem: .search, target: self, action: #selector(self.searchButtonPressed)) | ||
self.navigationItem.leftBarButtonItem = searchItem | ||
self.navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .search, target: self, action: #selector(self.searchButtonPressed)) | ||
} | ||
|
||
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { | ||
return ServiceLocator.versionManager.lastChckedUpdateState() == .UpdateRequired ? 0 : self.filteredGoals.count |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- include 'update required' as one of the reasons for an empty list (show need upgrade in the background view)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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 collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { | ||
return ServiceLocator.versionManager.lastChckedUpdateState() == .UpdateRequired ? 0 : self.filteredGoals.count | ||
} | ||
|
||
func numberOfSections(in collectionView: UICollectionView) -> Int { | ||
return 1 | ||
[filteredGoals.isEmpty, goals.isEmpty].contains(true) ? 0 : 1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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
|
||
cell.goal = goal | ||
|
||
return cell | ||
} | ||
|
||
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForFooterInSection section: Int) -> CGSize { | ||
return CGSize(width: 320, height: section == 0 && self.goals.count > 0 ? 5 : 0) | ||
return CGSize(width: 320, height: section == 0 && self.allGoals.count > 0 ? 5 : 0) | ||
} | ||
|
||
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { | ||
let row = (indexPath as NSIndexPath).row |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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 |
@@ -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 | |||
|
|||
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
var deadbeatView = UIView() | |
var outofdateView = UIView() | |
let deadbeatView = UIView() | |
let outOfDateView = UIView() |
uses the common technique of setting the backgroundView of the CollectionView when no items would be displayed fixes beeminder#226
now it is in a small container and the visible text can be placed elsewhere easily
... or the search could placed in viewDidLoad with the rest of the setup
af1943c
to
c86c79e
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:
