diff --git a/app/src/main/java/sh/sar/basedbank/LockActivity.kt b/app/src/main/java/sh/sar/basedbank/LockActivity.kt
index fefe21e..247ba5e 100644
--- a/app/src/main/java/sh/sar/basedbank/LockActivity.kt
+++ b/app/src/main/java/sh/sar/basedbank/LockActivity.kt
@@ -51,6 +51,10 @@ class LockActivity : AppCompatActivity() {
}
private fun buildNumpad() {
+ val dp = resources.displayMetrics.density
+ val btnSize = (68 * dp).toInt()
+ val btnMarginH = (10 * dp).toInt()
+ val rowMarginV = (6 * dp).toInt()
val rows = listOf(
listOf("1", "2", "3"),
listOf("4", "5", "6"),
@@ -60,9 +64,11 @@ class LockActivity : AppCompatActivity() {
rows.forEach { keys ->
val row = LinearLayout(this).apply {
orientation = LinearLayout.HORIZONTAL
+ gravity = android.view.Gravity.CENTER
layoutParams = LinearLayout.LayoutParams(
- LinearLayout.LayoutParams.MATCH_PARENT, 0, 1f
- )
+ LinearLayout.LayoutParams.WRAP_CONTENT,
+ LinearLayout.LayoutParams.WRAP_CONTENT
+ ).also { it.setMargins(0, rowMarginV, 0, rowMarginV) }
}
keys.forEach { key ->
val style = if (key == "✓")
@@ -71,10 +77,12 @@ class LockActivity : AppCompatActivity() {
com.google.android.material.R.attr.materialButtonOutlinedStyle
val btn = MaterialButton(this, null, style).apply {
text = key
- textSize = 20f
+ textSize = 24f
insetTop = 0; insetBottom = 0
- layoutParams = LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.MATCH_PARENT, 1f)
- .also { it.setMargins(4, 4, 4, 4) }
+ minimumWidth = 0; minimumHeight = 0
+ cornerRadius = btnSize / 2
+ layoutParams = LinearLayout.LayoutParams(btnSize, btnSize)
+ .also { it.setMargins(btnMarginH, 0, btnMarginH, 0) }
}
btn.setOnClickListener { handleKey(key) }
row.addView(btn)
diff --git a/app/src/main/java/sh/sar/basedbank/ui/home/HomeActivity.kt b/app/src/main/java/sh/sar/basedbank/ui/home/HomeActivity.kt
index f60651a..793b827 100644
--- a/app/src/main/java/sh/sar/basedbank/ui/home/HomeActivity.kt
+++ b/app/src/main/java/sh/sar/basedbank/ui/home/HomeActivity.kt
@@ -2,6 +2,8 @@ package sh.sar.basedbank.ui.home
import android.content.Intent
import android.os.Bundle
+import android.view.Menu
+import android.view.MenuItem
import android.view.View
import android.widget.Toast
import androidx.activity.viewModels
@@ -131,6 +133,21 @@ class HomeActivity : AppCompatActivity() {
.commit()
}
+ override fun onCreateOptionsMenu(menu: Menu): Boolean {
+ menuInflater.inflate(R.menu.toolbar_menu, menu)
+ return true
+ }
+
+ override fun onOptionsItemSelected(item: MenuItem): Boolean {
+ if (item.itemId == R.id.action_lock) {
+ startActivity(Intent(this, sh.sar.basedbank.LockActivity::class.java))
+ finish()
+ return true
+ }
+ return super.onOptionsItemSelected(item)
+ }
+
+
private fun autoRefresh(
mibCreds: CredentialStore.MibCredentials?,
bmlCreds: CredentialStore.BmlCredentials?,
diff --git a/app/src/main/java/sh/sar/basedbank/ui/home/SettingsFragment.kt b/app/src/main/java/sh/sar/basedbank/ui/home/SettingsFragment.kt
index f064243..8126e39 100644
--- a/app/src/main/java/sh/sar/basedbank/ui/home/SettingsFragment.kt
+++ b/app/src/main/java/sh/sar/basedbank/ui/home/SettingsFragment.kt
@@ -7,10 +7,12 @@ import android.view.View
import android.view.ViewGroup
import androidx.appcompat.app.AppCompatDelegate
import androidx.appcompat.app.AppCompatDelegate.setApplicationLocales
+import androidx.biometric.BiometricManager
import androidx.core.os.LocaleListCompat
import androidx.fragment.app.Fragment
import sh.sar.basedbank.R
import sh.sar.basedbank.databinding.FragmentSettingsBinding
+import sh.sar.basedbank.ui.onboarding.SecuritySetupFragment
class SettingsFragment : Fragment() {
@@ -25,7 +27,7 @@ class SettingsFragment : Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
val prefs = requireContext().getSharedPreferences("prefs", Context.MODE_PRIVATE)
- // Set initial selection
+ // Theme
val saved = prefs.getString("theme", "system")
val initialId = when (saved) {
"light" -> R.id.btnThemeLight
@@ -57,6 +59,24 @@ class SettingsFragment : Fragment() {
val tag = if (checkedId == R.id.btnLangDhivehi) "dv" else "en"
setApplicationLocales(LocaleListCompat.forLanguageTags(tag))
}
+
+ // Change lock
+ binding.btnChangeLock.setOnClickListener {
+ (requireActivity() as HomeActivity).showWithBackStack(
+ SecuritySetupFragment.newInstance(changeMode = true)
+ )
+ }
+
+ // Biometrics toggle — only show if device supports it
+ val canUseBiometrics = BiometricManager.from(requireContext())
+ .canAuthenticate(BiometricManager.Authenticators.BIOMETRIC_WEAK) == BiometricManager.BIOMETRIC_SUCCESS
+ if (canUseBiometrics) {
+ binding.rowBiometrics.visibility = View.VISIBLE
+ binding.switchBiometrics.isChecked = prefs.getBoolean("biometrics_enabled", false)
+ binding.switchBiometrics.setOnCheckedChangeListener { _, isChecked ->
+ prefs.edit().putBoolean("biometrics_enabled", isChecked).apply()
+ }
+ }
}
override fun onResume() {
diff --git a/app/src/main/java/sh/sar/basedbank/ui/onboarding/SecuritySetupFragment.kt b/app/src/main/java/sh/sar/basedbank/ui/onboarding/SecuritySetupFragment.kt
index 1b76154..1ccb49b 100644
--- a/app/src/main/java/sh/sar/basedbank/ui/onboarding/SecuritySetupFragment.kt
+++ b/app/src/main/java/sh/sar/basedbank/ui/onboarding/SecuritySetupFragment.kt
@@ -21,6 +21,13 @@ class SecuritySetupFragment : Fragment() {
fun onSecuritySetupComplete()
}
+ companion object {
+ private const val ARG_CHANGE_MODE = "change_mode"
+ fun newInstance(changeMode: Boolean = false) = SecuritySetupFragment().apply {
+ arguments = android.os.Bundle().also { it.putBoolean(ARG_CHANGE_MODE, changeMode) }
+ }
+ }
+
private var _b: FragmentSecuritySetupBinding? = null
private val b get() = _b!!
@@ -38,7 +45,8 @@ class SecuritySetupFragment : Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
val prefs = requireContext().getSharedPreferences("prefs", Context.MODE_PRIVATE)
- if (prefs.getString("security_method", null) != null) {
+ val changeMode = arguments?.getBoolean(ARG_CHANGE_MODE, false) ?: false
+ if (!changeMode && prefs.getString("security_method", null) != null) {
(activity as? Callback)?.onSecuritySetupComplete()
}
@@ -69,6 +77,10 @@ class SecuritySetupFragment : Fragment() {
}
private fun buildNumpad() {
+ val dp = resources.displayMetrics.density
+ val btnSize = (68 * dp).toInt()
+ val btnMarginH = (10 * dp).toInt()
+ val rowMarginV = (6 * dp).toInt()
val rows = listOf(
listOf("1", "2", "3"),
listOf("4", "5", "6"),
@@ -78,9 +90,11 @@ class SecuritySetupFragment : Fragment() {
rows.forEach { keys ->
val row = LinearLayout(requireContext()).apply {
orientation = LinearLayout.HORIZONTAL
+ gravity = android.view.Gravity.CENTER
layoutParams = LinearLayout.LayoutParams(
- LinearLayout.LayoutParams.MATCH_PARENT, 0, 1f
- )
+ LinearLayout.LayoutParams.WRAP_CONTENT,
+ LinearLayout.LayoutParams.WRAP_CONTENT
+ ).also { it.setMargins(0, rowMarginV, 0, rowMarginV) }
}
keys.forEach { key ->
val style = if (key == "✓")
@@ -89,11 +103,12 @@ class SecuritySetupFragment : Fragment() {
com.google.android.material.R.attr.materialButtonOutlinedStyle
val btn = MaterialButton(requireContext(), null, style).apply {
text = key
- textSize = 20f
- insetTop = 0
- insetBottom = 0
- layoutParams = LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.MATCH_PARENT, 1f)
- .also { it.setMargins(4, 4, 4, 4) }
+ textSize = 24f
+ insetTop = 0; insetBottom = 0
+ minimumWidth = 0; minimumHeight = 0
+ cornerRadius = btnSize / 2
+ layoutParams = LinearLayout.LayoutParams(btnSize, btnSize)
+ .also { it.setMargins(btnMarginH, 0, btnMarginH, 0) }
}
btn.setOnClickListener { handleKey(key) }
row.addView(btn)
@@ -223,7 +238,12 @@ class SecuritySetupFragment : Fragment() {
.digest(input.toByteArray()).joinToString("") { "%02x".format(it) }
private fun finishSetup() {
- (activity as? Callback)?.onSecuritySetupComplete()
+ val cb = activity as? Callback
+ if (cb != null) {
+ cb.onSecuritySetupComplete()
+ } else {
+ parentFragmentManager.popBackStack()
+ }
}
override fun onDestroyView() {
diff --git a/app/src/main/res/drawable/ic_lock.xml b/app/src/main/res/drawable/ic_lock.xml
new file mode 100644
index 0000000..72682a1
--- /dev/null
+++ b/app/src/main/res/drawable/ic_lock.xml
@@ -0,0 +1,11 @@
+
+