This commit is contained in:
@@ -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>
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user