forked from shihaam/thijooree
categorize settings to unclutter it.. might need to revert this later
This commit is contained in:
@@ -0,0 +1,75 @@
|
|||||||
|
package sh.sar.basedbank.ui.home
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.appcompat.app.AppCompatDelegate
|
||||||
|
import androidx.appcompat.app.AppCompatDelegate.setApplicationLocales
|
||||||
|
import androidx.core.os.LocaleListCompat
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
|
import sh.sar.basedbank.R
|
||||||
|
import sh.sar.basedbank.databinding.FragmentSettingsAppearanceBinding
|
||||||
|
|
||||||
|
class SettingsAppearanceFragment : Fragment() {
|
||||||
|
|
||||||
|
private var _binding: FragmentSettingsAppearanceBinding? = null
|
||||||
|
private val binding get() = _binding!!
|
||||||
|
|
||||||
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
|
||||||
|
_binding = FragmentSettingsAppearanceBinding.inflate(inflater, container, false)
|
||||||
|
return binding.root
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
|
val prefs = requireContext().getSharedPreferences("prefs", Context.MODE_PRIVATE)
|
||||||
|
|
||||||
|
// Navigation mode
|
||||||
|
val isBottom = prefs.getBoolean("bottom_nav", false)
|
||||||
|
binding.navModeToggle.check(if (isBottom) R.id.btnNavBottom else R.id.btnNavDrawer)
|
||||||
|
binding.navModeToggle.addOnButtonCheckedListener { _, checkedId, isChecked ->
|
||||||
|
if (!isChecked) return@addOnButtonCheckedListener
|
||||||
|
prefs.edit().putBoolean("bottom_nav", checkedId == R.id.btnNavBottom).apply()
|
||||||
|
(activity as? HomeActivity)?.applyNavMode()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Theme
|
||||||
|
val saved = prefs.getString("theme", "system")
|
||||||
|
binding.themeToggle.check(when (saved) {
|
||||||
|
"light" -> R.id.btnThemeLight
|
||||||
|
"dark" -> R.id.btnThemeDark
|
||||||
|
else -> R.id.btnThemeSystem
|
||||||
|
})
|
||||||
|
binding.themeToggle.addOnButtonCheckedListener { _, checkedId, isChecked ->
|
||||||
|
if (!isChecked) return@addOnButtonCheckedListener
|
||||||
|
val (key, mode) = when (checkedId) {
|
||||||
|
R.id.btnThemeLight -> "light" to AppCompatDelegate.MODE_NIGHT_NO
|
||||||
|
R.id.btnThemeDark -> "dark" to AppCompatDelegate.MODE_NIGHT_YES
|
||||||
|
else -> "system" to AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM
|
||||||
|
}
|
||||||
|
prefs.edit().putString("theme", key).apply()
|
||||||
|
AppCompatDelegate.setDefaultNightMode(mode)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Language
|
||||||
|
val currentLocales = AppCompatDelegate.getApplicationLocales()
|
||||||
|
val currentLang = if (currentLocales.isEmpty) "en" else currentLocales[0]?.language ?: "en"
|
||||||
|
binding.languageToggle.check(if (currentLang == "dv") R.id.btnLangDhivehi else R.id.btnLangEnglish)
|
||||||
|
binding.languageToggle.addOnButtonCheckedListener { _, checkedId, isChecked ->
|
||||||
|
if (!isChecked) return@addOnButtonCheckedListener
|
||||||
|
val tag = if (checkedId == R.id.btnLangDhivehi) "dv" else "en"
|
||||||
|
setApplicationLocales(LocaleListCompat.forLanguageTags(tag))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onResume() {
|
||||||
|
super.onResume()
|
||||||
|
requireActivity().title = getString(R.string.settings_appearance)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDestroyView() {
|
||||||
|
super.onDestroyView()
|
||||||
|
_binding = null
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,358 +1,51 @@
|
|||||||
package sh.sar.basedbank.ui.home
|
package sh.sar.basedbank.ui.home
|
||||||
|
|
||||||
import android.content.Context
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.Gravity
|
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.widget.ImageView
|
import android.widget.ImageView
|
||||||
import android.widget.LinearLayout
|
import android.widget.LinearLayout
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import android.widget.Toast
|
import androidx.annotation.DrawableRes
|
||||||
import androidx.appcompat.app.AppCompatDelegate
|
import androidx.annotation.StringRes
|
||||||
import androidx.appcompat.app.AppCompatDelegate.setApplicationLocales
|
|
||||||
import androidx.biometric.BiometricManager
|
|
||||||
import androidx.core.os.LocaleListCompat
|
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import android.content.Intent
|
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
|
||||||
import sh.sar.basedbank.BasedBankApp
|
|
||||||
import sh.sar.basedbank.R
|
import sh.sar.basedbank.R
|
||||||
import sh.sar.basedbank.api.mib.TransactionCache
|
|
||||||
import sh.sar.basedbank.databinding.FragmentSettingsBinding
|
|
||||||
import sh.sar.basedbank.ui.onboarding.SecuritySetupFragment
|
|
||||||
import sh.sar.basedbank.util.AccountCache
|
|
||||||
import sh.sar.basedbank.util.ContactImageCache
|
|
||||||
import sh.sar.basedbank.util.ContactsCache
|
|
||||||
import sh.sar.basedbank.util.CredentialStore
|
|
||||||
import sh.sar.basedbank.ui.login.LoginActivity
|
|
||||||
import sh.sar.basedbank.util.FinancingCache
|
|
||||||
import sh.sar.basedbank.util.ForeignLimitsCache
|
|
||||||
import sh.sar.basedbank.util.RecentsCache
|
|
||||||
|
|
||||||
class SettingsFragment : Fragment() {
|
class SettingsFragment : Fragment() {
|
||||||
|
|
||||||
private var _binding: FragmentSettingsBinding? = null
|
private data class SettingsItem(
|
||||||
private val binding get() = _binding!!
|
@DrawableRes val icon: Int,
|
||||||
|
@StringRes val title: Int,
|
||||||
|
val dest: () -> Fragment
|
||||||
|
)
|
||||||
|
|
||||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
|
private val items = listOf(
|
||||||
_binding = FragmentSettingsBinding.inflate(inflater, container, false)
|
SettingsItem(R.drawable.ic_contacts, R.string.settings_logins) { SettingsLoginsFragment() },
|
||||||
return binding.root
|
SettingsItem(R.drawable.ic_settings_appearance, R.string.settings_appearance) { SettingsAppearanceFragment() },
|
||||||
}
|
SettingsItem(R.drawable.ic_lock, R.string.settings_privacy_security) { SettingsSecurityFragment() },
|
||||||
|
SettingsItem(R.drawable.ic_settings_storage, R.string.settings_storage) { SettingsStorageFragment() },
|
||||||
|
)
|
||||||
|
|
||||||
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View =
|
||||||
|
inflater.inflate(R.layout.fragment_settings, container, false)
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
val prefs = requireContext().getSharedPreferences("prefs", Context.MODE_PRIVATE)
|
val list = view.findViewById<LinearLayout>(R.id.settingsList)
|
||||||
|
val inflater = LayoutInflater.from(requireContext())
|
||||||
// Navigation mode
|
for (item in items) {
|
||||||
val isBottom = prefs.getBoolean("bottom_nav", false)
|
val row = inflater.inflate(R.layout.item_more_nav, list, false)
|
||||||
binding.navModeToggle.check(if (isBottom) R.id.btnNavBottom else R.id.btnNavDrawer)
|
row.findViewById<ImageView>(R.id.ivIcon).setImageResource(item.icon)
|
||||||
binding.navModeToggle.addOnButtonCheckedListener { _, checkedId, isChecked ->
|
row.findViewById<TextView>(R.id.tvLabel).setText(item.title)
|
||||||
if (!isChecked) return@addOnButtonCheckedListener
|
row.setOnClickListener {
|
||||||
prefs.edit().putBoolean("bottom_nav", checkedId == R.id.btnNavBottom).apply()
|
(requireActivity() as HomeActivity).showWithBackStack(item.dest())
|
||||||
(activity as? HomeActivity)?.applyNavMode()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Theme
|
|
||||||
val saved = prefs.getString("theme", "system")
|
|
||||||
val initialId = when (saved) {
|
|
||||||
"light" -> R.id.btnThemeLight
|
|
||||||
"dark" -> R.id.btnThemeDark
|
|
||||||
else -> R.id.btnThemeSystem
|
|
||||||
}
|
|
||||||
binding.themeToggle.check(initialId)
|
|
||||||
|
|
||||||
binding.themeToggle.addOnButtonCheckedListener { _, checkedId, isChecked ->
|
|
||||||
if (!isChecked) return@addOnButtonCheckedListener
|
|
||||||
val (key, mode) = when (checkedId) {
|
|
||||||
R.id.btnThemeLight -> "light" to AppCompatDelegate.MODE_NIGHT_NO
|
|
||||||
R.id.btnThemeDark -> "dark" to AppCompatDelegate.MODE_NIGHT_YES
|
|
||||||
else -> "system" to AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM
|
|
||||||
}
|
}
|
||||||
prefs.edit().putString("theme", key).apply()
|
list.addView(row)
|
||||||
AppCompatDelegate.setDefaultNightMode(mode)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Language
|
|
||||||
val currentLocales = AppCompatDelegate.getApplicationLocales()
|
|
||||||
val currentLang = if (currentLocales.isEmpty) "en" else currentLocales[0]?.language ?: "en"
|
|
||||||
binding.languageToggle.check(
|
|
||||||
if (currentLang == "dv") R.id.btnLangDhivehi else R.id.btnLangEnglish
|
|
||||||
)
|
|
||||||
|
|
||||||
binding.languageToggle.addOnButtonCheckedListener { _, checkedId, isChecked ->
|
|
||||||
if (!isChecked) return@addOnButtonCheckedListener
|
|
||||||
val tag = if (checkedId == R.id.btnLangDhivehi) "dv" else "en"
|
|
||||||
setApplicationLocales(LocaleListCompat.forLanguageTags(tag))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Auto-lock
|
|
||||||
val savedTimeout = prefs.getLong("autolock_timeout", 60_000L)
|
|
||||||
binding.autolockToggle.check(when (savedTimeout) {
|
|
||||||
0L -> R.id.btnAutolockOff
|
|
||||||
30_000L -> R.id.btnAutolock30s
|
|
||||||
180_000L -> R.id.btnAutolock3m
|
|
||||||
300_000L -> R.id.btnAutolock5m
|
|
||||||
else -> R.id.btnAutolock1m
|
|
||||||
})
|
|
||||||
binding.autolockToggle.addOnButtonCheckedListener { _, checkedId, isChecked ->
|
|
||||||
if (!isChecked) return@addOnButtonCheckedListener
|
|
||||||
val timeout = when (checkedId) {
|
|
||||||
R.id.btnAutolockOff -> 0L
|
|
||||||
R.id.btnAutolock30s -> 30_000L
|
|
||||||
R.id.btnAutolock3m -> 180_000L
|
|
||||||
R.id.btnAutolock5m -> 300_000L
|
|
||||||
else -> 60_000L
|
|
||||||
}
|
|
||||||
prefs.edit().putLong("autolock_timeout", timeout).apply()
|
|
||||||
(activity as? HomeActivity)?.resetAutolockTimer()
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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.setOnCheckedChangeListener { _, isChecked ->
|
|
||||||
prefs.edit().putBoolean("biometrics_enabled", isChecked).apply()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Block screenshots
|
|
||||||
val blockScreenshots = prefs.getBoolean("block_screenshots", true)
|
|
||||||
binding.switchBlockScreenshots.isChecked = blockScreenshots
|
|
||||||
applyFlagSecure(blockScreenshots)
|
|
||||||
binding.switchBlockScreenshots.setOnCheckedChangeListener { _, isChecked ->
|
|
||||||
prefs.edit().putBoolean("block_screenshots", isChecked).apply()
|
|
||||||
applyFlagSecure(isChecked)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add account
|
|
||||||
binding.btnAddAccount.setOnClickListener {
|
|
||||||
startActivity(Intent(requireContext(), LoginActivity::class.java))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clear cache
|
|
||||||
binding.btnClearCache.setOnClickListener {
|
|
||||||
val ctx = requireContext()
|
|
||||||
clearAllCaches(ctx)
|
|
||||||
Toast.makeText(ctx, R.string.settings_cache_cleared, Toast.LENGTH_SHORT).show()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
super.onResume()
|
super.onResume()
|
||||||
requireActivity().title = getString(R.string.nav_settings)
|
requireActivity().title = getString(R.string.nav_settings)
|
||||||
val prefs = requireContext().getSharedPreferences("prefs", Context.MODE_PRIVATE)
|
|
||||||
if (binding.rowBiometrics.visibility == View.VISIBLE) {
|
|
||||||
binding.switchBiometrics.isChecked = prefs.getBoolean("biometrics_enabled", false)
|
|
||||||
}
|
|
||||||
buildLoginsSection()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onDestroyView() {
|
|
||||||
super.onDestroyView()
|
|
||||||
_binding = null
|
|
||||||
}
|
|
||||||
|
|
||||||
// ── Logins section ───────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
private fun buildLoginsSection() {
|
|
||||||
val ctx = requireContext()
|
|
||||||
val store = CredentialStore(ctx)
|
|
||||||
val container = binding.loginsContainer
|
|
||||||
container.removeAllViews()
|
|
||||||
|
|
||||||
val hasMib = store.hasMibCredentials()
|
|
||||||
val hasBml = store.hasBmlCredentials()
|
|
||||||
val hasFahipay = store.hasFahipayCredentials()
|
|
||||||
|
|
||||||
binding.tvLoginsTitle.visibility = if (hasMib || hasBml || hasFahipay) View.VISIBLE else View.GONE
|
|
||||||
|
|
||||||
if (hasMib) {
|
|
||||||
val profile = store.loadMibUserProfile()
|
|
||||||
val displayName = profile?.fullName?.takeIf { it.isNotBlank() } ?: getString(R.string.mib_name)
|
|
||||||
val profileNames = AccountCache.load(ctx)
|
|
||||||
.map { it.profileName }.filter { it.isNotBlank() }.distinct()
|
|
||||||
addLoginRow(container, R.drawable.mib_logo, displayName) {
|
|
||||||
showLoginDetails(
|
|
||||||
title = getString(R.string.mib_name),
|
|
||||||
details = buildString {
|
|
||||||
if (!profile?.fullName.isNullOrBlank()) appendLine("${getString(R.string.login_detail_name)}: ${profile!!.fullName}")
|
|
||||||
if (!profile?.email.isNullOrBlank()) appendLine("${getString(R.string.login_detail_email)}: ${profile!!.email}")
|
|
||||||
if (!profile?.mobile.isNullOrBlank()) appendLine("${getString(R.string.login_detail_mobile)}: ${profile!!.mobile}")
|
|
||||||
if (profileNames.isNotEmpty()) {
|
|
||||||
appendLine()
|
|
||||||
appendLine(getString(R.string.login_detail_profiles))
|
|
||||||
profileNames.forEach { appendLine(" • $it") }
|
|
||||||
}
|
|
||||||
}.trim(),
|
|
||||||
onLogout = { confirmLogout(getString(R.string.mib_name)) { logoutMib(store) } }
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hasBml) {
|
|
||||||
val profile = store.loadBmlUserProfile()
|
|
||||||
val displayName = profile?.fullName?.takeIf { it.isNotBlank() } ?: getString(R.string.bml_name)
|
|
||||||
val profileNames = AccountCache.loadBml(ctx)
|
|
||||||
.map { it.profileName }.filter { it.isNotBlank() }.distinct()
|
|
||||||
addLoginRow(container, R.drawable.bml_logo_vector, displayName) {
|
|
||||||
showLoginDetails(
|
|
||||||
title = getString(R.string.bml_name),
|
|
||||||
details = buildString {
|
|
||||||
if (!profile?.fullName.isNullOrBlank()) appendLine("${getString(R.string.login_detail_name)}: ${profile!!.fullName}")
|
|
||||||
if (!profile?.email.isNullOrBlank()) appendLine("${getString(R.string.login_detail_email)}: ${profile!!.email}")
|
|
||||||
if (!profile?.mobile.isNullOrBlank()) appendLine("${getString(R.string.login_detail_mobile)}: ${profile!!.mobile}")
|
|
||||||
if (!profile?.customerId.isNullOrBlank()) appendLine("${getString(R.string.login_detail_customer_id)}: ${profile!!.customerId}")
|
|
||||||
if (!profile?.idCard.isNullOrBlank()) appendLine("${getString(R.string.login_detail_id_card)}: ${profile!!.idCard}")
|
|
||||||
if (profileNames.isNotEmpty()) {
|
|
||||||
appendLine()
|
|
||||||
appendLine(getString(R.string.login_detail_profiles))
|
|
||||||
profileNames.forEach { appendLine(" • $it") }
|
|
||||||
}
|
|
||||||
}.trim(),
|
|
||||||
onLogout = { confirmLogout(getString(R.string.bml_name)) { logoutBml(store) } }
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hasFahipay) {
|
|
||||||
val profile = store.loadFahipayUserProfile()
|
|
||||||
val displayName = profile?.fullName?.takeIf { it.isNotBlank() } ?: getString(R.string.fahipay_name)
|
|
||||||
addLoginRow(container, R.drawable.fahipay_logo, displayName) {
|
|
||||||
showLoginDetails(
|
|
||||||
title = getString(R.string.fahipay_name),
|
|
||||||
details = buildString {
|
|
||||||
if (!profile?.fullName.isNullOrBlank()) appendLine("${getString(R.string.login_detail_name)}: ${profile!!.fullName}")
|
|
||||||
if (!profile?.email.isNullOrBlank()) appendLine("${getString(R.string.login_detail_email)}: ${profile!!.email}")
|
|
||||||
if (!profile?.mobile.isNullOrBlank()) appendLine("${getString(R.string.login_detail_mobile)}: ${profile!!.mobile}")
|
|
||||||
if (!profile?.nid.isNullOrBlank()) appendLine("${getString(R.string.login_detail_id_card)}: ${profile!!.nid}")
|
|
||||||
}.trim(),
|
|
||||||
onLogout = { confirmLogout(getString(R.string.fahipay_name)) { logoutFahipay(store) } }
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun addLoginRow(
|
|
||||||
container: LinearLayout,
|
|
||||||
logoRes: Int,
|
|
||||||
displayName: String,
|
|
||||||
onClick: () -> Unit
|
|
||||||
) {
|
|
||||||
val ctx = requireContext()
|
|
||||||
val dp = ctx.resources.displayMetrics.density
|
|
||||||
|
|
||||||
val row = LinearLayout(ctx).apply {
|
|
||||||
orientation = LinearLayout.HORIZONTAL
|
|
||||||
gravity = Gravity.CENTER_VERTICAL
|
|
||||||
setPadding(0, (12 * dp).toInt(), 0, (12 * dp).toInt())
|
|
||||||
isClickable = true
|
|
||||||
isFocusable = true
|
|
||||||
val ta = ctx.obtainStyledAttributes(intArrayOf(android.R.attr.selectableItemBackground))
|
|
||||||
background = ta.getDrawable(0)
|
|
||||||
ta.recycle()
|
|
||||||
setOnClickListener { onClick() }
|
|
||||||
}
|
|
||||||
|
|
||||||
val logo = ImageView(ctx).apply {
|
|
||||||
setImageResource(logoRes)
|
|
||||||
scaleType = ImageView.ScaleType.CENTER_INSIDE
|
|
||||||
layoutParams = LinearLayout.LayoutParams((36 * dp).toInt(), (36 * dp).toInt()).apply {
|
|
||||||
marginEnd = (12 * dp).toInt()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val tvName = TextView(ctx).apply {
|
|
||||||
text = displayName
|
|
||||||
setTextAppearance(com.google.android.material.R.style.TextAppearance_Material3_BodyLarge)
|
|
||||||
layoutParams = LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.WRAP_CONTENT, 1f)
|
|
||||||
}
|
|
||||||
|
|
||||||
row.addView(logo)
|
|
||||||
row.addView(tvName)
|
|
||||||
container.addView(row)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun showLoginDetails(title: String, details: String, onLogout: () -> Unit) {
|
|
||||||
MaterialAlertDialogBuilder(requireContext())
|
|
||||||
.setTitle(title)
|
|
||||||
.apply { if (details.isNotBlank()) setMessage(details) }
|
|
||||||
.setPositiveButton(R.string.close, null)
|
|
||||||
.setNegativeButton(R.string.settings_logout) { _, _ -> onLogout() }
|
|
||||||
.show()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun confirmLogout(bankName: String, onConfirm: () -> Unit) {
|
|
||||||
MaterialAlertDialogBuilder(requireContext())
|
|
||||||
.setTitle(getString(R.string.settings_logout_confirm_title, bankName))
|
|
||||||
.setMessage(R.string.settings_logout_confirm_message)
|
|
||||||
.setPositiveButton(R.string.settings_logout) { _, _ -> onConfirm() }
|
|
||||||
.setNegativeButton(R.string.cancel, null)
|
|
||||||
.show()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun logoutMib(store: CredentialStore) {
|
|
||||||
val ctx = requireContext()
|
|
||||||
store.clearMibCredentials()
|
|
||||||
ctx.getSharedPreferences("mib_prefs", Context.MODE_PRIVATE).edit().clear().apply()
|
|
||||||
val app = requireActivity().application as BasedBankApp
|
|
||||||
app.accounts = emptyList()
|
|
||||||
app.mibSession = null
|
|
||||||
app.mibProfiles = emptyList()
|
|
||||||
clearAllCaches(ctx)
|
|
||||||
(activity as HomeActivity).relogin()
|
|
||||||
buildLoginsSection()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun logoutBml(store: CredentialStore) {
|
|
||||||
val ctx = requireContext()
|
|
||||||
store.clearBmlCredentials()
|
|
||||||
store.clearBmlSession()
|
|
||||||
val app = requireActivity().application as BasedBankApp
|
|
||||||
app.bmlSession = null
|
|
||||||
app.bmlAccounts = emptyList()
|
|
||||||
clearAllCaches(ctx)
|
|
||||||
(activity as HomeActivity).relogin()
|
|
||||||
buildLoginsSection()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun logoutFahipay(store: CredentialStore) {
|
|
||||||
val ctx = requireContext()
|
|
||||||
store.clearFahipayCredentials()
|
|
||||||
store.clearFahipaySession()
|
|
||||||
val app = requireActivity().application as BasedBankApp
|
|
||||||
app.fahipaySession = null
|
|
||||||
app.fahipayAccounts = emptyList()
|
|
||||||
clearAllCaches(ctx)
|
|
||||||
(activity as HomeActivity).relogin()
|
|
||||||
buildLoginsSection()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun applyFlagSecure(enabled: Boolean) {
|
|
||||||
val win = activity?.window ?: return
|
|
||||||
if (enabled) {
|
|
||||||
win.addFlags(android.view.WindowManager.LayoutParams.FLAG_SECURE)
|
|
||||||
} else {
|
|
||||||
win.clearFlags(android.view.WindowManager.LayoutParams.FLAG_SECURE)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun clearAllCaches(ctx: Context) {
|
|
||||||
AccountCache.clear(ctx)
|
|
||||||
ContactsCache.clear(ctx)
|
|
||||||
FinancingCache.clear(ctx)
|
|
||||||
ForeignLimitsCache.clear(ctx)
|
|
||||||
RecentsCache.clear(ctx)
|
|
||||||
TransactionCache.clearAll(ctx)
|
|
||||||
ContactImageCache.clearAll(ctx)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,211 @@
|
|||||||
|
package sh.sar.basedbank.ui.home
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.Gravity
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import android.widget.ImageView
|
||||||
|
import android.widget.LinearLayout
|
||||||
|
import android.widget.TextView
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
|
import sh.sar.basedbank.BasedBankApp
|
||||||
|
import sh.sar.basedbank.R
|
||||||
|
import sh.sar.basedbank.api.mib.TransactionCache
|
||||||
|
import sh.sar.basedbank.databinding.FragmentSettingsLoginsBinding
|
||||||
|
import sh.sar.basedbank.ui.login.LoginActivity
|
||||||
|
import sh.sar.basedbank.util.AccountCache
|
||||||
|
import sh.sar.basedbank.util.ContactImageCache
|
||||||
|
import sh.sar.basedbank.util.ContactsCache
|
||||||
|
import sh.sar.basedbank.util.CredentialStore
|
||||||
|
import sh.sar.basedbank.util.FinancingCache
|
||||||
|
import sh.sar.basedbank.util.ForeignLimitsCache
|
||||||
|
import sh.sar.basedbank.util.RecentsCache
|
||||||
|
|
||||||
|
class SettingsLoginsFragment : Fragment() {
|
||||||
|
|
||||||
|
private var _binding: FragmentSettingsLoginsBinding? = null
|
||||||
|
private val binding get() = _binding!!
|
||||||
|
|
||||||
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
|
||||||
|
_binding = FragmentSettingsLoginsBinding.inflate(inflater, container, false)
|
||||||
|
return binding.root
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
|
binding.btnAddAccount.setOnClickListener {
|
||||||
|
startActivity(Intent(requireContext(), LoginActivity::class.java))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onResume() {
|
||||||
|
super.onResume()
|
||||||
|
requireActivity().title = getString(R.string.settings_logins)
|
||||||
|
buildLoginsSection()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDestroyView() {
|
||||||
|
super.onDestroyView()
|
||||||
|
_binding = null
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun buildLoginsSection() {
|
||||||
|
val ctx = requireContext()
|
||||||
|
val store = CredentialStore(ctx)
|
||||||
|
val container = binding.loginsContainer
|
||||||
|
container.removeAllViews()
|
||||||
|
|
||||||
|
val hasMib = store.hasMibCredentials()
|
||||||
|
val hasBml = store.hasBmlCredentials()
|
||||||
|
val hasFahipay = store.hasFahipayCredentials()
|
||||||
|
|
||||||
|
binding.tvLoginsTitle.visibility = if (hasMib || hasBml || hasFahipay) View.VISIBLE else View.GONE
|
||||||
|
|
||||||
|
if (hasMib) {
|
||||||
|
val profile = store.loadMibUserProfile()
|
||||||
|
val displayName = profile?.fullName?.takeIf { it.isNotBlank() } ?: getString(R.string.mib_name)
|
||||||
|
val profileNames = AccountCache.load(ctx).map { it.profileName }.filter { it.isNotBlank() }.distinct()
|
||||||
|
addLoginRow(container, R.drawable.mib_logo, displayName) {
|
||||||
|
showLoginDetails(
|
||||||
|
title = getString(R.string.mib_name),
|
||||||
|
details = buildString {
|
||||||
|
if (!profile?.fullName.isNullOrBlank()) appendLine("${getString(R.string.login_detail_name)}: ${profile!!.fullName}")
|
||||||
|
if (!profile?.email.isNullOrBlank()) appendLine("${getString(R.string.login_detail_email)}: ${profile!!.email}")
|
||||||
|
if (!profile?.mobile.isNullOrBlank()) appendLine("${getString(R.string.login_detail_mobile)}: ${profile!!.mobile}")
|
||||||
|
if (profileNames.isNotEmpty()) {
|
||||||
|
appendLine()
|
||||||
|
appendLine(getString(R.string.login_detail_profiles))
|
||||||
|
profileNames.forEach { appendLine(" • $it") }
|
||||||
|
}
|
||||||
|
}.trim(),
|
||||||
|
onLogout = { confirmLogout(getString(R.string.mib_name)) { logoutMib(store) } }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasBml) {
|
||||||
|
val profile = store.loadBmlUserProfile()
|
||||||
|
val displayName = profile?.fullName?.takeIf { it.isNotBlank() } ?: getString(R.string.bml_name)
|
||||||
|
val profileNames = AccountCache.loadBml(ctx).map { it.profileName }.filter { it.isNotBlank() }.distinct()
|
||||||
|
addLoginRow(container, R.drawable.bml_logo_vector, displayName) {
|
||||||
|
showLoginDetails(
|
||||||
|
title = getString(R.string.bml_name),
|
||||||
|
details = buildString {
|
||||||
|
if (!profile?.fullName.isNullOrBlank()) appendLine("${getString(R.string.login_detail_name)}: ${profile!!.fullName}")
|
||||||
|
if (!profile?.email.isNullOrBlank()) appendLine("${getString(R.string.login_detail_email)}: ${profile!!.email}")
|
||||||
|
if (!profile?.mobile.isNullOrBlank()) appendLine("${getString(R.string.login_detail_mobile)}: ${profile!!.mobile}")
|
||||||
|
if (!profile?.customerId.isNullOrBlank()) appendLine("${getString(R.string.login_detail_customer_id)}: ${profile!!.customerId}")
|
||||||
|
if (!profile?.idCard.isNullOrBlank()) appendLine("${getString(R.string.login_detail_id_card)}: ${profile!!.idCard}")
|
||||||
|
if (profileNames.isNotEmpty()) {
|
||||||
|
appendLine()
|
||||||
|
appendLine(getString(R.string.login_detail_profiles))
|
||||||
|
profileNames.forEach { appendLine(" • $it") }
|
||||||
|
}
|
||||||
|
}.trim(),
|
||||||
|
onLogout = { confirmLogout(getString(R.string.bml_name)) { logoutBml(store) } }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasFahipay) {
|
||||||
|
val profile = store.loadFahipayUserProfile()
|
||||||
|
val displayName = profile?.fullName?.takeIf { it.isNotBlank() } ?: getString(R.string.fahipay_name)
|
||||||
|
addLoginRow(container, R.drawable.fahipay_logo, displayName) {
|
||||||
|
showLoginDetails(
|
||||||
|
title = getString(R.string.fahipay_name),
|
||||||
|
details = buildString {
|
||||||
|
if (!profile?.fullName.isNullOrBlank()) appendLine("${getString(R.string.login_detail_name)}: ${profile!!.fullName}")
|
||||||
|
if (!profile?.email.isNullOrBlank()) appendLine("${getString(R.string.login_detail_email)}: ${profile!!.email}")
|
||||||
|
if (!profile?.mobile.isNullOrBlank()) appendLine("${getString(R.string.login_detail_mobile)}: ${profile!!.mobile}")
|
||||||
|
if (!profile?.nid.isNullOrBlank()) appendLine("${getString(R.string.login_detail_id_card)}: ${profile!!.nid}")
|
||||||
|
}.trim(),
|
||||||
|
onLogout = { confirmLogout(getString(R.string.fahipay_name)) { logoutFahipay(store) } }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun addLoginRow(container: LinearLayout, logoRes: Int, displayName: String, onClick: () -> Unit) {
|
||||||
|
val ctx = requireContext()
|
||||||
|
val dp = ctx.resources.displayMetrics.density
|
||||||
|
val row = LinearLayout(ctx).apply {
|
||||||
|
orientation = LinearLayout.HORIZONTAL
|
||||||
|
gravity = Gravity.CENTER_VERTICAL
|
||||||
|
setPadding(0, (12 * dp).toInt(), 0, (12 * dp).toInt())
|
||||||
|
isClickable = true; isFocusable = true
|
||||||
|
val ta = ctx.obtainStyledAttributes(intArrayOf(android.R.attr.selectableItemBackground))
|
||||||
|
background = ta.getDrawable(0); ta.recycle()
|
||||||
|
setOnClickListener { onClick() }
|
||||||
|
}
|
||||||
|
val logo = ImageView(ctx).apply {
|
||||||
|
setImageResource(logoRes)
|
||||||
|
scaleType = ImageView.ScaleType.CENTER_INSIDE
|
||||||
|
layoutParams = LinearLayout.LayoutParams((36 * dp).toInt(), (36 * dp).toInt()).apply { marginEnd = (12 * dp).toInt() }
|
||||||
|
}
|
||||||
|
val tvName = TextView(ctx).apply {
|
||||||
|
text = displayName
|
||||||
|
setTextAppearance(com.google.android.material.R.style.TextAppearance_Material3_BodyLarge)
|
||||||
|
layoutParams = LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.WRAP_CONTENT, 1f)
|
||||||
|
}
|
||||||
|
row.addView(logo); row.addView(tvName)
|
||||||
|
container.addView(row)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun showLoginDetails(title: String, details: String, onLogout: () -> Unit) {
|
||||||
|
MaterialAlertDialogBuilder(requireContext())
|
||||||
|
.setTitle(title)
|
||||||
|
.apply { if (details.isNotBlank()) setMessage(details) }
|
||||||
|
.setPositiveButton(R.string.close, null)
|
||||||
|
.setNegativeButton(R.string.settings_logout) { _, _ -> onLogout() }
|
||||||
|
.show()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun confirmLogout(bankName: String, onConfirm: () -> Unit) {
|
||||||
|
MaterialAlertDialogBuilder(requireContext())
|
||||||
|
.setTitle(getString(R.string.settings_logout_confirm_title, bankName))
|
||||||
|
.setMessage(R.string.settings_logout_confirm_message)
|
||||||
|
.setPositiveButton(R.string.settings_logout) { _, _ -> onConfirm() }
|
||||||
|
.setNegativeButton(R.string.cancel, null)
|
||||||
|
.show()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun logoutMib(store: CredentialStore) {
|
||||||
|
val ctx = requireContext()
|
||||||
|
store.clearMibCredentials()
|
||||||
|
ctx.getSharedPreferences("mib_prefs", Context.MODE_PRIVATE).edit().clear().apply()
|
||||||
|
val app = requireActivity().application as BasedBankApp
|
||||||
|
app.accounts = emptyList(); app.mibSession = null; app.mibProfiles = emptyList()
|
||||||
|
clearAllCaches(ctx)
|
||||||
|
(activity as HomeActivity).relogin()
|
||||||
|
buildLoginsSection()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun logoutBml(store: CredentialStore) {
|
||||||
|
val ctx = requireContext()
|
||||||
|
store.clearBmlCredentials(); store.clearBmlSession()
|
||||||
|
val app = requireActivity().application as BasedBankApp
|
||||||
|
app.bmlSession = null; app.bmlAccounts = emptyList()
|
||||||
|
clearAllCaches(ctx)
|
||||||
|
(activity as HomeActivity).relogin()
|
||||||
|
buildLoginsSection()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun logoutFahipay(store: CredentialStore) {
|
||||||
|
val ctx = requireContext()
|
||||||
|
store.clearFahipayCredentials(); store.clearFahipaySession()
|
||||||
|
val app = requireActivity().application as BasedBankApp
|
||||||
|
app.fahipaySession = null; app.fahipayAccounts = emptyList()
|
||||||
|
clearAllCaches(ctx)
|
||||||
|
(activity as HomeActivity).relogin()
|
||||||
|
buildLoginsSection()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun clearAllCaches(ctx: Context) {
|
||||||
|
AccountCache.clear(ctx); ContactsCache.clear(ctx); FinancingCache.clear(ctx)
|
||||||
|
ForeignLimitsCache.clear(ctx); RecentsCache.clear(ctx)
|
||||||
|
TransactionCache.clearAll(ctx); ContactImageCache.clearAll(ctx)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,91 @@
|
|||||||
|
package sh.sar.basedbank.ui.home
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.biometric.BiometricManager
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
|
import sh.sar.basedbank.R
|
||||||
|
import sh.sar.basedbank.databinding.FragmentSettingsSecurityBinding
|
||||||
|
import sh.sar.basedbank.ui.onboarding.SecuritySetupFragment
|
||||||
|
|
||||||
|
class SettingsSecurityFragment : Fragment() {
|
||||||
|
|
||||||
|
private var _binding: FragmentSettingsSecurityBinding? = null
|
||||||
|
private val binding get() = _binding!!
|
||||||
|
|
||||||
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
|
||||||
|
_binding = FragmentSettingsSecurityBinding.inflate(inflater, container, false)
|
||||||
|
return binding.root
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
|
val prefs = requireContext().getSharedPreferences("prefs", Context.MODE_PRIVATE)
|
||||||
|
|
||||||
|
// Change lock
|
||||||
|
binding.btnChangeLock.setOnClickListener {
|
||||||
|
(requireActivity() as HomeActivity).showWithBackStack(
|
||||||
|
SecuritySetupFragment.newInstance(changeMode = true)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Biometrics
|
||||||
|
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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Auto-lock
|
||||||
|
binding.autolockToggle.check(when (prefs.getLong("autolock_timeout", 60_000L)) {
|
||||||
|
0L -> R.id.btnAutolockOff
|
||||||
|
30_000L -> R.id.btnAutolock30s
|
||||||
|
180_000L -> R.id.btnAutolock3m
|
||||||
|
300_000L -> R.id.btnAutolock5m
|
||||||
|
else -> R.id.btnAutolock1m
|
||||||
|
})
|
||||||
|
binding.autolockToggle.addOnButtonCheckedListener { _, checkedId, isChecked ->
|
||||||
|
if (!isChecked) return@addOnButtonCheckedListener
|
||||||
|
val timeout = when (checkedId) {
|
||||||
|
R.id.btnAutolockOff -> 0L
|
||||||
|
R.id.btnAutolock30s -> 30_000L
|
||||||
|
R.id.btnAutolock3m -> 180_000L
|
||||||
|
R.id.btnAutolock5m -> 300_000L
|
||||||
|
else -> 60_000L
|
||||||
|
}
|
||||||
|
prefs.edit().putLong("autolock_timeout", timeout).apply()
|
||||||
|
(activity as? HomeActivity)?.resetAutolockTimer()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Block screenshots
|
||||||
|
val blockScreenshots = prefs.getBoolean("block_screenshots", true)
|
||||||
|
binding.switchBlockScreenshots.isChecked = blockScreenshots
|
||||||
|
applyFlagSecure(blockScreenshots)
|
||||||
|
binding.switchBlockScreenshots.setOnCheckedChangeListener { _, isChecked ->
|
||||||
|
prefs.edit().putBoolean("block_screenshots", isChecked).apply()
|
||||||
|
applyFlagSecure(isChecked)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onResume() {
|
||||||
|
super.onResume()
|
||||||
|
requireActivity().title = getString(R.string.settings_privacy_security)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDestroyView() {
|
||||||
|
super.onDestroyView()
|
||||||
|
_binding = null
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun applyFlagSecure(enabled: Boolean) {
|
||||||
|
val win = activity?.window ?: return
|
||||||
|
if (enabled) win.addFlags(android.view.WindowManager.LayoutParams.FLAG_SECURE)
|
||||||
|
else win.clearFlags(android.view.WindowManager.LayoutParams.FLAG_SECURE)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
package sh.sar.basedbank.ui.home
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import android.widget.Toast
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
|
import sh.sar.basedbank.R
|
||||||
|
import sh.sar.basedbank.api.mib.TransactionCache
|
||||||
|
import sh.sar.basedbank.databinding.FragmentSettingsStorageBinding
|
||||||
|
import sh.sar.basedbank.util.AccountCache
|
||||||
|
import sh.sar.basedbank.util.ContactImageCache
|
||||||
|
import sh.sar.basedbank.util.ContactsCache
|
||||||
|
import sh.sar.basedbank.util.FinancingCache
|
||||||
|
import sh.sar.basedbank.util.ForeignLimitsCache
|
||||||
|
import sh.sar.basedbank.util.RecentsCache
|
||||||
|
|
||||||
|
class SettingsStorageFragment : Fragment() {
|
||||||
|
|
||||||
|
private var _binding: FragmentSettingsStorageBinding? = null
|
||||||
|
private val binding get() = _binding!!
|
||||||
|
|
||||||
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
|
||||||
|
_binding = FragmentSettingsStorageBinding.inflate(inflater, container, false)
|
||||||
|
return binding.root
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
|
binding.btnClearCache.setOnClickListener {
|
||||||
|
val ctx = requireContext()
|
||||||
|
clearAllCaches(ctx)
|
||||||
|
Toast.makeText(ctx, R.string.settings_cache_cleared, Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onResume() {
|
||||||
|
super.onResume()
|
||||||
|
requireActivity().title = getString(R.string.settings_storage)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDestroyView() {
|
||||||
|
super.onDestroyView()
|
||||||
|
_binding = null
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun clearAllCaches(ctx: Context) {
|
||||||
|
AccountCache.clear(ctx); ContactsCache.clear(ctx); FinancingCache.clear(ctx)
|
||||||
|
ForeignLimitsCache.clear(ctx); RecentsCache.clear(ctx)
|
||||||
|
TransactionCache.clearAll(ctx); ContactImageCache.clearAll(ctx)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path
|
||||||
|
android:fillColor="?attr/colorOnSurfaceVariant"
|
||||||
|
android:pathData="M12,3c-4.97,0 -9,4.03 -9,9s4.03,9 9,9c0.83,0 1.5,-0.67 1.5,-1.5 0,-0.39 -0.15,-0.74 -0.39,-1.01 -0.23,-0.26 -0.38,-0.61 -0.38,-0.99 0,-0.83 0.67,-1.5 1.5,-1.5H16c2.76,0 5,-2.24 5,-5 0,-4.42 -4.03,-8 -9,-8zM6.5,12C5.67,12 5,11.33 5,10.5S5.67,9 6.5,9 8,9.67 8,10.5 7.33,12 6.5,12zM9.5,8C8.67,8 8,7.33 8,6.5S8.67,5 9.5,5 11,5.67 11,6.5 10.33,8 9.5,8zM14.5,8C13.67,8 13,7.33 13,6.5S13.67,5 14.5,5 16,5.67 16,6.5 15.33,8 14.5,8zM17.5,12C16.67,12 16,11.33 16,10.5S16.67,9 17.5,9 19,9.67 19,10.5 18.33,12 17.5,12z" />
|
||||||
|
</vector>
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path
|
||||||
|
android:fillColor="?attr/colorOnSurfaceVariant"
|
||||||
|
android:pathData="M2,20h20v-4H2v4zM4,17h2v2H4v-2zM2,4v4h20V4H2zM6,7H4V5h2v2zM2,14h20v-4H2v4zM4,11h2v2H4v-2z" />
|
||||||
|
</vector>
|
||||||
@@ -1,317 +1,16 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<ScrollView
|
<ScrollView
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:background="?attr/colorSurface">
|
android:background="?attr/colorSurface">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
|
android:id="@+id/settingsList"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:padding="16dp">
|
android:paddingTop="8dp"
|
||||||
|
android:paddingBottom="8dp" />
|
||||||
<TextView
|
|
||||||
android:id="@+id/tvLoginsTitle"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/settings_logins"
|
|
||||||
android:textAppearance="?attr/textAppearanceTitleMedium"
|
|
||||||
android:layout_marginBottom="8dp"
|
|
||||||
android:visibility="gone" />
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:id="@+id/loginsContainer"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="vertical" />
|
|
||||||
|
|
||||||
<com.google.android.material.button.MaterialButton
|
|
||||||
android:id="@+id/btnAddAccount"
|
|
||||||
style="@style/Widget.Material3.Button.OutlinedButton"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="8dp"
|
|
||||||
android:layout_marginBottom="24dp"
|
|
||||||
android:text="@string/nav_add_account" />
|
|
||||||
|
|
||||||
<!-- Navigation -->
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/settings_navigation"
|
|
||||||
android:textAppearance="?attr/textAppearanceTitleMedium"
|
|
||||||
android:layout_marginBottom="12dp" />
|
|
||||||
|
|
||||||
<com.google.android.material.button.MaterialButtonToggleGroup
|
|
||||||
android:id="@+id/navModeToggle"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginBottom="24dp"
|
|
||||||
app:singleSelection="true"
|
|
||||||
app:selectionRequired="true">
|
|
||||||
|
|
||||||
<com.google.android.material.button.MaterialButton
|
|
||||||
android:id="@+id/btnNavDrawer"
|
|
||||||
style="@style/Widget.Material3.Button.OutlinedButton"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:text="@string/settings_nav_drawer" />
|
|
||||||
|
|
||||||
<com.google.android.material.button.MaterialButton
|
|
||||||
android:id="@+id/btnNavBottom"
|
|
||||||
style="@style/Widget.Material3.Button.OutlinedButton"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:text="@string/settings_nav_bottom" />
|
|
||||||
|
|
||||||
</com.google.android.material.button.MaterialButtonToggleGroup>
|
|
||||||
|
|
||||||
<!-- Theme -->
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/theme"
|
|
||||||
android:textAppearance="?attr/textAppearanceTitleMedium"
|
|
||||||
android:layout_marginBottom="12dp" />
|
|
||||||
|
|
||||||
<com.google.android.material.button.MaterialButtonToggleGroup
|
|
||||||
android:id="@+id/themeToggle"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
app:singleSelection="true"
|
|
||||||
app:selectionRequired="true">
|
|
||||||
|
|
||||||
<com.google.android.material.button.MaterialButton
|
|
||||||
android:id="@+id/btnThemeSystem"
|
|
||||||
style="@style/Widget.Material3.Button.OutlinedButton"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:text="@string/theme_system" />
|
|
||||||
|
|
||||||
<com.google.android.material.button.MaterialButton
|
|
||||||
android:id="@+id/btnThemeLight"
|
|
||||||
style="@style/Widget.Material3.Button.OutlinedButton"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:text="@string/theme_light" />
|
|
||||||
|
|
||||||
<com.google.android.material.button.MaterialButton
|
|
||||||
android:id="@+id/btnThemeDark"
|
|
||||||
style="@style/Widget.Material3.Button.OutlinedButton"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:text="@string/theme_dark" />
|
|
||||||
|
|
||||||
</com.google.android.material.button.MaterialButtonToggleGroup>
|
|
||||||
|
|
||||||
<!-- Language -->
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/language"
|
|
||||||
android:textAppearance="?attr/textAppearanceTitleMedium"
|
|
||||||
android:layout_marginTop="24dp"
|
|
||||||
android:layout_marginBottom="12dp" />
|
|
||||||
|
|
||||||
<com.google.android.material.button.MaterialButtonToggleGroup
|
|
||||||
android:id="@+id/languageToggle"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
app:singleSelection="true"
|
|
||||||
app:selectionRequired="true">
|
|
||||||
|
|
||||||
<com.google.android.material.button.MaterialButton
|
|
||||||
android:id="@+id/btnLangEnglish"
|
|
||||||
style="@style/Widget.Material3.Button.OutlinedButton"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:text="@string/lang_english" />
|
|
||||||
|
|
||||||
<com.google.android.material.button.MaterialButton
|
|
||||||
android:id="@+id/btnLangDhivehi"
|
|
||||||
style="@style/Widget.Material3.Button.OutlinedButton"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:text="@string/lang_dhivehi" />
|
|
||||||
|
|
||||||
</com.google.android.material.button.MaterialButtonToggleGroup>
|
|
||||||
|
|
||||||
<!-- Security -->
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/settings_security"
|
|
||||||
android:textAppearance="?attr/textAppearanceTitleMedium"
|
|
||||||
android:layout_marginTop="24dp"
|
|
||||||
android:layout_marginBottom="12dp" />
|
|
||||||
|
|
||||||
<com.google.android.material.button.MaterialButton
|
|
||||||
android:id="@+id/btnChangeLock"
|
|
||||||
style="@style/Widget.Material3.Button.OutlinedButton"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/settings_change_lock" />
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:id="@+id/rowBiometrics"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="horizontal"
|
|
||||||
android:gravity="center_vertical"
|
|
||||||
android:layout_marginTop="16dp"
|
|
||||||
android:visibility="gone">
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:text="@string/settings_biometrics"
|
|
||||||
android:textAppearance="?attr/textAppearanceBodyLarge"
|
|
||||||
android:textColor="?attr/colorOnSurface" />
|
|
||||||
|
|
||||||
<com.google.android.material.materialswitch.MaterialSwitch
|
|
||||||
android:id="@+id/switchBiometrics"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content" />
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/settings_autolock"
|
|
||||||
android:textAppearance="?attr/textAppearanceBodyLarge"
|
|
||||||
android:textColor="?attr/colorOnSurface"
|
|
||||||
android:layout_marginTop="16dp"
|
|
||||||
android:layout_marginBottom="8dp" />
|
|
||||||
|
|
||||||
<com.google.android.material.button.MaterialButtonToggleGroup
|
|
||||||
android:id="@+id/autolockToggle"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
app:singleSelection="true"
|
|
||||||
app:selectionRequired="true">
|
|
||||||
|
|
||||||
<com.google.android.material.button.MaterialButton
|
|
||||||
android:id="@+id/btnAutolockOff"
|
|
||||||
style="@style/Widget.Material3.Button.OutlinedButton"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:text="@string/autolock_off" />
|
|
||||||
|
|
||||||
<com.google.android.material.button.MaterialButton
|
|
||||||
android:id="@+id/btnAutolock30s"
|
|
||||||
style="@style/Widget.Material3.Button.OutlinedButton"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:text="@string/autolock_30s" />
|
|
||||||
|
|
||||||
<com.google.android.material.button.MaterialButton
|
|
||||||
android:id="@+id/btnAutolock1m"
|
|
||||||
style="@style/Widget.Material3.Button.OutlinedButton"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:text="@string/autolock_1m" />
|
|
||||||
|
|
||||||
<com.google.android.material.button.MaterialButton
|
|
||||||
android:id="@+id/btnAutolock3m"
|
|
||||||
style="@style/Widget.Material3.Button.OutlinedButton"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:text="@string/autolock_3m" />
|
|
||||||
|
|
||||||
<com.google.android.material.button.MaterialButton
|
|
||||||
android:id="@+id/btnAutolock5m"
|
|
||||||
style="@style/Widget.Material3.Button.OutlinedButton"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:text="@string/autolock_5m" />
|
|
||||||
|
|
||||||
</com.google.android.material.button.MaterialButtonToggleGroup>
|
|
||||||
|
|
||||||
<!-- Privacy -->
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/settings_privacy"
|
|
||||||
android:textAppearance="?attr/textAppearanceTitleMedium"
|
|
||||||
android:layout_marginTop="24dp"
|
|
||||||
android:layout_marginBottom="8dp" />
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:id="@+id/rowBlockScreenshots"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="horizontal"
|
|
||||||
android:gravity="center_vertical"
|
|
||||||
android:layout_marginBottom="4dp">
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:orientation="vertical">
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/settings_block_screenshots"
|
|
||||||
android:textAppearance="?attr/textAppearanceBodyLarge"
|
|
||||||
android:textColor="?attr/colorOnSurface" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/settings_block_screenshots_desc"
|
|
||||||
android:textAppearance="?attr/textAppearanceBodySmall"
|
|
||||||
android:textColor="?attr/colorOnSurfaceVariant" />
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<com.google.android.material.materialswitch.MaterialSwitch
|
|
||||||
android:id="@+id/switchBlockScreenshots"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="8dp" />
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<!-- Cache -->
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/settings_cache"
|
|
||||||
android:textAppearance="?attr/textAppearanceTitleMedium"
|
|
||||||
android:layout_marginTop="24dp"
|
|
||||||
android:layout_marginBottom="12dp" />
|
|
||||||
|
|
||||||
<com.google.android.material.button.MaterialButton
|
|
||||||
android:id="@+id/btnClearCache"
|
|
||||||
style="@style/Widget.Material3.Button.OutlinedButton"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/settings_clear_cache" />
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
|
|||||||
@@ -0,0 +1,123 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<ScrollView
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="?attr/colorSurface">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:padding="16dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/settings_navigation"
|
||||||
|
android:textAppearance="?attr/textAppearanceTitleMedium"
|
||||||
|
android:layout_marginBottom="12dp" />
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButtonToggleGroup
|
||||||
|
android:id="@+id/navModeToggle"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginBottom="24dp"
|
||||||
|
app:singleSelection="true"
|
||||||
|
app:selectionRequired="true">
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/btnNavDrawer"
|
||||||
|
style="@style/Widget.Material3.Button.OutlinedButton"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:text="@string/settings_nav_drawer" />
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/btnNavBottom"
|
||||||
|
style="@style/Widget.Material3.Button.OutlinedButton"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:text="@string/settings_nav_bottom" />
|
||||||
|
|
||||||
|
</com.google.android.material.button.MaterialButtonToggleGroup>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/theme"
|
||||||
|
android:textAppearance="?attr/textAppearanceTitleMedium"
|
||||||
|
android:layout_marginBottom="12dp" />
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButtonToggleGroup
|
||||||
|
android:id="@+id/themeToggle"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:singleSelection="true"
|
||||||
|
app:selectionRequired="true">
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/btnThemeSystem"
|
||||||
|
style="@style/Widget.Material3.Button.OutlinedButton"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:text="@string/theme_system" />
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/btnThemeLight"
|
||||||
|
style="@style/Widget.Material3.Button.OutlinedButton"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:text="@string/theme_light" />
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/btnThemeDark"
|
||||||
|
style="@style/Widget.Material3.Button.OutlinedButton"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:text="@string/theme_dark" />
|
||||||
|
|
||||||
|
</com.google.android.material.button.MaterialButtonToggleGroup>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/language"
|
||||||
|
android:textAppearance="?attr/textAppearanceTitleMedium"
|
||||||
|
android:layout_marginTop="24dp"
|
||||||
|
android:layout_marginBottom="12dp" />
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButtonToggleGroup
|
||||||
|
android:id="@+id/languageToggle"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:singleSelection="true"
|
||||||
|
app:selectionRequired="true">
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/btnLangEnglish"
|
||||||
|
style="@style/Widget.Material3.Button.OutlinedButton"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:text="@string/lang_english" />
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/btnLangDhivehi"
|
||||||
|
style="@style/Widget.Material3.Button.OutlinedButton"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:text="@string/lang_dhivehi" />
|
||||||
|
|
||||||
|
</com.google.android.material.button.MaterialButtonToggleGroup>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</ScrollView>
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<ScrollView
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="?attr/colorSurface">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:padding="16dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tvLoginsTitle"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/settings_logins"
|
||||||
|
android:textAppearance="?attr/textAppearanceTitleMedium"
|
||||||
|
android:layout_marginBottom="8dp"
|
||||||
|
android:visibility="gone" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/loginsContainer"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical" />
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/btnAddAccount"
|
||||||
|
style="@style/Widget.Material3.Button.OutlinedButton"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:text="@string/nav_add_account" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</ScrollView>
|
||||||
@@ -0,0 +1,159 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<ScrollView
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="?attr/colorSurface">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:padding="16dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/settings_security"
|
||||||
|
android:textAppearance="?attr/textAppearanceTitleMedium"
|
||||||
|
android:layout_marginBottom="12dp" />
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/btnChangeLock"
|
||||||
|
style="@style/Widget.Material3.Button.OutlinedButton"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/settings_change_lock" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/rowBiometrics"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:visibility="gone">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:text="@string/settings_biometrics"
|
||||||
|
android:textAppearance="?attr/textAppearanceBodyLarge"
|
||||||
|
android:textColor="?attr/colorOnSurface" />
|
||||||
|
|
||||||
|
<com.google.android.material.materialswitch.MaterialSwitch
|
||||||
|
android:id="@+id/switchBiometrics"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/settings_autolock"
|
||||||
|
android:textAppearance="?attr/textAppearanceBodyLarge"
|
||||||
|
android:textColor="?attr/colorOnSurface"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:layout_marginBottom="8dp" />
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButtonToggleGroup
|
||||||
|
android:id="@+id/autolockToggle"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:singleSelection="true"
|
||||||
|
app:selectionRequired="true">
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/btnAutolockOff"
|
||||||
|
style="@style/Widget.Material3.Button.OutlinedButton"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:text="@string/autolock_off" />
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/btnAutolock30s"
|
||||||
|
style="@style/Widget.Material3.Button.OutlinedButton"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:text="@string/autolock_30s" />
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/btnAutolock1m"
|
||||||
|
style="@style/Widget.Material3.Button.OutlinedButton"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:text="@string/autolock_1m" />
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/btnAutolock3m"
|
||||||
|
style="@style/Widget.Material3.Button.OutlinedButton"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:text="@string/autolock_3m" />
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/btnAutolock5m"
|
||||||
|
style="@style/Widget.Material3.Button.OutlinedButton"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:text="@string/autolock_5m" />
|
||||||
|
|
||||||
|
</com.google.android.material.button.MaterialButtonToggleGroup>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/settings_privacy"
|
||||||
|
android:textAppearance="?attr/textAppearanceTitleMedium"
|
||||||
|
android:layout_marginTop="24dp"
|
||||||
|
android:layout_marginBottom="8dp" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/rowBlockScreenshots"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:layout_marginBottom="4dp">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/settings_block_screenshots"
|
||||||
|
android:textAppearance="?attr/textAppearanceBodyLarge"
|
||||||
|
android:textColor="?attr/colorOnSurface" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/settings_block_screenshots_desc"
|
||||||
|
android:textAppearance="?attr/textAppearanceBodySmall"
|
||||||
|
android:textColor="?attr/colorOnSurfaceVariant" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<com.google.android.material.materialswitch.MaterialSwitch
|
||||||
|
android:id="@+id/switchBlockScreenshots"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="8dp" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</ScrollView>
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<ScrollView
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="?attr/colorSurface">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:padding="16dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/settings_cache"
|
||||||
|
android:textAppearance="?attr/textAppearanceTitleMedium"
|
||||||
|
android:layout_marginBottom="12dp" />
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/btnClearCache"
|
||||||
|
style="@style/Widget.Material3.Button.OutlinedButton"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/settings_clear_cache" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</ScrollView>
|
||||||
@@ -126,6 +126,9 @@
|
|||||||
<string name="settings_navigation">Navigation</string>
|
<string name="settings_navigation">Navigation</string>
|
||||||
<string name="settings_nav_drawer">Drawer</string>
|
<string name="settings_nav_drawer">Drawer</string>
|
||||||
<string name="settings_nav_bottom">Bottom Bar</string>
|
<string name="settings_nav_bottom">Bottom Bar</string>
|
||||||
|
<string name="settings_appearance">Appearance</string>
|
||||||
|
<string name="settings_privacy_security">Privacy & Security</string>
|
||||||
|
<string name="settings_storage">Storage</string>
|
||||||
<string name="settings_logins">Logins</string>
|
<string name="settings_logins">Logins</string>
|
||||||
<string name="settings_logout">Log out</string>
|
<string name="settings_logout">Log out</string>
|
||||||
<string name="settings_logout_confirm_title">Log out of %s?</string>
|
<string name="settings_logout_confirm_title">Log out of %s?</string>
|
||||||
|
|||||||
Reference in New Issue
Block a user