Can update friend following status

This commit is contained in:
Pierre HUBERT 2018-08-23 14:51:05 +02:00
parent 0f8274dd28
commit 7989c2c377
6 changed files with 202 additions and 68 deletions

View File

@ -22,6 +22,16 @@ import java.util.ArrayList;
public class FriendsListDbHelper { public class FriendsListDbHelper {
/**
* Required database columns
*/
private static final String[] mColumns = {
FriendsListSchema.COLUMN_NAME_FRIEND_ID,
FriendsListSchema.COLUMN_NAME_FRIEND_ACCEPTED,
FriendsListSchema.COLUMN_NAME_FRIEND_FOLLOWING,
FriendsListSchema.COLUMN_NAME_FRIEND_LAST_ACTIVITY
};
/** /**
* Database helper * Database helper
*/ */
@ -49,16 +59,10 @@ public class FriendsListDbHelper {
//Prepare the request on the database //Prepare the request on the database
String table_name = FriendsListSchema.TABLE_NAME; String table_name = FriendsListSchema.TABLE_NAME;
String[] columns = {
FriendsListSchema.COLUMN_NAME_FRIEND_ID,
FriendsListSchema.COLUMN_NAME_FRIEND_ACCEPTED,
FriendsListSchema.COLUMN_NAME_FRIEND_FOLLOWING,
FriendsListSchema.COLUMN_NAME_FRIEND_LAST_ACTIVITY
};
String order = FriendsListSchema._ID; String order = FriendsListSchema._ID;
//Perform the request //Perform the request
Cursor c = db.query(table_name, columns, null, null, null, null, order); Cursor c = db.query(table_name, mColumns, null, null, null, null, order);
//Check if the request echoed //Check if the request echoed
if(c == null) if(c == null)
@ -70,23 +74,8 @@ public class FriendsListDbHelper {
c.moveToFirst(); c.moveToFirst();
for(int i = 0; i < c.getCount(); i++){ for(int i = 0; i < c.getCount(); i++){
//Get information about the friend
Friend friend = new Friend();
friend.setId(c.getInt(c.getColumnIndexOrThrow(
FriendsListSchema.COLUMN_NAME_FRIEND_ID)));
friend.setAccepted(c.getInt(c.getColumnIndexOrThrow(
FriendsListSchema.COLUMN_NAME_FRIEND_ACCEPTED)) == 1);
friend.setFollowing(c.getInt(c.getColumnIndexOrThrow(
FriendsListSchema.COLUMN_NAME_FRIEND_FOLLOWING)) == 1);
friend.setLast_activity(c.getInt(c.getColumnIndexOrThrow(
FriendsListSchema.COLUMN_NAME_FRIEND_LAST_ACTIVITY)));
//Add the friend to the list //Add the friend to the list
friendsList.add(friend); friendsList.add(parseDbEntryToFriend(c));
//Move to the next friend //Move to the next friend
if(!c.moveToNext()) if(!c.moveToNext())
@ -99,6 +88,32 @@ public class FriendsListDbHelper {
return friendsList; return friendsList;
} }
/**
* Get a single friend entry
*
* @param friendID The ID of the friend to get
* @return Information about the friend / null in case of failure
*/
@Nullable
Friend getSingleFriend(int friendID){
SQLiteDatabase db = dbHelper.getReadableDatabase();
String[] selectionArgs = {friendID+""};
Cursor c = db.query(FriendsListSchema.TABLE_NAME, mColumns,
FriendsListSchema.COLUMN_NAME_FRIEND_ID + " = ?", selectionArgs,
null, null, null);
c.moveToFirst();
if(c.getCount() < 1)
return null;
Friend friend = parseDbEntryToFriend(c);
c.close();
return friend;
}
/** /**
* Update the entire list of friends * Update the entire list of friends
* *
@ -234,4 +249,29 @@ public class FriendsListDbHelper {
return values; return values;
} }
/**
* Parse a database entry into a cursor object
*
* @param c Database cursor
* @return Generated Friend object
*/
private Friend parseDbEntryToFriend(Cursor c){
Friend friend = new Friend();
friend.setId(c.getInt(c.getColumnIndexOrThrow(
FriendsListSchema.COLUMN_NAME_FRIEND_ID)));
friend.setAccepted(c.getInt(c.getColumnIndexOrThrow(
FriendsListSchema.COLUMN_NAME_FRIEND_ACCEPTED)) == 1);
friend.setFollowing(c.getInt(c.getColumnIndexOrThrow(
FriendsListSchema.COLUMN_NAME_FRIEND_FOLLOWING)) == 1);
friend.setLast_activity(c.getInt(c.getColumnIndexOrThrow(
FriendsListSchema.COLUMN_NAME_FRIEND_LAST_ACTIVITY)));
return friend;
}
} }

View File

@ -30,7 +30,7 @@ public class FriendsListHelper {
//Debug tag //Debug tag
private static final String TAG = "FriendsList"; private static final String TAG = "FriendsList";
private FriendsListDbHelper fdbHelper; private FriendsListDbHelper mDbHelper;
private Context mContext; private Context mContext;
//Friends list access lock //Friends list access lock
@ -42,7 +42,7 @@ public class FriendsListHelper {
* @param context The context of the application * @param context The context of the application
*/ */
public FriendsListHelper(Context context){ public FriendsListHelper(Context context){
this.fdbHelper = new FriendsListDbHelper(DatabaseHelper.getInstance(context)); this.mDbHelper = new FriendsListDbHelper(DatabaseHelper.getInstance(context));
this.mContext = context; this.mContext = context;
} }
@ -53,7 +53,7 @@ public class FriendsListHelper {
* @param context the context of the application * @param context the context of the application
*/ */
public FriendsListHelper(DatabaseHelper dbHelper, Context context){ public FriendsListHelper(DatabaseHelper dbHelper, Context context){
this.fdbHelper = new FriendsListDbHelper(dbHelper); this.mDbHelper = new FriendsListDbHelper(dbHelper);
this.mContext = context.getApplicationContext(); this.mContext = context.getApplicationContext();
} }
@ -70,7 +70,7 @@ public class FriendsListHelper {
//Fetch the list //Fetch the list
ArrayList<Friend> list; ArrayList<Friend> list;
try { try {
list = fdbHelper.get_list(); list = mDbHelper.get_list();
} finally { } finally {
FriendsListHelper.ListAccessLock.unlock(); FriendsListHelper.ListAccessLock.unlock();
} }
@ -135,7 +135,7 @@ public class FriendsListHelper {
//Set friend information //Set friend information
friend.setId(friendship_infos.getInt("ID_friend")); friend.setId(friendship_infos.getInt("ID_friend"));
friend.setAccepted(friendship_infos.getInt("accepted") == 1); friend.setAccepted(friendship_infos.getInt("accepted") == 1);
friend.setFollowing(friendship_infos.getInt("ID_friend") == 1); friend.setFollowing(friendship_infos.getInt("following") == 1);
friend.setLast_activity(friendship_infos.getInt("time_last_activity")); friend.setLast_activity(friendship_infos.getInt("time_last_activity"));
//Add the friend to the list //Add the friend to the list
@ -165,7 +165,7 @@ public class FriendsListHelper {
new APIRequestHelper().exec(delparams); new APIRequestHelper().exec(delparams);
//Remove the friend from the local database //Remove the friend from the local database
fdbHelper.delete_friend(friend); mDbHelper.delete_friend(friend);
} catch (Exception e){ } catch (Exception e){
Log.e(TAG, "Couldn't delete friend !"); Log.e(TAG, "Couldn't delete friend !");
@ -233,10 +233,10 @@ public class FriendsListHelper {
//Update the friend in the local database //Update the friend in the local database
if(accept) { if(accept) {
friend.setAccepted(true); friend.setAccepted(true);
fdbHelper.update_friend(friend); mDbHelper.update_friend(friend);
} }
else { else {
fdbHelper.delete_friend(friend); mDbHelper.delete_friend(friend);
} }
} catch(Exception e){ } catch(Exception e){
@ -311,4 +311,36 @@ public class FriendsListHelper {
} }
} }
/**
* Update follow status of a user
*
* @param friendID The ID of the user to update
* @param following TRUE to follow / FALSE else
* @return The result of the operation
*/
public boolean setFollowing(int friendID, boolean following){
//Get information about the friend
Friend friend = mDbHelper.getSingleFriend(friendID);
if(friend == null)
return false;
friend.setFollowing(following);
//Update friend information locally
mDbHelper.update_friend(friend);
//Update the friend on the server too
APIRequest request = new APIRequest(mContext, "friends/setFollowing");
request.addInt("friendID", friendID);
request.addBoolean("follow", following);
//Perform request on the server
try {
return new APIRequestHelper().exec(request).getResponse_code() == 200;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
} }

View File

@ -21,6 +21,7 @@ import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import org.communiquons.android.comunic.client.R; import org.communiquons.android.comunic.client.R;
import org.communiquons.android.comunic.client.data.asynctasks.SafeAsyncTask;
import org.communiquons.android.comunic.client.data.helpers.DatabaseHelper; import org.communiquons.android.comunic.client.data.helpers.DatabaseHelper;
import org.communiquons.android.comunic.client.data.helpers.FriendsListHelper; import org.communiquons.android.comunic.client.data.helpers.FriendsListHelper;
import org.communiquons.android.comunic.client.data.helpers.GetUsersHelper; import org.communiquons.android.comunic.client.data.helpers.GetUsersHelper;
@ -65,32 +66,32 @@ public class FriendsListFragment extends Fragment implements OnFriendListActionL
/** /**
* Get user helper * Get user helper
*/ */
private GetUsersHelper usersHelper; private GetUsersHelper mUsersHelper;
/** /**
* The current list of friends * The current list of friends
*/ */
private ArrayList<FriendUser> friendsList; private ArrayList<FriendUser> mList;
/** /**
* Friend list operations object * Friend list operations object
*/ */
private FriendsListHelper flistHelper; private FriendsListHelper mFriendsHelper;
/** /**
* Conversation opener * Conversation opener
*/ */
private openConversationListener convOpener; private openConversationListener mConvOpener;
/** /**
* Users page opener * Users page opener
*/ */
private onOpenUsersPageListener usersPageOpener; private onOpenUsersPageListener mUsersPageOpener;
/** /**
* Friend adapter * Friend adapter
*/ */
private FriendsAdapter fAdapter; private FriendsAdapter mAdapter;
/** /**
* Loading progress bar * Loading progress bar
@ -123,15 +124,15 @@ public class FriendsListFragment extends Fragment implements OnFriendListActionL
mDbHelper = DatabaseHelper.getInstance(mContext); mDbHelper = DatabaseHelper.getInstance(mContext);
//Create friend list helper object //Create friend list helper object
flistHelper = new FriendsListHelper(mDbHelper, mContext); mFriendsHelper = new FriendsListHelper(mDbHelper, mContext);
//Create get user helper //Create get user helper
usersHelper = new GetUsersHelper(mContext, mDbHelper); mUsersHelper = new GetUsersHelper(mContext, mDbHelper);
//Cast activity to convOpener //Cast activity to mConvOpener
try { try {
convOpener = (openConversationListener) getActivity(); mConvOpener = (openConversationListener) getActivity();
usersPageOpener = (onOpenUsersPageListener) getActivity(); mUsersPageOpener = (onOpenUsersPageListener) getActivity();
} catch (ClassCastException e) { } catch (ClassCastException e) {
e.printStackTrace(); e.printStackTrace();
@ -193,22 +194,22 @@ public class FriendsListFragment extends Fragment implements OnFriendListActionL
protected ArrayList<FriendUser> doInBackground(Void... params) { protected ArrayList<FriendUser> doInBackground(Void... params) {
//Fetch the list of friends //Fetch the list of friends
ArrayList<Friend> friendsList = flistHelper.get(); ArrayList<Friend> friendsList = mFriendsHelper.get();
//Check for errors //Check for errors
if (friendsList == null) if (friendsList == null)
return null; return null;
//Get user info //Get user info
ArrayMap<Integer, UserInfo> userInfos = usersHelper.getMultiple( ArrayMap<Integer, UserInfo> userInfo = mUsersHelper.getMultiple(
FriendsUtils.getFriendsIDs(friendsList)); FriendsUtils.getFriendsIDs(friendsList));
//Check for errors //Check for errors
if (userInfos == null) if (userInfo == null)
return null; return null;
//Merge friend and user and return result //Merge friend and user and return result
return FriendsUtils.merge_friends_user_infos_list(friendsList, userInfos); return FriendsUtils.merge_friends_user_infos_list(friendsList, userInfo);
} }
@ -242,17 +243,17 @@ public class FriendsListFragment extends Fragment implements OnFriendListActionL
} }
//Save the list of friends //Save the list of friends
this.friendsList = friendsList; this.mList = friendsList;
//Update the visibility of the no friend notice //Update the visibility of the no friend notice
updateNoFriendNoticeVisibility(); updateNoFriendNoticeVisibility();
//Set the adapter //Set the adapter
fAdapter = new FriendsAdapter(getActivity(), friendsList, this); mAdapter = new FriendsAdapter(getActivity(), friendsList, this);
mFriendsList.setLayoutManager(new LinearLayoutManager(getActivity())); mFriendsList.setLayoutManager(new LinearLayoutManager(getActivity()));
mFriendsList.addItemDecoration(new DividerItemDecoration(mFriendsList.getContext(), mFriendsList.addItemDecoration(new DividerItemDecoration(mFriendsList.getContext(),
DividerItemDecoration.VERTICAL)); DividerItemDecoration.VERTICAL));
mFriendsList.setAdapter(fAdapter); mFriendsList.setAdapter(mAdapter);
//Register the view for the context menu //Register the view for the context menu
registerForContextMenu(mFriendsList); registerForContextMenu(mFriendsList);
@ -275,11 +276,11 @@ public class FriendsListFragment extends Fragment implements OnFriendListActionL
public void onClick(DialogInterface dialog, int which) { public void onClick(DialogInterface dialog, int which) {
//Get the friend to delete //Get the friend to delete
final Friend toDelete = friendsList.get(pos).getFriend(); final Friend toDelete = mList.get(pos).getFriend();
//Apply new list version //Apply new list version
friendsList.remove(pos); mList.remove(pos);
fAdapter.notifyDataSetChanged(); mAdapter.notifyDataSetChanged();
//Remove the friend list on a parallel thread //Remove the friend list on a parallel thread
new AsyncTask<Integer, Void, Void>() { new AsyncTask<Integer, Void, Void>() {
@ -287,7 +288,7 @@ public class FriendsListFragment extends Fragment implements OnFriendListActionL
protected Void doInBackground(Integer[] params) { protected Void doInBackground(Integer[] params) {
//Delete the friend from the list //Delete the friend from the list
flistHelper.remove(toDelete); mFriendsHelper.remove(toDelete);
return null; return null;
} }
@ -303,30 +304,30 @@ public class FriendsListFragment extends Fragment implements OnFriendListActionL
@Override @Override
public void onOpenUserPage(int userID) { public void onOpenUserPage(int userID) {
usersPageOpener.openUserPage(userID); mUsersPageOpener.openUserPage(userID);
} }
@Override @Override
public void onRespondFrienshipRequest(int pos, final boolean response) { public void onRespondFrienshipRequest(int pos, final boolean response) {
//Get the Friend object //Get the Friend object
Friend targetFriend = friendsList.get(pos).getFriend(); Friend targetFriend = mList.get(pos).getFriend();
if (response) if (response)
//Mark the friend as accepted //Mark the friend as accepted
targetFriend.setAccepted(true); targetFriend.setAccepted(true);
else else
//Remove the friend from the list //Remove the friend from the list
friendsList.remove(pos); mList.remove(pos);
//Inform the adapter the list has changed //Inform the adapter the list has changed
fAdapter.notifyDataSetChanged(); mAdapter.notifyDataSetChanged();
//Accept the request on a separate thread //Accept the request on a separate thread
new AsyncTask<Friend, Void, Void>() { new AsyncTask<Friend, Void, Void>() {
@Override @Override
protected Void doInBackground(Friend... params) { protected Void doInBackground(Friend... params) {
flistHelper.respondRequest(params[0], response); mFriendsHelper.respondRequest(params[0], response);
return null; return null;
} }
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, targetFriend); }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, targetFriend);
@ -339,10 +340,16 @@ public class FriendsListFragment extends Fragment implements OnFriendListActionL
//Save selected position //Save selected position
mPosInContextMenu = pos; mPosInContextMenu = pos;
//Initialize and show menu //Initialize menu
PopupMenu menu = new PopupMenu(getActivity(), view); PopupMenu menu = new PopupMenu(getActivity(), view);
menu.inflate(R.menu.menu_fragment_friendslist_item); menu.inflate(R.menu.menu_friend);
menu.setOnMenuItemClickListener(this); menu.setOnMenuItemClickListener(this);
//Update following checkbox
menu.getMenu().findItem(R.id.action_follow).setChecked(mList.get(pos).getFriend()
.isFollowing());
menu.show(); menu.show();
} }
@ -352,20 +359,60 @@ public class FriendsListFragment extends Fragment implements OnFriendListActionL
switch (item.getItemId()) { switch (item.getItemId()) {
//To open a private conversation with the friend //To open a private conversation with the friend
case R.id.menu_fragment_friendslist_private_conversation: case R.id.action_private_conversation:
convOpener.openPrivateConversation(friendsList.get(mPosInContextMenu).getFriend().getId()); mConvOpener.openPrivateConversation(mList.get(mPosInContextMenu).getFriend().getId());
return true; return true;
//To delete the friend //To delete the friend
case R.id.menu_fragment_friendslist_delete_friend: case R.id.action_delete_friend:
delete_friend(mPosInContextMenu); delete_friend(mPosInContextMenu);
return true; return true;
case R.id.action_follow:
onSetFollowing(mPosInContextMenu,
!mList.get(mPosInContextMenu).getFriend().isFollowing());
return true;
} }
return false; return false;
} }
@Override
public void onSetFollowing(int pos, boolean following) {
Friend friend = mList.get(pos).getFriend();
friend.setFollowing(following);
mAdapter.notifyDataSetChanged();
//Perform update
new SetFollowingTask(getActivity(), friend.getId(), friend.isFollowing())
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
/**
* Class used to update following status
*/
static class SetFollowingTask extends SafeAsyncTask<Void, Void, Void> {
private int friendID;
private boolean follow;
SetFollowingTask(Context context, int friendID, boolean follow) {
super(context);
this.friendID = friendID;
this.follow = follow;
}
@Override
protected Void doInBackground(Void... voids) {
new FriendsListHelper(getContext()).setFollowing(friendID, follow);
return null;
}
}
/** /**
* Hide (or display) progress bar * Hide (or display) progress bar
* *
@ -379,7 +426,7 @@ public class FriendsListFragment extends Fragment implements OnFriendListActionL
* Update the visibility of the no friend notice * Update the visibility of the no friend notice
*/ */
private void updateNoFriendNoticeVisibility() { private void updateNoFriendNoticeVisibility() {
if (friendsList != null) if (mList != null)
mNoFriendNotice.setVisibility(friendsList.size() == 0 ? View.VISIBLE : View.GONE); mNoFriendNotice.setVisibility(mList.size() == 0 ? View.VISIBLE : View.GONE);
} }
} }

View File

@ -30,4 +30,12 @@ public interface OnFriendListActionListener {
* @param pos The position of the friend in the list * @param pos The position of the friend in the list
*/ */
void onOpenContextMenuForFriend(View view, int pos); void onOpenContextMenuForFriend(View view, int pos);
/**
* Specify whether a friend should be followed or not
*
* @param pos The position of the friend to update
* @param following New following status
*/
void onSetFollowing(int pos, boolean following);
} }

View File

@ -1,14 +1,20 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"> <menu xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Update following state -->
<item
android:id="@+id/action_follow"
android:title="@string/action_follow"
android:checkable="true" />
<!-- Start private conversation --> <!-- Start private conversation -->
<item <item
android:id="@+id/menu_fragment_friendslist_private_conversation" android:id="@+id/action_private_conversation"
android:title="@string/action_friends_start_private_conversation" /> android:title="@string/action_friends_start_private_conversation" />
<!-- Delete the friend --> <!-- Delete the friend -->
<item <item
android:id="@+id/menu_fragment_friendslist_delete_friend" android:id="@+id/action_delete_friend"
android:title="@string/action_friends_delete" /> android:title="@string/action_friends_delete" />
</menu> </menu>

View File

@ -243,4 +243,5 @@
<string name="action_reject_friend_request">Reject</string> <string name="action_reject_friend_request">Reject</string>
<string name="notice_request">Requested</string> <string name="notice_request">Requested</string>
<string name="action_more_description">Get more options</string> <string name="action_more_description">Get more options</string>
<string name="action_follow">Follow</string>
</resources> </resources>