diff --git a/Habitica/res/layout/drawer_main.xml b/Habitica/res/layout/drawer_main.xml
index d10d097b59..24baba3040 100644
--- a/Habitica/res/layout/drawer_main.xml
+++ b/Habitica/res/layout/drawer_main.xml
@@ -18,17 +18,19 @@
android:background="?colorPrimaryOffset"
android:baselineAligned="false">
-
+ android:background="@drawable/rounded_avatar_bg"
+ android:clipToPadding="true"
+ android:clipChildren="true">
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/Habitica/res/layout/subscription_benefits.xml b/Habitica/res/layout/subscription_benefits.xml
index 39c80aed24..8adcc4a06a 100644
--- a/Habitica/res/layout/subscription_benefits.xml
+++ b/Habitica/res/layout/subscription_benefits.xml
@@ -6,6 +6,7 @@
tools:parentTag="android.widget.LinearLayout"
android:orientation="vertical">
diff --git a/Habitica/res/values/strings.xml b/Habitica/res/values/strings.xml
index 5c4727749a..ef584ce69b 100644
--- a/Habitica/res/values/strings.xml
+++ b/Habitica/res/values/strings.xml
@@ -1463,6 +1463,7 @@
Your subscription gives you an extra chance at the Armoire!
You got a second chance with 1HP!
Your %s broke
+ Subscribe to buy Gems with Gold and receive these other exclusive benefits!
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 085b9f76b9..8f8cb3ca33 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
@@ -268,7 +268,6 @@ class NavigationDrawerFragment : DialogFragment() {
setDisplayName(user.profile?.name)
setUsername(user.formattedUsername)
binding?.avatarView?.setAvatar(user)
- binding?.questMenuView?.configure(user)
val userItems = user.items
var hasSpecialItems = false
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/AvatarCircleShape.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/AvatarCircleShape.kt
deleted file mode 100644
index ee5d711e3b..0000000000
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/AvatarCircleShape.kt
+++ /dev/null
@@ -1,17 +0,0 @@
-package com.habitrpg.android.habitica.ui.views
-
-import androidx.compose.foundation.shape.CircleShape
-import androidx.compose.ui.geometry.Size
-import androidx.compose.ui.graphics.Outline
-import androidx.compose.ui.graphics.Shape
-import androidx.compose.ui.unit.Density
-import androidx.compose.ui.unit.LayoutDirection
-
-object AvatarCircleShape : Shape {
- override fun createOutline(
- size: Size,
- layoutDirection: LayoutDirection,
- density: Density
- ): Outline =
- CircleShape.createOutline(size, 20f, 20f, 20f, 20f, layoutDirection)
-}
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/RoundedCornerLayout.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/RoundedCornerLayout.kt
deleted file mode 100644
index 1ed0422dd3..0000000000
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/RoundedCornerLayout.kt
+++ /dev/null
@@ -1,79 +0,0 @@
-package com.habitrpg.android.habitica.ui.views
-
-import android.content.Context
-import android.graphics.Bitmap
-import android.graphics.Canvas
-import android.graphics.Color
-import android.graphics.Paint
-import android.graphics.PorterDuff
-import android.graphics.PorterDuffXfermode
-import android.graphics.RectF
-import android.util.AttributeSet
-import android.util.TypedValue
-import android.widget.FrameLayout
-
-// https://stackoverflow.com/a/26201117
-class RoundedCornerLayout : FrameLayout {
-
- private var maskBitmap: Bitmap? = null
- private var paint: Paint? = null
- private var maskPaint: Paint? = null
- private var cornerRadius: Float = CORNER_RADIUS
-
- constructor(context: Context) : super(context) {
- init(context)
- }
-
- constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {
- init(context)
- }
-
- constructor(context: Context, attrs: AttributeSet, defStyle: Int) : super(context, attrs, defStyle) {
- init(context)
- }
-
- private fun init(context: Context) {
- val metrics = context.resources.displayMetrics
- cornerRadius = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, CORNER_RADIUS, metrics)
-
- paint = Paint(Paint.ANTI_ALIAS_FLAG)
-
- maskPaint = Paint(Paint.ANTI_ALIAS_FLAG or Paint.FILTER_BITMAP_FLAG)
- maskPaint?.xfermode = PorterDuffXfermode(PorterDuff.Mode.CLEAR)
-
- setWillNotDraw(false)
- }
-
- override fun draw(canvas: Canvas) {
- val offscreenBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
- val offscreenCanvas = Canvas(offscreenBitmap)
-
- super.draw(offscreenCanvas)
-
- if (maskBitmap == null) {
- maskBitmap = createMask(width, height)
- }
-
- maskBitmap?.let { offscreenCanvas.drawBitmap(it, 0f, 0f, maskPaint) }
- canvas.drawBitmap(offscreenBitmap, 0f, 0f, paint)
- }
-
- private fun createMask(width: Int, height: Int): Bitmap {
- val mask = Bitmap.createBitmap(width, height, Bitmap.Config.ALPHA_8)
- val canvas = Canvas(mask)
-
- val paint = Paint(Paint.ANTI_ALIAS_FLAG)
- paint.color = Color.WHITE
-
- canvas.drawRect(0f, 0f, width.toFloat(), height.toFloat(), paint)
-
- paint.xfermode = PorterDuffXfermode(PorterDuff.Mode.CLEAR)
- canvas.drawRoundRect(RectF(0f, 0f, width.toFloat(), height.toFloat()), cornerRadius, cornerRadius, paint)
-
- return mask
- }
-
- companion object {
- private const val CORNER_RADIUS = 40.0f
- }
-}
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/equipment/EquipmentItemRow.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/equipment/EquipmentItemRow.kt
deleted file mode 100644
index 989186c5b3..0000000000
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/equipment/EquipmentItemRow.kt
+++ /dev/null
@@ -1,43 +0,0 @@
-package com.habitrpg.android.habitica.ui.views.equipment
-
-import android.content.Context
-import android.util.AttributeSet
-import android.view.View
-import android.widget.LinearLayout
-import com.habitrpg.android.habitica.R
-import com.habitrpg.android.habitica.databinding.ItemImageRowBinding
-import com.habitrpg.common.habitica.extensions.layoutInflater
-import com.habitrpg.common.habitica.extensions.loadImage
-
-class EquipmentItemRow(context: Context, attrs: AttributeSet?) : LinearLayout(context, attrs) {
-
- private val binding: ItemImageRowBinding = ItemImageRowBinding.inflate(context.layoutInflater, this)
- var equipmentIdentifier: String? = null
- set(value) {
- field = value
- val imageName = if (equipmentIdentifier?.isNotEmpty() == true && equipmentIdentifier?.endsWith("base_0") == false) "shop_$equipmentIdentifier" else "icon_head_0"
- binding.imageView.loadImage(imageName)
- }
-
- var customizationIdentifier: String? = null
- set(value) {
- field = value
- val imageName = if (customizationIdentifier?.isNotEmpty() == true) "icon_$customizationIdentifier" else "icon_head_0"
- binding.imageView.loadImage(imageName)
- }
-
- init {
- View.inflate(context, R.layout.item_image_row, this)
- isClickable = true
-
- val attributes = context.theme?.obtainStyledAttributes(
- attrs,
- R.styleable.EquipmentItemRow,
- 0,
- 0
- )
-
- binding.titleTextView.text = attributes?.getString(R.styleable.EquipmentItemRow_equipmentTitle)
- binding.valueTextView.visibility = View.GONE
- }
-}
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 a1769004ca..81e330149c 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
@@ -18,6 +18,8 @@ import com.habitrpg.android.habitica.HabiticaBaseApplication
import com.habitrpg.android.habitica.R
import com.habitrpg.android.habitica.data.InventoryRepository
import com.habitrpg.android.habitica.data.UserRepository
+import com.habitrpg.android.habitica.databinding.DialogPurchaseShopitemButtonBinding
+import com.habitrpg.android.habitica.databinding.DialogPurchaseShopitemHeaderBinding
import com.habitrpg.android.habitica.extensions.addCancelButton
import com.habitrpg.android.habitica.extensions.addCloseButton
import com.habitrpg.android.habitica.extensions.getShortRemainingString
@@ -31,7 +33,6 @@ 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.ArmoireActivityDirections
-import com.habitrpg.android.habitica.ui.fragments.purchases.SubscriptionBottomSheetFragment
import com.habitrpg.android.habitica.ui.views.CurrencyView
import com.habitrpg.android.habitica.ui.views.CurrencyViews
import com.habitrpg.android.habitica.ui.views.HabiticaIconsHelper
@@ -42,6 +43,7 @@ import com.habitrpg.android.habitica.ui.views.insufficientCurrency.InsufficientG
import com.habitrpg.android.habitica.ui.views.insufficientCurrency.InsufficientHourglassesDialog
import com.habitrpg.android.habitica.ui.views.insufficientCurrency.InsufficientSubscriberGemsDialog
import com.habitrpg.android.habitica.ui.views.tasks.form.StepperValueFormView
+import com.habitrpg.common.habitica.extensions.layoutInflater
import com.habitrpg.common.habitica.helpers.ExceptionHandler
import com.habitrpg.common.habitica.helpers.launchCatching
import dagger.hilt.android.internal.managers.ViewComponentManager
@@ -62,11 +64,11 @@ class PurchaseDialog(
private val userRepository: UserRepository,
private val inventoryRepository: InventoryRepository,
val item: ShopItem,
- val parentActivity: AppCompatActivity? = null
+ private val parentActivity: AppCompatActivity? = null
) : HabiticaAlertDialog(context) {
private val customHeader: View by lazy {
- LayoutInflater.from(context).inflate(R.layout.dialog_purchase_shopitem_header, null)
+ DialogPurchaseShopitemHeaderBinding.inflate(context.layoutInflater).root
}
private val currencyView: CurrencyViews
private val limitedTextView: TextView
@@ -80,7 +82,7 @@ class PurchaseDialog(
private var purchaseQuantity = 1
- var purchaseCardAction: ((ShopItem) -> Unit)? = null
+ private var purchaseCardAction: ((ShopItem) -> Unit)? = null
var onShopNeedsRefresh: ((ShopItem) -> Unit)? = null
private var shopItem: ShopItem = item
@@ -270,7 +272,7 @@ class PurchaseDialog(
pinTextView = customHeader.findViewById(R.id.pin_text)
addCloseButton()
- buyButton = addButton(layoutInflater.inflate(R.layout.dialog_purchase_shopitem_button, null), autoDismiss = false) { _, _ ->
+ buyButton = addButton(DialogPurchaseShopitemButtonBinding.inflate(layoutInflater).root, autoDismiss = false) { _, _ ->
onBuyButtonClicked()
}
priceLabel = buyButton.findViewById(R.id.priceLabel)
@@ -368,7 +370,6 @@ class PurchaseDialog(
parentActivity?.let { activity -> InsufficientGemsDialog(activity, shopItem.value).show() }
}
"hourglasses" == shopItem.currency -> InsufficientHourglassesDialog(context).show()
- else -> null
}
return
}
@@ -484,7 +485,10 @@ class PurchaseDialog(
val alert = HabiticaAlertDialog(context)
alert.setTitle(R.string.excess_items)
alert.setMessage(context.getString(R.string.excessItemsNoneLeft, item.text, purchaseQuantity, item.text))
- alert.addButton(context.getString(R.string.purchaseX, purchaseQuantity), true, false) { _, _ ->
+ alert.addButton(context.getString(R.string.purchaseX, purchaseQuantity),
+ isPrimary = true,
+ isDestructive = false
+ ) { _, _ ->
buyItem(purchaseQuantity)
}
alert.addCancelButton()
diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/social/QuestMenuView.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/social/QuestMenuView.kt
deleted file mode 100644
index 6d14ad9744..0000000000
--- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/views/social/QuestMenuView.kt
+++ /dev/null
@@ -1,79 +0,0 @@
-package com.habitrpg.android.habitica.ui.views.social
-
-import android.content.Context
-import android.util.AttributeSet
-import android.view.Gravity
-import android.view.View
-import android.view.ViewGroup
-import android.widget.LinearLayout
-import androidx.core.content.ContextCompat
-import com.habitrpg.android.habitica.R
-import com.habitrpg.android.habitica.databinding.QuestMenuViewBinding
-import com.habitrpg.android.habitica.models.inventory.Quest
-import com.habitrpg.android.habitica.models.inventory.QuestContent
-import com.habitrpg.android.habitica.models.user.User
-import com.habitrpg.android.habitica.ui.views.HabiticaIconsHelper
-import com.habitrpg.common.habitica.extensions.layoutInflater
-import java.util.Locale
-
-class QuestMenuView : LinearLayout {
- private val binding = QuestMenuViewBinding.inflate(context.layoutInflater, this)
-
- private var questContent: QuestContent? = null
-
- constructor(context: Context) : super(context) {
- setupView()
- }
-
- constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {
- setupView()
- }
-
- private fun setupView() {
- orientation = VERTICAL
-
- binding.heartIconView.setImageBitmap(HabiticaIconsHelper.imageOfHeartDarkBg())
- binding.rageIconView.setImageBitmap(HabiticaIconsHelper.imageOfRage())
-
- binding.pendingDamageIconView.setImageBitmap(HabiticaIconsHelper.imageOfDamage())
- }
-
- fun configure(quest: Quest) {
- binding.healthBarView.currentValue = quest.progress?.hp ?: 0.0
- binding.rageBarView.currentValue = quest.progress?.rage ?: 0.0
- }
-
- fun configure(questContent: QuestContent) {
- this.questContent = questContent
- binding.healthBarView.maxValue = questContent.boss?.hp?.toDouble() ?: 0.0
- binding.bossNameView.text = questContent.boss?.name
- binding.typeTextView.text = context.getString(R.string.boss_quest)
-
- if (questContent.boss?.hasRage == true) {
- binding.rageView.visibility = View.VISIBLE
- binding.rageBarView.maxValue = questContent.boss?.rage?.value ?: 0.0
- } else {
- binding.rageView.visibility = View.GONE
- }
- }
-
- fun configure(user: User) {
- binding.pendingDamageTextView.text = String.format(Locale.getDefault(), "%.01f", (user.party?.quest?.progress?.up ?: 0f))
- }
-
- fun hideBossArt() {
- binding.topView.orientation = HORIZONTAL
- binding.topView.setBackgroundColor(questContent?.colors?.mediumColor ?: 0)
- binding.bossNameView.gravity = Gravity.START
- binding.bossNameView.layoutParams = LayoutParams(0, ViewGroup.LayoutParams.WRAP_CONTENT, 1F)
- binding.typeTextView.setTextColor(questContent?.colors?.extraLightColor ?: 0)
- }
-
- fun showBossArt() {
- binding.topView.orientation = VERTICAL
- binding.topView.setBackgroundColor(ContextCompat.getColor(context, R.color.transparent))
- binding.bossNameView.gravity = Gravity.END
- binding.bossNameView.layoutParams = LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
- binding.typeTextView.setTextColor(ContextCompat.getColor(context, R.color.white))
- }
-}