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)) - } -}