aboutsummaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/src/main/java/ml/docilealligator/infinityforreddit/activities/CustomThemeListingActivity.java9
-rw-r--r--app/src/main/java/ml/docilealligator/infinityforreddit/customtheme/CustomTheme.java92
2 files changed, 94 insertions, 7 deletions
diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/CustomThemeListingActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/CustomThemeListingActivity.java
index c2dc2afa..c47023e5 100644
--- a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/CustomThemeListingActivity.java
+++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/CustomThemeListingActivity.java
@@ -1,7 +1,5 @@
package ml.docilealligator.infinityforreddit.activities;
-import static android.content.ClipDescription.MIMETYPE_TEXT_PLAIN;
-
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
@@ -27,8 +25,7 @@ import com.google.android.material.appbar.CollapsingToolbarLayout;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.android.material.snackbar.Snackbar;
-import com.google.gson.Gson;
-import com.google.gson.JsonSyntaxException;
+import com.google.gson.JsonParseException;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
@@ -272,9 +269,9 @@ public class CustomThemeListingActivity extends BaseActivity implements
String json = item.coerceToText(this.getApplicationContext()).toString();
if (!TextUtils.isEmpty(json)) {
try {
- CustomTheme customTheme = new Gson().fromJson(json, CustomTheme.class);
+ CustomTheme customTheme = CustomTheme.fromJson(json);
checkDuplicateAndImportTheme(customTheme, true);
- } catch (JsonSyntaxException e) {
+ } catch (JsonParseException e) {
Snackbar.make(coordinatorLayout, R.string.parse_theme_failed, Snackbar.LENGTH_SHORT).show();
}
} else {
diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/customtheme/CustomTheme.java b/app/src/main/java/ml/docilealligator/infinityforreddit/customtheme/CustomTheme.java
index 54c33e93..7acff53b 100644
--- a/app/src/main/java/ml/docilealligator/infinityforreddit/customtheme/CustomTheme.java
+++ b/app/src/main/java/ml/docilealligator/infinityforreddit/customtheme/CustomTheme.java
@@ -1,13 +1,26 @@
package ml.docilealligator.infinityforreddit.customtheme;
+import android.graphics.Color;
+
import androidx.annotation.NonNull;
import androidx.room.ColumnInfo;
import androidx.room.Entity;
import androidx.room.PrimaryKey;
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.JsonSerializationContext;
+import com.google.gson.JsonSerializer;
+import java.lang.reflect.Field;
+import java.lang.reflect.Type;
import java.util.ArrayList;
+import java.util.Map;
@Entity(tableName = "custom_themes")
public class CustomTheme {
@@ -197,10 +210,22 @@ public class CustomTheme {
}
public String getJSONModel() {
- Gson gson = new Gson();
+ Gson gson = getGsonBuilder().create();
return gson.toJson(this);
}
+ private static GsonBuilder getGsonBuilder() {
+ GsonBuilder builder = new GsonBuilder();
+ builder.registerTypeAdapter(CustomTheme.class, new CustomThemeSerializer());
+ builder.registerTypeAdapter(CustomTheme.class, new CustomThemeDeserializer());
+ return builder;
+ }
+
+ public static CustomTheme fromJson(String json) throws JsonParseException {
+ Gson gson = getGsonBuilder().create();
+ return gson.fromJson(json, CustomTheme.class);
+ }
+
public static CustomTheme convertSettingsItemsToCustomTheme(ArrayList<CustomThemeSettingsItem> customThemeSettingsItems, String themeName) {
CustomTheme customTheme = new CustomTheme(themeName);
@@ -298,4 +323,69 @@ public class CustomTheme {
return customTheme;
}
+
+ private static class CustomThemeSerializer implements JsonSerializer<CustomTheme> {
+ @Override
+ public JsonElement serialize(CustomTheme src, Type typeofSrc, JsonSerializationContext context) {
+ JsonObject obj = new JsonObject();
+
+ for (Field field : src.getClass().getDeclaredFields()) {
+ try {
+ if (field.getType() == int.class) {
+ obj.addProperty(field.getName(), String.format("#%08X", field.getInt(src)));
+ } else {
+ obj.add(field.getName(), context.serialize(field.get(src)));
+ }
+ } catch (IllegalAccessException ignored) {
+ }
+ }
+ return obj;
+ }
+ }
+
+ private static class CustomThemeDeserializer implements JsonDeserializer<CustomTheme> {
+ @Override
+ public CustomTheme deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
+ CustomTheme customTheme = new CustomTheme();
+
+ JsonObject obj = json.getAsJsonObject();
+
+ for (Map.Entry<String, JsonElement> entry : obj.entrySet()) {
+
+ Field field;
+ try {
+ field = customTheme.getClass().getDeclaredField(entry.getKey());
+ } catch (NoSuchFieldException e) {
+ // Field not found, skip
+ continue;
+ }
+
+ JsonElement value = entry.getValue();
+
+ try {
+ Class<?> type = field.getType();
+ if (int.class.equals(type)) {
+ if (value.getAsJsonPrimitive().isString()) {
+ // Hex or text color string
+ field.set(customTheme, Color.parseColor(value.getAsString()));
+ } else {
+ // Int color
+ field.set(customTheme, value.getAsInt());
+ }
+ } else if (String.class.equals(type)) {
+ field.set(customTheme, value.getAsString());
+ } else if (boolean.class.equals(type)) {
+ field.set(customTheme, value.getAsBoolean());
+ }
+
+ } catch (IllegalAccessException e) {
+ throw new JsonParseException("Failed to access theme field.");
+ } catch (IllegalArgumentException e) {
+ throw new JsonParseException("Invalid color string.");
+ }
+
+ }
+ return customTheme;
+ }
+ }
}