diff --git a/app/src/main/java/org/communiquons/android/comunic/client/data/ImageLoad/ImageLoadRunnable.java b/app/src/main/java/org/communiquons/android/comunic/client/data/ImageLoad/ImageLoadRunnable.java index 9be6cbe..b754d89 100644 --- a/app/src/main/java/org/communiquons/android/comunic/client/data/ImageLoad/ImageLoadRunnable.java +++ b/app/src/main/java/org/communiquons/android/comunic/client/data/ImageLoad/ImageLoadRunnable.java @@ -69,6 +69,9 @@ class ImageLoadRunnable implements Runnable { @Override public void run() { + //Create the parent directory if required + ImageLoadUtils.create_parent_directory(mContext); + //Determine the filename for the requested URL String filename = ImageLoadUtils.IMAGE_CACHE_DIRECTORY + ImageLoadUtils.get_file_name(url); @@ -122,7 +125,7 @@ class ImageLoadRunnable implements Runnable { } /** - * Once the image was downloaded (if it wasn't already) load the image into a bitmpa object + * Once the image was downloaded (if it wasn't already) load the image into a bitmap object * The apply to the final image view */ private void load_image(){ diff --git a/app/src/main/java/org/communiquons/android/comunic/client/data/ImageLoad/ImageLoadTask.java b/app/src/main/java/org/communiquons/android/comunic/client/data/ImageLoad/ImageLoadTask.java index 1e649ce..e49c61e 100644 --- a/app/src/main/java/org/communiquons/android/comunic/client/data/ImageLoad/ImageLoadTask.java +++ b/app/src/main/java/org/communiquons/android/comunic/client/data/ImageLoad/ImageLoadTask.java @@ -139,7 +139,7 @@ public class ImageLoadTask extends AsyncTask { private boolean download_image(){ //Create cache parent directory - if(!create_parent_directory()) + if(!ImageLoadUtils.create_parent_directory(mContext)) return false; try { @@ -176,27 +176,4 @@ public class ImageLoadTask extends AsyncTask { return true; } - - /** - * Create cache images files parent directory if it does not exist - * - * @return True in case of success - */ - private boolean create_parent_directory(){ - File parent = new File(mContext.getCacheDir(), ImageLoadUtils.IMAGE_CACHE_DIRECTORY); - - //Check if parent directory already exists - if(parent.exists()) - return true; - - - //Try to create directories - boolean success = parent.mkdirs(); - - //Return error if required - if(!success) - Log.e("ImageLoadTask", "Couldn't create cache parent directory !"); - - return success; - } } diff --git a/app/src/main/java/org/communiquons/android/comunic/client/data/ImageLoad/ImageLoadUtils.java b/app/src/main/java/org/communiquons/android/comunic/client/data/ImageLoad/ImageLoadUtils.java index 3ff24a3..4e4ed83 100644 --- a/app/src/main/java/org/communiquons/android/comunic/client/data/ImageLoad/ImageLoadUtils.java +++ b/app/src/main/java/org/communiquons/android/comunic/client/data/ImageLoad/ImageLoadUtils.java @@ -1,7 +1,12 @@ package org.communiquons.android.comunic.client.data.ImageLoad; +import android.content.Context; +import android.util.Log; + import org.communiquons.android.comunic.client.data.Utilities; +import java.io.File; + /** * Image loading utilities * @@ -11,6 +16,11 @@ import org.communiquons.android.comunic.client.data.Utilities; class ImageLoadUtils { + /** + * Debug tag + */ + private static final String TAG = "ImageLoadUtils"; + /** * The main folder in the cache directory that stores the file */ @@ -26,4 +36,28 @@ class ImageLoadUtils { return Utilities.sha1(url); } + /** + * Create cache images files parent directory if it does not exist + * + * @param context Context of execution + * @return True in case of success + */ + static boolean create_parent_directory(Context context){ + File parent = new File(context.getCacheDir(), IMAGE_CACHE_DIRECTORY); + + //Check if parent directory already exists + if(parent.exists()) + return true; + + + //Try to create directories + boolean success = parent.mkdirs(); + + //Return error if required + if(!success) + Log.e(TAG, "Couldn't create cache parent directory !"); + + return success; + } + } diff --git a/app/src/main/java/org/communiquons/android/comunic/client/data/UsersInfo/GetUsersHelper.java b/app/src/main/java/org/communiquons/android/comunic/client/data/UsersInfo/GetUsersHelper.java new file mode 100644 index 0000000..1269027 --- /dev/null +++ b/app/src/main/java/org/communiquons/android/comunic/client/data/UsersInfo/GetUsersHelper.java @@ -0,0 +1,265 @@ +package org.communiquons.android.comunic.client.data.UsersInfo; + +import android.content.Context; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.util.ArrayMap; +import android.util.Log; + +import org.communiquons.android.comunic.client.api.APIRequest; +import org.communiquons.android.comunic.client.api.APIRequestParameters; +import org.communiquons.android.comunic.client.api.APIResponse; +import org.communiquons.android.comunic.client.data.DatabaseHelper; +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.ArrayList; + +/** + * Get information about the users + * + * @author Pierre HUBERT + * Created by pierre on 12/10/17. + */ + +public class GetUsersHelper { + + /** + * Debug tag + */ + private final String TAG = "GetUsersHelper"; + + /** + * The context of the application + */ + private Context mContext; + + /** + * User information database helper + */ + private UsersInfosDbHelper udbHelper = null; + + /** + * Public constructor of the class + * + * @param context The context of execution of the application + * @param udbHelper User database helper + */ + public GetUsersHelper(@NonNull Context context, @NonNull UsersInfosDbHelper udbHelper){ + mContext = context; + this.udbHelper = udbHelper; + } + + /** + * Public constructor of the class + * + * @param context The context of execution of the application + * @param dbHelper Databasehelpepr + */ + public GetUsersHelper(@NonNull Context context, @NonNull DatabaseHelper dbHelper){ + mContext = context; + this.udbHelper = new UsersInfosDbHelper(dbHelper); + } + + /** + * Get information about a single user from the server + * + * @param id The ID of the user to get informations on + * @param force Force the informations to be fetched from the server + * @return User information or null in case of failure + */ + @Nullable + public UserInfo getSingle(int id, boolean force){ + + //Check, if we are allowed, if the user isn't already in the local database + if(!force){ + if(udbHelper.exists(id)) + return udbHelper.get(id); + } + + //Else fetch user information from server + ArrayList IDs = new ArrayList<>(); + IDs.add(id); + + ArrayMap result = getMultipleOnServer(IDs); + + if(result != null) { + if (result.containsKey(id)) { + + UserInfo infos = result.get(id); + + if (infos != null) { + + //Add the user to the database + udbHelper.insertOrUpdate(infos); + + //Return user informations + return infos; + + } + + } + } + + //If we got there, an error occured + Log.e(TAG, "Couldn't get information about a single user !"); + return null; + + } + + /** + * Get information about multiple users from the database or from the server + * + * @param IDs The ID of teh users to get + * @return users information / null in case of failure + */ + @Nullable + public ArrayMap getMultiple(ArrayList IDs){ + + ArrayMap usersInfo = new ArrayMap<>(); + ArrayList usersToDownload = new ArrayList<>(); + + //Check which users are available offline + for(Integer id : IDs){ + if(udbHelper.exists(id)){ + usersInfo.put(id, udbHelper.get(id)); + } + else { + usersToDownload.add(id); + } + } + + //If required, get users online + if(usersToDownload.size() > 0){ + ArrayMap download = getMultipleOnServer(usersToDownload); + + if(download != null){ + + //Process the list + for(int id : usersToDownload){ + + if(download.containsKey(id)){ + UserInfo info = download.get(id); + if(info != null) { + usersInfo.put(id, info); + udbHelper.insertOrUpdate(info); + } + } + + } + } + } + + + + return usersInfo; + } + + + /** + * Get and return the information about multiple users from the server + * + * @param IDs The ID of the user to get information + * @return Information about teh user / null in case of failure + */ + @Nullable + private ArrayMap getMultipleOnServer(ArrayList IDs){ + + ArrayMap uInfos = new ArrayMap<>(); + + //Perform a request on the API server + //Setup the request + APIRequestParameters requestParameters = new APIRequestParameters(mContext, + "user/getInfosMultiple"); + + + //Convert the IDs into a string + String id_string = ""; + for(int id : IDs) { + id_string += id + ","; + } + requestParameters.addParameter("usersID", id_string); + + + try { + + //Perform the request + APIResponse result = new APIRequest().exec(requestParameters); + + if(result != null) { + + //Try to extract user information + JSONObject userObjectContainer = result.getJSONObject(); + + if (userObjectContainer != null) { + + //Process each user ID + for(int userID : IDs) { + + UserInfo userInfos = null; + + //Extract user object + JSONObject userObject = userObjectContainer.getJSONObject(""+userID); + + //Continue only if we could extract required informations + if (userObject != null) { + //Parse user information + userInfos = parse_user_json(userObject); + + //Add the user to the list + uInfos.put(userID, userInfos); + } + + } + } + else { + Log.e(TAG, "Couldn't parse response from server !"); + return null; + } + + } + else + return null; + + } catch (Exception e){ + Log.e(TAG, "Couldn't get user information from server !"); + e.printStackTrace(); + return null; + } + + return uInfos; + } + + /** + * Parse a JSON object into a user object + * + * @param userObject Informations about the user in an object + * @return User object in case of success, null else + */ + private UserInfo parse_user_json(JSONObject userObject){ + + //Check if the JSON object passed is null or not + if(userObject == null) + return null; //Failure + + UserInfo userInfos = new UserInfo(); + + //Try to retrieve user informations + try { + + //Retrieve all user informations + userInfos.setId(userObject.getInt("userID")); + userInfos.setFirstName(userObject.getString("firstName")); + userInfos.setLastName(userObject.getString("lastName")); + userInfos.setAccountImageURL(userObject.getString("accountImage")); + + } catch (JSONException e){ + e.printStackTrace(); + return null; + } + + //Return result + return userInfos; + + } +} diff --git a/app/src/main/java/org/communiquons/android/comunic/client/data/UsersInfo/GetUsersInfos.java b/app/src/main/java/org/communiquons/android/comunic/client/data/UsersInfo/GetUsersInfos.java index 0d9b775..a7d697e 100644 --- a/app/src/main/java/org/communiquons/android/comunic/client/data/UsersInfo/GetUsersInfos.java +++ b/app/src/main/java/org/communiquons/android/comunic/client/data/UsersInfo/GetUsersInfos.java @@ -1,6 +1,7 @@ package org.communiquons.android.comunic.client.data.UsersInfo; import android.content.Context; +import android.os.AsyncTask; import android.util.ArrayMap; import org.communiquons.android.comunic.client.api.APIRequestParameters; @@ -22,14 +23,9 @@ import java.util.ArrayList; public class GetUsersInfos { /** - * User informations database helper + * User information database helper */ - private UsersInfosDbHelper udbHelper = null; - - /** - * Operations context - */ - private Context context; + private GetUsersHelper uHelper = null; /** * Public constructor @@ -39,11 +35,8 @@ public class GetUsersInfos { */ public GetUsersInfos(Context context, DatabaseHelper dbHelper){ - //Save context - this.context = context; - //Save database helper object - this.udbHelper = new UsersInfosDbHelper(dbHelper); + this.uHelper = new GetUsersHelper(context, dbHelper); } @@ -80,21 +73,24 @@ public class GetUsersInfos { * @param id The ID of the user to get the informations * @param callback What to do once we got the response */ - public void get(int id, getUserInfosCallback callback){ + public void get(int id, final getUserInfosCallback callback){ //Check if the ID is positive, error else if(id < 1){ callback.callback(null); //This is an error } - //Check if the user is already present in the database or not - if(!udbHelper.exists(id)) - //Perform a request on the server - getOnServer(id, callback); + new AsyncTask(){ + @Override + protected UserInfo doInBackground(Integer... params) { + return uHelper.getSingle(params[0], false); + } - //Else we can retrieve user informations from the local database - else - callback.callback(udbHelper.get(id)); + @Override + protected void onPostExecute(UserInfo userInfo) { + callback.callback(userInfo); + } + }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, id); } @@ -104,195 +100,21 @@ public class GetUsersInfos { * @param IDs The ID of the user to get * @param callback The result once we got all the users */ - public void getMultiple(ArrayList IDs, getMultipleUserInfosCallback callback){ + public void getMultiple(final ArrayList IDs, final getMultipleUserInfosCallback callback){ - //Initializate variables - ArrayList usersToGet = new ArrayList<>(); - ArrayMap usersInfo = new ArrayMap<>(); - - //Process each given user to check if they are available locally or not - for(Integer id : IDs){ - //Check if the user exist or not - if(!udbHelper.exists(id)) - usersToGet.add(id); - else { - //Get and save user informations - usersInfo.put(id, udbHelper.get(id)); + new AsyncTask>(){ + @Override + protected ArrayMap doInBackground(Void... params) { + return uHelper.getMultiple(IDs); } - } - - //Check if there are user informations to get on the server - if(usersToGet.size() > 0){ - getMultipleOnServer(usersToGet, usersInfo, callback); - } - else { - //Call the callback now with the cached user informations - callback.callback(usersInfo); - } - } - - /** - * Get and return the informations about a user on the server - * - * @param id The ID of the user to get informations from - * @param callback What to do once the request is done - */ - private void getOnServer(final int id, final getUserInfosCallback callback){ - - //Perform a request on the API server - //Setup the request - APIRequestParameters requestParameters = new APIRequestParameters(context, "user/getInfos"); - requestParameters.addParameter("userID", ""+id); - - //Do it. - new APIRequestTask(){ @Override - protected void onPostExecute(APIResponse result) { - - UserInfo userInfos = null; - - try { - if(result != null) { - - //Try to extract user informations - JSONObject userObjectContainer = result.getJSONObject(); - - if (userObjectContainer != null) { - - //Extract user object - JSONObject userObject = userObjectContainer.getJSONObject("" + id); - - //Continue only if we could extract required informations - if (userObject != null) { - //Parse user informations - userInfos = parse_user_json(userObject); - } - - //Save user information in the local database in case of success - if (userInfos != null) - udbHelper.insertOrUpdate(userInfos); - } - - } - - } catch (JSONException e){ - e.printStackTrace(); - } - - //Go to the next function - callback.callback(userInfos); - + protected void onPostExecute(ArrayMap integerUserInfoArrayMap) { + callback.callback(integerUserInfoArrayMap); } - - }.execute(requestParameters); - + }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); } - /** - * Get and return the informations about mutliple users on the server - * - * @param IDs The ID of the user to get informations from - * @param uInfos Informations about the other users (users that were already available in the db) - * @param callback What to do once the request is done - */ - private void getMultipleOnServer(final ArrayList IDs, final ArrayMap uInfos, - final getMultipleUserInfosCallback callback){ - //Determine IDs list - String IDs_list = ""; - for(int id : IDs){ - IDs_list += id + ","; - } - - //Perform a request on the API server - //Setup the request - APIRequestParameters requestParameters = new APIRequestParameters(context, "user/getInfosMultiple"); - requestParameters.addParameter("usersID", IDs_list); - - //Do it. - new APIRequestTask(){ - - @Override - protected void onPostExecute(APIResponse result) { - - try { - if(result != null) { - - //Try to extract user informations - JSONObject userObjectContainer = result.getJSONObject(); - - if (userObjectContainer != null) { - - //Process each user ID - for(int userID : IDs) { - - UserInfo userInfos = null; - - //Extract user object - JSONObject userObject = userObjectContainer.getJSONObject(""+userID); - - //Continue only if we could extract required informations - if (userObject != null) { - //Parse user informations - userInfos = parse_user_json(userObject); - } - - //Save user information in the local database in case of success - if (userInfos != null) - udbHelper.insertOrUpdate(userInfos); - - //Add the user to the list - uInfos.put(userID, userInfos); - } - } - - } - - } catch (JSONException e){ - e.printStackTrace(); - } - - //Perform callback action - callback.callback(uInfos); - - } - - }.execute(requestParameters); - - } - - /** - * Parse a JSON object into a user object - * - * @param userObject Informations about the user in an object - * @return User object in case of success, null else - */ - private UserInfo parse_user_json(JSONObject userObject){ - - //Check if the JSON object passed is null or not - if(userObject == null) - return null; //Failure - - UserInfo userInfos = new UserInfo(); - - //Try to retrieve user informations - try { - - //Retrieve all user informations - userInfos.setId(userObject.getInt("userID")); - userInfos.setFirstName(userObject.getString("firstName")); - userInfos.setLastName(userObject.getString("lastName")); - userInfos.setAccountImageURL(userObject.getString("accountImage")); - - } catch (JSONException e){ - e.printStackTrace(); - return null; - } - - //Return result - return userInfos; - - } } diff --git a/app/src/main/java/org/communiquons/android/comunic/client/data/conversations/ConversationsInfo.java b/app/src/main/java/org/communiquons/android/comunic/client/data/conversations/ConversationsInfo.java index fe71b9b..64e0c46 100644 --- a/app/src/main/java/org/communiquons/android/comunic/client/data/conversations/ConversationsInfo.java +++ b/app/src/main/java/org/communiquons/android/comunic/client/data/conversations/ConversationsInfo.java @@ -1,5 +1,7 @@ package org.communiquons.android.comunic.client.data.conversations; +import android.support.annotation.Nullable; + import java.util.ArrayList; /** @@ -17,17 +19,22 @@ public class ConversationsInfo { private int ID; private int ID_owner; private int last_active; - private String name; + private String name = null; private boolean following; private boolean saw_last_message; private ArrayList members; + /** + * Additional values used to display conversation information + */ + private String displayName = null; + /** * Set the ID of the conversation * * @param ID The ID of the conversation */ - public void setID(int ID) { + void setID(int ID) { this.ID = ID; } @@ -81,8 +88,13 @@ public class ConversationsInfo { * * @param name The name of the conversation */ - public void setName(String name) { - this.name = name; + public void setName(@Nullable String name) { + + //Check the validity of the name + if(name == "false" || name == "null" || name == null) + this.name = null; + else + this.name = name; } /** @@ -94,6 +106,15 @@ public class ConversationsInfo { return name; } + /** + * Check if the conversation has a name or not + * + * @return True if the conversation has a name / false else + */ + public boolean hasName(){ + return name == null; + } + /** * Specify whether the user is following the conversation or not * @@ -171,4 +192,34 @@ public class ConversationsInfo { public ArrayList getMembers() { return members; } + + + + + /** + * Set the displayed name of the conversation + * + * @param displayName The displayed name of the conversation + */ + public void setDisplayName(String displayName) { + this.displayName = displayName; + } + + /** + * Get the displayed name of the conversation + * + * @return The displayed name of the conversation + */ + public String getDisplayName() { + return displayName; + } + + /** + * Check if the conversation has a display name or not + * + * @return true If the conversation has a display name + */ + public boolean hasDisplayName(){ + return displayName == null; + } } diff --git a/app/src/main/java/org/communiquons/android/comunic/client/fragments/ConversationsListFragment.java b/app/src/main/java/org/communiquons/android/comunic/client/fragments/ConversationsListFragment.java index fa9547b..f43c27f 100644 --- a/app/src/main/java/org/communiquons/android/comunic/client/fragments/ConversationsListFragment.java +++ b/app/src/main/java/org/communiquons/android/comunic/client/fragments/ConversationsListFragment.java @@ -4,7 +4,6 @@ import android.app.Fragment; import android.os.AsyncTask; import android.os.Bundle; import android.support.annotation.Nullable; -import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -56,27 +55,66 @@ public class ConversationsListFragment extends Fragment { conversationsListHelper = new ConversationsListHelper(getActivity()); //Get the list of conversations - new AsyncTask(){ + new AsyncTask>(){ @Override - protected Void doInBackground(Void... params) { + protected ArrayList doInBackground(Void... params) { //Get the list of conversations - convList = conversationsListHelper.download(); + return conversationsListHelper.download(); - return null; } @Override - protected void onPostExecute(Void aVoid) { - super.onPostExecute(aVoid); - - for(ConversationsInfo conv : convList){ - Log.v(TAG, "Conversation "+conv.getID()+": " + conv.getName() + " / " + - conv.countMembers() + " members / Owner: " + conv.getID_owner()); - } + protected void onPostExecute(ArrayList list) { + process_conversations_list(list); } }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + } + + /** + * Process the conversation list + * + * @param list The list of conversations + */ + public void process_conversations_list(ArrayList list){ + + //Check if got the list + if(list == null){ + Toast.makeText(getActivity(), R.string.fragment_conversationslist_err_get_list, + Toast.LENGTH_LONG).show(); + return; + } + + //Process the list of conversation + ArrayList usersToGet = new ArrayList<>(); + ArrayList convToUpdate = new ArrayList<>(); + for(ConversationsInfo conv : list){ + + //Set the displayed names of the conversation + if(conv.hasName()){ + //Use the name of the conversation if available + conv.setDisplayName(conv.getName()); + } + else { + + //Add the first users of the conversations to the users for which we need info + for(int i = 0; i < 2; i++){ + + if(conv.getMembers().size() <= i) + break; + + usersToGet.add(conv.getMembers().get(i)); + + } + + convToUpdate.add(conv); + } + + } + + + } } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index bb907ec..96f8152 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -33,4 +33,5 @@ Deny Respond to the request Do you want to accept or deny this friendship request ? + An error occurred while retrieving conversations list !