Skip to content

Infinite scroll for People Management#4120

Merged
nbradbury merged 25 commits intofeature/people-management-syncfrom
feature/people-infinite-scroll
May 26, 2016
Merged

Infinite scroll for People Management#4120
nbradbury merged 25 commits intofeature/people-management-syncfrom
feature/people-infinite-scroll

Conversation

@oguzkocer
Copy link
Copy Markdown
Contributor

Relevant #3901. This PR adds infinite scroll to people list. As per our discussion on Slack, we remove the users list for a site when you visit the people page, except for the first 20 users so we don't show an empty list. The idea behind this implementation is to make sure the removed users don't show up in that list.

When a fresh list of users is received from remote, meaning the request offset parameter is 0, we remove ALL users for that site and fill it with the users from the response. From then on, when you scroll down to the end of list, a new page will be requested and we'll just save those users on top of the ones we already have. I've implemented the same progress bar we use in the reader posts page to show that we're loading more users. I just centered it because it was blocking the gravatar for the users (it's on the left for reader).

I moved PeopleAdapter into PeopleListFragment to handle end of list condition a bit easier. Initially I tried to add a listener to the adapter which was the fragment and that'd trigger the activity to make the request, but then I thought it was too long of a chain. Moving the adapter inside of the fragment made things simpler.

Question:

  • In deletePeopleForLocalBlogIdExceptForFirstPage method of PeopleTable I was unable to add the table's name people as a query parameter. The query to delete n users from the end of a table turned out to be a bit complicated. I'd appreciate any suggestions on improving that, as well as finding a way to add the PEOPLE_TABLE as a parameter.

Known issue:

  • This is unrelated to this PR but I've recently found out that public View getView(int position, View convertView, ViewGroup parent) is called 3 times for each row in PeopleAdapter. I was unable to find the source of the issue so far and will be handling it separately.

To test: Navigate to a blog where there is more than 20 users, go into People page and scroll to the end of list. You should see a loading progress bar and once that's gone, you should be able to scroll to see more users.

/cc @astralbodies, @hypest, @jleandroperez

Needs review: @nbradbury

@oguzkocer oguzkocer added this to the 5.4 milestone May 24, 2016
@nbradbury nbradbury self-assigned this May 24, 2016
if (size > fetchLimit) {
int deleteCount = size - fetchLimit;
String[] args = new String[]{Integer.toString(deleteCount), Integer.toString(localTableBlogId)};
getWritableDb().delete(PEOPLE_TABLE, "person_id " +
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Rather than hard-code "people" here, how about "person_id IN (SELECT person_id FROM " + PEOPLE_TABLE + "WHERE..."

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I've added a question to the PR description just for this 👊, because I was trying to use ? and pass the PEOPLE_TABLE as an argument. Working on that sql statement probably fried my brain a bit. 😢

@nbradbury
Copy link
Copy Markdown
Contributor

nbradbury commented May 24, 2016

This is unrelated to this PR but I've recently found out that public View getView(int position, View convertView, ViewGroup parent) is called 3 times for each row in PeopleAdapter. I was unable to find the source of the issue so far and will be handling it separately.

I remember running into this same problem in the past. Replacing the ListView with a RecyclerView should fix it (but you probably want to make that a separate PR, since it's not a simple change).

import java.util.List;

public class PeopleListFragment extends ListFragment implements OnItemClickListener {
private static String ARG_LOCAL_TABLE_BLOG_ID = "local_table_blog_id";
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Just noticed this should be final.

@maxme maxme removed this from the 5.4 milestone May 25, 2016
Integer.toString(localTableBlogId),
Integer.toString(deleteCount)
};
getWritableDb().delete(PEOPLE_TABLE, "local_blog_id=? AND person_id " +
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

For future reference, you can use numbered arguments (like ?1) in queries so you don't need to pass the same argument twice. Example:

String[] args = new String[] {
        Integer.toString(localTableBlogId),
        Integer.toString(deleteCount)
};
getWritableDb().delete(PEOPLE_TABLE, "local_blog_id=?1 AND person_id " +
        "IN (SELECT person_id FROM " + PEOPLE_TABLE + " WHERE local_blog_id=?1 " +
        "ORDER BY display_name DESC LIMIT ?2)", args);

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

TIL, thanks!

@nbradbury
Copy link
Copy Markdown
Contributor

nbradbury commented May 25, 2016

Nice work on the switch to a RecyclerView - but unfortunately the change seems to have broken infinite scroll. I can no longer scroll to get more than the initial 20 users.

@nbradbury
Copy link
Copy Markdown
Contributor

Ignore my previous comment about infinite scroll not working - that was apparently caused by some code changes I made while testing. Sorry for the false alarm!

@oguzkocer oguzkocer force-pushed the feature/people-infinite-scroll branch from b5ba30f to 113f43a Compare May 26, 2016 09:57
@oguzkocer
Copy link
Copy Markdown
Contributor Author

@nbradbury I've addressed all your feedback. fdec9be is the best way I could find that ensures the progress bar is visible at correct times. The PR should be ready for another pass. Thanks!

return mPeopleList.size();
}

@Override
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

In addition to this, the adapter's constructor should have setHasStableIds(true);

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I swear I had that! It didn't even work at first when I added it because I removed the getItemId while I was changing to RecyclerView. I guess I forgot to put it back in, so sorry, fixing now!

@oguzkocer
Copy link
Copy Markdown
Contributor Author

@nbradbury I've improved the offline mode in 821625e. We don't remove the cached users if there is no connectivity anymore (as you suggested) and we don't try to make a call to the server for any action. I've checked our codebase and generally we silently fail if there is no connection, but I think it'd be better if we tell the user about it. For now, I've used the same errors we use if the request actually fails, however I feel like it'd be better if we had a general error string to use in these situations, maybe something like "No network connection". What do you think?

@Override
public void onRoleChanged(long personID, int localTableBlogId, String newRole) {
if(!NetworkUtils.isNetworkAvailable(this)) {
ToastUtils.showToast(this, R.string.error_update_role, ToastUtils.Duration.LONG);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Since the error is due to no network, it'd be nicer to tell the user that's what the problem is. How about R.string.no_network_message instead?

@nbradbury nbradbury merged commit bbf7170 into feature/people-management-sync May 26, 2016
@nbradbury nbradbury deleted the feature/people-infinite-scroll branch May 26, 2016 18:36
};

Map<String, String> params = new HashMap<>();
params.put("number", Integer.toString(PeopleUtils.FETCH_USERS_LIMIT));
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Guys, heads up. Not sure if we're hitting the exact same endpoint, or there's a difference. But on my end, the number parameter appears to be disregarded.

Instead, i'm using page. (Checked with dotcom source!).

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Okay. Update. Apparently Users deal with offset, while Followers deal with page

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Thanks for the heads up @jleandroperez. I am currently working on the follower section and I'll make sure we use the correct parameters for this. We currently use the default values, so probably that's why I didn't notice the issue before and just used what the documentation said here: https://developer.wordpress.com/docs/api/1.1/get/sites/%24site/users/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants