From c672891e3ef0b940fdc78d0817196a09598f3a8d Mon Sep 17 00:00:00 2001 From: Pierre Date: Sat, 28 Apr 2018 12:49:07 +0200 Subject: [PATCH] Can display older conversation messages --- .../helpers/ConversationMessagesDbHelper.java | 32 ++++++++ .../helpers/ConversationMessagesHelper.java | 76 +++++++++++++++++ .../client/data/utils/PreferencesUtils.java | 3 +- .../ui/fragments/ConversationFragment.java | 82 +++++++++++++++++-- 4 files changed, 186 insertions(+), 7 deletions(-) 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 88f3be0..841ec07 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 @@ -92,6 +92,38 @@ class ConversationMessagesDbHelper { return message; } + /** + * Get the oldest message known of a conversation + * + * @param convID Target conversation ID + * @return The ID of the latest known message / -1 in case of failure + */ + int getOldestMessageID(int convID) { + + SQLiteDatabase db = dbHelper.getReadableDatabase(); + + //Prepare the query over the database + String[] columns = {ConversationsMessagesSchema.COLUMN_NAME_MESSAGE_ID}; + String selection = ConversationsMessagesSchema.COLUMN_NAME_CONVERSATION_ID + " = ?"; + String[] selectionArgs = {""+convID}; + String orderBy = ConversationsMessagesSchema.COLUMN_NAME_MESSAGE_ID; + + //Perform the request + Cursor response = db.query(TABLE_NAME, columns, selection, selectionArgs, null, + null, orderBy, "1"); + + //Process response + int messageID = 0; + if(response.getCount() != 0){ + response.moveToFirst(); + messageID = response.getInt(response.getColumnIndexOrThrow( + ConversationsMessagesSchema.COLUMN_NAME_MESSAGE_ID)); + } + response.close(); + + return messageID; + } + /** * Insert a list of messages 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 16da5b2..53e2802 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 @@ -138,6 +138,39 @@ public class ConversationMessagesHelper { } + /** + * Request the request of older messages from the database / API + * + * @param convID Target conversationID + * @param oldestMessageID The ID of the oldest known message + * @return The list of messages / null in case of failure + */ + @Nullable + public ArrayList getOlderMessages(int convID, int oldestMessageID){ + + //Check what is the oldest message stored in the database + int oldestMessageDownloaded = mDbHelper.getOldestMessageID(convID); + + //Check if no message has been already download + if(oldestMessageDownloaded == 0) + return null; + + //Download older messages from the server + ArrayList messages = + downloadOlder(convID, oldestMessageDownloaded, 10); + + //Check for errors + if(messages == null) + return null; + + //Save the new messages + if(!mDbHelper.insertMultiple(messages)) + return null; + + //Get the messages + return mDbHelper.getInterval(convID, 0, oldestMessageID - 1); + } + /** * Get the ID of the last message of the conversation from the database * @@ -200,6 +233,49 @@ public class ConversationMessagesHelper { return list; } + /** + * Get older messages for a conversation + * + * @param conversationID The ID of the target conversation + * @param oldestMessageID The ID of the oldest known message + * @param limit The limit for the download + * @return The list of message / null in case of failure + */ + @Nullable + private ArrayList downloadOlder(int conversationID, int oldestMessageID, + int limit){ + + ArrayList list = new ArrayList<>(); + + //Prepare a request over the server + APIRequest req = new APIRequest(mContext, "conversations/get_older_messages"); + req.addInt("conversationID", conversationID); + req.addInt("oldest_message_id", oldestMessageID); + req.addInt("limit", limit); + + //Perform the request + try { + + APIResponse response = new APIRequestHelper().exec(req); + + //Check for errors + if(response.getResponse_code() != 200) + return null; + + //Process the list of messages + JSONArray messages = response.getJSONArray(); + + for(int i = 0; i < messages.length(); i++) + list.add(getMessageObject(conversationID, messages.getJSONObject(i))); + + } catch (Exception e){ + e.printStackTrace(); + return null; + } + + return list; + } + /** * Convert a JSON object into a conversation message element * diff --git a/app/src/main/java/org/communiquons/android/comunic/client/data/utils/PreferencesUtils.java b/app/src/main/java/org/communiquons/android/comunic/client/data/utils/PreferencesUtils.java index aa6f01f..f6db42c 100644 --- a/app/src/main/java/org/communiquons/android/comunic/client/data/utils/PreferencesUtils.java +++ b/app/src/main/java/org/communiquons/android/comunic/client/data/utils/PreferencesUtils.java @@ -22,7 +22,8 @@ public class PreferencesUtils { * @return The preference value (if found) or the default value */ public static boolean getBoolean(Context context, String key, boolean def){ - SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(context); + SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences( + context.getApplicationContext()); return sharedPrefs.getBoolean(key, def); } 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 1a2cd4b..6a060c4 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 @@ -5,7 +5,6 @@ import android.app.Fragment; import android.content.DialogInterface; import android.content.Intent; import android.graphics.Bitmap; -import android.graphics.BitmapFactory; import android.net.Uri; import android.os.AsyncTask; import android.os.Bundle; @@ -17,10 +16,8 @@ import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.view.inputmethod.EditorInfo; import android.widget.EditText; import android.widget.ImageButton; -import android.widget.ListView; import android.widget.ProgressBar; import android.widget.TextView; import android.widget.Toast; @@ -38,7 +35,9 @@ import org.communiquons.android.comunic.client.data.utils.AccountUtils; import org.communiquons.android.comunic.client.data.utils.FilesUtils; 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.listeners.OnScrollChangeDetectListener; import org.communiquons.android.comunic.client.ui.utils.BitmapUtils; +import org.communiquons.android.comunic.client.ui.views.ScrollListView; import java.io.File; import java.io.FileNotFoundException; @@ -57,7 +56,8 @@ import static android.app.Activity.RESULT_OK; */ public class ConversationFragment extends Fragment - implements ConversationRefreshRunnable.onMessagesChangeListener { + implements ConversationRefreshRunnable.onMessagesChangeListener, + OnScrollChangeDetectListener { /** * Pick image request number @@ -115,9 +115,9 @@ public class ConversationFragment extends Fragment private TextView no_msg_notice; /** - * Converstion message listView + * Conversation message listView */ - private ListView convMessListView; + private ScrollListView convMessListView; /** * Conversation messages helper @@ -164,6 +164,11 @@ public class ConversationFragment extends Fragment */ private GetUsersHelper getUsersHelper; + /** + * Async task used to fetch older messages + */ + private AsyncTask mGetOlderMessagesTask; + @Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -280,6 +285,10 @@ public class ConversationFragment extends Fragment //Hide new message sending wheel new_message_progress_bar.setVisibility(View.GONE); + + + //Set a listener to detect when the user reaches the top of the conversation + convMessListView.setOnScrollChangeDetectListener(this); } @Override @@ -607,4 +616,65 @@ public class ConversationFragment extends Fragment private void display_not_msg_notice(boolean visible){ no_msg_notice.setVisibility(visible ? View.VISIBLE : View.GONE); } + + /** + * This method is called when the user reach the top of the conversation + */ + @Override + public void onReachTop() { + + //Check if we have got other messages to get + if(messagesList == null) + return; + if(messagesList.size() == 0) + return; + final int firstMessageID = messagesList.get(0).getId(); + + //Check if another task is running + if(mGetOlderMessagesTask != null) + return; + + //Create and execute the task + mGetOlderMessagesTask = new AsyncTask>(){ + + @Override + protected ArrayList doInBackground(Void... params) { + return convMessHelper.getOlderMessages(conversation_id, firstMessageID); + } + + @Override + protected void onPostExecute(ArrayList conversationMessages) { + if(getActivity() == null) + return; + + onGotOlderMessages(conversationMessages); + + } + }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + + } + + /** + * Actions to do once we downloaded older messages from the server + * + * @param list The list of messages that was downloaded + */ + private void onGotOlderMessages(@Nullable ArrayList list){ + + //Remove link over task + mGetOlderMessagesTask = null; + + //Check if the list is null (in case of error) + if(list == null) + return; + + if(list.size() == 0) + return; + + //Add the messages to the list + messagesList.addAll(0, list); + + //Notify adapter + convMessAdapter.notifyDataSetChanged(); + } }