diff --git a/Habitica/res/layout/dialog_purchase_customization.xml b/Habitica/res/layout/dialog_purchase_customization.xml
index 26adb2384..c9c1ef4e0 100644
--- a/Habitica/res/layout/dialog_purchase_customization.xml
+++ b/Habitica/res/layout/dialog_purchase_customization.xml
@@ -1,44 +1,27 @@
-
+
-
-
-
-
-
-
-
-
-
\ No newline at end of file
+ android:layout_height="wrap_content"
+ style="@style/Headline"
+ android:textColor="@color/text_primary"
+ tools:text="This is the Title"
+ android:gravity="center"
+ android:layout_marginTop="14dp"
+ android:layout_marginBottom="4dp"/>
+
\ No newline at end of file
diff --git a/Habitica/res/layout/purchase_dialog_background.xml b/Habitica/res/layout/purchase_dialog_background.xml
new file mode 100644
index 000000000..987007542
--- /dev/null
+++ b/Habitica/res/layout/purchase_dialog_background.xml
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Habitica/res/values-zh-rTW/strings.xml b/Habitica/res/values-zh-rTW/strings.xml
index 3a1c7dfbb..4c40fcd08 100644
--- a/Habitica/res/values-zh-rTW/strings.xml
+++ b/Habitica/res/values-zh-rTW/strings.xml
@@ -1044,7 +1044,7 @@
取消裝備
你已經有得到所有%s寵物所需的一切物品。你確定你要買%2$d個%3$s?
買%d個
- 你只需要%d個%2$s即可孵化所有可得到的這種寵物。你確定你想要買%1$d個?
+ 你只需要%3$d個%2$s即可孵化所有可得到的這種寵物。你確定你想要買%1$d個?
完成任務有概率掉落寵物食品!這樣你就可以把寵物餵大長成坐騎啦!
多餘物品
你完成了新手任務!
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/UserRepository.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/data/UserRepository.kt
index 6a2101bfa..7f8be410a 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/UserRepository.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/UserRepository.kt
@@ -51,6 +51,7 @@ interface UserRepository : BaseRepository {
fun changeClass(selectedClass: String): Flowable
+ fun unlockPath(user: User?, unlockPath: String?, type: String?, price: Int): Flowable
fun unlockPath(user: User?, customization: Customization): Flowable
fun unlockPath(set: CustomizationSet): Flowable
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/UserRepositoryImpl.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/UserRepositoryImpl.kt
index f60500c31..7236c7e0e 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/UserRepositoryImpl.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/UserRepositoryImpl.kt
@@ -162,9 +162,9 @@ class UserRepositoryImpl(
override fun changeClass(selectedClass: String): Flowable = apiClient.changeClass(selectedClass)
.flatMap { retrieveUser(false) }
- override fun unlockPath(user: User?, customization: Customization): Flowable {
- var path = customization.path
- if (path.last() == '.' && customization.type == "background") {
+ override fun unlockPath(user: User?, unlockPath: String?, type: String?, price: Int): Flowable {
+ var path = unlockPath ?: return Flowable.empty()
+ if (path.last() == '.' && type == "background") {
path += user?.preferences?.background
}
return zipWithLiveUser(apiClient.unlockPath(path)) { unlockResponse, copiedUser ->
@@ -172,12 +172,16 @@ class UserRepositoryImpl(
user.preferences = unlockResponse.preferences
user.purchased = unlockResponse.purchased
user.items = unlockResponse.items
- user.balance = copiedUser.balance - (customization.price ?: 0) / 4.0
+ user.balance = copiedUser.balance - (price / 4.0)
localRepository.saveUser(copiedUser, false)
unlockResponse
}
}
+ override fun unlockPath(user: User?, customization: Customization): Flowable {
+ return unlockPath(user, customization.path, customization.type, customization.price ?: 0)
+ }
+
override fun unlockPath(set: CustomizationSet): Flowable {
var path = ""
for (customization in set.customizations) {
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/models/shops/ShopItem.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/models/shops/ShopItem.kt
index 1cca5db5c..200044c00 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/models/shops/ShopItem.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/models/shops/ShopItem.kt
@@ -5,6 +5,7 @@ import android.content.res.Resources
import com.google.gson.annotations.SerializedName
import com.habitrpg.android.habitica.R
import com.habitrpg.android.habitica.models.BaseObject
+import com.habitrpg.android.habitica.models.inventory.Customization
import com.habitrpg.android.habitica.models.inventory.ItemEvent
import com.habitrpg.android.habitica.models.user.User
import io.realm.RealmObject
@@ -150,5 +151,18 @@ open class ShopItem : RealmObject(), BaseObject {
item.purchaseType = "fortify"
return item
}
+
+ fun fromCustomization(customization: Customization, userSize: String?, hairColor: String?): ShopItem {
+ val item = ShopItem()
+ item.key = customization.identifier ?: ""
+ item.text = customization.text
+ item.currency = "gems"
+ item.notes = customization.notes
+ item.value = customization.price ?: 0
+ item.path = customization.path
+ item.purchaseType = if (customization.type == "background") "background" else "customization"
+ item.imageName = customization.getImageName(userSize, hairColor)
+ return item
+ }
}
}
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/CustomizationRecyclerViewAdapter.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/CustomizationRecyclerViewAdapter.kt
index a12e2f7a3..cca9f40b7 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/CustomizationRecyclerViewAdapter.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/CustomizationRecyclerViewAdapter.kt
@@ -4,12 +4,12 @@ import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
-import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.TextView
import androidx.core.content.ContextCompat
import androidx.core.os.bundleOf
import coil.load
+import com.habitrpg.android.habitica.HabiticaBaseApplication
import com.habitrpg.android.habitica.R
import com.habitrpg.android.habitica.databinding.CustomizationGridItemBinding
import com.habitrpg.android.habitica.databinding.CustomizationSectionFooterBinding
@@ -17,9 +17,10 @@ import com.habitrpg.android.habitica.databinding.CustomizationSectionHeaderBindi
import com.habitrpg.android.habitica.helpers.MainNavigationController
import com.habitrpg.android.habitica.models.inventory.Customization
import com.habitrpg.android.habitica.models.inventory.CustomizationSet
+import com.habitrpg.android.habitica.models.shops.ShopItem
import com.habitrpg.android.habitica.ui.helpers.DataBindingUtils
-import com.habitrpg.android.habitica.ui.views.HabiticaIconsHelper
import com.habitrpg.android.habitica.ui.views.dialogs.HabiticaAlertDialog
+import com.habitrpg.android.habitica.ui.views.shops.PurchaseDialog
import io.reactivex.rxjava3.core.BackpressureStrategy
import io.reactivex.rxjava3.core.Flowable
import io.reactivex.rxjava3.subjects.PublishSubject
@@ -198,31 +199,10 @@ class CustomizationRecyclerViewAdapter() : androidx.recyclerview.widget.Recycler
dialog.addButton(R.string.reward_dialog_dismiss, false)
dialog.show()
} else {
- val dialogContent = LayoutInflater.from(itemView.context).inflate(R.layout.dialog_purchase_customization, null) as LinearLayout
-
- val imageView = dialogContent.findViewById(R.id.imageView)
- DataBindingUtils.loadImage(imageView, customization?.getImageName(userSize, hairColor))
-
- val priceLabel = dialogContent.findViewById(R.id.priceLabel)
- priceLabel.text = customization?.price.toString()
-
- (dialogContent.findViewById(R.id.gem_icon) as? ImageView)?.setImageBitmap(HabiticaIconsHelper.imageOfGem())
-
- val dialog = HabiticaAlertDialog(itemView.context)
- dialog.addButton(R.string.purchase_button, true) { _, _ ->
- if (customization?.price ?: 0 > gemBalance) {
- MainNavigationController.navigate(R.id.gemPurchaseActivity, bundleOf(Pair("openSubscription", false)))
- return@addButton
- }
-
- customization?.let {
- unlockCustomizationEvents.onNext(it)
- }
+ customization?.let {
+ val dialog = PurchaseDialog(itemView.context, HabiticaBaseApplication.userComponent, ShopItem.fromCustomization(it, userSize, hairColor))
+ dialog.show()
}
- dialog.setTitle(R.string.purchase_customization)
- dialog.setAdditionalContentView(dialogContent)
- dialog.addButton(R.string.reward_dialog_dismiss, false)
- dialog.show()
}
return
}
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/dialogs/HabiticaAlertDialog.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/dialogs/HabiticaAlertDialog.kt
index d400f29a1..2de98b3fc 100644
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/dialogs/HabiticaAlertDialog.kt
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/dialogs/HabiticaAlertDialog.kt
@@ -47,7 +47,7 @@ open class HabiticaAlertDialog(context: Context) : AlertDialog(context, R.style.
internal var contentView: FrameLayout
private var scrollingSeparator: View
internal var scrollView: LockableScrollView
- private var buttonsWrapper: LinearLayout
+ protected var buttonsWrapper: LinearLayout
private var noticeTextView: TextView
private var closeButton: Button
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 be0f8ae14..cf52fd1ba 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
@@ -27,7 +27,6 @@ import com.habitrpg.android.habitica.models.shops.Shop
import com.habitrpg.android.habitica.models.shops.ShopItem
import com.habitrpg.android.habitica.models.user.OwnedItem
import com.habitrpg.android.habitica.models.user.User
-import com.habitrpg.android.habitica.ui.activities.ArmoireActivityArgs
import com.habitrpg.android.habitica.ui.activities.ArmoireActivityDirections
import com.habitrpg.android.habitica.ui.views.CurrencyView
import com.habitrpg.android.habitica.ui.views.CurrencyViews
@@ -42,16 +41,16 @@ import com.habitrpg.android.habitica.ui.views.tasks.form.StepperValueFormView
import io.reactivex.rxjava3.core.Flowable
import io.reactivex.rxjava3.core.Maybe
import io.reactivex.rxjava3.disposables.CompositeDisposable
-import java.util.*
-import javax.inject.Inject
-import kotlin.math.max
-import kotlin.time.Duration
-import kotlin.time.ExperimentalTime
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
+import java.util.Date
+import javax.inject.Inject
+import kotlin.math.max
+import kotlin.time.DurationUnit
+import kotlin.time.toDuration
class PurchaseDialog(context: Context, component: UserComponent?, val item: ShopItem) : HabiticaAlertDialog(context) {
@@ -106,6 +105,8 @@ class PurchaseDialog(context: Context, component: UserComponent?, val item: Shop
checkGearClass()
}
"gems" == shopItem.purchaseType -> contentView = PurchaseDialogGemsContent(context)
+ "background" == shopItem.purchaseType -> contentView = PurchaseDialogBackgroundContent(context)
+ "customization" == shopItem.purchaseType -> contentView = PurchaseDialogCustomizationContent(context)
else -> contentView = PurchaseDialogBaseContent(context)
}
@@ -168,7 +169,6 @@ class PurchaseDialog(context: Context, component: UserComponent?, val item: Shop
private var limitedTextViewJob: Job? = null
- @OptIn(ExperimentalTime::class)
private fun setLimitedTextView() {
if (user == null) return
if (shopItem.habitClass != null && shopItem.habitClass != "special" && shopItem.habitClass != "armoire" && user?.stats?.habitClass != shopItem.habitClass) {
@@ -182,7 +182,7 @@ class PurchaseDialog(context: Context, component: UserComponent?, val item: Shop
while (shopItem.event?.end?.after(Date()) == true) {
limitedTextView.text = context.getString(R.string.available_for, shopItem.event?.end?.getShortRemainingString())
val diff = (shopItem.event?.end?.time ?: 0) - Date().time
- delay(if (diff < (60 * 60 * 1000)) Duration.seconds(1) else Duration.minutes(1))
+ delay(1.toDuration(if (diff < (60 * 60 * 1000)) DurationUnit.SECONDS else DurationUnit.MINUTES))
}
if (shopItem.event?.end?.before(Date()) == true) {
limitedTextView.text = context.getString(R.string.no_longer_available)
@@ -239,10 +239,11 @@ class PurchaseDialog(context: Context, component: UserComponent?, val item: Shop
pinTextView = customHeader.findViewById(R.id.pin_text)
addCloseButton()
- buyButton = addButton(layoutInflater.inflate(R.layout.dialog_purchase_shopitem_button, null), autoDismiss = false) { _, _ ->
+ buyButton = addButton(layoutInflater.inflate(R.layout.dialog_purchase_shopitem_button, buttonsWrapper, false), autoDismiss = false) { _, _ ->
onBuyButtonClicked()
}
priceLabel = buyButton.findViewById(R.id.priceLabel)
+ priceLabel.animationDuration = 0L
buyLabel = buyButton.findViewById(R.id.buy_label)
pinButton.setOnClickListener { inventoryRepository.togglePinnedItem(shopItem).subscribe({ isPinned = !this.isPinned }, RxErrorHandler.handleEmptyError()) }
@@ -353,6 +354,12 @@ class PurchaseDialog(context: Context, component: UserComponent?, val item: Shop
observable = inventoryRepository.purchaseQuest(shopItem.key).cast(Any::class.java)
} else if (shopItem.purchaseType == "debuffPotion") {
observable = userRepository.useSkill(shopItem.key, null).cast(Any::class.java)
+ } else if (shopItem.purchaseType == "customization" || shopItem.purchaseType == "background") {
+ observable = userRepository.unlockPath(user, item.path, item.purchaseType,
+ item.value
+ ).cast(Any::class.java)
+ } else if (shopItem.purchaseType == "debuffPotion") {
+ observable = userRepository.useSkill(shopItem.key, null).cast(Any::class.java)
} else if (shopItem.purchaseType == "card") {
purchaseCardAction?.invoke(shopItem)
dismiss()
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/shops/PurchaseDialogBackgroundContent.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/shops/PurchaseDialogBackgroundContent.kt
new file mode 100644
index 000000000..22346a7cc
--- /dev/null
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/shops/PurchaseDialogBackgroundContent.kt
@@ -0,0 +1,21 @@
+package com.habitrpg.android.habitica.ui.views.shops
+
+import android.content.Context
+import android.widget.ImageView
+import android.widget.TextView
+import com.habitrpg.android.habitica.databinding.PurchaseDialogBackgroundBinding
+import com.habitrpg.android.habitica.extensions.layoutInflater
+import com.habitrpg.android.habitica.models.shops.ShopItem
+
+class PurchaseDialogBackgroundContent(context: Context) : PurchaseDialogContent(context) {
+ val binding = PurchaseDialogBackgroundBinding.inflate(context.layoutInflater, this)
+ override val imageView: ImageView
+ get() = binding.imageView
+ override val titleTextView: TextView
+ get() = binding.titleTextView
+
+ override fun setItem(item: ShopItem) {
+ super.setItem(item)
+ binding.notesTextView.text = item.notes
+ }
+}
\ No newline at end of file
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/shops/PurchaseDialogCustomizationContent.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/shops/PurchaseDialogCustomizationContent.kt
new file mode 100644
index 000000000..4b761f067
--- /dev/null
+++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/shops/PurchaseDialogCustomizationContent.kt
@@ -0,0 +1,15 @@
+package com.habitrpg.android.habitica.ui.views.shops
+
+import android.content.Context
+import android.widget.ImageView
+import android.widget.TextView
+import com.habitrpg.android.habitica.databinding.DialogPurchaseCustomizationBinding
+import com.habitrpg.android.habitica.extensions.layoutInflater
+
+class PurchaseDialogCustomizationContent(context: Context) : PurchaseDialogContent(context) {
+ val binding = DialogPurchaseCustomizationBinding.inflate(context.layoutInflater, this)
+ override val imageView: ImageView
+ get() = binding.imageView
+ override val titleTextView: TextView
+ get() = binding.titleTextView
+}
\ No newline at end of file