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 {
/**
* 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
*/
@ -49,16 +59,10 @@ public class FriendsListDbHelper {
//Prepare the request on the database
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;
//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
if(c == null)
@ -70,23 +74,8 @@ public class FriendsListDbHelper {
c.moveToFirst();
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
friendsList.add(friend);
friendsList.add(parseDbEntryToFriend(c));
//Move to the next friend
if(!c.moveToNext())
@ -99,6 +88,32 @@ public class FriendsListDbHelper {
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
*
@ -234,4 +249,29 @@ public class FriendsListDbHelper {
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
private static final String TAG = "FriendsList";
private FriendsListDbHelper fdbHelper;
private FriendsListDbHelper mDbHelper;
private Context mContext;
//Friends list access lock
@ -42,7 +42,7 @@ public class FriendsListHelper {
* @param context The context of the application
*/
public FriendsListHelper(Context context){
this.fdbHelper = new FriendsListDbHelper(DatabaseHelper.getInstance(context));
this.mDbHelper = new FriendsListDbHelper(DatabaseHelper.getInstance(context));
this.mContext = context;
}
@ -53,7 +53,7 @@ public class FriendsListHelper {
* @param context the context of the application
*/
public FriendsListHelper(DatabaseHelper dbHelper, Context context){
this.fdbHelper = new FriendsListDbHelper(dbHelper);
this.mDbHelper = new FriendsListDbHelper(dbHelper);
this.mContext = context.getApplicationContext();
}
@ -70,7 +70,7 @@ public class FriendsListHelper {
//Fetch the list
ArrayList<Friend> list;
try {
list = fdbHelper.get_list();
list = mDbHelper.get_list();
} finally {
FriendsListHelper.ListAccessLock.unlock();
}
@ -135,7 +135,7 @@ public class FriendsListHelper {
//Set friend information
friend.setId(friendship_infos.getInt("ID_friend"));
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"));
//Add the friend to the list
@ -165,7 +165,7 @@ public class FriendsListHelper {
new APIRequestHelper().exec(delparams);
//Remove the friend from the local database
fdbHelper.delete_friend(friend);
mDbHelper.delete_friend(friend);
} catch (Exception e){
Log.e(TAG, "Couldn't delete friend !");
@ -233,10 +233,10 @@ public class FriendsListHelper {
//Update the friend in the local database
if(accept) {
friend.setAccepted(true);
fdbHelper.update_friend(friend);
mDbHelper.update_friend(friend);
}
else {
fdbHelper.delete_friend(friend);
mDbHelper.delete_friend(friend);
}
} 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 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.FriendsListHelper;
import org.communiquons.android.comunic.client.data.helpers.GetUsersHelper;
@ -65,32 +66,32 @@ public class FriendsListFragment extends Fragment implements OnFriendListActionL
/**
* Get user helper
*/
private GetUsersHelper usersHelper;
private GetUsersHelper mUsersHelper;
/**
* The current list of friends
*/
private ArrayList<FriendUser> friendsList;
private ArrayList<FriendUser> mList;
/**
* Friend list operations object
*/
private FriendsListHelper flistHelper;
private FriendsListHelper mFriendsHelper;
/**
* Conversation opener
*/
private openConversationListener convOpener;
private openConversationListener mConvOpener;
/**
* Users page opener
*/
private onOpenUsersPageListener usersPageOpener;
private onOpenUsersPageListener mUsersPageOpener;
/**
* Friend adapter
*/
private FriendsAdapter fAdapter;
private FriendsAdapter mAdapter;
/**
* Loading progress bar
@ -123,15 +124,15 @@ public class FriendsListFragment extends Fragment implements OnFriendListActionL
mDbHelper = DatabaseHelper.getInstance(mContext);
//Create friend list helper object
flistHelper = new FriendsListHelper(mDbHelper, mContext);
mFriendsHelper = new FriendsListHelper(mDbHelper, mContext);
//Create get user helper
usersHelper = new GetUsersHelper(mContext, mDbHelper);
mUsersHelper = new GetUsersHelper(mContext, mDbHelper);
//Cast activity to convOpener
//Cast activity to mConvOpener
try {
convOpener = (openConversationListener) getActivity();
usersPageOpener = (onOpenUsersPageListener) getActivity();
mConvOpener = (openConversationListener) getActivity();
mUsersPageOpener = (onOpenUsersPageListener) getActivity();
} catch (ClassCastException e) {
e.printStackTrace();
@ -193,22 +194,22 @@ public class FriendsListFragment extends Fragment implements OnFriendListActionL
protected ArrayList<FriendUser> doInBackground(Void... params) {
//Fetch the list of friends
ArrayList<Friend> friendsList = flistHelper.get();
ArrayList<Friend> friendsList = mFriendsHelper.get();
//Check for errors
if (friendsList == null)
return null;
//Get user info
ArrayMap<Integer, UserInfo> userInfos = usersHelper.getMultiple(
ArrayMap<Integer, UserInfo> userInfo = mUsersHelper.getMultiple(
FriendsUtils.getFriendsIDs(friendsList));
//Check for errors
if (userInfos == null)
if (userInfo == null)
return null;
//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
this.friendsList = friendsList;
this.mList = friendsList;
//Update the visibility of the no friend notice
updateNoFriendNoticeVisibility();
//Set the adapter
fAdapter = new FriendsAdapter(getActivity(), friendsList, this);
mAdapter = new FriendsAdapter(getActivity(), friendsList, this);
mFriendsList.setLayoutManager(new LinearLayoutManager(getActivity()));
mFriendsList.addItemDecoration(new DividerItemDecoration(mFriendsList.getContext(),
DividerItemDecoration.VERTICAL));
mFriendsList.setAdapter(fAdapter);
mFriendsList.setAdapter(mAdapter);
//Register the view for the context menu
registerForContextMenu(mFriendsList);
@ -275,11 +276,11 @@ public class FriendsListFragment extends Fragment implements OnFriendListActionL
public void onClick(DialogInterface dialog, int which) {
//Get the friend to delete
final Friend toDelete = friendsList.get(pos).getFriend();
final Friend toDelete = mList.get(pos).getFriend();
//Apply new list version
friendsList.remove(pos);
fAdapter.notifyDataSetChanged();
mList.remove(pos);
mAdapter.notifyDataSetChanged();
//Remove the friend list on a parallel thread
new AsyncTask<Integer, Void, Void>() {
@ -287,7 +288,7 @@ public class FriendsListFragment extends Fragment implements OnFriendListActionL
protected Void doInBackground(Integer[] params) {
//Delete the friend from the list
flistHelper.remove(toDelete);
mFriendsHelper.remove(toDelete);
return null;
}
@ -303,30 +304,30 @@ public class FriendsListFragment extends Fragment implements OnFriendListActionL
@Override
public void onOpenUserPage(int userID) {
usersPageOpener.openUserPage(userID);
mUsersPageOpener.openUserPage(userID);
}
@Override
public void onRespondFrienshipRequest(int pos, final boolean response) {
//Get the Friend object
Friend targetFriend = friendsList.get(pos).getFriend();
Friend targetFriend = mList.get(pos).getFriend();
if (response)
//Mark the friend as accepted
targetFriend.setAccepted(true);
else
//Remove the friend from the list
friendsList.remove(pos);
mList.remove(pos);
//Inform the adapter the list has changed
fAdapter.notifyDataSetChanged();
mAdapter.notifyDataSetChanged();
//Accept the request on a separate thread
new AsyncTask<Friend, Void, Void>() {
@Override
protected Void doInBackground(Friend... params) {
flistHelper.respondRequest(params[0], response);
mFriendsHelper.respondRequest(params[0], response);
return null;
}
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, targetFriend);
@ -339,10 +340,16 @@ public class FriendsListFragment extends Fragment implements OnFriendListActionL
//Save selected position
mPosInContextMenu = pos;
//Initialize and show menu
//Initialize menu
PopupMenu menu = new PopupMenu(getActivity(), view);
menu.inflate(R.menu.menu_fragment_friendslist_item);
menu.inflate(R.menu.menu_friend);
menu.setOnMenuItemClickListener(this);
//Update following checkbox
menu.getMenu().findItem(R.id.action_follow).setChecked(mList.get(pos).getFriend()
.isFollowing());
menu.show();
}
@ -352,20 +359,60 @@ public class FriendsListFragment extends Fragment implements OnFriendListActionL
switch (item.getItemId()) {
//To open a private conversation with the friend
case R.id.menu_fragment_friendslist_private_conversation:
convOpener.openPrivateConversation(friendsList.get(mPosInContextMenu).getFriend().getId());
case R.id.action_private_conversation:
mConvOpener.openPrivateConversation(mList.get(mPosInContextMenu).getFriend().getId());
return true;
//To delete the friend
case R.id.menu_fragment_friendslist_delete_friend:
case R.id.action_delete_friend:
delete_friend(mPosInContextMenu);
return true;
case R.id.action_follow:
onSetFollowing(mPosInContextMenu,
!mList.get(mPosInContextMenu).getFriend().isFollowing());
return true;
}
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
*
@ -379,7 +426,7 @@ public class FriendsListFragment extends Fragment implements OnFriendListActionL
* Update the visibility of the no friend notice
*/
private void updateNoFriendNoticeVisibility() {
if (friendsList != null)
mNoFriendNotice.setVisibility(friendsList.size() == 0 ? View.VISIBLE : View.GONE);
if (mList != null)
mNoFriendNotice.setVisibility(mList.size() == 0 ? View.VISIBLE : View.GONE);
}
}

View File

@ -19,7 +19,7 @@ public interface OnFriendListActionListener {
/**
* Respond to a friendship request
*
* @param pos Position of the friend on the list
* @param pos Position of the friend on the list
* @param response TRUE to accept / FALSE else
*/
void onRespondFrienshipRequest(int pos, boolean response);
@ -30,4 +30,12 @@ public interface OnFriendListActionListener {
* @param pos The position of the friend in the list
*/
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"?>
<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 -->
<item
android:id="@+id/menu_fragment_friendslist_private_conversation"
android:id="@+id/action_private_conversation"
android:title="@string/action_friends_start_private_conversation" />
<!-- Delete the friend -->
<item
android:id="@+id/menu_fragment_friendslist_delete_friend"
android:id="@+id/action_delete_friend"
android:title="@string/action_friends_delete" />
</menu>

View File

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