forked from shihaam/thijooree
customize quick actions and bottom bar
This commit is contained in:
@@ -8,7 +8,7 @@ import android.view.LayoutInflater
|
|||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.appcompat.app.AlertDialog
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
import androidx.core.view.ViewCompat
|
import androidx.core.view.ViewCompat
|
||||||
import androidx.core.view.WindowInsetsCompat
|
import androidx.core.view.WindowInsetsCompat
|
||||||
import androidx.core.widget.addTextChangedListener
|
import androidx.core.widget.addTextChangedListener
|
||||||
@@ -177,11 +177,11 @@ class ContactsFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun confirmDelete(contact: ContactDisplay) {
|
private fun confirmDelete(contact: ContactDisplay) {
|
||||||
AlertDialog.Builder(requireContext())
|
MaterialAlertDialogBuilder(requireContext())
|
||||||
.setTitle(R.string.contact_delete_title)
|
.setTitle(R.string.contact_delete_title)
|
||||||
.setMessage(getString(R.string.contact_delete_message, contact.name))
|
.setMessage(getString(R.string.contact_delete_message, contact.name))
|
||||||
.setPositiveButton(R.string.contact_delete) { _, _ -> deleteContact(contact) }
|
.setPositiveButton(R.string.contact_delete) { _, _ -> deleteContact(contact) }
|
||||||
.setNegativeButton(android.R.string.cancel, null)
|
.setNegativeButton(R.string.cancel, null)
|
||||||
.show()
|
.show()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
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.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.widget.Toast
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.core.view.ViewCompat
|
import androidx.core.view.ViewCompat
|
||||||
import androidx.core.view.WindowInsetsCompat
|
import androidx.core.view.WindowInsetsCompat
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
@@ -41,17 +42,25 @@ class DashboardFragment : Fragment() {
|
|||||||
insets
|
insets
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.btnTransfer.setOnClickListener {
|
|
||||||
(requireActivity() as HomeActivity).navigateTo(R.id.nav_transfer)
|
|
||||||
}
|
|
||||||
binding.btnPayMvQr.setOnClickListener {
|
|
||||||
Toast.makeText(requireContext(), R.string.work_in_progress, Toast.LENGTH_SHORT).show()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
super.onResume()
|
super.onResume()
|
||||||
requireActivity().title = getString(R.string.nav_dashboard)
|
requireActivity().title = getString(R.string.nav_dashboard)
|
||||||
|
refreshQuickActions()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun refreshQuickActions() {
|
||||||
|
val prefs = requireContext().getSharedPreferences("prefs", Context.MODE_PRIVATE)
|
||||||
|
val ids = NavCustomization.getQuickActions(prefs)
|
||||||
|
listOf(binding.btnQuickAction1, binding.btnQuickAction2).forEachIndexed { i, btn ->
|
||||||
|
val def = NavCustomization.ALL_SWAPPABLE.find { it.id == ids[i] }
|
||||||
|
if (def != null) {
|
||||||
|
btn.setText(def.titleRes)
|
||||||
|
btn.icon = ContextCompat.getDrawable(requireContext(), def.iconRes)
|
||||||
|
}
|
||||||
|
btn.setOnClickListener { (requireActivity() as HomeActivity).navigateTo(ids[i]) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateBalances(accounts: List<MibAccount>) {
|
private fun updateBalances(accounts: List<MibAccount>) {
|
||||||
|
|||||||
@@ -9,7 +9,9 @@ import android.os.Looper
|
|||||||
import android.view.Menu
|
import android.view.Menu
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
import com.google.android.material.navigation.NavigationBarView
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
|
import sh.sar.basedbank.ui.home.NavCustomization
|
||||||
import androidx.appcompat.app.AlertDialog
|
import androidx.appcompat.app.AlertDialog
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
import androidx.activity.viewModels
|
import androidx.activity.viewModels
|
||||||
@@ -108,14 +110,21 @@ class HomeActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
binding.bottomNavigation.setOnItemSelectedListener { item ->
|
binding.bottomNavigation.setOnItemSelectedListener { item ->
|
||||||
if (suppressBottomNavCallback) return@setOnItemSelectedListener true
|
if (suppressBottomNavCallback) return@setOnItemSelectedListener true
|
||||||
when (item.itemId) {
|
val frag = when (item.itemId) {
|
||||||
R.id.nav_dashboard -> { show(DashboardFragment()); true }
|
R.id.nav_dashboard -> DashboardFragment()
|
||||||
R.id.nav_accounts -> { show(AccountsFragment()); true }
|
R.id.nav_accounts -> AccountsFragment()
|
||||||
R.id.nav_contacts -> { show(ContactsFragment()); true }
|
R.id.nav_contacts -> ContactsFragment()
|
||||||
R.id.nav_transfer -> { show(TransferFragment()); true }
|
R.id.nav_transfer -> TransferFragment()
|
||||||
R.id.nav_more -> { show(MoreFragment()); true }
|
R.id.nav_more -> MoreFragment()
|
||||||
else -> false
|
R.id.nav_transfer_history -> TransferHistoryFragment()
|
||||||
|
R.id.nav_finances -> FinancingFragment()
|
||||||
|
R.id.nav_otp -> OtpFragment()
|
||||||
|
R.id.nav_settings -> SettingsFragment()
|
||||||
|
else -> null
|
||||||
}
|
}
|
||||||
|
if (frag != null) show(frag)
|
||||||
|
else Toast.makeText(this, R.string.work_in_progress, Toast.LENGTH_SHORT).show()
|
||||||
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
applyNavMode()
|
applyNavMode()
|
||||||
@@ -210,12 +219,15 @@ class HomeActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun applyNavMode() {
|
fun applyNavMode() {
|
||||||
val isBottom = getSharedPreferences("prefs", MODE_PRIVATE).getBoolean("bottom_nav", false)
|
val prefs = getSharedPreferences("prefs", MODE_PRIVATE)
|
||||||
|
val isBottom = prefs.getBoolean("bottom_nav", false)
|
||||||
if (isBottom) {
|
if (isBottom) {
|
||||||
binding.drawerLayout.setDrawerLockMode(androidx.drawerlayout.widget.DrawerLayout.LOCK_MODE_LOCKED_CLOSED)
|
binding.drawerLayout.setDrawerLockMode(androidx.drawerlayout.widget.DrawerLayout.LOCK_MODE_LOCKED_CLOSED)
|
||||||
toggle.isDrawerIndicatorEnabled = false
|
toggle.isDrawerIndicatorEnabled = false
|
||||||
supportActionBar?.setDisplayHomeAsUpEnabled(false)
|
supportActionBar?.setDisplayHomeAsUpEnabled(false)
|
||||||
binding.bottomNavigation.visibility = View.VISIBLE
|
binding.bottomNavigation.visibility = View.VISIBLE
|
||||||
|
rebuildBottomNav(prefs)
|
||||||
|
applyNavLabelVisibility()
|
||||||
} else {
|
} else {
|
||||||
binding.drawerLayout.setDrawerLockMode(androidx.drawerlayout.widget.DrawerLayout.LOCK_MODE_UNLOCKED)
|
binding.drawerLayout.setDrawerLockMode(androidx.drawerlayout.widget.DrawerLayout.LOCK_MODE_UNLOCKED)
|
||||||
toggle.isDrawerIndicatorEnabled = true
|
toggle.isDrawerIndicatorEnabled = true
|
||||||
@@ -224,6 +236,27 @@ class HomeActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun rebuildBottomNav(prefs: android.content.SharedPreferences = getSharedPreferences("prefs", MODE_PRIVATE)) {
|
||||||
|
val slots = NavCustomization.getSlots(prefs)
|
||||||
|
val menu = binding.bottomNavigation.menu
|
||||||
|
menu.clear()
|
||||||
|
menu.add(Menu.NONE, R.id.nav_dashboard, 0, R.string.nav_dashboard)
|
||||||
|
.setIcon(R.drawable.ic_nav_dashboard)
|
||||||
|
slots.forEachIndexed { i, id ->
|
||||||
|
val item = NavCustomization.ALL_SWAPPABLE.find { it.id == id } ?: return@forEachIndexed
|
||||||
|
menu.add(Menu.NONE, item.id, i + 1, item.titleRes).setIcon(item.iconRes)
|
||||||
|
}
|
||||||
|
menu.add(Menu.NONE, R.id.nav_more, 4, R.string.nav_more)
|
||||||
|
.setIcon(R.drawable.ic_nav_more)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun applyNavLabelVisibility() {
|
||||||
|
val showLabels = getSharedPreferences("prefs", MODE_PRIVATE).getBoolean("bottom_nav_show_labels", true)
|
||||||
|
binding.bottomNavigation.labelVisibilityMode =
|
||||||
|
if (showLabels) NavigationBarView.LABEL_VISIBILITY_LABELED
|
||||||
|
else NavigationBarView.LABEL_VISIBILITY_AUTO
|
||||||
|
}
|
||||||
|
|
||||||
fun navigateTo(itemId: Int, fragment: Fragment? = null) {
|
fun navigateTo(itemId: Int, fragment: Fragment? = null) {
|
||||||
val dest = fragment ?: when (itemId) {
|
val dest = fragment ?: when (itemId) {
|
||||||
R.id.nav_dashboard -> DashboardFragment()
|
R.id.nav_dashboard -> DashboardFragment()
|
||||||
@@ -238,11 +271,15 @@ class HomeActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
show(dest)
|
show(dest)
|
||||||
binding.navigationView.setCheckedItem(itemId)
|
binding.navigationView.setCheckedItem(itemId)
|
||||||
val bottomNavIds = setOf(R.id.nav_dashboard, R.id.nav_accounts, R.id.nav_contacts, R.id.nav_transfer, R.id.nav_more)
|
if (binding.bottomNavigation.visibility == View.VISIBLE) {
|
||||||
if (binding.bottomNavigation.visibility == View.VISIBLE && itemId in bottomNavIds) {
|
val bottomNavIds = (0 until binding.bottomNavigation.menu.size())
|
||||||
suppressBottomNavCallback = true
|
.map { binding.bottomNavigation.menu.getItem(it).itemId }.toSet()
|
||||||
binding.bottomNavigation.selectedItemId = itemId
|
val selectId = if (itemId in bottomNavIds) itemId else if (R.id.nav_more in bottomNavIds) R.id.nav_more else null
|
||||||
suppressBottomNavCallback = false
|
if (selectId != null) {
|
||||||
|
suppressBottomNavCallback = true
|
||||||
|
binding.bottomNavigation.selectedItemId = selectId
|
||||||
|
suppressBottomNavCallback = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
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.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
@@ -7,35 +8,23 @@ 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 androidx.annotation.DrawableRes
|
|
||||||
import androidx.annotation.StringRes
|
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import sh.sar.basedbank.R
|
import sh.sar.basedbank.R
|
||||||
|
|
||||||
class MoreFragment : Fragment() {
|
class MoreFragment : Fragment() {
|
||||||
|
|
||||||
private data class NavItem(val id: Int, @DrawableRes val icon: Int, @StringRes val title: Int)
|
|
||||||
|
|
||||||
private val items = listOf(
|
|
||||||
NavItem(R.id.nav_pay_mv_qr, R.drawable.ic_qr_scan, R.string.pay_mv_qr),
|
|
||||||
NavItem(R.id.nav_activities, R.drawable.ic_nav_activities, R.string.nav_activities),
|
|
||||||
NavItem(R.id.nav_transfer_history, R.drawable.ic_nav_transfer_history, R.string.nav_transfer_history),
|
|
||||||
NavItem(R.id.nav_finances, R.drawable.ic_nav_finances, R.string.nav_finances),
|
|
||||||
NavItem(R.id.nav_card_settings, R.drawable.ic_nav_card, R.string.nav_card_settings),
|
|
||||||
NavItem(R.id.nav_otp, R.drawable.ic_nav_otp, R.string.nav_otp),
|
|
||||||
NavItem(R.id.nav_settings, R.drawable.ic_nav_settings, R.string.nav_settings),
|
|
||||||
)
|
|
||||||
|
|
||||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View =
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View =
|
||||||
inflater.inflate(R.layout.fragment_more, container, false)
|
inflater.inflate(R.layout.fragment_more, 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 items = NavCustomization.getMoreItems(prefs)
|
||||||
val list = view.findViewById<LinearLayout>(R.id.moreList)
|
val list = view.findViewById<LinearLayout>(R.id.moreList)
|
||||||
val inflater = LayoutInflater.from(requireContext())
|
val inflater = LayoutInflater.from(requireContext())
|
||||||
for (item in items) {
|
for (item in items) {
|
||||||
val row = inflater.inflate(R.layout.item_more_nav, list, false)
|
val row = inflater.inflate(R.layout.item_more_nav, list, false)
|
||||||
row.findViewById<ImageView>(R.id.ivIcon).setImageResource(item.icon)
|
row.findViewById<ImageView>(R.id.ivIcon).setImageResource(item.iconRes)
|
||||||
row.findViewById<TextView>(R.id.tvLabel).setText(item.title)
|
row.findViewById<TextView>(R.id.tvLabel).setText(item.titleRes)
|
||||||
row.setOnClickListener { (requireActivity() as HomeActivity).navigateTo(item.id) }
|
row.setOnClickListener { (requireActivity() as HomeActivity).navigateTo(item.id) }
|
||||||
list.addView(row)
|
list.addView(row)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,61 @@
|
|||||||
|
package sh.sar.basedbank.ui.home
|
||||||
|
|
||||||
|
import android.content.SharedPreferences
|
||||||
|
import androidx.annotation.DrawableRes
|
||||||
|
import androidx.annotation.StringRes
|
||||||
|
import sh.sar.basedbank.R
|
||||||
|
|
||||||
|
object NavCustomization {
|
||||||
|
|
||||||
|
data class NavItemDef(
|
||||||
|
val id: Int,
|
||||||
|
@DrawableRes val iconRes: Int,
|
||||||
|
@StringRes val titleRes: Int
|
||||||
|
)
|
||||||
|
|
||||||
|
/** All items that can occupy either a bottom nav slot or the "More" screen. */
|
||||||
|
val ALL_SWAPPABLE = listOf(
|
||||||
|
NavItemDef(R.id.nav_accounts, R.drawable.ic_nav_accounts, R.string.nav_accounts),
|
||||||
|
NavItemDef(R.id.nav_contacts, R.drawable.ic_contacts, R.string.nav_contacts),
|
||||||
|
NavItemDef(R.id.nav_transfer, R.drawable.ic_send, R.string.transfer),
|
||||||
|
NavItemDef(R.id.nav_pay_mv_qr, R.drawable.ic_qr_scan, R.string.pay_mv_qr),
|
||||||
|
NavItemDef(R.id.nav_activities, R.drawable.ic_nav_activities, R.string.nav_activities),
|
||||||
|
NavItemDef(R.id.nav_transfer_history, R.drawable.ic_nav_transfer_history, R.string.nav_transfer_history),
|
||||||
|
NavItemDef(R.id.nav_finances, R.drawable.ic_nav_finances, R.string.nav_finances),
|
||||||
|
NavItemDef(R.id.nav_card_settings, R.drawable.ic_nav_card, R.string.nav_card_settings),
|
||||||
|
NavItemDef(R.id.nav_otp, R.drawable.ic_nav_otp, R.string.nav_otp),
|
||||||
|
NavItemDef(R.id.nav_settings, R.drawable.ic_nav_settings, R.string.nav_settings),
|
||||||
|
)
|
||||||
|
|
||||||
|
fun getSlots(prefs: SharedPreferences): List<Int> = listOf(
|
||||||
|
prefs.getInt("bottom_nav_slot_1", R.id.nav_accounts),
|
||||||
|
prefs.getInt("bottom_nav_slot_2", R.id.nav_contacts),
|
||||||
|
prefs.getInt("bottom_nav_slot_3", R.id.nav_transfer),
|
||||||
|
)
|
||||||
|
|
||||||
|
fun saveSlots(prefs: SharedPreferences, slots: List<Int>) {
|
||||||
|
prefs.edit()
|
||||||
|
.putInt("bottom_nav_slot_1", slots[0])
|
||||||
|
.putInt("bottom_nav_slot_2", slots[1])
|
||||||
|
.putInt("bottom_nav_slot_3", slots[2])
|
||||||
|
.apply()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getQuickActions(prefs: SharedPreferences): List<Int> = listOf(
|
||||||
|
prefs.getInt("quick_action_1", R.id.nav_transfer),
|
||||||
|
prefs.getInt("quick_action_2", R.id.nav_pay_mv_qr),
|
||||||
|
)
|
||||||
|
|
||||||
|
fun saveQuickActions(prefs: SharedPreferences, ids: List<Int>) {
|
||||||
|
prefs.edit()
|
||||||
|
.putInt("quick_action_1", ids[0])
|
||||||
|
.putInt("quick_action_2", ids[1])
|
||||||
|
.apply()
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Items that belong in the "More" screen — those not occupying a bottom nav slot. */
|
||||||
|
fun getMoreItems(prefs: SharedPreferences): List<NavItemDef> {
|
||||||
|
val slots = getSlots(prefs).toSet()
|
||||||
|
return ALL_SWAPPABLE.filter { it.id !in slots }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,7 +1,9 @@
|
|||||||
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.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
|
import android.view.Menu
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
|
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
|
||||||
@@ -16,7 +18,14 @@ class NavMoreSheetFragment : BottomSheetDialogFragment() {
|
|||||||
inflater.inflate(R.layout.sheet_nav_more, container, false)
|
inflater.inflate(R.layout.sheet_nav_more, container, false)
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
view.findViewById<NavigationView>(R.id.navMoreView).setNavigationItemSelectedListener { item ->
|
val prefs = requireContext().getSharedPreferences("prefs", Context.MODE_PRIVATE)
|
||||||
|
val items = NavCustomization.getMoreItems(prefs)
|
||||||
|
val navView = view.findViewById<NavigationView>(R.id.navMoreView)
|
||||||
|
navView.menu.clear()
|
||||||
|
items.forEachIndexed { i, item ->
|
||||||
|
navView.menu.add(Menu.NONE, item.id, i, item.titleRes).setIcon(item.iconRes)
|
||||||
|
}
|
||||||
|
navView.setNavigationItemSelectedListener { item ->
|
||||||
dismiss()
|
dismiss()
|
||||||
onNavigate?.invoke(item.itemId)
|
onNavigate?.invoke(item.itemId)
|
||||||
true
|
true
|
||||||
|
|||||||
@@ -1,29 +1,45 @@
|
|||||||
package sh.sar.basedbank.ui.home
|
package sh.sar.basedbank.ui.home
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.content.SharedPreferences
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
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.LinearLayout
|
||||||
|
import android.widget.ScrollView
|
||||||
|
import android.widget.TextView
|
||||||
import androidx.appcompat.app.AppCompatDelegate
|
import androidx.appcompat.app.AppCompatDelegate
|
||||||
import androidx.appcompat.app.AppCompatDelegate.setApplicationLocales
|
import androidx.appcompat.app.AppCompatDelegate.setApplicationLocales
|
||||||
import androidx.core.os.LocaleListCompat
|
import androidx.core.os.LocaleListCompat
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
|
import androidx.recyclerview.widget.ItemTouchHelper
|
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
import sh.sar.basedbank.R
|
import sh.sar.basedbank.R
|
||||||
import sh.sar.basedbank.databinding.FragmentSettingsAppearanceBinding
|
import sh.sar.basedbank.databinding.FragmentSettingsAppearanceBinding
|
||||||
|
import java.util.Collections
|
||||||
|
|
||||||
class SettingsAppearanceFragment : Fragment() {
|
class SettingsAppearanceFragment : Fragment() {
|
||||||
|
|
||||||
private var _binding: FragmentSettingsAppearanceBinding? = null
|
private var _binding: FragmentSettingsAppearanceBinding? = null
|
||||||
private val binding get() = _binding!!
|
private val binding get() = _binding!!
|
||||||
|
|
||||||
|
private lateinit var prefs: SharedPreferences
|
||||||
|
private val slots = mutableListOf<Int>()
|
||||||
|
private val quickActions = mutableListOf<Int>()
|
||||||
|
private lateinit var slotAdapter: NavItemAdapter
|
||||||
|
private lateinit var quickActionAdapter: NavItemAdapter
|
||||||
|
|
||||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
|
||||||
_binding = FragmentSettingsAppearanceBinding.inflate(inflater, container, false)
|
_binding = FragmentSettingsAppearanceBinding.inflate(inflater, container, false)
|
||||||
return binding.root
|
return binding.root
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
val prefs = requireContext().getSharedPreferences("prefs", Context.MODE_PRIVATE)
|
prefs = requireContext().getSharedPreferences("prefs", Context.MODE_PRIVATE)
|
||||||
|
|
||||||
// Navigation mode
|
// Navigation mode
|
||||||
val isBottom = prefs.getBoolean("bottom_nav", false)
|
val isBottom = prefs.getBoolean("bottom_nav", false)
|
||||||
@@ -32,8 +48,35 @@ class SettingsAppearanceFragment : Fragment() {
|
|||||||
if (!isChecked) return@addOnButtonCheckedListener
|
if (!isChecked) return@addOnButtonCheckedListener
|
||||||
prefs.edit().putBoolean("bottom_nav", checkedId == R.id.btnNavBottom).apply()
|
prefs.edit().putBoolean("bottom_nav", checkedId == R.id.btnNavBottom).apply()
|
||||||
(activity as? HomeActivity)?.applyNavMode()
|
(activity as? HomeActivity)?.applyNavMode()
|
||||||
|
updateShortcutsVisibility()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Quick actions
|
||||||
|
quickActions.clear()
|
||||||
|
quickActions.addAll(NavCustomization.getQuickActions(prefs))
|
||||||
|
quickActionAdapter = NavItemAdapter(quickActions) {
|
||||||
|
NavCustomization.saveQuickActions(prefs, quickActions)
|
||||||
|
}
|
||||||
|
setupNavItemRecyclerView(binding.rvQuickActions, quickActionAdapter, quickActions)
|
||||||
|
|
||||||
|
// Bottom bar shortcuts
|
||||||
|
slots.clear()
|
||||||
|
slots.addAll(NavCustomization.getSlots(prefs))
|
||||||
|
slotAdapter = NavItemAdapter(slots) {
|
||||||
|
NavCustomization.saveSlots(prefs, slots)
|
||||||
|
(activity as? HomeActivity)?.rebuildBottomNav(prefs)
|
||||||
|
}
|
||||||
|
setupNavItemRecyclerView(binding.rvNavSlots, slotAdapter, slots)
|
||||||
|
// Show labels toggle
|
||||||
|
val showLabels = prefs.getBoolean("bottom_nav_show_labels", true)
|
||||||
|
binding.switchShowLabels.isChecked = showLabels
|
||||||
|
binding.switchShowLabels.setOnCheckedChangeListener { _, checked ->
|
||||||
|
prefs.edit().putBoolean("bottom_nav_show_labels", checked).apply()
|
||||||
|
(activity as? HomeActivity)?.applyNavLabelVisibility()
|
||||||
|
}
|
||||||
|
|
||||||
|
updateShortcutsVisibility()
|
||||||
|
|
||||||
// Theme
|
// Theme
|
||||||
val saved = prefs.getString("theme", "system")
|
val saved = prefs.getString("theme", "system")
|
||||||
binding.themeToggle.check(when (saved) {
|
binding.themeToggle.check(when (saved) {
|
||||||
@@ -63,6 +106,95 @@ class SettingsAppearanceFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun setupNavItemRecyclerView(
|
||||||
|
rv: RecyclerView,
|
||||||
|
adapter: NavItemAdapter,
|
||||||
|
items: MutableList<Int>
|
||||||
|
) {
|
||||||
|
rv.layoutManager = LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL, false)
|
||||||
|
rv.adapter = adapter
|
||||||
|
ItemTouchHelper(object : ItemTouchHelper.SimpleCallback(
|
||||||
|
ItemTouchHelper.START or ItemTouchHelper.END, 0
|
||||||
|
) {
|
||||||
|
override fun onMove(
|
||||||
|
rv: RecyclerView,
|
||||||
|
from: RecyclerView.ViewHolder,
|
||||||
|
to: RecyclerView.ViewHolder
|
||||||
|
): Boolean {
|
||||||
|
val fromPos = from.adapterPosition
|
||||||
|
val toPos = to.adapterPosition
|
||||||
|
Collections.swap(items, fromPos, toPos)
|
||||||
|
adapter.notifyItemMoved(fromPos, toPos)
|
||||||
|
adapter.onSave()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {}
|
||||||
|
}).attachToRecyclerView(rv)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun updateShortcutsVisibility() {
|
||||||
|
val isBottom = prefs.getBoolean("bottom_nav", false)
|
||||||
|
binding.sectionBottomBarShortcuts.alpha = if (isBottom) 1f else 0.38f
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun showItemPicker(items: MutableList<Int>, slotIndex: Int, adapter: NavItemAdapter) {
|
||||||
|
if (items === slots && !prefs.getBoolean("bottom_nav", false)) return
|
||||||
|
val ctx = requireContext()
|
||||||
|
val otherIds = items.filterIndexed { i, _ -> i != slotIndex }.toSet()
|
||||||
|
val available = NavCustomization.ALL_SWAPPABLE.filter { it.id !in otherIds }
|
||||||
|
val listLayout = LinearLayout(ctx).apply { orientation = LinearLayout.VERTICAL }
|
||||||
|
val rows = available.map { item ->
|
||||||
|
LayoutInflater.from(ctx).inflate(R.layout.item_more_nav, listLayout, false).also { row ->
|
||||||
|
row.findViewById<ImageView>(R.id.ivIcon).setImageResource(item.iconRes)
|
||||||
|
row.findViewById<TextView>(R.id.tvLabel).setText(item.titleRes)
|
||||||
|
listLayout.addView(row)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val scroll = ScrollView(ctx).apply { addView(listLayout) }
|
||||||
|
var dialog: androidx.appcompat.app.AlertDialog? = null
|
||||||
|
dialog = MaterialAlertDialogBuilder(ctx)
|
||||||
|
.setTitle(R.string.settings_bottom_bar_select)
|
||||||
|
.setView(scroll)
|
||||||
|
.setNegativeButton(R.string.cancel, null)
|
||||||
|
.show()
|
||||||
|
available.forEachIndexed { i, item ->
|
||||||
|
rows[i].setOnClickListener {
|
||||||
|
items[slotIndex] = item.id
|
||||||
|
adapter.onSave()
|
||||||
|
adapter.notifyItemChanged(slotIndex)
|
||||||
|
dialog?.dismiss()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private inner class NavItemAdapter(
|
||||||
|
val items: MutableList<Int>,
|
||||||
|
val onSave: () -> Unit
|
||||||
|
) : RecyclerView.Adapter<NavItemAdapter.VH>() {
|
||||||
|
|
||||||
|
inner class VH(view: View) : RecyclerView.ViewHolder(view) {
|
||||||
|
val ivNavIcon: ImageView = view.findViewById(R.id.ivNavIcon)
|
||||||
|
val tvNavLabel: TextView = view.findViewById(R.id.tvNavLabel)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): VH {
|
||||||
|
val view = LayoutInflater.from(parent.context).inflate(R.layout.item_nav_slot, parent, false)
|
||||||
|
val itemWidth = if (parent.measuredWidth > 0) parent.measuredWidth / items.size
|
||||||
|
else RecyclerView.LayoutParams.WRAP_CONTENT
|
||||||
|
view.layoutParams = RecyclerView.LayoutParams(itemWidth, RecyclerView.LayoutParams.WRAP_CONTENT)
|
||||||
|
return VH(view)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getItemCount() = items.size
|
||||||
|
|
||||||
|
override fun onBindViewHolder(holder: VH, position: Int) {
|
||||||
|
val def = NavCustomization.ALL_SWAPPABLE.find { it.id == items[position] } ?: return
|
||||||
|
holder.ivNavIcon.setImageResource(def.iconRes)
|
||||||
|
holder.tvNavLabel.setText(def.titleRes)
|
||||||
|
holder.itemView.setOnClickListener { showItemPicker(items, holder.adapterPosition, this) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
super.onResume()
|
super.onResume()
|
||||||
requireActivity().title = getString(R.string.settings_appearance)
|
requireActivity().title = getString(R.string.settings_appearance)
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import android.widget.LinearLayout
|
|||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.appcompat.app.AlertDialog
|
import androidx.appcompat.app.AlertDialog
|
||||||
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
import androidx.biometric.BiometricManager
|
import androidx.biometric.BiometricManager
|
||||||
import androidx.biometric.BiometricPrompt
|
import androidx.biometric.BiometricPrompt
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
@@ -590,10 +591,10 @@ class TransferFragment : Fragment() {
|
|||||||
if (isSrcBml && isDestMib && currency == "USD") {
|
if (isSrcBml && isDestMib && currency == "USD") {
|
||||||
val hasBmlContact = allContacts.any { it.benefCategoryId == "BML" && it.benefAccount == resolvedAccountNumber }
|
val hasBmlContact = allContacts.any { it.benefCategoryId == "BML" && it.benefAccount == resolvedAccountNumber }
|
||||||
if (!hasBmlContact) {
|
if (!hasBmlContact) {
|
||||||
AlertDialog.Builder(requireContext())
|
MaterialAlertDialogBuilder(requireContext())
|
||||||
.setTitle(R.string.transfer_bml_contact_required_title)
|
.setTitle(R.string.transfer_bml_contact_required_title)
|
||||||
.setMessage(R.string.transfer_bml_contact_required_msg)
|
.setMessage(R.string.transfer_bml_contact_required_msg)
|
||||||
.setPositiveButton("OK", null)
|
.setPositiveButton(R.string.close, null)
|
||||||
.show()
|
.show()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -637,7 +638,7 @@ class TransferFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val dialogBuilder = AlertDialog.Builder(requireContext())
|
val dialogBuilder = MaterialAlertDialogBuilder(requireContext())
|
||||||
.setTitle(R.string.transfer)
|
.setTitle(R.string.transfer)
|
||||||
.setPositiveButton(R.string.transfer_confirm) { _, _ -> doTransfer() }
|
.setPositiveButton(R.string.transfer_confirm) { _, _ -> doTransfer() }
|
||||||
.setNegativeButton(android.R.string.cancel, null)
|
.setNegativeButton(android.R.string.cancel, null)
|
||||||
|
|||||||
@@ -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="M9,3h2v2H9V3zm4,0h2v2h-2V3zM9,7h2v2H9V7zm4,0h2v2h-2V7zM9,11h2v2H9v-2zm4,0h2v2h-2v-2zM9,15h2v2H9v-2zm4,0h2v2h-2v-2zM9,19h2v2H9v-2zm4,0h2v2h-2v-2z"/>
|
||||||
|
</vector>
|
||||||
@@ -172,33 +172,52 @@
|
|||||||
|
|
||||||
</androidx.core.widget.NestedScrollView>
|
</androidx.core.widget.NestedScrollView>
|
||||||
|
|
||||||
<!-- Action buttons fixed at bottom -->
|
<!-- Quick actions fixed at bottom -->
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/buttonBar"
|
android:id="@+id/buttonBar"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="horizontal"
|
android:orientation="vertical"
|
||||||
android:paddingHorizontal="16dp"
|
android:paddingHorizontal="16dp"
|
||||||
android:paddingTop="8dp"
|
android:paddingTop="8dp"
|
||||||
android:paddingBottom="16dp">
|
android:paddingBottom="16dp">
|
||||||
|
|
||||||
<com.google.android.material.button.MaterialButton
|
<TextView
|
||||||
android:id="@+id/btnTransfer"
|
android:layout_width="wrap_content"
|
||||||
style="@style/Widget.Material3.Button.OutlinedButton"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_weight="1"
|
android:text="@string/dashboard_quick_actions"
|
||||||
android:layout_marginEnd="8dp"
|
android:textAppearance="?attr/textAppearanceLabelMedium"
|
||||||
android:text="@string/transfer" />
|
android:textColor="?attr/colorOnSurfaceVariant"
|
||||||
|
android:layout_marginBottom="8dp" />
|
||||||
|
|
||||||
<com.google.android.material.button.MaterialButton
|
<LinearLayout
|
||||||
android:id="@+id/btnPayMvQr"
|
android:layout_width="match_parent"
|
||||||
style="@style/Widget.Material3.Button.OutlinedButton"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_weight="1"
|
android:orientation="horizontal">
|
||||||
android:layout_marginStart="8dp"
|
|
||||||
android:text="@string/pay_mv_qr" />
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/btnQuickAction1"
|
||||||
|
style="@style/Widget.Material3.Button.OutlinedButton"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:layout_marginEnd="8dp"
|
||||||
|
app:iconGravity="textStart"
|
||||||
|
app:iconSize="18dp"
|
||||||
|
app:iconPadding="8dp" />
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/btnQuickAction2"
|
||||||
|
style="@style/Widget.Material3.Button.OutlinedButton"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:layout_marginStart="8dp"
|
||||||
|
app:iconGravity="textStart"
|
||||||
|
app:iconSize="18dp"
|
||||||
|
app:iconPadding="8dp" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
|||||||
@@ -45,6 +45,69 @@
|
|||||||
|
|
||||||
</com.google.android.material.button.MaterialButtonToggleGroup>
|
</com.google.android.material.button.MaterialButtonToggleGroup>
|
||||||
|
|
||||||
|
<!-- Quick actions (always active) -->
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/dashboard_quick_actions"
|
||||||
|
android:textAppearance="?attr/textAppearanceTitleMedium"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:layout_marginBottom="12dp" />
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/rvQuickActions"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:nestedScrollingEnabled="false"
|
||||||
|
android:overScrollMode="never"
|
||||||
|
android:layout_marginBottom="16dp" />
|
||||||
|
|
||||||
|
<!-- Bottom bar shortcuts — shown only when bottom nav is active -->
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/sectionBottomBarShortcuts"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_marginBottom="8dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/settings_bottom_bar_shortcuts"
|
||||||
|
android:textAppearance="?attr/textAppearanceTitleMedium"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:layout_marginBottom="12dp" />
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/rvNavSlots"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:nestedScrollingEnabled="false"
|
||||||
|
android:overScrollMode="never" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="12dp"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:text="@string/settings_bottom_bar_show_labels"
|
||||||
|
android:textAppearance="?attr/textAppearanceTitleMedium" />
|
||||||
|
|
||||||
|
<com.google.android.material.materialswitch.MaterialSwitch
|
||||||
|
android:id="@+id/switchShowLabels"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:gravity="center"
|
||||||
|
android:paddingVertical="12dp"
|
||||||
|
android:paddingHorizontal="8dp"
|
||||||
|
android:background="?attr/selectableItemBackground">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/ivNavIcon"
|
||||||
|
android:layout_width="28dp"
|
||||||
|
android:layout_height="28dp"
|
||||||
|
android:layout_marginBottom="6dp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tvNavLabel"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textAppearance="?attr/textAppearanceLabelSmall"
|
||||||
|
android:textColor="?attr/colorOnSurface"
|
||||||
|
android:gravity="center"
|
||||||
|
android:maxLines="1"
|
||||||
|
android:ellipsize="end" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
@@ -1,8 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<com.google.android.material.navigation.NavigationView
|
<com.google.android.material.navigation.NavigationView
|
||||||
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:id="@+id/navMoreView"
|
android:id="@+id/navMoreView"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content" />
|
||||||
app:menu="@menu/more_nav_menu" />
|
|
||||||
|
|||||||
@@ -79,6 +79,7 @@
|
|||||||
<string name="work_in_progress">ތައްޔާރުވަމުން ދަނީ</string>
|
<string name="work_in_progress">ތައްޔާރުވަމުން ދަނީ</string>
|
||||||
|
|
||||||
<!-- Dashboard -->
|
<!-- Dashboard -->
|
||||||
|
<string name="dashboard_quick_actions">ހަލުވި ހަރަކާތްތައް</string>
|
||||||
<string name="balance_mvr">ޖުމްލަ MVR</string>
|
<string name="balance_mvr">ޖުމްލަ MVR</string>
|
||||||
<string name="balance_usd">ޖުމްލަ USD</string>
|
<string name="balance_usd">ޖުމްލަ USD</string>
|
||||||
<string name="card_support_wip">ކާޑް ސަޕޯޓް</string>
|
<string name="card_support_wip">ކާޑް ސަޕޯޓް</string>
|
||||||
@@ -86,6 +87,11 @@
|
|||||||
<string name="pay_mv_qr">PayMV QR</string>
|
<string name="pay_mv_qr">PayMV QR</string>
|
||||||
|
|
||||||
<!-- Settings -->
|
<!-- Settings -->
|
||||||
|
<string name="settings_bottom_bar_shortcuts">ތިރި ބާ ޝޯޓްކަޓްތައް</string>
|
||||||
|
<string name="settings_bottom_bar_select">ބަޓަން ހިޔާރު ކުރޭ</string>
|
||||||
|
<string name="settings_bottom_bar_slot_1">ތަން 1</string>
|
||||||
|
<string name="settings_bottom_bar_slot_2">ތަން 2</string>
|
||||||
|
<string name="settings_bottom_bar_slot_3">ތަން 3</string>
|
||||||
<string name="theme">ތީމް</string>
|
<string name="theme">ތީމް</string>
|
||||||
<string name="theme_system">ސިސްޓަމް</string>
|
<string name="theme_system">ސިސްޓަމް</string>
|
||||||
<string name="theme_light">ލައިޓް</string>
|
<string name="theme_light">ލައިޓް</string>
|
||||||
@@ -113,6 +119,8 @@
|
|||||||
<string name="close">ބަންދު</string>
|
<string name="close">ބަންދު</string>
|
||||||
<string name="cancel">ކެންސަލް</string>
|
<string name="cancel">ކެންސަލް</string>
|
||||||
|
|
||||||
|
<string name="settings_bottom_bar_show_labels">ބޮޓަމް ބާ ލޭބަލް އަބަދުވެސް ދެއްކުން</string>
|
||||||
|
|
||||||
<!-- Home -->
|
<!-- Home -->
|
||||||
<string name="accounts">އެކައުންޓްތައް</string>
|
<string name="accounts">އެކައުންޓްތައް</string>
|
||||||
<string name="available_balance">ލިބެން ހުރި ބެލެންސް</string>
|
<string name="available_balance">ލިބެން ހުރި ބެލެންސް</string>
|
||||||
|
|||||||
@@ -92,6 +92,7 @@
|
|||||||
|
|
||||||
<!-- Dashboard -->
|
<!-- Dashboard -->
|
||||||
<string name="dashboard_pending_finances">Pending Finances</string>
|
<string name="dashboard_pending_finances">Pending Finances</string>
|
||||||
|
<string name="dashboard_quick_actions">Quick Actions</string>
|
||||||
<string name="balance_mvr">MVR Total</string>
|
<string name="balance_mvr">MVR Total</string>
|
||||||
<string name="balance_usd">USD Total</string>
|
<string name="balance_usd">USD Total</string>
|
||||||
<string name="card_support_wip">Card Support</string>
|
<string name="card_support_wip">Card Support</string>
|
||||||
@@ -136,6 +137,12 @@
|
|||||||
<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_appearance">Appearance</string>
|
||||||
|
<string name="settings_bottom_bar_shortcuts">Bottom Bar Shortcuts</string>
|
||||||
|
<string name="settings_bottom_bar_show_labels">Always show bottom bar labels</string>
|
||||||
|
<string name="settings_bottom_bar_select">Choose button</string>
|
||||||
|
<string name="settings_bottom_bar_slot_1">Slot 1</string>
|
||||||
|
<string name="settings_bottom_bar_slot_2">Slot 2</string>
|
||||||
|
<string name="settings_bottom_bar_slot_3">Slot 3</string>
|
||||||
<string name="settings_privacy_security">Privacy & Security</string>
|
<string name="settings_privacy_security">Privacy & Security</string>
|
||||||
<string name="settings_storage">Storage</string>
|
<string name="settings_storage">Storage</string>
|
||||||
<string name="settings_logins">Logins</string>
|
<string name="settings_logins">Logins</string>
|
||||||
|
|||||||
Reference in New Issue
Block a user