optimize contacts page and contact picker

This commit is contained in:
2026-05-17 19:01:53 +05:00
parent 83499aed35
commit 36ab100aa7
5 changed files with 18 additions and 12 deletions
@@ -14,6 +14,7 @@ import sh.sar.basedbank.databinding.ItemPickerRowBinding
import sh.sar.basedbank.databinding.ItemPickerSectionHeaderBinding import sh.sar.basedbank.databinding.ItemPickerSectionHeaderBinding
class ContactPickerAdapter( class ContactPickerAdapter(
private val imageCache: MutableMap<String, Bitmap>,
private val onItemClick: (accountNumber: String, label: String) -> Unit, private val onItemClick: (accountNumber: String, label: String) -> Unit,
private val onSameAsFrom: () -> Unit, private val onSameAsFrom: () -> Unit,
private val onImageNeeded: ((hash: String) -> Unit)? = null, private val onImageNeeded: ((hash: String) -> Unit)? = null,
@@ -35,7 +36,6 @@ class ContactPickerAdapter(
} }
private var items: List<PickerItem> = emptyList() private var items: List<PickerItem> = emptyList()
private val imageCache = mutableMapOf<String, Bitmap>()
fun updateImage(hash: String, bitmap: Bitmap) { fun updateImage(hash: String, bitmap: Bitmap) {
imageCache[hash] = bitmap imageCache[hash] = bitmap
@@ -33,6 +33,7 @@ class ContactPickerSheetFragment : BottomSheetDialogFragment() {
private val viewModel: HomeViewModel by activityViewModels() private val viewModel: HomeViewModel by activityViewModels()
private val pendingHashes = mutableSetOf<String>() private val pendingHashes = mutableSetOf<String>()
private val sharedImageCache = mutableMapOf<String, Bitmap>()
private val profileImageHashes = mutableSetOf<String>() private val profileImageHashes = mutableSetOf<String>()
private val app get() = requireActivity().application as BasedBankApp private val app get() = requireActivity().application as BasedBankApp
private val session get() = app.mibSession private val session get() = app.mibSession
@@ -48,6 +49,7 @@ class ContactPickerSheetFragment : BottomSheetDialogFragment() {
val pageAdapters: List<ContactPickerAdapter> = pages.mapIndexed { i, page -> val pageAdapters: List<ContactPickerAdapter> = pages.mapIndexed { i, page ->
ContactPickerAdapter( ContactPickerAdapter(
imageCache = sharedImageCache,
onItemClick = { accountNumber, label -> handlePickerSelection(accountNumber, label) }, onItemClick = { accountNumber, label -> handlePickerSelection(accountNumber, label) },
onSameAsFrom = {}, onSameAsFrom = {},
onImageNeeded = { hash -> fetchImage(hash) }, onImageNeeded = { hash -> fetchImage(hash) },
@@ -16,6 +16,7 @@ import sh.sar.basedbank.api.mib.MibBeneficiary
import sh.sar.basedbank.databinding.ItemContactBinding import sh.sar.basedbank.databinding.ItemContactBinding
class ContactsAdapter( class ContactsAdapter(
private val imageCache: MutableMap<String, Bitmap>,
private val onImageNeeded: (hash: String) -> Unit, private val onImageNeeded: (hash: String) -> Unit,
private val onDeleteClick: (MibBeneficiary) -> Unit, private val onDeleteClick: (MibBeneficiary) -> Unit,
private val onTransferClick: (MibBeneficiary) -> Unit private val onTransferClick: (MibBeneficiary) -> Unit
@@ -23,7 +24,6 @@ class ContactsAdapter(
private var allContacts: List<MibBeneficiary> = emptyList() private var allContacts: List<MibBeneficiary> = emptyList()
private var displayed: List<MibBeneficiary> = emptyList() private var displayed: List<MibBeneficiary> = emptyList()
private val imageCache = mutableMapOf<String, Bitmap>()
private var activeCategoryId: String? = null private var activeCategoryId: String? = null
private var searchQuery: String = "" private var searchQuery: String = ""
@@ -36,6 +36,7 @@ class ContactsFragment : Fragment() {
private val viewModel: HomeViewModel by activityViewModels() private val viewModel: HomeViewModel by activityViewModels()
private val pendingHashes = mutableSetOf<String>() private val pendingHashes = mutableSetOf<String>()
private val sharedImageCache = mutableMapOf<String, Bitmap>()
private val app get() = requireActivity().application as BasedBankApp private val app get() = requireActivity().application as BasedBankApp
private val session get() = app.mibSession private val session get() = app.mibSession
@@ -52,6 +53,7 @@ class ContactsFragment : Fragment() {
private val density get() = resources.displayMetrics.density private val density get() = resources.displayMetrics.density
val contactAdapters: List<ContactsAdapter> = pages.map { page -> val contactAdapters: List<ContactsAdapter> = pages.map { page ->
ContactsAdapter( ContactsAdapter(
imageCache = sharedImageCache,
onImageNeeded = { hash -> fetchImage(hash) }, onImageNeeded = { hash -> fetchImage(hash) },
onDeleteClick = { contact -> confirmDelete(contact) }, onDeleteClick = { contact -> confirmDelete(contact) },
onTransferClick = { contact -> openTransfer(contact) } onTransferClick = { contact -> openTransfer(contact) }
@@ -450,8 +450,9 @@ class HomeActivity : AppCompatActivity() {
val bmlContacts = withContext(Dispatchers.IO) { bmlFlow.fetchContacts(session) } val bmlContacts = withContext(Dispatchers.IO) { bmlFlow.fetchContacts(session) }
if (bmlContacts.isNotEmpty()) { if (bmlContacts.isNotEmpty()) {
ContactsCache.saveBml(this@HomeActivity, bmlContacts) ContactsCache.saveBml(this@HomeActivity, bmlContacts)
val mibContacts = viewModel.contacts.value ?: ContactsCache.loadContacts(this@HomeActivity) val mibContacts = ContactsCache.loadContacts(this@HomeActivity)
viewModel.contacts.postValue(mergeContacts(mibContacts, bmlContacts)) val fahipayContacts = ContactsCache.loadFahipay(this@HomeActivity)
viewModel.contacts.postValue(mergeContacts(mergeContacts(mibContacts, bmlContacts), fahipayContacts))
} }
} catch (_: Exception) { /* keep cached */ } } catch (_: Exception) { /* keep cached */ }
} }
@@ -489,12 +490,11 @@ class HomeActivity : AppCompatActivity() {
val contacts = groups.flatMap { it.contacts } val contacts = groups.flatMap { it.contacts }
val categories = groups.map { MibBeneficiaryCategory(it.categoryId, it.label, it.contacts.size) } val categories = groups.map { MibBeneficiaryCategory(it.categoryId, it.label, it.contacts.size) }
ContactsCache.saveFahipay(this@HomeActivity, contacts, categories) ContactsCache.saveFahipay(this@HomeActivity, contacts, categories)
val existing = viewModel.contacts.value ?: emptyList() val mibContacts = ContactsCache.loadContacts(this@HomeActivity)
val nonFahipay = existing.filter { it.benefType != "FAHIPAY" } val bmlContacts = ContactsCache.loadBml(this@HomeActivity)
viewModel.contacts.postValue(mergeContacts(nonFahipay, contacts)) viewModel.contacts.postValue(mergeContacts(mergeContacts(mibContacts, bmlContacts), contacts))
val existingCats = viewModel.contactCategories.value ?: emptyList() val mibCategories = ContactsCache.loadCategories(this@HomeActivity)
val nonFahipayCats = existingCats.filter { !it.id.startsWith("FAHIPAY_") } viewModel.contactCategories.postValue(mibCategories + categories)
viewModel.contactCategories.postValue(nonFahipayCats + categories)
} catch (_: Exception) {} } catch (_: Exception) {}
} }
} }
@@ -538,8 +538,10 @@ class HomeActivity : AppCompatActivity() {
if (allContacts.isNotEmpty()) { if (allContacts.isNotEmpty()) {
ContactsCache.save(this@HomeActivity, allContacts, allCategories) ContactsCache.save(this@HomeActivity, allContacts, allCategories)
val bmlContacts = ContactsCache.loadBml(this@HomeActivity) val bmlContacts = ContactsCache.loadBml(this@HomeActivity)
viewModel.contacts.postValue(mergeContacts(allContacts, bmlContacts)) val fahipayContacts = ContactsCache.loadFahipay(this@HomeActivity)
viewModel.contactCategories.postValue(allCategories) val fahipayCategories = ContactsCache.loadFahipayCategories(this@HomeActivity)
viewModel.contacts.postValue(mergeContacts(mergeContacts(allContacts, bmlContacts), fahipayContacts))
viewModel.contactCategories.postValue(allCategories + fahipayCategories)
} }
} catch (_: Exception) { /* keep cached data */ } } catch (_: Exception) { /* keep cached data */ }
} }