diff --git a/Habitica/AndroidManifest.xml b/Habitica/AndroidManifest.xml
index 128c8bab5..d453c944a 100644
--- a/Habitica/AndroidManifest.xml
+++ b/Habitica/AndroidManifest.xml
@@ -7,6 +7,7 @@
+
diff --git a/Habitica/build.gradle b/Habitica/build.gradle
index 9b19c603b..38e49f375 100644
--- a/Habitica/build.gradle
+++ b/Habitica/build.gradle
@@ -51,10 +51,10 @@ dependencies {
compileOnly 'javax.annotation:javax.annotation-api:1.3.2'
compileOnly 'com.github.pengrad:jdk9-deps:1.0'
//App Compatibility and Material Design
- implementation 'androidx.appcompat:appcompat:1.4.0'
- implementation 'com.google.android.material:material:1.4.0'
+ implementation 'androidx.appcompat:appcompat:1.4.1'
+ implementation 'com.google.android.material:material:1.5.0'
implementation 'androidx.recyclerview:recyclerview:1.2.1'
- implementation "androidx.preference:preference-ktx:1.1.1"
+ implementation "androidx.preference:preference-ktx:1.2.0"
// Markdown
@@ -121,10 +121,10 @@ dependencies {
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.4.0"
implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.4.0"
implementation "androidx.lifecycle:lifecycle-common-java8:2.4.0"
- implementation 'androidx.navigation:navigation-fragment-ktx:2.3.5'
- implementation 'androidx.navigation:navigation-ui-ktx:2.3.5'
+ implementation 'androidx.navigation:navigation-fragment-ktx:2.4.0'
+ implementation 'androidx.navigation:navigation-ui-ktx:2.4.0'
implementation 'com.plattysoft.leonids:LeonidsLib:1.3.2'
- implementation "androidx.fragment:fragment-ktx:1.4.0"
+ implementation "androidx.fragment:fragment-ktx:1.4.1"
implementation "androidx.paging:paging-runtime-ktx:3.1.0"
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.0'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.0'
@@ -142,7 +142,7 @@ dependencies {
android {
compileSdkVersion 32
- buildToolsVersion '30.0.2'
+ buildToolsVersion '30.0.3'
testOptions {
unitTests {
includeAndroidResources = true
@@ -157,7 +157,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 3218
+ versionCode 3223
versionName "3.5"
targetSdkVersion 32
@@ -382,8 +382,8 @@ def mainSrc = "${project.projectDir}/src/main/java"
task jacocoTestReport(type: JacocoReport, dependsOn: 'testProdDebugUnitTest') {
group = "Reporting"
reports {
- html.enabled = true
- xml.enabled = true
+ html.required.set(true)
+ xml.required.set(true)
//html.destination = "${buildDir}/reports/jacoco"
}
@@ -404,7 +404,6 @@ task jacocoTestReport(type: JacocoReport, dependsOn: 'testProdDebugUnitTest') {
task ktlint(type: JavaExec, group: "verification") {
description = "Check Kotlin code style."
classpath = configurations.ktlint
- main = "com.pinterest.ktlint.Main"
args "--disabled_rules=no-wildcard-imports", "--reporter=plain?group_by_file", "src/**/*.kt"
// to generate report in checkstyle format prepend following args:
// "--reporter=plain", "--reporter=checkstyle,output=${buildDir}/ktlint.xml"
@@ -417,6 +416,5 @@ check.dependsOn ktlint
task ktlintFormat(type: JavaExec, group: "formatting") {
description = "Fix Kotlin code style deviations."
classpath = configurations.ktlint
- main = "com.pinterest.ktlint.Main"
args "--disabled_rules=no-wildcard-imports", "-F", "src/**/*.kt"
}
diff --git a/Habitica/res/drawable-hdpi/gift_sub_gift.png b/Habitica/res/drawable-hdpi/gift_sub_gift.png
index 30842a74b..278e05552 100644
Binary files a/Habitica/res/drawable-hdpi/gift_sub_gift.png and b/Habitica/res/drawable-hdpi/gift_sub_gift.png differ
diff --git a/Habitica/res/drawable-mdpi/gift_sub_gift.png b/Habitica/res/drawable-mdpi/gift_sub_gift.png
index fd10d6689..d13327594 100644
Binary files a/Habitica/res/drawable-mdpi/gift_sub_gift.png and b/Habitica/res/drawable-mdpi/gift_sub_gift.png differ
diff --git a/Habitica/res/drawable-xhdpi/gift_sub_gift.png b/Habitica/res/drawable-xhdpi/gift_sub_gift.png
index cb0b08379..f13dbf105 100644
Binary files a/Habitica/res/drawable-xhdpi/gift_sub_gift.png and b/Habitica/res/drawable-xhdpi/gift_sub_gift.png differ
diff --git a/Habitica/res/drawable-xxhdpi/gift_sub_gift.png b/Habitica/res/drawable-xxhdpi/gift_sub_gift.png
index f5fc9dbe5..6e7180dd5 100644
Binary files a/Habitica/res/drawable-xxhdpi/gift_sub_gift.png and b/Habitica/res/drawable-xxhdpi/gift_sub_gift.png differ
diff --git a/Habitica/res/layout/fragment_gem_purchase.xml b/Habitica/res/layout/fragment_gem_purchase.xml
index 1e910c52e..1333f53b4 100644
--- a/Habitica/res/layout/fragment_gem_purchase.xml
+++ b/Habitica/res/layout/fragment_gem_purchase.xml
@@ -233,11 +233,12 @@
android:layout_width="wrap_content"
android:paddingStart="41dp"
android:paddingEnd="41dp"
- android:paddingBottom="20dp"
+ android:paddingBottom="30dp"
android:paddingTop="70dp"
android:text="@string/gem_purchase_title"
android:layout_gravity="center_horizontal"
android:gravity="center"
+ android:lineSpacingExtra="3dp"
android:textColor="@color/white"
style="@style/Caption2"
android:drawablePadding="@dimen/spacing_medium"/>
diff --git a/Habitica/res/layout/purchase_gem_view.xml b/Habitica/res/layout/purchase_gem_view.xml
index 454c3e295..b83800c33 100644
--- a/Habitica/res/layout/purchase_gem_view.xml
+++ b/Habitica/res/layout/purchase_gem_view.xml
@@ -17,19 +17,37 @@
android:contentDescription="@string/gems"
android:layout_marginTop="20dp"/>
-
+ android:orientation="horizontal">
+
+
+
-
+
Rewards
Yes
No
+ Discard
Quest
Body
Hair
@@ -378,7 +379,7 @@
Google play services could not be found.
Purchase
Buying gems supports the developers and helps keep Habitica running
- Gems allow you to buy fun extras for your account:
+ Gems allow you to buy fun extras for your account
Cool costumes for your avatar
Awesome backgrounds
Quests that reward you with pet eggs
@@ -470,6 +471,7 @@
Each month, subscribers will receive a mystery item. This is usually released about one week before the end of the month.
Open>
Open
+ Use Item on party member>
You earned a %1$s as a reward for your devotion to improving your life.
Next prize in %1$d Check-Ins
pending approval
@@ -527,6 +529,7 @@
Your device does not have any of the supported payment methods. Please use the habitica website if you want to purchase gems.
Your device does not have any of the supported payment methods. Please use the habitica website if you want to purchase a subscription.
Save
+ Unsaved Changes
Location
Gem prize
Tasks
@@ -551,6 +554,7 @@
Start My Day
Are you sure you want to leave this party?
Do you want to keep participating in the Challenge when leaving the Party?
+ Are you sure you want to discard changes to this task?
You will not be able to rejoin this party unless invited.
Pending
Accepted
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/components/UserComponent.java b/Habitica/src/main/java/com/habitrpg/android/habitica/components/UserComponent.java
index bf889d2f4..128148286 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/components/UserComponent.java
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/components/UserComponent.java
@@ -103,6 +103,7 @@ import com.habitrpg.android.habitica.ui.viewmodels.AuthenticationViewModel;
import com.habitrpg.android.habitica.ui.viewmodels.GroupViewModel;
import com.habitrpg.android.habitica.ui.viewmodels.InboxViewModel;
import com.habitrpg.android.habitica.ui.viewmodels.MainActivityViewModel;
+import com.habitrpg.android.habitica.ui.viewmodels.MainUserViewModel;
import com.habitrpg.android.habitica.ui.viewmodels.NotificationsViewModel;
import com.habitrpg.android.habitica.ui.viewmodels.inventory.equipment.EquipmentOverviewViewModel;
import com.habitrpg.android.habitica.ui.views.insufficientCurrency.InsufficientGemsDialog;
@@ -352,4 +353,6 @@ public interface UserComponent {
void inject(@NotNull MainActivityViewModel mainActivityViewModel);
void inject(@NotNull GuidelinesActivity guidelinesActivity);
+
+ void inject(@NotNull MainUserViewModel mainUserViewModel);
}
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/SocialRepository.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/data/SocialRepository.kt
index 721e7ace7..af3994412 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/SocialRepository.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/SocialRepository.kt
@@ -84,6 +84,5 @@ interface SocialRepository : BaseRepository {
fun getGroupMembership(id: String): Flowable
fun getGroupMemberships(): Flowable>
- fun getChatmessage(messageID: String): Flowable
fun blockMember(userID: 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 fd4c8cb9e..94c363df5 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
@@ -9,7 +9,6 @@ import com.habitrpg.android.habitica.models.ContentResult
import com.habitrpg.android.habitica.models.WorldState
import com.habitrpg.android.habitica.models.inventory.SpecialItem
import io.reactivex.rxjava3.core.Flowable
-import io.realm.RealmList
import java.util.*
class ContentRepositoryImpl(localRepository: T, apiClient: ApiClient, context: Context) : BaseRepositoryImpl(localRepository, apiClient), ContentRepository {
@@ -24,7 +23,6 @@ class ContentRepositoryImpl(localRepository: T, apiC
return if (forced || now - this.lastContentSync > 300000) {
lastContentSync = now
apiClient.content.doOnNext {
- it.special = RealmList()
it.special.add(mysteryItem)
localRepository.saveContent(it)
}
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/SocialRepositoryImpl.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/SocialRepositoryImpl.kt
index acfbb2bde..954164dd4 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/SocialRepositoryImpl.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/SocialRepositoryImpl.kt
@@ -37,10 +37,6 @@ class SocialRepositoryImpl(localRepository: SocialLocalRepository, apiClient: Ap
}
}
- override fun getChatmessage(messageID: String): Flowable {
- return localRepository.getChatMessage(messageID)
- }
-
override fun blockMember(userID: String): Flowable> {
return apiClient.blockMember(userID)
}
@@ -92,7 +88,9 @@ class SocialRepositoryImpl(localRepository: SocialLocalRepository, apiClient: Ap
return Flowable.empty()
}
val liked = chatMessage.userLikesMessage(userID)
- localRepository.likeMessage(chatMessage, userID, !liked)
+ if (chatMessage.isManaged) {
+ localRepository.likeMessage(chatMessage, userID, !liked)
+ }
return apiClient.likeMessage(chatMessage.groupId ?: "", chatMessage.id)
}
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/SocialLocalRepository.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/SocialLocalRepository.kt
index aebf06a4b..2dd96f015 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/SocialLocalRepository.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/SocialLocalRepository.kt
@@ -47,5 +47,4 @@ interface SocialLocalRepository : BaseLocalRepository {
fun saveGroupMemberships(userID: String?, memberships: List)
fun saveInboxMessages(userID: String, recipientID: String, messages: List, page: Int)
fun saveInboxConversations(userID: String, conversations: List)
- fun getChatMessage(messageID: String): 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 da558dc96..042f35b2f 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
@@ -28,6 +28,7 @@ open class RealmContentLocalRepository(realm: Realm) : RealmBaseLocalRepository(
realm1.insertOrUpdate(contentResult.mounts)
realm1.insertOrUpdate(contentResult.spells)
+ realm1.insertOrUpdate(contentResult.special)
realm1.insertOrUpdate(contentResult.appearances)
realm1.insertOrUpdate(contentResult.backgrounds)
realm1.insertOrUpdate(contentResult.faq)
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 9375752f6..cd739e699 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
@@ -96,7 +96,7 @@ class RealmInventoryLocalRepository(realm: Realm) : RealmContentLocalRepository(
"hatchingPotions" -> it.items?.hatchingPotions
"food" -> it.items?.food
"quests" -> it.items?.quests
- "special" -> it.items?.special?.ownedItems
+ "special" -> it.items?.special
else -> emptyList()
} ?: emptyList()
if (includeZero) {
@@ -286,7 +286,7 @@ class RealmInventoryLocalRepository(realm: Realm) : RealmContentLocalRepository(
return
}
val liveUser = getLiveObject(user)
- val ownedItems = liveUser?.items?.special?.ownedItems
+ val ownedItems = liveUser?.items?.special
val item = ownedItems?.firstOrNull() { it.key == "inventory_present" }
executeTransaction {
if (item != null && item.isValid) {
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmSocialLocalRepository.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmSocialLocalRepository.kt
index 07329b047..2bac1fc16 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmSocialLocalRepository.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmSocialLocalRepository.kt
@@ -12,14 +12,6 @@ import io.realm.Sort
import java.util.*
class RealmSocialLocalRepository(realm: Realm) : RealmBaseLocalRepository(realm), SocialLocalRepository {
- override fun getChatMessage(messageID: String): Flowable = RxJavaBridge.toV3Flowable(
- realm.where(ChatMessage::class.java)
- .equalTo("id", messageID)
- .findAll()
- .asFlowable()
- .filter { it.isLoaded && it.isNotEmpty() }
- .map { it.first() }
- )
override fun getGroupMembership(userId: String, id: String): Flowable = RxJavaBridge.toV3Flowable(
realm.where(GroupMembership::class.java)
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmUserLocalRepository.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmUserLocalRepository.kt
index 455c2b00d..ad7040b3a 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmUserLocalRepository.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/local/implementation/RealmUserLocalRepository.kt
@@ -146,22 +146,10 @@ class RealmUserLocalRepository(realm: Realm) : RealmBaseLocalRepository(realm),
override fun getSpecialItems(user: User): Flowable> {
val specialItems = user.items?.special
val ownedItems = ArrayList()
- if (specialItems != null) {
- if (specialItems.snowball > 0) {
- ownedItems.add("snowball")
+ for (key in listOf("snowball", "shinySeed", "seafoam", "spookySparkles")) {
+ if (specialItems?.firstOrNull() { it.key == key }?.numberOwned ?: 0 > 0) {
+ ownedItems.add(key)
}
- if (specialItems.shinySeed > 0) {
- ownedItems.add("shinySeed")
- }
- if (specialItems.seafoam > 0) {
- ownedItems.add("seafoam")
- }
- if (specialItems.spookySparkles > 0) {
- ownedItems.add("spookySparkles")
- }
- }
- if (ownedItems.size == 0) {
- ownedItems.add("")
}
return RxJavaBridge.toV3Flowable(
realm.where(Skill::class.java)
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/TaskAlarmManager.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/TaskAlarmManager.kt
index ce2a67a2a..23861569d 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/TaskAlarmManager.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/helpers/TaskAlarmManager.kt
@@ -1,6 +1,7 @@
package com.habitrpg.android.habitica.helpers
import android.app.AlarmManager
+import android.app.AlarmManager.AlarmClockInfo
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
@@ -121,6 +122,7 @@ class TaskAlarmManager(private var context: Context, private var taskRepository:
const val TASK_NAME_INTENT_KEY = "TASK_NAME"
fun scheduleDailyReminder(context: Context?) {
+ if (context == null) return
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
if (prefs.getBoolean("use_reminder", false)) {
val timeval = prefs.getString("reminder_time", "19:00")
@@ -174,7 +176,7 @@ class TaskAlarmManager(private var context: Context, private var taskRepository:
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
alarmManager?.setWindow(AlarmManager.RTC_WAKEUP, time, 60000, pendingIntent)
} else {
- alarmManager?.setAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, time, pendingIntent)
+ alarmManager?.setAlarmClock(AlarmClockInfo(time, pendingIntent), pendingIntent)
}
}
}
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/models/inventory/SpecialItem.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/models/inventory/SpecialItem.kt
index 061955b30..521388af6 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/models/inventory/SpecialItem.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/models/inventory/SpecialItem.kt
@@ -15,6 +15,7 @@ open class SpecialItem : RealmObject(), Item {
internal var notes: String = ""
override var value: Int = 0
override var event: ItemEvent? = null
+ var target: String? = null
var isMysteryItem: Boolean = false
companion object {
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/models/tasks/Task.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/models/tasks/Task.kt
index 7a1b66989..ebcfa2949 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/models/tasks/Task.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/models/tasks/Task.kt
@@ -256,6 +256,47 @@ open class Task : RealmObject, BaseMainObject, Parcelable {
}
}
+ fun isBeingEdited(task: Task): Boolean {
+
+ when {
+ text != task.text -> return true
+ notes != task.notes -> return true
+ reminders != task.reminders -> return true
+ checklist != task.checklist -> return true
+ priority != task.priority -> return true
+ attribute != task.attribute && attribute != null -> return true
+ tags != task.tags -> return true
+ }
+ if (type == TaskType.HABIT) {
+ return when {
+ up != task.up -> true
+ down != task.down -> true
+ frequency != task.frequency -> true
+ counterUp != task.counterUp -> true
+ counterDown != task.counterDown -> true
+ else -> false
+ }
+ } else if (type == TaskType.DAILY) {
+ return when {
+ startDate != task.startDate -> true
+ everyX != task.everyX -> true
+ frequency != task.frequency -> true
+ repeat != task.repeat -> true
+ streak != task.streak -> true
+ else -> false
+ }
+
+ } else if (type == TaskType.TODO) {
+ return dueDate != task.dueDate
+
+ } else if (type == TaskType.REWARD) {
+ return value != task.value
+
+ } else {
+ return false
+ }
+ }
+
override fun hashCode(): Int {
return id?.hashCode() ?: 0
}
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/models/user/Items.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/models/user/Items.kt
index 049378511..d4d52ad47 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/models/user/Items.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/models/user/Items.kt
@@ -13,6 +13,7 @@ open class Items : RealmObject, BaseObject {
eggs?.forEach { it.itemType = "eggs" }
food?.forEach { it.itemType = "food" }
quests?.forEach { it.itemType = "quests" }
+ special?.forEach { it.itemType = "special" }
}
var eggs: RealmList? = null
@@ -35,6 +36,12 @@ open class Items : RealmObject, BaseObject {
field = value
field?.forEach { it.itemType = "quests" }
}
+ var special: RealmList? = null
+ set(value) {
+ field = value
+ field?.forEach { it.itemType = "special" }
+ }
+
var pets: RealmList? = null
var mounts: RealmList? = null
var currentMount: String? = null
@@ -44,7 +51,6 @@ open class Items : RealmObject, BaseObject {
// private QuestContent quest;
var gear: Gear? = null
- var special: SpecialItems? = null
constructor(currentMount: String, currentPet: String, lastDropCount: Int, lastDropDate: Date) {
this.currentMount = currentMount
@@ -54,4 +60,14 @@ open class Items : RealmObject, BaseObject {
}
constructor()
+
+ val hasTransformationItems: Boolean
+ get() {
+ return special?.any { transformationItem ->
+ transformationItem.key == ("seafoam") && transformationItem.numberOwned > 0||
+ transformationItem.key == ("shinySeed") && transformationItem.numberOwned > 0||
+ transformationItem.key == ("snowball") && transformationItem.numberOwned > 0||
+ transformationItem.key == ("spookySparkles") && transformationItem.numberOwned > 0
+ } ?: false
+ }
}
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/models/user/SpecialItems.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/models/user/SpecialItems.kt
deleted file mode 100644
index 681e158eb..000000000
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/models/user/SpecialItems.kt
+++ /dev/null
@@ -1,20 +0,0 @@
-package com.habitrpg.android.habitica.models.user
-
-import com.habitrpg.android.habitica.models.BaseObject
-import io.realm.RealmList
-import io.realm.RealmObject
-import io.realm.annotations.RealmClass
-
-@RealmClass(embedded = true)
-open class SpecialItems : RealmObject(), BaseObject {
- var ownedItems: RealmList? = null
- var seafoam: Int = 0
- var shinySeed: Int = 0
- var snowball: Int = 0
- var spookySparkles: Int = 0
-
- val hasSpecialItems: Boolean
- get() {
- return seafoam > 0 || shinySeed > 0 || snowball > 0 || spookySparkles > 0
- }
-}
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/modules/AppModule.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/modules/AppModule.kt
index b4a8d3de5..ddb99448a 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/modules/AppModule.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/modules/AppModule.kt
@@ -34,7 +34,7 @@ class AppModule(private val application: Application) {
@Provides
@Singleton
- fun provideSharedPreferences(context: Context?): SharedPreferences {
+ fun provideSharedPreferences(context: Context): SharedPreferences {
return PreferenceManager.getDefaultSharedPreferences(context)
}
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/modules/UserModule.java b/Habitica/src/main/java/com/habitrpg/android/habitica/modules/UserModule.java
index e6ac9f658..e6e231245 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/modules/UserModule.java
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/modules/UserModule.java
@@ -4,8 +4,10 @@ import android.content.Context;
import android.content.SharedPreferences;
import com.habitrpg.android.habitica.data.TaskRepository;
+import com.habitrpg.android.habitica.data.UserRepository;
import com.habitrpg.android.habitica.helpers.TaskAlarmManager;
import com.habitrpg.android.habitica.helpers.UserScope;
+import com.habitrpg.android.habitica.ui.viewmodels.MainUserViewModel;
import javax.inject.Named;
@@ -28,4 +30,10 @@ public class UserModule {
public String providesUserID(SharedPreferences sharedPreferences) {
return sharedPreferences.getString("UserID", "");
}
+
+ @Provides
+ @UserScope
+ MainUserViewModel providesUserViewModel(UserRepository userRepository) {
+ return new MainUserViewModel(userRepository);
+ }
}
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/prefs/TimePreference.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/prefs/TimePreference.kt
index 7635262ad..fb2900833 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/prefs/TimePreference.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/prefs/TimePreference.kt
@@ -7,7 +7,7 @@ import androidx.preference.DialogPreference
import java.text.DateFormat
import java.util.*
-class TimePreference(ctxt: Context?, attrs: AttributeSet?) : DialogPreference(ctxt, attrs) {
+class TimePreference(ctxt: Context, attrs: AttributeSet?) : DialogPreference(ctxt, attrs) {
private var timeval: String? = null
override fun onGetDefaultValue(a: TypedArray, index: Int): Any {
return a.getString(index)!!
@@ -39,7 +39,7 @@ class TimePreference(ctxt: Context?, attrs: AttributeSet?) : DialogPreference(ct
}
}
- override fun setSummary(summary: CharSequence) {
+ override fun setSummary(summary: CharSequence?) {
val calendar = Calendar.getInstance(Locale.getDefault())
calendar.set(Calendar.HOUR_OF_DAY, getHour(timeval))
calendar.set(Calendar.MINUTE, getMinute(timeval))
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/AvatarWithBarsViewModel.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/AvatarWithBarsViewModel.kt
index ccb64cf42..e51369eb5 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/AvatarWithBarsViewModel.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/AvatarWithBarsViewModel.kt
@@ -73,9 +73,9 @@ class AvatarWithBarsViewModel(private val context: Context, private val binding:
if (!stats.isBuffed) {
binding.buffImageView.visibility = View.GONE
}
-
- binding.currencyView.gold = stats.gp ?: 0.0
+
if (user is User) {
+ binding.currencyView.gold = stats.gp ?: 0.0
binding.currencyView.hourglasses = user.hourglassCount.toDouble()
binding.currencyView.gems = user.gemCount.toDouble()
}
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/GemPurchaseOptionsView.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/GemPurchaseOptionsView.kt
index 89dd9db5a..6f3e7a308 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/GemPurchaseOptionsView.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/GemPurchaseOptionsView.kt
@@ -20,7 +20,7 @@ class GemPurchaseOptionsView(context: Context, attrs: AttributeSet) : FrameLayou
0, 0
)
- binding.gemAmount.text = "${a.getText(R.styleable.GemPurchaseOptionsView_gemAmount)} GEMS"
+ binding.gemAmount.text = a.getText(R.styleable.GemPurchaseOptionsView_gemAmount)
val iconRes = a.getDrawable(R.styleable.GemPurchaseOptionsView_gemDrawable)
if (iconRes != null) {
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 23f799a37..7e02ed842 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
@@ -273,7 +273,7 @@ open class MainActivity : BaseActivity(), TutorialView.OnTutorialReaction, Snack
navigationController.addOnDestinationChangedListener { _, destination, arguments -> updateToolbarTitle(destination, arguments) }
if (launchScreen == "/party") {
- if (viewModel.isUserInParty) {
+ if (viewModel.userViewModel.isUserInParty) {
MainNavigationController.navigate(R.id.partyFragment)
}
}
@@ -430,7 +430,7 @@ open class MainActivity : BaseActivity(), TutorialView.OnTutorialReaction, Snack
}
private fun displayDeathDialogIfNeeded() {
- if (!viewModel.isUserFainted) {
+ if (!viewModel.userViewModel.isUserFainted) {
return
}
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/TaskFormActivity.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/TaskFormActivity.kt
index edd88c8e3..d8c1b69b2 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/TaskFormActivity.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/TaskFormActivity.kt
@@ -1,6 +1,7 @@
package com.habitrpg.android.habitica.ui.activities
import android.app.Activity
+import android.content.DialogInterface
import android.content.Intent
import android.content.SharedPreferences
import android.content.res.ColorStateList
@@ -13,6 +14,7 @@ import android.widget.CheckBox
import android.widget.TextView
import androidx.appcompat.widget.AppCompatCheckBox
import androidx.core.content.ContextCompat
+import androidx.core.os.bundleOf
import androidx.core.view.children
import androidx.core.view.forEachIndexed
import androidx.core.widget.NestedScrollView
@@ -21,7 +23,6 @@ import com.habitrpg.android.habitica.components.UserComponent
import com.habitrpg.android.habitica.data.ChallengeRepository
import com.habitrpg.android.habitica.data.TagRepository
import com.habitrpg.android.habitica.data.TaskRepository
-import com.habitrpg.android.habitica.data.UserRepository
import com.habitrpg.android.habitica.databinding.ActivityTaskFormBinding
import com.habitrpg.android.habitica.extensions.OnChangeTextWatcher
import com.habitrpg.android.habitica.extensions.addCancelButton
@@ -64,6 +65,7 @@ class TaskFormActivity : BaseActivity() {
private var isChallengeTask = false
private var usesTaskAttributeStats = false
private var task: Task? = null
+ private var initialTaskInstance: Task? = null
private var taskType: TaskType = TaskType.HABIT
private var tags = listOf()
private var preselectedTags: ArrayList? = null
@@ -74,6 +76,7 @@ class TaskFormActivity : BaseActivity() {
setSelectedAttribute(value)
}
+ private var isDiscardCancelled: Boolean = false
private var canSave: Boolean = false
private var tintColor: Int = 0
@@ -198,6 +201,7 @@ class TaskFormActivity : BaseActivity() {
{
if (!it.isValid) return@subscribe
task = it
+ initialTaskInstance = it
// tintColor = ContextCompat.getColor(this, it.mediumTaskColor)
fillForm(it)
it.challengeID?.let { challengeID ->
@@ -224,17 +228,21 @@ class TaskFormActivity : BaseActivity() {
task = bundle.getParcelable(PARCELABLE_TASK)
task?.let { fillForm(it) }
}
- else -> title = getString(
- R.string.create_task,
- getString(
- when (taskType) {
- TaskType.DAILY -> R.string.daily
- TaskType.TODO -> R.string.todo
- TaskType.REWARD -> R.string.reward
- else -> R.string.habit
- }
+ else -> {
+ title = getString(
+ R.string.create_task,
+ getString(
+ when (taskType) {
+ TaskType.DAILY -> R.string.daily
+ TaskType.TODO -> R.string.todo
+ TaskType.REWARD -> R.string.reward
+ else -> R.string.habit
+ }
+ )
)
- )
+ initialTaskInstance = configureTask(Task())
+ }
+
}
configureForm()
}
@@ -252,6 +260,29 @@ class TaskFormActivity : BaseActivity() {
}
}
+ override fun onBackPressed() {
+ val currentTaskInstance = configureTask(Task())
+ if (initialTaskInstance?.isBeingEdited(currentTaskInstance) == true) {
+ val alert = HabiticaAlertDialog(this)
+ alert.setTitle(R.string.unsaved_changes)
+ alert.setMessage(R.string.discard_changes_to_task_message)
+ alert.addButton(R.string.discard, true, true) { _, _ ->
+ analyticsManager.logEvent("discard_task", bundleOf(Pair("is_creating", isCreating)))
+ super.onBackPressed()
+ }
+ alert.addButton(R.string.cancel, false) { _, _ ->
+ isDiscardCancelled = true
+ alert.dismiss()
+ }
+ alert.setOnDismissListener(DialogInterface.OnDismissListener {
+ isDiscardCancelled = true
+ })
+ alert.show()
+ } else {
+ super.onBackPressed()
+ }
+ }
+
override fun onCreateOptionsMenu(menu: Menu): Boolean {
if (isCreating) {
menuInflater.inflate(R.menu.menu_task_create, menu)
@@ -437,19 +468,10 @@ class TaskFormActivity : BaseActivity() {
}
}
- private fun saveTask() {
- if (isSaving) {
- return
- }
- isSaving = true
- var thisTask = task
- if (thisTask == null) {
- thisTask = Task()
- thisTask.type = taskType
- thisTask.dateCreated = Date()
- } else {
- if (!thisTask.isValid) return
- }
+ private fun configureTask(thisTask: Task): Task {
+ thisTask.type = taskType
+ thisTask.dateCreated = Date()
+
thisTask.text = binding.textEditText.text.toString()
thisTask.notes = binding.notesEditText.text.toString()
thisTask.priority = binding.taskDifficultyButtons.selectedDifficulty
@@ -460,8 +482,10 @@ class TaskFormActivity : BaseActivity() {
thisTask.up = binding.habitScoringButtons.isPositive
thisTask.down = binding.habitScoringButtons.isNegative
thisTask.frequency = binding.habitResetStreakButtons.selectedResetOption.value
- if (binding.habitAdjustPositiveStreakView.text?.isNotEmpty() == true) thisTask.counterUp = binding.habitAdjustPositiveStreakView.text.toString().toIntCatchOverflow()
- if (binding.habitAdjustNegativeStreakView.text?.isNotEmpty() == true) thisTask.counterDown = binding.habitAdjustNegativeStreakView.text.toString().toIntCatchOverflow()
+ if (binding.habitAdjustPositiveStreakView.text?.isNotEmpty() == true) thisTask.counterUp =
+ binding.habitAdjustPositiveStreakView.text.toString().toIntCatchOverflow()
+ if (binding.habitAdjustNegativeStreakView.text?.isNotEmpty() == true) thisTask.counterDown =
+ binding.habitAdjustNegativeStreakView.text.toString().toIntCatchOverflow()
} else if (taskType == TaskType.DAILY) {
thisTask.startDate = binding.taskSchedulingControls.startDate
thisTask.everyX = binding.taskSchedulingControls.everyX
@@ -469,15 +493,13 @@ class TaskFormActivity : BaseActivity() {
thisTask.repeat = binding.taskSchedulingControls.weeklyRepeat
thisTask.setDaysOfMonth(binding.taskSchedulingControls.daysOfMonth)
thisTask.setWeeksOfMonth(binding.taskSchedulingControls.weeksOfMonth)
- if (binding.habitAdjustPositiveStreakView.text?.isNotEmpty() == true) thisTask.streak = binding.habitAdjustPositiveStreakView.text.toString().toIntCatchOverflow()
+ if (binding.habitAdjustPositiveStreakView.text?.isNotEmpty() == true) thisTask.streak =
+ binding.habitAdjustPositiveStreakView.text.toString().toIntCatchOverflow()
} else if (taskType == TaskType.TODO) {
thisTask.dueDate = binding.taskSchedulingControls.dueDate
} else if (taskType == TaskType.REWARD) {
thisTask.value = binding.rewardValue.value
}
-
- val resultIntent = Intent()
- resultIntent.putExtra(TASK_TYPE_KEY, taskType)
if (!isChallengeTask) {
if (taskType == TaskType.DAILY || taskType == TaskType.TODO) {
thisTask.checklist = RealmList()
@@ -492,10 +514,40 @@ class TaskFormActivity : BaseActivity() {
thisTask.tags?.add(tags[index])
}
}
+ }
+ return thisTask
+ }
+
+ private fun saveTask() {
+ if (isSaving) {
+ return
+ }
+ isSaving = true
+ var thisTask = task
+ if (thisTask == null) {
+ thisTask = Task()
+ thisTask.type = taskType
+ thisTask.dateCreated = Date()
+ } else {
+ if (!thisTask.isValid) return
+ }
+
+ thisTask = configureTask(thisTask)
+
+ val resultIntent = Intent()
+ resultIntent.putExtra(TASK_TYPE_KEY, taskType)
+ if (!isChallengeTask) {
if (isCreating) {
+ if (isDiscardCancelled){
+ analyticsManager.logEvent("back_to_task", bundleOf(Pair("is_creating", isCreating)))
+ }
taskRepository.createTaskInBackground(thisTask)
+
} else {
+ if (isDiscardCancelled){
+ analyticsManager.logEvent("back_to_task", bundleOf(Pair("is_creating", isCreating)))
+ }
taskRepository.updateTaskInBackground(thisTask)
}
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/SkillsRecyclerViewAdapter.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/SkillsRecyclerViewAdapter.kt
index 423793985..6b64fa8b0 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/SkillsRecyclerViewAdapter.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/SkillsRecyclerViewAdapter.kt
@@ -12,12 +12,13 @@ import com.habitrpg.android.habitica.databinding.SkillListItemBinding
import com.habitrpg.android.habitica.extensions.inflate
import com.habitrpg.android.habitica.extensions.isUsingNightModeResources
import com.habitrpg.android.habitica.models.Skill
-import com.habitrpg.android.habitica.models.user.SpecialItems
+import com.habitrpg.android.habitica.models.user.OwnedItem
import com.habitrpg.android.habitica.ui.helpers.DataBindingUtils
import com.habitrpg.android.habitica.ui.views.HabiticaIconsHelper
import io.reactivex.rxjava3.core.BackpressureStrategy
import io.reactivex.rxjava3.core.Flowable
import io.reactivex.rxjava3.subjects.PublishSubject
+import io.realm.RealmList
class SkillsRecyclerViewAdapter : RecyclerView.Adapter() {
@@ -34,7 +35,7 @@ class SkillsRecyclerViewAdapter : RecyclerView.Adapter?? = null
set(value) {
field = value
notifyDataSetChanged()
@@ -134,13 +135,7 @@ class SkillsRecyclerViewAdapter : RecyclerView.Adapter specialItems?.snowball
- "shinySeed" -> specialItems?.shinySeed
- "seafoam" -> specialItems?.seafoam
- "spookySparkles" -> specialItems?.spookySparkles
- else -> 0
- } ?: 0
+ return specialItems?.firstOrNull() { it.key == key }?.numberOwned ?: 0
}
}
}
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/ItemRecyclerAdapter.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/ItemRecyclerAdapter.kt
index 88143efb8..d13f80c92 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/ItemRecyclerAdapter.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/ItemRecyclerAdapter.kt
@@ -47,6 +47,7 @@ class ItemRecyclerAdapter(val context: Context, val user: User?) : BaseRecyclerV
private val hatchPetSubject = PublishSubject.create>()
private val feedPetSubject = PublishSubject.create()
private val createNewPartySubject = PublishSubject.create()
+ private val useSpecialSubject = PublishSubject.create()
fun getSellItemFlowable(): Flowable {
return sellItemEvents.toFlowable(BackpressureStrategy.DROP)
@@ -63,6 +64,7 @@ class ItemRecyclerAdapter(val context: Context, val user: User?) : BaseRecyclerV
val hatchPetEvents: Flowable> = hatchPetSubject.toFlowable(BackpressureStrategy.DROP)
val feedPetEvents: Flowable = feedPetSubject.toFlowable(BackpressureStrategy.DROP)
val startNewPartyEvents: Flowable = createNewPartySubject.toFlowable(BackpressureStrategy.DROP)
+ val useSpecialEvents: Flowable = useSpecialSubject.toFlowable(BackpressureStrategy.DROP)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder {
return ItemViewHolder(ItemItemBinding.inflate(context.layoutInflater, parent, false))
@@ -115,9 +117,14 @@ class ItemRecyclerAdapter(val context: Context, val user: User?) : BaseRecyclerV
if (item is QuestContent) {
imageName = "inventory_quest_scroll_" + ownedItem.key
} else if (item is SpecialItem) {
- val sdf = SimpleDateFormat("MM", Locale.getDefault())
- val month = sdf.format(Date())
- imageName = "inventory_present_$month"
+ if (item.key == "inventory_present") {
+ val sdf = SimpleDateFormat("MM", Locale.getDefault())
+ val month = sdf.format(Date())
+ imageName = "inventory_present_$month"
+ } else {
+ imageName = "shop_" + ownedItem.key
+ }
+
} else {
val type = when (ownedItem.itemType) {
"eggs" -> "Egg"
@@ -164,7 +171,10 @@ class ItemRecyclerAdapter(val context: Context, val user: User?) : BaseRecyclerV
val specialItem = item as SpecialItem
if (specialItem.isMysteryItem && ownedItem?.numberOwned ?: 0 > 0) {
menu.addMenuItem(BottomSheetMenuItem(resources.getString(R.string.open)))
+ } else if (ownedItem?.numberOwned ?: 0 > 0){
+ menu.addMenuItem(BottomSheetMenuItem(resources.getString(R.string.use_item)))
}
+
}
menu.setSelectionRunnable { index ->
item?.let { selectedItem ->
@@ -189,7 +199,12 @@ class ItemRecyclerAdapter(val context: Context, val user: User?) : BaseRecyclerV
}
}
- is SpecialItem -> openMysteryItemEvents.onNext(selectedItem)
+ is SpecialItem ->
+ if (item?.key != "inventory_present") {
+ useSpecialSubject.onNext(selectedItem)
+ } else {
+ openMysteryItemEvents.onNext(selectedItem)
+ }
}
}
}
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 462627480..69e9bcbda 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
@@ -15,7 +15,11 @@ class MountDetailRecyclerAdapter : androidx.recyclerview.widget.RecyclerView.Ada
private var ownedMounts: Map? = null
private val equipEvents = PublishSubject.create()
- private var user: User? = null
+ var currentMount: String? = null
+ set(value) {
+ field = value
+ notifyDataSetChanged()
+ }
private var itemList: List = ArrayList()
@@ -37,7 +41,7 @@ class MountDetailRecyclerAdapter : androidx.recyclerview.widget.RecyclerView.Ada
override fun onBindViewHolder(holder: androidx.recyclerview.widget.RecyclerView.ViewHolder, position: Int) {
when (val obj = this.itemList[position]) {
is StableSection -> (holder as? SectionViewHolder)?.bind(obj)
- is Mount -> (holder as? MountViewHolder)?.bind(obj, ownedMounts?.get(obj.key ?: "")?.owned == true, user)
+ is Mount -> (holder as? MountViewHolder)?.bind(obj, ownedMounts?.get(obj.key ?: "")?.owned == true, currentMount)
}
}
@@ -49,9 +53,4 @@ class MountDetailRecyclerAdapter : androidx.recyclerview.widget.RecyclerView.Ada
this.ownedMounts = ownedMounts
notifyDataSetChanged()
}
-
- fun setUser(user: User) {
- this.user = user
- notifyDataSetChanged()
- }
}
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 ffc74fe7d..cfb6b1279 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
@@ -17,7 +17,11 @@ class PetDetailRecyclerAdapter : androidx.recyclerview.widget.RecyclerView.Adapt
private var ownedPets: Map? = null
private var ownedMounts: Map? = null
private var ownedItems: Map? = null
- private var user: User? = null
+ var currentPet: String? = null
+ set(value) {
+ field = value
+ notifyDataSetChanged()
+ }
private val equipEvents = PublishSubject.create()
private val feedEvents = PublishSubject.create>()
private var ownsSaddles: Boolean = false
@@ -29,11 +33,6 @@ class PetDetailRecyclerAdapter : androidx.recyclerview.widget.RecyclerView.Adapt
this.notifyDataSetChanged()
}
- fun setUser(user: User) {
- this.user = user
- notifyDataSetChanged()
- }
-
fun getEquipFlowable(): Flowable {
return equipEvents.toFlowable(BackpressureStrategy.DROP)
}
@@ -81,7 +80,7 @@ class PetDetailRecyclerAdapter : androidx.recyclerview.widget.RecyclerView.Adapt
ownedItems?.get(obj.animal + "-eggs") != null,
ownedItems?.get(obj.color + "-hatchingPotions") != null,
ownedMounts?.containsKey(obj.key) == true,
- user
+ currentPet
)
}
}
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 90b2da691..ea2d6fb92 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
@@ -31,7 +31,16 @@ class StableRecyclerAdapter : RecyclerView.Adapter() {
var animalIngredientsRetriever: ((Animal, ((Pair) -> Unit)) -> Unit)? = null
private val feedEvents = PublishSubject.create>()
var itemType: String? = null
- private var user: User? = null
+ var currentPet: String? = null
+ set(value) {
+ field = value
+ notifyDataSetChanged()
+ }
+ var currentMount: String? = null
+ set(value) {
+ field = value
+ notifyDataSetChanged()
+ }
private val equipEvents = PublishSubject.create()
private var existingMounts: List? = null
private var ownedMounts: Map? = null
@@ -43,11 +52,6 @@ class StableRecyclerAdapter : RecyclerView.Adapter() {
return equipEvents.toFlowable(BackpressureStrategy.DROP)
}
- fun setUser(user: User) {
- this.user = user
- notifyDataSetChanged()
- }
-
private fun canRaiseToMount(pet: Pet): Boolean {
if (pet.type == "special") return false
for (mount in existingMounts ?: emptyList()) {
@@ -122,10 +126,10 @@ class StableRecyclerAdapter : RecyclerView.Adapter() {
hasUnlockedEgg = ownedItems?.get(item.animal + "-eggs") != null,
hasUnlockedPotion = ownedItems?.get(item.color + "-hatchingPotions") != null,
hasMount = ownedMounts?.containsKey(item.key) == true,
- user = user
+ currentPet = currentPet
)
} else if (item is Mount) {
- (holder as? MountViewHolder)?.bind(item, item.numberOwned > 0, user)
+ (holder as? MountViewHolder)?.bind(item, item.numberOwned > 0, currentMount)
}
return
}
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/AchievementsFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/AchievementsFragment.kt
index 640535294..b77c3c20f 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/AchievementsFragment.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/AchievementsFragment.kt
@@ -14,6 +14,7 @@ import com.habitrpg.android.habitica.databinding.FragmentRefreshRecyclerviewBind
import com.habitrpg.android.habitica.helpers.RxErrorHandler
import com.habitrpg.android.habitica.ui.adapter.AchievementsAdapter
import com.habitrpg.android.habitica.ui.helpers.ToolbarColorHelper
+import com.habitrpg.android.habitica.ui.viewmodels.MainUserViewModel
import io.reactivex.rxjava3.kotlin.Flowables
import io.reactivex.rxjava3.kotlin.combineLatest
import javax.inject.Inject
@@ -22,6 +23,8 @@ class AchievementsFragment : BaseMainFragment 0) {
entries.add(Pair("Challenges won", challengeAchievementCount))
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/BaseMainFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/BaseMainFragment.kt
index 9fe7288b5..0d1289d7b 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/BaseMainFragment.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/BaseMainFragment.kt
@@ -39,23 +39,12 @@ abstract class BaseMainFragment : BaseFragment() {
var usesTabLayout: Boolean = false
var hidesToolbar: Boolean = false
var usesBottomNavigation = false
- open var user: User? = null
-
- override fun onAttach(context: Context) {
- super.onAttach(context)
-
- if (activity is MainActivity) {
- user = activity?.viewModel?.user?.value
- }
- }
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
- compositeSubscription.add(userRepository.getUser().subscribe({ user = it }, RxErrorHandler.handleEmptyError()))
-
if (this.usesBottomNavigation) {
bottomNavigation?.visibility = View.VISIBLE
} else {
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 90164183a..0eb00cb47 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
@@ -28,7 +28,6 @@ import com.habitrpg.android.habitica.extensions.*
import com.habitrpg.android.habitica.helpers.AppConfigManager
import com.habitrpg.android.habitica.helpers.MainNavigationController
import com.habitrpg.android.habitica.helpers.RxErrorHandler
-import com.habitrpg.android.habitica.models.WorldState
import com.habitrpg.android.habitica.models.WorldStateEvent
import com.habitrpg.android.habitica.models.inventory.Item
import com.habitrpg.android.habitica.models.inventory.Quest
@@ -41,7 +40,6 @@ import com.habitrpg.android.habitica.models.user.User
import com.habitrpg.android.habitica.ui.activities.MainActivity
import com.habitrpg.android.habitica.ui.activities.NotificationsActivity
import com.habitrpg.android.habitica.ui.adapter.NavigationDrawerAdapter
-import com.habitrpg.android.habitica.ui.fragments.social.TavernDetailFragment
import com.habitrpg.android.habitica.ui.menu.HabiticaDrawerItem
import com.habitrpg.android.habitica.ui.viewmodels.NotificationsViewModel
import com.habitrpg.android.habitica.ui.views.HabiticaSnackbar
@@ -339,10 +337,10 @@ class NavigationDrawerFragment : DialogFragment() {
tavernItem?.subtitle = null
}
- val specialItems = user.items?.special
+ val userItems = user.items
var hasSpecialItems = false
- if (specialItems != null) {
- hasSpecialItems = specialItems.hasSpecialItems
+ if (userItems != null) {
+ hasSpecialItems = userItems.hasTransformationItems
}
val item = getItemWithIdentifier(SIDEBAR_SKILLS)
if (item != null) {
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 e89ab1837..4a94dad1e 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
@@ -18,6 +18,7 @@ import com.habitrpg.android.habitica.ui.adapter.CustomizationRecyclerViewAdapter
import com.habitrpg.android.habitica.ui.fragments.BaseMainFragment
import com.habitrpg.android.habitica.ui.helpers.MarginDecoration
import com.habitrpg.android.habitica.ui.helpers.SafeDefaultItemAnimator
+import com.habitrpg.android.habitica.ui.viewmodels.MainUserViewModel
import javax.inject.Inject
class AvatarCustomizationFragment :
@@ -34,6 +35,8 @@ class AvatarCustomizationFragment :
lateinit var customizationRepository: CustomizationRepository
@Inject
lateinit var inventoryRepository: InventoryRepository
+ @Inject
+ lateinit var userViewModel: MainUserViewModel
var type: String? = null
var category: String? = null
@@ -52,7 +55,7 @@ class AvatarCustomizationFragment :
adapter.getSelectCustomizationEvents()
.flatMap { customization ->
if (customization.type == "background") {
- userRepository.unlockPath(user, customization)
+ userRepository.unlockPath(userViewModel.user.value, customization)
.flatMap { userRepository.retrieveUser(false, true, true) }
} else {
userRepository.useCustomization(customization.type ?: "", customization.category, customization.identifier ?: "")
@@ -63,7 +66,7 @@ class AvatarCustomizationFragment :
compositeSubscription.add(
adapter.getUnlockCustomizationEvents()
.flatMap { customization ->
- userRepository.unlockPath(user, customization)
+ userRepository.unlockPath(userViewModel.user.value, customization)
}
.flatMap { userRepository.retrieveUser(withTasks = false, forced = true) }
.flatMap { inventoryRepository.retrieveInAppRewards() }
@@ -112,11 +115,7 @@ class AvatarCustomizationFragment :
binding?.recyclerView?.itemAnimator = SafeDefaultItemAnimator()
this.loadCustomizations()
- compositeSubscription.add(
- userRepository.getUser().subscribeWithErrorHandler {
- updateUser(it)
- }
- )
+ userViewModel.user.observe(viewLifecycleOwner) { updateUser(it) }
}
override fun onDestroy() {
@@ -153,7 +152,8 @@ class AvatarCustomizationFragment :
layoutManager.spanCount = spanCount
}
- fun updateUser(user: User) {
+ fun updateUser(user: User?) {
+ if (user == null) return
this.updateActiveCustomization(user)
if (adapter.customizationList.size != 0) {
val ownedCustomizations = ArrayList()
@@ -162,8 +162,8 @@ class AvatarCustomizationFragment :
} else {
this.loadCustomizations()
}
- this.adapter.userSize = this.user?.preferences?.size
- this.adapter.hairColor = this.user?.preferences?.hair?.color
+ this.adapter.userSize = user.preferences?.size
+ this.adapter.hairColor = user.preferences?.hair?.color
this.adapter.gemBalance = user.gemCount
adapter.notifyDataSetChanged()
}
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/customization/AvatarEquipmentFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/customization/AvatarEquipmentFragment.kt
index 7808822ea..2f5e9d9b6 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/customization/AvatarEquipmentFragment.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/customization/AvatarEquipmentFragment.kt
@@ -18,6 +18,7 @@ import com.habitrpg.android.habitica.ui.adapter.CustomizationEquipmentRecyclerVi
import com.habitrpg.android.habitica.ui.fragments.BaseMainFragment
import com.habitrpg.android.habitica.ui.helpers.MarginDecoration
import com.habitrpg.android.habitica.ui.helpers.SafeDefaultItemAnimator
+import com.habitrpg.android.habitica.ui.viewmodels.MainUserViewModel
import io.reactivex.rxjava3.core.Flowable
import javax.inject.Inject
@@ -27,6 +28,8 @@ class AvatarEquipmentFragment :
@Inject
lateinit var inventoryRepository: InventoryRepository
+ @Inject
+ lateinit var userViewModel: MainUserViewModel
override var binding: FragmentRefreshRecyclerviewBinding? = null
@@ -51,7 +54,7 @@ class AvatarEquipmentFragment :
adapter.getSelectCustomizationEvents()
.flatMap { equipment ->
val key = (if (equipment.key?.isNotBlank() != true) activeEquipment else equipment.key) ?: ""
- inventoryRepository.equip(user, if (user?.preferences?.costume == true) "costume" else "equipped", key)
+ inventoryRepository.equip(userViewModel.user.value, if (userViewModel.user.value?.preferences?.costume == true) "costume" else "equipped", key)
}
.subscribe({ }, RxErrorHandler.handleEmptyError())
)
@@ -143,7 +146,7 @@ class AvatarEquipmentFragment :
if (this.type == null || user.preferences == null) {
return
}
- val outfit = if (user.preferences?.costume == true) this.user?.items?.gear?.costume else this.user?.items?.gear?.equipped
+ val outfit = if (user.preferences?.costume == true) user.items?.gear?.costume else user.items?.gear?.equipped
val activeEquipment = when (this.type) {
"headAccessory" -> outfit?.headAccessory
"back" -> outfit?.back
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/equipment/EquipmentDetailFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/equipment/EquipmentDetailFragment.kt
index 665316463..f7c278f11 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/equipment/EquipmentDetailFragment.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/equipment/EquipmentDetailFragment.kt
@@ -44,7 +44,7 @@ class EquipmentDetailFragment :
savedInstanceState: Bundle?
): View? {
compositeSubscription.add(
- this.adapter.equipEvents.flatMapMaybe { key -> inventoryRepository.equipGear(user, key, isCostume ?: false).firstElement() }
+ this.adapter.equipEvents.flatMapMaybe { key -> inventoryRepository.equipGear(null, key, isCostume ?: false).firstElement() }
.subscribe({ }, RxErrorHandler.handleEmptyError())
)
return super.onCreateView(inflater, container, savedInstanceState)
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/equipment/EquipmentOverviewFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/equipment/EquipmentOverviewFragment.kt
index 2d0fb80de..a18122de8 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/equipment/EquipmentOverviewFragment.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/equipment/EquipmentOverviewFragment.kt
@@ -45,10 +45,10 @@ class EquipmentOverviewFragment : BaseMainFragment(), SwipeRefreshLayout.OnRefreshListener {
@@ -41,11 +50,15 @@ class ItemRecyclerFragment : BaseFragment(), SwipeRefreshL
lateinit var userRepository: UserRepository
@Inject
internal lateinit var hatchPetUseCase: HatchPetUseCase
+ @Inject
+ lateinit var userViewModel: MainUserViewModel
var adapter: ItemRecyclerAdapter? = null
var itemType: String? = null
+ var transformationItems: MutableList = mutableListOf()
var itemTypeText: String? = null
var user: User? = null
+ private var selectedSpecialItem: SpecialItem? = null
internal var layoutManager: androidx.recyclerview.widget.LinearLayoutManager? = null
override var binding: FragmentItemsBinding? = null
@@ -91,7 +104,7 @@ class ItemRecyclerFragment : BaseFragment(), SwipeRefreshL
adapter = ItemRecyclerAdapter(context, user)
}
binding?.recyclerView?.adapter = adapter
-
+ adapter?.useSpecialEvents?.subscribeWithErrorHandler { onSpecialItemSelected(it) }?.let { compositeSubscription.add(it) }
adapter?.let { adapter ->
compositeSubscription.add(
adapter.getSellItemFlowable()
@@ -112,7 +125,7 @@ class ItemRecyclerFragment : BaseFragment(), SwipeRefreshL
)
compositeSubscription.add(
adapter.getOpenMysteryItemFlowable()
- .flatMap { inventoryRepository.openMysteryItem(user) }
+ .flatMap { inventoryRepository.openMysteryItem(userViewModel.user.value) }
.doOnNext {
val activity = activity as? MainActivity
if (activity != null) {
@@ -123,7 +136,7 @@ class ItemRecyclerFragment : BaseFragment(), SwipeRefreshL
dialog.binding.titleView.text = it.text
dialog.binding.descriptionView.text = it.notes
dialog.addButton(R.string.equip, true) { _, _ ->
- inventoryRepository.equip(user, "equipped", it.key ?: "").subscribe({}, RxErrorHandler.handleEmptyError())
+ inventoryRepository.equip(userViewModel.user.value, "equipped", it.key ?: "").subscribe({}, RxErrorHandler.handleEmptyError())
}
dialog.addCloseButton()
dialog.enqueue()
@@ -253,7 +266,9 @@ class ItemRecyclerFragment : BaseFragment(), SwipeRefreshL
adapter?.data = items
}
.map { items -> items.mapNotNull { it.key } }
- .flatMap { inventoryRepository.getItems(itemClass, it.toTypedArray()) }
+ .flatMap {
+ inventoryRepository.getItems(itemClass, it.toTypedArray())
+ }
.map {
val itemMap = mutableMapOf()
for (item in it) {
@@ -268,6 +283,7 @@ class ItemRecyclerFragment : BaseFragment(), SwipeRefreshL
RxErrorHandler.handleEmptyError()
)
)
+
}
compositeSubscription.add(inventoryRepository.getPets().subscribe({ adapter?.setExistingPets(it) }, RxErrorHandler.handleEmptyError()))
@@ -286,6 +302,51 @@ class ItemRecyclerFragment : BaseFragment(), SwipeRefreshL
MainNavigationController.navigate(R.id.marketFragment)
}
+ private fun onSpecialItemSelected(specialItem: SpecialItem) {
+ selectedSpecialItem = specialItem
+ val intent = Intent(activity, SkillMemberActivity::class.java)
+ memberSelectionResult.launch(intent)
+ }
+
+ private val memberSelectionResult =
+ registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
+ if (it.resultCode == Activity.RESULT_OK) {
+ useSpecialItem(selectedSpecialItem, it.data?.getStringExtra("member_id"))
+ }
+ }
+
+ private fun useSpecialItem(specialItem: SpecialItem?, memberID: String? = null) {
+ if (specialItem == null || memberID == null) {
+ return
+ }
+
+ val observable: Flowable =
+ userRepository.useSkill(specialItem.key, specialItem.target, memberID)
+
+ compositeSubscription.add(
+ observable.subscribe(
+ { skillResponse -> this.displaySpecialItemResult(specialItem) },
+ RxErrorHandler.handleEmptyError()
+ )
+ )
+ }
+
+ private fun displaySpecialItemResult(specialItem: SpecialItem?) {
+ if (!isAdded) return
+
+ val activity = activity as? MainActivity
+ activity?.let {
+ HabiticaSnackbar.showSnackbar(
+ it.snackbarContainer,
+ context?.getString(R.string.used_skill_without_mana, specialItem?.text),
+ HabiticaSnackbar.SnackbarDisplayType.BLUE
+ )
+ }
+
+ loadItems()
+
+ }
+
companion object {
private const val ITEM_TYPE_KEY = "CLASS_TYPE_KEY"
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/items/ItemsFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/items/ItemsFragment.kt
index df4293962..374f1efa3 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/items/ItemsFragment.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/items/ItemsFragment.kt
@@ -68,7 +68,6 @@ class ItemsFragment : BaseMainFragment() {
4 -> "special"
else -> ""
}
- fragment.user = this@ItemsFragment.user
fragment.itemTypeText =
if (position == 4 && isAdded) getString(R.string.special_items)
else getPageTitle(position)
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 f007fb066..9d8333152 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
@@ -24,6 +24,7 @@ import com.habitrpg.android.habitica.ui.adapter.inventory.ShopRecyclerAdapter
import com.habitrpg.android.habitica.ui.fragments.BaseMainFragment
import com.habitrpg.android.habitica.ui.helpers.RecyclerViewState
import com.habitrpg.android.habitica.ui.helpers.SafeDefaultItemAnimator
+import com.habitrpg.android.habitica.ui.viewmodels.MainUserViewModel
import com.habitrpg.android.habitica.ui.views.CurrencyViews
import com.habitrpg.android.habitica.ui.views.dialogs.HabiticaAlertDialog
import javax.inject.Inject
@@ -44,6 +45,8 @@ open class ShopFragment : BaseMainFragment()
lateinit var socialRepository: SocialRepository
@Inject
lateinit var configManager: AppConfigManager
+ @Inject
+ lateinit var userViewModel: MainUserViewModel
private var layoutManager: GridLayoutManager? = null
@@ -106,7 +109,7 @@ open class ShopFragment : BaseMainFragment()
this.shopIdentifier = savedInstanceState.getString(SHOP_IDENTIFIER_KEY, "")
}
- adapter?.selectedGearCategory = user?.stats?.habitClass ?: ""
+ adapter?.selectedGearCategory = userViewModel.user.value?.stats?.habitClass ?: ""
if (shop != null) {
adapter?.setShop(shop)
@@ -122,15 +125,10 @@ open class ShopFragment : BaseMainFragment()
}
}
- compositeSubscription.add(
- userRepository.getUser().subscribe(
- {
- adapter?.user = user
- updateCurrencyView(it)
- },
- RxErrorHandler.handleEmptyError()
- )
- )
+ userViewModel.user.observe(viewLifecycleOwner) {
+ adapter?.user = it
+ updateCurrencyView(it)
+ }
compositeSubscription.add(
socialRepository.getGroup(Group.TAVERN_ID)
@@ -183,7 +181,7 @@ open class ShopFragment : BaseMainFragment()
this.inventoryRepository.retrieveShopInventory(shopUrl)
.map { shop1 ->
if (shop1.identifier == Shop.MARKET) {
- val user = user
+ val user = userViewModel.user.value
val specialCategory = ShopCategory()
specialCategory.text = getString(R.string.special)
if (user?.isValid == true && user.purchased?.plan?.isActive == true) {
@@ -315,9 +313,9 @@ open class ShopFragment : BaseMainFragment()
private const val SHOP_IDENTIFIER_KEY = "SHOP_IDENTIFIER_KEY"
}
- private fun updateCurrencyView(user: User) {
- currencyView.gold = user.stats?.gp ?: 0.0
- currencyView.gems = user.gemCount.toDouble()
- currencyView.hourglasses = user.hourglassCount.toDouble()
+ private fun updateCurrencyView(user: User?) {
+ currencyView.gold = user?.stats?.gp ?: 0.0
+ currencyView.gems = user?.gemCount?.toDouble() ?: 0.0
+ currencyView.hourglasses = user?.hourglassCount?.toDouble() ?: 0.0
}
}
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/stable/MountDetailRecyclerFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/stable/MountDetailRecyclerFragment.kt
index e476df24b..5c385c316 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/stable/MountDetailRecyclerFragment.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/stable/MountDetailRecyclerFragment.kt
@@ -18,6 +18,7 @@ import com.habitrpg.android.habitica.ui.adapter.inventory.MountDetailRecyclerAda
import com.habitrpg.android.habitica.ui.fragments.BaseMainFragment
import com.habitrpg.android.habitica.ui.helpers.MarginDecoration
import com.habitrpg.android.habitica.ui.helpers.SafeDefaultItemAnimator
+import com.habitrpg.android.habitica.ui.viewmodels.MainUserViewModel
import javax.inject.Inject
class MountDetailRecyclerFragment :
@@ -26,6 +27,8 @@ class MountDetailRecyclerFragment :
@Inject
internal lateinit var inventoryRepository: InventoryRepository
+ @Inject
+ lateinit var userViewModel: MainUserViewModel
var adapter: MountDetailRecyclerAdapter? = null
var animalType: String? = null
@@ -86,14 +89,15 @@ class MountDetailRecyclerFragment :
binding?.recyclerView?.itemAnimator = SafeDefaultItemAnimator()
this.loadItems()
- adapter?.getEquipFlowable()?.flatMap { key -> inventoryRepository.equip(user, "mount", key) }
+ adapter?.getEquipFlowable()?.flatMap { key -> inventoryRepository.equip(null, "mount", key) }
?.subscribe(
{
- user?.let { updatedUser -> adapter?.setUser(updatedUser) }
+ adapter?.currentMount = it.currentMount
},
RxErrorHandler.handleEmptyError()
)?.let { compositeSubscription.add(it) }
}
+ userViewModel.user.observe(viewLifecycleOwner) { adapter?.currentMount = it?.currentMount }
if (savedInstanceState != null) {
this.animalType = savedInstanceState.getString(ANIMAL_TYPE_KEY, "")
@@ -134,7 +138,6 @@ class MountDetailRecyclerFragment :
return@map mountMap
}.doOnNext {
adapter?.setOwnedMounts(it)
- user?.let { updatedUser -> adapter?.setUser(updatedUser) }
},
{ unsortedAnimals, ownedAnimals ->
val items = mutableListOf()
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/stable/PetDetailRecyclerFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/stable/PetDetailRecyclerFragment.kt
index a0d655fa4..3bbe400c7 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/stable/PetDetailRecyclerFragment.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/stable/PetDetailRecyclerFragment.kt
@@ -22,6 +22,7 @@ import com.habitrpg.android.habitica.ui.adapter.inventory.PetDetailRecyclerAdapt
import com.habitrpg.android.habitica.ui.fragments.BaseMainFragment
import com.habitrpg.android.habitica.ui.fragments.inventory.items.ItemDialogFragment
import com.habitrpg.android.habitica.ui.helpers.SafeDefaultItemAnimator
+import com.habitrpg.android.habitica.ui.viewmodels.MainUserViewModel
import io.reactivex.rxjava3.core.Maybe
import io.reactivex.rxjava3.kotlin.Flowables
import javax.inject.Inject
@@ -34,6 +35,8 @@ class PetDetailRecyclerFragment :
lateinit var inventoryRepository: InventoryRepository
@Inject
lateinit var feedPetUseCase: FeedPetUseCase
+ @Inject
+ lateinit var userViewModel: MainUserViewModel
var adapter: PetDetailRecyclerAdapter = PetDetailRecyclerAdapter()
private var animalType: String? = null
@@ -109,14 +112,15 @@ class PetDetailRecyclerFragment :
compositeSubscription.add(
adapter.getEquipFlowable()
- .flatMap { key -> inventoryRepository.equip(user, "pet", key) }
+ .flatMap { key -> inventoryRepository.equip(null, "pet", key) }
.subscribe(
{
- user?.let { updatedUser -> adapter.setUser(updatedUser) }
+ adapter.currentPet = it.currentPet
},
RxErrorHandler.handleEmptyError()
)
)
+ userViewModel.user.observe(viewLifecycleOwner) { adapter.currentPet = it?.currentPet }
compositeSubscription.add(adapter.feedFlowable.subscribe({ showFeedingDialog(it.first, it.second) }, RxErrorHandler.handleEmptyError()))
view.post { setGridSpanCount(view.width) }
@@ -168,7 +172,6 @@ class PetDetailRecyclerFragment :
return@map petMap
}.doOnNext {
adapter.setOwnedPets(it)
- user?.let { updatedUser -> adapter.setUser(updatedUser) }
}
).map {
val items = mutableListOf()
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/stable/StableFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/stable/StableFragment.kt
index 32e34d316..ee8fff172 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/stable/StableFragment.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/inventory/stable/StableFragment.kt
@@ -56,8 +56,7 @@ class StableFragment : BaseMainFragment() {
fragment.itemType = "mounts"
}
}
- fragment.user = this@StableFragment.user
- fragment.itemTypeText = getPageTitle(position).toString()
+ fragment.itemTypeText = getPageTitle(position)
return fragment
}
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 bd88b672f..84a2a1f79 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
@@ -23,6 +23,7 @@ import com.habitrpg.android.habitica.ui.fragments.BaseFragment
import com.habitrpg.android.habitica.ui.helpers.EmptyItem
import com.habitrpg.android.habitica.ui.helpers.MarginDecoration
import com.habitrpg.android.habitica.ui.helpers.SafeDefaultItemAnimator
+import com.habitrpg.android.habitica.ui.viewmodels.MainUserViewModel
import io.reactivex.rxjava3.core.Flowable
import io.reactivex.rxjava3.core.Maybe
import io.reactivex.rxjava3.kotlin.combineLatest
@@ -39,11 +40,12 @@ class StableRecyclerFragment :
lateinit var userRepository: UserRepository
@Inject
lateinit var configManager: AppConfigManager
+ @Inject
+ lateinit var userViewModel: MainUserViewModel
var adapter: StableRecyclerAdapter? = null
var itemType: String? = null
var itemTypeText: String? = null
- var user: User? = null
internal var layoutManager: androidx.recyclerview.widget.GridLayoutManager? = null
override var binding: FragmentRefreshRecyclerviewBinding? = null
@@ -96,7 +98,6 @@ class StableRecyclerFragment :
adapter = binding?.recyclerView?.adapter as? StableRecyclerAdapter
if (adapter == null) {
adapter = StableRecyclerAdapter()
- user?.let { adapter?.setUser(it) }
adapter?.animalIngredientsRetriever = { animal, callback ->
Maybe.zip(
inventoryRepository.getItems(Egg::class.java, arrayOf(animal.animal)).firstElement(),
@@ -119,11 +120,15 @@ class StableRecyclerFragment :
adapter?.let {
compositeSubscription.add(
it.getEquipFlowable()
- .flatMap { key -> inventoryRepository.equip(user, if (itemType == "pets") "pet" else "mount", key) }
+ .flatMap { key -> inventoryRepository.equip(null, if (itemType == "pets") "pet" else "mount", key) }
.subscribe({ }, RxErrorHandler.handleEmptyError())
)
}
}
+ userViewModel.user.observe(viewLifecycleOwner) {
+ adapter?.currentPet = it?.currentPet
+ adapter?.currentMount = it?.currentMount
+ }
this.loadItems()
view.post { setGridSpanCount(view.width) }
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/preferences/AccountPreferenceFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/preferences/AccountPreferenceFragment.kt
index 1ef0a9cb9..57e75fbd0 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/preferences/AccountPreferenceFragment.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/preferences/AccountPreferenceFragment.kt
@@ -64,11 +64,11 @@ class AccountPreferenceFragment: BasePreferencesFragment(),
override fun onResume() {
super.onResume()
- preferenceManager.sharedPreferences.registerOnSharedPreferenceChangeListener(this)
+ preferenceManager.sharedPreferences?.registerOnSharedPreferenceChangeListener(this)
}
override fun onPause() {
- preferenceManager.sharedPreferences.unregisterOnSharedPreferenceChangeListener(this)
+ preferenceManager.sharedPreferences?.unregisterOnSharedPreferenceChangeListener(this)
super.onPause()
}
@@ -130,8 +130,8 @@ class AccountPreferenceFragment: BasePreferencesFragment(),
preference?.summary = value
}
- override fun onPreferenceTreeClick(preference: Preference?): Boolean {
- when(preference?.key) {
+ override fun onPreferenceTreeClick(preference: Preference): Boolean {
+ when(preference.key) {
"username" -> showLoginNameDialog()
"confirm_username" -> showConfirmUsernameDialog()
"email" -> {
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/preferences/DayStartPreferenceDialogFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/preferences/DayStartPreferenceDialogFragment.kt
index ddfecaa8c..b7f33cdff 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/preferences/DayStartPreferenceDialogFragment.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/preferences/DayStartPreferenceDialogFragment.kt
@@ -33,7 +33,7 @@ class DayStartPreferenceDialogFragment : PreferenceDialogFragmentCompat() {
return lastHour.toString() + ":00"
}
- override fun onCreateDialogView(context: Context?): View {
+ override fun onCreateDialogView(context: Context): View {
val wrapper = LinearLayout(context)
wrapper.orientation = LinearLayout.VERTICAL
picker = TimePicker(context)
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/preferences/EmailNotificationsPreferencesFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/preferences/EmailNotificationsPreferencesFragment.kt
index 7d81ddb33..0e1910c6c 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/preferences/EmailNotificationsPreferencesFragment.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/preferences/EmailNotificationsPreferencesFragment.kt
@@ -19,12 +19,12 @@ class EmailNotificationsPreferencesFragment : BasePreferencesFragment(), SharedP
override fun onResume() {
super.onResume()
- preferenceScreen.sharedPreferences.registerOnSharedPreferenceChangeListener(this)
+ preferenceScreen.sharedPreferences?.registerOnSharedPreferenceChangeListener(this)
}
override fun onPause() {
super.onPause()
- preferenceScreen.sharedPreferences.unregisterOnSharedPreferenceChangeListener(this)
+ preferenceScreen.sharedPreferences?.unregisterOnSharedPreferenceChangeListener(this)
}
override fun setupPreferences() { /* no-on */ }
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/preferences/PreferencesFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/preferences/PreferencesFragment.kt
index 1c289f462..6702d0374 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/preferences/PreferencesFragment.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/preferences/PreferencesFragment.kt
@@ -62,16 +62,16 @@ class PreferencesFragment : BasePreferencesFragment(), SharedPreferences.OnShare
override fun setupPreferences() {
timePreference = findPreference("reminder_time") as? TimePreference
- val useReminder = preferenceManager.sharedPreferences.getBoolean("use_reminder", false)
- timePreference?.isEnabled = useReminder
+ val useReminder = preferenceManager.sharedPreferences?.getBoolean("use_reminder", false)
+ timePreference?.isEnabled = useReminder ?: false
pushNotificationsPreference = findPreference("pushNotifications") as? PreferenceScreen
- val usePushNotifications = preferenceManager.sharedPreferences.getBoolean("usePushNotifications", true)
- pushNotificationsPreference?.isEnabled = usePushNotifications
+ val usePushNotifications = preferenceManager.sharedPreferences?.getBoolean("usePushNotifications", true)
+ pushNotificationsPreference?.isEnabled = usePushNotifications ?: false
emailNotificationsPreference = findPreference("emailNotifications") as? PreferenceScreen
- val useEmailNotifications = preferenceManager.sharedPreferences.getBoolean("useEmailNotifications", true)
- emailNotificationsPreference?.isEnabled = useEmailNotifications
+ val useEmailNotifications = preferenceManager.sharedPreferences?.getBoolean("useEmailNotifications", true)
+ emailNotificationsPreference?.isEnabled = useEmailNotifications ?: false
classSelectionPreference = findPreference("choose_class")
@@ -80,7 +80,7 @@ class PreferencesFragment : BasePreferencesFragment(), SharedPreferences.OnShare
serverUrlPreference = findPreference("server_url") as? ListPreference
serverUrlPreference?.isVisible = false
- serverUrlPreference?.summary = preferenceManager.sharedPreferences.getString("server_url", "")
+ serverUrlPreference?.summary = preferenceManager.sharedPreferences?.getString("server_url", "")
val themePreference = findPreference("theme_name") as? ListPreference
themePreference?.summary = themePreference?.entry ?: "Default"
@@ -101,11 +101,11 @@ class PreferencesFragment : BasePreferencesFragment(), SharedPreferences.OnShare
override fun onResume() {
super.onResume()
- preferenceManager.sharedPreferences.registerOnSharedPreferenceChangeListener(this)
+ preferenceManager.sharedPreferences?.registerOnSharedPreferenceChangeListener(this)
}
override fun onPause() {
- preferenceManager.sharedPreferences.unregisterOnSharedPreferenceChangeListener(this)
+ preferenceManager.sharedPreferences?.unregisterOnSharedPreferenceChangeListener(this)
super.onPause()
}
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/preferences/PushNotificationsPreferencesFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/preferences/PushNotificationsPreferencesFragment.kt
index 4de688c49..97a6eb276 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/preferences/PushNotificationsPreferencesFragment.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/preferences/PushNotificationsPreferencesFragment.kt
@@ -19,12 +19,12 @@ class PushNotificationsPreferencesFragment : BasePreferencesFragment(), SharedPr
override fun onResume() {
super.onResume()
- preferenceScreen.sharedPreferences.registerOnSharedPreferenceChangeListener(this)
+ preferenceScreen.sharedPreferences?.registerOnSharedPreferenceChangeListener(this)
}
override fun onPause() {
super.onPause()
- preferenceScreen.sharedPreferences.unregisterOnSharedPreferenceChangeListener(this)
+ preferenceScreen.sharedPreferences?.unregisterOnSharedPreferenceChangeListener(this)
}
override fun setupPreferences() { /* no-on */ }
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/preferences/TimePreferenceDialogFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/preferences/TimePreferenceDialogFragment.kt
index b9dc928a5..d7c97b50d 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/preferences/TimePreferenceDialogFragment.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/preferences/TimePreferenceDialogFragment.kt
@@ -34,7 +34,7 @@ class TimePreferenceDialogFragment : PreferenceDialogFragmentCompat() {
return lastHour.toString() + ":" + String.format(Locale.UK, "%02d", lastMinute)
}
- override fun onCreateDialogView(context: Context?): View {
+ override fun onCreateDialogView(context: Context): View {
picker = TimePicker(context)
picker.setIs24HourView(android.text.format.DateFormat.is24HourFormat(context))
return picker
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/skills/SkillsFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/skills/SkillsFragment.kt
index 1451d75c2..cca68dcd0 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/skills/SkillsFragment.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/skills/SkillsFragment.kt
@@ -23,12 +23,14 @@ import com.habitrpg.android.habitica.ui.activities.SkillTasksActivity
import com.habitrpg.android.habitica.ui.adapter.SkillsRecyclerViewAdapter
import com.habitrpg.android.habitica.ui.fragments.BaseMainFragment
import com.habitrpg.android.habitica.ui.helpers.SafeDefaultItemAnimator
+import com.habitrpg.android.habitica.ui.viewmodels.MainUserViewModel
import com.habitrpg.android.habitica.ui.views.HabiticaIconsHelper
import com.habitrpg.android.habitica.ui.views.HabiticaSnackbar
import com.habitrpg.android.habitica.ui.views.HabiticaSnackbar.Companion.showSnackbar
import io.reactivex.rxjava3.core.Flowable
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
+import javax.inject.Inject
class SkillsFragment : BaseMainFragment() {
internal var adapter: SkillsRecyclerViewAdapter? = null
@@ -36,20 +38,16 @@ class SkillsFragment : BaseMainFragment() {
override var binding: FragmentSkillsBinding? = null
+ @Inject
+ lateinit var userViewModel: MainUserViewModel
+
override fun createBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentSkillsBinding {
return FragmentSkillsBinding.inflate(inflater, container, false)
}
- override var user: User? = null
- set(value) {
- field = value
- checkUserLoadSkills()
- }
-
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
adapter = SkillsRecyclerViewAdapter()
adapter?.useSkillEvents?.subscribeWithErrorHandler { onSkillSelected(it) }?.let { compositeSubscription.add(it) }
- checkUserLoadSkills()
this.tutorialStepIdentifier = "skills"
this.tutorialText = getString(R.string.tutorial_skills)
@@ -62,20 +60,21 @@ class SkillsFragment : BaseMainFragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
-
+ userViewModel.user.observe(viewLifecycleOwner) { user ->
+ user?.let { checkUserLoadSkills(it) }
+ }
binding?.recyclerView?.layoutManager = androidx.recyclerview.widget.LinearLayoutManager(activity)
binding?.recyclerView?.adapter = adapter
binding?.recyclerView?.itemAnimator = SafeDefaultItemAnimator()
}
- private fun checkUserLoadSkills() {
- if (user == null || adapter == null) {
+ private fun checkUserLoadSkills(user: User) {
+ if (adapter == null) {
return
}
- adapter?.mana = this.user?.stats?.mp ?: 0.0
- adapter?.level = this.user?.stats?.lvl ?: 0
- adapter?.specialItems = this.user?.items?.special
- user?.let { user ->
+ adapter?.mana = user.stats?.mp ?: 0.0
+ adapter?.level = user.stats?.lvl ?: 0
+ adapter?.specialItems = user.items?.special
Flowable.combineLatest(
userRepository.getSkills(user),
userRepository.getSpecialItems(user),
@@ -89,9 +88,7 @@ class SkillsFragment : BaseMainFragment() {
}
return@combineLatest allEntries
}
- )
- .subscribe({ skills -> adapter?.setSkillList(skills) }, RxErrorHandler.handleEmptyError())
- }
+ ).subscribe({ skills -> adapter?.setSkillList(skills) }, RxErrorHandler.handleEmptyError())
}
private fun onSkillSelected(skill: Skill) {
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/InboxMessageListFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/InboxMessageListFragment.kt
index 5abbb4fa1..78f11d71c 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/InboxMessageListFragment.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/InboxMessageListFragment.kt
@@ -7,6 +7,7 @@ import android.os.Bundle
import android.view.*
import androidx.appcompat.app.AlertDialog
import androidx.fragment.app.viewModels
+import androidx.recyclerview.widget.RecyclerView
import com.habitrpg.android.habitica.MainNavDirections
import com.habitrpg.android.habitica.R
import com.habitrpg.android.habitica.components.UserComponent
@@ -88,7 +89,14 @@ class InboxMessageListFragment : BaseMainFragment
setReceivingUser(member.username, member.id)
activity?.title = member.displayName
- chatAdapter = InboxAdapter(user, member)
+ chatAdapter = InboxAdapter(viewModel.user.value, member)
+ chatAdapter?.registerAdapterDataObserver(object : RecyclerView.AdapterDataObserver() {
+ override fun onItemRangeInserted(positionStart: Int, itemCount: Int) {
+ if (positionStart == 0) {
+ binding?.recyclerView?.scrollToPosition(0)
+ }
+ }
+ })
viewModel.messages.observe(this.viewLifecycleOwner) {
markMessagesAsRead(it)
chatAdapter?.submitList(it)
@@ -170,7 +178,7 @@ class InboxMessageListFragment : BaseMainFragment) {
- socialRepository.markSomePrivateMessagesAsRead(user, messages)
+ socialRepository.markSomePrivateMessagesAsRead(viewModel.user.value, messages)
}
private fun startAutoRefreshing() {
@@ -215,7 +223,6 @@ class InboxMessageListFragment : BaseMainFragment
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/InboxOverviewFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/InboxOverviewFragment.kt
index d42ca5996..ec808c326 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/InboxOverviewFragment.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/InboxOverviewFragment.kt
@@ -41,7 +41,7 @@ class InboxOverviewFragment : BaseMainFragment(), androidx
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
this.hidesToolbar = true
- compositeSubscription.add(this.socialRepository.markPrivateMessagesRead(user).subscribe({ }, RxErrorHandler.handleEmptyError()))
+ compositeSubscription.add(this.socialRepository.markPrivateMessagesRead(null).subscribe({ }, RxErrorHandler.handleEmptyError()))
return super.onCreateView(inflater, container, savedInstanceState)
}
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/QuestDetailFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/QuestDetailFragment.kt
index 1768723bf..226e6a294 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/QuestDetailFragment.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/QuestDetailFragment.kt
@@ -26,6 +26,7 @@ import com.habitrpg.android.habitica.modules.AppModule
import com.habitrpg.android.habitica.ui.fragments.BaseMainFragment
import com.habitrpg.android.habitica.ui.helpers.DataBindingUtils
import com.habitrpg.android.habitica.ui.helpers.MarkdownParser
+import com.habitrpg.android.habitica.ui.viewmodels.MainUserViewModel
import com.habitrpg.android.habitica.ui.views.dialogs.HabiticaAlertDialog
import javax.inject.Inject
import javax.inject.Named
@@ -38,6 +39,8 @@ class QuestDetailFragment : BaseMainFragment() {
lateinit var inventoryRepository: InventoryRepository
@field:[Inject Named(AppModule.NAMED_USER_ID)]
lateinit var userId: String
+ @Inject
+ lateinit var userViewModel: MainUserViewModel
override var binding: FragmentQuestDetailBinding? = null
@@ -101,7 +104,7 @@ class QuestDetailFragment : BaseMainFragment() {
compositeSubscription.add(
socialRepository.getMember(quest?.leader).subscribe(
{ member ->
- if (context != null && binding?.questLeaderView != null && member != null) {
+ if (context != null && binding?.questLeaderView != null) {
binding?.questLeaderView?.text = context?.getString(R.string.quest_leader_header, member.displayName)
}
},
@@ -109,6 +112,7 @@ class QuestDetailFragment : BaseMainFragment() {
)
)
+ val user = userViewModel.user.value
if (binding?.questResponseWrapper != null) {
if (userId != party?.quest?.leader && user?.party?.quest?.key == group.quest?.key && user?.party?.quest?.RSVPNeeded == false) {
binding?.questLeaveButton?.visibility = View.VISIBLE
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/challenges/ChallengeDetailFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/challenges/ChallengeDetailFragment.kt
index 7e61daf32..943295fc7 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/challenges/ChallengeDetailFragment.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/challenges/ChallengeDetailFragment.kt
@@ -29,6 +29,7 @@ import com.habitrpg.android.habitica.ui.viewHolders.tasks.DailyViewHolder
import com.habitrpg.android.habitica.ui.viewHolders.tasks.HabitViewHolder
import com.habitrpg.android.habitica.ui.viewHolders.tasks.RewardViewHolder
import com.habitrpg.android.habitica.ui.viewHolders.tasks.TodoViewHolder
+import com.habitrpg.android.habitica.ui.viewmodels.MainUserViewModel
import com.habitrpg.android.habitica.ui.views.HabiticaIconsHelper
import com.habitrpg.android.habitica.ui.views.dialogs.HabiticaAlertDialog
import retrofit2.HttpException
@@ -41,6 +42,9 @@ class ChallengeDetailFragment : BaseMainFragment
lateinit var challengeRepository: ChallengeRepository
@Inject
lateinit var socialRepository: SocialRepository
+ @Inject
+ lateinit var userViewModel: MainUserViewModel
+
override var binding: FragmentChallengeDetailBinding? = null
@@ -236,7 +240,7 @@ class ChallengeDetailFragment : BaseMainFragment
binding?.creatorAvatarview?.setAvatar(creator)
binding?.creatorLabel?.tier = creator.contributor?.level ?: 0
binding?.creatorLabel?.username = creator.displayName
- isCreator = creator.id == user?.id
+ isCreator = creator.id == userViewModel.userID
this.activity?.invalidateOptionsMenu()
}
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/party/NoPartyFragmentFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/party/NoPartyFragmentFragment.kt
index a92ee5ee9..8ca468010 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/party/NoPartyFragmentFragment.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/party/NoPartyFragmentFragment.kt
@@ -30,6 +30,7 @@ import com.habitrpg.android.habitica.ui.activities.GroupFormActivity
import com.habitrpg.android.habitica.ui.fragments.BaseMainFragment
import com.habitrpg.android.habitica.ui.helpers.DataBindingUtils
import com.habitrpg.android.habitica.ui.helpers.setMarkdown
+import com.habitrpg.android.habitica.ui.viewmodels.MainUserViewModel
import com.habitrpg.android.habitica.ui.views.HabiticaSnackbar
import javax.inject.Inject
import kotlin.math.roundToInt
@@ -40,6 +41,8 @@ class NoPartyFragmentFragment : BaseMainFragment() {
lateinit var socialRepository: SocialRepository
@Inject
lateinit var configManager: AppConfigManager
+ @Inject
+ lateinit var userViewModel: MainUserViewModel
override var binding: FragmentNoPartyBinding? = null
@@ -65,7 +68,7 @@ class NoPartyFragmentFragment : BaseMainFragment() {
parentFragmentManager.popBackStack()
MainNavigationController.navigate(
R.id.partyFragment,
- bundleOf(Pair("partyID", user?.party?.id))
+ bundleOf(Pair("partyID", userViewModel.partyID))
)
},
RxErrorHandler.handleEmptyError()
@@ -92,7 +95,7 @@ class NoPartyFragmentFragment : BaseMainFragment() {
binding?.usernameTextview?.setOnClickListener {
val clipboard = context?.getSystemService(Context.CLIPBOARD_SERVICE) as? ClipboardManager
- val clip = ClipData.newPlainText(context?.getString(R.string.username), user?.username)
+ val clip = ClipData.newPlainText(context?.getString(R.string.username), userViewModel.username)
clipboard?.setPrimaryClip(clip)
val activity = activity
if (activity != null) {
@@ -103,7 +106,7 @@ class NoPartyFragmentFragment : BaseMainFragment() {
binding?.createPartyButton?.setOnClickListener {
val bundle = Bundle()
bundle.putString("groupType", "party")
- bundle.putString("leader", user?.id)
+ bundle.putString("leader", userViewModel.userID)
val intent = Intent(activity, GroupFormActivity::class.java)
intent.putExtras(bundle)
intent.flags = Intent.FLAG_ACTIVITY_REORDER_TO_FRONT
@@ -132,14 +135,15 @@ class NoPartyFragmentFragment : BaseMainFragment() {
}
}
- if ((user?.invitations?.parties?.count() ?: 0) > 0) {
+ val partyInvitations = userViewModel.partyInvitations
+ if (partyInvitations.size > 0) {
binding?.invitationWrapper?.visibility = View.VISIBLE
- user?.invitations?.parties?.let { binding?.invitationsView?.setInvitations(it) }
+ binding?.invitationsView?.setInvitations(partyInvitations)
} else {
binding?.invitationWrapper?.visibility = View.GONE
}
- binding?.usernameTextview?.text = user?.formattedUsername
+ binding?.usernameTextview?.text = userViewModel.formattedUsername
}
private val groupFormResult = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
@@ -164,7 +168,7 @@ class NoPartyFragmentFragment : BaseMainFragment() {
}
MainNavigationController.navigate(
R.id.partyFragment,
- bundleOf(Pair("partyID", user?.party?.id))
+ bundleOf(Pair("partyID", userViewModel.partyID))
)
},
RxErrorHandler.handleEmptyError()
@@ -196,12 +200,11 @@ class NoPartyFragmentFragment : BaseMainFragment() {
companion object {
- fun newInstance(user: User?): NoPartyFragmentFragment {
+ fun newInstance(): NoPartyFragmentFragment {
val args = Bundle()
val fragment = NoPartyFragmentFragment()
fragment.arguments = args
- fragment.user = user
return fragment
}
}
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/party/PartyFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/party/PartyFragment.kt
index 62eea83b3..9aa943813 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/party/PartyFragment.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/social/party/PartyFragment.kt
@@ -96,15 +96,11 @@ class PartyFragment : BaseMainFragment() {
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
val group = viewModel.getGroupData().value
- if (group != null && this.user != null) {
- if (group.leaderID == this.user?.id) {
- inflater.inflate(R.menu.menu_party_admin, menu)
- if (group.memberCount > 1) {
- menu.findItem(R.id.menu_guild_leave).isVisible = false
- }
- } else {
- inflater.inflate(R.menu.menu_party, menu)
- }
+ if (viewModel.isLeader) {
+ inflater.inflate(R.menu.menu_party_admin, menu)
+ menu.findItem(R.id.menu_guild_leave).isVisible = group?.memberCount != 1
+ } else {
+ inflater.inflate(R.menu.menu_party, menu)
}
}
@@ -159,7 +155,7 @@ class PartyFragment : BaseMainFragment() {
private val sendInvitesResult = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
if (it.resultCode == Activity.RESULT_OK) {
val inviteData = HashMap()
- inviteData["inviter"] = user?.profile?.name ?: ""
+ inviteData["inviter"] = viewModel.user.value?.profile?.name ?: ""
val emails = it.data?.getStringArrayExtra(GroupInviteActivity.EMAILS_KEY)
if (emails != null && emails.isNotEmpty()) {
val invites = ArrayList>()
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/support/BugFixFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/support/BugFixFragment.kt
index 3c63575f8..53e4b2036 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/support/BugFixFragment.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/support/BugFixFragment.kt
@@ -20,6 +20,7 @@ import com.habitrpg.android.habitica.helpers.DeviceName
import com.habitrpg.android.habitica.helpers.MainNavigationController
import com.habitrpg.android.habitica.modules.AppModule
import com.habitrpg.android.habitica.ui.fragments.BaseMainFragment
+import com.habitrpg.android.habitica.ui.viewmodels.MainUserViewModel
import io.reactivex.rxjava3.core.Completable
import io.reactivex.rxjava3.schedulers.Schedulers
import javax.inject.Inject
@@ -42,6 +43,8 @@ class BugFixFragment : BaseMainFragment() {
@Inject
lateinit var appConfigManager: AppConfigManager
+ @Inject
+ lateinit var userViewModel: MainUserViewModel
override fun injectFragment(component: UserComponent) {
component.inject(this)
@@ -124,8 +127,7 @@ class BugFixFragment : BaseMainFragment() {
}
bodyOfEmail += newLine + Uri.encode("User ID: $userId")
- val user = this.user
- if (user != null) {
+ userViewModel.user.value?.let { user ->
bodyOfEmail += newLine + Uri.encode("Level: " + (user.stats?.lvl ?: 0)) +
newLine + Uri.encode(
"Class: " + (if (user.preferences?.disableClasses == true) "Disabled" else (user.stats?.habitClass
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/MountViewHolder.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/MountViewHolder.kt
index 27aab30e1..8a4e33a69 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/MountViewHolder.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/MountViewHolder.kt
@@ -19,7 +19,7 @@ class MountViewHolder(parent: ViewGroup, private val equipEvents: PublishSubject
private var binding: MountOverviewItemBinding = MountOverviewItemBinding.bind(itemView)
private var owned: Boolean = false
var animal: Mount? = null
- private var user: User? = null
+ private var currentMount: String? = null
var resources: Resources = itemView.resources
@@ -27,10 +27,10 @@ class MountViewHolder(parent: ViewGroup, private val equipEvents: PublishSubject
itemView.setOnClickListener(this)
}
- fun bind(item: Mount, owned: Boolean, user: User?) {
+ fun bind(item: Mount, owned: Boolean, currentMount: String?) {
animal = item
this.owned = owned
- this.user = user
+ this.currentMount = currentMount
binding.titleTextView.visibility = View.GONE
binding.ownedTextView.visibility = View.GONE
val imageName = "stable_Mount_Icon_" + item.animal + "-" + item.color
@@ -39,7 +39,7 @@ class MountViewHolder(parent: ViewGroup, private val equipEvents: PublishSubject
binding.imageView.alpha = 0.2f
}
binding.imageView.background = null
- binding.activeIndicator.visibility = if (user?.currentMount.equals(animal?.key)) View.VISIBLE else View.GONE
+ binding.activeIndicator.visibility = if (currentMount.equals(animal?.key)) View.VISIBLE else View.GONE
DataBindingUtils.loadImage(itemView.context, imageName) {
val drawable = if (owned) it else BitmapDrawable(itemView.context.resources, it.toBitmap().extractAlpha())
binding.imageView.background = drawable
@@ -53,7 +53,7 @@ class MountViewHolder(parent: ViewGroup, private val equipEvents: PublishSubject
val menu = BottomSheetMenu(itemView.context)
menu.setTitle(animal?.text)
- val hasCurrentMount = user?.currentMount.equals(animal?.key)
+ val hasCurrentMount = currentMount.equals(animal?.key)
val labelId = if (hasCurrentMount) R.string.unequip else R.string.equip
menu.addMenuItem(BottomSheetMenuItem(resources.getString(labelId)))
menu.setSelectionRunnable {
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/PetViewHolder.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/PetViewHolder.kt
index ff7f5f0dc..f4bb3c0c2 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/PetViewHolder.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewHolders/PetViewHolder.kt
@@ -24,7 +24,7 @@ class PetViewHolder(parent: ViewGroup, private val equipEvents: PublishSubject 0
@@ -61,7 +61,7 @@ class PetViewHolder(parent: ViewGroup, private val equipEvents: PublishSubject by lazy {
- loadUserFromLocal()
- MutableLiveData()
- }
val user: LiveData by lazy {
- _user
+ userViewModel.user
}
init {
@@ -47,11 +40,6 @@ abstract class BaseViewModel(initializeComponent: Boolean = true) : ViewModel()
internal val disposable = CompositeDisposable()
- internal fun loadUserFromLocal() {
- disposable.add(userRepository.getUser().observeOn(AndroidSchedulers.mainThread())
- .subscribe({ _user.value = it }, RxErrorHandler.handleEmptyError()))
- }
-
fun updateUser(path: String, value: Any) {
disposable.add(userRepository.updateUser(path, value)
.subscribe({ }, RxErrorHandler.handleEmptyError()))
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewmodels/GroupViewModel.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewmodels/GroupViewModel.kt
index ceee471c5..81f5a3c27 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewmodels/GroupViewModel.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewmodels/GroupViewModel.kt
@@ -249,7 +249,8 @@ open class GroupViewModel(initializeComponent: Boolean) : BaseViewModel(initiali
}
fun likeMessage(message: ChatMessage) {
- val index = _chatMessages.value?.indexOf(message) ?: return
+ val index = _chatMessages.value?.indexOf(message)
+ if (index == null || index < 0) return
disposable.add(socialRepository.likeMessage(message).subscribe(
{
val list = _chatMessages.value?.toMutableList()
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewmodels/MainUserViewModel.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewmodels/MainUserViewModel.kt
new file mode 100644
index 000000000..d921c4694
--- /dev/null
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewmodels/MainUserViewModel.kt
@@ -0,0 +1,62 @@
+package com.habitrpg.android.habitica.ui.viewmodels
+
+import androidx.lifecycle.LiveData
+import androidx.lifecycle.MutableLiveData
+import androidx.lifecycle.ViewModel
+import com.habitrpg.android.habitica.HabiticaBaseApplication
+import com.habitrpg.android.habitica.components.UserComponent
+import com.habitrpg.android.habitica.data.UserRepository
+import com.habitrpg.android.habitica.helpers.RxErrorHandler
+import com.habitrpg.android.habitica.models.invitations.GenericInvitation
+import com.habitrpg.android.habitica.models.invitations.PartyInvite
+import com.habitrpg.android.habitica.models.user.User
+import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
+import io.reactivex.rxjava3.disposables.CompositeDisposable
+import javax.inject.Inject
+
+class MainUserViewModel(val userRepository: UserRepository) {
+
+ val formattedUsername: CharSequence?
+ get() = user.value?.formattedUsername
+ val partyInvitations: List
+ get() = user.value?.invitations?.parties ?: emptyList()
+ val userID: String?
+ get() = user.value?.id
+ val username: CharSequence
+ get() = user.value?.username ?: ""
+ val partyID: String?
+ get() = user.value?.party?.id
+ val isUserFainted: Boolean
+ get() = (user.value?.stats?.hp ?: 1.0) == 0.0
+ val isUserInParty: Boolean
+ get() = user.value?.hasParty == true
+
+ private val _user: MutableLiveData by lazy {
+ loadUserFromLocal()
+ MutableLiveData()
+ }
+ val user: LiveData by lazy {
+ _user
+ }
+
+ init {
+ HabiticaBaseApplication.userComponent?.inject(this)
+ }
+
+ fun onCleared() {
+ userRepository.close()
+ disposable.clear()
+ }
+
+ internal val disposable = CompositeDisposable()
+
+ internal fun loadUserFromLocal() {
+ disposable.add(userRepository.getUser().observeOn(AndroidSchedulers.mainThread())
+ .subscribe({ _user.value = it }, RxErrorHandler.handleEmptyError()))
+ }
+
+ fun updateUser(path: String, value: Any) {
+ disposable.add(userRepository.updateUser(path, value)
+ .subscribe({ }, RxErrorHandler.handleEmptyError()))
+ }
+}
\ No newline at end of file
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewmodels/inventory/equipment/EquipmentOverviewViewModel.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewmodels/inventory/equipment/EquipmentOverviewViewModel.kt
index ebc740ec1..1d2f454e3 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewmodels/inventory/equipment/EquipmentOverviewViewModel.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewmodels/inventory/equipment/EquipmentOverviewViewModel.kt
@@ -9,6 +9,10 @@ import com.habitrpg.android.habitica.ui.viewmodels.BaseViewModel
import javax.inject.Inject
class EquipmentOverviewViewModel(savedStateHandle: SavedStateHandle): BaseViewModel() {
+ val usesAutoEquip: Boolean
+ get() = user.value?.preferences?.autoEquip == true
+ val usesCostume: Boolean
+ get() = user.value?.preferences?.costume == true
@Inject
lateinit var inventoryRepository: InventoryRepository
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/ExtraLabelPreference.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/ExtraLabelPreference.kt
index 54ba9940e..4a5a5cdc7 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/ExtraLabelPreference.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/ExtraLabelPreference.kt
@@ -8,7 +8,7 @@ import androidx.preference.PreferenceViewHolder
import com.habitrpg.android.habitica.R
class ExtraLabelPreference(
- context: Context?,
+ context: Context,
attrs: AttributeSet?
) : Preference(context, attrs) {
var extraText: String? = null
@@ -18,9 +18,9 @@ class ExtraLabelPreference(
layoutResource = R.layout.preference_button
}
- override fun onBindViewHolder(holder: PreferenceViewHolder?) {
+ override fun onBindViewHolder(holder: PreferenceViewHolder) {
super.onBindViewHolder(holder)
- val textView = holder?.itemView?.findViewById(R.id.extra_label)
+ val textView = holder.itemView.findViewById(R.id.extra_label)
textView?.text = extraText
extraTextColor?.let {
textView?.setTextColor(it)
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/dialogs/PetSuggestHatchDialog.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/dialogs/PetSuggestHatchDialog.kt
index 1358370e3..408825289 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/dialogs/PetSuggestHatchDialog.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/dialogs/PetSuggestHatchDialog.kt
@@ -6,6 +6,7 @@ import android.view.LayoutInflater
import android.view.View
import android.widget.LinearLayout
import androidx.core.graphics.drawable.toBitmap
+import com.habitrpg.android.habitica.HabiticaBaseApplication
import com.habitrpg.android.habitica.R
import com.habitrpg.android.habitica.databinding.DialogPetSuggestHatchBinding
import com.habitrpg.android.habitica.extensions.subscribeWithErrorHandler
@@ -36,6 +37,7 @@ class PetSuggestHatchDialog(context: Context) : HabiticaAlertDialog(context) {
val inflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as? LayoutInflater
inflater?.let { binding = DialogPetSuggestHatchBinding.inflate(it) }
setAdditionalContentView(binding.root)
+ HabiticaBaseApplication.userComponent?.inject(this)
}
fun configure(pet: Animal, egg: Egg?, potion: HatchingPotion?, eggCount: Int, potionCount: Int, hasUnlockedEgg: Boolean, hasUnlockedPotion: Boolean, hasMount: Boolean) {
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/shops/PurchaseDialog.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/shops/PurchaseDialog.kt
index 95dd40dbf..19674690a 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/shops/PurchaseDialog.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/shops/PurchaseDialog.kt
@@ -11,6 +11,7 @@ import androidx.core.content.ContextCompat
import androidx.core.graphics.drawable.toDrawable
import androidx.core.os.bundleOf
import com.google.firebase.analytics.FirebaseAnalytics
+import com.habitrpg.android.habitica.HabiticaBaseApplication
import com.habitrpg.android.habitica.R
import com.habitrpg.android.habitica.components.UserComponent
import com.habitrpg.android.habitica.data.InventoryRepository
@@ -319,6 +320,7 @@ class PurchaseDialog(context: Context, component: UserComponent?, val item: Shop
}
private fun buyItem(quantity: Int) {
+ val application = ownerActivity?.application as? HabiticaBaseApplication
FirebaseAnalytics.getInstance(context).logEvent(
"item_purchased",
bundleOf(
@@ -373,7 +375,7 @@ class PurchaseDialog(context: Context, component: UserComponent?, val item: Shop
"hourglasses" -> ContextCompat.getColor(context, R.color.text_brand)
else -> 0
}
- (ownerActivity as? SnackbarActivity)?.showSnackbar(
+ ((application?.currentActivity?.get() ?: getActivity() ?: ownerActivity) as? SnackbarActivity)?.showSnackbar(
content = text,
rightIcon = priceLabel.compoundDrawables[0],
rightTextColor = rightTextColor,
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/yesterdailies/YesterdailyDialog.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/yesterdailies/YesterdailyDialog.kt
index 2ec30a1ce..2f075e230 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/yesterdailies/YesterdailyDialog.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/yesterdailies/YesterdailyDialog.kt
@@ -158,7 +158,8 @@ class YesterdailyDialog private constructor(context: Context, private val userRe
private fun configureTaskView(taskView: View, task: Task) {
val completed = !task.isDisplayedActive
- val checkmark = taskView.findViewById(R.id.checkmark)
+ val checkmark = taskView.findViewById(R.id.checkmark)
+ checkmark?.drawable?.setTint(ContextCompat.getColor(context, R.color.gray_400))
val checkboxHolder = taskView.findViewById(R.id.checkBoxHolder)
val checkboxBackground = taskView.findViewById(R.id.checkbox_background)
checkmark?.visibility = if (completed) View.VISIBLE else View.GONE
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
index 815dc0ed2..b413e31dd 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/utils/ContentDeserializer.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/utils/ContentDeserializer.kt
@@ -11,14 +11,7 @@ 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 com.habitrpg.android.habitica.models.inventory.*
import io.realm.RealmList
import java.lang.reflect.Type
@@ -101,6 +94,13 @@ class ContentDeserializer : JsonDeserializer {
result.spells.add(skill)
}
}
+
+ if (obj.has("special")) {
+ for (entry in obj.get("special").asJsonObject.entrySet()) {
+ result.special.add(context.deserialize(entry.value, SpecialItem::class.java))
+ }
+ }
+
result.appearances = context.deserialize(obj.get("appearances"), object : TypeToken>() {}.type)
result.backgrounds = context.deserialize(obj.get("backgrounds"), object : TypeToken>() {}.type)
val noBackground = Customization()
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/utils/OwnedItemListDeserializer.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/utils/OwnedItemListDeserializer.kt
index 814063d64..0e8de546d 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/utils/OwnedItemListDeserializer.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/utils/OwnedItemListDeserializer.kt
@@ -13,10 +13,12 @@ class OwnedItemListDeserializer : JsonDeserializer> {
val entrySet = json?.asJsonObject?.entrySet()
if (entrySet != null) {
for (entry in entrySet) {
- val item = OwnedItem()
- item.key = entry.key
- item.numberOwned = entry.value.asInt
- ownedItems.add(item)
+ if (entry.value.isJsonPrimitive){
+ val item = OwnedItem()
+ item.key = entry.key
+ item.numberOwned = entry.value.asInt
+ ownedItems.add(item)
+ }
}
}
return ownedItems
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 186339f11..a7eee286a 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
@@ -99,8 +99,7 @@ class UserDeserializer : JsonDeserializer {
item.key = "inventory_present"
item.userID = user.id
item.numberOwned = user.purchased?.plan?.mysteryItemCount ?: 0
- user.items?.special?.ownedItems = RealmList()
- user.items?.special?.ownedItems?.add(item)
+ user.items?.special?.add(item)
user.items?.setItemTypes()
}
if (obj.has("auth")) {
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/widget/AddTaskWidgetProvider.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/widget/AddTaskWidgetProvider.kt
index 9bff91d95..923b83bad 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/widget/AddTaskWidgetProvider.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/widget/AddTaskWidgetProvider.kt
@@ -61,7 +61,7 @@ class AddTaskWidgetProvider : BaseWidgetProvider() {
}
private fun getSelectedTaskType(widgetId: Int): TaskType {
- val preferences = PreferenceManager.getDefaultSharedPreferences(this.context)
- return TaskType.from(preferences.getString("add_task_widget_$widgetId", TaskType.HABIT.value)) ?: TaskType.HABIT
+ val preferences = context?.let { PreferenceManager.getDefaultSharedPreferences(it) }
+ return TaskType.from(preferences?.getString("add_task_widget_$widgetId", TaskType.HABIT.value)) ?: TaskType.HABIT
}
}
diff --git a/Habitica/src/test/java/com/habitrpg/android/habitica/models/user/SpecialItemsTest.kt b/Habitica/src/test/java/com/habitrpg/android/habitica/models/user/SpecialItemsTest.kt
deleted file mode 100644
index b459b4afd..000000000
--- a/Habitica/src/test/java/com/habitrpg/android/habitica/models/user/SpecialItemsTest.kt
+++ /dev/null
@@ -1,37 +0,0 @@
-package com.habitrpg.android.habitica.models.user
-
-import io.kotest.common.ExperimentalKotest
-import io.kotest.core.spec.style.WordSpec
-import io.kotest.datatest.withData
-import io.kotest.matchers.shouldBe
-
-@ExperimentalKotest
-class SpecialItemsTest : WordSpec({
- data class SpecialItemsData(val snowBalls: Int, val seafoam: Int, val shinyseed: Int, val spookySparkles: Int)
- lateinit var items: SpecialItems
- beforeEach {
- items = SpecialItems()
- }
- "hasSpecialItems" should {
- "false if none are owned" {
- items.hasSpecialItems shouldBe false
- }
- "true if any are owned" {
- items.snowball = 4
- items.hasSpecialItems shouldBe true
- }
- withData(
- SpecialItemsData(1, 0, 0, 0),
- SpecialItemsData(0, 1, 0, 0),
- SpecialItemsData(0, 0, 1, 0),
- SpecialItemsData(0, 0, 0, 1),
- SpecialItemsData(1, 3, 4, 8)
- ) { (snowballs, seafoam, shinyseeds, spookySparkles) ->
- items.snowball = snowballs
- items.seafoam = seafoam
- items.shinySeed = shinyseeds
- items.spookySparkles = spookySparkles
- items.hasSpecialItems shouldBe true
- }
- }
-})