Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
66 commits
Select commit Hold shift + click to select a range
33818df
Update the people list row layout to match the latest design
oguzkocer Apr 26, 2016
c44dc22
Don't use bg color and right align role
oguzkocer Apr 26, 2016
f7f834e
Change avatar size for people screen
oguzkocer Apr 26, 2016
e52766b
Change people list background to white
oguzkocer Apr 26, 2016
2877a22
Change people list divider to have a left margin
oguzkocer Apr 27, 2016
d925e88
Display name should be retrieved as for Person
oguzkocer Apr 27, 2016
51a3245
Extract person_detail layout for better reusability
oguzkocer Apr 27, 2016
22e7fff
Remove margin after avatar for person_detail
oguzkocer Apr 27, 2016
0aa2983
Use custom toolbar in PeopleManagementActivity layout
oguzkocer Apr 27, 2016
9f42d04
Setup custom toolbar in PeopleManagementActivity as it got broken
oguzkocer Apr 27, 2016
1442ec3
Fix the divider margin to match the latest changes
oguzkocer Apr 27, 2016
6761818
Refactor person UI ids for better reusability
oguzkocer Apr 28, 2016
86a6ceb
Reuse the person_detail layout in detail fragment
oguzkocer Apr 28, 2016
2a24858
Fix the role not showing up in the person details page
oguzkocer Apr 28, 2016
ebb1cf9
Make sure the display name in person details don't push role out of b…
oguzkocer Apr 28, 2016
2fbf331
No need to set an id for the include anymore
oguzkocer Apr 28, 2016
321ec04
Use match_parent for person_detail to remove unnecessary alignLeft
oguzkocer Apr 28, 2016
4d92a89
Update person detail page's layout for the latest design
oguzkocer Apr 28, 2016
3935713
Fixed some spacing issues in person detail fragment
oguzkocer Apr 29, 2016
b798904
Sets up role container and checks capabilities to edit the role
oguzkocer Apr 29, 2016
9250010
Remove background color from Role enum as it's not used anymore
oguzkocer Apr 29, 2016
493276f
Initial implementation of select role dialog
oguzkocer Apr 29, 2016
90cb52d
Merge branch 'feature/people-management-sync' into feature/people-man…
oguzkocer May 5, 2016
688abd8
Fixed: Role enum should have been deleted in the merge
oguzkocer May 5, 2016
97005c7
RoleListAdapter introduced. Better styling for the role list
oguzkocer May 5, 2016
7a7efd2
Update user role fully implemented
oguzkocer May 5, 2016
c27b3e1
Change update role network request parameters
oguzkocer May 6, 2016
d14121f
Make the update role request from activity to refresh both fragments
oguzkocer May 6, 2016
4a27fd2
Remove duplicate code by introducing refreshOnScreenFragmentDetails m…
oguzkocer May 6, 2016
22d6576
Adds a helpful comment for resetting the selected role
oguzkocer May 9, 2016
6b2977b
Better naming for the role label in change role dialog
oguzkocer May 9, 2016
d1175e1
Fix: Role container should be enabled if the user has edit_users capa…
oguzkocer May 9, 2016
68feb3f
Order people list by display name & username
oguzkocer May 9, 2016
5ba685b
Show error message for fetch people list & update user role
oguzkocer May 9, 2016
62f57ac
Update updateRole method signature to avoid unnecessary String cast
oguzkocer May 9, 2016
affa51e
Check promote_users instead of edit_users for updating user role
oguzkocer May 9, 2016
c5333c3
Current user shouldn't be able to update her own role
oguzkocer May 9, 2016
8b323a2
Role container alpha set for the disabled state
oguzkocer May 10, 2016
d448784
Adds remove user button to person detail page
oguzkocer May 10, 2016
b106066
Remove user network call implemented in PeopleUtils
oguzkocer May 10, 2016
59e8371
Adds remove user functionality to person detail page
oguzkocer May 10, 2016
1f395a7
When a fresh list of people is received, delete the old ones
oguzkocer May 11, 2016
85e692f
When a blog is deleted from DB, delete people for that blog
oguzkocer May 11, 2016
2702f0f
When a user is removed, go back to the list and refresh
oguzkocer May 11, 2016
bb09320
Remove unnecessary styling from role change dialog
oguzkocer May 11, 2016
42b8b7b
Better toast message after a user is removed
oguzkocer May 11, 2016
dbdbd41
Add a confirmation dialog for removing a person
oguzkocer May 11, 2016
80c9d1b
Merge branch 'feature/people-management-sync' into feature/people-man…
oguzkocer May 12, 2016
fff6640
Don't show remove user button if it's the current user
oguzkocer May 12, 2016
7f1cbef
Move OnClickListener for role change to inline
oguzkocer May 12, 2016
f20e9e3
Wrap to 120 chars in PeopleTable
oguzkocer May 12, 2016
4f7ad0f
Instead of keeping a reference to selecter person, get it from fragment
oguzkocer May 12, 2016
f36411b
Better handle of deprecation warning for clearing background drawable
oguzkocer May 12, 2016
941fe1f
Role array set as translatable, administrator changed to admin
oguzkocer May 13, 2016
73774da
Move clearRoleContainerBackground comment to invocation
oguzkocer May 13, 2016
5d1ff37
getCurrentPerson method renamed as loadPerson
oguzkocer May 16, 2016
9cb4399
Person role label top margin increased
oguzkocer May 16, 2016
da32d11
Keep reference to selected role in the adapter instead of fragment
oguzkocer May 16, 2016
60ce5cf
Introduce RoleChangeDialogFragment to fix dialog dismiss issue on rotate
oguzkocer May 16, 2016
01dfa29
Change selectable role from Admin to Administrator
oguzkocer May 16, 2016
6538a35
Save role change dialog state to fix rotation issue
oguzkocer May 16, 2016
d3de340
Change tool text for role label in person detail fragment
oguzkocer May 18, 2016
29182ed
Update toolbar elevation for detail page for larger toolbar look
oguzkocer May 18, 2016
f2c748b
Get rid of an extra null check in RoleChangeDialogFragment
oguzkocer May 18, 2016
2553772
Revert "Update toolbar elevation for detail page for larger toolbar l…
oguzkocer May 18, 2016
907b0bb
Remove null check for role before adding into the bundle
oguzkocer May 18, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion WordPress/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,7 @@
<activity
android:name=".ui.people.PeopleManagementActivity"
android:label="@string/people"
android:theme="@style/CalypsoTheme"/>
android:theme="@style/Calypso.NoActionBar"/>

<!-- Me activities -->
<activity
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -760,6 +760,7 @@ public boolean deleteBlog(Context ctx, int id) {
int rowsAffected = db.delete(BLOGS_TABLE, "id=?", new String[]{Integer.toString(id)});
deleteQuickPressShortcutsForLocalTableBlogId(ctx, id);
deleteAllPostsForLocalTableBlogId(id);
PeopleTable.deletePeopleForBlog(id);
return (rowsAffected > 0);
}

Expand All @@ -769,6 +770,7 @@ public boolean deleteWordPressComBlogs(Context ctx) {
int localBlogId = MapUtils.getMapInt(blog, "id");
deleteQuickPressShortcutsForLocalTableBlogId(ctx, localBlogId);
deleteAllPostsForLocalTableBlogId(localBlogId);
PeopleTable.deletePeopleForBlog(localBlogId);
}

// H4ck alert: We need to delete the Jetpack sites that were added in the initial
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,12 @@ public static void save(Person person, SQLiteDatabase database) {
database.insertWithOnConflict(PEOPLE_TABLE, null, values, SQLiteDatabase.CONFLICT_REPLACE);
}

public static void savePeople(List<Person> peopleList) {
public static void savePeople(List<Person> peopleList, int localTableBlogId) {
getWritableDb().beginTransaction();
try {
//We have a fresh list, remove the previous list of people in case it was deleted on remote
PeopleTable.deletePeopleForBlog(localTableBlogId);

for (Person person : peopleList) {
PeopleTable.save(person);
}
Expand All @@ -77,10 +80,21 @@ public static void savePeople(List<Person> peopleList) {
}
}

public static void deletePeopleForBlog(int localTableBlogId) {
String[] args = new String[]{Integer.toString(localTableBlogId)};
getWritableDb().delete(PEOPLE_TABLE, "local_blog_id=?", args);
}

public static void deletePerson(long personID, int localTableBlogId) {
String[] args = new String[]{Long.toString(personID), Integer.toString(localTableBlogId)};
getWritableDb().delete(PEOPLE_TABLE, "person_id=? AND local_blog_id=?", args);
}

public static List<Person> getPeople(int localTableBlogId) {
List<Person> people = new ArrayList<>();
String[] args = { Integer.toString(localTableBlogId) };
Cursor c = getReadableDb().rawQuery("SELECT * FROM " + PEOPLE_TABLE + " WHERE local_blog_id=?", args);
Cursor c = getReadableDb().rawQuery("SELECT * FROM " + PEOPLE_TABLE +
" WHERE local_blog_id=? ORDER BY display_name, user_name", args);
Copy link
Contributor

Choose a reason for hiding this comment

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

Not in this changeset but, there are a couple of lines below this one that could use the same treatment and be wrapped at 120chars. Cheers!


try {
while (c.moveToNext()) {
Expand All @@ -102,7 +116,8 @@ public static List<Person> getPeople(int localTableBlogId) {
*/
public static Person getPerson(long personId, int localTableBlogId) {
String[] args = { Long.toString(personId), Integer.toString(localTableBlogId) };
Cursor c = getReadableDb().rawQuery("SELECT * FROM " + PEOPLE_TABLE + " WHERE person_id=? AND local_blog_id=?", args);
Cursor c = getReadableDb().rawQuery("SELECT * FROM " + PEOPLE_TABLE +
" WHERE person_id=? AND local_blog_id=?", args);
try {
if (!c.moveToFirst()) {
return null;
Expand All @@ -123,6 +138,7 @@ private static Person getPersonFromCursor(Cursor c, int localTableBlogId) {
String avatarUrl = c.getString(c.getColumnIndex("avatar_url"));
String role = c.getString(c.getColumnIndex("role"));

return new Person(personId, blogId, localTableBlogId, username, firstName, lastName, displayName, avatarUrl, role);
return new Person(personId, blogId, localTableBlogId, username,
firstName, lastName, displayName, avatarUrl, role);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
* A list of capabilities can be found in: https://codex.wordpress.org/Roles_and_Capabilities#Capabilities
*/
public enum Capability {
EDIT_USERS("edit_users"), // Check if user can change another user's role
LIST_USERS("list_users"), // Check if user can visit People page
PROMOTE_USERS("promote_users"); // Check if user can invite another user
PROMOTE_USERS("promote_users"), // Check if user can change another user's role
REMOVE_USERS("remove_users"); // Check if user can remove another user

private final String label;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public static Person fromJSON(JSONObject json, String blogId, int localTableBlog
String username = json.optString("login");
String firstName = json.optString("first_name");
String lastName = json.optString("last_name");
String displayName = json.optString("nice_name");
String displayName = json.optString("name");
String avatarUrl = json.optString("avatar_URL");
// We don't support multiple roles, so the first role is picked just as it's in Calypso
String role = json.getJSONArray("roles").optString(0);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,10 +88,10 @@ private class PeopleViewHolder {
private final TextView txtRole;

PeopleViewHolder(View row) {
imgAvatar = (WPNetworkImageView) row.findViewById(R.id.people_list_row_avatar);
txtDisplayName = (TextView) row.findViewById(R.id.people_list_row_display_name);
txtUsername = (TextView) row.findViewById(R.id.people_list_row_username);
txtRole = (TextView) row.findViewById(R.id.people_list_row_role);
imgAvatar = (WPNetworkImageView) row.findViewById(R.id.person_avatar);
txtDisplayName = (TextView) row.findViewById(R.id.person_display_name);
txtUsername = (TextView) row.findViewById(R.id.person_username);
txtRole = (TextView) row.findViewById(R.id.person_role);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
package org.wordpress.android.ui.people;

import android.app.AlertDialog;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.MenuItem;

import org.wordpress.android.R;
Expand All @@ -15,23 +18,29 @@
import org.wordpress.android.ui.ActivityLauncher;
import org.wordpress.android.ui.accounts.BlogUtils;
import org.wordpress.android.ui.people.utils.PeopleUtils;
import org.wordpress.android.util.ToastUtils;

import java.util.List;

public class PeopleManagementActivity extends AppCompatActivity implements PeopleListFragment.OnPersonSelectedListener {
public class PeopleManagementActivity extends AppCompatActivity
implements PeopleListFragment.OnPersonSelectedListener, RoleChangeDialogFragment.OnChangeListener {
private static final String KEY_PEOPLE_LIST_FRAGMENT = "people-list-fragment";
private static final String KEY_PERSON_DETAIL_FRAGMENT = "person-detail-fragment";

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

setContentView(R.layout.people_management_activity);

Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.setTitle(R.string.people);
actionBar.setHomeButtonEnabled(true);
actionBar.setDisplayHomeAsUpEnabled(true);
}
setContentView(R.layout.people_management_activity);

int localBlogId = BlogUtils.getBlogLocalId(WordPress.getCurrentBlog());
Blog blog = WordPress.getBlog(localBlogId);
Expand All @@ -57,9 +66,7 @@ public void finish() {

@Override
public void onBackPressed() {
if (getFragmentManager().getBackStackEntryCount() > 0 ){
getFragmentManager().popBackStack();
} else {
if (!navigateBackToPeopleListFragment()) {
super.onBackPressed();
}
}
Expand All @@ -69,6 +76,9 @@ public boolean onOptionsItemSelected(final MenuItem item) {
if (item.getItemId() == android.R.id.home) {
onBackPressed();
return true;
} else if (item.getItemId() == R.id.remove_person) {
confirmRemovePerson();
return true;
}
return super.onOptionsItemSelected(item);
}
Expand All @@ -77,25 +87,15 @@ private void refreshUsersList(String dotComBlogId, final int localTableBlogId) {
PeopleUtils.fetchUsers(dotComBlogId, localTableBlogId, new PeopleUtils.FetchUsersCallback() {
@Override
public void onSuccess(List<Person> peopleList) {
PeopleTable.savePeople(peopleList);

FragmentManager fragmentManager = getFragmentManager();
PeopleListFragment peopleListFragment = (PeopleListFragment) fragmentManager
.findFragmentByTag(KEY_PEOPLE_LIST_FRAGMENT);
PersonDetailFragment personDetailFragment = (PersonDetailFragment) fragmentManager
.findFragmentByTag(KEY_PERSON_DETAIL_FRAGMENT);

if (peopleListFragment != null) {
peopleListFragment.refreshPeopleList();
}
if (personDetailFragment != null) {
personDetailFragment.refreshPersonDetails();
}
PeopleTable.savePeople(peopleList, localTableBlogId);
refreshOnScreenFragmentDetails();
}

@Override
public void onError() {
//TODO: show some kind of error to the user
ToastUtils.showToast(PeopleManagementActivity.this,
R.string.error_fetch_people_list,
ToastUtils.Duration.LONG);
}
});
}
Expand All @@ -120,4 +120,124 @@ public void onPersonSelected(Person person) {
fragmentTransaction.commit();
}
}

@Override
public void onRoleChanged(long personID, int localTableBlogId, String newRole) {
Person person = PeopleTable.getPerson(personID, localTableBlogId);
if (person == null || newRole == null || newRole.equalsIgnoreCase(person.getRole())) {
return;
}
PeopleUtils.updateRole(person.getBlogId(), person.getPersonID(), newRole, localTableBlogId,
new PeopleUtils.UpdateUserCallback() {
@Override
public void onSuccess(Person person) {
PeopleTable.save(person);
refreshOnScreenFragmentDetails();
}

@Override
public void onError() {
ToastUtils.showToast(PeopleManagementActivity.this,
R.string.error_update_role,
ToastUtils.Duration.LONG);
}
});
}

private void confirmRemovePerson() {
Copy link
Contributor

Choose a reason for hiding this comment

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

It seems that we're not checking for current user when removing. Should that be allowed? If not, perhaps we can put out a message explaining why it cannot be done, or more simply remove the "remove" button completely. Cheers!

Person person = getCurrentPerson();
if (person == null) {
return;
}

AlertDialog.Builder builder = new AlertDialog.Builder(this, R.style.Calypso_AlertDialog);
builder.setTitle(getString(R.string.person_remove_confirmation_title, person.getDisplayName()));
builder.setMessage(getString(R.string.person_remove_confirmation_message, person.getDisplayName()));
builder.setNegativeButton(R.string.cancel, null);
builder.setPositiveButton(R.string.remove, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
removeSelectedPerson();
}
});
builder.show();
}

private void removeSelectedPerson() {
Person person = getCurrentPerson();
if (person == null) {
return;
}
PeopleUtils.removePerson(person.getBlogId(),
person.getPersonID(),
person.getLocalTableBlogId(),
new PeopleUtils.RemoveUserCallback() {
@Override
public void onSuccess(long personID, int localTableBlogId) {
// remove the person from db, navigate back to list fragment and refresh it
Person person = PeopleTable.getPerson(personID, localTableBlogId);
String text;
if (person != null) {
PeopleTable.deletePerson(personID, localTableBlogId);
text = getString(R.string.person_removed, person.getUsername());
Copy link
Contributor

Choose a reason for hiding this comment

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

Not sure if this is by design but, since we are asking for remove confirmation using the Person's display name, I think it makes sense to use the same in the Toast as well. Cheers!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's by design. Although I agree with you, we want to match what Calypso does, and Calypso uses the exact same strings.

} else {
text = getString(R.string.person_removed_general);
}

ToastUtils.showToast(PeopleManagementActivity.this, text, ToastUtils.Duration.LONG);

navigateBackToPeopleListFragment();
refreshPeopleListFragment();
}

@Override
public void onError() {
ToastUtils.showToast(PeopleManagementActivity.this,
R.string.error_remove_user,
ToastUtils.Duration.LONG);
}
});
}

// This helper method is used after a successful network request
private void refreshOnScreenFragmentDetails() {
FragmentManager fragmentManager = getFragmentManager();
PersonDetailFragment personDetailFragment = (PersonDetailFragment) fragmentManager
.findFragmentByTag(KEY_PERSON_DETAIL_FRAGMENT);

if (personDetailFragment != null) {
personDetailFragment.refreshPersonDetails();
}

refreshPeopleListFragment();
}

private void refreshPeopleListFragment() {
FragmentManager fragmentManager = getFragmentManager();
PeopleListFragment peopleListFragment = (PeopleListFragment) fragmentManager
.findFragmentByTag(KEY_PEOPLE_LIST_FRAGMENT);
if (peopleListFragment != null) {
peopleListFragment.refreshPeopleList();
}
}

private boolean navigateBackToPeopleListFragment() {
if (getFragmentManager().getBackStackEntryCount() > 0) {
getFragmentManager().popBackStack();
return true;
}
return false;
}

private Person getCurrentPerson() {
FragmentManager fragmentManager = getFragmentManager();
PersonDetailFragment personDetailFragment = (PersonDetailFragment) fragmentManager
.findFragmentByTag(KEY_PERSON_DETAIL_FRAGMENT);

if (personDetailFragment == null) {
return null;
}

return personDetailFragment.loadPerson();
}
}
Loading