mirror of
https://github.com/sudoxnym/habitica-android.git
synced 2026-04-14 19:56:32 +00:00
Implement bulk buying gems
This commit is contained in:
parent
95c9590be4
commit
2ea68a1b58
20 changed files with 171 additions and 56 deletions
|
|
@ -155,7 +155,7 @@ android {
|
|||
multiDexEnabled true
|
||||
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 2390
|
||||
versionCode 2392
|
||||
versionName "2.5"
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,4 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="48dp" android:viewportHeight="24.0" android:viewportWidth="24.0" android:width="48dp">
|
||||
<path android:fillColor="#33878190" android:pathData="M7,14l5,-5 5,5z"/>
|
||||
</vector>
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:state_enabled="false" android:drawable="@drawable/ic_arrow_drop_up_gray_48dp_disabled" />
|
||||
<item android:drawable="@drawable/ic_arrow_drop_up_gray_48dp" />
|
||||
</selector>
|
||||
|
|
@ -83,7 +83,7 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:text="@string/cost"
|
||||
style="@style/TaskFormSectionheader"/>
|
||||
<com.habitrpg.android.habitica.ui.views.tasks.form.RewardValueFormView
|
||||
<com.habitrpg.android.habitica.ui.views.tasks.form.StepperValueFormView
|
||||
android:id="@+id/reward_value"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="56dp" />
|
||||
|
|
|
|||
45
Habitica/res/layout/dialog_purchase_gems.xml
Normal file
45
Habitica/res/layout/dialog_purchase_gems.xml
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<merge xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingLeft="@dimen/shopitem_dialog_content_inset"
|
||||
android:paddingRight="@dimen/shopitem_dialog_content_inset"
|
||||
android:gravity="center_horizontal"
|
||||
tools:parentTag="LinearLayout"
|
||||
tools:background="@color/white"
|
||||
tools:orientation="vertical">
|
||||
|
||||
<com.facebook.drawee.view.SimpleDraweeView
|
||||
android:id="@+id/imageView"
|
||||
android:layout_width="@dimen/shopitem_image_size"
|
||||
android:layout_height="@dimen/shopitem_image_size" />
|
||||
<TextView
|
||||
android:id="@+id/titleTextView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/Headline"
|
||||
tools:text="This is the Title"
|
||||
android:gravity="center"
|
||||
android:layout_marginTop="14dp"
|
||||
android:layout_marginBottom="4dp"/>
|
||||
<TextView
|
||||
android:id="@+id/notesTextView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/Body2"
|
||||
android:textColor="@color/black_50_alpha"
|
||||
tools:text="These are the notes"
|
||||
android:gravity="center"/>
|
||||
|
||||
<com.habitrpg.android.habitica.ui.views.tasks.form.StepperValueFormView
|
||||
android:id="@+id/stepper_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="56dp"
|
||||
android:layout_marginTop="@dimen/spacing_large"
|
||||
app:defaultValue="1"
|
||||
app:minValue="1"
|
||||
/>
|
||||
</merge>
|
||||
|
|
@ -20,7 +20,7 @@
|
|||
android:layout_width="56dp"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/gray_600"
|
||||
android:src="@drawable/ic_arrow_drop_up_gray_48dp"
|
||||
android:src="@drawable/ic_arrow_drop_up_gray_48dp_states"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_alignParentTop="true"
|
||||
/>
|
||||
|
|
@ -137,4 +137,10 @@
|
|||
<attr name="description" />
|
||||
<attr name="iconDrawable" />
|
||||
</declare-styleable>
|
||||
<declare-styleable name="StepperValueFormView">
|
||||
<attr name="defaultValue" />
|
||||
<attr name="iconDrawable" />
|
||||
<attr name="maxValue" format="integer" />
|
||||
<attr name="minValue" format="integer" />
|
||||
</declare-styleable>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -62,10 +62,10 @@ interface ApiService {
|
|||
fun equipItem(@Path("type") type: String, @Path("key") itemKey: String): Flowable<HabitResponse<Items>>
|
||||
|
||||
@POST("user/buy/{key}")
|
||||
fun buyItem(@Path("key") itemKey: String): Flowable<HabitResponse<BuyResponse>>
|
||||
fun buyItem(@Path("key") itemKey: String, @Body quantity: Map<String, Int>): Flowable<HabitResponse<BuyResponse>>
|
||||
|
||||
@POST("user/purchase/{type}/{key}")
|
||||
fun purchaseItem(@Path("type") type: String, @Path("key") itemKey: String): Flowable<HabitResponse<Void>>
|
||||
fun purchaseItem(@Path("type") type: String, @Path("key") itemKey: String, @Body quantity: Map<String, Int>): Flowable<HabitResponse<Void>>
|
||||
|
||||
@POST("user/purchase-hourglass/{type}/{key}")
|
||||
fun purchaseHourglassItem(@Path("type") type: String, @Path("key") itemKey: String): Flowable<HabitResponse<Void>>
|
||||
|
|
|
|||
|
|
@ -52,9 +52,9 @@ interface ApiClient {
|
|||
|
||||
fun equipItem(type: String, itemKey: String): Flowable<Items>
|
||||
|
||||
fun buyItem(itemKey: String): Flowable<BuyResponse>
|
||||
fun buyItem(itemKey: String, purchaseQuantity: Int): Flowable<BuyResponse>
|
||||
|
||||
fun purchaseItem(type: String, itemKey: String): Flowable<Any>
|
||||
fun purchaseItem(type: String, itemKey: String, purchaseQuantity: Int): Flowable<Any>
|
||||
|
||||
fun purchaseHourglassItem(type: String, itemKey: String): Flowable<Any>
|
||||
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ interface InventoryRepository : BaseRepository {
|
|||
|
||||
fun inviteToQuest(quest: QuestContent): Flowable<Quest>
|
||||
|
||||
fun buyItem(user: User?, id: String, value: Double): Flowable<BuyResponse>
|
||||
fun buyItem(user: User?, id: String, value: Double, purchaseQuantity: Int): Flowable<BuyResponse>
|
||||
|
||||
fun retrieveShopInventory(identifier: String): Flowable<Shop>
|
||||
fun retrieveMarketGear(): Flowable<Shop>
|
||||
|
|
@ -71,7 +71,7 @@ interface InventoryRepository : BaseRepository {
|
|||
|
||||
fun purchaseQuest(key: String): Flowable<Any>
|
||||
|
||||
fun purchaseItem(purchaseType: String, key: String): Flowable<Any>
|
||||
fun purchaseItem(purchaseType: String, key: String, purchaseQuantity: Int): Flowable<Any>
|
||||
|
||||
fun togglePinnedItem(item: ShopItem): Flowable<List<ShopItem>>
|
||||
fun getItems(itemClass: Class<out Item>, keys: Array<String>, user: User?): Flowable<out RealmResults<out Item>>
|
||||
|
|
|
|||
|
|
@ -321,12 +321,12 @@ class ApiClientImpl//private OnHabitsAPIResult mResultListener;
|
|||
return apiService.equipItem(type, itemKey).compose(configureApiCallObserver())
|
||||
}
|
||||
|
||||
override fun buyItem(itemKey: String): Flowable<BuyResponse> {
|
||||
return apiService.buyItem(itemKey).compose(configureApiCallObserver())
|
||||
override fun buyItem(itemKey: String, purchaseQuantity: Int): Flowable<BuyResponse> {
|
||||
return apiService.buyItem(itemKey, mapOf(Pair("quantity", purchaseQuantity))).compose(configureApiCallObserver())
|
||||
}
|
||||
|
||||
override fun purchaseItem(type: String, itemKey: String): Flowable<Any> {
|
||||
return apiService.purchaseItem(type, itemKey).compose(configureApiCallObserver())
|
||||
override fun purchaseItem(type: String, itemKey: String, purchaseQuantity: Int): Flowable<Any> {
|
||||
return apiService.purchaseItem(type, itemKey, mapOf(Pair("quantity", purchaseQuantity))).compose(configureApiCallObserver())
|
||||
}
|
||||
|
||||
override fun validateSubscription(request: SubscriptionValidationRequest): Flowable<Any> {
|
||||
|
|
|
|||
|
|
@ -228,8 +228,8 @@ class InventoryRepositoryImpl(localRepository: InventoryLocalRepository, apiClie
|
|||
.doOnNext { localRepository.changeOwnedCount("quests", quest.key, userID, -1) }
|
||||
}
|
||||
|
||||
override fun buyItem(user: User?, id: String, value: Double): Flowable<BuyResponse> {
|
||||
return apiClient.buyItem(id)
|
||||
override fun buyItem(user: User?, id: String, value: Double, purchaseQuantity: Int): Flowable<BuyResponse> {
|
||||
return apiClient.buyItem(id, purchaseQuantity)
|
||||
.doOnNext { buyResponse ->
|
||||
if (user == null) {
|
||||
return@doOnNext
|
||||
|
|
@ -251,7 +251,7 @@ class InventoryRepositoryImpl(localRepository: InventoryLocalRepository, apiClie
|
|||
if (buyResponse.gp != null) {
|
||||
copiedUser.stats?.gp = buyResponse.gp
|
||||
} else {
|
||||
copiedUser.stats?.gp = copiedUser.stats?.gp ?: 0 - value
|
||||
copiedUser.stats?.gp = copiedUser.stats?.gp ?: 0 - (value * purchaseQuantity)
|
||||
}
|
||||
if (buyResponse.lvl != null) {
|
||||
copiedUser.stats?.lvl = buyResponse.lvl
|
||||
|
|
@ -280,8 +280,8 @@ class InventoryRepositoryImpl(localRepository: InventoryLocalRepository, apiClie
|
|||
return apiClient.purchaseQuest(key)
|
||||
}
|
||||
|
||||
override fun purchaseItem(purchaseType: String, key: String): Flowable<Any> {
|
||||
return apiClient.purchaseItem(purchaseType, key)
|
||||
override fun purchaseItem(purchaseType: String, key: String, purchaseQuantity: Int): Flowable<Any> {
|
||||
return apiClient.purchaseItem(purchaseType, key, purchaseQuantity)
|
||||
}
|
||||
|
||||
override fun togglePinnedItem(item: ShopItem): Flowable<List<ShopItem>> {
|
||||
|
|
|
|||
|
|
@ -68,10 +68,10 @@ open class ShopItem : RealmObject() {
|
|||
val isTypeAnimal: Boolean
|
||||
get() = "pets" == purchaseType || "mounts" == purchaseType
|
||||
|
||||
fun canAfford(user: User?, canAlwaysAffordSpecial: Boolean): Boolean = when(currency) {
|
||||
"gold" -> value <= user?.stats?.gp ?: 0.0
|
||||
"gems" -> if (canAlwaysAffordSpecial) true else value <= user?.gemCount ?: 0
|
||||
"hourglasses" -> if (canAlwaysAffordSpecial) true else value <= user?.purchased?.plan?.consecutive?.trinkets ?: 0
|
||||
fun canAfford(user: User?, quantity: Int): Boolean = when(currency) {
|
||||
"gold" -> (value * quantity) <= user?.stats?.gp ?: 0.0
|
||||
"gems" -> true
|
||||
"hourglasses" -> true
|
||||
else -> false
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ class TaskFormActivity : BaseActivity() {
|
|||
private val statPerceptionButton: TextView by bindView(R.id.stat_perception_button)
|
||||
|
||||
private val rewardValueTitleView: TextView by bindView(R.id.reward_value_title)
|
||||
private val rewardValueFormView: RewardValueFormView by bindView(R.id.reward_value)
|
||||
private val stepperValueFormView: StepperValueFormView by bindView(R.id.reward_value)
|
||||
|
||||
private val tagsTitleView: TextView by bindView(R.id.tags_title)
|
||||
private val tagsWrapper: LinearLayout by bindView(R.id.tags_wrapper)
|
||||
|
|
@ -271,7 +271,7 @@ class TaskFormActivity : BaseActivity() {
|
|||
|
||||
val rewardViewsVisibility = if (taskType == Task.TYPE_REWARD) View.VISIBLE else View.GONE
|
||||
rewardValueTitleView.visibility = rewardViewsVisibility
|
||||
rewardValueFormView.visibility = rewardViewsVisibility
|
||||
stepperValueFormView.visibility = rewardViewsVisibility
|
||||
|
||||
tagsTitleView.visibility = if (isChallengeTask) View.GONE else View.VISIBLE
|
||||
tagsWrapper.visibility = if (isChallengeTask) View.GONE else View.VISIBLE
|
||||
|
|
@ -346,7 +346,7 @@ class TaskFormActivity : BaseActivity() {
|
|||
taskSchedulingControls.frequency = task.frequency ?: Task.FREQUENCY_DAILY
|
||||
}
|
||||
Task.TYPE_TODO -> taskSchedulingControls.dueDate = task.dueDate
|
||||
Task.TYPE_REWARD -> rewardValueFormView.value = task.value
|
||||
Task.TYPE_REWARD -> stepperValueFormView.value = task.value
|
||||
}
|
||||
if (taskType == Task.TYPE_DAILY || taskType == Task.TYPE_TODO) {
|
||||
task.checklist?.let { checklistContainer.checklistItems = it }
|
||||
|
|
@ -420,7 +420,7 @@ class TaskFormActivity : BaseActivity() {
|
|||
} else if (taskType == Task.TYPE_TODO) {
|
||||
thisTask.dueDate = taskSchedulingControls.dueDate
|
||||
} else if (taskType == Task.TYPE_REWARD) {
|
||||
thisTask.value = rewardValueFormView.value
|
||||
thisTask.value = stepperValueFormView.value
|
||||
}
|
||||
|
||||
val resultIntent = Intent()
|
||||
|
|
|
|||
|
|
@ -139,7 +139,7 @@ class ShopRecyclerAdapter(private val configManager: AppConfigManager) : android
|
|||
ShopItem::class.java -> {
|
||||
val item = obj as? ShopItem ?: return
|
||||
val itemHolder = holder as? ShopItemViewHolder ?: return
|
||||
itemHolder.bind(item, item.canAfford(user, configManager.insufficientGemPurchase()))
|
||||
itemHolder.bind(item, item.canAfford(user, 1))
|
||||
if (ownedItems.containsKey(item.key+"-"+item.pinType)) {
|
||||
itemHolder.itemCount = ownedItems[item.key+"-"+item.pinType]?.numberOwned ?: 0
|
||||
}
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ class RewardsRecyclerViewAdapter(private var customRewards: OrderedRealmCollecti
|
|||
} else if (inAppRewards != null) {
|
||||
val item = inAppRewards?.get(position - customRewardCount) ?: return
|
||||
if (holder is ShopItemViewHolder) {
|
||||
holder.bind(item, item.canAfford(user, configManager.insufficientGemPurchase()))
|
||||
holder.bind(item, item.canAfford(user, 1))
|
||||
holder.isPinned = true
|
||||
holder.hidePinIndicator()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ class ProfilePreferencesFragment: BasePreferencesFragment(), SharedPreferences.O
|
|||
val profileCategory = findPreference("profile") as? PreferenceCategory
|
||||
configurePreference(profileCategory?.findPreference(key), sharedPreferences?.getString(key, ""))
|
||||
if (sharedPreferences != null) {
|
||||
val newValue = sharedPreferences.getString(key, "") ?: ""
|
||||
val newValue = sharedPreferences.getString(key, "") ?: return
|
||||
val observable: Flowable<User>? = when (key) {
|
||||
"display_name" -> {
|
||||
if (newValue != user?.profile?.name) {
|
||||
|
|
@ -65,16 +65,14 @@ class ProfilePreferencesFragment: BasePreferencesFragment(), SharedPreferences.O
|
|||
}
|
||||
}
|
||||
"photo_url" -> {
|
||||
val newName = sharedPreferences.getString(key, "") ?: ""
|
||||
if (newName != user?.profile?.imageUrl) {
|
||||
if (newValue != user?.profile?.imageUrl) {
|
||||
userRepository.updateUser(user, "profile.imageUrl", newValue)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
"about" -> {
|
||||
val newName = sharedPreferences.getString(key, "") ?: ""
|
||||
if (newName != user?.profile?.blurb) {
|
||||
if (newValue != user?.profile?.blurb) {
|
||||
userRepository.updateUser(user, "profile.blurb", newValue)
|
||||
} else {
|
||||
null
|
||||
|
|
@ -85,5 +83,4 @@ class ProfilePreferencesFragment: BasePreferencesFragment(), SharedPreferences.O
|
|||
observable?.subscribe(Consumer {}, RxErrorHandler.handleEmptyError())?.let { compositeSubscription.add(it) }
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -60,6 +60,8 @@ class PurchaseDialog(context: Context, component: UserComponent?, val item: Shop
|
|||
private val buyLabel: TextView
|
||||
private val pinButton: Button by bindView(customHeader, R.id.pin_button)
|
||||
|
||||
private var purchaseQuantity = 1
|
||||
|
||||
var purchaseCardAction: ((ShopItem) -> Unit)? = null
|
||||
|
||||
private var shopItem: ShopItem = item
|
||||
|
|
@ -74,7 +76,7 @@ class PurchaseDialog(context: Context, component: UserComponent?, val item: Shop
|
|||
}
|
||||
|
||||
if (shopItem.lockedReason(context) == null) {
|
||||
priceLabel.value = shopItem.value.toDouble()
|
||||
updatePurchaseTotal()
|
||||
priceLabel.currency = shopItem.currency
|
||||
} else {
|
||||
limitedTextView.text = shopItem.lockedReason(context)
|
||||
|
|
@ -100,13 +102,34 @@ class PurchaseDialog(context: Context, component: UserComponent?, val item: Shop
|
|||
inventoryRepository.getEquipment(shopItem.key).firstElement().subscribe(Consumer<Equipment> { contentView.setEquipment(it) }, RxErrorHandler.handleEmptyError())
|
||||
checkGearClass()
|
||||
}
|
||||
"gems" == shopItem.purchaseType -> contentView = PurchaseDialogGemsContent(context)
|
||||
"gems" == shopItem.purchaseType -> {
|
||||
val gemContent = PurchaseDialogGemsContent(context)
|
||||
gemContent.stepperView.onValueChanged = {
|
||||
purchaseQuantity = it.toInt()
|
||||
updatePurchaseTotal()
|
||||
}
|
||||
contentView = gemContent
|
||||
}
|
||||
else -> contentView = PurchaseDialogBaseContent(context)
|
||||
}
|
||||
contentView.setItem(shopItem)
|
||||
setAdditionalContentView(contentView)
|
||||
}
|
||||
|
||||
fun updatePurchaseTotal() {
|
||||
priceLabel.value = shopItem.value.toDouble() * purchaseQuantity
|
||||
|
||||
if (shopItem.canAfford(user, purchaseQuantity) && !shopItem.locked) {
|
||||
buyButton.background = context.getDrawable(R.drawable.button_background_primary)
|
||||
priceLabel.setTextColor(ContextCompat.getColor(context, R.color.white))
|
||||
buyLabel.setTextColor(ContextCompat.getColor(context, R.color.white))
|
||||
} else {
|
||||
buyButton.background = context.getDrawable(R.drawable.button_background_gray_600)
|
||||
priceLabel.setTextColor(ContextCompat.getColor(context, R.color.gray_100))
|
||||
buyLabel.setTextColor(ContextCompat.getColor(context, R.color.gray_100))
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkGearClass() {
|
||||
val user = user ?: return
|
||||
|
||||
|
|
@ -183,15 +206,7 @@ class PurchaseDialog(context: Context, component: UserComponent?, val item: Shop
|
|||
}
|
||||
|
||||
buyButton.elevation = 0f
|
||||
if (shopItem.canAfford(user, configManager.insufficientGemPurchase()) && !shopItem.locked) {
|
||||
buyButton.background = context.getDrawable(R.drawable.button_background_primary)
|
||||
priceLabel.setTextColor(ContextCompat.getColor(context, R.color.white))
|
||||
buyLabel.setTextColor(ContextCompat.getColor(context, R.color.white))
|
||||
} else {
|
||||
buyButton.background = context.getDrawable(R.drawable.button_background_gray_600)
|
||||
priceLabel.setTextColor(ContextCompat.getColor(context, R.color.gray_100))
|
||||
buyLabel.setTextColor(ContextCompat.getColor(context, R.color.gray_100))
|
||||
}
|
||||
updatePurchaseTotal()
|
||||
|
||||
if (shopItem.isTypeGear) {
|
||||
checkGearClass()
|
||||
|
|
@ -211,7 +226,7 @@ class PurchaseDialog(context: Context, component: UserComponent?, val item: Shop
|
|||
val snackbarText = arrayOf("")
|
||||
if (shopItem.isValid && !shopItem.locked) {
|
||||
val gemsLeft = if (shopItem.limitedNumberLeft != null) shopItem.limitedNumberLeft else 0
|
||||
if ((gemsLeft == 0 && shopItem.purchaseType == "gems") || shopItem.canAfford(user, false)) {
|
||||
if ((gemsLeft == 0 && shopItem.purchaseType == "gems") || shopItem.canAfford(user, purchaseQuantity)) {
|
||||
val observable: Flowable<Any>
|
||||
if (shopIdentifier != null && shopIdentifier == Shop.TIME_TRAVELERS_SHOP || "mystery_set" == shopItem.purchaseType || shopItem.currency == "hourglasses") {
|
||||
observable = if (shopItem.purchaseType == "gear") {
|
||||
|
|
@ -226,7 +241,7 @@ class PurchaseDialog(context: Context, component: UserComponent?, val item: Shop
|
|||
dismiss()
|
||||
return
|
||||
} else if ("gold" == shopItem.currency && "gem" != shopItem.key) {
|
||||
observable = inventoryRepository.buyItem(user, shopItem.key, shopItem.value.toDouble()).map { buyResponse ->
|
||||
observable = inventoryRepository.buyItem(user, shopItem.key, shopItem.value.toDouble(), purchaseQuantity).map { buyResponse ->
|
||||
if (shopItem.key == "armoire") {
|
||||
snackbarText[0] = when {
|
||||
buyResponse.armoire["type"] == "gear" -> context.getString(R.string.armoireEquipment, buyResponse.armoire["dropText"])
|
||||
|
|
@ -237,7 +252,7 @@ class PurchaseDialog(context: Context, component: UserComponent?, val item: Shop
|
|||
buyResponse
|
||||
}
|
||||
} else {
|
||||
observable = inventoryRepository.purchaseItem(shopItem.purchaseType, shopItem.key)
|
||||
observable = inventoryRepository.purchaseItem(shopItem.purchaseType, shopItem.key, purchaseQuantity)
|
||||
}
|
||||
observable
|
||||
.doOnNext {
|
||||
|
|
|
|||
|
|
@ -3,20 +3,29 @@ package com.habitrpg.android.habitica.ui.views.shops
|
|||
import android.content.Context
|
||||
import android.widget.TextView
|
||||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.ui.helpers.bindView
|
||||
import com.habitrpg.android.habitica.extensions.asDrawable
|
||||
import com.habitrpg.android.habitica.models.shops.ShopItem
|
||||
import com.habitrpg.android.habitica.ui.helpers.bindView
|
||||
import com.habitrpg.android.habitica.ui.views.HabiticaIconsHelper
|
||||
import com.habitrpg.android.habitica.ui.views.tasks.form.StepperValueFormView
|
||||
|
||||
internal class PurchaseDialogGemsContent(context: Context) : PurchaseDialogContent(context) {
|
||||
|
||||
val notesTextView: TextView by bindView(R.id.notesTextView)
|
||||
val stepperView: StepperValueFormView by bindView(R.id.stepper_view)
|
||||
|
||||
override val viewId: Int
|
||||
get() = R.layout.dialog_purchase_content_item
|
||||
get() = R.layout.dialog_purchase_gems
|
||||
|
||||
init {
|
||||
stepperView.iconDrawable = HabiticaIconsHelper.imageOfGem().asDrawable(context.resources)
|
||||
}
|
||||
|
||||
override fun setItem(item: ShopItem) {
|
||||
super.setItem(item)
|
||||
|
||||
notesTextView.text = item.notes
|
||||
|
||||
stepperView.maxValue = item.limitedNumberLeft?.toDouble()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package com.habitrpg.android.habitica.ui.views.tasks.form
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.util.AttributeSet
|
||||
import android.widget.EditText
|
||||
import android.widget.ImageButton
|
||||
|
|
@ -13,7 +14,7 @@ import com.habitrpg.android.habitica.ui.helpers.bindView
|
|||
import com.habitrpg.android.habitica.ui.views.HabiticaIconsHelper
|
||||
import java.text.DecimalFormat
|
||||
|
||||
class RewardValueFormView @JvmOverloads constructor(
|
||||
class StepperValueFormView @JvmOverloads constructor(
|
||||
context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
|
||||
) : RelativeLayout(context, attrs, defStyleAttr) {
|
||||
|
||||
|
|
@ -21,20 +22,36 @@ class RewardValueFormView @JvmOverloads constructor(
|
|||
private val upButton: ImageButton by bindView(R.id.up_button)
|
||||
private val downButton: ImageButton by bindView(R.id.down_button)
|
||||
|
||||
var onValueChanged: ((Double) -> Unit)? = null
|
||||
|
||||
private val decimalFormat = DecimalFormat("0.###")
|
||||
private var editTextIsFocused = false
|
||||
|
||||
var value = 0.0
|
||||
set(value) {
|
||||
val newValue = if (value >= 0) value else 0.0
|
||||
var newValue = if (value >= minValue) value else minValue
|
||||
maxValue?.let {
|
||||
if (newValue > it) {
|
||||
newValue = it
|
||||
}
|
||||
}
|
||||
val oldValue = field
|
||||
field = newValue
|
||||
if (oldValue != newValue) {
|
||||
valueString = decimalFormat.format(newValue)
|
||||
}
|
||||
downButton.isEnabled = field > 0
|
||||
downButton.isEnabled = field > minValue
|
||||
maxValue?.let {
|
||||
if (it == 0.0) return@let
|
||||
upButton.isEnabled = value < it
|
||||
}
|
||||
|
||||
onValueChanged?.invoke(value)
|
||||
}
|
||||
|
||||
var maxValue: Double? = null
|
||||
var minValue: Double = 0.0
|
||||
|
||||
private var valueString = ""
|
||||
set(value) {
|
||||
field = value
|
||||
|
|
@ -51,11 +68,28 @@ class RewardValueFormView @JvmOverloads constructor(
|
|||
}
|
||||
}
|
||||
|
||||
var iconDrawable: Drawable?
|
||||
get() {
|
||||
return editText.compoundDrawables.firstOrNull()
|
||||
}
|
||||
set(value) {
|
||||
editText.setCompoundDrawablesWithIntrinsicBounds(value, null, null, null)
|
||||
}
|
||||
|
||||
init {
|
||||
inflate(R.layout.task_form_reward_value, true)
|
||||
inflate(R.layout.form_stepper_value, true)
|
||||
|
||||
val attributes = context.theme?.obtainStyledAttributes(
|
||||
attrs,
|
||||
R.styleable.StepperValueFormView,
|
||||
0, 0)
|
||||
|
||||
//set value here, so that the setter is called and everything is set up correctly
|
||||
value = 10.0
|
||||
editText.setCompoundDrawablesWithIntrinsicBounds(HabiticaIconsHelper.imageOfGold().asDrawable(context.resources), null, null, null)
|
||||
maxValue = attributes?.getFloat(R.styleable.StepperValueFormView_maxValue, 0f)?.toDouble()
|
||||
minValue = attributes?.getFloat(R.styleable.StepperValueFormView_minValue, 0f)?.toDouble() ?: 0.0
|
||||
value = attributes?.getFloat(R.styleable.StepperValueFormView_defaultValue, 10.0f)?.toDouble() ?: 10.0
|
||||
iconDrawable = attributes?.getDrawable(R.styleable.StepperValueFormView_iconDrawable) ?: HabiticaIconsHelper.imageOfGold().asDrawable(context.resources)
|
||||
|
||||
|
||||
upButton.setOnClickListener {
|
||||
value += 1
|
||||
Loading…
Reference in a new issue