From 2ea68a1b5842590957db3ad6306f27b1de3cbb97 Mon Sep 17 00:00:00 2001 From: Phillip Thelen Date: Thu, 2 Apr 2020 13:55:16 +0200 Subject: [PATCH] Implement bulk buying gems --- Habitica/build.gradle | 2 +- .../ic_arrow_drop_up_gray_48dp_disabled.xml | 4 ++ .../ic_arrow_drop_up_gray_48dp_states.xml | 5 ++ Habitica/res/layout/activity_task_form.xml | 2 +- Habitica/res/layout/dialog_purchase_gems.xml | 45 ++++++++++++++++++ ...eward_value.xml => form_stepper_value.xml} | 2 +- Habitica/res/values/attrs.xml | 6 +++ .../android/habitica/api/ApiService.kt | 4 +- .../android/habitica/data/ApiClient.kt | 4 +- .../habitica/data/InventoryRepository.kt | 4 +- .../data/implementation/ApiClientImpl.kt | 8 ++-- .../implementation/InventoryRepositoryImpl.kt | 10 ++-- .../android/habitica/models/shops/ShopItem.kt | 8 ++-- .../ui/activities/TaskFormActivity.kt | 8 ++-- .../adapter/inventory/ShopRecyclerAdapter.kt | 2 +- .../tasks/RewardsRecyclerViewAdapter.kt | 2 +- .../preferences/ProfilePreferencesFragment.kt | 9 ++-- .../habitica/ui/views/shops/PurchaseDialog.kt | 43 +++++++++++------ .../views/shops/PurchaseDialogGemsContent.kt | 13 +++++- ...lueFormView.kt => StepperValueFormView.kt} | 46 ++++++++++++++++--- 20 files changed, 171 insertions(+), 56 deletions(-) create mode 100644 Habitica/res/drawable/ic_arrow_drop_up_gray_48dp_disabled.xml create mode 100644 Habitica/res/drawable/ic_arrow_drop_up_gray_48dp_states.xml create mode 100644 Habitica/res/layout/dialog_purchase_gems.xml rename Habitica/res/layout/{task_form_reward_value.xml => form_stepper_value.xml} (96%) rename Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/tasks/form/{RewardValueFormView.kt => StepperValueFormView.kt} (58%) diff --git a/Habitica/build.gradle b/Habitica/build.gradle index 8631a26a5..cedf0c625 100644 --- a/Habitica/build.gradle +++ b/Habitica/build.gradle @@ -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" } diff --git a/Habitica/res/drawable/ic_arrow_drop_up_gray_48dp_disabled.xml b/Habitica/res/drawable/ic_arrow_drop_up_gray_48dp_disabled.xml new file mode 100644 index 000000000..0d441d1cc --- /dev/null +++ b/Habitica/res/drawable/ic_arrow_drop_up_gray_48dp_disabled.xml @@ -0,0 +1,4 @@ + + + + diff --git a/Habitica/res/drawable/ic_arrow_drop_up_gray_48dp_states.xml b/Habitica/res/drawable/ic_arrow_drop_up_gray_48dp_states.xml new file mode 100644 index 000000000..41b906774 --- /dev/null +++ b/Habitica/res/drawable/ic_arrow_drop_up_gray_48dp_states.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/Habitica/res/layout/activity_task_form.xml b/Habitica/res/layout/activity_task_form.xml index b377a792f..82f5f0b12 100644 --- a/Habitica/res/layout/activity_task_form.xml +++ b/Habitica/res/layout/activity_task_form.xml @@ -83,7 +83,7 @@ android:layout_height="wrap_content" android:text="@string/cost" style="@style/TaskFormSectionheader"/> - diff --git a/Habitica/res/layout/dialog_purchase_gems.xml b/Habitica/res/layout/dialog_purchase_gems.xml new file mode 100644 index 000000000..8bc9e122e --- /dev/null +++ b/Habitica/res/layout/dialog_purchase_gems.xml @@ -0,0 +1,45 @@ + + + + + + + + + \ No newline at end of file diff --git a/Habitica/res/layout/task_form_reward_value.xml b/Habitica/res/layout/form_stepper_value.xml similarity index 96% rename from Habitica/res/layout/task_form_reward_value.xml rename to Habitica/res/layout/form_stepper_value.xml index 203e3d079..17387eadc 100644 --- a/Habitica/res/layout/task_form_reward_value.xml +++ b/Habitica/res/layout/form_stepper_value.xml @@ -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" /> diff --git a/Habitica/res/values/attrs.xml b/Habitica/res/values/attrs.xml index 3893f1ae4..c892eeec8 100644 --- a/Habitica/res/values/attrs.xml +++ b/Habitica/res/values/attrs.xml @@ -137,4 +137,10 @@ + + + + + + diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/api/ApiService.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/api/ApiService.kt index db6cfab56..fc98d19c1 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/api/ApiService.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/api/ApiService.kt @@ -62,10 +62,10 @@ interface ApiService { fun equipItem(@Path("type") type: String, @Path("key") itemKey: String): Flowable> @POST("user/buy/{key}") - fun buyItem(@Path("key") itemKey: String): Flowable> + fun buyItem(@Path("key") itemKey: String, @Body quantity: Map): Flowable> @POST("user/purchase/{type}/{key}") - fun purchaseItem(@Path("type") type: String, @Path("key") itemKey: String): Flowable> + fun purchaseItem(@Path("type") type: String, @Path("key") itemKey: String, @Body quantity: Map): Flowable> @POST("user/purchase-hourglass/{type}/{key}") fun purchaseHourglassItem(@Path("type") type: String, @Path("key") itemKey: String): Flowable> diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/ApiClient.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/data/ApiClient.kt index 6ae204161..f0437e8b6 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/ApiClient.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/ApiClient.kt @@ -52,9 +52,9 @@ interface ApiClient { fun equipItem(type: String, itemKey: String): Flowable - fun buyItem(itemKey: String): Flowable + fun buyItem(itemKey: String, purchaseQuantity: Int): Flowable - fun purchaseItem(type: String, itemKey: String): Flowable + fun purchaseItem(type: String, itemKey: String, purchaseQuantity: Int): Flowable fun purchaseHourglassItem(type: String, itemKey: String): Flowable diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/InventoryRepository.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/data/InventoryRepository.kt index 2b64387ac..e420d130a 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/InventoryRepository.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/InventoryRepository.kt @@ -60,7 +60,7 @@ interface InventoryRepository : BaseRepository { fun inviteToQuest(quest: QuestContent): Flowable - fun buyItem(user: User?, id: String, value: Double): Flowable + fun buyItem(user: User?, id: String, value: Double, purchaseQuantity: Int): Flowable fun retrieveShopInventory(identifier: String): Flowable fun retrieveMarketGear(): Flowable @@ -71,7 +71,7 @@ interface InventoryRepository : BaseRepository { fun purchaseQuest(key: String): Flowable - fun purchaseItem(purchaseType: String, key: String): Flowable + fun purchaseItem(purchaseType: String, key: String, purchaseQuantity: Int): Flowable fun togglePinnedItem(item: ShopItem): Flowable> fun getItems(itemClass: Class, keys: Array, user: User?): Flowable> diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/ApiClientImpl.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/ApiClientImpl.kt index 309d16b10..d127013e5 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/ApiClientImpl.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/data/implementation/ApiClientImpl.kt @@ -321,12 +321,12 @@ class ApiClientImpl//private OnHabitsAPIResult mResultListener; return apiService.equipItem(type, itemKey).compose(configureApiCallObserver()) } - override fun buyItem(itemKey: String): Flowable { - return apiService.buyItem(itemKey).compose(configureApiCallObserver()) + override fun buyItem(itemKey: String, purchaseQuantity: Int): Flowable { + return apiService.buyItem(itemKey, mapOf(Pair("quantity", purchaseQuantity))).compose(configureApiCallObserver()) } - override fun purchaseItem(type: String, itemKey: String): Flowable { - return apiService.purchaseItem(type, itemKey).compose(configureApiCallObserver()) + override fun purchaseItem(type: String, itemKey: String, purchaseQuantity: Int): Flowable { + return apiService.purchaseItem(type, itemKey, mapOf(Pair("quantity", purchaseQuantity))).compose(configureApiCallObserver()) } override fun validateSubscription(request: SubscriptionValidationRequest): Flowable { 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 328826ac5..8a8b91bd4 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 @@ -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 { - return apiClient.buyItem(id) + override fun buyItem(user: User?, id: String, value: Double, purchaseQuantity: Int): Flowable { + 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 { - return apiClient.purchaseItem(purchaseType, key) + override fun purchaseItem(purchaseType: String, key: String, purchaseQuantity: Int): Flowable { + return apiClient.purchaseItem(purchaseType, key, purchaseQuantity) } override fun togglePinnedItem(item: ShopItem): Flowable> { 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 ffb204910..543fc0994 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 @@ -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 } 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 8f74022b8..b602e61dd 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 @@ -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() diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/ShopRecyclerAdapter.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/ShopRecyclerAdapter.kt index 0d98050d8..9136c0c5f 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/ShopRecyclerAdapter.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/inventory/ShopRecyclerAdapter.kt @@ -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 } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/tasks/RewardsRecyclerViewAdapter.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/tasks/RewardsRecyclerViewAdapter.kt index a409ce8d3..89ab638fa 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/tasks/RewardsRecyclerViewAdapter.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/adapter/tasks/RewardsRecyclerViewAdapter.kt @@ -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() } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/preferences/ProfilePreferencesFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/preferences/ProfilePreferencesFragment.kt index 661322830..95a5da80d 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/preferences/ProfilePreferencesFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/preferences/ProfilePreferencesFragment.kt @@ -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? = 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) } } } - } \ No newline at end of file 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 a698aaff1..5be4dfaf3 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 @@ -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 { 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 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 { diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/shops/PurchaseDialogGemsContent.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/shops/PurchaseDialogGemsContent.kt index 9b64ff5fb..f84a51a23 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/shops/PurchaseDialogGemsContent.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/shops/PurchaseDialogGemsContent.kt @@ -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() } } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/tasks/form/RewardValueFormView.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/tasks/form/StepperValueFormView.kt similarity index 58% rename from Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/tasks/form/RewardValueFormView.kt rename to Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/tasks/form/StepperValueFormView.kt index 1c58d7265..80a78eae0 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/tasks/form/RewardValueFormView.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/tasks/form/StepperValueFormView.kt @@ -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