From e92201b51d8494df9672f48ebf532a3ce1acd50f Mon Sep 17 00:00:00 2001 From: Pierre HUBERT Date: Tue, 28 Aug 2018 10:09:40 +0200 Subject: [PATCH] Can delete conversation messages --- .../helpers/ConversationMessagesDbHelper.java | 14 ++ .../helpers/ConversationMessagesHelper.java | 36 ++++- .../adapters/ConversationMessageAdapter.java | 26 +++- .../DeleteConversationMessageTask.java | 23 ++++ .../ui/fragments/ConversationFragment.java | 123 +++++++++++++++++- .../OnConversationMessageActionsListener.java | 29 +++++ .../res/menu/menu_conversation_message.xml | 8 ++ app/src/main/res/values-fr/strings.xml | 4 + app/src/main/res/values/strings.xml | 6 + 9 files changed, 265 insertions(+), 4 deletions(-) create mode 100644 app/src/main/java/org/communiquons/android/comunic/client/ui/asynctasks/DeleteConversationMessageTask.java create mode 100644 app/src/main/java/org/communiquons/android/comunic/client/ui/listeners/OnConversationMessageActionsListener.java create mode 100644 app/src/main/res/menu/menu_conversation_message.xml diff --git a/app/src/main/java/org/communiquons/android/comunic/client/data/helpers/ConversationMessagesDbHelper.java b/app/src/main/java/org/communiquons/android/comunic/client/data/helpers/ConversationMessagesDbHelper.java index 841ec07..cda5895 100644 --- a/app/src/main/java/org/communiquons/android/comunic/client/data/helpers/ConversationMessagesDbHelper.java +++ b/app/src/main/java/org/communiquons/android/comunic/client/data/helpers/ConversationMessagesDbHelper.java @@ -190,6 +190,20 @@ class ConversationMessagesDbHelper { return list; } + /** + * Delete a message from the local database + * + * @param messageID The ID of the message to delete + * @return The result of the operation + */ + boolean deleteMessage(int messageID){ + SQLiteDatabase db = dbHelper.getWritableDatabase(); + + String conditions = ConversationsMessagesSchema.COLUMN_NAME_MESSAGE_ID + " = ?"; + String[] args = {messageID+""}; + return db.delete(TABLE_NAME, conditions, args) > 0; + } + /** * Insert a single message into the database * diff --git a/app/src/main/java/org/communiquons/android/comunic/client/data/helpers/ConversationMessagesHelper.java b/app/src/main/java/org/communiquons/android/comunic/client/data/helpers/ConversationMessagesHelper.java index 53e2802..eec5037 100644 --- a/app/src/main/java/org/communiquons/android/comunic/client/data/helpers/ConversationMessagesHelper.java +++ b/app/src/main/java/org/communiquons/android/comunic/client/data/helpers/ConversationMessagesHelper.java @@ -2,7 +2,6 @@ package org.communiquons.android.comunic.client.data.helpers; import android.content.Context; import android.graphics.Bitmap; -import android.graphics.drawable.Drawable; import android.support.annotation.Nullable; import android.util.Log; @@ -41,6 +40,15 @@ public class ConversationMessagesHelper { */ private Context mContext; + /** + * Constructor of the helper + * + * @param context The context of the application + */ + public ConversationMessagesHelper(Context context){ + this(context.getApplicationContext(), DatabaseHelper.getInstance(context)); + } + /** * Public constructor of the helper * @@ -276,6 +284,32 @@ public class ConversationMessagesHelper { return list; } + /** + * Delete a conversation message + * + * @param messageID The ID of the message to delete + * @return TRUE for a success / FALSE else + */ + public boolean deleteMessage(int messageID){ + + //Make a request on the server + APIRequest request = new APIRequest(mContext, "conversations/deleteMessage"); + request.addInt("messageID", messageID); + + try { + APIResponse response = new APIRequestHelper().exec(request); + + if(response.getResponse_code() != 200) return false; + + //Delete the message in the local database + return mDbHelper.deleteMessage(messageID); + + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + /** * Convert a JSON object into a conversation message element * diff --git a/app/src/main/java/org/communiquons/android/comunic/client/ui/adapters/ConversationMessageAdapter.java b/app/src/main/java/org/communiquons/android/comunic/client/ui/adapters/ConversationMessageAdapter.java index d912ae1..dc8385a 100644 --- a/app/src/main/java/org/communiquons/android/comunic/client/ui/adapters/ConversationMessageAdapter.java +++ b/app/src/main/java/org/communiquons/android/comunic/client/ui/adapters/ConversationMessageAdapter.java @@ -4,6 +4,7 @@ import android.content.Context; import android.support.annotation.CallSuper; import android.support.annotation.NonNull; import android.support.v7.widget.RecyclerView; +import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -15,6 +16,7 @@ import org.communiquons.android.comunic.client.data.models.ConversationMessage; import org.communiquons.android.comunic.client.data.models.UserInfo; import org.communiquons.android.comunic.client.data.utils.StringsUtils; import org.communiquons.android.comunic.client.data.utils.Utilities; +import org.communiquons.android.comunic.client.ui.listeners.OnConversationMessageActionsListener; import org.communiquons.android.comunic.client.ui.views.EnlargeableWebImageView; import org.communiquons.android.comunic.client.ui.views.WebUserAccountImage; @@ -53,6 +55,11 @@ public class ConversationMessageAdapter extends RecyclerView.Adapter { */ private ConversationMessagesList mList; + /** + * Conversation messages listener + */ + private OnConversationMessageActionsListener mOnConversationMessageActionsListener; + private Utilities utils; /** @@ -85,6 +92,10 @@ public class ConversationMessageAdapter extends RecyclerView.Adapter { : VIEW_TYPE_MESSAGE_RECEIVED; } + public void setOnConversationMessageActionsListener(OnConversationMessageActionsListener listener) { + this.mOnConversationMessageActionsListener = listener; + } + @NonNull @Override public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int type) { @@ -122,7 +133,8 @@ public class ConversationMessageAdapter extends RecyclerView.Adapter { /** * Base messages holder */ - private class BaseMessageHolder extends RecyclerView.ViewHolder { + private class BaseMessageHolder extends RecyclerView.ViewHolder + implements View.OnLongClickListener{ private TextView mMessage; private TextView mSentDate; @@ -134,6 +146,9 @@ public class ConversationMessageAdapter extends RecyclerView.Adapter { mMessage = itemView.findViewById(R.id.message_body); mImage = itemView.findViewById(R.id.messageImage); mSentDate = itemView.findViewById(R.id.text_message_time); + + itemView.setOnLongClickListener(this); + mImage.setOnLongClickListener(this); } /** @@ -174,6 +189,15 @@ public class ConversationMessageAdapter extends RecyclerView.Adapter { else mSentDate.setVisibility(View.VISIBLE); } + + @Override + public boolean onLongClick(View v) { + + if(mOnConversationMessageActionsListener != null) + mOnConversationMessageActionsListener.onOpenContextMenu(getLayoutPosition(), v); + + return true; + } } /** diff --git a/app/src/main/java/org/communiquons/android/comunic/client/ui/asynctasks/DeleteConversationMessageTask.java b/app/src/main/java/org/communiquons/android/comunic/client/ui/asynctasks/DeleteConversationMessageTask.java new file mode 100644 index 0000000..feb096b --- /dev/null +++ b/app/src/main/java/org/communiquons/android/comunic/client/ui/asynctasks/DeleteConversationMessageTask.java @@ -0,0 +1,23 @@ +package org.communiquons.android.comunic.client.ui.asynctasks; + +import android.content.Context; + +import org.communiquons.android.comunic.client.data.asynctasks.SafeAsyncTask; +import org.communiquons.android.comunic.client.data.helpers.ConversationMessagesHelper; + +/** + * Delete conversation message async task + * + * @author Pierre HUBERT + */ +public class DeleteConversationMessageTask extends SafeAsyncTask { + + public DeleteConversationMessageTask(Context context) { + super(context); + } + + @Override + protected Boolean doInBackground(Integer... integers) { + return new ConversationMessagesHelper(getContext()).deleteMessage(integers[0]); + } +} \ No newline at end of file diff --git a/app/src/main/java/org/communiquons/android/comunic/client/ui/fragments/ConversationFragment.java b/app/src/main/java/org/communiquons/android/comunic/client/ui/fragments/ConversationFragment.java index b72453f..1b98d7b 100644 --- a/app/src/main/java/org/communiquons/android/comunic/client/ui/fragments/ConversationFragment.java +++ b/app/src/main/java/org/communiquons/android/comunic/client/ui/fragments/ConversationFragment.java @@ -1,6 +1,7 @@ package org.communiquons.android.comunic.client.ui.fragments; import android.app.AlertDialog; +import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.graphics.Bitmap; @@ -14,16 +15,19 @@ import android.util.ArrayMap; import android.util.Log; import android.view.KeyEvent; import android.view.LayoutInflater; +import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.EditText; import android.widget.ImageButton; +import android.widget.PopupMenu; import android.widget.ProgressBar; import android.widget.TextView; import android.widget.Toast; import org.communiquons.android.comunic.client.R; import org.communiquons.android.comunic.client.data.arrays.ConversationMessagesList; +import org.communiquons.android.comunic.client.data.asynctasks.SafeAsyncTask; import org.communiquons.android.comunic.client.data.helpers.ConversationMessagesHelper; import org.communiquons.android.comunic.client.data.helpers.ConversationsListHelper; import org.communiquons.android.comunic.client.data.helpers.DatabaseHelper; @@ -35,6 +39,8 @@ import org.communiquons.android.comunic.client.data.runnables.ConversationRefres import org.communiquons.android.comunic.client.data.utils.AccountUtils; import org.communiquons.android.comunic.client.ui.activities.MainActivity; import org.communiquons.android.comunic.client.ui.adapters.ConversationMessageAdapter; +import org.communiquons.android.comunic.client.ui.asynctasks.DeleteConversationMessageTask; +import org.communiquons.android.comunic.client.ui.listeners.OnConversationMessageActionsListener; import org.communiquons.android.comunic.client.ui.listeners.OnScrollChangeDetectListener; import org.communiquons.android.comunic.client.ui.utils.BitmapUtils; import org.communiquons.android.comunic.client.ui.utils.UiUtils; @@ -57,7 +63,8 @@ import static android.app.Activity.RESULT_OK; public class ConversationFragment extends Fragment implements ConversationRefreshRunnable.onMessagesChangeListener, - OnScrollChangeDetectListener { + OnScrollChangeDetectListener, OnConversationMessageActionsListener, + PopupMenu.OnMenuItemClickListener { /** * Pick image request number @@ -89,6 +96,11 @@ public class ConversationFragment extends Fragment */ private int last_message_id = 0; + /** + * Current user ID + */ + private int userID; + /** * The list of messages of the conversation */ @@ -174,6 +186,16 @@ public class ConversationFragment extends Fragment */ private AsyncTask mGetOlderMessagesTask; + /** + * Current conversation message in context menu + */ + private int mMessageInContextMenu; + + /** + * Safely delete message + */ + private DeleteConversationMessageTask mDeleteMessageAsyncTask; + @Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -237,7 +259,7 @@ public class ConversationFragment extends Fragment mAppBar = view.findViewById(R.id.appbar); //Need user ID - int userID = new AccountUtils(getActivity()).get_current_user_id(); + userID = new AccountUtils(getActivity()).get_current_user_id(); //Initialize toolbar mAppBar.addBackButton(new View.OnClickListener() { @@ -258,6 +280,7 @@ public class ConversationFragment extends Fragment //Create the adapter convMessAdapter = new ConversationMessageAdapter(getActivity(), messagesList, userID); + convMessAdapter.setOnConversationMessageActionsListener(this); //Apply adapter mLinearLayoutManager = new LinearLayoutManager(getActivity()); @@ -369,6 +392,14 @@ public class ConversationFragment extends Fragment } + @Override + public void onDestroy() { + super.onDestroy(); + + if(mDeleteMessageAsyncTask != null) + mDeleteMessageAsyncTask.setOnPostExecuteListener(null); + } + @Override public void onNoMessage() { @@ -730,4 +761,92 @@ public class ConversationFragment extends Fragment //Refresh user information if required refreshUserInfo(); } + + @Override + public void onOpenContextMenu(int pos, View v) { + + mMessageInContextMenu = pos; + ConversationMessage message = messagesList.get(pos); + + PopupMenu popup = new PopupMenu(getActivity(), v); + popup.inflate(R.menu.menu_conversation_message); + + if(message.getUser_id() != userID) + popup.getMenu().findItem(R.id.action_delete).setEnabled(false); + + popup.setOnMenuItemClickListener(this); + + popup.show(); + } + + @Override + public boolean onMenuItemClick(MenuItem item) { + + if(item.getItemId() == R.id.action_delete){ + onConfirmDeleteConversationMessage(mMessageInContextMenu); + return true; + } + + return false; + } + + @Override + public void onConfirmDeleteConversationMessage(final int pos) { + new AlertDialog.Builder(getActivity()) + .setTitle(R.string.dialog_delete_conversation_message_title) + .setMessage(R.string.dialog_delete_conversation_message_message) + .setNegativeButton(R.string.dialog_delete_conversation_message_cancel, null) + + .setPositiveButton(R.string.dialog_delete_conversation_message_confirm, + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + deleteConversationMessage(pos); + } + }) + + .show(); + } + + /** + * Delete conversation message at a specified position + * + * @param pos The position of the message to delete + */ + private void deleteConversationMessage(final int pos){ + mDeleteMessageAsyncTask = new DeleteConversationMessageTask(getActivity()); + mDeleteMessageAsyncTask.setOnPostExecuteListener(new SafeAsyncTask.OnPostExecuteListener() { + @Override + public void OnPostExecute(Boolean result) { + deleteConversationMessagesCallback(pos, result); + } + }); + + + mDeleteMessageAsyncTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, + messagesList.get(pos).getId()); + } + + /** + * Delete conversation message callback + * + * @param pos The position of the message + * @param result Result of the operation + */ + private void deleteConversationMessagesCallback(int pos, boolean result){ + + if(getActivity() == null) + return; + + if(!result) { + Toast.makeText(getActivity(), R.string.err_delete_conversation_message, + Toast.LENGTH_SHORT).show(); + return; + } + + messagesList.remove(pos); + convMessAdapter.notifyDataSetChanged(); + } + + } diff --git a/app/src/main/java/org/communiquons/android/comunic/client/ui/listeners/OnConversationMessageActionsListener.java b/app/src/main/java/org/communiquons/android/comunic/client/ui/listeners/OnConversationMessageActionsListener.java new file mode 100644 index 0000000..2240ac0 --- /dev/null +++ b/app/src/main/java/org/communiquons/android/comunic/client/ui/listeners/OnConversationMessageActionsListener.java @@ -0,0 +1,29 @@ +package org.communiquons.android.comunic.client.ui.listeners; + +import android.view.View; + +import org.communiquons.android.comunic.client.data.models.ConversationMessage; + +/** + * Listener for actions on conversation messages + * + * @author Pierre HUBERT + */ +public interface OnConversationMessageActionsListener { + + /** + * Open messages context menu for message at a specified position + * + * @param pos The position of the context menu + * @param v The view to display the context menu + */ + void onOpenContextMenu(int pos, View v); + + /** + * Ask the user to confirm the deletion of a conversation message + * + * @param pos The position of the message to delete + */ + void onConfirmDeleteConversationMessage(int pos); + +} diff --git a/app/src/main/res/menu/menu_conversation_message.xml b/app/src/main/res/menu/menu_conversation_message.xml new file mode 100644 index 0000000..7e4a21d --- /dev/null +++ b/app/src/main/res/menu/menu_conversation_message.xml @@ -0,0 +1,8 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 1a699ee..cc1784f 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -244,4 +244,8 @@ Suivre Suivre Suivi + Supprimer + A propos + Licences Open Source + Licences Open Source \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 9502bdd..7980458 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -246,4 +246,10 @@ Follow Follow Following + Delete + Delete message + Do you really want to delete this conversation message? Note: This may not have any effect if the other members of the conversation have already downloaded the message! + Cancel + Delete + Could not delete conversation message!