Skip to content

Let devs intercept onChanged events and control when to update their adapter #488

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

Merged
merged 29 commits into from
Jan 24, 2017
Merged

Let devs intercept onChanged events and control when to update their adapter #488

merged 29 commits into from
Jan 24, 2017

Conversation

SUPERCILEX
Copy link
Collaborator

Would address issues like #482 and see #15 (comment).

mManager = new LinearLayoutManager(this);
mManager.setReverseLayout(false);

mMessages.setHasFixedSize(false);
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unnecessary, these are defaults.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are valid reasons for having this code here, which we could debate here. But these reasons have nothing to do with letting devs intercept change events. In future PRs please keep functional changes separate from code cleanup.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed this change, but I am curious, why are we setting default values and adding seemingly unnecessary code?

Toast.makeText(ChatActivity.this, "Signed In",
Toast.LENGTH_SHORT).show();
attachRecyclerViewAdapter();
Toast.makeText(getApplicationContext(),
Copy link
Collaborator Author

@SUPERCILEX SUPERCILEX Jan 4, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Show toast and continue logging in even if screen was rotated.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did we remove the call to attachRecyclerViewAdapter() here? Also if we scope the onComplete listener to the Activity context then we can avoid dead activity issues.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@samtstern I've extracted the toast logic into a static class to prevent activity leaks. As for the attachRecyclerViewAdapter, I moved that up to an onSuccess listener that is tied to the activity.

@SUPERCILEX
Copy link
Collaborator Author

@puf PTAL, these changes shouldn't be anything major and can be merged in this branch since I'm targeting the dev branch. I'll merge your other PRs into this branch and resolve conflicts since I think there will be style issues causing the Travis build to fail. (FirebaseUI now has static analysis checks!)

Copy link
Contributor

@samtstern samtstern left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change LGTM.

Toast.makeText(ChatActivity.this, "Signed In",
Toast.LENGTH_SHORT).show();
attachRecyclerViewAdapter();
Toast.makeText(getApplicationContext(),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did we remove the call to attachRecyclerViewAdapter() here? Also if we scope the onComplete listener to the Activity context then we can avoid dead activity issues.

@samtstern samtstern requested a review from puf January 5, 2017 17:12
@samtstern
Copy link
Contributor

@puf could you take a look? Basically this does two things:

  1. Move the OnChangedListener interface out of FirebaseArray and make it first class.
  2. Make a protected onChanged() function in the adapters so that some developers can change the behavior.

@SUPERCILEX
Copy link
Collaborator Author

@puf Since OnChangedListener is now public would you be ok with me renaming things?

  1. OnChangedListener -> ChangeEventListener to be more consistent with Firebase apis
  2. onChanged -> onChildChanged as discussed in This change allows easy detection of the list being empty *and* respo… #487 (comment)

@puf @samtstern What do you guys think?

Copy link
Contributor

@puf puf left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall looks like a useful change, but I have a few comments

mManager = new LinearLayoutManager(this);
mManager.setReverseLayout(false);

mMessages.setHasFixedSize(false);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are valid reasons for having this code here, which we could debate here. But these reasons have nothing to do with letting devs intercept change events. In future PRs please keep functional changes separate from code cleanup.

attachRecyclerViewAdapter();
} else {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as before: this change seems unrelated to the topic of this PR and just expresses a personal preference. While that preference might well be better than the existing code, it should not pollute this PR.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@puf I write my PRs with the philosophy that small improvements as we go along are better than constantly submitting side PRs for this kind of change. However, I see where you are coming from and removed these changes from this PR.

@@ -286,4 +276,21 @@ public void setText(String text) {
mTextField.setText(text);
}
}

private static class SignInResultNotifier implements OnCompleteListener<AuthResult> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice addition! I'd appreciate some documentation on this class though.

import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;

public interface OnChangedListener {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm fine pulling this up. But wouldn't it be better as an interface in FirebaseArray (which I see moving towards becoming an abstract base-class or interface itself)? Having this inside FirebaseArray makes it more explicitly scoped as "these operations apply to this FirebaseArray (or subclass) object".

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@puf, I would like that too, but you've chosen to keep FirebaseArray package private so people will get an error when overriding onChanged saying they can't access FirebaseArray.OnChangedListener.EventType. To put OnChangedListener in FirebaseArray we would have to go public and I don't think FirebaseArray is quite ready for that.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But then isn't this essentially doing the same: making a part of the internal workings of FirebaseArray public?

Copy link
Collaborator Author

@SUPERCILEX SUPERCILEX left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@puf, I addressed your review comments, but I would like your thoughts on #488 (comment) before merging.

import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;

public interface OnChangedListener {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@puf, I would like that too, but you've chosen to keep FirebaseArray package private so people will get an error when overriding onChanged saying they can't access FirebaseArray.OnChangedListener.EventType. To put OnChangedListener in FirebaseArray we would have to go public and I don't think FirebaseArray is quite ready for that.

@puf
Copy link
Contributor

puf commented Jan 8, 2017 via email

@SUPERCILEX
Copy link
Collaborator Author

SUPERCILEX commented Jan 8, 2017 via email

@SUPERCILEX
Copy link
Collaborator Author

@puf since you pushed 21d5d44, I went ahead with the rename.

Signed-off-by: Alex Saveau <[email protected]>
…predicates

# Conflicts:
#	database/src/androidTest/java/com/firebase/ui/database/TestUtils.java
#	database/src/main/java/com/firebase/ui/database/FirebaseListAdapter.java
#	database/src/main/java/com/firebase/ui/database/FirebaseRecyclerAdapter.java
Signed-off-by: Alex Saveau <[email protected]>
Signed-off-by: Alex Saveau <[email protected]>
@SUPERCILEX
Copy link
Collaborator Author

@puf, any chance you could take another look at this? (I just merged everything)

@@ -80,21 +69,21 @@ public void onChildAdded(DataSnapshot snapshot, String previousChildKey) {
index = getIndexForKey(previousChildKey) + 1;
}
mSnapshots.add(index, snapshot);
notifyChangedListeners(OnChangedListener.EventType.ADDED, index);
notifyChangedListeners(ChangeEventListener.EventType.ADDED, index);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Definitely a better name! +1

@@ -51,7 +51,7 @@
* contained in the children of the given Firebase location
*/
public abstract class FirebaseListAdapter<T> extends BaseAdapter {
private static final String TAG = FirebaseListAdapter.class.getSimpleName();
private static final String TAG = "FirebaseListAdapter";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you explain why this change is needed/useful?

Copy link
Collaborator Author

@SUPERCILEX SUPERCILEX Jan 16, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@puf This isn't so much needed in FirebaseListAdapter, but this is a massive no-no in the FirebaseRecyclerAdapter where the name is 23 characters long. I made this tag in one of my first PRs and I really regret it: if someone were to create a tag using getSimpleName() in FirebaseIndexRecyclerAdapter, Log.anything will throw an exception because the tag name exceeds 24 characters. You should NEVER use dynamic tag names for that reason.

@puf, since this is higher priority than #488, I've created #525.

@puf
Copy link
Contributor

puf commented Jan 16, 2017

@SUPERCILEX I left a few comments. Most are very minor. The only real concern is that we'll end up exposing internal details of the FirebaseArray when those aren't sufficiently hardened yet. But I'm very willing to take a vote there, as the recent changes feel like a move in the right direction.

Of course we'll need the same ability to listen for changes in FirebaseUI-iOS, before we can merge. @morganchen12 did you already have a look at this?

@SUPERCILEX
Copy link
Collaborator Author

@puf SGTM! I think you'll like my upcoming PRs for FirebaseArray... 😄

@morganchen12
Copy link

morganchen12 commented Jan 17, 2017

I think this feature is added with the transforms PR on iOS. @puf

@SUPERCILEX SUPERCILEX changed the base branch from version-1.1.0-dev to master January 17, 2017 19:00
Signed-off-by: Alex Saveau <[email protected]>
Signed-off-by: Alex Saveau <[email protected]>
@SUPERCILEX
Copy link
Collaborator Author

SUPERCILEX commented Jan 18, 2017

@puf @morganchen12 @samtstern This PR doesn't provide explicit support for joins because @puf doesn't want that, but it does allow devs to do their own filtering as seen in my crappy example. So, @morganchen12 @puf do you guys want to merge this PR and firebase/FirebaseUI-iOS#186 and call it good because @puf doesn't want to support on device filerting? Or should we do something else?

I personally agree with @puf about not doing filtering on device, but there's the feature parity thing. I think this PR is good enough though because it lets devs choose what they want to do. If need be, we could provider a better example than my own that demos filtering and sorting on device with this PR.

@morganchen12
Copy link

iOS doesn't add on-device filtering either, so no feature parity issues there.

@SUPERCILEX
Copy link
Collaborator Author

@samtstern @puf @morganchen12 So are we good to merge?

@samtstern
Copy link
Contributor

Still fine with me, will let @puf pull the trigger. I have just pushed a new version-1.2.0-dev branch off of master where we should put this feature.

@morganchen12
Copy link

Fine with me, pending @puf's decision as well

@SUPERCILEX SUPERCILEX changed the base branch from master to version-1.2.0-dev January 21, 2017 01:30
@SUPERCILEX
Copy link
Collaborator Author

@puf, could you please take another look at this? It's blocking progress on my other PRs... Thanks!

@samtstern
Copy link
Contributor

Ok after some team discussion it's time to merge this. Squashing and merging into the 1.2.0 branch.

@samtstern samtstern merged commit d08eaa0 into firebase:version-1.2.0-dev Jan 24, 2017
@SUPERCILEX SUPERCILEX deleted the enable-filtering+predicates branch January 24, 2017 22:14
@SUPERCILEX
Copy link
Collaborator Author

@samtstern Really glad to have this merged!

I started writing a post demoing some use cases so just in case anyone wants to see it, here you go: #482 (comment).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants