diff --git a/Habitica/build.gradle b/Habitica/build.gradle
index c95fb8330..7e4fcc874 100644
--- a/Habitica/build.gradle
+++ b/Habitica/build.gradle
@@ -150,7 +150,7 @@ android {
buildConfigField "String", "TESTING_LEVEL", "\"production\""
resConfigs "en", "bg", "de", "en-rGB", "es", "fr", "hr-rHR", "in", "it", "iw", "ja", "ko", "lt", "nl", "pl", "pt-rBR", "pt-rPT", "ru", "tr", "zh", "zh-rTW"
- versionCode 2614
+ versionCode 2620
versionName "3.1"
}
diff --git a/Habitica/res/layout/fragment_inbox_message_list.xml b/Habitica/res/layout/fragment_inbox_message_list.xml
index 0963d3685..8ae0ae3f6 100644
--- a/Habitica/res/layout/fragment_inbox_message_list.xml
+++ b/Habitica/res/layout/fragment_inbox_message_list.xml
@@ -6,7 +6,8 @@
+ android:layout_height="0dp"
+ android:layout_weight="1"/>
Abort Quest
Version %1$s (%2$d)
- Help & FAQ
+ Support
Got it!
Remind me again
Welcome to
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/InventoryRepositoryImpl.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/InventoryRepositoryImpl.kt
index 5345935a5..5febec2fd 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/InventoryRepositoryImpl.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/InventoryRepositoryImpl.kt
@@ -137,7 +137,7 @@ class InventoryRepositoryImpl(localRepository: InventoryLocalRepository, apiClie
localRepository.executeTransaction {
val liveItem = localRepository.getLiveObject(ownedItem)
val liveUser = localRepository.getLiveObject(user)
- liveItem?.numberOwned = 1 + (liveItem?.numberOwned ?: 0)
+ liveItem?.numberOwned = 1 - (liveItem?.numberOwned ?: 0)
liveUser?.stats?.gp = (user.stats?.gp ?: 0.0) + item.value
}
}
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 4a7806ff6..15d3a34ea 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
@@ -205,8 +205,9 @@ class RealmInventoryLocalRepository(realm: Realm) : RealmContentLocalRepository(
}
override fun changeOwnedCount(item: OwnedItem, amountToAdd: Int?) {
+ val liveItem = getLiveObject(item) ?: return
amountToAdd?.let { amount ->
- executeTransaction { item.numberOwned = item.numberOwned + amount }
+ executeTransaction { liveItem.numberOwned = liveItem.numberOwned + amount }
}
}
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 2c255e75c..901d35291 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
@@ -173,10 +173,17 @@ class RealmSocialLocalRepository(realm: Realm) : RealmBaseLocalRepository(realm)
if (chatMessage.userLikesMessage(userId) == liked) {
return
}
+ val liveMessage = getLiveObject(chatMessage)
if (liked) {
- executeTransaction { chatMessage.likes?.add(ChatMessageLike(userId, chatMessage.id)) }
+ executeTransaction {
+ liveMessage?.likes?.add(ChatMessageLike(userId, chatMessage.id))
+ }
} else {
- chatMessage.likes?.filter { userId == it.id }?.forEach { like -> executeTransaction { like.deleteFromRealm() } }
+ liveMessage?.likes?.filter { userId == it.id }?.forEach { like ->
+ executeTransaction(Realm.Transaction {
+ like.deleteFromRealm()
+ })
+ }
}
}
@@ -212,8 +219,10 @@ class RealmSocialLocalRepository(realm: Realm) : RealmBaseLocalRepository(realm)
}
override fun setQuestActivity(party: Group?, active: Boolean) {
+ if (party == null) return
+ val liveParty = getLiveObject(party)
executeTransaction {
- party?.quest?.active = active
+ liveParty?.quest?.active = active
}
}
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/models/social/ChatMessage.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/models/social/ChatMessage.kt
index d78a224a3..fa2108aec 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/models/social/ChatMessage.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/models/social/ChatMessage.kt
@@ -1,13 +1,23 @@
package com.habitrpg.android.habitica.models.social
+import android.renderscript.BaseObj
+import com.habitrpg.android.habitica.models.BaseObject
import com.habitrpg.android.habitica.models.user.Backer
import com.habitrpg.android.habitica.models.user.ContributorInfo
+import com.habitrpg.android.habitica.models.user.User
import io.realm.RealmList
import io.realm.RealmObject
import io.realm.annotations.Ignore
import io.realm.annotations.PrimaryKey
-open class ChatMessage : RealmObject() {
+open class ChatMessage : RealmObject(), BaseObject {
+
+ override val realmClass: Class
+ get() = ChatMessage::class.java
+ override val primaryIdentifier: String?
+ get() = id
+ override val primaryIdentifierName: String
+ get() = "id"
@PrimaryKey
var id: String = ""
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/models/social/Group.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/models/social/Group.kt
index a885d956f..4d1ed7ab0 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/models/social/Group.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/models/social/Group.kt
@@ -1,6 +1,7 @@
package com.habitrpg.android.habitica.models.social
import com.google.gson.annotations.SerializedName
+import com.habitrpg.android.habitica.models.BaseObject
import com.habitrpg.android.habitica.models.inventory.Quest
import com.habitrpg.android.habitica.models.user.User
@@ -8,7 +9,14 @@ import io.realm.RealmList
import io.realm.RealmObject
import io.realm.annotations.PrimaryKey
-open class Group : RealmObject() {
+open class Group : RealmObject(), BaseObject {
+
+ override val realmClass: Class
+ get() = Group::class.java
+ override val primaryIdentifier: String?
+ get() = id
+ override val primaryIdentifierName: String
+ get() = "id"
@SerializedName("_id")
@PrimaryKey
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/BaseActivity.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/BaseActivity.kt
index 98931c0b6..5076d00a9 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/BaseActivity.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/activities/BaseActivity.kt
@@ -7,6 +7,7 @@ import android.content.res.Resources
import android.os.Bundle
import android.view.LayoutInflater
import android.view.Menu
+import android.view.MenuItem
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.app.AppCompatDelegate
@@ -102,6 +103,16 @@ abstract class BaseActivity : AppCompatActivity() {
super.onStop()
}
+ override fun onOptionsItemSelected(item: MenuItem): Boolean {
+ when (item.itemId) {
+ android.R.id.home -> {
+ onBackPressed()
+ return true
+ }
+ }
+ return super.onOptionsItemSelected(item)
+ }
+
internal open fun loadTheme(sharedPreferences: SharedPreferences, forced: Boolean = false) {
val theme = forcedTheme ?: sharedPreferences.getString("theme_name", "purple")
val modernHeaderStyle = overrideModernHeader ?: sharedPreferences.getBoolean("modern_header_style", true)
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 cf9e4b60d..abad4e8f8 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
@@ -238,10 +238,6 @@ class TaskFormActivity : BaseActivity() {
when (item.itemId) {
R.id.action_save -> saveTask()
R.id.action_delete -> deleteTask()
- android.R.id.home -> {
- onBackPressed()
- return true
- }
}
return super.onOptionsItemSelected(item)
}
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/NavigationDrawerAdapter.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/NavigationDrawerAdapter.kt
index 6dfd8443e..ac6ed066f 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/NavigationDrawerAdapter.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/NavigationDrawerAdapter.kt
@@ -158,7 +158,7 @@ class NavigationDrawerAdapter(tintColor: Int, backgroundTintColor: Int): Recycle
titleTextView?.text = drawerItem.text
if (isSelected) {
- itemView.setBackgroundColor(ContextCompat.getColor(itemView.context, R.color.offset_background))
+ itemView.setBackgroundColor(ContextCompat.getColor(itemView.context, R.color.content_background_offset))
itemView.background.alpha = 69
titleTextView?.setTextColor(tintColor)
} else {
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 df8d737b5..b7d76edba 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
@@ -31,7 +31,7 @@ class PetDetailRecyclerAdapter : androidx.recyclerview.widget.RecyclerView.Adapt
return equipEvents.toFlowable(BackpressureStrategy.DROP)
}
- var animalIngredientsRetriever: ((Animal) -> Pair)? = null
+ var animalIngredientsRetriever: ((Animal, ((Pair) -> Unit)) -> Unit)? = null
private fun canRaiseToMount(pet: Pet): Boolean {
for (mount in existingMounts ?: emptyList()) {
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 df8c38c3e..c3685c80a 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
@@ -27,7 +27,7 @@ class StableRecyclerAdapter : RecyclerView.Adapter() {
var shopSpriteSuffix: String? = null
private var eggs: Map = mapOf()
- var animalIngredientsRetriever: ((Animal) -> Pair)? = null
+ var animalIngredientsRetriever: ((Animal, ((Pair) -> Unit)) -> Unit)? = null
var itemType: String? = null
private val equipEvents = PublishSubject.create()
var ownedEggs: Map? = null
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 2677801f8..ed9f2bace 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
@@ -474,11 +474,7 @@ class NavigationDrawerFragment : DialogFragment() {
val bg = binding?.notificationsBadge?.background as? GradientDrawable
bg?.color = ColorStateList.valueOf(color)
- binding?.notificationsBadge?.setTextColor(if (allSeen) {
- ContextCompat.getColor(it, R.color.gray_10)
- } else {
- ContextCompat.getColor(it, R.color.white)
- })
+ binding?.notificationsBadge?.setTextColor(ContextCompat.getColor(it, R.color.white))
}
}
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 3e00ca58b..ca7b0abd3 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,8 @@ import com.habitrpg.android.habitica.ui.fragments.BaseMainFragment
import com.habitrpg.android.habitica.ui.fragments.inventory.items.ItemRecyclerFragment
import com.habitrpg.android.habitica.ui.helpers.MarginDecoration
import com.habitrpg.android.habitica.ui.helpers.SafeDefaultItemAnimator
+import io.reactivex.rxjava3.core.Flowable
+import io.reactivex.rxjava3.core.Maybe
import io.reactivex.rxjava3.kotlin.Flowables
import org.greenrobot.eventbus.Subscribe
import javax.inject.Inject
@@ -86,10 +88,15 @@ class PetDetailRecyclerFragment : BaseMainFragment(
}
binding?.recyclerView?.layoutManager = layoutManager
binding?.recyclerView?.addItemDecoration(MarginDecoration(getActivity()))
- adapter.animalIngredientsRetriever = {
- val egg = inventoryRepository.getItems(Egg::class.java, arrayOf(it.animal)).firstElement().blockingGet().firstOrNull()
- val potion = inventoryRepository.getItems(HatchingPotion::class.java, arrayOf(it.color)).firstElement().blockingGet().firstOrNull()
- Pair(egg as? Egg, potion as? HatchingPotion)
+ adapter.animalIngredientsRetriever = { animal, callback ->
+ Maybe.zip(
+ inventoryRepository.getItems(Egg::class.java, arrayOf(animal.animal)).firstElement(),
+ inventoryRepository.getItems(HatchingPotion::class.java, arrayOf(animal.color)).firstElement(), { eggs, potions ->
+ Pair(eggs.first() as? Egg, potions.first() as? HatchingPotion)
+ }
+ ).subscribe({
+ callback(it)
+ }, RxErrorHandler.handleEmptyError())
}
binding?.recyclerView?.adapter = adapter
binding?.recyclerView?.itemAnimator = SafeDefaultItemAnimator()
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 5b2fecdab..abebebd38 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
@@ -86,10 +86,15 @@ class StableRecyclerFragment : BaseFragment() {
adapter = binding?.recyclerView?.adapter as? StableRecyclerAdapter
if (adapter == null) {
adapter = StableRecyclerAdapter()
- adapter?.animalIngredientsRetriever = {
- val egg = inventoryRepository.getItems(Egg::class.java, arrayOf(it.animal)).firstElement().blockingGet().firstOrNull()
- val potion = inventoryRepository.getItems(HatchingPotion::class.java, arrayOf(it.color)).firstElement().blockingGet().firstOrNull()
- Pair(egg as? Egg, potion as? HatchingPotion)
+ adapter?.animalIngredientsRetriever = { animal, callback ->
+ Maybe.zip(
+ inventoryRepository.getItems(Egg::class.java, arrayOf(animal.animal)).firstElement(),
+ inventoryRepository.getItems(HatchingPotion::class.java, arrayOf(animal.color)).firstElement(), { eggs, potions ->
+ Pair(eggs.first() as? Egg, potions.first() as? HatchingPotion)
+ }
+ ).subscribe({
+ callback(it)
+ }, RxErrorHandler.handleEmptyError())
}
adapter?.itemType = this.itemType
adapter?.shopSpriteSuffix = configManager.shopSpriteSuffix()
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 bb6e8a3c3..c7c9962b6 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
@@ -78,9 +78,17 @@ class SkillsFragment : BaseMainFragment() {
adapter?.level = this.user?.stats?.lvl ?: 0
adapter?.specialItems = this.user?.items?.special
user?.let { user ->
- Observable.concat(userRepository.getSkills(user).toObservable().flatMap { Observable.fromIterable(it) },
- userRepository.getSpecialItems(user).toObservable().flatMap { Observable.fromIterable(it) })
- .toList()
+ Flowable.combineLatest(userRepository.getSkills(user),
+ userRepository.getSpecialItems(user), { skills, items ->
+ val allEntries = mutableListOf()
+ for (skill in skills) {
+ allEntries.add(skill)
+ }
+ for (item in items) {
+ allEntries.add(item)
+ }
+ return@combineLatest allEntries
+ })
.subscribe({ skills -> adapter?.setSkillList(skills) }, RxErrorHandler.handleEmptyError())
}
}
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 cc5af4362..78fd96507 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
@@ -77,7 +77,13 @@ class InboxMessageListFragment : BaseMainFragment
+ val observable = if (replyToUserUUID?.isNotBlank() == true) {
+ apiClient.getMember(replyToUserUUID!!)
+ } else {
+ apiClient.getMemberWithUsername(chatRoomUser ?: "")
+ }
+ compositeSubscription.add(observable.subscribe( { member ->
+ setReceivingUser(member.username, member.id)
chatAdapter = InboxAdapter(user, member)
viewModel?.messages?.observe(this.viewLifecycleOwner, { chatAdapter?.submitList(it) })
@@ -193,7 +199,7 @@ class InboxMessageListFragment : BaseMainFragment, private val animalIngredientsRetriever: ((Animal) -> Pair)?) : androidx.recyclerview.widget.RecyclerView.ViewHolder(parent.inflate(R.layout.pet_detail_item)), View.OnClickListener {
+class PetViewHolder(parent: ViewGroup, private val equipEvents: PublishSubject, private val animalIngredientsRetriever: ((Animal, ((Pair) -> Unit)) -> Unit)?) : androidx.recyclerview.widget.RecyclerView.ViewHolder(parent.inflate(R.layout.pet_detail_item)), View.OnClickListener {
private var hasMount: Boolean = false
private var hasUnlockedPotion: Boolean = false
private var hasUnlockedEgg: Boolean = false
@@ -147,16 +147,17 @@ class PetViewHolder(parent: ViewGroup, private val equipEvents: PublishSubject
+ dialog.configure(it,
+ ingredients.first,
+ ingredients.second,
+ eggCount,
+ potionCount,
+ hasUnlockedEgg,
+ hasUnlockedPotion,
+ hasMount)
+ dialog.show()
+ }
}
- dialog.show()
}
}
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewmodels/InboxViewModel.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewmodels/InboxViewModel.kt
index 3c769b8fd..cf94fb8c9 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewmodels/InboxViewModel.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/viewmodels/InboxViewModel.kt
@@ -118,10 +118,10 @@ private class MessagesDataSource(val socialRepository: SocialRepository, var rec
if (it.isEmpty()) {
if (recipientID?.isNotBlank() != true) { return@flatMapPublisher Flowable.just(it) }
socialRepository.retrieveInboxMessages(recipientID ?: "", 0)
- .doOnNext {
- messages -> if (messages.size < 10) {
- lastFetchWasEnd = true
- }
+ .doOnNext { messages ->
+ if (messages.size < 10) {
+ lastFetchWasEnd = true
+ }
}
} else {
Flowable.just(it)