diff --git a/app/build.gradle b/app/build.gradle
index 7d23faf..ed4a54d 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -57,6 +57,7 @@ dependencies {
implementation 'com.android.support:appcompat-v7:28.0.0-rc01'
implementation 'com.android.support.constraint:constraint-layout:1.1.2'
implementation 'com.android.support:design:28.0.0-rc01'
+ implementation 'com.android.support:preference-v7:28.0.0-rc01'
implementation 'com.android.support:support-v4:28.0.0-rc01'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index bc1ee4f..ed1e13d 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -49,6 +49,10 @@
android:name=".ui.activities.PDFActivity"
android:label="@string/activity_view_pdf_label" />
+
+
+
+ android:label="@string/activity_about_title" />
+
diff --git a/app/src/main/java/org/communiquons/android/comunic/client/data/enums/AccountImageVisibility.java b/app/src/main/java/org/communiquons/android/comunic/client/data/enums/AccountImageVisibility.java
new file mode 100644
index 0000000..b29ea29
--- /dev/null
+++ b/app/src/main/java/org/communiquons/android/comunic/client/data/enums/AccountImageVisibility.java
@@ -0,0 +1,12 @@
+package org.communiquons.android.comunic.client.data.enums;
+
+/**
+ * Account image visibility levels
+ *
+ * @author Pierre HUBERT
+ */
+public enum AccountImageVisibility {
+ OPEN,
+ PUBLIC,
+ FRIENDS
+}
diff --git a/app/src/main/java/org/communiquons/android/comunic/client/data/helpers/AccountSettingsHelper.java b/app/src/main/java/org/communiquons/android/comunic/client/data/helpers/AccountSettingsHelper.java
new file mode 100644
index 0000000..783fe1a
--- /dev/null
+++ b/app/src/main/java/org/communiquons/android/comunic/client/data/helpers/AccountSettingsHelper.java
@@ -0,0 +1,130 @@
+package org.communiquons.android.comunic.client.data.helpers;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.support.annotation.Nullable;
+
+import org.communiquons.android.comunic.client.data.enums.AccountImageVisibility;
+import org.communiquons.android.comunic.client.data.models.APIFileRequest;
+import org.communiquons.android.comunic.client.data.models.APIPostFile;
+import org.communiquons.android.comunic.client.data.models.APIRequest;
+import org.communiquons.android.comunic.client.data.models.APIResponse;
+import org.communiquons.android.comunic.client.data.models.AccountImageSettings;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+/**
+ * Account settings helper
+ *
+ * @author Pierre HUBERT
+ */
+public class AccountSettingsHelper extends BaseHelper {
+
+ public AccountSettingsHelper(Context context) {
+ super(context);
+ }
+
+ /**
+ * Get account image settings
+ *
+ * @return The account image settings / null in case of failure
+ */
+ @Nullable
+ public AccountImageSettings getAccountImageSettings(){
+
+ APIRequest request = new APIRequest(getContext(), "settings/get_account_image");
+ try {
+ APIResponse response = new APIRequestHelper().exec(request);
+
+ if(response.getResponse_code() != 200)
+ return null;
+
+ return APIToAccountImageSettings(response.getJSONObject());
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ return null;
+ }
+ }
+
+ /**
+ * Upload a new account image
+ *
+ * @param bitmap The image bitmap to upload
+ * @return The result of the operation
+ */
+ public boolean uploadAccountImage(Bitmap bitmap){
+ APIFileRequest request = new APIFileRequest(getContext(),
+ "settings/upload_account_image");
+
+ APIPostFile file = new APIPostFile();
+ file.setFileName("image.png");
+ file.setBitmap(bitmap);
+ file.setFieldName("picture");
+ request.addFile(file);
+
+ try {
+ return new APIRequestHelper().execPostFile(request).getResponse_code() == 200;
+ } catch (Exception e) {
+ e.printStackTrace();
+ return false;
+ }
+ }
+
+ /**
+ * Delete user account image
+ *
+ * @return TRUE for a success / FALSE else
+ */
+ public boolean deleteAccountImage(){
+ APIRequest request = new APIRequest(getContext(), "settings/delete_account_image");
+ request.setTryContinueOnError(true);
+
+ try {
+ APIResponse response = new APIRequestHelper().exec(request);
+ return response.getResponse_code() == 200;
+ } catch (Exception e) {
+ e.printStackTrace();
+ return false;
+ }
+ }
+
+ /**
+ * Parse an API entry into an AccountImageSettings entry
+ *
+ * @param object JSON object to parse
+ * @return Generated AccountImageSettings object
+ * @throws JSONException In case of failure
+ */
+ private static AccountImageSettings APIToAccountImageSettings(JSONObject object)
+ throws JSONException {
+ AccountImageSettings accountImageSettings = new AccountImageSettings();
+ accountImageSettings.setHas_image(object.getBoolean("has_image"));
+ accountImageSettings.setImageURL(object.getString("image_url"));
+ accountImageSettings.setVisibility(StringToAccountImageVisibility(
+ object.getString("visibility")));
+ return accountImageSettings;
+ }
+
+ /**
+ * Turn a string into an AccountImageVisibility level
+ *
+ * @param string The string to parse
+ * @return Matching enum entry
+ */
+ private static AccountImageVisibility StringToAccountImageVisibility(String string){
+ switch (string){
+ case "open":
+ return AccountImageVisibility.OPEN;
+
+ case "public":
+ return AccountImageVisibility.PUBLIC;
+
+ case "friends":
+ return AccountImageVisibility.FRIENDS;
+
+ default:
+ throw new AssertionError();
+ }
+ }
+}
diff --git a/app/src/main/java/org/communiquons/android/comunic/client/data/models/AccountImageSettings.java b/app/src/main/java/org/communiquons/android/comunic/client/data/models/AccountImageSettings.java
new file mode 100644
index 0000000..fb537f8
--- /dev/null
+++ b/app/src/main/java/org/communiquons/android/comunic/client/data/models/AccountImageSettings.java
@@ -0,0 +1,41 @@
+package org.communiquons.android.comunic.client.data.models;
+
+import org.communiquons.android.comunic.client.data.enums.AccountImageVisibility;
+
+/**
+ * Account image settings container
+ *
+ * @author Pierre HUBERT
+ */
+public class AccountImageSettings {
+
+ //Private fields
+ private boolean has_image;
+ private String imageURL;
+ private AccountImageVisibility visibility;
+
+ public boolean isHas_image() {
+ return has_image;
+ }
+
+ public void setHas_image(boolean has_image) {
+ this.has_image = has_image;
+ }
+
+ public String getImageURL() {
+ return imageURL;
+ }
+
+ public void setImageURL(String imageURL) {
+ this.imageURL = imageURL;
+ }
+
+
+ public AccountImageVisibility getVisibility() {
+ return visibility;
+ }
+
+ public void setVisibility(AccountImageVisibility visibility) {
+ this.visibility = visibility;
+ }
+}
diff --git a/app/src/main/java/org/communiquons/android/comunic/client/ui/Constants.java b/app/src/main/java/org/communiquons/android/comunic/client/ui/Constants.java
index b3a0bca..9f09fde 100644
--- a/app/src/main/java/org/communiquons/android/comunic/client/ui/Constants.java
+++ b/app/src/main/java/org/communiquons/android/comunic/client/ui/Constants.java
@@ -31,6 +31,11 @@ public final class Constants {
* Intent code : search a user
*/
public static final int MAIN_ACTIVITY_SEARCH_USER_INTENT = 3;
+
+ /**
+ * Pick image to update account image
+ */
+ public static final int ACCOUNT_IMAGE_SETTINGS_PICK_NEW_INTENT = 4;
}
}
diff --git a/app/src/main/java/org/communiquons/android/comunic/client/ui/activities/AccountSettingsActivity.java b/app/src/main/java/org/communiquons/android/comunic/client/ui/activities/AccountSettingsActivity.java
new file mode 100644
index 0000000..55095bb
--- /dev/null
+++ b/app/src/main/java/org/communiquons/android/comunic/client/ui/activities/AccountSettingsActivity.java
@@ -0,0 +1,44 @@
+package org.communiquons.android.comunic.client.ui.activities;
+
+import android.os.Bundle;
+import android.support.v4.app.FragmentTransaction;
+import android.view.MenuItem;
+
+import org.communiquons.android.comunic.client.ui.fragments.accountsettings.AccountSettingsMainFragment;
+
+/**
+ * Account settings activity
+ *
+ * @author Pierre HUBERT
+ */
+public class AccountSettingsActivity extends BaseActivity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ getSupportActionBar().setDisplayHomeAsUpEnabled(true);
+
+ //Open main fragment if required
+ if(savedInstanceState == null){
+ AccountSettingsMainFragment fragment = new AccountSettingsMainFragment();
+ FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
+ transaction.replace(android.R.id.content, fragment);
+ transaction.commit();
+ }
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+
+ //To go back
+ if(item.getItemId() == android.R.id.home){
+ if(getSupportFragmentManager().getBackStackEntryCount() > 0)
+ getSupportFragmentManager().popBackStack();
+ else
+ finish();
+ }
+
+ return super.onContextItemSelected(item);
+ }
+}
diff --git a/app/src/main/java/org/communiquons/android/comunic/client/ui/activities/BaseActivity.java b/app/src/main/java/org/communiquons/android/comunic/client/ui/activities/BaseActivity.java
new file mode 100644
index 0000000..51db929
--- /dev/null
+++ b/app/src/main/java/org/communiquons/android/comunic/client/ui/activities/BaseActivity.java
@@ -0,0 +1,20 @@
+package org.communiquons.android.comunic.client.ui.activities;
+
+import android.support.annotation.NonNull;
+import android.support.v7.app.ActionBar;
+import android.support.v7.app.AppCompatActivity;
+
+/**
+ * Base application activity
+ *
+ * @author Pierre HUBERT
+ */
+public abstract class BaseActivity extends AppCompatActivity {
+
+ @NonNull
+ @Override
+ public ActionBar getSupportActionBar() {
+ assert super.getSupportActionBar() != null;
+ return super.getSupportActionBar();
+ }
+}
diff --git a/app/src/main/java/org/communiquons/android/comunic/client/ui/activities/MainActivity.java b/app/src/main/java/org/communiquons/android/comunic/client/ui/activities/MainActivity.java
index 1a05e3e..c9d93f4 100644
--- a/app/src/main/java/org/communiquons/android/comunic/client/ui/activities/MainActivity.java
+++ b/app/src/main/java/org/communiquons/android/comunic/client/ui/activities/MainActivity.java
@@ -57,7 +57,7 @@ import static org.communiquons.android.comunic.client.ui.Constants.IntentRequest
*
* @author Pierre HUBERT
*/
-public class MainActivity extends AppCompatActivity implements
+public class MainActivity extends BaseActivity implements
openConversationListener, updateConversationListener, onOpenUsersPageListener,
onPostOpenListener, NavigationBar.OnNavigationItemSelectedListener {
@@ -153,7 +153,6 @@ public class MainActivity extends AppCompatActivity implements
conversationsListHelper = new ConversationsListHelper(this, dbHelper);
//Use navigation bar
- assert getSupportActionBar() != null;
getSupportActionBar().hide();
mNavBar = findViewById(R.id.nav_bar);
mNavBar.setOnNavigationItemSelectedListener(this);
@@ -230,6 +229,11 @@ public class MainActivity extends AppCompatActivity implements
return true;
}
+ //To open account settings
+ if(id == R.id.action_account_settings){
+ openAccountSettings();
+ return true;
+ }
//To open settings fragment
if (id == R.id.action_settings) {
@@ -430,6 +434,13 @@ public class MainActivity extends AppCompatActivity implements
}
+ /**
+ * Open account settings
+ */
+ void openAccountSettings(){
+ startActivity(new Intent(this, AccountSettingsActivity.class));
+ }
+
/**
* Open settings activity
*/
diff --git a/app/src/main/java/org/communiquons/android/comunic/client/ui/asynctasks/DeleteUserAccountImageTask.java b/app/src/main/java/org/communiquons/android/comunic/client/ui/asynctasks/DeleteUserAccountImageTask.java
new file mode 100644
index 0000000..80a6636
--- /dev/null
+++ b/app/src/main/java/org/communiquons/android/comunic/client/ui/asynctasks/DeleteUserAccountImageTask.java
@@ -0,0 +1,22 @@
+package org.communiquons.android.comunic.client.ui.asynctasks;
+
+import android.content.Context;
+
+import org.communiquons.android.comunic.client.data.helpers.AccountSettingsHelper;
+
+/**
+ * Delete user account image AsyncTask
+ *
+ * @author Pierre HUBERT
+ */
+public class DeleteUserAccountImageTask extends SafeAsyncTask {
+
+ public DeleteUserAccountImageTask(Context context) {
+ super(context);
+ }
+
+ @Override
+ protected Boolean doInBackground(Void... voids) {
+ return new AccountSettingsHelper(getContext()).deleteAccountImage();
+ }
+}
diff --git a/app/src/main/java/org/communiquons/android/comunic/client/ui/asynctasks/GetAccountImageSettingsTask.java b/app/src/main/java/org/communiquons/android/comunic/client/ui/asynctasks/GetAccountImageSettingsTask.java
new file mode 100644
index 0000000..d97b1c7
--- /dev/null
+++ b/app/src/main/java/org/communiquons/android/comunic/client/ui/asynctasks/GetAccountImageSettingsTask.java
@@ -0,0 +1,23 @@
+package org.communiquons.android.comunic.client.ui.asynctasks;
+
+import android.content.Context;
+
+import org.communiquons.android.comunic.client.data.helpers.AccountSettingsHelper;
+import org.communiquons.android.comunic.client.data.models.AccountImageSettings;
+
+/**
+ * Get account image settings task
+ *
+ * @author Pierre HUBERT
+ */
+public class GetAccountImageSettingsTask extends SafeAsyncTask {
+
+ public GetAccountImageSettingsTask(Context context) {
+ super(context);
+ }
+
+ @Override
+ protected AccountImageSettings doInBackground(Void... voids) {
+ return new AccountSettingsHelper(getContext()).getAccountImageSettings();
+ }
+}
diff --git a/app/src/main/java/org/communiquons/android/comunic/client/ui/asynctasks/UploadNewAccountImageTask.java b/app/src/main/java/org/communiquons/android/comunic/client/ui/asynctasks/UploadNewAccountImageTask.java
new file mode 100644
index 0000000..2dc8cdd
--- /dev/null
+++ b/app/src/main/java/org/communiquons/android/comunic/client/ui/asynctasks/UploadNewAccountImageTask.java
@@ -0,0 +1,27 @@
+package org.communiquons.android.comunic.client.ui.asynctasks;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+
+import org.communiquons.android.comunic.client.data.helpers.AccountSettingsHelper;
+
+/**
+ * Upload a new account image task
+ *
+ * @author Pierre HUBERT
+ */
+public class UploadNewAccountImageTask extends SafeAsyncTask {
+
+ public UploadNewAccountImageTask(Context context) {
+ super(context);
+ }
+
+ @Override
+ protected Boolean doInBackground(Bitmap... bitmaps) {
+
+ return bitmaps.length != 0 &&
+ bitmaps[0] != null &&
+ new AccountSettingsHelper(getContext()).uploadAccountImage(bitmaps[0]);
+
+ }
+}
diff --git a/app/src/main/java/org/communiquons/android/comunic/client/ui/fragments/accountsettings/AccountImageSettingsFragment.java b/app/src/main/java/org/communiquons/android/comunic/client/ui/fragments/accountsettings/AccountImageSettingsFragment.java
new file mode 100644
index 0000000..fbc0def
--- /dev/null
+++ b/app/src/main/java/org/communiquons/android/comunic/client/ui/fragments/accountsettings/AccountImageSettingsFragment.java
@@ -0,0 +1,248 @@
+package org.communiquons.android.comunic.client.ui.fragments.accountsettings;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.support.v7.preference.Preference;
+import android.widget.Toast;
+
+import org.communiquons.android.comunic.client.R;
+import org.communiquons.android.comunic.client.data.models.AccountImageSettings;
+import org.communiquons.android.comunic.client.ui.asynctasks.DeleteUserAccountImageTask;
+import org.communiquons.android.comunic.client.ui.asynctasks.GetAccountImageSettingsTask;
+import org.communiquons.android.comunic.client.ui.asynctasks.SafeAsyncTask;
+import org.communiquons.android.comunic.client.ui.asynctasks.UploadNewAccountImageTask;
+import org.communiquons.android.comunic.client.ui.preference.AccountImagePreference;
+import org.communiquons.android.comunic.client.ui.utils.BitmapUtils;
+
+import java.io.FileNotFoundException;
+
+import static org.communiquons.android.comunic.client.ui.Constants.IntentRequestCode.ACCOUNT_IMAGE_SETTINGS_PICK_NEW_INTENT;
+
+/**
+ * Account image settings fragment
+ */
+public class AccountImageSettingsFragment extends BaseAccountSettingsFragment implements Preference.OnPreferenceClickListener {
+
+ private static final String TAG = AccountImageSettingsFragment.class.getSimpleName();
+
+ //Preferences
+ private static final String PREFERENCE_UPDATE_ACCOUNT_IMAGE = "update_account_image";
+ private static final String PREFERENCE_DELETE_ACCOUNT_IMAGE = "delete_account_image";
+
+ private AccountImageSettings mAccountImageSettings;
+
+ private GetAccountImageSettingsTask mGetAccountImageSettingsTask;
+ private UploadNewAccountImageTask mUploadNewAccountImageTask;
+ private DeleteUserAccountImageTask mDeleteUserAccountImageTask;
+
+ @Override
+ public void onCreatePreferences(Bundle bundle, String s) {
+ addPreferencesFromResource(R.xml.account_preference_image);
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ findPreference(PREFERENCE_UPDATE_ACCOUNT_IMAGE).setOnPreferenceClickListener(this);
+ findPreference(PREFERENCE_DELETE_ACCOUNT_IMAGE).setOnPreferenceClickListener(this);
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ getActivity().setTitle(R.string.preferences_account_image_title);
+
+ if(mAccountImageSettings == null)
+ load_settings();
+ else
+ onGotAccountImageSettings(mAccountImageSettings);
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ unset_loading_tasks();
+ removeLoadingDialog();
+ }
+
+ private void unset_loading_tasks(){
+ if(mGetAccountImageSettingsTask != null)
+ mGetAccountImageSettingsTask.setOnPostExecuteListener(null);
+
+ if(mUploadNewAccountImageTask != null)
+ mUploadNewAccountImageTask.setOnPostExecuteListener(null);
+
+ if(mDeleteUserAccountImageTask != null)
+ mDeleteUserAccountImageTask.setOnPostExecuteListener(null);
+ }
+
+
+
+ /**
+ * Load account image settings. As soon as this method is called, cached information about
+ * account image are cleared, so on pause and resume of the fragment it can be loaded again
+ */
+ private void load_settings(){
+ unset_loading_tasks();
+
+ showLoadingDialog();
+
+ mAccountImageSettings = null;
+ mGetAccountImageSettingsTask = new GetAccountImageSettingsTask(getActivity());
+ mGetAccountImageSettingsTask.setOnPostExecuteListener(new SafeAsyncTask.OnPostExecuteListener() {
+ @Override
+ public void OnPostExecute(AccountImageSettings accountImageSettings) {
+ onGotAccountImageSettings(accountImageSettings);
+ }
+ });
+ mGetAccountImageSettingsTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
+ }
+
+ private void onGotAccountImageSettings(@Nullable AccountImageSettings accountImageSettings){
+
+ removeLoadingDialog();
+
+ //Check for errors
+ if(accountImageSettings == null){
+ Toast.makeText(getActivity(), R.string.err_get_account_image_settings,
+ Toast.LENGTH_SHORT).show();
+ return;
+ }
+
+ mAccountImageSettings = accountImageSettings;
+
+ //Apply settings
+ ((AccountImagePreference)findPreference(PREFERENCE_UPDATE_ACCOUNT_IMAGE))
+ .setImage_url(mAccountImageSettings.getImageURL());
+ findPreference(PREFERENCE_DELETE_ACCOUNT_IMAGE).setEnabled(
+ accountImageSettings.isHas_image());
+
+ }
+
+ @Override
+ public boolean onPreferenceClick(Preference preference) {
+
+ switch (preference.getKey()){
+
+ //Upload new account image
+ case PREFERENCE_UPDATE_ACCOUNT_IMAGE:
+ pickNewAccountImage();
+ break;
+
+ //Delete account image
+ case PREFERENCE_DELETE_ACCOUNT_IMAGE:
+ confirmDeleteAccountImage();
+ break;
+
+ }
+
+ return false;
+ }
+
+ @Override
+ public void onActivityResult(int requestCode, int resultCode, Intent data) {
+ super.onActivityResult(requestCode, resultCode, data);
+
+ //Check if the request was to choose a new account image
+ if(requestCode == ACCOUNT_IMAGE_SETTINGS_PICK_NEW_INTENT)
+ pickNewAccountImageCallback(resultCode, data);
+ }
+
+ /**
+ * Prompt the user to choose a new account image
+ */
+ private void pickNewAccountImage(){
+ Intent intent = new Intent(Intent.ACTION_PICK);
+ intent.setType("image/*");
+ startActivityForResult(intent, ACCOUNT_IMAGE_SETTINGS_PICK_NEW_INTENT);
+ }
+
+ /**
+ * Pick new account image callback
+ *
+ * @param resultCode Result code of the operation
+ * @param data Associated data
+ */
+ private void pickNewAccountImageCallback(int resultCode, Intent data){
+ if(resultCode != Activity.RESULT_OK)
+ return;
+
+ try {
+ uploadNewAccountImage(BitmapUtils.IntentResultToBitmap(getActivity(), data));
+
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * Perform the upload of new account image
+ *
+ * @param bitmap The new account image, as bitmap
+ */
+ private void uploadNewAccountImage(Bitmap bitmap){
+ showLoadingDialog();
+ unset_loading_tasks();
+
+ mUploadNewAccountImageTask = new UploadNewAccountImageTask(getContext());
+ mUploadNewAccountImageTask.setOnPostExecuteListener(new SafeAsyncTask.OnPostExecuteListener() {
+ @Override
+ public void OnPostExecute(Boolean result) {
+ if(!result)
+ Toast.makeText(getActivity(), R.string.err_upload_account_image,
+ Toast.LENGTH_SHORT).show();
+
+ load_settings();
+ }
+ });
+ mUploadNewAccountImageTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, bitmap);
+ }
+
+ /**
+ * Prompt user confirmation to delete account image
+ */
+ private void confirmDeleteAccountImage(){
+ new AlertDialog.Builder(getActivity())
+ .setTitle(R.string.dialog_delete_accountimage_title)
+ .setMessage(R.string.dialog_delete_accountimage_message)
+ .setNegativeButton(R.string.dialog_delete_accountimage_cancel, null)
+
+ .setPositiveButton(R.string.dialog_delete_accountimage_confirm, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ deleteAccountImage();
+ }
+ })
+
+ .show();
+ }
+
+ /**
+ * Perform account image deletion
+ */
+ private void deleteAccountImage(){
+ showLoadingDialog();
+ unset_loading_tasks();
+
+ mDeleteUserAccountImageTask = new DeleteUserAccountImageTask(getActivity());
+ mDeleteUserAccountImageTask.setOnPostExecuteListener(new SafeAsyncTask.OnPostExecuteListener() {
+ @Override
+ public void OnPostExecute(Boolean result) {
+
+ if(!result)
+ Toast.makeText(getActivity(), R.string.err_delete_account_image,
+ Toast.LENGTH_SHORT).show();
+
+ load_settings();
+ }
+ });
+ mDeleteUserAccountImageTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
+ }
+}
diff --git a/app/src/main/java/org/communiquons/android/comunic/client/ui/fragments/accountsettings/AccountSettingsMainFragment.java b/app/src/main/java/org/communiquons/android/comunic/client/ui/fragments/accountsettings/AccountSettingsMainFragment.java
new file mode 100644
index 0000000..1040108
--- /dev/null
+++ b/app/src/main/java/org/communiquons/android/comunic/client/ui/fragments/accountsettings/AccountSettingsMainFragment.java
@@ -0,0 +1,62 @@
+package org.communiquons.android.comunic.client.ui.fragments.accountsettings;
+
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.support.v4.app.FragmentTransaction;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceFragmentCompat;
+
+import org.communiquons.android.comunic.client.R;
+
+/**
+ * Main account preference fragment
+ */
+public class AccountSettingsMainFragment extends PreferenceFragmentCompat
+ implements Preference.OnPreferenceClickListener {
+
+ private static final String PREFERENCE_CATEGORY_ACCOUNT_IMAGE = "preference_category_account_image";
+
+ @Override
+ public void onCreatePreferences(Bundle bundle, String s) {
+ addPreferencesFromResource(R.xml.account_preference_main);
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ this.findPreference(PREFERENCE_CATEGORY_ACCOUNT_IMAGE).setOnPreferenceClickListener(this);
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ getActivity().setTitle(R.string.activity_account_settings_label);
+ }
+
+ @Override
+ public boolean onPreferenceClick(Preference preference) {
+
+ Fragment fragment;
+
+ switch (preference.getKey()){
+
+ case PREFERENCE_CATEGORY_ACCOUNT_IMAGE:
+ fragment = new AccountImageSettingsFragment();
+ break;
+
+ default:
+ throw new AssertionError();
+ }
+
+ if(getActivity() == null) return false;
+
+ FragmentTransaction transaction = getActivity()
+ .getSupportFragmentManager().beginTransaction();
+ transaction.replace(android.R.id.content, fragment);
+ transaction.addToBackStack(null);
+ transaction.commit();
+
+ return true;
+ }
+}
diff --git a/app/src/main/java/org/communiquons/android/comunic/client/ui/fragments/accountsettings/BaseAccountSettingsFragment.java b/app/src/main/java/org/communiquons/android/comunic/client/ui/fragments/accountsettings/BaseAccountSettingsFragment.java
new file mode 100644
index 0000000..b9d55f1
--- /dev/null
+++ b/app/src/main/java/org/communiquons/android/comunic/client/ui/fragments/accountsettings/BaseAccountSettingsFragment.java
@@ -0,0 +1,32 @@
+package org.communiquons.android.comunic.client.ui.fragments.accountsettings;
+
+import android.app.AlertDialog;
+import android.support.v7.preference.PreferenceFragmentCompat;
+
+import org.communiquons.android.comunic.client.ui.utils.UiUtils;
+
+/**
+ * Base account settings fragment
+ */
+public abstract class BaseAccountSettingsFragment extends PreferenceFragmentCompat {
+
+ //Loading dialog
+ private AlertDialog mLoadingDialog;
+
+ /**
+ * Remove any currently visible loading dialog
+ */
+ protected void removeLoadingDialog(){
+ if(mLoadingDialog != null)
+ mLoadingDialog.dismiss();
+ }
+
+ /**
+ * Show (display) a new loading dialog
+ */
+ protected void showLoadingDialog(){
+ removeLoadingDialog();
+ mLoadingDialog = UiUtils.create_loading_dialog(getActivity());
+ }
+
+}
diff --git a/app/src/main/java/org/communiquons/android/comunic/client/ui/preference/AccountImagePreference.java b/app/src/main/java/org/communiquons/android/comunic/client/ui/preference/AccountImagePreference.java
new file mode 100644
index 0000000..0b2e271
--- /dev/null
+++ b/app/src/main/java/org/communiquons/android/comunic/client/ui/preference/AccountImagePreference.java
@@ -0,0 +1,60 @@
+package org.communiquons.android.comunic.client.ui.preference;
+
+import android.content.Context;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceViewHolder;
+import android.util.AttributeSet;
+
+import org.communiquons.android.comunic.client.R;
+import org.communiquons.android.comunic.client.ui.views.WebUserAccountImage;
+
+/**
+ * Account image preference
+ */
+public class AccountImagePreference extends Preference {
+
+ private String image_url;
+ private WebUserAccountImage mWebUserAccountImage;
+
+ public AccountImagePreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+ super(context, attrs, defStyleAttr, defStyleRes);
+ initialize();
+ }
+
+ public AccountImagePreference(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ initialize();
+ }
+
+ public AccountImagePreference(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ initialize();
+ }
+
+ public AccountImagePreference(Context context) {
+ super(context);
+ initialize();
+ }
+
+ private void initialize(){
+ setLayoutResource(R.layout.preference_account_image);
+ }
+
+ @Override
+ public void onBindViewHolder(PreferenceViewHolder holder) {
+ super.onBindViewHolder(holder);
+
+ mWebUserAccountImage = (WebUserAccountImage) holder.findViewById(R.id.account_image);
+ refresh();
+ }
+
+ public void setImage_url(String image_url) {
+ this.image_url = image_url;
+ refresh();
+ }
+
+ public void refresh(){
+ if(mWebUserAccountImage != null && image_url != null)
+ mWebUserAccountImage.loadURL(image_url);
+ }
+}
diff --git a/app/src/main/res/drawable/ic_account_circle.xml b/app/src/main/res/drawable/ic_account_circle.xml
new file mode 100644
index 0000000..2274c5b
--- /dev/null
+++ b/app/src/main/res/drawable/ic_account_circle.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/layout/preference_account_image.xml b/app/src/main/res/layout/preference_account_image.xml
new file mode 100644
index 0000000..bf04b2d
--- /dev/null
+++ b/app/src/main/res/layout/preference_account_image.xml
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/menu/main_menu.xml b/app/src/main/res/menu/main_menu.xml
index 26aeabd..8a762e6 100644
--- a/app/src/main/res/menu/main_menu.xml
+++ b/app/src/main/res/menu/main_menu.xml
@@ -5,23 +5,28 @@
+ android:title="@string/main_menu_search_user" />
+
+
+
+ android:title="@string/action_settings" />
+ android:title="@string/action_about" />
+ android:title="@string/main_menu_logout"
+ app:showAsAction="never" />
\ 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 4d68403..bcca5d5 100644
--- a/app/src/main/res/values-fr/strings.xml
+++ b/app/src/main/res/values-fr/strings.xml
@@ -270,4 +270,18 @@
Il n\'y a aucun post à afficher ici pour le moment.
Visiblité du post
Une erreur a survenue lors de la récupération d\'information sur les groupes liés !
+ Paramètres du compte
+ Paramètres du compte
+ Image du compte
+ Mettre à jour votre image de compte et sa visibilité
+ Mettre à jour votre image de compte
+ Touchez ici pour mettre une nouvelle image de compte en ligne
+ Une erreur a survenue lors de la récupération des paramètres d\'image de compte !
+ Supprimer votre image de compte
+ Suppression de l\'image de compte
+ Voulez vous vraiment supprimer votre image de compte ? Cette opération est irréversible !
+ Annuler
+ Supprimer
+ Une erreur a survenu lors de la suppression de votre image de compte !
+ Une erreur a survenu lors de la mise en ligne de votre nouvelle image de compte !
\ 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 a151bbe..e03335d 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -269,4 +269,18 @@
There is no post to display here yet.
Post visibility
Could not get information about related groups!
+ Account Settings
+ Account settings
+ Account image
+ Update your account image and its visibility
+ Update account image
+ Click here to upload a new account image
+ Could not get account image settings!
+ Delete account image
+ Delete account image
+ Are you sure to do this? This operation can not be recovered!
+ Cancel
+ Delete
+ Could not delete your account image!
+ Could not upload new account image!
diff --git a/app/src/main/res/xml/account_preference_image.xml b/app/src/main/res/xml/account_preference_image.xml
new file mode 100644
index 0000000..eac7b0a
--- /dev/null
+++ b/app/src/main/res/xml/account_preference_image.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/xml/account_preference_main.xml b/app/src/main/res/xml/account_preference_main.xml
new file mode 100644
index 0000000..87b7bed
--- /dev/null
+++ b/app/src/main/res/xml/account_preference_main.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
\ No newline at end of file