manage card mode added
Auto Tag on Version Change / check-version (push) Successful in 4s

This commit is contained in:
2026-05-28 22:02:09 +05:00
parent b780091bb8
commit bfbb649b33
5 changed files with 148 additions and 19 deletions
@@ -255,6 +255,9 @@ class HomeActivity : AppCompatActivity() {
binding.drawerLayout.closeDrawers()
return
}
// Let CardsFragment handle back if in manage mode
val currentFrag = supportFragmentManager.findFragmentById(R.id.contentFrame)
if (currentFrag is CardsFragment && currentFrag.onBackPressed()) return
// Pop fragment back stack if there's anything on it (e.g. showWithBackStack)
if (supportFragmentManager.backStackEntryCount > 0) {
supportFragmentManager.popBackStack()
@@ -263,7 +266,6 @@ class HomeActivity : AppCompatActivity() {
// In bottom nav mode, pressing back navigates up the hierarchy
val isBottomNav = getSharedPreferences("prefs", MODE_PRIVATE).getBoolean("bottom_nav", false)
if (isBottomNav && binding.bottomNavigation.selectedItemId != R.id.nav_dashboard) {
val currentFrag = supportFragmentManager.findFragmentById(R.id.contentFrame)
// Sub-page reached via More (e.g. Settings, Activities) — go back to More
if (binding.bottomNavigation.selectedItemId == R.id.nav_more && currentFrag !is MoreFragment) {
show(MoreFragment())
@@ -39,6 +39,7 @@ class CardsFragment : Fragment() {
private var currentCardPosition: Int = 0
private var cardWidth: Int = 0
private var pendingQrAccountNumber: String? = null
private var isManageMode: Boolean = false
private val qrLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
if (result.resultCode != Activity.RESULT_OK) return@registerForActivityResult
@@ -128,6 +129,10 @@ ViewCompat.setOnApplyWindowInsetsListener(binding.contentLayout) { v, insets ->
}
(activity as? HomeActivity)?.triggerRefreshCards()
binding.btnManageCard.setOnClickListener {
setManageMode(!isManageMode)
}
binding.btnScanToPay.setOnClickListener {
val item = cards.getOrNull(currentCardPosition) ?: return@setOnClickListener
if (item is CardItem.Mib) {
@@ -154,6 +159,43 @@ ViewCompat.setOnApplyWindowInsetsListener(binding.contentLayout) { v, insets ->
binding.btnBlock.setOnClickListener(wip)
}
private fun setManageMode(enabled: Boolean) {
isManageMode = enabled
val gone = View.GONE
val visible = View.VISIBLE
binding.btnManageCard.visibility = if (enabled) gone else visible
binding.topSpacer.visibility = if (enabled) gone else visible
binding.rvCards.visibility = if (enabled) gone else visible
binding.pageIndicator.visibility = if (enabled) gone else visible
binding.llPayButtons.visibility = if (enabled) gone else visible
binding.llManageButtons.visibility = if (enabled) visible else gone
binding.manageCardView.root.visibility = if (enabled) visible else gone
if (!enabled) buildDots(cards.size, currentCardPosition)
if (enabled) {
val item = cards.getOrNull(currentCardPosition) ?: return
val cv = binding.manageCardView
when (item) {
is CardItem.Mib -> {
cv.tvCardOwner.text = item.card.cardHolderName
cv.tvCardNumber.text = formatMasked(item.card.maskedCardNumber)
val assetPath = cardImageAsset(item.card)
if (assetPath != null) loadCardImage(cv.ivCardImage, assetPath)
else cv.ivCardImage.setImageDrawable(null)
bindCardStatus(cv.tvCardStatus, mibCardStatusLabel(item.card.cardStatus))
cv.root.alpha = 1f
}
is CardItem.Bml -> {
cv.tvCardOwner.text = item.account.accountBriefName
cv.tvCardNumber.text = formatMasked(item.account.accountNumber)
loadCardImage(cv.ivCardImage, BmlCardParser.cardImageAsset(item.account))
val isActive = item.account.statusDesc.equals("Active", ignoreCase = true)
bindCardStatus(cv.tvCardStatus, item.account.statusDesc.takeUnless { isActive })
cv.root.alpha = if (isActive) 1f else 0.45f
}
}
}
}
private fun applyCardScales() {
val rv = binding.rvCards
val rvCenter = rv.paddingStart + (rv.width - rv.paddingStart - rv.paddingEnd) / 2f
@@ -173,6 +215,7 @@ ViewCompat.setOnApplyWindowInsetsListener(binding.contentLayout) { v, insets ->
}
private fun buildDots(count: Int, selected: Int) {
if (isManageMode) return
binding.pageIndicator.removeAllViews()
if (count <= 1) {
binding.pageIndicator.visibility = View.GONE
@@ -207,6 +250,14 @@ ViewCompat.setOnApplyWindowInsetsListener(binding.contentLayout) { v, insets ->
}
}
fun onBackPressed(): Boolean {
if (isManageMode) {
setManageMode(false)
return true
}
return false
}
override fun onResume() {
super.onResume()
requireActivity().title = getString(R.string.nav_pay_with_card)
@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<!-- Card icon -->
<path
android:fillColor="?attr/colorOnSurfaceVariant"
android:pathData="M20,4H4C2.89,4 2.01,4.89 2.01,6L2,18c0,1.11 0.89,2 2,2h16c1.11,0 2,-0.89 2,-2V6C22,4.89 21.11,4 20,4zM20,18H4v-6h16V18zM20,8H4V6h16V8z" />
<!-- Background circle to separate gear from card -->
<path
android:fillColor="?attr/colorSurface"
android:pathData="M12.5,18 A5.5,5.5 0 1 0 23.5,18 A5.5,5.5 0 1 0 12.5,18 Z" />
<!-- Gear icon scaled 0.5x, centered at (18,18) in the bottom-right corner -->
<group
android:scaleX="0.5"
android:scaleY="0.5"
android:translateX="12"
android:translateY="12">
<path
android:fillColor="?attr/colorOnSurfaceVariant"
android:pathData="M19.14,12.94c0.04,-0.3 0.06,-0.61 0.06,-0.94c0,-0.32 -0.02,-0.64 -0.07,-0.94l2.03,-1.58c0.18,-0.14 0.23,-0.41 0.12,-0.61l-1.92,-3.32c-0.12,-0.22 -0.37,-0.29 -0.59,-0.22l-2.39,0.96c-0.5,-0.38 -1.03,-0.7 -1.62,-0.94l-0.36,-2.54c-0.04,-0.24 -0.24,-0.41 -0.48,-0.41h-3.84c-0.24,0 -0.43,0.17 -0.47,0.41l-0.36,2.54c-0.59,0.24 -1.13,0.57 -1.62,0.94l-2.39,-0.96c-0.22,-0.08 -0.47,0 -0.59,0.22L2.74,8.87c-0.12,0.21 -0.08,0.47 0.12,0.61l2.03,1.58c-0.05,0.3 -0.09,0.63 -0.09,0.94s0.02,0.64 0.07,0.94l-2.03,1.58c-0.18,0.14 -0.23,0.41 -0.12,0.61l1.92,3.32c0.12,0.22 0.37,0.29 0.59,0.22l2.39,-0.96c0.5,0.38 1.03,0.7 1.62,0.94l0.36,2.54c0.05,0.24 0.24,0.41 0.48,0.41h3.84c0.24,0 0.44,-0.17 0.47,-0.41l0.36,-2.54c0.59,-0.24 1.13,-0.56 1.62,-0.94l2.39,0.96c0.22,0.08 0.47,0 0.59,-0.22l1.92,-3.32c0.12,-0.22 0.07,-0.47 -0.12,-0.61L19.14,12.94zM12,15.6c-1.98,0 -3.6,-1.62 -3.6,-3.6s1.62,-3.6 3.6,-3.6s3.6,1.62 3.6,3.6S13.98,15.6 12,15.6z" />
</group>
</vector>
+68 -18
View File
@@ -14,12 +14,47 @@
android:orientation="vertical"
android:visibility="gone">
<!-- Top spacer: pushes card to vertical center -->
<!-- Manage Card button row -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="end"
android:paddingHorizontal="12dp"
android:paddingTop="4dp">
<com.google.android.material.button.MaterialButton
android:id="@+id/btnManageCard"
style="@style/Widget.Material3.Button.TextButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minWidth="0dp"
android:minHeight="0dp"
android:text="@string/card_manage"
android:textSize="12sp"
app:icon="@drawable/ic_manage_card"
app:iconSize="20dp"
app:iconPadding="4dp" />
</LinearLayout>
<!-- Top spacer: pushes card to vertical center (hidden in manage mode) -->
<View
android:id="@+id/topSpacer"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
<!-- Manage mode: selected card with overlays -->
<include
android:id="@+id/manageCardView"
layout="@layout/item_card_stack"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:layout_marginTop="8dp"
android:visibility="gone" />
<!-- Horizontal card stack. Width/padding set programmatically for centering + peek. -->
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rvCards"
@@ -64,14 +99,15 @@
android:layout_marginBottom="4dp"
android:background="?attr/colorOutlineVariant" />
<!-- Primary pay actions -->
<!-- Primary pay actions (normal mode) -->
<LinearLayout
android:id="@+id/llPayButtons"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:paddingHorizontal="16dp"
android:paddingTop="8dp"
android:paddingBottom="4dp">
android:paddingBottom="12dp">
<com.google.android.material.button.MaterialButton
android:id="@+id/btnScanToPay"
@@ -111,56 +147,70 @@
</LinearLayout>
<!-- Secondary card management actions -->
<!-- Card management actions (manage mode only) -->
<LinearLayout
android:id="@+id/llManageButtons"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:paddingHorizontal="8dp"
android:paddingTop="4dp"
android:paddingBottom="8dp">
android:paddingTop="8dp"
android:paddingBottom="12dp"
android:visibility="gone">
<com.google.android.material.button.MaterialButton
android:id="@+id/btnChangePin"
style="@style/Widget.Material3.Button.TextButton"
style="@style/Widget.Material3.Button.TonalButton"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:layout_marginHorizontal="4dp"
android:minWidth="0dp"
android:minHeight="0dp"
android:paddingTop="14dp"
android:paddingBottom="14dp"
android:text="@string/card_action_change_pin"
android:textSize="11sp"
android:textSize="12sp"
app:icon="@drawable/ic_edit"
app:iconSize="16dp"
app:iconPadding="3dp" />
app:iconSize="22dp"
app:iconGravity="top"
app:iconPadding="6dp" />
<com.google.android.material.button.MaterialButton
android:id="@+id/btnFreeze"
style="@style/Widget.Material3.Button.TextButton"
style="@style/Widget.Material3.Button.TonalButton"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:layout_marginHorizontal="4dp"
android:minWidth="0dp"
android:minHeight="0dp"
android:paddingTop="14dp"
android:paddingBottom="14dp"
android:text="@string/card_action_freeze"
android:textSize="11sp"
android:textSize="12sp"
app:icon="@drawable/ic_freeze"
app:iconSize="16dp"
app:iconPadding="3dp" />
app:iconSize="22dp"
app:iconGravity="top"
app:iconPadding="6dp" />
<com.google.android.material.button.MaterialButton
android:id="@+id/btnBlock"
style="@style/Widget.Material3.Button.TextButton"
style="@style/Widget.Material3.Button.TonalButton"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:layout_marginHorizontal="4dp"
android:minWidth="0dp"
android:minHeight="0dp"
android:paddingTop="14dp"
android:paddingBottom="14dp"
android:text="@string/card_action_block"
android:textSize="11sp"
android:textSize="12sp"
app:icon="@drawable/ic_block"
app:iconSize="16dp"
app:iconPadding="3dp" />
app:iconSize="22dp"
app:iconGravity="top"
app:iconPadding="6dp" />
</LinearLayout>
+1
View File
@@ -330,6 +330,7 @@
<string name="card_pay_qr">Scan to Pay</string>
<string name="card_pay_nfc">Tap to Pay</string>
<string name="mib_qr_nfc_not_supported">Skill issue on MIB side, Not supported</string>
<string name="card_manage">Manage Card</string>
<string name="card_action_change_pin">Change PIN</string>
<string name="card_action_freeze">Freeze</string>
<string name="card_action_block">Block</string>