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 @@ + + + + diff --git a/app/src/main/res/layout/activity_lock.xml b/app/src/main/res/layout/activity_lock.xml index 1360160..69bfb79 100644 --- a/app/src/main/res/layout/activity_lock.xml +++ b/app/src/main/res/layout/activity_lock.xml @@ -11,11 +11,16 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" - android:paddingTop="48dp" - android:paddingHorizontal="16dp" - android:paddingBottom="16dp" + android:paddingHorizontal="24dp" + android:paddingBottom="40dp" android:visibility="gone"> + + + + android:gravity="center" /> + + + + android:layout_marginBottom="24dp" /> + android:layout_height="wrap_content" + android:orientation="vertical" + android:gravity="center_horizontal" /> @@ -69,12 +79,16 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" - android:paddingTop="48dp" - android:paddingHorizontal="32dp" - android:paddingBottom="16dp" - android:gravity="center_horizontal" + android:paddingHorizontal="24dp" + android:paddingBottom="40dp" android:visibility="gone"> + + + + android:gravity="center" /> + + + + android:layout_weight="2" + android:layout_gravity="center_horizontal" /> diff --git a/app/src/main/res/layout/fragment_security_setup.xml b/app/src/main/res/layout/fragment_security_setup.xml index 15802ad..bef4fa1 100644 --- a/app/src/main/res/layout/fragment_security_setup.xml +++ b/app/src/main/res/layout/fragment_security_setup.xml @@ -138,11 +138,15 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" - android:paddingTop="32dp" - android:paddingHorizontal="16dp" - android:paddingBottom="8dp" + android:paddingHorizontal="24dp" + android:paddingBottom="40dp" android:visibility="gone"> + + + android:gravity="center" /> + + + android:layout_marginBottom="24dp" /> + android:layout_height="wrap_content" + android:orientation="vertical" + android:gravity="center_horizontal" /> @@ -196,12 +204,15 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" - android:paddingTop="32dp" - android:paddingHorizontal="32dp" - android:paddingBottom="8dp" - android:gravity="center_horizontal" + android:paddingHorizontal="24dp" + android:paddingBottom="40dp" android:visibility="gone"> + + + android:gravity="center" /> + + + android:layout_weight="2" + android:layout_gravity="center_horizontal" /> diff --git a/app/src/main/res/layout/fragment_settings.xml b/app/src/main/res/layout/fragment_settings.xml index cbf4894..5bb5cd8 100644 --- a/app/src/main/res/layout/fragment_settings.xml +++ b/app/src/main/res/layout/fragment_settings.xml @@ -85,6 +85,45 @@ + + + + + + + + + + + + diff --git a/app/src/main/res/menu/toolbar_menu.xml b/app/src/main/res/menu/toolbar_menu.xml new file mode 100644 index 0000000..3884170 --- /dev/null +++ b/app/src/main/res/menu/toolbar_menu.xml @@ -0,0 +1,11 @@ + + + + + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 6a4146a..1cd87a9 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -82,7 +82,13 @@ Transfer PayMV QR + + Lock app + + Security + Change PIN / Pattern + Use Biometrics Theme System Light