forked from shihaam/thijooree
quality of life features: logo and account type shown in trasfer page and contact picker and my accounts in contact picker, also money amount is dispayed bigger
This commit is contained in:
@@ -31,7 +31,9 @@ class ContactPickerAdapter(
|
|||||||
val isSameAsFrom: Boolean = false,
|
val isSameAsFrom: Boolean = false,
|
||||||
val isManualEntry: Boolean = false,
|
val isManualEntry: Boolean = false,
|
||||||
val imageHash: String? = null,
|
val imageHash: String? = null,
|
||||||
val inactiveReason: String? = null
|
val inactiveReason: String? = null,
|
||||||
|
val balance: String? = null,
|
||||||
|
val bankLogoRes: Int? = null
|
||||||
) : PickerItem()
|
) : PickerItem()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -89,14 +91,31 @@ class ContactPickerAdapter(
|
|||||||
binding.tvPrimary.text = item.displayName
|
binding.tvPrimary.text = item.displayName
|
||||||
binding.tvSecondary.text = item.subtitle
|
binding.tvSecondary.text = item.subtitle
|
||||||
|
|
||||||
val cached = item.imageHash?.let { imageCache[it] }
|
if (item.balance != null) {
|
||||||
if (cached != null) {
|
binding.tvBalance.text = item.balance
|
||||||
binding.ivIcon.setImageBitmap(cached)
|
binding.tvBalance.visibility = android.view.View.VISIBLE
|
||||||
} else {
|
} else {
|
||||||
val iconChar = if (item.isManualEntry) "→" else item.displayName.firstOrNull()?.uppercaseChar()?.toString() ?: "?"
|
binding.tvBalance.visibility = android.view.View.GONE
|
||||||
val iconColor = if (item.isManualEntry) "#546E7A" else item.colorHex
|
}
|
||||||
binding.ivIcon.setImageBitmap(makeInitialsBitmap(iconChar, iconColor, binding.ivIcon.context))
|
|
||||||
if (item.imageHash != null) onImageNeeded?.invoke(item.imageHash)
|
val cached = item.imageHash?.let { imageCache[it] }
|
||||||
|
when {
|
||||||
|
cached != null -> {
|
||||||
|
binding.ivIcon.scaleType = android.widget.ImageView.ScaleType.CENTER_CROP
|
||||||
|
binding.ivIcon.setImageBitmap(cached)
|
||||||
|
}
|
||||||
|
item.bankLogoRes != null -> {
|
||||||
|
binding.ivIcon.scaleType = android.widget.ImageView.ScaleType.FIT_CENTER
|
||||||
|
binding.ivIcon.setImageResource(item.bankLogoRes)
|
||||||
|
if (item.imageHash != null) onImageNeeded?.invoke(item.imageHash)
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
binding.ivIcon.scaleType = android.widget.ImageView.ScaleType.CENTER_CROP
|
||||||
|
val iconChar = if (item.isManualEntry) "→" else item.displayName.firstOrNull()?.uppercaseChar()?.toString() ?: "?"
|
||||||
|
val iconColor = if (item.isManualEntry) "#546E7A" else item.colorHex
|
||||||
|
binding.ivIcon.setImageBitmap(makeInitialsBitmap(iconChar, iconColor, binding.ivIcon.context))
|
||||||
|
if (item.imageHash != null) onImageNeeded?.invoke(item.imageHash)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.root.alpha = if (item.isSameAsFrom || item.inactiveReason != null) 0.4f else 1.0f
|
binding.root.alpha = if (item.isSameAsFrom || item.inactiveReason != null) 0.4f else 1.0f
|
||||||
|
|||||||
@@ -24,7 +24,10 @@ import sh.sar.basedbank.BasedBankApp
|
|||||||
import sh.sar.basedbank.R
|
import sh.sar.basedbank.R
|
||||||
import sh.sar.basedbank.api.mib.MibContactsClient
|
import sh.sar.basedbank.api.mib.MibContactsClient
|
||||||
import sh.sar.basedbank.databinding.SheetContactPickerBinding
|
import sh.sar.basedbank.databinding.SheetContactPickerBinding
|
||||||
|
import sh.sar.basedbank.util.AccountListParser
|
||||||
import sh.sar.basedbank.util.RecentsCache
|
import sh.sar.basedbank.util.RecentsCache
|
||||||
|
import sh.sar.basedbank.util.bmlapi.BmlCardParser
|
||||||
|
import sh.sar.basedbank.util.bmlapi.BmlDashboardParser
|
||||||
|
|
||||||
class ContactPickerSheetFragment : BottomSheetDialogFragment() {
|
class ContactPickerSheetFragment : BottomSheetDialogFragment() {
|
||||||
|
|
||||||
@@ -225,17 +228,27 @@ class ContactPickerSheetFragment : BottomSheetDialogFragment() {
|
|||||||
for (acc in filteredRegular) {
|
for (acc in filteredRegular) {
|
||||||
if (acc.profileImageHash != null) profileImageHashes.add(acc.profileImageHash)
|
if (acc.profileImageHash != null) profileImageHashes.add(acc.profileImageHash)
|
||||||
val isSame = acc.accountNumber == fromAccountNumber
|
val isSame = acc.accountNumber == fromAccountNumber
|
||||||
val accBal = if (hide) "••••••" else acc.availableBalance
|
val parsedBalance = AccountListParser.from(acc)?.balance
|
||||||
|
?: "${acc.currencyName} ${acc.availableBalance}"
|
||||||
|
val balance = if (hide) maskAmount(parsedBalance) else parsedBalance
|
||||||
|
val logoRes = when (acc.bank) {
|
||||||
|
"BML" -> R.drawable.bml_logo_vector
|
||||||
|
"FAHIPAY" -> R.drawable.fahipay_logo
|
||||||
|
"MIB" -> R.drawable.mib_logo
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
items.add(ContactPickerAdapter.PickerItem.Row(
|
items.add(ContactPickerAdapter.PickerItem.Row(
|
||||||
accountNumber = acc.accountNumber,
|
accountNumber = acc.accountNumber,
|
||||||
displayName = acc.accountBriefName,
|
displayName = acc.accountBriefName,
|
||||||
subtitle = "${acc.accountNumber} · ${acc.currencyName} $accBal",
|
subtitle = acc.accountNumber,
|
||||||
colorHex = "#FE860E",
|
colorHex = "#FE860E",
|
||||||
isSameAsFrom = isSame,
|
isSameAsFrom = isSame,
|
||||||
imageHash = acc.profileImageHash,
|
imageHash = acc.profileImageHash,
|
||||||
inactiveReason = if (isSame) null
|
inactiveReason = if (isSame) null
|
||||||
else if (fromIsCard && acc.loginTag != fromLoginTag) "Cards can only be used within the same BML account"
|
else if (fromIsCard && acc.loginTag != fromLoginTag) "Cards can only be used within the same BML account"
|
||||||
else currencyMismatchReason(fromCurrency, acc.currencyName)
|
else currencyMismatchReason(fromCurrency, acc.currencyName),
|
||||||
|
balance = balance,
|
||||||
|
bankLogoRes = logoRes
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -249,18 +262,24 @@ class ContactPickerSheetFragment : BottomSheetDialogFragment() {
|
|||||||
if (acc.profileImageHash != null) profileImageHashes.add(acc.profileImageHash)
|
if (acc.profileImageHash != null) profileImageHashes.add(acc.profileImageHash)
|
||||||
val isSame = acc.accountNumber == fromAccountNumber
|
val isSame = acc.accountNumber == fromAccountNumber
|
||||||
val isActive = acc.statusDesc.equals("Active", ignoreCase = true)
|
val isActive = acc.statusDesc.equals("Active", ignoreCase = true)
|
||||||
val cardBal = if (hide) "••••••" else acc.availableBalance
|
val isDebit = acc.profileType == "BML_DEBIT"
|
||||||
|
val parsedBalance = if (isDebit) null
|
||||||
|
else AccountListParser.from(acc)?.balance ?: "${acc.currencyName} ${acc.availableBalance}"
|
||||||
|
val balance = parsedBalance?.let { if (hide) maskAmount(it) else it }
|
||||||
|
val logoRes = BmlCardParser.cardNetworkIcon(acc) ?: R.drawable.bml_logo_vector
|
||||||
items.add(ContactPickerAdapter.PickerItem.Row(
|
items.add(ContactPickerAdapter.PickerItem.Row(
|
||||||
accountNumber = acc.accountNumber,
|
accountNumber = acc.accountNumber,
|
||||||
displayName = acc.accountBriefName,
|
displayName = acc.accountBriefName,
|
||||||
subtitle = "${acc.accountNumber} · ${acc.currencyName} $cardBal",
|
subtitle = acc.accountNumber,
|
||||||
colorHex = "#FE860E",
|
colorHex = "#FE860E",
|
||||||
isSameAsFrom = isSame,
|
isSameAsFrom = isSame,
|
||||||
imageHash = acc.profileImageHash,
|
imageHash = acc.profileImageHash,
|
||||||
inactiveReason = if (isSame) null
|
inactiveReason = if (isSame) null
|
||||||
else if (!isActive) acc.statusDesc
|
else if (!isActive) acc.statusDesc
|
||||||
else if (acc.loginTag != fromLoginTag) "Cards can only be used within the same BML account"
|
else if (acc.loginTag != fromLoginTag) "Cards can only be used within the same BML account"
|
||||||
else currencyMismatchReason(fromCurrency, acc.currencyName)
|
else currencyMismatchReason(fromCurrency, acc.currencyName),
|
||||||
|
balance = balance,
|
||||||
|
bankLogoRes = logoRes
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,11 +32,15 @@ import kotlinx.coroutines.Job
|
|||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
|
import sh.sar.basedbank.BasedBankApp
|
||||||
import sh.sar.basedbank.R
|
import sh.sar.basedbank.R
|
||||||
import sh.sar.basedbank.api.models.BankAccount
|
import sh.sar.basedbank.api.models.BankAccount
|
||||||
import sh.sar.basedbank.databinding.FragmentPayMvQrBinding
|
import sh.sar.basedbank.databinding.FragmentPayMvQrBinding
|
||||||
import sh.sar.basedbank.databinding.ItemAccountDropdownBinding
|
import sh.sar.basedbank.databinding.ItemAccountDropdownBinding
|
||||||
|
import sh.sar.basedbank.util.AccountListParser
|
||||||
import sh.sar.basedbank.util.PaymvQrParser
|
import sh.sar.basedbank.util.PaymvQrParser
|
||||||
|
import sh.sar.basedbank.util.bmlapi.BmlCardParser
|
||||||
|
import sh.sar.basedbank.util.bmlapi.BmlDashboardParser
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.FileOutputStream
|
import java.io.FileOutputStream
|
||||||
|
|
||||||
@@ -49,6 +53,7 @@ class PayMvQrFragment : Fragment() {
|
|||||||
private var selectedAccount: BankAccount? = null
|
private var selectedAccount: BankAccount? = null
|
||||||
private var generatedBitmap: Bitmap? = null
|
private var generatedBitmap: Bitmap? = null
|
||||||
private var generateJob: Job? = null
|
private var generateJob: Job? = null
|
||||||
|
private val dropdownProfileImageCache = mutableMapOf<String, Bitmap>()
|
||||||
|
|
||||||
private val qrLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
|
private val qrLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
|
||||||
if (result.resultCode != Activity.RESULT_OK) return@registerForActivityResult
|
if (result.resultCode != Activity.RESULT_OK) return@registerForActivityResult
|
||||||
@@ -410,9 +415,66 @@ class PayMvQrFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
val ownerPrefix = if (acc.bank == "BML" && acc.profileName.isNotBlank()) "${acc.profileName} · " else ""
|
val ownerPrefix = if (acc.bank == "BML" && acc.profileName.isNotBlank()) "${acc.profileName} · " else ""
|
||||||
b.tvDropdownAccountName.text = "$ownerPrefix${acc.accountBriefName}"
|
b.tvDropdownAccountName.text = "$ownerPrefix${acc.accountBriefName}"
|
||||||
|
|
||||||
|
val displayData = AccountListParser.from(acc)
|
||||||
|
val typeLabel = displayData?.typeLabel
|
||||||
|
?: if (acc.bank == "BML") BmlDashboardParser.productLabel(acc.accountTypeName)
|
||||||
|
else acc.accountTypeName.trim()
|
||||||
b.tvDropdownAccountNumber.text = acc.accountNumber
|
b.tvDropdownAccountNumber.text = acc.accountNumber
|
||||||
b.tvDropdownBalance.text = ""
|
if (typeLabel.isNotBlank()) {
|
||||||
|
b.tvDropdownAccountType.text = typeLabel
|
||||||
|
b.tvDropdownAccountType.visibility = View.VISIBLE
|
||||||
|
} else {
|
||||||
|
b.tvDropdownAccountType.visibility = View.GONE
|
||||||
|
}
|
||||||
|
b.tvDropdownBalance.text = displayData?.balance ?: ""
|
||||||
b.root.alpha = 1f
|
b.root.alpha = 1f
|
||||||
|
|
||||||
|
val networkIcon = BmlCardParser.cardNetworkIcon(acc)
|
||||||
|
when {
|
||||||
|
networkIcon != null -> {
|
||||||
|
b.ivDropdownCardLogo.setImageResource(networkIcon)
|
||||||
|
b.ivDropdownCardLogo.visibility = View.VISIBLE
|
||||||
|
}
|
||||||
|
acc.bank == "BML" -> {
|
||||||
|
b.ivDropdownCardLogo.setImageResource(R.drawable.bml_logo_vector)
|
||||||
|
b.ivDropdownCardLogo.visibility = View.VISIBLE
|
||||||
|
}
|
||||||
|
acc.bank == "FAHIPAY" -> {
|
||||||
|
b.ivDropdownCardLogo.setImageResource(R.drawable.fahipay_logo)
|
||||||
|
b.ivDropdownCardLogo.visibility = View.VISIBLE
|
||||||
|
}
|
||||||
|
acc.bank == "MIB" -> {
|
||||||
|
val hash = acc.profileImageHash
|
||||||
|
val cached = hash?.let { dropdownProfileImageCache[it] }
|
||||||
|
val imageView = b.ivDropdownCardLogo
|
||||||
|
imageView.tag = hash
|
||||||
|
if (cached != null) {
|
||||||
|
imageView.setImageBitmap(cached)
|
||||||
|
} else {
|
||||||
|
imageView.setImageResource(R.drawable.mib_logo)
|
||||||
|
if (hash != null) {
|
||||||
|
val app = requireActivity().application as BasedBankApp
|
||||||
|
viewLifecycleOwner.lifecycleScope.launch {
|
||||||
|
val bitmap = withContext(Dispatchers.IO) {
|
||||||
|
try {
|
||||||
|
val sess = app.anyMibSession() ?: return@withContext null
|
||||||
|
val b64 = app.anyMibFlow()?.fetchProfileImage(sess, hash) ?: return@withContext null
|
||||||
|
val bytes = android.util.Base64.decode(b64, android.util.Base64.DEFAULT)
|
||||||
|
BitmapFactory.decodeByteArray(bytes, 0, bytes.size)
|
||||||
|
} catch (_: Exception) { null }
|
||||||
|
}
|
||||||
|
if (bitmap != null) {
|
||||||
|
dropdownProfileImageCache[hash] = bitmap
|
||||||
|
if (imageView.tag == hash) imageView.setImageBitmap(bitmap)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
imageView.visibility = View.VISIBLE
|
||||||
|
}
|
||||||
|
else -> b.ivDropdownCardLogo.visibility = View.GONE
|
||||||
|
}
|
||||||
return b.root
|
return b.root
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -62,6 +62,7 @@ import sh.sar.basedbank.util.CredentialStore
|
|||||||
import sh.sar.basedbank.util.AccountInputParser
|
import sh.sar.basedbank.util.AccountInputParser
|
||||||
import sh.sar.basedbank.util.PaymvQrParser
|
import sh.sar.basedbank.util.PaymvQrParser
|
||||||
import sh.sar.basedbank.util.bmlapi.BmlCardParser
|
import sh.sar.basedbank.util.bmlapi.BmlCardParser
|
||||||
|
import sh.sar.basedbank.util.bmlapi.BmlDashboardParser
|
||||||
import sh.sar.basedbank.util.RecentPick
|
import sh.sar.basedbank.util.RecentPick
|
||||||
import sh.sar.basedbank.util.RecentsCache
|
import sh.sar.basedbank.util.RecentsCache
|
||||||
import sh.sar.basedbank.util.ReceiptStore
|
import sh.sar.basedbank.util.ReceiptStore
|
||||||
@@ -85,6 +86,7 @@ class TransferFragment : Fragment() {
|
|||||||
private var resolvedAccountNumber = ""
|
private var resolvedAccountNumber = ""
|
||||||
private var resolvedRecipientName = ""
|
private var resolvedRecipientName = ""
|
||||||
private var resolvedBankName = ""
|
private var resolvedBankName = ""
|
||||||
|
private var resolvedToOwnAccount: BankAccount? = null
|
||||||
|
|
||||||
// Selected Fahipay service when source is Fahipay and destination is a phone number
|
// Selected Fahipay service when source is Fahipay and destination is a phone number
|
||||||
// Values: "FAHIPAY_TRANSFER", "RAASTAS", "OOREDOO_BILL"
|
// Values: "FAHIPAY_TRANSFER", "RAASTAS", "OOREDOO_BILL"
|
||||||
@@ -206,6 +208,7 @@ class TransferFragment : Fragment() {
|
|||||||
viewModel.hideAmounts.observe(viewLifecycleOwner) {
|
viewModel.hideAmounts.observe(viewLifecycleOwner) {
|
||||||
accountDropdownAdapter?.notifyDataSetChanged()
|
accountDropdownAdapter?.notifyDataSetChanged()
|
||||||
selectedAccount?.let { showFromCard(it) }
|
selectedAccount?.let { showFromCard(it) }
|
||||||
|
resolvedToOwnAccount?.let { showToCard(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
childFragmentManager.setFragmentResultListener(ContactPickerSheetFragment.REQUEST_KEY, viewLifecycleOwner) { _, bundle ->
|
childFragmentManager.setFragmentResultListener(ContactPickerSheetFragment.REQUEST_KEY, viewLifecycleOwner) { _, bundle ->
|
||||||
@@ -281,6 +284,9 @@ class TransferFragment : Fragment() {
|
|||||||
// Show merchant in the "To" card — clear button hidden (can't change recipient for QR)
|
// Show merchant in the "To" card — clear button hidden (can't change recipient for QR)
|
||||||
binding.tvToAccountName.text = info.merchantName
|
binding.tvToAccountName.text = info.merchantName
|
||||||
binding.tvToBankBic.text = info.merchantAddress.ifBlank { "BML Merchant" }
|
binding.tvToBankBic.text = info.merchantAddress.ifBlank { "BML Merchant" }
|
||||||
|
binding.tvToAccountDetails.visibility = View.GONE
|
||||||
|
binding.tvToBalance.visibility = View.GONE
|
||||||
|
binding.ivToPhoto.scaleType = android.widget.ImageView.ScaleType.CENTER_CROP
|
||||||
binding.ivToPhoto.setImageBitmap(makeInitialsBitmap(info.merchantName, "#0066A1"))
|
binding.ivToPhoto.setImageBitmap(makeInitialsBitmap(info.merchantName, "#0066A1"))
|
||||||
binding.btnClearToInfo.visibility = View.GONE
|
binding.btnClearToInfo.visibility = View.GONE
|
||||||
binding.cardToInfo.visibility = View.VISIBLE
|
binding.cardToInfo.visibility = View.VISIBLE
|
||||||
@@ -366,34 +372,102 @@ class TransferFragment : Fragment() {
|
|||||||
val bankLabel = when (account.bank) {
|
val bankLabel = when (account.bank) {
|
||||||
"BML" -> "BML"
|
"BML" -> "BML"
|
||||||
"FAHIPAY" -> "FP"
|
"FAHIPAY" -> "FP"
|
||||||
|
"MIB" -> "MIB"
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
val typeLabel = when {
|
val typeLabel = AccountListParser.from(account)?.typeLabel
|
||||||
account.profileType == "BML_PREPAID" -> "Prepaid Card"
|
?: if (account.bank == "BML") BmlDashboardParser.productLabel(account.accountTypeName)
|
||||||
account.profileType == "BML_CREDIT" -> "Credit Card"
|
else account.accountTypeName.ifBlank { account.profileType }
|
||||||
account.profileType == "BML_DEBIT" -> "Debit Card"
|
|
||||||
account.accountTypeName.isNotBlank() -> account.accountTypeName
|
|
||||||
else -> account.profileType
|
|
||||||
}
|
|
||||||
|
|
||||||
val hide = viewModel.hideAmounts.value ?: false
|
val hide = viewModel.hideAmounts.value ?: false
|
||||||
val isDebitCard = account.profileType == "BML_DEBIT"
|
val isDebitCard = account.profileType == "BML_DEBIT"
|
||||||
val balancePart = if (isDebitCard) null else "${account.currencyName} ${account.availableBalance}"
|
val balancePart = if (isDebitCard) null else "${account.currencyName} ${account.availableBalance}"
|
||||||
binding.tvFromAccountName.text = account.accountBriefName
|
binding.tvFromAccountName.text = account.accountBriefName
|
||||||
binding.tvFromAccountNumber.text = account.accountNumber
|
binding.tvFromAccountNumber.text = account.accountNumber
|
||||||
|
binding.tvFromAccountDetails.text = listOfNotNull(bankLabel, typeLabel).joinToString(" · ")
|
||||||
val balanceDisplay = balancePart?.let { if (hide) maskAmount(it) else it }
|
val balanceDisplay = balancePart?.let { if (hide) maskAmount(it) else it }
|
||||||
binding.tvFromAccountDetails.text = listOfNotNull(bankLabel, typeLabel, balanceDisplay).joinToString(" · ")
|
if (balanceDisplay != null) {
|
||||||
val networkIcon = BmlCardParser.cardNetworkIcon(account)
|
binding.tvFromBalance.text = balanceDisplay
|
||||||
if (networkIcon != null) {
|
binding.tvFromBalance.visibility = View.VISIBLE
|
||||||
binding.ivFromPhoto.setImageResource(networkIcon)
|
|
||||||
} else {
|
} else {
|
||||||
binding.ivFromPhoto.setImageBitmap(makeInitialsBitmap(account.accountBriefName, colorHex))
|
binding.tvFromBalance.visibility = View.GONE
|
||||||
|
}
|
||||||
|
val networkIcon = BmlCardParser.cardNetworkIcon(account)
|
||||||
|
when {
|
||||||
|
networkIcon != null -> {
|
||||||
|
binding.ivFromPhoto.scaleType = android.widget.ImageView.ScaleType.FIT_CENTER
|
||||||
|
binding.ivFromPhoto.setImageResource(networkIcon)
|
||||||
|
}
|
||||||
|
account.bank == "BML" -> {
|
||||||
|
binding.ivFromPhoto.scaleType = android.widget.ImageView.ScaleType.FIT_CENTER
|
||||||
|
binding.ivFromPhoto.setImageResource(R.drawable.bml_logo_vector)
|
||||||
|
}
|
||||||
|
account.bank == "FAHIPAY" -> {
|
||||||
|
binding.ivFromPhoto.scaleType = android.widget.ImageView.ScaleType.FIT_CENTER
|
||||||
|
binding.ivFromPhoto.setImageResource(R.drawable.fahipay_logo)
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
binding.ivFromPhoto.scaleType = android.widget.ImageView.ScaleType.FIT_CENTER
|
||||||
|
binding.ivFromPhoto.setImageResource(R.drawable.mib_logo)
|
||||||
|
if (account.profileImageHash != null) loadFromPhoto(account.profileImageHash)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
binding.tilFrom.visibility = View.GONE
|
binding.tilFrom.visibility = View.GONE
|
||||||
binding.cardFromInfo.visibility = View.VISIBLE
|
binding.cardFromInfo.visibility = View.VISIBLE
|
||||||
|
}
|
||||||
|
|
||||||
if (account.bank != "BML" && account.profileImageHash != null) {
|
private fun showToCard(account: BankAccount) {
|
||||||
loadFromPhoto(account.profileImageHash)
|
resolvedToOwnAccount = account
|
||||||
|
val colorHex = when (account.bank) {
|
||||||
|
"BML" -> "#0066A1"
|
||||||
|
"FAHIPAY" -> "#15BEA7"
|
||||||
|
else -> "#FE860E"
|
||||||
|
}
|
||||||
|
val bankLabel = when (account.bank) {
|
||||||
|
"BML" -> "BML"
|
||||||
|
"FAHIPAY" -> "FP"
|
||||||
|
"MIB" -> "MIB"
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
val typeLabel = AccountListParser.from(account)?.typeLabel
|
||||||
|
?: if (account.bank == "BML") BmlDashboardParser.productLabel(account.accountTypeName)
|
||||||
|
else account.accountTypeName.ifBlank { account.profileType }
|
||||||
|
|
||||||
|
val hide = viewModel.hideAmounts.value ?: false
|
||||||
|
val isDebitCard = account.profileType == "BML_DEBIT"
|
||||||
|
val balancePart = if (isDebitCard) null else AccountListParser.from(account)?.balance
|
||||||
|
?: "${account.currencyName} ${account.availableBalance}"
|
||||||
|
|
||||||
|
binding.tvToAccountName.text = account.accountBriefName
|
||||||
|
binding.tvToBankBic.text = account.accountNumber
|
||||||
|
binding.tvToAccountDetails.text = listOfNotNull(bankLabel, typeLabel).joinToString(" · ")
|
||||||
|
binding.tvToAccountDetails.visibility = View.VISIBLE
|
||||||
|
val balanceDisplay = balancePart?.let { if (hide) maskAmount(it) else it }
|
||||||
|
if (balanceDisplay != null) {
|
||||||
|
binding.tvToBalance.text = balanceDisplay
|
||||||
|
binding.tvToBalance.visibility = View.VISIBLE
|
||||||
|
} else {
|
||||||
|
binding.tvToBalance.visibility = View.GONE
|
||||||
|
}
|
||||||
|
val networkIcon = BmlCardParser.cardNetworkIcon(account)
|
||||||
|
when {
|
||||||
|
networkIcon != null -> {
|
||||||
|
binding.ivToPhoto.scaleType = android.widget.ImageView.ScaleType.FIT_CENTER
|
||||||
|
binding.ivToPhoto.setImageResource(networkIcon)
|
||||||
|
}
|
||||||
|
account.bank == "BML" -> {
|
||||||
|
binding.ivToPhoto.scaleType = android.widget.ImageView.ScaleType.FIT_CENTER
|
||||||
|
binding.ivToPhoto.setImageResource(R.drawable.bml_logo_vector)
|
||||||
|
}
|
||||||
|
account.bank == "FAHIPAY" -> {
|
||||||
|
binding.ivToPhoto.scaleType = android.widget.ImageView.ScaleType.FIT_CENTER
|
||||||
|
binding.ivToPhoto.setImageResource(R.drawable.fahipay_logo)
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
binding.ivToPhoto.scaleType = android.widget.ImageView.ScaleType.FIT_CENTER
|
||||||
|
binding.ivToPhoto.setImageResource(R.drawable.mib_logo)
|
||||||
|
if (account.profileImageHash != null) loadToPhoto(account.profileImageHash, isProfile = true)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -406,7 +480,10 @@ class TransferFragment : Fragment() {
|
|||||||
val bytes = Base64.decode(base64, Base64.DEFAULT)
|
val bytes = Base64.decode(base64, Base64.DEFAULT)
|
||||||
val bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.size) ?: return@launch
|
val bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.size) ?: return@launch
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
if (_binding != null) binding.ivFromPhoto.setImageBitmap(bitmap)
|
if (_binding != null) {
|
||||||
|
binding.ivFromPhoto.scaleType = android.widget.ImageView.ScaleType.CENTER_CROP
|
||||||
|
binding.ivFromPhoto.setImageBitmap(bitmap)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (_: Exception) { }
|
} catch (_: Exception) { }
|
||||||
}
|
}
|
||||||
@@ -422,6 +499,7 @@ class TransferFragment : Fragment() {
|
|||||||
binding.btnClearToInfo.setOnClickListener {
|
binding.btnClearToInfo.setOnClickListener {
|
||||||
resolvedAccountNumber = ""
|
resolvedAccountNumber = ""
|
||||||
resolvedRecipientName = ""
|
resolvedRecipientName = ""
|
||||||
|
resolvedToOwnAccount = null
|
||||||
selectedFahipayService = null
|
selectedFahipayService = null
|
||||||
binding.cardToInfo.visibility = View.GONE
|
binding.cardToInfo.visibility = View.GONE
|
||||||
binding.layoutServiceSelector.visibility = View.INVISIBLE
|
binding.layoutServiceSelector.visibility = View.INVISIBLE
|
||||||
@@ -437,6 +515,7 @@ class TransferFragment : Fragment() {
|
|||||||
if (binding.cardToInfo.visibility == View.VISIBLE) {
|
if (binding.cardToInfo.visibility == View.VISIBLE) {
|
||||||
resolvedAccountNumber = ""
|
resolvedAccountNumber = ""
|
||||||
resolvedRecipientName = ""
|
resolvedRecipientName = ""
|
||||||
|
resolvedToOwnAccount = null
|
||||||
binding.cardToInfo.visibility = View.GONE
|
binding.cardToInfo.visibility = View.GONE
|
||||||
binding.tilTo.visibility = View.VISIBLE
|
binding.tilTo.visibility = View.VISIBLE
|
||||||
binding.btnPickContact.visibility = View.VISIBLE
|
binding.btnPickContact.visibility = View.VISIBLE
|
||||||
@@ -546,9 +625,16 @@ class TransferFragment : Fragment() {
|
|||||||
resolvedRecipientName = info.accountName
|
resolvedRecipientName = info.accountName
|
||||||
resolvedBankName = info.bankId
|
resolvedBankName = info.bankId
|
||||||
|
|
||||||
binding.tvToAccountName.text = displayName
|
if (matchedAcc != null) {
|
||||||
binding.tvToBankBic.text = "${info.accountNumber} · ${info.bankId}"
|
showToCard(matchedAcc)
|
||||||
binding.ivToPhoto.setImageBitmap(makeInitialsBitmap(displayName, colorHex))
|
} else {
|
||||||
|
binding.tvToAccountName.text = displayName
|
||||||
|
binding.tvToBankBic.text = "${info.accountNumber} · ${info.bankId}"
|
||||||
|
binding.tvToAccountDetails.visibility = View.GONE
|
||||||
|
binding.tvToBalance.visibility = View.GONE
|
||||||
|
binding.ivToPhoto.scaleType = android.widget.ImageView.ScaleType.CENTER_CROP
|
||||||
|
binding.ivToPhoto.setImageBitmap(makeInitialsBitmap(displayName, colorHex))
|
||||||
|
}
|
||||||
binding.tilTo.visibility = View.GONE
|
binding.tilTo.visibility = View.GONE
|
||||||
binding.btnPickContact.visibility = View.GONE
|
binding.btnPickContact.visibility = View.GONE
|
||||||
binding.btnScanQr.visibility = View.GONE
|
binding.btnScanQr.visibility = View.GONE
|
||||||
@@ -673,9 +759,18 @@ class TransferFragment : Fragment() {
|
|||||||
val contacts = viewModel.contacts.value ?: emptyList()
|
val contacts = viewModel.contacts.value ?: emptyList()
|
||||||
resolvedBankName = contacts.firstOrNull { it.benefAccount == accountNumber }?.benefBankName ?: ""
|
resolvedBankName = contacts.firstOrNull { it.benefAccount == accountNumber }?.benefBankName ?: ""
|
||||||
|
|
||||||
binding.tvToAccountName.text = displayName
|
val ownAccount = viewModel.accounts.value?.firstOrNull { it.accountNumber == accountNumber }
|
||||||
binding.tvToBankBic.text = subtitle
|
if (ownAccount != null) {
|
||||||
binding.ivToPhoto.setImageBitmap(makeInitialsBitmap(displayName, colorHex))
|
showToCard(ownAccount)
|
||||||
|
} else {
|
||||||
|
resolvedToOwnAccount = null
|
||||||
|
binding.tvToAccountName.text = displayName
|
||||||
|
binding.tvToBankBic.text = subtitle
|
||||||
|
binding.tvToAccountDetails.visibility = View.GONE
|
||||||
|
binding.tvToBalance.visibility = View.GONE
|
||||||
|
binding.ivToPhoto.scaleType = android.widget.ImageView.ScaleType.CENTER_CROP
|
||||||
|
binding.ivToPhoto.setImageBitmap(makeInitialsBitmap(displayName, colorHex))
|
||||||
|
}
|
||||||
binding.tilTo.visibility = View.GONE
|
binding.tilTo.visibility = View.GONE
|
||||||
binding.btnPickContact.visibility = View.GONE
|
binding.btnPickContact.visibility = View.GONE
|
||||||
binding.btnScanQr.visibility = View.GONE
|
binding.btnScanQr.visibility = View.GONE
|
||||||
@@ -1479,6 +1574,7 @@ class TransferFragment : Fragment() {
|
|||||||
resolvedAccountNumber = ""
|
resolvedAccountNumber = ""
|
||||||
resolvedRecipientName = ""
|
resolvedRecipientName = ""
|
||||||
resolvedBankName = ""
|
resolvedBankName = ""
|
||||||
|
resolvedToOwnAccount = null
|
||||||
selectedFahipayService = null
|
selectedFahipayService = null
|
||||||
binding.cardToInfo.visibility = View.GONE
|
binding.cardToInfo.visibility = View.GONE
|
||||||
binding.chipGroupService.visibility = View.GONE
|
binding.chipGroupService.visibility = View.GONE
|
||||||
@@ -1505,7 +1601,10 @@ class TransferFragment : Fragment() {
|
|||||||
val bytes = Base64.decode(base64, Base64.DEFAULT)
|
val bytes = Base64.decode(base64, Base64.DEFAULT)
|
||||||
val bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.size) ?: return@launch
|
val bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.size) ?: return@launch
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
if (_binding != null) binding.ivToPhoto.setImageBitmap(bitmap)
|
if (_binding != null) {
|
||||||
|
binding.ivToPhoto.scaleType = android.widget.ImageView.ScaleType.CENTER_CROP
|
||||||
|
binding.ivToPhoto.setImageBitmap(bitmap)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (_: Exception) { }
|
} catch (_: Exception) { }
|
||||||
}
|
}
|
||||||
@@ -1633,8 +1732,18 @@ class TransferFragment : Fragment() {
|
|||||||
val ownerPrefix = if (isBmlAccount && acc.profileName.isNotBlank()) "${acc.profileName} · " else ""
|
val ownerPrefix = if (isBmlAccount && acc.profileName.isNotBlank()) "${acc.profileName} · " else ""
|
||||||
val hide = viewModel.hideAmounts.value ?: false
|
val hide = viewModel.hideAmounts.value ?: false
|
||||||
b.tvDropdownAccountName.text = "$ownerPrefix${acc.accountBriefName}"
|
b.tvDropdownAccountName.text = "$ownerPrefix${acc.accountBriefName}"
|
||||||
|
val displayData = AccountListParser.from(acc)
|
||||||
|
val typeLabel = displayData?.typeLabel
|
||||||
|
?: if (acc.bank == "BML") BmlDashboardParser.productLabel(acc.accountTypeName)
|
||||||
|
else acc.accountTypeName.trim()
|
||||||
b.tvDropdownAccountNumber.text = if (inactive) "${acc.accountNumber} · ${acc.statusDesc}" else acc.accountNumber
|
b.tvDropdownAccountNumber.text = if (inactive) "${acc.accountNumber} · ${acc.statusDesc}" else acc.accountNumber
|
||||||
val balance = AccountListParser.from(acc)?.balance ?: ""
|
if (typeLabel.isNotBlank()) {
|
||||||
|
b.tvDropdownAccountType.text = typeLabel
|
||||||
|
b.tvDropdownAccountType.visibility = View.VISIBLE
|
||||||
|
} else {
|
||||||
|
b.tvDropdownAccountType.visibility = View.GONE
|
||||||
|
}
|
||||||
|
val balance = displayData?.balance ?: ""
|
||||||
b.tvDropdownBalance.text = if (hide && balance.isNotBlank()) maskAmount(balance) else balance
|
b.tvDropdownBalance.text = if (hide && balance.isNotBlank()) maskAmount(balance) else balance
|
||||||
b.root.alpha = if (inactive) 0.4f else 1f
|
b.root.alpha = if (inactive) 0.4f else 1f
|
||||||
val networkIcon = BmlCardParser.cardNetworkIcon(acc)
|
val networkIcon = BmlCardParser.cardNetworkIcon(acc)
|
||||||
|
|||||||
@@ -55,6 +55,7 @@
|
|||||||
|
|
||||||
</com.google.android.material.textfield.TextInputLayout>
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
|
|
||||||
<!-- Amount (optional) -->
|
<!-- Amount (optional) -->
|
||||||
<com.google.android.material.textfield.TextInputLayout
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
android:id="@+id/tilAmount"
|
android:id="@+id/tilAmount"
|
||||||
|
|||||||
@@ -101,6 +101,15 @@
|
|||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tvFromBalance"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textAppearance="?attr/textAppearanceTitleMedium"
|
||||||
|
android:textColor="?attr/colorOnSurface"
|
||||||
|
android:paddingHorizontal="8dp"
|
||||||
|
android:visibility="gone" />
|
||||||
|
|
||||||
<ImageButton
|
<ImageButton
|
||||||
android:id="@+id/btnClearFromInfo"
|
android:id="@+id/btnClearFromInfo"
|
||||||
android:layout_width="40dp"
|
android:layout_width="40dp"
|
||||||
@@ -218,10 +227,29 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="2dp"
|
android:layout_marginTop="2dp"
|
||||||
android:textAppearance="?attr/textAppearanceBodySmall"
|
android:textAppearance="?attr/textAppearanceBodySmall"
|
||||||
android:textColor="?attr/colorOnSurfaceVariant" />
|
android:textColor="?attr/colorOnSurfaceVariant"
|
||||||
|
android:fontFamily="monospace" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tvToAccountDetails"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="2dp"
|
||||||
|
android:textAppearance="?attr/textAppearanceBodySmall"
|
||||||
|
android:textColor="?attr/colorOnSurfaceVariant"
|
||||||
|
android:visibility="gone" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tvToBalance"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textAppearance="?attr/textAppearanceTitleMedium"
|
||||||
|
android:textColor="?attr/colorOnSurface"
|
||||||
|
android:paddingHorizontal="8dp"
|
||||||
|
android:visibility="gone" />
|
||||||
|
|
||||||
<ImageButton
|
<ImageButton
|
||||||
android:id="@+id/btnClearToInfo"
|
android:id="@+id/btnClearToInfo"
|
||||||
android:layout_width="40dp"
|
android:layout_width="40dp"
|
||||||
|
|||||||
@@ -53,6 +53,14 @@
|
|||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tvDropdownAccountType"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textAppearance="?attr/textAppearanceBodySmall"
|
||||||
|
android:textColor="?attr/colorOnSurfaceVariant"
|
||||||
|
android:visibility="gone" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|||||||
@@ -47,4 +47,13 @@
|
|||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tvBalance"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textAppearance="?attr/textAppearanceTitleMedium"
|
||||||
|
android:textColor="?attr/colorOnSurface"
|
||||||
|
android:paddingHorizontal="8dp"
|
||||||
|
android:visibility="gone" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|||||||
Reference in New Issue
Block a user