From ec5751ba10c2788c80253912629d583a8cf46b69 Mon Sep 17 00:00:00 2001 From: Phillip Thelen Date: Fri, 5 Apr 2019 09:36:32 +0200 Subject: [PATCH] Improve deserialization speeds --- Habitica/AndroidManifest.xml | 6 +- Habitica/build.gradle | 2 +- Habitica/res/values-bg/strings.xml | 8 +- Habitica/res/values-de/strings.xml | 8 +- Habitica/res/values-en-rGB/strings.xml | 6 +- Habitica/res/values-es/strings.xml | 8 +- Habitica/res/values-fr/strings.xml | 8 +- Habitica/res/values-hr-rHR/strings.xml | 8 +- Habitica/res/values-in/strings.xml | 6 +- Habitica/res/values-it/strings.xml | 8 +- Habitica/res/values-iw/strings.xml | 6 +- Habitica/res/values-ja/strings.xml | 8 +- Habitica/res/values-ko/strings.xml | 6 +- Habitica/res/values-lt/strings.xml | 6 +- Habitica/res/values-nl/strings.xml | 8 +- Habitica/res/values-pl/strings.xml | 6 +- Habitica/res/values-pt-rBR/strings.xml | 8 +- Habitica/res/values-pt-rPT/strings.xml | 6 +- Habitica/res/values-ru/strings.xml | 8 +- Habitica/res/values-tr/strings.xml | 8 +- Habitica/res/values-zh-rTW/strings.xml | 8 +- Habitica/res/values-zh/strings.xml | 8 +- Habitica/res/values/strings.xml | 8 +- Habitica/res/xml/network_security_config.xml | 8 + Habitica/res/xml/remote_config_defaults.xml | 4 + .../habitica/api/GSonFactoryCreator.java | 6 +- .../android/habitica/data/UserRepository.kt | 1 + .../implementation/ContentRepositoryImpl.kt | 2 +- .../implementation/InventoryRepositoryImpl.kt | 27 ++- .../data/implementation/UserRepositoryImpl.kt | 31 +++- .../RealmInventoryLocalRepository.kt | 24 +-- .../extensions/JsonObject-Extensions.kt | 11 ++ .../habitica/helpers/RemoteConfigManager.kt | 14 +- .../habitica/models/inventory/Animal.java | 21 +-- .../models/inventory/Customization.java | 3 + .../habitica/models/inventory/Mount.java | 54 +++--- .../habitica/models/inventory/Pet.java | 54 +++--- .../habitica/modules/RepositoryModule.java | 10 +- .../habitica/ui/activities/MainActivity.kt | 37 ++-- .../inventory/MountDetailRecyclerAdapter.kt | 2 +- .../inventory/PetDetailRecyclerAdapter.kt | 2 +- .../inventory/StableRecyclerAdapter.kt | 2 +- .../AvatarCustomizationFragment.kt | 6 +- .../inventory/items/ItemRecyclerFragment.kt | 2 +- .../stable/StableRecyclerFragment.kt | 11 +- .../habitica/ui/helpers/KeyboardUtil.kt | 12 +- .../habitica/utils/ContentDeserializer.java | 154 ---------------- .../habitica/utils/ContentDeserializer.kt | 108 +++++++++++ .../habitica/utils/SkillDeserializer.java | 2 +- .../utils/TaskGroupPlanDeserializer.java | 25 --- .../habitica/utils/TaskListDeserializer.java | 66 ------- .../habitica/utils/TaskListDeserializer.kt | 172 ++++++++++++++++++ .../habitica/utils/UserDeserializer.kt | 6 +- 53 files changed, 554 insertions(+), 485 deletions(-) create mode 100644 Habitica/res/xml/network_security_config.xml create mode 100644 Habitica/src/main/java/com/habitrpg/android/habitica/extensions/JsonObject-Extensions.kt delete mode 100644 Habitica/src/main/java/com/habitrpg/android/habitica/utils/ContentDeserializer.java create mode 100644 Habitica/src/main/java/com/habitrpg/android/habitica/utils/ContentDeserializer.kt delete mode 100644 Habitica/src/main/java/com/habitrpg/android/habitica/utils/TaskGroupPlanDeserializer.java delete mode 100644 Habitica/src/main/java/com/habitrpg/android/habitica/utils/TaskListDeserializer.java create mode 100644 Habitica/src/main/java/com/habitrpg/android/habitica/utils/TaskListDeserializer.kt diff --git a/Habitica/AndroidManifest.xml b/Habitica/AndroidManifest.xml index 5aa83f69e..4ea1120c8 100644 --- a/Habitica/AndroidManifest.xml +++ b/Habitica/AndroidManifest.xml @@ -25,7 +25,11 @@ android:label="@string/app_name" android:theme="@style/AppTheme" tools:replace="android:name" - android:fullBackupContent="@xml/backup_descriptor"> + android:fullBackupContent="@xml/backup_descriptor" + android:networkSecurityConfig="@xml/network_security_config"> + Даване на любимец Излюпване с яйце Поканване на групата - Хранене на %1$s %2$s с: + Хранене на %s с: Използване Хранене Излюпване на любимец с %s - Вие излюпихте %1$s %2$s! - Вие опитомихте %1$s %2$s. Да се качваме! + Вие излюпихте %s! + Вие опитомихте %s. Да се качваме! Затваряне Споделяне - Вие нахранихте своя(та/то) %1$s %2$s! + Вие нахранихте своя(та/то) %s! Вие закупихте %s Вие закупихте награда Обикновени diff --git a/Habitica/res/values-de/strings.xml b/Habitica/res/values-de/strings.xml index d471432bb..2b9c042c4 100644 --- a/Habitica/res/values-de/strings.xml +++ b/Habitica/res/values-de/strings.xml @@ -296,15 +296,15 @@ An Haustier verfüttern Mit Ei ausbrüten Party einladen - Füttere %1$s %2$s mit: + Füttere %s mit: Nutzen Füttern Haustier mit %s ausbrüten - Du hast ein %1$s %2$s ausgebrütet! - Du hast %1$s%2$s gezähmt, auf geht\'s! + Du hast ein %s ausgebrütet! + Du hast %s gezähmt, auf geht\'s! Schließen Teilen - Du hast Dein/e/n %1$s %2$s gefüttert! + Du hast Dein/e/n %s gefüttert! Du hast %s gekauft Du hast eine Belohnung gekauft Standard diff --git a/Habitica/res/values-en-rGB/strings.xml b/Habitica/res/values-en-rGB/strings.xml index cb5e90627..ca9dab2d3 100644 --- a/Habitica/res/values-en-rGB/strings.xml +++ b/Habitica/res/values-en-rGB/strings.xml @@ -285,14 +285,14 @@ Feed to pet Hatch with egg Invite party - Feed %1$s %2$s with: + Feed %s with: Use Feed Hatch pet with %s - You hatched a %1$s %2$s! + You hatched a %s! Close Share - You fed your %1$s %2$s! + You fed your %s! World Quest You don\'t have any %s Lvl %d diff --git a/Habitica/res/values-es/strings.xml b/Habitica/res/values-es/strings.xml index ce3f90202..46b607948 100644 --- a/Habitica/res/values-es/strings.xml +++ b/Habitica/res/values-es/strings.xml @@ -296,15 +296,15 @@ Alimentar a mascota Mezclar con huevo Invitar al grupo - Dar de comer a %2$s %1$s: + Dar de comer a %s: Usar Alimentar Criar mascota con %s - ¡Ha nacido un/a %2$s %1$s! - Has domado %1$s %2$s, ¡vamos a dar un paseo! + ¡Ha nacido un/a %s! + Has domado %s, ¡vamos a dar un paseo! Cerrar Compartir - ¡Tu %2$s %1$s ha comido! + ¡Tu %s ha comido! Has comprado %s Has obtenido una recompensa. Estandar diff --git a/Habitica/res/values-fr/strings.xml b/Habitica/res/values-fr/strings.xml index bd2296b28..eb4d0d1b2 100644 --- a/Habitica/res/values-fr/strings.xml +++ b/Habitica/res/values-fr/strings.xml @@ -296,15 +296,15 @@ Donner au familier Faire éclore avec l\'œuf Inviter l\'équipe - Nourrissez votre %1$s %2$s avec : + Nourrissez votre %s avec : Utiliser Nourrir Faire éclore le familier avec %s - Votre %1$s %2$s a éclos ! - Vous avez dompté %2$s%1$s, partez en promenade ensemble ! + Votre %s a éclos ! + Vous avez dompté %s, partez en promenade ensemble ! Fermer Partager - Vous avez nourri votre %1$s %2$s ! + Vous avez nourri votre %s ! Vous avez acheté %s Vous avez acheté une récompense Standard diff --git a/Habitica/res/values-hr-rHR/strings.xml b/Habitica/res/values-hr-rHR/strings.xml index 877d73802..79813a303 100644 --- a/Habitica/res/values-hr-rHR/strings.xml +++ b/Habitica/res/values-hr-rHR/strings.xml @@ -298,15 +298,15 @@ Nahrani ljubimca Izlegni s jajetom Pozovi družinu - Nahrani %1$s %2$s s: + Nahrani %s s: Koristi Nahrani Izlegni ljubimca s %s - %1$s %2$s se izlegao/la! - Pripitomio/la si %1$s %2$s, hajdemo jahati! + %s se izlegao/la! + Pripitomio/la si %s, hajdemo jahati! Zatvori Podijeli - Nahranio/la si svoju/ga %1$s %2$s! + Nahranio/la si svoju/ga %s! Kupio/la si %s Kupio/la si nagradu Standardni diff --git a/Habitica/res/values-in/strings.xml b/Habitica/res/values-in/strings.xml index 326bccd33..67a79d639 100644 --- a/Habitica/res/values-in/strings.xml +++ b/Habitica/res/values-in/strings.xml @@ -286,14 +286,14 @@ Beri makan peliharaan Tetaskan dengan telur Undang party - Beri makan %2$s %1$s dengan: + Beri makan %s dengan: Gunakan Beri makan Tetaskan dengan %s - Kamu menetaskan seekor %2$s %1$s! + Kamu menetaskan seekor %s Tutup Bagikan - Kamu memberi makan %2$s %1$s! + Kamu memberi makan %s! %s telah dibeli Kamu membeli sebuah hadiah Standard diff --git a/Habitica/res/values-it/strings.xml b/Habitica/res/values-it/strings.xml index 8b5212b9c..498404fbe 100644 --- a/Habitica/res/values-it/strings.xml +++ b/Habitica/res/values-it/strings.xml @@ -296,15 +296,15 @@ Dai ad animale Schiudi con uovo Invita squadra - Dai da mangiare a %1$s %2$s: + Dai da mangiare a %s: Usa Dai da mangiare Fai nascere un animale con %s - È nato un %2$s %1$s! - Hai domato %1$s%2$s, inizia a cavalcare! + È nato un %s! + Hai domato %s, inizia a cavalcare! Chiudi Condividi - Hai dato da mangiare al tuo %1$s %2$s! + Hai dato da mangiare al tuo %s! Hai comprato %s Hai comprato una ricompensa Base diff --git a/Habitica/res/values-iw/strings.xml b/Habitica/res/values-iw/strings.xml index 451ad9a15..970dc937f 100644 --- a/Habitica/res/values-iw/strings.xml +++ b/Habitica/res/values-iw/strings.xml @@ -244,14 +244,14 @@ האכילו חיית מחמד הבקיעו עם ביצה הזמינו חבורה - האכלתם %1$s %2$s עם: + האכלתם %s עם: השתמשו האכילו הבקיעו חיית מחמד עם %s - הבקעתם %1$s %2$s! + הבקעתם %1s! סיגרו שתפו - האכלתם את ה %1$s %2$s שלכם! + האכלתם את ה %s שלכם! הרפתקאה עולמית אין לכם כל %s דרגה %d diff --git a/Habitica/res/values-ja/strings.xml b/Habitica/res/values-ja/strings.xml index 93fefffb7..68da16656 100644 --- a/Habitica/res/values-ja/strings.xml +++ b/Habitica/res/values-ja/strings.xml @@ -297,15 +297,15 @@ ペットにえさをやる たまごをかえす パーティーに招待する - %1$s%2$s にえさをやる : + %s にえさをやる : 連れていく えさをやる %s でペットをかえす - %1$s%2$sが生まれた! - %1$s%2$sを手なずけた!さあ、乗ってみよう! + %sが生まれた! + %sを手なずけた!さあ、乗ってみよう! 閉じる 共有する - %1$s%2$sにえさをやった! + %sにえさをやった! %sを購入しました 報酬をを購入しました ふつうの diff --git a/Habitica/res/values-ko/strings.xml b/Habitica/res/values-ko/strings.xml index 2922008ff..94b3fb319 100644 --- a/Habitica/res/values-ko/strings.xml +++ b/Habitica/res/values-ko/strings.xml @@ -293,14 +293,14 @@ 펫 먹이주기 알 부화 파티에 초대 - %1$s %2$s 에게 다음의 먹이 주기: + %s 에게 다음의 먹이 주기: 사용 먹이주기 %s 으로 펫 부화 - 당신은 %1$s %2$s 를 부화시켰습니다! + 당신은 %s 를 부화시켰습니다! 닫기 나누기 - %1$s %2$s 에게 먹이를 줬습니다! + %s 에게 먹이를 줬습니다! %s 를 구매했습니다 보상을 구매했습니다 기본 펫 diff --git a/Habitica/res/values-lt/strings.xml b/Habitica/res/values-lt/strings.xml index 1917b92b6..5978c46db 100644 --- a/Habitica/res/values-lt/strings.xml +++ b/Habitica/res/values-lt/strings.xml @@ -251,14 +251,14 @@ Maitinti gyvūnui Išperėti kiaušinį Pakviesti grupę - Pašerti %1$s %2$s su: + Pašerti %s su: Naudoti Maitinti Užauginti gyvūną su %s - Užauginai %1$s %2$s! + Užauginai %s! Uždaryti Dalintis - Pašėrei savo %1$s %2$s! + Pašėrei savo %s! Pasaulinė Misija Nebeturi %s Karys diff --git a/Habitica/res/values-nl/strings.xml b/Habitica/res/values-nl/strings.xml index a019856a3..d1d9b1a66 100644 --- a/Habitica/res/values-nl/strings.xml +++ b/Habitica/res/values-nl/strings.xml @@ -296,15 +296,15 @@ Aan huisdier voederen Laten uitkomen met ei Nodig groep uit - Voeder %1$s %2$s met: + Voeder %s met: Gebruik Voeder Laat huisdier uitkomen met %s - Je hebt een %1$s %2$s laten uitkomen! - Je hebt %1$s%2$s afgericht, laten we een ridje maken! + Je hebt een %s laten uitkomen! + Je hebt %s afgericht, laten we een ridje maken! Sluiten Delen - Je hebt je %1$s %2$s gevoederd! + Je hebt je %s gevoederd! Je hebt %s gekocht Je hebt een beloning gekocht Standaard diff --git a/Habitica/res/values-pl/strings.xml b/Habitica/res/values-pl/strings.xml index 75241bd34..53547d747 100644 --- a/Habitica/res/values-pl/strings.xml +++ b/Habitica/res/values-pl/strings.xml @@ -288,14 +288,14 @@ Nakarm chowańca Wykluj za pomocą jaja Zaproś drużynę - Nakarm %1$s %2$s + Nakarm %s Użyj Nakarm Wykluj za pomocą %s - Wyklułeś/as %1$s %2$s! + Wyklułeś/as %s! Zamknij Podziel się - Nakarmiłeś/aś %1$s %2$s! + Nakarmiłeś/aś %s! Kupiłeś %s Kupiłeś nagrodę Standardowe diff --git a/Habitica/res/values-pt-rBR/strings.xml b/Habitica/res/values-pt-rBR/strings.xml index 6b7f0a0f9..f859749b5 100644 --- a/Habitica/res/values-pt-rBR/strings.xml +++ b/Habitica/res/values-pt-rBR/strings.xml @@ -296,15 +296,15 @@ Alimentar mascote Chocar com ovo Convidar Grupo - Alimentar %1$s %2$s com: + Alimentar %s com: Usar Alimentar Chocar mascote com %s - Você chocou um %1$s %2$s! - Você domou %1$s %2$s, vamos dar um passeio ! + Você chocou um %s! + Você domou %s, vamos dar um passeio ! Fechar Compartilhar - Você alimentou seu %1$s %2$s! + Você alimentou seu %s! Você comprou %s Você comprou uma recompensa Base diff --git a/Habitica/res/values-pt-rPT/strings.xml b/Habitica/res/values-pt-rPT/strings.xml index b6248feb4..1bcb117fb 100644 --- a/Habitica/res/values-pt-rPT/strings.xml +++ b/Habitica/res/values-pt-rPT/strings.xml @@ -279,14 +279,14 @@ Alimento para o animal Nascimento com ovo Convidar a equipa - Alimente %1$s %2$s com: + Alimente %s com: Usar Alimentar Nascimento do animal com %s - Chocou um %1$s %2$s! + Chocou um %s! Fechar Partilhar - Alimentou o seu %1$s %2$s! + Alimentou o seu %s! Comprou %s Comprou uma recompensa Padrão diff --git a/Habitica/res/values-ru/strings.xml b/Habitica/res/values-ru/strings.xml index 94f89d624..5b0122673 100644 --- a/Habitica/res/values-ru/strings.xml +++ b/Habitica/res/values-ru/strings.xml @@ -294,15 +294,15 @@ Покормить питомца Вывести питомца из яйца Пригласить команду - Покормить %1$s %2$s: + Покормить %s: Использовать Покормить Вылупить питомца с помощью %s - У вас вылупился %1$s %2$s! - Вы приручили %1$s%2$s, пора покататься! + У вас вылупился %s! + "Вы приручили %s, пора покататься! " Закрыть Поделиться - Вы покормили вашего %1$s %2$s! + Вы покормили вашего %s! Вы купили %s Вы купили награду Обычные diff --git a/Habitica/res/values-tr/strings.xml b/Habitica/res/values-tr/strings.xml index 8a400d05f..a6821918d 100644 --- a/Habitica/res/values-tr/strings.xml +++ b/Habitica/res/values-tr/strings.xml @@ -296,15 +296,15 @@ Evcil hayvana besle Yumurta ile üret Takımı davet et - %1$s %2$s besle: + %s besle: Kullan Besle Evcil hayvanı %s ile üret - %1$s %2$s ürettin! - Bir %1$s %2$s ehlileştirdin. + %s ürettin! + Bir %s ehlileştirdin. Kapat Paylaş - %1$s %2$s besledin! + %s besledin! %s satın aldın Bir ödül satın aldın Standart diff --git a/Habitica/res/values-zh-rTW/strings.xml b/Habitica/res/values-zh-rTW/strings.xml index ba3c076dd..a75c17098 100644 --- a/Habitica/res/values-zh-rTW/strings.xml +++ b/Habitica/res/values-zh-rTW/strings.xml @@ -294,15 +294,15 @@ 餵食寵物 孵化寵物蛋 隊伍邀請 - 餵養%1$s %2$s用: + 餵養%s用: 用 %s 孵化寵物 - 你孵化了一隻 %1$s %2$s! - 你馴服了%1$s%2$s,讓我們騎上牠吧! + 你孵化了一隻 %s! + 你馴服了%s,讓我們騎上牠吧! 關閉 分享 - 你餵食了你的%1$s %2$s! + 你餵食了你的%s! 你購買了%s 你購買了一個獎勵 基本寵物 diff --git a/Habitica/res/values-zh/strings.xml b/Habitica/res/values-zh/strings.xml index c893be01a..2d4dcc1ee 100644 --- a/Habitica/res/values-zh/strings.xml +++ b/Habitica/res/values-zh/strings.xml @@ -298,15 +298,15 @@ 喂养宠物 孵化宠物蛋 邀请队伍 - 喂养%1$s %2$s用: + 喂养%s用: 使用 喂食 用%s孵化宠物 - 你孵化了一个 %1$s %2$s! - 您驯服了%1$s%2$s,我们去骑一圈吧! + 你孵化了一个 %s! + 您驯服了%s,我们去骑一圈吧! 关闭 分享 - 你喂食了你的%1$s %2$s! + 你喂食了你的%s! 你购买了%s 你购买了一个奖励 基本宠物 diff --git a/Habitica/res/values/strings.xml b/Habitica/res/values/strings.xml index 447d9eca8..e22b5f646 100644 --- a/Habitica/res/values/strings.xml +++ b/Habitica/res/values/strings.xml @@ -326,15 +326,15 @@ Feed to pet Hatch with egg Invite party - Feed %1$s %2$s with: + Feed %s with: Use Feed Hatch pet with %s - You hatched a %1$s %2$s! - You have tamed %1$s %2$s, let\'s go for a ride! + You hatched a %s! + You have tamed %s, let\'s go for a ride! Close Share - You fed your %1$s %2$s! + You fed your %s! You purchased %s You purchased a reward Standard diff --git a/Habitica/res/xml/network_security_config.xml b/Habitica/res/xml/network_security_config.xml new file mode 100644 index 000000000..bd229b92f --- /dev/null +++ b/Habitica/res/xml/network_security_config.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/Habitica/res/xml/remote_config_defaults.xml b/Habitica/res/xml/remote_config_defaults.xml index 15d4faa95..120b9771c 100644 --- a/Habitica/res/xml/remote_config_defaults.xml +++ b/Habitica/res/xml/remote_config_defaults.xml @@ -20,5 +20,9 @@ enableUsernameAutocomplete false + + enableLocalChanges + true + \ No newline at end of file diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/api/GSonFactoryCreator.java b/Habitica/src/main/java/com/habitrpg/android/habitica/api/GSonFactoryCreator.java index 2d01c1960..ac798f708 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/api/GSonFactoryCreator.java +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/api/GSonFactoryCreator.java @@ -57,11 +57,10 @@ import com.habitrpg.android.habitica.utils.QuestDeserializer; import com.habitrpg.android.habitica.utils.QuestDropItemsListSerialization; import com.habitrpg.android.habitica.utils.QuestListDeserializer; import com.habitrpg.android.habitica.utils.SkillDeserializer; -import com.habitrpg.android.habitica.utils.TaskDeserializer; import com.habitrpg.android.habitica.utils.TaskListDeserializer; import com.habitrpg.android.habitica.utils.TaskSerializer; -import com.habitrpg.android.habitica.utils.TaskTagDeserializer; import com.habitrpg.android.habitica.utils.TutorialStepListDeserializer; +import com.habitrpg.android.habitica.utils.TaskTagDeserializer; import com.habitrpg.android.habitica.utils.UserDeserializer; import com.habitrpg.android.habitica.utils.WorldStateSerialization; @@ -76,8 +75,8 @@ import retrofit2.converter.gson.GsonConverterFactory; public class GSonFactoryCreator { public static GsonConverterFactory create() { - Type taskTagClassListType = new TypeToken>() {}.getType(); Type skillListType = new TypeToken>() {}.getType(); + Type taskTagClassListType = new TypeToken>() {}.getType(); Type customizationListType = new TypeToken>() {}.getType(); Type tutorialStepListType = new TypeToken>() {}.getType(); Type faqArticleListType = new TypeToken>() {}.getType(); @@ -133,7 +132,6 @@ public class GSonFactoryCreator { .registerTypeAdapter(Member.class, new MemberSerialization()) .registerTypeAdapter(WorldState.class, new WorldStateSerialization()) .registerTypeAdapter(FindUsernameResult.class, new FindUsernameResultDeserializer()) - //.registerTypeAdapter(Task.class, new TaskDeserializer()) .setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'") .create(); return GsonConverterFactory.create(gson); diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/UserRepository.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/data/UserRepository.kt index fc513edee..209c176ee 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/UserRepository.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/UserRepository.kt @@ -69,4 +69,5 @@ interface UserRepository : BaseRepository { fun allocatePoint(user: User?, stat: String): Flowable fun bulkAllocatePoints(user: User?, strength: Int, intelligence: Int, constitution: Int, perception: Int): Flowable + fun useCustomization(user: User?, type: String, category: String?, identifier: String): Flowable } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/ContentRepositoryImpl.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/ContentRepositoryImpl.kt index 624bb33dd..0de14925c 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/ContentRepositoryImpl.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/ContentRepositoryImpl.kt @@ -19,7 +19,7 @@ abstract class ContentRepositoryImpl(localRepository override fun retrieveContent(forced: Boolean): Flowable { val now = Date().time - return if (forced || now - this.lastContentSync > 3600000) { + return if (forced || now - this.lastContentSync > 3) { lastContentSync = now apiClient.content.doOnNext { localRepository.saveContent(it) } } else { diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/InventoryRepositoryImpl.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/InventoryRepositoryImpl.kt index 613788fc2..495be05f9 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/InventoryRepositoryImpl.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/InventoryRepositoryImpl.kt @@ -3,6 +3,7 @@ package com.habitrpg.android.habitica.data.implementation import com.habitrpg.android.habitica.data.ApiClient import com.habitrpg.android.habitica.data.InventoryRepository import com.habitrpg.android.habitica.data.local.InventoryLocalRepository +import com.habitrpg.android.habitica.helpers.RemoteConfigManager import com.habitrpg.android.habitica.models.inventory.* import com.habitrpg.android.habitica.models.responses.BuyResponse import com.habitrpg.android.habitica.models.responses.FeedResponse @@ -13,7 +14,7 @@ import com.habitrpg.android.habitica.models.user.User import io.reactivex.Flowable import io.realm.RealmResults -class InventoryRepositoryImpl(localRepository: InventoryLocalRepository, apiClient: ApiClient, userID: String) : ContentRepositoryImpl(localRepository, apiClient, userID), InventoryRepository { +class InventoryRepositoryImpl(localRepository: InventoryLocalRepository, apiClient: ApiClient, userID: String, var remoteConfigManager: RemoteConfigManager) : ContentRepositoryImpl(localRepository, apiClient, userID), InventoryRepository { override fun getQuestContent(key: String): Flowable { return localRepository.getQuestContent(key) @@ -142,6 +143,30 @@ class InventoryRepositoryImpl(localRepository: InventoryLocalRepository, apiClie } override fun equip(user: User?, type: String, key: String): Flowable { + if (user != null && remoteConfigManager.enableLocalChanges()) { + localRepository.executeTransaction { + if (type == "mount") { + user.items?.currentMount = key + } else if (type == "pet") { + user.items?.currentPet = key + } + val outfit = if (type == "costume") { + user.items?.gear?.costume + } else { + user.items?.gear?.equipped + } + when (key.split("_").firstOrNull()) { + "weapon" -> outfit?.head = key + "armor" -> outfit?.armor = key + "shield" -> outfit?.shield = key + "eyewear" -> outfit?.eyeWear = key + "head" -> outfit?.head = key + "back" -> outfit?.back = key + "headAccessory" -> outfit?.headAccessory = key + "body" -> outfit?.body = key + } + } + } return apiClient.equipItem(type, key) .doOnNext { items -> if (user == null) { diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/UserRepositoryImpl.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/UserRepositoryImpl.kt index af5c9593d..6505d4232 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/UserRepositoryImpl.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/UserRepositoryImpl.kt @@ -4,6 +4,7 @@ import com.habitrpg.android.habitica.data.ApiClient import com.habitrpg.android.habitica.data.TaskRepository import com.habitrpg.android.habitica.data.UserRepository import com.habitrpg.android.habitica.data.local.UserLocalRepository +import com.habitrpg.android.habitica.helpers.RemoteConfigManager import com.habitrpg.android.habitica.helpers.RxErrorHandler import com.habitrpg.android.habitica.models.Skill import com.habitrpg.android.habitica.models.inventory.Customization @@ -21,7 +22,7 @@ import io.realm.RealmResults import java.util.* import java.util.concurrent.TimeUnit -class UserRepositoryImpl(localRepository: UserLocalRepository, apiClient: ApiClient, userID: String, private val taskRepository: TaskRepository) : BaseRepositoryImpl(localRepository, apiClient, userID), UserRepository { +class UserRepositoryImpl(localRepository: UserLocalRepository, apiClient: ApiClient, userID: String, private val taskRepository: TaskRepository, var remoteConfigManager: RemoteConfigManager) : BaseRepositoryImpl(localRepository, apiClient, userID), UserRepository { private var lastSync: Date? = null @@ -274,6 +275,34 @@ class UserRepositoryImpl(localRepository: UserLocalRepository, apiClient: ApiCli .subscribe(Consumer { }, RxErrorHandler.handleEmptyError()) } + override fun useCustomization(user: User?, type: String, category: String?, identifier: String): Flowable { + if (user != null && remoteConfigManager.enableLocalChanges()) { + localRepository.executeTransaction { + when (type) { + "skin" -> user.preferences?.setSkin(identifier) + "shirt" -> user.preferences?.setShirt(identifier) + "hair" -> { + when (category) { + "color" -> user.preferences?.hair?.color = identifier + "flower" -> user.preferences?.hair?.flower = identifier.toInt() + "mustache" -> user.preferences?.hair?.mustache = identifier.toInt() + "beard" -> user.preferences?.hair?.beard = identifier.toInt() + "bangs" -> user.preferences?.hair?.bangs = identifier.toInt() + "base" -> user.preferences?.hair?.base = identifier.toInt() + } + } + "background" -> user.preferences?.setBackground(identifier) + "chair" -> user.preferences?.setChair(identifier) + } + } + } + var updatePath = "preferences.$type" + if (category != null) { + updatePath = "$updatePath.$category" + } + return updateUser(user, updatePath, identifier) + } + private fun mergeUser(oldUser: User?, newUser: User): User { if (oldUser == null || !oldUser.isValid) { return oldUser ?: newUser diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmInventoryLocalRepository.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmInventoryLocalRepository.kt index 9456f4e96..cd45362c2 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmInventoryLocalRepository.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmInventoryLocalRepository.kt @@ -19,10 +19,11 @@ import io.realm.Sort class RealmInventoryLocalRepository(realm: Realm, private val context: Context) : RealmContentLocalRepository(realm), InventoryLocalRepository { override fun getQuestContent(key: String): Flowable { - return realm.where(QuestContent::class.java).equalTo("key", key).findFirstAsync() - .asFlowable() - .filter { realmObject -> realmObject.isLoaded } - .cast(QuestContent::class.java) + return realm.where(QuestContent::class.java).equalTo("key", key) + .findAll() + .asFlowable() + .filter { content -> content.isLoaded && content.isValid && !content.isEmpty() } + .map { content -> content.first() } } override fun getEquipment(searchedKeys: List): Flowable> { @@ -126,7 +127,7 @@ class RealmInventoryLocalRepository(realm: Realm, private val context: Context) override fun getMounts(type: String, group: String): Flowable> { return realm.where(Mount::class.java) .sort("color", Sort.ASCENDING) - .equalTo("animalGroup", group) + .equalTo("type", group) .equalTo("animal", type) .findAll() .asFlowable() @@ -136,16 +137,15 @@ class RealmInventoryLocalRepository(realm: Realm, private val context: Context) override fun getOwnedMounts(): Flowable> { return realm.where(Mount::class.java) .equalTo("owned", true) - .sort("animalGroup", Sort.ASCENDING, "animal", Sort.ASCENDING) + .sort("type", Sort.ASCENDING, "animal", Sort.ASCENDING) .findAll() .asFlowable() .filter { it.isLoaded } } override fun getOwnedMounts(animalType: String, animalGroup: String): Flowable> { - val thisAnimalGroup = animalGroup.replace("pets", "mounts").replace("Pets", "Mounts") return realm.where(Mount::class.java) - .equalTo("animalGroup", thisAnimalGroup) + .equalTo("type", animalGroup) .equalTo("animal", animalType) .equalTo("owned", true) .sort("animal") @@ -156,7 +156,7 @@ class RealmInventoryLocalRepository(realm: Realm, private val context: Context) override fun getPets(): Flowable> { return realm.where(Pet::class.java) - .sort("animalGroup", Sort.ASCENDING, "animal", Sort.ASCENDING) + .sort("type", Sort.ASCENDING, "animal", Sort.ASCENDING) .findAll() .asFlowable() .filter { it.isLoaded } @@ -165,7 +165,7 @@ class RealmInventoryLocalRepository(realm: Realm, private val context: Context) override fun getPets(type: String, group: String): Flowable> { return realm.where(Pet::class.java) .sort("color", Sort.ASCENDING) - .equalTo("animalGroup", group) + .equalTo("type", group) .equalTo("animal", type) .findAll() .asFlowable() @@ -175,7 +175,7 @@ class RealmInventoryLocalRepository(realm: Realm, private val context: Context) override fun getOwnedPets(): Flowable> { return realm.where(Pet::class.java) .greaterThan("trained", 0) - .sort("animalGroup", Sort.ASCENDING, "animal", Sort.ASCENDING) + .sort("type", Sort.ASCENDING, "animal", Sort.ASCENDING) .findAll() .asFlowable() .filter { it.isLoaded } @@ -183,7 +183,7 @@ class RealmInventoryLocalRepository(realm: Realm, private val context: Context) override fun getOwnedPets(type: String, group: String): Flowable> { return realm.where(Pet::class.java) - .equalTo("animalGroup", group) + .equalTo("type", group) .equalTo("animal", type) .greaterThan("trained", 0) .sort("animal") diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/extensions/JsonObject-Extensions.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/extensions/JsonObject-Extensions.kt new file mode 100644 index 000000000..8c336fdcc --- /dev/null +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/extensions/JsonObject-Extensions.kt @@ -0,0 +1,11 @@ +package com.habitrpg.android.habitica.extensions + +import com.google.gson.JsonObject + + +fun JsonObject?.getAsString(key: String): String { + if (this?.get(key)?.isJsonPrimitive == true) { + return this.get(key)?.asString ?: "" + } + return "" +} \ No newline at end of file diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/RemoteConfigManager.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/RemoteConfigManager.kt index ab28371ba..b77b20e94 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/RemoteConfigManager.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/RemoteConfigManager.kt @@ -1,18 +1,8 @@ package com.habitrpg.android.habitica.helpers -import android.content.Context -import android.os.AsyncTask -import androidx.preference.PreferenceManager import com.google.firebase.remoteconfig.FirebaseRemoteConfig import com.google.gson.Gson -import com.google.gson.JsonObject import com.google.gson.reflect.TypeToken -import okhttp3.OkHttpClient -import okhttp3.Request - -import org.json.JSONException -import org.json.JSONObject -import java.io.* class RemoteConfigManager { @@ -50,4 +40,8 @@ class RemoteConfigManager { fun enableUsernameAutocomplete(): Boolean { return remoteConfig.getBoolean("enableUsernameAutocomplete") } + + fun enableLocalChanges(): Boolean { + return remoteConfig.getBoolean("enableLocalChanges") + } } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/models/inventory/Animal.java b/Habitica/src/main/java/com/habitrpg/android/habitica/models/inventory/Animal.java index 7519951d8..c3409d3e8 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/models/inventory/Animal.java +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/models/inventory/Animal.java @@ -1,11 +1,20 @@ package com.habitrpg.android.habitica.models.inventory; + public interface Animal { public String getKey(); public void setKey(String key); + public String getText(); + + public void setText(String text); + + public String getType(); + + public void setType(String type); + public String getAnimal(); public void setAnimal(String animal); @@ -18,22 +27,10 @@ public interface Animal { public void setAnimalGroup(String group); - public String getAnimalText(); - - public void setAnimalText(String animalText); - - public String getColorText(); - - public void setColorText(String colorText); - public boolean getPremium(); public void setPremium(boolean premium); - public boolean getLimited(); - - public void setLimited(boolean limited); - public Integer getNumberOwned(); public void setNumberOwned(Integer numberOwned); diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/models/inventory/Customization.java b/Habitica/src/main/java/com/habitrpg/android/habitica/models/inventory/Customization.java index e33f99404..1bffe35f8 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/models/inventory/Customization.java +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/models/inventory/Customization.java @@ -28,6 +28,7 @@ public class Customization extends RealmObject { this.id = id; } + @Nullable public String getIdentifier() { return this.identifier; } @@ -37,6 +38,7 @@ public class Customization extends RealmObject { this.updateID(); } + @Nullable public String getCategory() { return this.category; } @@ -46,6 +48,7 @@ public class Customization extends RealmObject { this.updateID(); } + @Nullable public String getType() { return this.type; } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/models/inventory/Mount.java b/Habitica/src/main/java/com/habitrpg/android/habitica/models/inventory/Mount.java index 548c497e5..cc692079c 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/models/inventory/Mount.java +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/models/inventory/Mount.java @@ -11,8 +11,8 @@ public class Mount extends RealmObject implements Animal { Boolean owned; @PrimaryKey String key; - String animal, color, animalGroup, animalText, colorText; - boolean premium, limited; + String animal, color, animalGroup, text, type; + boolean premium; @Ignore Integer numberOwned; @@ -25,6 +25,26 @@ public class Mount extends RealmObject implements Animal { this.key = key; } + @Override + public String getText() { + return text; + } + + @Override + public void setText(String text) { + this.text = text; + } + + @Override + public String getType() { + return type; + } + + @Override + public void setType(String type) { + this.type = type; + } + public String getAnimal() { if (animal == null) { return key.split("-")[0]; @@ -58,28 +78,6 @@ public class Mount extends RealmObject implements Animal { this.animalGroup = group; } - public String getAnimalText() { - if (animalText == null) { - return animal; - } - return animalText; - } - - public void setAnimalText(String animalText) { - this.animalText = animalText; - } - - public String getColorText() { - if (colorText == null) { - return color; - } - return colorText; - } - - public void setColorText(String colorText) { - this.colorText = colorText; - } - public boolean getPremium() { return premium; } @@ -88,14 +86,6 @@ public class Mount extends RealmObject implements Animal { this.premium = premium; } - public boolean getLimited() { - return limited; - } - - public void setLimited(boolean limited) { - this.limited = limited; - } - public Integer getNumberOwned() { if (numberOwned == null) { return 0; diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/models/inventory/Pet.java b/Habitica/src/main/java/com/habitrpg/android/habitica/models/inventory/Pet.java index f4f73f8ea..09fcbb18f 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/models/inventory/Pet.java +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/models/inventory/Pet.java @@ -10,8 +10,8 @@ public class Pet extends RealmObject implements Animal{ Integer trained; @PrimaryKey String key; - String animal, color, animalGroup, animalText, colorText; - boolean premium, limited; + String animal, color, animalGroup, text, type; + boolean premium; @Ignore private Integer numberOwned; @@ -24,6 +24,26 @@ public class Pet extends RealmObject implements Animal{ this.key = key; } + @Override + public String getText() { + return text; + } + + @Override + public void setText(String text) { + this.text = text; + } + + @Override + public String getType() { + return type; + } + + @Override + public void setType(String type) { + this.type = type; + } + public String getAnimal() { if (animal == null) { return getKey().split("-")[0]; @@ -57,28 +77,6 @@ public class Pet extends RealmObject implements Animal{ this.animalGroup = group; } - public String getAnimalText() { - if (animalText == null) { - return animal; - } - return animalText; - } - - public void setAnimalText(String animalText) { - this.animalText = animalText; - } - - public String getColorText() { - if (colorText == null) { - return color; - } - return colorText; - } - - public void setColorText(String colorText) { - this.colorText = colorText; - } - public boolean getPremium() { return premium; } @@ -87,14 +85,6 @@ public class Pet extends RealmObject implements Animal{ this.premium = premium; } - public boolean getLimited() { - return limited; - } - - public void setLimited(boolean limited) { - this.limited = limited; - } - public Integer getNumberOwned() { if (numberOwned == null) { return 0; diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/modules/RepositoryModule.java b/Habitica/src/main/java/com/habitrpg/android/habitica/modules/RepositoryModule.java index 2ffa32e6e..6e7fd4640 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/modules/RepositoryModule.java +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/modules/RepositoryModule.java @@ -42,6 +42,7 @@ import com.habitrpg.android.habitica.data.local.implementation.RealmTagLocalRepo import com.habitrpg.android.habitica.data.local.implementation.RealmTaskLocalRepository; import com.habitrpg.android.habitica.data.local.implementation.RealmTutorialLocalRepository; import com.habitrpg.android.habitica.data.local.implementation.RealmUserLocalRepository; +import com.habitrpg.android.habitica.helpers.RemoteConfigManager; import javax.inject.Named; import javax.inject.Singleton; @@ -100,8 +101,8 @@ public class RepositoryModule { } @Provides - UserRepository providesUserRepository(UserLocalRepository localRepository, ApiClient apiClient, @Named(AppModule.NAMED_USER_ID) String userId, TaskRepository taskRepository) { - return new UserRepositoryImpl(localRepository, apiClient, userId, taskRepository); + UserRepository providesUserRepository(UserLocalRepository localRepository, ApiClient apiClient, @Named(AppModule.NAMED_USER_ID) String userId, TaskRepository taskRepository, RemoteConfigManager remoteConfigManager) { + return new UserRepositoryImpl(localRepository, apiClient, userId, taskRepository, remoteConfigManager); } @Provides @@ -120,11 +121,10 @@ public class RepositoryModule { } @Provides - InventoryRepository providesInventoryRepository(InventoryLocalRepository localRepository, ApiClient apiClient, @Named(AppModule.NAMED_USER_ID) String userId) { - return new InventoryRepositoryImpl(localRepository, apiClient, userId); + InventoryRepository providesInventoryRepository(InventoryLocalRepository localRepository, ApiClient apiClient, @Named(AppModule.NAMED_USER_ID) String userId, RemoteConfigManager remoteConfig) { + return new InventoryRepositoryImpl(localRepository, apiClient, userId, remoteConfig); } - @Provides FAQLocalRepository providesFAQLocalRepository(Realm realm) { return new RealmFAQLocalRepository(realm); diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/MainActivity.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/MainActivity.kt index 570e68a95..c3a05eb36 100755 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/MainActivity.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/MainActivity.kt @@ -187,15 +187,7 @@ open class MainActivity : BaseActivity(), TutorialView.OnTutorialReaction { val languageHelper = LanguageHelper(sharedPreferences.getString("language", "en")) Locale.setDefault(languageHelper.locale) val configuration = Configuration() - if (SDK_INT <= Build.VERSION_CODES.JELLY_BEAN) { - @Suppress("Deprecation") - configuration.locale = languageHelper.locale - } else { - configuration.setLocale(languageHelper.locale) - } - @Suppress("Deprecation") - resources.updateConfiguration(configuration, - resources.displayMetrics) + configuration.setLocale(languageHelper.locale) super.onCreate(savedInstanceState) if (!HabiticaBaseApplication.checkUserAuthentication(this, hostConfig)) { @@ -207,18 +199,16 @@ open class MainActivity : BaseActivity(), TutorialView.OnTutorialReaction { avatarInHeader = AvatarWithBarsViewModel(this, avatarWithBars, userRepository) sideAvatarView = AvatarView(this, true, false, false) - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { - val window = window - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - window.statusBarColor = ContextCompat.getColor(this, R.color.black_10_alpha) - } - getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS) - toolbar.setPadding(0, statusBarHeight, 0, 0) - val px = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 16f, resources.displayMetrics) - avatarWithBars.setPadding(px.toInt(), statusBarHeight, px.toInt(), 0) + val window = window + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + window.statusBarColor = ContextCompat.getColor(this, R.color.black_10_alpha) } + getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS) + toolbar.setPadding(0, statusBarHeight, 0, 0) + val px = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 16f, resources.displayMetrics) + avatarWithBars.setPadding(px.toInt(), statusBarHeight, px.toInt(), 0) - compositeSubscription.add(userRepository.getUser(hostConfig.user ?: "") + compositeSubscription.add(userRepository.getUser(hostConfig.user) .subscribe(Consumer { newUser -> this@MainActivity.user = newUser this@MainActivity.setUserData() @@ -566,21 +556,19 @@ open class MainActivity : BaseActivity(), TutorialView.OnTutorialReaction { val pet = event.usingPet this.inventoryRepository.feedPet(event.usingPet, event.usingFood) .subscribe(Consumer { feedResponse -> - HabiticaSnackbar.showSnackbar(floatingMenuWrapper, getString(R.string.notification_pet_fed, pet.colorText, pet.animalText), SnackbarDisplayType.NORMAL) + HabiticaSnackbar.showSnackbar(floatingMenuWrapper, getString(R.string.notification_pet_fed, pet.text), SnackbarDisplayType.NORMAL) if (feedResponse.value == -1) { val mountWrapper = View.inflate(this, R.layout.pet_imageview, null) as FrameLayout val mountImageView = mountWrapper.findViewById(R.id.pet_imageview) as SimpleDraweeView DataBindingUtils.loadImage(mountImageView, "Mount_Icon_" + event.usingPet.key) - val colorName = event.usingPet.colorText - val animalName = event.usingPet.animalText val dialog = AlertDialog.Builder(this@MainActivity) - .setTitle(getString(R.string.evolved_pet_title, colorName, animalName)) + .setTitle(getString(R.string.evolved_pet_title, pet.text)) .setView(mountWrapper) .setPositiveButton(R.string.close) { hatchingDialog, _ -> hatchingDialog.dismiss() } .setNeutralButton(R.string.share) { hatchingDialog, _ -> val event1 = ShareEvent() - event1.sharedMessage = getString(R.string.share_raised, colorName, animalName) + " https://habitica.com/social/raise-pet" + event1.sharedMessage = getString(R.string.share_raised, pet.text) + " https://habitica.com/social/raise-pet" val sharedImage = Bitmap.createBitmap(99, 99, Bitmap.Config.ARGB_8888) val canvas = Canvas(sharedImage) canvas.drawColor(ContextCompat.getColor(this, R.color.brand_300)) @@ -661,7 +649,6 @@ open class MainActivity : BaseActivity(), TutorialView.OnTutorialReaction { pushNotificationManager.setUser(user1) pushNotificationManager.addPushDeviceUsingStoredToken() } - .flatMap { socialRepository.retrieveInboxMessages() } .flatMap { inventoryRepository.retrieveContent(false) } .flatMap { inventoryRepository.retrieveWorldState() } .subscribe(Consumer { }, RxErrorHandler.handleEmptyError()) diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/MountDetailRecyclerAdapter.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/MountDetailRecyclerAdapter.kt index 11923e488..63fa5de9b 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/MountDetailRecyclerAdapter.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/MountDetailRecyclerAdapter.kt @@ -54,7 +54,7 @@ class MountDetailRecyclerAdapter(data: OrderedRealmCollection?, autoUpdat fun bind(item: Mount) { animal = item - titleView.text = item.colorText + titleView.text = item.color ownedTextView.visibility = View.GONE this.imageView.alpha = 1.0f if (this.animal?.owned == true) { diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/PetDetailRecyclerAdapter.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/PetDetailRecyclerAdapter.kt index 017acdc52..b64600d45 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/PetDetailRecyclerAdapter.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/PetDetailRecyclerAdapter.kt @@ -77,7 +77,7 @@ class PetDetailRecyclerAdapter(data: OrderedRealmCollection?, autoUpdate: B fun bind(item: Pet) { this.animal = item - this.titleView.text = item.colorText + this.titleView.text = item.color this.trainedProgressbar.visibility = if (animal?.animalGroup == "specialPets") View.GONE else View.VISIBLE this.imageView.alpha = 1.0f if (this.animal?.trained ?: 0 > 0) { diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/StableRecyclerAdapter.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/StableRecyclerAdapter.kt index b5c0835bc..b22bba9de 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/StableRecyclerAdapter.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/StableRecyclerAdapter.kt @@ -74,7 +74,7 @@ class StableRecyclerAdapter : androidx.recyclerview.widget.RecyclerView.Adapter< fun bind(item: Animal) { this.animal = item - titleView.text = item.animalText + titleView.text = item.animal ownedTextView.visibility = View.VISIBLE this.imageView.alpha = 1.0f if (item.numberOwned > 0) { diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/customization/AvatarCustomizationFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/customization/AvatarCustomizationFragment.kt index c6d011dea..a18805569 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/customization/AvatarCustomizationFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/customization/AvatarCustomizationFragment.kt @@ -42,11 +42,7 @@ class AvatarCustomizationFragment : BaseMainFragment() { compositeSubscription.add(adapter.getSelectCustomizationEvents() .flatMap { customization -> - var updatePath = "preferences." + customization.type - if (customization.category != null) { - updatePath = updatePath + "." + customization.category - } - userRepository.updateUser(user, updatePath, customization.identifier) + userRepository.useCustomization(user, customization.type ?: "", customization.category, customization.identifier ?: "") } .subscribe(Consumer { }, RxErrorHandler.handleEmptyError())) compositeSubscription.add(adapter.getUnlockCustomizationEvents() diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/items/ItemRecyclerFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/items/ItemRecyclerFragment.kt index 0b277a3ba..0e64b07dc 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/items/ItemRecyclerFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/items/ItemRecyclerFragment.kt @@ -123,7 +123,7 @@ class ItemRecyclerFragment : BaseFragment() { } this.isFeeding -> { dialog?.requestWindowFeature(Window.FEATURE_NO_TITLE) - this.titleView?.text = getString(R.string.dialog_feeding, this.feedingPet?.colorText, this.feedingPet?.animalText) + this.titleView?.text = getString(R.string.dialog_feeding, this.feedingPet?.text) this.titleView?.visibility = View.VISIBLE this.footerView?.text = getString(R.string.feeding_market_info) this.footerView?.visibility = View.VISIBLE diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/stable/StableRecyclerFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/stable/StableRecyclerFragment.kt index a6454e9d8..42e82e7dd 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/stable/StableRecyclerFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/stable/StableRecyclerFragment.kt @@ -135,8 +135,7 @@ class StableRecyclerFragment : BaseFragment() { var lastAnimal: Animal = unsortedAnimals[0] for (animal in unsortedAnimals) { if (animal.animal != lastAnimal.animal || animal === unsortedAnimals[unsortedAnimals.size - 1]) { - if (!((lastAnimal.animalGroup == "premiumPets" || lastAnimal.animalGroup == "specialPets" - || lastAnimal.animalGroup == "specialMounts" || lastAnimal.animalGroup == "premiumMounts") && lastAnimal.numberOwned == 0)) { + if (!((lastAnimal.type == "premium" || lastAnimal.type == "special") && lastAnimal.numberOwned == 0)) { items.add(lastAnimal) } lastAnimal = animal @@ -151,14 +150,14 @@ class StableRecyclerFragment : BaseFragment() { if (user != null && user?.items != null) { when (itemType) { "pets" -> { - val pet = animal as Pet - if (pet.trained > 0) { + val pet = animal as? Pet + if (pet?.trained ?: 0 > 0) { lastAnimal.numberOwned = lastAnimal.numberOwned + 1 } } "mounts" -> { - val mount = animal as Mount - if (mount.owned) { + val mount = animal as? Mount + if (mount?.owned == true) { lastAnimal.numberOwned = lastAnimal.numberOwned + 1 } } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/helpers/KeyboardUtil.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/helpers/KeyboardUtil.kt index 3c6619ec9..6091a094a 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/helpers/KeyboardUtil.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/helpers/KeyboardUtil.kt @@ -60,21 +60,15 @@ class KeyboardUtil(activity: Activity, private val contentView: View) { } init { - if (Build.VERSION.SDK_INT >= 19) { - decorView.viewTreeObserver.addOnGlobalLayoutListener(onGlobalLayoutListener) - } + decorView.viewTreeObserver.addOnGlobalLayoutListener(onGlobalLayoutListener) } fun enable() { - if (Build.VERSION.SDK_INT >= 19) { - decorView.viewTreeObserver.addOnGlobalLayoutListener(onGlobalLayoutListener) - } + decorView.viewTreeObserver.addOnGlobalLayoutListener(onGlobalLayoutListener) } fun disable() { - if (Build.VERSION.SDK_INT >= 19) { - decorView.viewTreeObserver.removeOnGlobalLayoutListener(onGlobalLayoutListener) - } + decorView.viewTreeObserver.removeOnGlobalLayoutListener(onGlobalLayoutListener) } companion object { diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/utils/ContentDeserializer.java b/Habitica/src/main/java/com/habitrpg/android/habitica/utils/ContentDeserializer.java deleted file mode 100644 index 72d320c03..000000000 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/utils/ContentDeserializer.java +++ /dev/null @@ -1,154 +0,0 @@ -package com.habitrpg.android.habitica.utils; - -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.reflect.TypeToken; -import com.habitrpg.android.habitica.data.CustomizationRepository; -import com.habitrpg.android.habitica.models.ContentGear; -import com.habitrpg.android.habitica.models.ContentResult; -import com.habitrpg.android.habitica.models.FAQArticle; -import com.habitrpg.android.habitica.models.Skill; -import com.habitrpg.android.habitica.models.inventory.Customization; -import com.habitrpg.android.habitica.models.inventory.Egg; -import com.habitrpg.android.habitica.models.inventory.Equipment; -import com.habitrpg.android.habitica.models.inventory.Food; -import com.habitrpg.android.habitica.models.inventory.HatchingPotion; -import com.habitrpg.android.habitica.models.inventory.Mount; -import com.habitrpg.android.habitica.models.inventory.Pet; -import com.habitrpg.android.habitica.models.inventory.QuestContent; - -import java.lang.reflect.Type; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import javax.inject.Inject; - -import io.realm.RealmList; - -public class ContentDeserializer implements JsonDeserializer { - - @Inject - CustomizationRepository customizationRepository; - - @Override - public ContentResult deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { - - ContentResult result = new ContentResult(); - JsonObject object = json.getAsJsonObject(); - - result.potion = context.deserialize(object.get("potion"), Equipment.class); - //result.potion.imageName = "shop_potion"; - //result.potion.currency = "gold"; - result.armoire = context.deserialize(object.get("armoire"), Equipment.class); - //result.armoire.imageName = "shop_armoire"; - //result.armoire.currency = "gold"; - result.gear = context.deserialize(object.get("gear"), ContentGear.class); - - result.quests = context.deserialize(object.get("quests"), new TypeToken>() {}.getType()); - result.eggs = context.deserialize(object.get("eggs"), new TypeToken>() {}.getType()); - result.food = context.deserialize(object.get("food"), new TypeToken>() {}.getType()); - result.hatchingPotions = context.deserialize(object.get("hatchingPotions"), new TypeToken>() {}.getType()); - - Map pets = context.deserialize(object.get("pets"), new TypeToken>() {}.getType()); - Map specialPets = context.deserialize(object.get("specialPets"), new TypeToken>() {}.getType()); - Map premiumPets = context.deserialize(object.get("premiumPets"), new TypeToken>() {}.getType()); - Map questPets = context.deserialize(object.get("questPets"), new TypeToken>() {}.getType()); - Map whackyPets = context.deserialize(object.get("whackyPets"), new TypeToken>() {}.getType()); - if (whackyPets == null) { - whackyPets = new HashMap<>(); - } - Map mounts = context.deserialize(object.get("mounts"), new TypeToken>() {}.getType()); - Map specialMounts = context.deserialize(object.get("specialMounts"), new TypeToken>() {}.getType()); - Map premiumMounts = context.deserialize(object.get("premiumMounts"), new TypeToken>() {}.getType()); - Map questMounts = context.deserialize(object.get("questMounts"), new TypeToken>() {}.getType()); - Map whackyMounts = context.deserialize(object.get("whackyMounts"), new TypeToken>() {}.getType()); - if (whackyMounts == null) { - whackyMounts = new HashMap<>(); - } - - for (Egg egg : result.eggs) { - for (HatchingPotion potion : result.hatchingPotions) { - String key = egg.getKey() + "-" + potion.getKey(); - if (pets.containsKey(key)) { - pets.put(key, this.populatePet(pets.get(key), egg, potion, "pets")); - } - if (specialPets.containsKey(key)) { - specialPets.put(key, this.populatePet(specialPets.get(key), egg, potion, "specialPets")); - } - if (premiumPets.containsKey(key)) { - premiumPets.put(key, this.populatePet(premiumPets.get(key), egg, potion, "premiumPets")); - } - if (questPets.containsKey(key)) { - questPets.put(key, this.populatePet(questPets.get(key), egg, potion, "questPets")); - } - if (whackyPets.containsKey(key)) { - whackyPets.put(key, this.populatePet(whackyPets.get(key), egg, potion, "whackyPets")); - } - if (mounts.containsKey(key)) { - mounts.put(key, this.populateMount(mounts.get(key), egg, potion, "mounts")); - } - if (specialMounts.containsKey(key)) { - specialMounts.put(key, this.populateMount(specialMounts.get(key), egg, potion, "specialMounts")); - } - if (premiumMounts.containsKey(key)) { - premiumMounts.put(key, this.populateMount(premiumMounts.get(key), egg, potion, "premiumMounts")); - } - if (questMounts.containsKey(key)) { - questMounts.put(key, this.populateMount(questMounts.get(key), egg, potion, "questMounts")); - } - if (whackyMounts.containsKey(key)) { - whackyMounts.put(key, this.populateMount(whackyMounts.get(key), egg, potion, "whackyMounts")); - } - } - } - for (Pet pet : specialPets.values()) { - pet.setAnimalGroup("specialPets"); - } - for (Mount mount : specialMounts.values()) { - mount.setAnimalGroup("specialMounts"); - } - - result.pets = new RealmList<>(); - result.pets.addAll(pets.values()); - result.pets.addAll(specialPets.values()); - result.pets.addAll(premiumPets.values()); - result.pets.addAll(questPets.values()); - - result.mounts = new RealmList<>(); - result.mounts.addAll(mounts.values()); - result.mounts.addAll(specialMounts.values()); - result.mounts.addAll(premiumMounts.values()); - result.mounts.addAll(questMounts.values()); - - result.spells = context.deserialize(object.get("spells"), new TypeToken>() {}.getType()); - - result.appearances = context.deserialize(object.get("appearances"), new TypeToken>() {}.getType()); - result.backgrounds = context.deserialize(object.get("backgrounds"), new TypeToken>() {}.getType()); - - result.faq = context.deserialize(object.get("faq"), new TypeToken>() {}.getType()); - - return result; - } - - private Mount populateMount(Mount mount, Egg egg, HatchingPotion potion, String group) { - mount.setAnimalText(egg.getMountText()); - mount.setColorText(potion.getText()); - mount.setLimited(potion.getLimited()); - mount.setPremium(potion.getPremium()); - mount.setAnimalGroup(group); - return mount; - } - - private Pet populatePet(Pet pet, Egg egg, HatchingPotion potion, String group) { - pet.setAnimalText(egg.getText()); - pet.setColorText(potion.getText()); - pet.setLimited(potion.getLimited()); - pet.setPremium(potion.getPremium()); - pet.setAnimalGroup(group); - return pet; - } -} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/utils/ContentDeserializer.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/utils/ContentDeserializer.kt new file mode 100644 index 000000000..5667c5da3 --- /dev/null +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/utils/ContentDeserializer.kt @@ -0,0 +1,108 @@ +package com.habitrpg.android.habitica.utils + +import com.google.firebase.perf.FirebasePerformance +import com.google.gson.JsonDeserializationContext +import com.google.gson.JsonDeserializer +import com.google.gson.JsonElement +import com.google.gson.JsonParseException +import com.google.gson.reflect.TypeToken +import com.habitrpg.android.habitica.data.CustomizationRepository +import com.habitrpg.android.habitica.extensions.getAsString +import com.habitrpg.android.habitica.models.ContentGear +import com.habitrpg.android.habitica.models.ContentResult +import com.habitrpg.android.habitica.models.FAQArticle +import com.habitrpg.android.habitica.models.Skill +import com.habitrpg.android.habitica.models.inventory.Customization +import com.habitrpg.android.habitica.models.inventory.Egg +import com.habitrpg.android.habitica.models.inventory.Equipment +import com.habitrpg.android.habitica.models.inventory.Food +import com.habitrpg.android.habitica.models.inventory.HatchingPotion +import com.habitrpg.android.habitica.models.inventory.Mount +import com.habitrpg.android.habitica.models.inventory.Pet +import com.habitrpg.android.habitica.models.inventory.QuestContent + +import java.lang.reflect.Type + +import javax.inject.Inject + +import io.realm.RealmList +import java.util.ArrayList + +class ContentDeserializer : JsonDeserializer { + + @Throws(JsonParseException::class) + override fun deserialize(json: JsonElement, typeOfT: Type, context: JsonDeserializationContext): ContentResult { + val deserializeTrace = FirebasePerformance.getInstance().newTrace("ContentDeserialize") + deserializeTrace.start() + val result = ContentResult() + val obj = json.asJsonObject + + result.potion = context.deserialize(obj.get("potion"), Equipment::class.java) + result.armoire = context.deserialize(obj.get("armoire"), Equipment::class.java) + result.gear = context.deserialize(obj.get("gear"), ContentGear::class.java) + + result.quests = context.deserialize(obj.get("quests"), object : TypeToken>() {}.type) + result.eggs = context.deserialize(obj.get("eggs"), object : TypeToken>() {}.type) + result.food = context.deserialize(obj.get("food"), object : TypeToken>() {}.type) + result.hatchingPotions = context.deserialize(obj.get("hatchingPotions"), object : TypeToken>() {}.type) + + result.pets = RealmList() + for (key in obj.getAsJsonObject("petInfo").keySet()) { + val pet = Pet() + val petObj = obj.getAsJsonObject(key) + pet.animal = petObj.getAsString("egg") + pet.color = petObj.getAsString("potion") + pet.key = petObj.getAsString("key") + pet.text = petObj.getAsString("text") + pet.type = petObj.getAsString("type") + if (pet.type == "premium") { + pet.premium = true + } + result.pets.add(pet) + } + + result.mounts = RealmList() + for (key in obj.getAsJsonObject("mountInfo").keySet()) { + val mount = Mount() + val mountObj = obj.getAsJsonObject(key) + mount.animal = mountObj.getAsString("egg") + mount.color = mountObj.getAsString("potion") + mount.key = mountObj.getAsString("key") + mount.type = mountObj.getAsString("type") + if (mount.type == "premium") { + mount.premium = true + } + result.mounts.add(mount) + } + result.spells = ArrayList() + for ((classname, value) in obj.getAsJsonObject("spells").entrySet()) { + val classObject = value.asJsonObject + + for ((_, value1) in classObject.entrySet()) { + val skillObject = value1.asJsonObject + val skill = Skill() + skill.key = skillObject.get("key").asString + skill.text = skillObject.get("text").asString + skill.notes = skillObject.get("notes").asString + skill.key = skillObject.get("key").asString + skill.target = skillObject.get("target").asString + skill.habitClass = classname + skill.mana = skillObject.get("mana").asInt + + val lvlElement = skillObject.get("lvl") + + if (lvlElement != null) { + skill.lvl = lvlElement.asInt + } + + result.spells.add(skill) + } + } + result.appearances = context.deserialize(obj.get("appearances"), object : TypeToken>() {}.type) + result.backgrounds = context.deserialize(obj.get("backgrounds"), object : TypeToken>() {}.type) + + result.faq = context.deserialize(obj.get("faq"), object : TypeToken>() {}.type) + deserializeTrace.stop() + return result + } +} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/utils/SkillDeserializer.java b/Habitica/src/main/java/com/habitrpg/android/habitica/utils/SkillDeserializer.java index b02e8815e..51535772d 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/utils/SkillDeserializer.java +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/utils/SkillDeserializer.java @@ -23,7 +23,7 @@ public class SkillDeserializer JsonDeserializationContext context) throws JsonParseException { JsonObject object = json.getAsJsonObject(); - List skills = new ArrayList(); + List skills = new ArrayList<>(); for (Map.Entry classEntry : object.entrySet()) { String classname = classEntry.getKey(); JsonObject classObject = classEntry.getValue().getAsJsonObject(); diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/utils/TaskGroupPlanDeserializer.java b/Habitica/src/main/java/com/habitrpg/android/habitica/utils/TaskGroupPlanDeserializer.java deleted file mode 100644 index caf283d7b..000000000 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/utils/TaskGroupPlanDeserializer.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.habitrpg.android.habitica.utils; - - -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.habitrpg.android.habitica.models.tasks.TaskGroupPlan; - -import java.lang.reflect.Type; - -public class TaskGroupPlanDeserializer implements JsonDeserializer { - @Override - public TaskGroupPlan deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { - TaskGroupPlan group = new TaskGroupPlan(); - JsonObject object = json.getAsJsonObject(); - JsonObject approvalObject = object.getAsJsonObject("approval"); - group.setApprovalRequested(approvalObject.getAsJsonPrimitive("requested").getAsBoolean()); - group.setApprovalApproved(approvalObject.getAsJsonPrimitive("approved").getAsBoolean()); - group.setApprovalRequired(approvalObject.getAsJsonPrimitive("required").getAsBoolean()); - - return null; - } -} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/utils/TaskListDeserializer.java b/Habitica/src/main/java/com/habitrpg/android/habitica/utils/TaskListDeserializer.java deleted file mode 100644 index f9df00fa1..000000000 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/utils/TaskListDeserializer.java +++ /dev/null @@ -1,66 +0,0 @@ -package com.habitrpg.android.habitica.utils; - -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonDeserializer; -import com.google.gson.JsonElement; -import com.google.gson.JsonArray; -import com.habitrpg.android.habitica.models.tasks.Task; -import com.habitrpg.android.habitica.models.tasks.TaskList; - -import java.lang.reflect.Type; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * Created by viirus on 09/12/15. - */ -public class TaskListDeserializer implements JsonDeserializer { - - private List getIntListFromJsonArray(JsonArray jsonArray) { - List intList = new ArrayList<>(); - - for (int i = 0; i < jsonArray.size(); i++) { - intList.add(jsonArray.get(i).getAsInt()); - } - - return intList; - } - - private void getMonthlyDays(JsonElement e, Task task) { - JsonArray weeksOfMonth = e.getAsJsonObject().getAsJsonArray("weeksOfMonth"); - if (weeksOfMonth != null && weeksOfMonth.size() > 0) { - task.setWeeksOfMonth(getIntListFromJsonArray(weeksOfMonth)); - } - - JsonArray daysOfMonth = e.getAsJsonObject().getAsJsonArray("daysOfMonth"); - if (weeksOfMonth != null && weeksOfMonth.size() > 0) { - task.setDaysOfMonth(getIntListFromJsonArray(daysOfMonth)); - } - } - - public TaskList deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext ctx) { - TaskList tasks = new TaskList(); - Map taskMap = new HashMap<>(); - - for (JsonElement e : json.getAsJsonArray()) { - try { - Task task = ctx.deserialize(e, Task.class); - - // Work around since Realm does not support Arrays of ints - getMonthlyDays(e, task); - - //Workaround, since gson doesn't call setter methods - task.setId(task.getId()); - taskMap.put(task.getId(), task); - } catch (ClassCastException ignored) { - - } - } - - tasks.tasks = taskMap; - - return tasks; - } -} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/utils/TaskListDeserializer.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/utils/TaskListDeserializer.kt new file mode 100644 index 000000000..cee3acad4 --- /dev/null +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/utils/TaskListDeserializer.kt @@ -0,0 +1,172 @@ +package com.habitrpg.android.habitica.utils + +import com.google.firebase.perf.FirebasePerformance +import com.google.gson.* +import com.habitrpg.android.habitica.extensions.getAsString +import com.habitrpg.android.habitica.models.Tag +import com.habitrpg.android.habitica.models.tasks.* +import io.realm.Realm +import io.realm.RealmList + +import java.lang.reflect.Type +import java.util.* + +/** + * Created by viirus on 09/12/15. + */ +class TaskListDeserializer : JsonDeserializer { + + private fun getIntListFromJsonArray(jsonArray: JsonArray): List { + val intList = ArrayList() + + for (i in 0 until jsonArray.size()) { + intList.add(jsonArray.get(i).asInt) + } + + return intList + } + + private fun getMonthlyDays(e: JsonElement, task: Task) { + val weeksOfMonth = e.asJsonObject.getAsJsonArray("weeksOfMonth") + if (weeksOfMonth != null && weeksOfMonth.size() > 0) { + task.setWeeksOfMonth(getIntListFromJsonArray(weeksOfMonth)) + } + + val daysOfMonth = e.asJsonObject.getAsJsonArray("daysOfMonth") + if (weeksOfMonth != null && weeksOfMonth.size() > 0) { + task.setDaysOfMonth(getIntListFromJsonArray(daysOfMonth)) + } + } + + override fun deserialize(json: JsonElement, typeOfT: Type, ctx: JsonDeserializationContext): TaskList { + val tasks = TaskList() + val taskMap = HashMap() + val deserializeTrace = FirebasePerformance.getInstance().newTrace("TaskListDeserialize") + deserializeTrace.start() + var databaseTags: List + try { + val realm = Realm.getDefaultInstance() + databaseTags = realm.copyFromRealm(realm.where(Tag::class.java).findAll()) + realm.close() + } catch (e: RuntimeException) { + //Tests don't have a database + databaseTags = ArrayList() + } + + for (e in json.asJsonArray) { + try { + val obj = e as? JsonObject + if (obj != null) { + val task = Task() + task.text = obj.getAsString("text") + task.notes = obj.getAsString("notes") + task.userId = obj.getAsString("userId") + task.value = obj.get("value")?.asDouble ?: 0.0 + task.type = obj.getAsString("type") + task.frequency = obj.getAsString("frequency") + task.attribute = obj.getAsString("attribute") + task.everyX = obj.get("everyX")?.asInt + task.priority = obj.get("priority")?.asFloat ?: 1.0f + task.completed = obj.get("completed")?.asBoolean ?: false + task.up = obj.get("up")?.asBoolean ?: false + task.down = obj.get("down")?.asBoolean ?: false + task.streak = obj.get("streak")?.asInt + task.counterUp = obj.get("counterUp")?.asInt + task.counterDown = obj.get("counterDown")?.asInt + task.dateCreated = ctx.deserialize(obj.get("createdAt"), Date::class.java) + task.dueDate = ctx.deserialize(obj.get("date"), Date::class.java) + task.startDate = ctx.deserialize(obj.get("startDate"), Date::class.java) + task.isDue = obj.get("isDue")?.asBoolean + if (obj.has("nextDue")) { + task.nextDue = RealmList() + for (due in obj.getAsJsonArray("nextDue")) { + task.nextDue?.add(ctx.deserialize(due, Date::class.java)) + } + } + task.tags = handleTags(databaseTags, obj.getAsJsonArray("tags"), ctx) + if (obj.has("checklist")) { + task.checklist = RealmList() + for (checklistElement in obj.getAsJsonArray("checklist")) { + task.checklist?.add(ChecklistItem( + obj.getAsString("id"), + obj.getAsString("text"), + obj.get("completed").asBoolean + )) + } + } + if (obj.has("reminders")) { + task.reminders = RealmList() + for (reminderElement in obj.getAsJsonArray("reminders")) { + val reminder = RemindersItem() + reminder.id = obj.getAsString("id") + reminder.startDate = ctx.deserialize(obj.get("startDate"), Date::class.java) + reminder.time = ctx.deserialize(obj.get("time"), Date::class.java) + task.reminders?.add(reminder) + } + } + if (obj.has("repeat")) { + task.repeat = ctx.deserialize(obj.get("repeat"), Days::class.java) + } + + if (obj.has("group")) { + val group = TaskGroupPlan() + val groupObject = obj.getAsJsonObject("group") + val approvalObject = groupObject.getAsJsonObject("approval") + group.approvalRequested = approvalObject.getAsJsonPrimitive("requested").asBoolean + group.approvalApproved = approvalObject.getAsJsonPrimitive("approved").asBoolean + group.approvalRequired = approvalObject.getAsJsonPrimitive("required").asBoolean + task.group = group + } + // Work around since Realm does not support Arrays of ints + getMonthlyDays(e, task) + + //Workaround, since gson doesn't call setter methods + task.id = obj.getAsString("_id") + task.id?.let { taskMap[it] = task } + } + } catch (ignored: ClassCastException) { + + } + } + + tasks.tasks = taskMap + deserializeTrace.stop() + return tasks + } + + private fun handleTags(databaseTags: List, json: JsonArray?, context: JsonDeserializationContext): RealmList? { + val tags = RealmList() + for (tagElement in json ?: listOf()) { + if (tagElement.isJsonObject) { + tags.add(context.deserialize(tagElement, Tag::class.java)) + } else { + try { + val tagId = tagElement.asString + for (tag in databaseTags) { + if (tag.getId() == tagId) { + if (!alreadyContainsTag(tags, tagId)) { + tags.add(tag) + } + + break + } + } + } catch (ignored: UnsupportedOperationException) { + + } + + } + } + return tags + } + + private fun alreadyContainsTag(list: List, idToCheck: String): Boolean { + for (t in list) { + if (t.getId() == idToCheck) { + return true + } + } + + return false + } +} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/utils/UserDeserializer.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/utils/UserDeserializer.kt index 97f4bd30e..689724bc6 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/utils/UserDeserializer.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/utils/UserDeserializer.kt @@ -1,5 +1,7 @@ package com.habitrpg.android.habitica.utils +import android.os.Trace +import com.google.firebase.perf.FirebasePerformance import com.google.gson.JsonDeserializationContext import com.google.gson.JsonDeserializer import com.google.gson.JsonElement @@ -21,6 +23,8 @@ import java.util.* class UserDeserializer : JsonDeserializer { @Throws(JsonParseException::class) override fun deserialize(json: JsonElement, typeOfT: Type, context: JsonDeserializationContext): User { + val deserializeTrace = FirebasePerformance.getInstance().newTrace("UserDeserialize") + deserializeTrace.start() val user = User() val obj = json.asJsonObject @@ -132,7 +136,7 @@ class UserDeserializer : JsonDeserializer { user.abTests?.add(test) } } - + deserializeTrace.stop() return user } } \ No newline at end of file