A few improvements

This commit is contained in:
Pierre 2017-12-10 09:45:28 +01:00
parent 18bb76b401
commit e669f0fa05
8 changed files with 433 additions and 242 deletions

View File

@ -69,6 +69,9 @@ class ImageLoadRunnable implements Runnable {
@Override @Override
public void run() { public void run() {
//Create the parent directory if required
ImageLoadUtils.create_parent_directory(mContext);
//Determine the filename for the requested URL //Determine the filename for the requested URL
String filename = ImageLoadUtils.IMAGE_CACHE_DIRECTORY + ImageLoadUtils.get_file_name(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 * The apply to the final image view
*/ */
private void load_image(){ private void load_image(){

View File

@ -139,7 +139,7 @@ public class ImageLoadTask extends AsyncTask<Void, Void, Void> {
private boolean download_image(){ private boolean download_image(){
//Create cache parent directory //Create cache parent directory
if(!create_parent_directory()) if(!ImageLoadUtils.create_parent_directory(mContext))
return false; return false;
try { try {
@ -176,27 +176,4 @@ public class ImageLoadTask extends AsyncTask<Void, Void, Void> {
return true; 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;
}
} }

View File

@ -1,7 +1,12 @@
package org.communiquons.android.comunic.client.data.ImageLoad; 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 org.communiquons.android.comunic.client.data.Utilities;
import java.io.File;
/** /**
* Image loading utilities * Image loading utilities
* *
@ -11,6 +16,11 @@ import org.communiquons.android.comunic.client.data.Utilities;
class ImageLoadUtils { class ImageLoadUtils {
/**
* Debug tag
*/
private static final String TAG = "ImageLoadUtils";
/** /**
* The main folder in the cache directory that stores the file * The main folder in the cache directory that stores the file
*/ */
@ -26,4 +36,28 @@ class ImageLoadUtils {
return Utilities.sha1(url); 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;
}
} }

View File

@ -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<Integer> IDs = new ArrayList<>();
IDs.add(id);
ArrayMap<Integer, UserInfo> 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<Integer, UserInfo> getMultiple(ArrayList<Integer> IDs){
ArrayMap<Integer, UserInfo> usersInfo = new ArrayMap<>();
ArrayList<Integer> 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<Integer, UserInfo> 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<Integer, UserInfo> getMultipleOnServer(ArrayList<Integer> IDs){
ArrayMap<Integer, UserInfo> 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;
}
}

View File

@ -1,6 +1,7 @@
package org.communiquons.android.comunic.client.data.UsersInfo; package org.communiquons.android.comunic.client.data.UsersInfo;
import android.content.Context; import android.content.Context;
import android.os.AsyncTask;
import android.util.ArrayMap; import android.util.ArrayMap;
import org.communiquons.android.comunic.client.api.APIRequestParameters; import org.communiquons.android.comunic.client.api.APIRequestParameters;
@ -22,14 +23,9 @@ import java.util.ArrayList;
public class GetUsersInfos { public class GetUsersInfos {
/** /**
* User informations database helper * User information database helper
*/ */
private UsersInfosDbHelper udbHelper = null; private GetUsersHelper uHelper = null;
/**
* Operations context
*/
private Context context;
/** /**
* Public constructor * Public constructor
@ -39,11 +35,8 @@ public class GetUsersInfos {
*/ */
public GetUsersInfos(Context context, DatabaseHelper dbHelper){ public GetUsersInfos(Context context, DatabaseHelper dbHelper){
//Save context
this.context = context;
//Save database helper object //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 id The ID of the user to get the informations
* @param callback What to do once we got the response * @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 //Check if the ID is positive, error else
if(id < 1){ if(id < 1){
callback.callback(null); //This is an error callback.callback(null); //This is an error
} }
//Check if the user is already present in the database or not new AsyncTask<Integer, Void, UserInfo>(){
if(!udbHelper.exists(id)) @Override
//Perform a request on the server protected UserInfo doInBackground(Integer... params) {
getOnServer(id, callback); return uHelper.getSingle(params[0], false);
}
//Else we can retrieve user informations from the local database @Override
else protected void onPostExecute(UserInfo userInfo) {
callback.callback(udbHelper.get(id)); 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 IDs The ID of the user to get
* @param callback The result once we got all the users * @param callback The result once we got all the users
*/ */
public void getMultiple(ArrayList<Integer> IDs, getMultipleUserInfosCallback callback){ public void getMultiple(final ArrayList<Integer> IDs, final getMultipleUserInfosCallback callback){
//Initializate variables new AsyncTask<Void, Void, ArrayMap<Integer, UserInfo>>(){
ArrayList<Integer> usersToGet = new ArrayList<>(); @Override
ArrayMap<Integer, UserInfo> usersInfo = new ArrayMap<>(); protected ArrayMap<Integer, UserInfo> doInBackground(Void... params) {
return uHelper.getMultiple(IDs);
//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));
} }
}
//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 @Override
protected void onPostExecute(APIResponse result) { protected void onPostExecute(ArrayMap<Integer, UserInfo> integerUserInfoArrayMap) {
callback.callback(integerUserInfoArrayMap);
UserInfo userInfos = null; }
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
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);
}
}.execute(requestParameters);
}
/**
* 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<Integer> IDs, final ArrayMap<Integer, UserInfo> 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;
}
} }

View File

@ -1,5 +1,7 @@
package org.communiquons.android.comunic.client.data.conversations; package org.communiquons.android.comunic.client.data.conversations;
import android.support.annotation.Nullable;
import java.util.ArrayList; import java.util.ArrayList;
/** /**
@ -17,17 +19,22 @@ public class ConversationsInfo {
private int ID; private int ID;
private int ID_owner; private int ID_owner;
private int last_active; private int last_active;
private String name; private String name = null;
private boolean following; private boolean following;
private boolean saw_last_message; private boolean saw_last_message;
private ArrayList<Integer> members; private ArrayList<Integer> members;
/**
* Additional values used to display conversation information
*/
private String displayName = null;
/** /**
* Set the ID of the conversation * Set the ID of the conversation
* *
* @param ID The ID of the conversation * @param ID The ID of the conversation
*/ */
public void setID(int ID) { void setID(int ID) {
this.ID = ID; this.ID = ID;
} }
@ -81,7 +88,12 @@ public class ConversationsInfo {
* *
* @param name The name of the conversation * @param name The name of the conversation
*/ */
public void setName(String 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; this.name = name;
} }
@ -94,6 +106,15 @@ public class ConversationsInfo {
return name; 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 * Specify whether the user is following the conversation or not
* *
@ -171,4 +192,34 @@ public class ConversationsInfo {
public ArrayList<Integer> getMembers() { public ArrayList<Integer> getMembers() {
return members; 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;
}
} }

View File

@ -4,7 +4,6 @@ import android.app.Fragment;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
@ -56,27 +55,66 @@ public class ConversationsListFragment extends Fragment {
conversationsListHelper = new ConversationsListHelper(getActivity()); conversationsListHelper = new ConversationsListHelper(getActivity());
//Get the list of conversations //Get the list of conversations
new AsyncTask<Void, Void, Void>(){ new AsyncTask<Void, Void, ArrayList<ConversationsInfo>>(){
@Override @Override
protected Void doInBackground(Void... params) { protected ArrayList<ConversationsInfo> doInBackground(Void... params) {
//Get the list of conversations //Get the list of conversations
convList = conversationsListHelper.download(); return conversationsListHelper.download();
return null;
} }
@Override @Override
protected void onPostExecute(Void aVoid) { protected void onPostExecute(ArrayList<ConversationsInfo> list) {
super.onPostExecute(aVoid); process_conversations_list(list);
for(ConversationsInfo conv : convList){
Log.v(TAG, "Conversation "+conv.getID()+": " + conv.getName() + " / " +
conv.countMembers() + " members / Owner: " + conv.getID_owner());
}
} }
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
/**
* Process the conversation list
*
* @param list The list of conversations
*/
public void process_conversations_list(ArrayList<ConversationsInfo> 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<Integer> usersToGet = new ArrayList<>();
ArrayList<ConversationsInfo> 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);
}
}
} }
} }

View File

@ -33,4 +33,5 @@
<string name="action_friends_deny_request">Deny</string> <string name="action_friends_deny_request">Deny</string>
<string name="popup_respond_friendship_request_title">Respond to the request</string> <string name="popup_respond_friendship_request_title">Respond to the request</string>
<string name="popup_respond_friendship_request_message">Do you want to accept or deny this friendship request ?</string> <string name="popup_respond_friendship_request_message">Do you want to accept or deny this friendship request ?</string>
<string name="fragment_conversationslist_err_get_list">An error occurred while retrieving conversations list !</string>
</resources> </resources>