forked from thijooree/android
add bml login, accounts and contacts
This commit is contained in:
@@ -61,7 +61,11 @@ class AccountsAdapter(accounts: List<MibAccount>) :
|
||||
RecyclerView.ViewHolder(binding.root) {
|
||||
fun bind(item: Item.Header) {
|
||||
binding.tvProfileName.text = item.profileName
|
||||
binding.tvProfileType.text = if (item.profileType == "0") "Personal" else "Business"
|
||||
binding.tvProfileType.text = when (item.profileType) {
|
||||
"BML" -> "Bank of Maldives"
|
||||
"0" -> "Personal"
|
||||
else -> "Business"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -14,6 +14,8 @@ import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import sh.sar.basedbank.BasedBankApp
|
||||
import sh.sar.basedbank.R
|
||||
import sh.sar.basedbank.api.bml.BmlLoginFlow
|
||||
import sh.sar.basedbank.api.mib.MibAccount
|
||||
import sh.sar.basedbank.api.mib.MibLoginFlow
|
||||
import sh.sar.basedbank.databinding.ActivityHomeBinding
|
||||
import sh.sar.basedbank.ui.login.LoginActivity
|
||||
@@ -63,30 +65,42 @@ class HomeActivity : AppCompatActivity() {
|
||||
|
||||
// Load data
|
||||
val app = application as BasedBankApp
|
||||
if (app.accounts.isNotEmpty()) {
|
||||
if (app.accounts.isNotEmpty() || app.bmlAccounts.isNotEmpty()) {
|
||||
// Came from fresh manual login — accounts ready, rest fetched in background
|
||||
viewModel.accounts.value = app.accounts
|
||||
AccountCache.save(this, app.accounts)
|
||||
val cached = FinancingCache.load(this)
|
||||
if (cached.isNotEmpty()) viewModel.financing.value = cached
|
||||
val cachedContacts = ContactsCache.loadContacts(this)
|
||||
if (cachedContacts.isNotEmpty()) viewModel.contacts.value = cachedContacts
|
||||
val cachedCats = ContactsCache.loadCategories(this)
|
||||
if (cachedCats.isNotEmpty()) viewModel.contactCategories.value = cachedCats
|
||||
refreshFinancing(app.mibSession, app.mibProfiles)
|
||||
refreshContacts(app.mibSession, app.mibProfiles)
|
||||
} else {
|
||||
// Came from lock screen — show caches immediately, refresh everything in background
|
||||
val cached = AccountCache.load(this)
|
||||
if (cached.isNotEmpty()) viewModel.accounts.value = cached
|
||||
val mibAccounts = app.accounts.filter { it.profileType != "BML" }
|
||||
val merged = mibAccounts + app.bmlAccounts
|
||||
viewModel.accounts.value = merged
|
||||
if (mibAccounts.isNotEmpty()) AccountCache.save(this, mibAccounts)
|
||||
if (app.bmlAccounts.isNotEmpty()) AccountCache.saveBml(this, app.bmlAccounts)
|
||||
|
||||
val cachedFinancing = FinancingCache.load(this)
|
||||
if (cachedFinancing.isNotEmpty()) viewModel.financing.value = cachedFinancing
|
||||
val cachedContacts = ContactsCache.loadContacts(this)
|
||||
val cachedContacts = mergeContacts(ContactsCache.loadContacts(this), ContactsCache.loadBml(this))
|
||||
if (cachedContacts.isNotEmpty()) viewModel.contacts.value = cachedContacts
|
||||
val cachedCats = ContactsCache.loadCategories(this)
|
||||
if (cachedCats.isNotEmpty()) viewModel.contactCategories.value = cachedCats
|
||||
val creds = CredentialStore(this).loadMibCredentials()
|
||||
if (creds != null) autoRefresh(creds)
|
||||
|
||||
refreshFinancing(app.mibSession, app.mibProfiles)
|
||||
refreshContacts(app.mibSession, app.mibProfiles)
|
||||
if (app.bmlSession != null) refreshBmlContacts(app)
|
||||
} else {
|
||||
// Came from lock screen — show caches immediately, refresh everything in background
|
||||
val cachedMib = AccountCache.load(this)
|
||||
val cachedBml = AccountCache.loadBml(this)
|
||||
val merged = cachedMib + cachedBml
|
||||
if (merged.isNotEmpty()) viewModel.accounts.value = merged
|
||||
val cachedFinancing = FinancingCache.load(this)
|
||||
if (cachedFinancing.isNotEmpty()) viewModel.financing.value = cachedFinancing
|
||||
val cachedContacts = mergeContacts(ContactsCache.loadContacts(this), ContactsCache.loadBml(this))
|
||||
if (cachedContacts.isNotEmpty()) viewModel.contacts.value = cachedContacts
|
||||
val cachedCats = ContactsCache.loadCategories(this)
|
||||
if (cachedCats.isNotEmpty()) viewModel.contactCategories.value = cachedCats
|
||||
|
||||
val store = CredentialStore(this)
|
||||
val mibCreds = store.loadMibCredentials()
|
||||
val bmlCreds = store.loadBmlCredentials()
|
||||
if (mibCreds != null) autoRefreshMib(mibCreds, bmlCreds)
|
||||
else if (bmlCreds != null) autoRefreshBml(bmlCreds)
|
||||
}
|
||||
|
||||
// Show dashboard on first create
|
||||
@@ -109,32 +123,96 @@ class HomeActivity : AppCompatActivity() {
|
||||
.commit()
|
||||
}
|
||||
|
||||
private fun autoRefresh(creds: CredentialStore.MibCredentials) {
|
||||
private fun autoRefreshMib(
|
||||
mibCreds: CredentialStore.MibCredentials,
|
||||
bmlCreds: CredentialStore.BmlCredentials?
|
||||
) {
|
||||
binding.refreshIndicator.visibility = View.VISIBLE
|
||||
val prefs = getSharedPreferences("mib_prefs", MODE_PRIVATE)
|
||||
val flow = MibLoginFlow(prefs)
|
||||
lifecycleScope.launch {
|
||||
var mibAccounts: List<MibAccount> = AccountCache.load(this@HomeActivity)
|
||||
try {
|
||||
val accounts = withContext(Dispatchers.IO) {
|
||||
flow.login(creds.username, creds.passwordHash, creds.otpSeed)
|
||||
mibAccounts = withContext(Dispatchers.IO) {
|
||||
flow.login(mibCreds.username, mibCreds.passwordHash, mibCreds.otpSeed)
|
||||
}
|
||||
val app = application as BasedBankApp
|
||||
app.accounts = accounts
|
||||
app.accounts = mibAccounts
|
||||
app.mibSession = flow.lastSession
|
||||
app.mibProfiles = flow.lastProfiles
|
||||
AccountCache.save(this@HomeActivity, accounts)
|
||||
viewModel.accounts.postValue(accounts)
|
||||
} catch (_: Exception) {
|
||||
// Keep cached data silently
|
||||
} finally {
|
||||
binding.refreshIndicator.visibility = View.GONE
|
||||
AccountCache.save(this@HomeActivity, mibAccounts)
|
||||
} catch (_: Exception) { /* keep cached */ }
|
||||
finally { binding.refreshIndicator.visibility = View.GONE }
|
||||
|
||||
val bmlAccounts = AccountCache.loadBml(this@HomeActivity).toMutableList()
|
||||
if (bmlCreds != null) {
|
||||
try {
|
||||
val bmlFlow = BmlLoginFlow()
|
||||
val (session, accounts) = withContext(Dispatchers.IO) {
|
||||
bmlFlow.login(bmlCreds.username, bmlCreds.password, bmlCreds.otpSeed)
|
||||
}
|
||||
val app = application as BasedBankApp
|
||||
app.bmlSession = session
|
||||
app.bmlAccounts = accounts
|
||||
AccountCache.saveBml(this@HomeActivity, accounts)
|
||||
bmlAccounts.clear()
|
||||
bmlAccounts.addAll(accounts)
|
||||
refreshBmlContacts(app)
|
||||
} catch (_: Exception) { /* keep cached */ }
|
||||
}
|
||||
viewModel.accounts.postValue(mibAccounts + bmlAccounts)
|
||||
val app = application as BasedBankApp
|
||||
refreshFinancing(app.mibSession, app.mibProfiles)
|
||||
refreshContacts(app.mibSession, app.mibProfiles)
|
||||
}
|
||||
}
|
||||
|
||||
private fun autoRefreshBml(bmlCreds: CredentialStore.BmlCredentials) {
|
||||
binding.refreshIndicator.visibility = View.VISIBLE
|
||||
lifecycleScope.launch {
|
||||
val cachedMib = AccountCache.load(this@HomeActivity)
|
||||
try {
|
||||
val bmlFlow = BmlLoginFlow()
|
||||
val (session, accounts) = withContext(Dispatchers.IO) {
|
||||
bmlFlow.login(bmlCreds.username, bmlCreds.password, bmlCreds.otpSeed)
|
||||
}
|
||||
val app = application as BasedBankApp
|
||||
app.bmlSession = session
|
||||
app.bmlAccounts = accounts
|
||||
AccountCache.saveBml(this@HomeActivity, accounts)
|
||||
viewModel.accounts.postValue(cachedMib + accounts)
|
||||
refreshBmlContacts(app)
|
||||
} catch (_: Exception) { /* keep cached */ }
|
||||
finally { binding.refreshIndicator.visibility = View.GONE }
|
||||
}
|
||||
}
|
||||
|
||||
private fun refreshBmlContacts(app: BasedBankApp) {
|
||||
val session = app.bmlSession ?: return
|
||||
val bmlFlow = BmlLoginFlow()
|
||||
lifecycleScope.launch {
|
||||
try {
|
||||
val bmlContacts = withContext(Dispatchers.IO) { bmlFlow.fetchContacts(session) }
|
||||
if (bmlContacts.isNotEmpty()) {
|
||||
ContactsCache.saveBml(this@HomeActivity, bmlContacts)
|
||||
val mibContacts = viewModel.contacts.value ?: ContactsCache.loadContacts(this@HomeActivity)
|
||||
viewModel.contacts.postValue(mergeContacts(mibContacts, bmlContacts))
|
||||
}
|
||||
} catch (_: Exception) { /* keep cached */ }
|
||||
}
|
||||
}
|
||||
|
||||
private fun mergeContacts(
|
||||
mib: List<MibBeneficiary>,
|
||||
bml: List<MibBeneficiary>
|
||||
): List<MibBeneficiary> {
|
||||
val seen = mutableSetOf<String>()
|
||||
val result = mutableListOf<MibBeneficiary>()
|
||||
for (c in mib) if (seen.add(c.benefNo)) result.add(c)
|
||||
for (c in bml) if (seen.add(c.benefNo)) result.add(c)
|
||||
return result
|
||||
}
|
||||
|
||||
private fun refreshContacts(session: MibSession?, profiles: List<MibProfile>) {
|
||||
if (session == null || profiles.isEmpty()) return
|
||||
val prefs = getSharedPreferences("mib_prefs", MODE_PRIVATE)
|
||||
@@ -162,7 +240,8 @@ class HomeActivity : AppCompatActivity() {
|
||||
}
|
||||
if (allContacts.isNotEmpty()) {
|
||||
ContactsCache.save(this@HomeActivity, allContacts, allCategories)
|
||||
viewModel.contacts.postValue(allContacts)
|
||||
val bmlContacts = ContactsCache.loadBml(this@HomeActivity)
|
||||
viewModel.contacts.postValue(mergeContacts(allContacts, bmlContacts))
|
||||
viewModel.contactCategories.postValue(allCategories)
|
||||
}
|
||||
} catch (_: Exception) { /* keep cached data */ }
|
||||
|
||||
Reference in New Issue
Block a user