diff --git a/Habitica/res/layout/avatar_overview_card.xml b/Habitica/res/layout/avatar_overview_card.xml
index 4ce643550..6961f16c1 100644
--- a/Habitica/res/layout/avatar_overview_card.xml
+++ b/Habitica/res/layout/avatar_overview_card.xml
@@ -8,13 +8,15 @@
-
+ android:layout_height="wrap_content"
+ android:minHeight="60dp"
+ android:padding="5dp"
+ android:paddingTop="8dp"
+ android:paddingBottom="8dp"
+ android:clickable="true"
+ android:background="@drawable/btn_habit_background">
-
-
\ No newline at end of file
diff --git a/Habitica/res/layout/customization_grid_item.xml b/Habitica/res/layout/customization_grid_item.xml
new file mode 100644
index 000000000..f313afe72
--- /dev/null
+++ b/Habitica/res/layout/customization_grid_item.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Habitica/res/layout/customization_section_header.xml b/Habitica/res/layout/customization_section_header.xml
new file mode 100644
index 000000000..3e52c9937
--- /dev/null
+++ b/Habitica/res/layout/customization_section_header.xml
@@ -0,0 +1,11 @@
+
+
+
+
\ No newline at end of file
diff --git a/Habitica/res/layout/fragment_avatar_overview.xml b/Habitica/res/layout/fragment_avatar_overview.xml
index 741a53c64..f9ebf8b64 100644
--- a/Habitica/res/layout/fragment_avatar_overview.xml
+++ b/Habitica/res/layout/fragment_avatar_overview.xml
@@ -35,45 +35,60 @@
+ android:layout_margin="@dimen/card_horizontal_padding">
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
-
-
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Habitica/res/values/dimens.xml b/Habitica/res/values/dimens.xml
index 65bdf545f..5b62c8cbd 100644
--- a/Habitica/res/values/dimens.xml
+++ b/Habitica/res/values/dimens.xml
@@ -49,4 +49,5 @@
350dp
20dp
8dp
+ 6dp
\ No newline at end of file
diff --git a/Habitica/src/com/habitrpg/android/habitica/APIHelper.java b/Habitica/src/com/habitrpg/android/habitica/APIHelper.java
index 29c1eee2a..6a00128d5 100644
--- a/Habitica/src/com/habitrpg/android/habitica/APIHelper.java
+++ b/Habitica/src/com/habitrpg/android/habitica/APIHelper.java
@@ -9,6 +9,11 @@ import com.google.gson.ExclusionStrategy;
import com.google.gson.FieldAttributes;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
+import com.google.gson.JsonDeserializationContext;
+import com.google.gson.JsonDeserializer;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParseException;
import com.google.gson.TypeAdapter;
import com.google.gson.reflect.TypeToken;
import com.google.gson.stream.JsonReader;
@@ -21,6 +26,7 @@ import com.magicmicky.habitrpgwrapper.lib.api.ApiService;
import com.magicmicky.habitrpgwrapper.lib.api.InAppPurchasesApiService;
import com.magicmicky.habitrpgwrapper.lib.api.Server;
import com.magicmicky.habitrpgwrapper.lib.api.TypeAdapter.TagsAdapter;
+import com.magicmicky.habitrpgwrapper.lib.models.HabitRPGUser;
import com.magicmicky.habitrpgwrapper.lib.models.PurchaseValidationRequest;
import com.magicmicky.habitrpgwrapper.lib.models.PurchaseValidationResult;
import com.magicmicky.habitrpgwrapper.lib.models.SkillList;
@@ -47,6 +53,7 @@ import retrofit.Profiler;
import retrofit.RequestInterceptor;
import retrofit.RestAdapter;
import retrofit.RetrofitError;
+import retrofit.converter.ConversionException;
import retrofit.converter.GsonConverter;
@@ -209,6 +216,10 @@ public class APIHelper implements ErrorHandler, Profiler {
public String err;
}
+ public class ErrorListResponse {
+ public List err;
+ }
+
@Override
public Throwable handleError(RetrofitError cause) {
@@ -219,17 +230,24 @@ public class APIHelper implements ErrorHandler, Profiler {
} else if (cause.getKind().equals(RetrofitError.Kind.HTTP)) {
retrofit.client.Response response = cause.getResponse();
- ErrorResponse res = (ErrorResponse) cause.getBodyAs(ErrorResponse.class) ;
+ ErrorResponse res = null;
+
+ try {
+ res = (ErrorResponse) cause.getBodyAs(ErrorResponse.class) ;
+ } catch (RuntimeException e) {
+ //Can cause errors when error is a list and not a string
+ ErrorListResponse resList = (ErrorListResponse) cause.getBodyAs(ErrorListResponse.class);
+ if (resList.err != null && resList.err.size() >= 1) {
+ res = new ErrorResponse();
+ res.err = resList.err.get(0);
+ }
+ }
int status = response.getStatus();
if (status == 401) {
-
- if(res.err != null && !res.err.isEmpty())
- {
+ if(res != null && res.err != null && !res.err.isEmpty()) {
showConnectionProblemDialog("", res.err);
- }
- else
- {
+ } else {
showConnectionProblemDialog(R.string.authentication_error_title, R.string.authentication_error_body);
}
diff --git a/Habitica/src/com/habitrpg/android/habitica/HabitDatabase.java b/Habitica/src/com/habitrpg/android/habitica/HabitDatabase.java
index 728160b99..33b50c174 100644
--- a/Habitica/src/com/habitrpg/android/habitica/HabitDatabase.java
+++ b/Habitica/src/com/habitrpg/android/habitica/HabitDatabase.java
@@ -10,5 +10,5 @@ public class HabitDatabase {
public static final String NAME = "Habitica";
- public static final int VERSION = 5;
+ public static final int VERSION = 6;
}
diff --git a/Habitica/src/com/habitrpg/android/habitica/events/commands/UpdateUserCommand.java b/Habitica/src/com/habitrpg/android/habitica/events/commands/UpdateUserCommand.java
new file mode 100644
index 000000000..8167c6855
--- /dev/null
+++ b/Habitica/src/com/habitrpg/android/habitica/events/commands/UpdateUserCommand.java
@@ -0,0 +1,12 @@
+package com.habitrpg.android.habitica.events.commands;
+
+import java.util.Map;
+
+/**
+ * Created by viirus on 13/01/16.
+ */
+public class UpdateUserCommand {
+
+ public Map updateData;
+
+}
diff --git a/Habitica/src/com/habitrpg/android/habitica/ui/activities/MainActivity.java b/Habitica/src/com/habitrpg/android/habitica/ui/activities/MainActivity.java
index 640453c60..eb6c69d08 100644
--- a/Habitica/src/com/habitrpg/android/habitica/ui/activities/MainActivity.java
+++ b/Habitica/src/com/habitrpg/android/habitica/ui/activities/MainActivity.java
@@ -37,6 +37,7 @@ import com.habitrpg.android.habitica.events.ToggledInnStateEvent;
import com.habitrpg.android.habitica.events.commands.BuyRewardCommand;
import com.habitrpg.android.habitica.events.commands.DeleteTaskCommand;
import com.habitrpg.android.habitica.events.commands.OpenGemPurchaseFragmentCommand;
+import com.habitrpg.android.habitica.events.commands.UpdateUserCommand;
import com.habitrpg.android.habitica.ui.AvatarWithBarsViewModel;
import com.habitrpg.android.habitica.ui.MainDrawerBuilder;
import com.habitrpg.android.habitica.ui.UiUtils;
@@ -461,6 +462,10 @@ public class MainActivity extends BaseActivity implements HabitRPGUserCallback.O
avatarInHeader.updateData(user);
}
+ public void onEvent(UpdateUserCommand event) {
+ mAPIHelper.apiService.updateUser(event.updateData, new HabitRPGUserCallback(this));
+ }
+
public void onEvent(final BuyRewardCommand event) {
final String rewardKey = event.Reward.getId();
diff --git a/Habitica/src/com/habitrpg/android/habitica/ui/adapter/CustomizationRecyclerViewAdapter.java b/Habitica/src/com/habitrpg/android/habitica/ui/adapter/CustomizationRecyclerViewAdapter.java
new file mode 100644
index 000000000..5bbd95e5f
--- /dev/null
+++ b/Habitica/src/com/habitrpg/android/habitica/ui/adapter/CustomizationRecyclerViewAdapter.java
@@ -0,0 +1,172 @@
+package com.habitrpg.android.habitica.ui.adapter;
+
+import android.content.res.Resources;
+import android.support.v7.widget.CardView;
+import android.support.v7.widget.RecyclerView;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import com.habitrpg.android.habitica.R;
+import com.habitrpg.android.habitica.events.commands.UpdateUserCommand;
+import com.habitrpg.android.habitica.ui.helpers.DataBindingUtils;
+import com.magicmicky.habitrpgwrapper.lib.models.Customization;
+import com.raizlabs.android.dbflow.sql.language.Update;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import butterknife.Bind;
+import butterknife.ButterKnife;
+import de.greenrobot.event.EventBus;
+
+/**
+ * Created by viirus on 13/01/16.
+ */
+public class CustomizationRecyclerViewAdapter extends RecyclerView.Adapter {
+
+ private List