forked from thijooree/android
lazy loading
This commit is contained in:
@@ -7,7 +7,7 @@ import sh.sar.basedbank.api.mib.MibAccount
|
||||
import sh.sar.basedbank.databinding.ItemAccountBinding
|
||||
import sh.sar.basedbank.databinding.ItemProfileHeaderBinding
|
||||
|
||||
class AccountsAdapter(private val accounts: List<MibAccount>) :
|
||||
class AccountsAdapter(accounts: List<MibAccount>) :
|
||||
RecyclerView.Adapter<RecyclerView.ViewHolder>() {
|
||||
|
||||
private sealed class Item {
|
||||
@@ -15,7 +15,15 @@ class AccountsAdapter(private val accounts: List<MibAccount>) :
|
||||
data class Account(val account: MibAccount) : Item()
|
||||
}
|
||||
|
||||
private val items: List<Item> = buildList {
|
||||
private val items: MutableList<Item> = buildItems(accounts).toMutableList()
|
||||
|
||||
fun updateAccounts(accounts: List<MibAccount>) {
|
||||
items.clear()
|
||||
items.addAll(buildItems(accounts))
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
|
||||
private fun buildItems(accounts: List<MibAccount>): List<Item> = buildList {
|
||||
var lastProfile = ""
|
||||
for (account in accounts) {
|
||||
if (account.profileName != lastProfile) {
|
||||
|
||||
@@ -1,26 +1,66 @@
|
||||
package sh.sar.basedbank.ui.home
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import sh.sar.basedbank.BasedBankApp
|
||||
import sh.sar.basedbank.api.mib.MibLoginFlow
|
||||
import sh.sar.basedbank.databinding.ActivityHomeBinding
|
||||
import sh.sar.basedbank.util.AccountCache
|
||||
import sh.sar.basedbank.util.CredentialStore
|
||||
|
||||
class HomeActivity : AppCompatActivity() {
|
||||
|
||||
private lateinit var binding: ActivityHomeBinding
|
||||
private lateinit var adapter: AccountsAdapter
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
binding = ActivityHomeBinding.inflate(layoutInflater)
|
||||
setContentView(binding.root)
|
||||
|
||||
setSupportActionBar(binding.toolbar)
|
||||
|
||||
val accounts = (application as BasedBankApp).accounts
|
||||
val adapter = AccountsAdapter(accounts)
|
||||
val app = application as BasedBankApp
|
||||
|
||||
// If we arrived here from a fresh manual login, accounts are already in memory.
|
||||
// Otherwise load the last-known cache so the UI is instant.
|
||||
val initial = if (app.accounts.isNotEmpty()) app.accounts else AccountCache.load(this)
|
||||
adapter = AccountsAdapter(initial)
|
||||
binding.recyclerView.layoutManager = LinearLayoutManager(this)
|
||||
binding.recyclerView.adapter = adapter
|
||||
|
||||
if (app.accounts.isNotEmpty()) {
|
||||
// Just logged in — persist the fresh data and we're done
|
||||
AccountCache.save(this, app.accounts)
|
||||
} else {
|
||||
// Came from lock screen — refresh in background
|
||||
val creds = CredentialStore(this).loadMibCredentials()
|
||||
if (creds != null) autoRefresh(creds)
|
||||
}
|
||||
}
|
||||
|
||||
private fun autoRefresh(creds: CredentialStore.MibCredentials) {
|
||||
binding.refreshIndicator.visibility = View.VISIBLE
|
||||
val prefs = getSharedPreferences("mib_prefs", MODE_PRIVATE)
|
||||
val flow = MibLoginFlow(prefs)
|
||||
lifecycleScope.launch {
|
||||
try {
|
||||
val accounts = withContext(Dispatchers.IO) {
|
||||
flow.login(creds.username, creds.passwordHash, creds.otpSeed)
|
||||
}
|
||||
(application as BasedBankApp).accounts = accounts
|
||||
AccountCache.save(this@HomeActivity, accounts)
|
||||
adapter.updateAccounts(accounts)
|
||||
} catch (_: Exception) {
|
||||
// Keep showing cached data silently
|
||||
} finally {
|
||||
binding.refreshIndicator.visibility = View.GONE
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ import kotlinx.coroutines.withContext
|
||||
import sh.sar.basedbank.util.Totp
|
||||
import sh.sar.basedbank.BasedBankApp
|
||||
import sh.sar.basedbank.api.mib.MibLoginFlow
|
||||
import sh.sar.basedbank.util.AccountCache
|
||||
import sh.sar.basedbank.util.CredentialStore
|
||||
import sh.sar.basedbank.databinding.FragmentCredentialsBinding
|
||||
import sh.sar.basedbank.ui.home.HomeActivity
|
||||
@@ -111,6 +112,7 @@ class CredentialsFragment : Fragment() {
|
||||
}
|
||||
Log.d(TAG, "Login succeeded, got ${accounts.size} accounts")
|
||||
CredentialStore(requireContext()).saveMibCredentials(username, passwordHash, otpSeed)
|
||||
AccountCache.save(requireContext(), accounts)
|
||||
(requireActivity().application as BasedBankApp).accounts = accounts
|
||||
startActivity(Intent(requireContext(), HomeActivity::class.java))
|
||||
requireActivity().finish()
|
||||
|
||||
@@ -1,19 +1,8 @@
|
||||
package sh.sar.basedbank.ui.login
|
||||
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import sh.sar.basedbank.BasedBankApp
|
||||
import sh.sar.basedbank.R
|
||||
import sh.sar.basedbank.api.mib.MibLoginFlow
|
||||
import sh.sar.basedbank.databinding.ActivityLoginBinding
|
||||
import sh.sar.basedbank.ui.home.HomeActivity
|
||||
import sh.sar.basedbank.util.CredentialStore
|
||||
|
||||
class LoginActivity : AppCompatActivity() {
|
||||
|
||||
@@ -23,31 +12,5 @@ class LoginActivity : AppCompatActivity() {
|
||||
super.onCreate(savedInstanceState)
|
||||
binding = ActivityLoginBinding.inflate(layoutInflater)
|
||||
setContentView(binding.root)
|
||||
|
||||
val creds = CredentialStore(this).loadMibCredentials()
|
||||
if (creds != null) {
|
||||
binding.navHostFragment.visibility = View.GONE
|
||||
binding.autoLoginGroup.visibility = View.VISIBLE
|
||||
autoLogin(creds)
|
||||
}
|
||||
}
|
||||
|
||||
private fun autoLogin(creds: CredentialStore.MibCredentials) {
|
||||
val prefs = getSharedPreferences("mib_prefs", MODE_PRIVATE)
|
||||
val flow = MibLoginFlow(prefs)
|
||||
lifecycleScope.launch {
|
||||
try {
|
||||
val accounts = withContext(Dispatchers.IO) {
|
||||
flow.login(creds.username, creds.passwordHash, creds.otpSeed)
|
||||
}
|
||||
(application as BasedBankApp).accounts = accounts
|
||||
startActivity(Intent(this@LoginActivity, HomeActivity::class.java))
|
||||
finish()
|
||||
} catch (e: Exception) {
|
||||
// Auto-login failed — fall back to manual login form
|
||||
binding.autoLoginGroup.visibility = View.GONE
|
||||
binding.navHostFragment.visibility = View.VISIBLE
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user