From e92a6c31f223e1328c94da8922d5e6a2396c8cbc Mon Sep 17 00:00:00 2001
From: Johannes Hoffmann <27806916+j-m-hoffmann@users.noreply.github.com>
Date: Thu, 4 Mar 2021 14:35:42 +0100
Subject: [PATCH 1/8] fix: increase contrast for timePicker buttons in new task
from 1.6 to 4.5
---
Habitica/res/values-night/colors.xml | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/Habitica/res/values-night/colors.xml b/Habitica/res/values-night/colors.xml
index 78b9bcde0..719e1e083 100644
--- a/Habitica/res/values-night/colors.xml
+++ b/Habitica/res/values-night/colors.xml
@@ -1,5 +1,6 @@
+ @color/brand_400
@color/brand_400
@color/gray_600
@color/gray_500
@@ -61,4 +62,4 @@
@color/white
@color/brand_50
@color/gray_10
-
\ No newline at end of file
+
From f20f7b13c31379aaa0311e7471f7dcb6637db225 Mon Sep 17 00:00:00 2001
From: Phillip Thelen
Date: Thu, 4 Mar 2021 11:29:11 +0100
Subject: [PATCH 2/8] Fix various minor issues
---
Habitica/build.gradle | 2 +-
Habitica/res/values-bg/strings.xml | 1 -
Habitica/res/values-en-rGB/strings.xml | 4 +--
Habitica/res/values-ru/strings.xml | 1 -
Habitica/res/values-zh-rTW/strings.xml | 3 +-
Habitica/res/values-zh/strings.xml | 3 +-
.../habitica/data/ContentRepository.kt | 1 +
.../implementation/ContentRepositoryImpl.kt | 11 +++----
.../data/implementation/UserRepositoryImpl.kt | 10 ++----
.../data/local/ContentLocalRepository.kt | 2 ++
.../RealmContentLocalRepository.kt | 13 ++++++++
.../extensions/Flowable-Extensions.kt | 5 +++
.../habitica/helpers/AppConfigManager.kt | 33 ++++++++++---------
.../android/habitica/models/WorldState.kt | 16 +++++----
.../habitica/models/WorldStateEvent.kt | 24 ++++++++++++++
.../android/habitica/modules/AppModule.java | 5 +--
.../android/habitica/ui/AvatarView.kt | 19 ++++++++---
.../ui/activities/GiftSubscriptionActivity.kt | 2 +-
.../ui/fragments/NavigationDrawerFragment.kt | 2 +-
.../ui/fragments/PromoInfoFragment.kt | 2 +-
.../purchases/GemsPurchaseFragment.kt | 2 +-
.../purchases/SubscriptionFragment.kt | 4 +--
.../habitica/ui/helpers/DataBindingUtils.kt | 2 +-
.../habitica/utils/WorldStateSerialization.kt | 18 +++++++---
24 files changed, 121 insertions(+), 64 deletions(-)
create mode 100644 Habitica/src/main/java/com/habitrpg/android/habitica/models/WorldStateEvent.kt
diff --git a/Habitica/build.gradle b/Habitica/build.gradle
index 2488a6b15..2b70e4e69 100644
--- a/Habitica/build.gradle
+++ b/Habitica/build.gradle
@@ -150,7 +150,7 @@ android {
buildConfigField "String", "TESTING_LEVEL", "\"production\""
resConfigs "en", "bg", "de", "en-rGB", "es", "fr", "hr-rHR", "in", "it", "iw", "ja", "ko", "lt", "nl", "pl", "pt-rBR", "pt-rPT", "ru", "tr", "zh", "zh-rTW"
- versionCode 2847
+ versionCode 2858
versionName "3.2.1"
}
diff --git a/Habitica/res/values-bg/strings.xml b/Habitica/res/values-bg/strings.xml
index 7f34d4aa8..a0fdcb1ed 100644
--- a/Habitica/res/values-bg/strings.xml
+++ b/Habitica/res/values-bg/strings.xml
@@ -344,7 +344,6 @@
Абониране
Александър Търговеца вече ще Ви продава диаманти на цената от 20 злато за диамант.\n\nМесечните му доставки отначало ще бъдат ограничени до 25 диаманта на месец, но може да се увеличат в зависимост от продължителността на абонамента Ви.\n\nОграничението се вдига с по 5 диаманта след всеки три месеца непрекъснат абонамент, докато не достигне 50 диаманта на месец!
Всеки месец ще получавате уникален козметичен предмет за героя си!\n\nОсвен това, за всеки три месеца непрекъснат абонамент, тайнствените пътешественици във времето ще Ви дават достъп до исторически козметични предмети (както и такива от бъдещето).
- Прави завършените задачи и историята на задачите налични за по-дълго време.
С двойно увеличеното ограничение на паданията ще получавате повече предмети от завършените си задачи всеки ден, което ще Ви помогне да завършите конюшнята си по-бързо!
Ограничение от 25 диаманта
Ограничение от 30 диаманта
diff --git a/Habitica/res/values-en-rGB/strings.xml b/Habitica/res/values-en-rGB/strings.xml
index 7575a9406..0918cdf79 100644
--- a/Habitica/res/values-en-rGB/strings.xml
+++ b/Habitica/res/values-en-rGB/strings.xml
@@ -393,8 +393,8 @@
Dailies are tasks that repeat on a regular basis. Choose the schedule that works for you!
You don\'t have any To Do\'s
To Do\'s are tasks that only need to be completed once. Add checklists to your To Do\'s to increase their value.
- You don’t have any Rewards
- Reset Justin’s Walkthrough
+ You don\'t have any Rewards
+ Reset Justins Walkthrough
Review our Community Guidelines before posting
Maintenance
Reload Content
diff --git a/Habitica/res/values-ru/strings.xml b/Habitica/res/values-ru/strings.xml
index 19afc99ed..35fbcf108 100644
--- a/Habitica/res/values-ru/strings.xml
+++ b/Habitica/res/values-ru/strings.xml
@@ -942,7 +942,6 @@
Вырастить питомца
Выполните эти задания и в итоге получите <b>5 достижений</b> и <font color=#EE9109><b>100 золота</b></font>!
%1$d / %2$d
- Подпишитесь сейчас, чтобы сразу же получить , а также получать новые предметы каждый месяц!
Удвойте количество выпадающих предметов
Личные сообщения заблокированы
Заблокировать получение личных сообщений
diff --git a/Habitica/res/values-zh-rTW/strings.xml b/Habitica/res/values-zh-rTW/strings.xml
index 825132fdf..c5097c126 100644
--- a/Habitica/res/values-zh-rTW/strings.xml
+++ b/Habitica/res/values-zh-rTW/strings.xml
@@ -339,7 +339,6 @@
加入會員
您將可以從市場上以每枚20金幣的價格購買寶石!
獲得神秘沙漏在時空穿越者的商店購買物品!
- 現在訂閱,可以得到贈品,和每月得到新的物品!
%d 個神秘沙漏
付款方式
訂閱
@@ -702,7 +701,7 @@
不想再繼續捐助了?你可以在Google應用商店裡的“我的應用程序”部分找到退訂選項。
在Habitica發現更多的物品,每天享受雙倍的物品掉落上限。
如果您變成訂閱者,您可以獲得紫禦鹿角兔寵物。
- 現在訂閱,可以得到%@和每月得到新的物品!
+ 現在訂閱,可以得到%s和每月得到新的物品!
雙倍掉落
創建一個帳戶
簽到%d次
diff --git a/Habitica/res/values-zh/strings.xml b/Habitica/res/values-zh/strings.xml
index b36f2c6eb..be6e5633c 100644
--- a/Habitica/res/values-zh/strings.xml
+++ b/Habitica/res/values-zh/strings.xml
@@ -344,7 +344,6 @@
订阅
您将可以从市场上以每枚20金币的价格购买宝石!
获得神秘沙漏在时空穿越者的商店购买物品!
- 现在订阅,可以得到赠品,和每月得到新的物品!
如果您变成订阅者,您可以获得紫御鹿角兔宠物。
25 宝石
30 宝石
@@ -898,7 +897,7 @@
Facebook登录
Apple登录
在Habitica发现更多的物品,每天享受双倍的物品掉落上限。
- 现在订阅,可以得到%@和每月得到新的物品!
+ 现在订阅,可以得到%s和每月得到新的物品!
双倍掉落
创建一个帐户
签到%d次
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/ContentRepository.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/data/ContentRepository.kt
index f72a0aa83..201fd838e 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/ContentRepository.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/ContentRepository.kt
@@ -12,4 +12,5 @@ interface ContentRepository {
fun retrieveContent(context: Context?, forced: Boolean): Flowable
fun retrieveWorldState(context: Context?): Flowable
+ fun getWorldState(): 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 61caa63e7..e154872f4 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
@@ -43,16 +43,13 @@ abstract class ContentRepositoryImpl(localRepository
lastWorldStateSync = now
apiClient.worldState.doOnNext {
localRepository.saveWorldState(it)
-
- val editor = PreferenceManager.getDefaultSharedPreferences(context).edit()
- editor.putString("currentEvent", it.currentEventKey)
- editor.putString("currentEventPromo", it.currentEventPromo)
- editor.putLong("currentEventStartDate", it.currentEventStartDate?.time ?: 0)
- editor.putLong("currentEventEndDate", it.currentEventEndDate?.time ?: 0)
- editor.apply()
}
} else {
Flowable.empty()
}
}
+
+ override fun getWorldState(): Flowable {
+ return localRepository.getWorldState()
+ }
}
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 c75388bc2..5c9bbcb80 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
@@ -5,6 +5,7 @@ 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.data.local.UserQuestStatus
+import com.habitrpg.android.habitica.extensions.skipNull
import com.habitrpg.android.habitica.helpers.AppConfigManager
import com.habitrpg.android.habitica.helpers.RxErrorHandler
import com.habitrpg.android.habitica.models.Achievement
@@ -164,7 +165,7 @@ class UserRepositoryImpl(localRepository: UserLocalRepository, apiClient: ApiCli
path = path.substring(1)
return Flowable.zip(apiClient.unlockPath(path), localRepository.getUser(userID).firstElement().toFlowable()
.map { localRepository.getUnmanagedCopy(it) }
- .skipNil(), { unlockResponse, copiedUser ->
+ .skipNull(), { unlockResponse, copiedUser ->
copiedUser.preferences = unlockResponse.preferences
copiedUser.purchased = unlockResponse.purchased
copiedUser.items = unlockResponse.items
@@ -380,7 +381,7 @@ class UserRepositoryImpl(localRepository: UserLocalRepository, apiClient: ApiCli
private fun getLiveUser(): Flowable {
return localRepository.getUser(userID)
.map { localRepository.getLiveObject(it) }
- .skipNil()
+ .skipNull()
}
private fun zipWithLiveUser(flowable: Flowable, mergeFunc: BiFunction): Flowable {
@@ -424,8 +425,3 @@ class UserRepositoryImpl(localRepository: UserLocalRepository, apiClient: ApiCli
return copiedUser
}
}
-
-private fun Flowable.skipNil(): Flowable {
- @Suppress("UNCHECKED_CAST")
- return skipWhile { it == null } as? Flowable ?: Flowable.empty()
-}
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/ContentLocalRepository.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/ContentLocalRepository.kt
index 4798a35d7..a3f601ab9 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/ContentLocalRepository.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/ContentLocalRepository.kt
@@ -2,8 +2,10 @@ package com.habitrpg.android.habitica.data.local
import com.habitrpg.android.habitica.models.ContentResult
import com.habitrpg.android.habitica.models.WorldState
+import io.reactivex.rxjava3.core.Flowable
interface ContentLocalRepository : BaseLocalRepository {
fun saveContent(contentResult: ContentResult)
fun saveWorldState(worldState: WorldState)
+ fun getWorldState(): Flowable
}
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmContentLocalRepository.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmContentLocalRepository.kt
index 36665ba91..5c89ffe95 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmContentLocalRepository.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmContentLocalRepository.kt
@@ -1,10 +1,13 @@
package com.habitrpg.android.habitica.data.local.implementation
import com.habitrpg.android.habitica.data.local.ContentLocalRepository
+import com.habitrpg.android.habitica.extensions.skipNull
import com.habitrpg.android.habitica.models.ContentResult
import com.habitrpg.android.habitica.models.WorldState
import com.habitrpg.android.habitica.models.inventory.Quest
import com.habitrpg.android.habitica.models.social.Group
+import hu.akarnokd.rxjava3.bridge.RxJavaBridge
+import io.reactivex.rxjava3.core.Flowable
import io.realm.Realm
@@ -33,6 +36,15 @@ open class RealmContentLocalRepository(realm: Realm) : RealmBaseLocalRepository(
}
}
+ override fun getWorldState(): Flowable {
+ return RxJavaBridge.toV3Flowable(realm.where(WorldState::class.java)
+ .findAll()
+ .asFlowable()
+ .filter { it.isLoaded && it.size > 0 }
+ .map { it.first() })
+ .skipNull()
+ }
+
override fun saveWorldState(worldState: WorldState) {
val tavern = getUnmanagedCopy(realm.where(Group::class.java)
.equalTo("id", Group.TAVERN_ID)
@@ -47,5 +59,6 @@ open class RealmContentLocalRepository(realm: Realm) : RealmBaseLocalRepository(
tavern.quest?.key = worldState.worldBossKey
tavern.quest?.progress = worldState.progress
save(tavern)
+ save(worldState)
}
}
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/extensions/Flowable-Extensions.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/extensions/Flowable-Extensions.kt
index ab67bc6db..4c4ba113b 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/extensions/Flowable-Extensions.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/extensions/Flowable-Extensions.kt
@@ -7,4 +7,9 @@ import io.reactivex.rxjava3.functions.Consumer
fun Flowable.subscribeWithErrorHandler(function: Consumer): Disposable {
return subscribe(function, RxErrorHandler.handleEmptyError())
+}
+
+fun Flowable.skipNull(): Flowable {
+ @Suppress("UNCHECKED_CAST")
+ return skipWhile { it == null } as? Flowable ?: Flowable.empty()
}
\ No newline at end of file
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/AppConfigManager.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/AppConfigManager.kt
index 09f1ef2cb..f565b3501 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/AppConfigManager.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/AppConfigManager.kt
@@ -6,16 +6,26 @@ import com.google.firebase.remoteconfig.FirebaseRemoteConfig
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import com.habitrpg.android.habitica.BuildConfig
+import com.habitrpg.android.habitica.data.ContentRepository
+import com.habitrpg.android.habitica.models.WorldState
import com.habitrpg.android.habitica.models.promotions.HabiticaPromotion
import com.habitrpg.android.habitica.models.promotions.getHabiticaPromotionFromKey
import java.util.*
-class AppConfigManager {
+class AppConfigManager(private val contentRepository: ContentRepository?) {
+
+ private var worldState: WorldState? = null
+
+ init {
+ contentRepository?.getWorldState()?.subscribe( {
+ worldState = it
+ }, RxErrorHandler.handleEmptyError())
+ }
private val remoteConfig = FirebaseRemoteConfig.getInstance()
fun shopSpriteSuffix(): String {
- return remoteConfig.getString("shopSpriteSuffix")
+ return worldState?.npcImageSuffix ?: remoteConfig.getString("shopSpriteSuffix")
}
fun maxChatLength(): Long {
@@ -59,10 +69,6 @@ class AppConfigManager {
return remoteConfig.getBoolean("enableLocalTaskScoring")
}
- fun flipAddTaskBehaviour(): Boolean {
- return remoteConfig.getBoolean("flipAddTaskBehaviour")
- }
-
fun insufficientGemPurchase(): Boolean {
return remoteConfig.getBoolean("insufficientGemPurchase")
}
@@ -100,15 +106,12 @@ class AppConfigManager {
return remoteConfig.getBoolean("enableAdventureGuide")
}
- fun activePromo(context: Context): HabiticaPromotion? {
- val preferences = PreferenceManager.getDefaultSharedPreferences(context)
- val key = preferences.getString("currentEvent", null)
- if (key?.isNotBlank() == true) {
- val startDateLong = preferences.getLong("currentEventStartDate", 0)
- val startDate = if (startDateLong > 0) Date(startDateLong) else null
- val endDateLong = preferences.getLong("currentEventEndDate", 0)
- val endDate = if (endDateLong > 0) Date(endDateLong) else null
- return getHabiticaPromotionFromKey(preferences.getString("currentEventPromo", null) ?: key, startDate, endDate)
+ fun activePromo(): HabiticaPromotion? {
+ for (event in worldState?.events ?: listOf(worldState?.currentEvent)) {
+ if (event == null) return null
+ if (event.promo != null) {
+ return getHabiticaPromotionFromKey(event.promo ?: "", event.start, event.end)
+ }
}
return null
}
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/models/WorldState.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/models/WorldState.kt
index 3cadec4ed..02b703fd8 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/models/WorldState.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/models/WorldState.kt
@@ -2,17 +2,19 @@ package com.habitrpg.android.habitica.models
import com.habitrpg.android.habitica.models.inventory.QuestProgress
import com.habitrpg.android.habitica.models.inventory.QuestRageStrike
+import io.realm.RealmList
+import io.realm.RealmModel
+import io.realm.RealmObject
import java.util.*
-class WorldState {
-
+open class WorldState: RealmObject() {
var worldBossKey: String = ""
var worldBossActive: Boolean = false
var progress: QuestProgress? = null
- var rageStrikes: MutableList? = null
+ var rageStrikes: RealmList? = null
- var currentEventKey: String? = null
- var currentEventPromo: String? = null
- var currentEventStartDate: Date? = null
- var currentEventEndDate: Date? = null
+ var npcImageSuffix: String? = null
+
+ var currentEvent: WorldStateEvent? = null
+ var events: RealmList = RealmList()
}
\ No newline at end of file
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/models/WorldStateEvent.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/models/WorldStateEvent.kt
new file mode 100644
index 000000000..de2219c16
--- /dev/null
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/models/WorldStateEvent.kt
@@ -0,0 +1,24 @@
+package com.habitrpg.android.habitica.models
+
+import com.google.gson.annotations.SerializedName
+import io.realm.RealmModel
+import io.realm.RealmObject
+import io.realm.annotations.PrimaryKey
+import java.util.*
+
+open class WorldStateEvent: RealmObject(), BaseObject {
+ @PrimaryKey
+ @SerializedName("event")
+ var eventKey: String? = null
+ var start: Date? = null
+ var end: Date? = null
+ var promo: String? = null
+ var npcImageSuffix: String? = null
+
+ override val realmClass: Class
+ get() = WorldStateEvent::class.java
+ override val primaryIdentifier: String?
+ get() = eventKey
+ override val primaryIdentifierName: String
+ get() = "eventKey"
+}
\ No newline at end of file
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/modules/AppModule.java b/Habitica/src/main/java/com/habitrpg/android/habitica/modules/AppModule.java
index 728630ab0..5b9d50519 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/modules/AppModule.java
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/modules/AppModule.java
@@ -8,6 +8,7 @@ import android.content.res.Resources;
import androidx.preference.PreferenceManager;
import com.habitrpg.android.habitica.data.ApiClient;
+import com.habitrpg.android.habitica.data.ContentRepository;
import com.habitrpg.android.habitica.executors.JobExecutor;
import com.habitrpg.android.habitica.executors.PostExecutionThread;
import com.habitrpg.android.habitica.executors.ThreadExecutor;
@@ -126,7 +127,7 @@ public class AppModule {
@Provides
@Singleton
- AppConfigManager providesRemoteConfigManager() {
- return new AppConfigManager();
+ AppConfigManager providesRemoteConfigManager(ContentRepository contentRepository) {
+ return new AppConfigManager(contentRepository);
}
}
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/AvatarView.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/AvatarView.kt
index 211053f05..41acac0f3 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/AvatarView.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/AvatarView.kt
@@ -50,6 +50,16 @@ class AvatarView : View {
return getLayerMap(avatar, true)
}
+ private var spriteSubstitutions: Map> = HashMap()
+ get() {
+ if (Date().time - (lastSubstitutionCheck?.time ?: 0) > 180000) {
+ field = AppConfigManager(null).spriteSubstitutions()
+ lastSubstitutionCheck = Date()
+ }
+ return field
+ }
+ private var lastSubstitutionCheck: Date? = null
+
private val originalRect: Rect
get() = if (showMount || showPet) FULL_HERO_RECT else if (showBackground) COMPACT_HERO_RECT else HERO_ONLY_RECT
@@ -151,8 +161,7 @@ class AvatarView : View {
}
private fun getLayerMap(avatar: Avatar, resetHasAttributes: Boolean): Map {
- val substitutions = AppConfigManager().spriteSubstitutions()
- val layerMap = getAvatarLayerMap(avatar, substitutions)
+ val layerMap = getAvatarLayerMap(avatar, spriteSubstitutions)
if (resetHasAttributes) {
hasPet = false
@@ -162,7 +171,7 @@ class AvatarView : View {
var mountName = avatar.currentMount
if (showMount && mountName?.isNotEmpty() == true) {
- mountName = substituteOrReturn(substitutions["mounts"], mountName)
+ mountName = substituteOrReturn(spriteSubstitutions["mounts"], mountName)
layerMap[LayerType.MOUNT_BODY] = "Mount_Body_$mountName"
layerMap[LayerType.MOUNT_HEAD] = "Mount_Head_$mountName"
if (resetHasAttributes) hasMount = true
@@ -170,14 +179,14 @@ class AvatarView : View {
var petName = avatar.currentPet
if (showPet && petName?.isNotEmpty() == true) {
- petName = substituteOrReturn(substitutions["pets"], petName)
+ petName = substituteOrReturn(spriteSubstitutions["pets"], petName)
layerMap[LayerType.PET] = "Pet-$petName"
if (resetHasAttributes) hasPet = true
}
var backgroundName = avatar.preferences?.background
if (showBackground && backgroundName?.isNotEmpty() == true) {
- backgroundName = substituteOrReturn(substitutions["backgrounds"], backgroundName)
+ backgroundName = substituteOrReturn(spriteSubstitutions["backgrounds"], backgroundName)
layerMap[LayerType.BACKGROUND] = "background_$backgroundName"
if (resetHasAttributes) hasBackground = true
}
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/GiftSubscriptionActivity.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/GiftSubscriptionActivity.kt
index d71e6a20e..34db00f38 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/GiftSubscriptionActivity.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/GiftSubscriptionActivity.kt
@@ -198,7 +198,7 @@ class GiftSubscriptionActivity : BaseActivity() {
}
private fun displayConfirmationDialog() {
- val message = getString(if (appConfigManager.activePromo(this)?.identifier == "g1g1"){
+ val message = getString(if (appConfigManager.activePromo()?.identifier == "g1g1"){
R.string.gift_confirmation_text_sub_g1g1
} else {
R.string.gift_confirmation_text_sub
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/NavigationDrawerFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/NavigationDrawerFragment.kt
index 43872f3cd..ba27d35de 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/NavigationDrawerFragment.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/NavigationDrawerFragment.kt
@@ -502,7 +502,7 @@ class NavigationDrawerFragment : DialogFragment() {
}
fun updatePromo() {
- activePromo = context?.let { configManager.activePromo(it) }
+ activePromo = configManager.activePromo()
val promoItem = getItemWithIdentifier(SIDEBAR_PROMO) ?: return
if (activePromo != null) {
promoItem.isVisible = true
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/PromoInfoFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/PromoInfoFragment.kt
index b3524874e..42adfbb40 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/PromoInfoFragment.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/PromoInfoFragment.kt
@@ -31,7 +31,7 @@ class PromoInfoFragment : BaseMainFragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
- val promo = context?.let { configManager.activePromo(it) }
+ val promo = configManager.activePromo()
promo?.configureInfoFragment(this)
}
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/purchases/GemsPurchaseFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/purchases/GemsPurchaseFragment.kt
index fa7c8ed43..7cd1b9ffb 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/purchases/GemsPurchaseFragment.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/purchases/GemsPurchaseFragment.kt
@@ -63,7 +63,7 @@ class GemsPurchaseFragment : BaseFragment(), GemPurc
binding?.headerImageView?.setImageResource(R.drawable.gem_purchase_header_dark)
}
- val promo = context?.let { appConfigManager.activePromo(it) }
+ val promo = appConfigManager.activePromo()
if (promo != null) {
binding?.let {
promo.configurePurchaseBanner(it)
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/purchases/SubscriptionFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/purchases/SubscriptionFragment.kt
index 149fe769c..38c5db502 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/purchases/SubscriptionFragment.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/purchases/SubscriptionFragment.kt
@@ -77,7 +77,7 @@ class SubscriptionFragment : BaseFragment(), GemPur
binding?.subscriptionDetails?.visibility = View.GONE
binding?.subscriptionDetails?.onShowSubscriptionOptions = { showSubscriptionOptions() }
- binding?.giftSubscriptionButton?.setOnClickListener { context?.let { context -> showGiftSubscriptionDialog(context, appConfigManager.activePromo(context)?.identifier == "g1g1") } }
+ binding?.giftSubscriptionButton?.setOnClickListener { context?.let { context -> showGiftSubscriptionDialog(context, appConfigManager.activePromo()?.identifier == "g1g1") } }
binding?.subscription1month?.setOnPurchaseClickListener { selectSubscription(PurchaseTypes.Subscription1Month) }
binding?.subscription3month?.setOnPurchaseClickListener { selectSubscription(PurchaseTypes.Subscription3Month) }
@@ -86,7 +86,7 @@ class SubscriptionFragment : BaseFragment(), GemPur
binding?.subscribeButton?.setOnClickListener { subscribeUser() }
- val promo = context?.let { appConfigManager.activePromo(it) }
+ val promo = appConfigManager.activePromo()
if (promo != null) {
binding?.let {
promo.configurePurchaseBanner(it)
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/helpers/DataBindingUtils.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/helpers/DataBindingUtils.kt
index 0f0552b5b..2107737b6 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/helpers/DataBindingUtils.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/helpers/DataBindingUtils.kt
@@ -132,7 +132,7 @@ object DataBindingUtils {
private var spriteSubstitutions: Map = HashMap()
get() {
if (Date().time - (lastSubstitutionCheck?.time ?: 0) > 180000) {
- field = AppConfigManager().spriteSubstitutions().get("generic") ?: HashMap()
+ field = AppConfigManager(null).spriteSubstitutions()["generic"] ?: HashMap()
lastSubstitutionCheck = Date()
}
return field
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/utils/WorldStateSerialization.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/utils/WorldStateSerialization.kt
index 01f2a0f67..2c5f136fd 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/utils/WorldStateSerialization.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/utils/WorldStateSerialization.kt
@@ -5,8 +5,10 @@ import com.google.gson.JsonDeserializer
import com.google.gson.JsonElement
import com.habitrpg.android.habitica.extensions.getAsString
import com.habitrpg.android.habitica.models.WorldState
+import com.habitrpg.android.habitica.models.WorldStateEvent
import com.habitrpg.android.habitica.models.inventory.QuestProgress
import com.habitrpg.android.habitica.models.inventory.QuestRageStrike
+import io.realm.RealmList
import java.lang.reflect.Type
import java.util.*
@@ -37,7 +39,7 @@ class WorldStateSerialization: JsonDeserializer {
val extra = worldBossObject["extra"].asJsonObject
if (extra.has("worldDmg")) {
val worldDmg = extra["worldDmg"].asJsonObject
- state.rageStrikes = mutableListOf()
+ state.rageStrikes = RealmList()
worldDmg.entrySet().forEach { (key, value) ->
val strike = QuestRageStrike(key, value.asBoolean)
state.rageStrikes?.add(strike)
@@ -46,14 +48,20 @@ class WorldStateSerialization: JsonDeserializer {
}
}
+ state.npcImageSuffix = json?.asJsonObject.getAsString("npcImageSuffix")
+
try {
if (json?.asJsonObject?.has("currentEvent") == true && json.asJsonObject?.get("currentEvent")?.isJsonObject == true) {
val event = json.asJsonObject?.getAsJsonObject("currentEvent")
if (event != null) {
- state.currentEventKey = event.getAsString("event")
- state.currentEventPromo = if (event.has("promo")) event.getAsString("promo") else null
- state.currentEventStartDate = context?.deserialize(event.get("start"), Date::class.java)
- state.currentEventEndDate = context?.deserialize(event.get("end"), Date::class.java)
+ state.currentEvent = context?.deserialize(event, WorldStateEvent::class.java)
+ }
+ if (json.asJsonObject.has("events")) {
+ val events = RealmList()
+ for (element in json.asJsonObject.getAsJsonArray("events")) {
+ context?.deserialize(element, WorldStateEvent::class.java)?.let { events.add(it) }
+ }
+ state.events = events
}
}
} catch (e: Exception) {
From 6176efdbb5cccdd353b56a3653b3ee76118ae911 Mon Sep 17 00:00:00 2001
From: Phillip Thelen
Date: Thu, 11 Mar 2021 14:39:36 +0100
Subject: [PATCH 3/8] Finish 3.2.1
---
Habitica/build.gradle | 2 +-
Habitica/res/values-es/strings.xml | 4 +-
.../data/implementation/UserRepositoryImpl.kt | 16 +-
.../models/auth/UserAuthResponse.java | 48 ------
.../habitica/models/auth/UserAuthResponse.kt | 15 ++
.../habitica/ui/activities/LoginActivity.kt | 4 +-
.../tasks/RewardsRecyclerviewFragment.kt | 3 +-
.../tasks/TaskRecyclerViewFragment.kt | 162 +++++++++---------
.../ui/fragments/tasks/TasksFragment.kt | 7 +-
.../ui/fragments/tasks/TeamBoardFragment.kt | 4 +-
fastlane/changelog.txt | 2 +-
11 files changed, 118 insertions(+), 149 deletions(-)
delete mode 100644 Habitica/src/main/java/com/habitrpg/android/habitica/models/auth/UserAuthResponse.java
create mode 100644 Habitica/src/main/java/com/habitrpg/android/habitica/models/auth/UserAuthResponse.kt
diff --git a/Habitica/build.gradle b/Habitica/build.gradle
index 2b70e4e69..a5273bfc5 100644
--- a/Habitica/build.gradle
+++ b/Habitica/build.gradle
@@ -150,7 +150,7 @@ android {
buildConfigField "String", "TESTING_LEVEL", "\"production\""
resConfigs "en", "bg", "de", "en-rGB", "es", "fr", "hr-rHR", "in", "it", "iw", "ja", "ko", "lt", "nl", "pl", "pt-rBR", "pt-rPT", "ru", "tr", "zh", "zh-rTW"
- versionCode 2858
+ versionCode 2868
versionName "3.2.1"
}
diff --git a/Habitica/res/values-es/strings.xml b/Habitica/res/values-es/strings.xml
index a84bd6ec3..4f5ea2ef9 100644
--- a/Habitica/res/values-es/strings.xml
+++ b/Habitica/res/values-es/strings.xml
@@ -935,8 +935,8 @@
%s Monturas
%s Mascotas
%s Tareas del Desafío
- Eliminar %s Tareas
- Mantener %s Tareas
+ Eliminar %d Tareas
+ Mantener %d Tareas
Desafío Terminado
Tu puedes enviar mensajes todavía, pero nadie puede enviartelas a ti. Puedes habilitarlo de nuevo desde Configuraciones.
Los Mensajes Privados están desactivados
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 5c9bbcb80..0b0fcef7f 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
@@ -39,16 +39,24 @@ class UserRepositoryImpl(localRepository: UserLocalRepository, apiClient: ApiCli
override fun getUser(userID: String): Flowable = localRepository.getUser(userID)
- override fun updateUser(updateData: Map): Flowable {
+ private fun updateUser(userID: String, updateData: Map): Flowable {
return Flowable.zip(apiClient.updateUser(updateData),
localRepository.getUser(userID).firstElement().toFlowable(),
{ newUser, user -> mergeUser(user, newUser) })
}
- override fun updateUser(key: String, value: Any): Flowable {
+ private fun updateUser(userID: String, key: String, value: Any): Flowable {
val updateData = HashMap()
updateData[key] = value
- return updateUser(updateData)
+ return updateUser(userID, updateData)
+ }
+
+ override fun updateUser(updateData: Map): Flowable {
+ return updateUser(userID, updateData)
+ }
+
+ override fun updateUser(key: String, value: Any): Flowable {
+ return updateUser(userID, key, value)
}
override fun retrieveUser(withTasks: Boolean): Flowable =
@@ -76,7 +84,7 @@ class UserRepositoryImpl(localRepository: UserLocalRepository, apiClient: ApiCli
val timeZone = calendar.timeZone
val offset = -TimeUnit.MINUTES.convert(timeZone.getOffset(calendar.timeInMillis).toLong(), TimeUnit.MILLISECONDS)
if (offset.toInt() != user.preferences?.timezoneOffset ?: 0) {
- return@flatMap updateUser("preferences.timezoneOffset", offset.toString())
+ return@flatMap updateUser(user.id ?: "", "preferences.timezoneOffset", offset.toString())
} else {
return@flatMap Flowable.just(user)
}
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/models/auth/UserAuthResponse.java b/Habitica/src/main/java/com/habitrpg/android/habitica/models/auth/UserAuthResponse.java
deleted file mode 100644
index a1cd8bc9a..000000000
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/models/auth/UserAuthResponse.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package com.habitrpg.android.habitica.models.auth;
-
-/**
- * Created by magicmicky on 04/02/15.
- */
-public class UserAuthResponse {
- //we need apiToken and token, as both are possible returns
- private String apiToken;
- private String token;
- private Boolean newUser = false;
- private String id;
-
- public String getToken() {
- if (this.token == null) {
- return this.apiToken;
- } else {
- return this.token;
- }
- }
-
- public void setToken(String token) {
- this.token = token;
- }
-
- public String getApiToken() {
- return apiToken;
- }
-
- public void setApiToken(String apiToken) {
- this.apiToken = apiToken;
- }
-
- public String getId() {
- return id;
- }
-
- public void setId(String id) {
- this.id = id;
- }
-
- public Boolean getNewUser() {
- return newUser;
- }
-
- public void setNewUser(Boolean newUser) {
- this.newUser = newUser;
- }
-}
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/models/auth/UserAuthResponse.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/models/auth/UserAuthResponse.kt
new file mode 100644
index 000000000..d788e8c6f
--- /dev/null
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/models/auth/UserAuthResponse.kt
@@ -0,0 +1,15 @@
+package com.habitrpg.android.habitica.models.auth
+
+class UserAuthResponse {
+ //we need apiToken and token, as both are possible returns
+ var apiToken: String = ""
+ var token: String
+ get() {
+ return apiToken
+ }
+ set(value) {
+ apiToken = value
+ }
+ var newUser = false
+ var id: String = ""
+}
\ No newline at end of file
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/LoginActivity.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/LoginActivity.kt
index 5e196d05c..8436cb154 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/LoginActivity.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/LoginActivity.kt
@@ -364,7 +364,7 @@ class LoginActivity : BaseActivity(), Consumer {
hideProgress()
dismissKeyboard()
try {
- saveTokens(userAuthResponse.token, userAuthResponse.id)
+ saveTokens(userAuthResponse.apiToken, userAuthResponse.id)
} catch (e: Exception) {
crashlyticsProxy.logException(e)
}
@@ -375,7 +375,7 @@ class LoginActivity : BaseActivity(), Consumer {
FirebaseAnalytics.getInstance(this).logEvent("user_registered", null)
}
- compositeSubscription.add(userRepository.retrieveUser(true)
+ compositeSubscription.add(userRepository.retrieveUser(true, true)
.subscribe({
if (userAuthResponse.newUser) {
this.startSetupActivity()
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/tasks/RewardsRecyclerviewFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/tasks/RewardsRecyclerviewFragment.kt
index a89cdb403..5ab6b244c 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/tasks/RewardsRecyclerviewFragment.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/tasks/RewardsRecyclerviewFragment.kt
@@ -14,7 +14,6 @@ import com.habitrpg.android.habitica.R
import com.habitrpg.android.habitica.extensions.subscribeWithErrorHandler
import com.habitrpg.android.habitica.helpers.RxErrorHandler
import com.habitrpg.android.habitica.models.shops.ShopItem
-import com.habitrpg.android.habitica.models.user.User
import com.habitrpg.android.habitica.ui.activities.MainActivity
import com.habitrpg.android.habitica.ui.activities.SkillMemberActivity
import com.habitrpg.android.habitica.ui.adapter.tasks.RewardsRecyclerViewAdapter
@@ -123,7 +122,7 @@ class RewardsRecyclerviewFragment : TaskRecyclerViewFragment() {
fun newInstance(context: Context?, classType: String, showCustomRewards: Boolean): RewardsRecyclerviewFragment {
val fragment = RewardsRecyclerviewFragment()
fragment.retainInstance = true
- fragment.classType = classType
+ fragment.taskType = classType
fragment.showCustomRewards = showCustomRewards
if (context != null) {
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/tasks/TaskRecyclerViewFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/tasks/TaskRecyclerViewFragment.kt
index 9414a7f0e..865244dbc 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/tasks/TaskRecyclerViewFragment.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/tasks/TaskRecyclerViewFragment.kt
@@ -28,8 +28,6 @@ import com.habitrpg.android.habitica.helpers.TaskFilterHelper
import com.habitrpg.android.habitica.models.responses.TaskDirection
import com.habitrpg.android.habitica.models.responses.TaskScoringResult
import com.habitrpg.android.habitica.models.tasks.Task
-import com.habitrpg.android.habitica.models.user.User
-import com.habitrpg.android.habitica.modules.AppModule
import com.habitrpg.android.habitica.ui.activities.MainActivity
import com.habitrpg.android.habitica.ui.activities.TaskFormActivity
import com.habitrpg.android.habitica.ui.adapter.BaseRecyclerViewAdapter
@@ -44,7 +42,6 @@ import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import java.util.*
import java.util.concurrent.TimeUnit
import javax.inject.Inject
-import javax.inject.Named
open class TaskRecyclerViewFragment : BaseFragment(), androidx.swiperefreshlayout.widget.SwipeRefreshLayout.OnRefreshListener {
internal var canEditTasks: Boolean = true
@@ -75,17 +72,17 @@ open class TaskRecyclerViewFragment : BaseFragment Unit) -> Unit)? = null
internal val className: String
- get() = this.classType ?: ""
+ get() = this.taskType ?: ""
// TODO needs a bit of cleanup
private fun setInnerAdapter() {
- val adapter: BaseRecyclerViewAdapter<*, *>? = when (this.classType) {
+ val adapter: BaseRecyclerViewAdapter<*, *>? = when (this.taskType) {
Task.TYPE_HABIT -> {
HabitsRecyclerViewAdapter(null, true, R.layout.habit_item_card, taskFilterHelper)
}
@@ -106,10 +103,29 @@ open class TaskRecyclerViewFragment : BaseFragment
HabiticaSnackbar.showSnackbar(activity.snackbarContainer, null, getString(R.string.notification_purchase_reward),
BitmapDrawable(resources, HabiticaIconsHelper.imageOfGold()),
@@ -123,7 +139,7 @@ open class TaskRecyclerViewFragment : BaseFragment if (direction == TaskDirection.UP) SoundManager.SoundPlusHabit else SoundManager.SoundMinusHabit
Task.TYPE_DAILY -> SoundManager.SoundDaily
Task.TYPE_TODO -> SoundManager.SoundTodo
@@ -160,13 +176,13 @@ open class TaskRecyclerViewFragment : BaseFragment taskFilterHelper.setActiveFilter(Task.TYPE_TODO, Task.FILTER_ACTIVE)
Task.TYPE_DAILY -> {
val user = (activity as? MainActivity)?.user
- if (user?.isValid == true && user?.preferences?.dailyDueDefaultView == true) {
+ if (user?.isValid == true && user.preferences?.dailyDueDefaultView == true) {
taskFilterHelper.setActiveFilter(Task.TYPE_DAILY, Task.FILTER_ACTIVE)
}
}
@@ -221,7 +237,7 @@ open class TaskRecyclerViewFragment : BaseFragment 0) {
- when (this.classType) {
- Task.TYPE_HABIT -> {
- binding?.emptyIconView?.setImageResource(R.drawable.icon_habits)
- binding?.emptyViewTitle?.setText(R.string.empty_title_habits_filtered)
- binding?.emptyViewDescription?.setText(R.string.empty_description_habits_filtered)
- }
- Task.TYPE_DAILY -> {
- binding?.emptyIconView?.setImageResource(R.drawable.icon_dailies)
- binding?.emptyViewTitle?.setText(R.string.empty_title_dailies_filtered)
- binding?.emptyViewDescription?.setText(R.string.empty_description_dailies_filtered)
- }
- Task.TYPE_TODO -> {
- binding?.emptyIconView?.setImageResource(R.drawable.icon_todos)
- binding?.emptyViewTitle?.setText(R.string.empty_title_todos_filtered)
- binding?.emptyViewDescription?.setText(R.string.empty_description_todos_filtered)
- }
- Task.TYPE_REWARD -> {
- binding?.emptyIconView?.setImageResource(R.drawable.icon_rewards)
- binding?.emptyViewTitle?.setText(R.string.empty_title_rewards)
- }
+ binding?.recyclerView?.setEmptyView(binding?.emptyView)
+ context?.let { binding?.emptyIconView?.setColorFilter(ContextCompat.getColor(it, R.color.text_dimmed), android.graphics.PorterDuff.Mode.MULTIPLY) }
+ if (taskFilterHelper.howMany(taskType) > 0) {
+ when (this.taskType) {
+ Task.TYPE_HABIT -> {
+ binding?.emptyIconView?.setImageResource(R.drawable.icon_habits)
+ binding?.emptyViewTitle?.setText(R.string.empty_title_habits_filtered)
+ binding?.emptyViewDescription?.setText(R.string.empty_description_habits_filtered)
}
- } else {
- when (this.classType) {
- Task.TYPE_HABIT -> {
- binding?.emptyIconView?.setImageResource(R.drawable.icon_habits)
- binding?.emptyViewTitle?.setText(R.string.empty_title_habits)
- binding?.emptyViewDescription?.setText(R.string.empty_description_habits)
- }
- Task.TYPE_DAILY -> {
- binding?.emptyIconView?.setImageResource(R.drawable.icon_dailies)
- binding?.emptyViewTitle?.setText(R.string.empty_title_dailies)
- binding?.emptyViewDescription?.setText(R.string.empty_description_dailies)
- }
- Task.TYPE_TODO -> {
- binding?.emptyIconView?.setImageResource(R.drawable.icon_todos)
- binding?.emptyViewTitle?.setText(R.string.empty_title_todos)
- binding?.emptyViewDescription?.setText(R.string.empty_description_todos)
- }
- Task.TYPE_REWARD -> {
- binding?.emptyIconView?.setImageResource(R.drawable.icon_rewards)
- binding?.emptyViewTitle?.setText(R.string.empty_title_rewards)
- }
+ Task.TYPE_DAILY -> {
+ binding?.emptyIconView?.setImageResource(R.drawable.icon_dailies)
+ binding?.emptyViewTitle?.setText(R.string.empty_title_dailies_filtered)
+ binding?.emptyViewDescription?.setText(R.string.empty_description_dailies_filtered)
+ }
+ Task.TYPE_TODO -> {
+ binding?.emptyIconView?.setImageResource(R.drawable.icon_todos)
+ binding?.emptyViewTitle?.setText(R.string.empty_title_todos_filtered)
+ binding?.emptyViewDescription?.setText(R.string.empty_description_todos_filtered)
+ }
+ Task.TYPE_REWARD -> {
+ binding?.emptyIconView?.setImageResource(R.drawable.icon_rewards)
+ binding?.emptyViewTitle?.setText(R.string.empty_title_rewards)
+ }
+ }
+ } else {
+ when (this.taskType) {
+ Task.TYPE_HABIT -> {
+ binding?.emptyIconView?.setImageResource(R.drawable.icon_habits)
+ binding?.emptyViewTitle?.setText(R.string.empty_title_habits)
+ binding?.emptyViewDescription?.setText(R.string.empty_description_habits)
+ }
+ Task.TYPE_DAILY -> {
+ binding?.emptyIconView?.setImageResource(R.drawable.icon_dailies)
+ binding?.emptyViewTitle?.setText(R.string.empty_title_dailies)
+ binding?.emptyViewDescription?.setText(R.string.empty_description_dailies)
+ }
+ Task.TYPE_TODO -> {
+ binding?.emptyIconView?.setImageResource(R.drawable.icon_todos)
+ binding?.emptyViewTitle?.setText(R.string.empty_title_todos)
+ binding?.emptyViewDescription?.setText(R.string.empty_description_todos)
+ }
+ Task.TYPE_REWARD -> {
+ binding?.emptyIconView?.setImageResource(R.drawable.icon_rewards)
+ binding?.emptyViewTitle?.setText(R.string.empty_title_rewards)
}
}
}
@@ -378,11 +371,11 @@ open class TaskRecyclerViewFragment : BaseFragment? = null
if (context != null) {
- when (fragment.classType) {
+ when (fragment.taskType) {
Task.TYPE_HABIT -> {
fragment.tutorialStepIdentifier = "habits"
tutorialTexts = listOf(context.getString(R.string.tutorial_overview), context.getString(R.string.tutorial_habits_1), context.getString(R.string.tutorial_habits_2), context.getString(R.string.tutorial_habits_3), context.getString(R.string.tutorial_habits_4))
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/tasks/TasksFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/tasks/TasksFragment.kt
index ab8969f13..0de033c00 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/tasks/TasksFragment.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/tasks/TasksFragment.kt
@@ -18,7 +18,6 @@ import com.habitrpg.android.habitica.extensions.getThemeColor
import com.habitrpg.android.habitica.extensions.setTintWith
import com.habitrpg.android.habitica.helpers.*
import com.habitrpg.android.habitica.models.tasks.Task
-import com.habitrpg.android.habitica.models.user.User
import com.habitrpg.android.habitica.modules.AppModule
import com.habitrpg.android.habitica.ui.activities.TaskFormActivity
import com.habitrpg.android.habitica.ui.fragments.BaseMainFragment
@@ -178,7 +177,7 @@ class TasksFragment : BaseMainFragment(), SearchView.O
disposable = tagRepository.getTags().subscribe({ tagsList -> dialog.setTags(tagsList)}, RxErrorHandler.handleEmptyError())
dialog.setActiveTags(taskFilterHelper.tags)
if (activeFragment != null) {
- val taskType = activeFragment?.classType
+ val taskType = activeFragment?.taskType
if (taskType != null) {
dialog.setTaskType(taskType, taskFilterHelper.getActiveFilter(taskType))
}
@@ -257,9 +256,9 @@ class TasksFragment : BaseMainFragment(), SearchView.O
}
private fun updateFilterIcon() {
- val filterCount = taskFilterHelper.howMany(activeFragment?.classType)
+ val filterCount = taskFilterHelper.howMany(activeFragment?.taskType)
- filterMenuItem?.isVisible = activeFragment?.classType != Task.TYPE_REWARD
+ filterMenuItem?.isVisible = activeFragment?.taskType != Task.TYPE_REWARD
if (filterCount == 0) {
filterMenuItem?.setIcon(R.drawable.ic_action_filter_list)
context?.let {
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/tasks/TeamBoardFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/tasks/TeamBoardFragment.kt
index feb7e923d..28f2d1e7c 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/tasks/TeamBoardFragment.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/tasks/TeamBoardFragment.kt
@@ -178,7 +178,7 @@ class TeamBoardFragment : BaseMainFragment(), SearchVi
disposable = tagRepository.getTags().subscribe({ tagsList -> dialog.setTags(tagsList)}, RxErrorHandler.handleEmptyError())
dialog.setActiveTags(taskFilterHelper.tags)
if (activeFragment != null) {
- val taskType = activeFragment?.classType
+ val taskType = activeFragment?.taskType
if (taskType != null) {
dialog.setTaskType(taskType, taskFilterHelper.getActiveFilter(taskType))
}
@@ -265,7 +265,7 @@ class TeamBoardFragment : BaseMainFragment(), SearchVi
}
var filterCount = 0
if (activeFragment != null) {
- filterCount = taskFilterHelper.howMany(activeFragment?.classType)
+ filterCount = taskFilterHelper.howMany(activeFragment?.taskType)
}
if (filterCount == 0) {
filterMenuItem?.setIcon(R.drawable.ic_action_filter_list)
diff --git a/fastlane/changelog.txt b/fastlane/changelog.txt
index c0c57196e..6057e994e 100644
--- a/fastlane/changelog.txt
+++ b/fastlane/changelog.txt
@@ -1 +1 @@
-In this update we've cleaned up Guilds and Challenges to look better than ever. Check them out and maybe find something new! Starting or leaving a Quest will update the Party view right away. Snowballs will actually transform your party members now. Certain notifications work better, bringing you to the right place and no longer crashing the app in some cases. Subscriber Mystery Boxes have a fancy new view when opening as well. Check these out and lots of other fixes by downloading the update!
+We’ve added the ability to select different default launch screens! Do you mainly use Dailies or find yourself constantly checking off To Do’s? Now you can set the app to automatically launch to either of those screens, and more! Go to Settings to explore the various launch screen options. We’ve also fixed a few bugs with views not updating automatically. Hope you enjoy this newest Habitica update!
From 07dfdd3f363b5f22f9fac4a077030a6349719ca0 Mon Sep 17 00:00:00 2001
From: Phillip Thelen
Date: Thu, 11 Mar 2021 14:56:23 +0100
Subject: [PATCH 4/8] fix g1g1 display issue
---
.../habitrpg/android/habitica/models/WorldStateEvent.kt | 1 +
.../habitica/ui/activities/GiftSubscriptionActivity.kt | 8 +++++++-
2 files changed, 8 insertions(+), 1 deletion(-)
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/models/WorldStateEvent.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/models/WorldStateEvent.kt
index de2219c16..7d8667db6 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/models/WorldStateEvent.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/models/WorldStateEvent.kt
@@ -14,6 +14,7 @@ open class WorldStateEvent: RealmObject(), BaseObject {
var end: Date? = null
var promo: String? = null
var npcImageSuffix: String? = null
+ var aprilFools: String? = null
override val realmClass: Class
get() = WorldStateEvent::class.java
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/GiftSubscriptionActivity.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/GiftSubscriptionActivity.kt
index 34db00f38..2bf9fed37 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/GiftSubscriptionActivity.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/GiftSubscriptionActivity.kt
@@ -86,6 +86,12 @@ class GiftSubscriptionActivity : BaseActivity() {
giftedUserID = it.id
giftedUsername = it.username
}, RxErrorHandler.handleEmptyError()))
+
+ if (appConfigManager.activePromo()?.identifier == "g1g1") {
+ binding.giftSubscriptionContainer.visibility = View.VISIBLE
+ } else {
+ binding.giftSubscriptionContainer.visibility = View.GONE
+ }
}
override fun onStart() {
@@ -198,7 +204,7 @@ class GiftSubscriptionActivity : BaseActivity() {
}
private fun displayConfirmationDialog() {
- val message = getString(if (appConfigManager.activePromo()?.identifier == "g1g1"){
+ val message = getString(if (appConfigManager.activePromo()?.identifier == "g1g1") {
R.string.gift_confirmation_text_sub_g1g1
} else {
R.string.gift_confirmation_text_sub
From abc930d217781db70744609c14bb5259212e56d5 Mon Sep 17 00:00:00 2001
From: Phillip Thelen
Date: Fri, 12 Mar 2021 13:20:58 +0100
Subject: [PATCH 5/8] Implement secret feature
---
Habitica/build.gradle | 4 +-
.../implementation/ContentRepositoryImpl.kt | 6 +++
.../habitica/helpers/AprilFoolsHandler.kt | 19 +++++++++
.../postProcessors/InvertPostProcessor.kt | 41 +++++++++++++++++++
.../android/habitica/models/WorldState.kt | 2 +
.../habitica/models/WorldStateEvent.kt | 6 +++
.../android/habitica/ui/AvatarView.kt | 29 +++++++------
.../habitica/ui/activities/MainActivity.kt | 23 ++++++-----
.../habitica/utils/WorldStateSerialization.kt | 4 +-
build.gradle | 4 +-
10 files changed, 108 insertions(+), 30 deletions(-)
create mode 100644 Habitica/src/main/java/com/habitrpg/android/habitica/helpers/AprilFoolsHandler.kt
create mode 100644 Habitica/src/main/java/com/habitrpg/android/habitica/helpers/postProcessors/InvertPostProcessor.kt
diff --git a/Habitica/build.gradle b/Habitica/build.gradle
index a5273bfc5..29b6331d7 100644
--- a/Habitica/build.gradle
+++ b/Habitica/build.gradle
@@ -150,8 +150,8 @@ android {
buildConfigField "String", "TESTING_LEVEL", "\"production\""
resConfigs "en", "bg", "de", "en-rGB", "es", "fr", "hr-rHR", "in", "it", "iw", "ja", "ko", "lt", "nl", "pl", "pt-rBR", "pt-rPT", "ru", "tr", "zh", "zh-rTW"
- versionCode 2868
- versionName "3.2.1"
+ versionCode 2871
+ versionName "3.2.2"
}
buildFeatures {
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 e154872f4..827bad464 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
@@ -5,6 +5,7 @@ import androidx.preference.PreferenceManager
import com.habitrpg.android.habitica.data.ApiClient
import com.habitrpg.android.habitica.data.ContentRepository
import com.habitrpg.android.habitica.data.local.ContentLocalRepository
+import com.habitrpg.android.habitica.helpers.AprilFoolsHandler
import com.habitrpg.android.habitica.models.ContentResult
import com.habitrpg.android.habitica.models.WorldState
import com.habitrpg.android.habitica.models.inventory.SpecialItem
@@ -43,6 +44,11 @@ abstract class ContentRepositoryImpl(localRepository
lastWorldStateSync = now
apiClient.worldState.doOnNext {
localRepository.saveWorldState(it)
+ for (event in it.events) {
+ if (event.aprilFools != null && event.isCurrentlyActive) {
+ AprilFoolsHandler.handle(event.aprilFools)
+ }
+ }
}
} else {
Flowable.empty()
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/AprilFoolsHandler.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/AprilFoolsHandler.kt
new file mode 100644
index 000000000..b653977a0
--- /dev/null
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/AprilFoolsHandler.kt
@@ -0,0 +1,19 @@
+package com.habitrpg.android.habitica.helpers
+
+import com.habitrpg.android.habitica.helpers.postProcessors.InvertPostProcessor
+import com.habitrpg.android.habitica.ui.AvatarView
+
+class AprilFoolsHandler {
+
+ companion object {
+ fun handle(name: String?) {
+ when(name) {
+ "invert" -> invertFools()
+ }
+ }
+
+ private fun invertFools() {
+ AvatarView.postProcessors[AvatarView.LayerType.PET] = { InvertPostProcessor() }
+ }
+ }
+}
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/postProcessors/InvertPostProcessor.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/postProcessors/InvertPostProcessor.kt
new file mode 100644
index 000000000..e9fbc99b8
--- /dev/null
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/postProcessors/InvertPostProcessor.kt
@@ -0,0 +1,41 @@
+package com.habitrpg.android.habitica.helpers.postProcessors
+
+import android.graphics.*
+import com.facebook.cache.common.CacheKey
+import com.facebook.cache.common.SimpleCacheKey
+import com.facebook.imagepipeline.request.BasePostprocessor
+
+
+class InvertPostProcessor: BasePostprocessor() {
+
+ override fun getName(): String {
+ return "invertPostProcessor"
+ }
+
+
+ override fun process(bitmap: Bitmap) {
+ val canvas = Canvas(bitmap)
+ val paint = Paint()
+
+ val matrixGrayscale = ColorMatrix()
+ matrixGrayscale.setSaturation(0f)
+
+ val matrixInvert = ColorMatrix()
+ matrixInvert.set(floatArrayOf(
+ -1.0f, 0.0f, 0.0f, 0.0f, 255.0f,
+ 0.0f, -1.0f, 0.0f, 0.0f, 255.0f,
+ 0.0f, 0.0f, -1.0f, 0.0f, 255.0f,
+ 0.0f, 0.0f, 0.0f, 1.0f, 0.0f
+ ))
+ matrixInvert.preConcat(matrixGrayscale)
+
+ val filter = ColorMatrixColorFilter(matrixInvert)
+ paint.colorFilter = filter
+
+ canvas.drawBitmap(bitmap, 0f, 0f, paint)
+ }
+
+ override fun getPostprocessorCacheKey(): CacheKey {
+ return SimpleCacheKey("0")
+ }
+}
\ No newline at end of file
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/models/WorldState.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/models/WorldState.kt
index 02b703fd8..6192d2f8f 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/models/WorldState.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/models/WorldState.kt
@@ -1,5 +1,6 @@
package com.habitrpg.android.habitica.models
+import com.google.gson.annotations.SerializedName
import com.habitrpg.android.habitica.models.inventory.QuestProgress
import com.habitrpg.android.habitica.models.inventory.QuestRageStrike
import io.realm.RealmList
@@ -16,5 +17,6 @@ open class WorldState: RealmObject() {
var npcImageSuffix: String? = null
var currentEvent: WorldStateEvent? = null
+ @SerializedName("currentEventList")
var events: RealmList = RealmList()
}
\ No newline at end of file
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/models/WorldStateEvent.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/models/WorldStateEvent.kt
index 7d8667db6..0cb6e43a0 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/models/WorldStateEvent.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/models/WorldStateEvent.kt
@@ -7,6 +7,12 @@ import io.realm.annotations.PrimaryKey
import java.util.*
open class WorldStateEvent: RealmObject(), BaseObject {
+ val isCurrentlyActive: Boolean
+ get() {
+ val now = Date()
+ return (start?.before(now) == true) && (end?.after(now) == true)
+ }
+
@PrimaryKey
@SerializedName("event")
var eventKey: String? = null
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/AvatarView.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/AvatarView.kt
index 41acac0f3..76c3d3479 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/AvatarView.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/AvatarView.kt
@@ -4,6 +4,7 @@ import android.content.Context
import android.graphics.*
import android.graphics.drawable.Animatable
import android.graphics.drawable.Drawable
+import android.net.Uri
import android.text.TextUtils
import android.util.AttributeSet
import android.util.Log
@@ -15,6 +16,8 @@ import com.facebook.drawee.generic.GenericDraweeHierarchyBuilder
import com.facebook.drawee.view.DraweeHolder
import com.facebook.drawee.view.MultiDraweeHolder
import com.facebook.imagepipeline.image.ImageInfo
+import com.facebook.imagepipeline.request.BasePostprocessor
+import com.facebook.imagepipeline.request.ImageRequestBuilder
import com.habitrpg.android.habitica.BuildConfig
import com.habitrpg.android.habitica.R
import com.habitrpg.android.habitica.helpers.AppConfigManager
@@ -60,7 +63,6 @@ class AvatarView : View {
}
private var lastSubstitutionCheck: Date? = null
-
private val originalRect: Rect
get() = if (showMount || showPet) FULL_HERO_RECT else if (showBackground) COMPACT_HERO_RECT else HERO_ONLY_RECT
@@ -132,8 +134,14 @@ class AvatarView : View {
draweeHolder.topLevelDrawable?.callback = this
multiDraweeHolder.add(draweeHolder)
+ val uri = Uri.parse(IMAGE_URI_ROOT + DataBindingUtils.getFullFilename(layerName, null))
+ var request = ImageRequestBuilder.newBuilderWithSource(uri)
+ postProcessors[layerKey]?.let {
+ request = request.setPostprocessor(it())
+ }
+
val controller = Fresco.newDraweeControllerBuilder()
- .setUri(IMAGE_URI_ROOT + DataBindingUtils.getFullFilename(layerName, null))
+ .setImageRequest(request.build())
.setControllerListener(object : BaseControllerListener() {
override fun onFinalImageSet(
id: String?,
@@ -252,6 +260,7 @@ class AvatarView : View {
hasVisualBuffs = true
}
+ val hair = prefs.hair
if (!hasVisualBuffs) {
if (!TextUtils.isEmpty(prefs.chair)) {
layerMap[LayerType.CHAIR] = prefs.chair
@@ -288,7 +297,6 @@ class AvatarView : View {
layerMap[LayerType.SHIRT] = prefs.size + "_shirt_" + prefs.shirt
layerMap[LayerType.HEAD_0] = "head_0"
- val hair = prefs.hair
if (hair != null) {
val hairColor = hair.color
@@ -304,17 +312,11 @@ class AvatarView : View {
if (hair.isAvailable(hair.beard)) {
layerMap[LayerType.HAIR_BEARD] = "hair_beard_" + hair.beard + "_" + hairColor
}
- if (hair.isAvailable(hair.flower)) {
- layerMap[LayerType.HAIR_FLOWER] = "hair_flower_" + hair.flower
- }
}
- } else {
- val hair = prefs.hair
+ }
- // Show flower all the time!
- if (hair != null && hair.isAvailable(hair.flower)) {
- layerMap[LayerType.HAIR_FLOWER] = "hair_flower_" + hair.flower
- }
+ if (hair != null && hair.isAvailable(hair.flower)) {
+ layerMap[LayerType.HAIR_FLOWER] = "hair_flower_" + hair.flower
}
return layerMap
@@ -418,7 +420,7 @@ class AvatarView : View {
val equals = currentLayers != null && currentLayers == newLayerMap
- if (!equals) {
+ if (!equals || postProcessors.isNotEmpty()) {
multiDraweeHolder.clear()
numberLayersInProcess.set(0)
}
@@ -530,5 +532,6 @@ class AvatarView : View {
private val COMPACT_HERO_RECT = Rect(0, 0, 114, 114)
private val HERO_ONLY_RECT = Rect(0, 0, 90, 90)
+ val postProcessors: MutableMap BasePostprocessor)> = mutableMapOf()
}
}
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 289994a9a..ff50271fc 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
@@ -634,17 +634,18 @@ open class MainActivity : BaseActivity(), TutorialView.OnTutorialReaction {
protected fun retrieveUser(forced: Boolean = false) {
if (hostConfig.hasAuthentication()) {
- compositeSubscription.add(this.userRepository.retrieveUser(true, forced)
- .doOnNext { user1 ->
- FirebaseAnalytics.getInstance(this).setUserProperty("has_party", if (user1.party?.id?.isNotEmpty() == true) "true" else "false")
- FirebaseAnalytics.getInstance(this).setUserProperty("is_subscribed", if (user1.isSubscribed) "true" else "false")
- pushNotificationManager.setUser(user1)
- pushNotificationManager.addPushDeviceUsingStoredToken()
- }
- .flatMap { userRepository.retrieveTeamPlans() }
- .flatMap { contentRepository.retrieveContent(this,false) }
- .flatMap { contentRepository.retrieveWorldState(this) }
- .subscribe({ }, RxErrorHandler.handleEmptyError()))
+ compositeSubscription.add(
+ contentRepository.retrieveWorldState(this)
+ .flatMap { userRepository.retrieveUser(true, forced) }
+ .doOnNext { user1 ->
+ FirebaseAnalytics.getInstance(this).setUserProperty("has_party", if (user1.party?.id?.isNotEmpty() == true) "true" else "false")
+ FirebaseAnalytics.getInstance(this).setUserProperty("is_subscribed", if (user1.isSubscribed) "true" else "false")
+ pushNotificationManager.setUser(user1)
+ pushNotificationManager.addPushDeviceUsingStoredToken()
+ }
+ .flatMap { userRepository.retrieveTeamPlans() }
+ .flatMap { contentRepository.retrieveContent(this) }
+ .subscribe({ }, RxErrorHandler.handleEmptyError()))
}
}
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/utils/WorldStateSerialization.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/utils/WorldStateSerialization.kt
index 2c5f136fd..2bd8c155b 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/utils/WorldStateSerialization.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/utils/WorldStateSerialization.kt
@@ -56,9 +56,9 @@ class WorldStateSerialization: JsonDeserializer {
if (event != null) {
state.currentEvent = context?.deserialize(event, WorldStateEvent::class.java)
}
- if (json.asJsonObject.has("events")) {
+ if (json.asJsonObject.has("currentEventList")) {
val events = RealmList()
- for (element in json.asJsonObject.getAsJsonArray("events")) {
+ for (element in json.asJsonObject.getAsJsonArray("currentEventList")) {
context?.deserialize(element, WorldStateEvent::class.java)?.let { events.add(it) }
}
state.events = events
diff --git a/build.gradle b/build.gradle
index e5e34869a..6fb4d83f7 100644
--- a/build.gradle
+++ b/build.gradle
@@ -14,12 +14,12 @@ buildscript {
classpath 'com.android.tools.build:gradle:4.1.2'
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
classpath 'com.google.gms:google-services:4.3.5'
- classpath 'com.google.firebase:firebase-crashlytics-gradle:2.5.0'
+ classpath 'com.google.firebase:firebase-crashlytics-gradle:2.5.1'
classpath "io.realm:realm-gradle-plugin:10.3.0"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "io.gitlab.arturbosch.detekt:detekt-gradle-plugin:1.1.0"
classpath "android.arch.navigation:navigation-safe-args-gradle-plugin:1.0.0"
- classpath 'com.google.firebase:perf-plugin:1.3.4'
+ classpath 'com.google.firebase:perf-plugin:1.3.5'
}
}
From e19af2526bb2a1749250d4883bac1f6b25cb18ec Mon Sep 17 00:00:00 2001
From: Phillip Thelen
Date: Wed, 31 Mar 2021 12:14:33 +0200
Subject: [PATCH 6/8] Fix party launch screen option
---
Habitica/build.gradle | 2 +-
Habitica/res/values-tr/strings.xml | 2 +-
.../implementation/ContentRepositoryImpl.kt | 2 +-
.../habitica/helpers/AprilFoolsHandler.kt | 17 +++++-
.../HabiticaFirebaseMessagingService.kt | 5 +-
.../notifications/PushNotificationManager.kt | 3 +
.../postProcessors/InvertPostProcessor.kt | 4 --
.../android/habitica/ui/AvatarView.kt | 2 +-
.../ui/activities/FullProfileActivity.kt | 4 +-
.../habitica/ui/activities/MainActivity.kt | 2 +-
.../tasks/TaskRecyclerViewFragment.kt | 59 ++++++++++---------
.../habitica/utils/ChallengeDeserializer.kt | 4 +-
12 files changed, 62 insertions(+), 44 deletions(-)
diff --git a/Habitica/build.gradle b/Habitica/build.gradle
index 29b6331d7..c549b4f45 100644
--- a/Habitica/build.gradle
+++ b/Habitica/build.gradle
@@ -150,7 +150,7 @@ android {
buildConfigField "String", "TESTING_LEVEL", "\"production\""
resConfigs "en", "bg", "de", "en-rGB", "es", "fr", "hr-rHR", "in", "it", "iw", "ja", "ko", "lt", "nl", "pl", "pt-rBR", "pt-rPT", "ru", "tr", "zh", "zh-rTW"
- versionCode 2871
+ versionCode 2895
versionName "3.2.2"
}
diff --git a/Habitica/res/values-tr/strings.xml b/Habitica/res/values-tr/strings.xml
index 53dd24872..4ac8f7066 100644
--- a/Habitica/res/values-tr/strings.xml
+++ b/Habitica/res/values-tr/strings.xml
@@ -994,7 +994,7 @@
Güncelleme uygun: %1$s (%2$d)
Seri
Atanan İstatistik
- Aşağıdaki kullanıcı adını bir arkadaşınıza verin veya potansiyel yoldaşlarla tanışmak için % s gidin!
+ Aşağıdaki kullanıcı adını bir arkadaşınıza verin veya potansiyel yoldaşlarla tanışmak için %s gidin!
Değerli Taş Satışı, bu yılki Sonbahar Galasının en sonunda tekrar gündeme geldi! Bu, her zamankinden daha fazla Mücevher almak için son bir şans, bu yüzden bu süre boyunca stok yapın!
Bu promosyon yalnızca sınırlı süreli etkinlik sırasında geçerlidir. Bu etkinlik 29 Ekim\'de 08:00 EDT\'de (12:00 UTC) başlayacak ve 2 Kasım 20:00 EDT\'de (00:00 UTC) sona erecek. Promosyon teklifi yalnızca kendiniz için Mücevher satın alırken geçerlidir.
29 Ekim ile 2 Kasım arasında, her zamanki gibi herhangi bir Mücevher paketi satın alın ve hesabınıza promosyon miktarda Mücevher yatırılacaktır. Gelecek sürümler için harcayabileceğiniz, paylaşabileceğiniz veya saklayabileceğiniz daha fazla Mücevher!
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 827bad464..e636f35a1 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
@@ -46,7 +46,7 @@ abstract class ContentRepositoryImpl(localRepository
localRepository.saveWorldState(it)
for (event in it.events) {
if (event.aprilFools != null && event.isCurrentlyActive) {
- AprilFoolsHandler.handle(event.aprilFools)
+ AprilFoolsHandler.handle(event.aprilFools, event.end)
}
}
}
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/AprilFoolsHandler.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/AprilFoolsHandler.kt
index b653977a0..396e9a57e 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/AprilFoolsHandler.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/AprilFoolsHandler.kt
@@ -1,19 +1,32 @@
package com.habitrpg.android.habitica.helpers
+import com.facebook.imagepipeline.request.BasePostprocessor
import com.habitrpg.android.habitica.helpers.postProcessors.InvertPostProcessor
import com.habitrpg.android.habitica.ui.AvatarView
+import java.util.*
class AprilFoolsHandler {
companion object {
- fun handle(name: String?) {
+ var eventEnd = Date(2020, 3, 1)
+
+ fun handle(name: String?, endDate: Date?) {
+ if (endDate != null) {
+ this.eventEnd = endDate
+ }
when(name) {
"invert" -> invertFools()
}
}
private fun invertFools() {
- AvatarView.postProcessors[AvatarView.LayerType.PET] = { InvertPostProcessor() }
+ AvatarView.postProcessors[AvatarView.LayerType.PET] = {
+ if (Date().after(eventEnd)) {
+ null
+ } else {
+ InvertPostProcessor()
+ }
+ }
}
}
}
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/notifications/HabiticaFirebaseMessagingService.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/notifications/HabiticaFirebaseMessagingService.kt
index 12395505b..1c67078d1 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/notifications/HabiticaFirebaseMessagingService.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/notifications/HabiticaFirebaseMessagingService.kt
@@ -17,16 +17,13 @@ class HabiticaFirebaseMessagingService : FirebaseMessagingService() {
@Inject
internal lateinit var pushNotificationManager: PushNotificationManager
- @Inject
- internal lateinit var userRepository: UserRepository
-
override fun onMessageReceived(remoteMessage: RemoteMessage) {
userComponent?.inject(this)
if (this::pushNotificationManager.isInitialized) {
pushNotificationManager.displayNotification(remoteMessage)
if (remoteMessage.data["identifier"]?.contains(PushNotificationManager.WON_CHALLENGE_PUSH_NOTIFICATION_KEY) == true) {
- userRepository.retrieveUser(true).subscribe({}, RxErrorHandler.handleEmptyError())
+ //userRepository.retrieveUser(true).subscribe({}, RxErrorHandler.handleEmptyError())
}
}
}
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/notifications/PushNotificationManager.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/notifications/PushNotificationManager.kt
index ac9324e7f..410d96f34 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/notifications/PushNotificationManager.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/notifications/PushNotificationManager.kt
@@ -32,6 +32,9 @@ class PushNotificationManager(var apiClient: ApiClient, private val sharedPrefer
fun addPushDeviceUsingStoredToken() {
FirebaseMessaging.getInstance().token.addOnCompleteListener {
+ if (!it.isSuccessful) {
+ return@addOnCompleteListener
+ }
this.refreshedToken = it.result
if (this.refreshedToken.isEmpty() || this.user == null || this.userHasPushDevice() || !this.userIsSubscribedToNotifications()) {
return@addOnCompleteListener
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/postProcessors/InvertPostProcessor.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/postProcessors/InvertPostProcessor.kt
index e9fbc99b8..734b2e598 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/postProcessors/InvertPostProcessor.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/postProcessors/InvertPostProcessor.kt
@@ -17,9 +17,6 @@ class InvertPostProcessor: BasePostprocessor() {
val canvas = Canvas(bitmap)
val paint = Paint()
- val matrixGrayscale = ColorMatrix()
- matrixGrayscale.setSaturation(0f)
-
val matrixInvert = ColorMatrix()
matrixInvert.set(floatArrayOf(
-1.0f, 0.0f, 0.0f, 0.0f, 255.0f,
@@ -27,7 +24,6 @@ class InvertPostProcessor: BasePostprocessor() {
0.0f, 0.0f, -1.0f, 0.0f, 255.0f,
0.0f, 0.0f, 0.0f, 1.0f, 0.0f
))
- matrixInvert.preConcat(matrixGrayscale)
val filter = ColorMatrixColorFilter(matrixInvert)
paint.colorFilter = filter
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/AvatarView.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/AvatarView.kt
index 76c3d3479..d2002b384 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/AvatarView.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/AvatarView.kt
@@ -532,6 +532,6 @@ class AvatarView : View {
private val COMPACT_HERO_RECT = Rect(0, 0, 114, 114)
private val HERO_ONLY_RECT = Rect(0, 0, 90, 90)
- val postProcessors: MutableMap BasePostprocessor)> = mutableMapOf()
+ val postProcessors: MutableMap BasePostprocessor?)> = mutableMapOf()
}
}
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/FullProfileActivity.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/FullProfileActivity.kt
index cc354aab7..c0cf94b12 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/FullProfileActivity.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/FullProfileActivity.kt
@@ -371,7 +371,9 @@ class FullProfileActivity : BaseActivity() {
binding.equipmentTableLayout.removeAllViews()
for (index in 1 until binding.attributesTableLayout.childCount) {
- binding.attributesTableLayout.removeViewAt(index)
+ if (binding.attributesTableLayout != null) {
+ binding.attributesTableLayout.removeViewAt(index)
+ }
}
addLevelAttributes(user)
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 ff50271fc..c3ecb7be0 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
@@ -364,7 +364,7 @@ open class MainActivity : BaseActivity(), TutorialView.OnTutorialReaction {
when (launchScreen) {
"/party" -> {
- if (user?.party?.id != null) {
+ if (user == null || user?.party?.id != null) {
MainNavigationController.navigate(R.id.partyFragment)
}
}
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/tasks/TaskRecyclerViewFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/tasks/TaskRecyclerViewFragment.kt
index 865244dbc..609b515a0 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/tasks/TaskRecyclerViewFragment.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/tasks/TaskRecyclerViewFragment.kt
@@ -39,6 +39,7 @@ import com.habitrpg.android.habitica.ui.views.HabiticaIconsHelper
import com.habitrpg.android.habitica.ui.views.HabiticaSnackbar
import com.habitrpg.android.habitica.ui.views.dialogs.HabiticaAlertDialog
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
+import io.reactivex.rxjava3.disposables.CompositeDisposable
import java.util.*
import java.util.concurrent.TimeUnit
import javax.inject.Inject
@@ -52,6 +53,7 @@ open class TaskRecyclerViewFragment : BaseFragment Unit) -> Unit)? = null
internal val className: String
- get() = this.taskType ?: ""
+ get() = this.taskType
// TODO needs a bit of cleanup
private fun setInnerAdapter() {
+ if (binding?.recyclerView?.adapter != null && binding?.recyclerView?.adapter == recyclerAdapter && !recyclerSubscription.isDisposed) {
+ return
+ }
+ if (!recyclerSubscription.isDisposed) {
+ recyclerSubscription.dispose()
+ }
+ recyclerSubscription = CompositeDisposable()
val adapter: BaseRecyclerViewAdapter<*, *>? = when (this.taskType) {
- Task.TYPE_HABIT -> {
- HabitsRecyclerViewAdapter(null, true, R.layout.habit_item_card, taskFilterHelper)
- }
- Task.TYPE_DAILY -> {
- DailiesRecyclerViewHolder(null, true, R.layout.daily_item_card, taskFilterHelper)
- }
- Task.TYPE_TODO -> {
- TodosRecyclerViewAdapter(null, true, R.layout.todo_item_card, taskFilterHelper)
- }
- Task.TYPE_REWARD -> {
- RewardsRecyclerViewAdapter(null, R.layout.reward_item_card)
- }
+ Task.TYPE_HABIT -> HabitsRecyclerViewAdapter(null, true, R.layout.habit_item_card, taskFilterHelper)
+ Task.TYPE_DAILY -> DailiesRecyclerViewHolder(null, true, R.layout.daily_item_card, taskFilterHelper)
+ Task.TYPE_TODO -> TodosRecyclerViewAdapter(null, true, R.layout.todo_item_card, taskFilterHelper)
+ Task.TYPE_REWARD -> RewardsRecyclerViewAdapter(null, R.layout.reward_item_card)
else -> null
}
@@ -106,19 +107,19 @@ open class TaskRecyclerViewFragment : BaseFragment
- recyclerAdapter?.filter()
layoutManager = getLayoutManager(context)
layoutManager?.isItemPrefetchEnabled = false
binding?.recyclerView?.layoutManager = layoutManager
- if (binding?.recyclerView?.adapter == null) {
- this.setInnerAdapter()
- }
+ this.setInnerAdapter()
allowReordering()
@@ -384,14 +383,20 @@ open class TaskRecyclerViewFragment : BaseFragment, JsonSerializer
Date: Wed, 31 Mar 2021 13:14:01 +0200
Subject: [PATCH 7/8] Fixes #1522
---
Habitica/res/layout/skill_list_item.xml | 6 ++++--
Habitica/res/layout/skill_task_item_card.xml | 13 ++++++-------
.../ui/adapter/SkillTasksRecyclerViewAdapter.kt | 3 ++-
3 files changed, 12 insertions(+), 10 deletions(-)
diff --git a/Habitica/res/layout/skill_list_item.xml b/Habitica/res/layout/skill_list_item.xml
index 6e3d86832..e0923e044 100644
--- a/Habitica/res/layout/skill_list_item.xml
+++ b/Habitica/res/layout/skill_list_item.xml
@@ -58,11 +58,13 @@
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_horizontal"/>
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_horizontal" />
-
-
+ android:background="@color/red_10"/>
+
Date: Wed, 31 Mar 2021 13:28:49 +0200
Subject: [PATCH 8/8] Fixes #1520
---
.../habitica/ui/fragments/inventory/shops/ShopFragment.kt | 3 +++
1 file changed, 3 insertions(+)
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/shops/ShopFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/shops/ShopFragment.kt
index 5bdb411ca..1ed986100 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/shops/ShopFragment.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/shops/ShopFragment.kt
@@ -164,6 +164,9 @@ open class ShopFragment : BaseMainFragment() {
}
if (shop1.identifier == Shop.TIME_TRAVELERS_SHOP) {
formatTimeTravelersShop(shop1)
+ } else if (shop1.identifier == Shop.SEASONAL_SHOP) {
+ shop1.categories.reverse()
+ shop1
} else {
shop1
}