Skip to content

Commit

Permalink
feat: preference to disable certain bottom bar tabs (closes #440)
Browse files Browse the repository at this point in the history
  • Loading branch information
Bnyro committed Feb 6, 2025
1 parent 9f6d247 commit 60c5529
Show file tree
Hide file tree
Showing 8 changed files with 106 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.Saver
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
Expand All @@ -38,6 +37,7 @@ val RouteSaver = Saver<MutableState<HomeRoutes>, Int>(

@Composable
fun HomeNavContainer(
enabledTabs: List<HomeNavBarItem>,
initialTab: HomeRoutes,
onNavigate: (NavRoutes) -> Unit,
smsModel: SmsModel,
Expand Down Expand Up @@ -70,7 +70,7 @@ fun HomeNavContainer(
NavigationBar(
tonalElevation = 5.dp
) {
HomeRoutes.all.forEach {
enabledTabs.forEach {
NavigationBarItem(
label = {
Text(stringResource(it.stringRes))
Expand All @@ -96,7 +96,7 @@ fun HomeNavContainer(
) {
if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
NavigationRail {
HomeRoutes.all.forEach {
enabledTabs.forEach {
NavigationRailItem(
selected = it.route == selectedRoute,
onClick = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import com.bnyro.contacts.presentation.screens.sms.model.SmsModel

@Composable
fun NavContainer(
enabledTabs: List<HomeNavBarItem>,
initialTab: HomeRoutes,
) {
val navController = rememberNavController()
Expand All @@ -19,6 +20,7 @@ fun NavContainer(
val themeModel: ThemeModel = viewModel()
AppNavHost(
navController,
enabledTabs = enabledTabs,
initialTab = initialTab,
modifier = Modifier
.fillMaxSize(),
Expand Down
2 changes: 2 additions & 0 deletions app/src/main/java/com/bnyro/contacts/navigation/NavHost.kt
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import com.bnyro.contacts.presentation.screens.sms.model.SmsModel
fun AppNavHost(
navController: NavHostController,
modifier: Modifier = Modifier,
enabledTabs: List<HomeNavBarItem>,
initialTab: HomeRoutes,
smsModel: SmsModel,
contactsModel: ContactsModel,
Expand All @@ -44,6 +45,7 @@ fun AppNavHost(
targetOffset = { it / 4 }) + fadeOut()
}) {
HomeNavContainer(
enabledTabs = enabledTabs,
initialTab = initialTab,
onNavigate = {
navController.navigate(it)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,12 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import com.bnyro.contacts.R
import com.bnyro.contacts.domain.enums.ThemeMode
import com.bnyro.contacts.navigation.HomeRoutes
import com.bnyro.contacts.presentation.components.ClickableIcon
import com.bnyro.contacts.presentation.screens.settings.components.AutoBackupPref
import com.bnyro.contacts.presentation.screens.settings.components.BlockPreference
import com.bnyro.contacts.presentation.screens.settings.components.EncryptBackupsPref
import com.bnyro.contacts.presentation.screens.settings.components.MultiBlockPreference
import com.bnyro.contacts.presentation.screens.settings.components.SettingsCategory
import com.bnyro.contacts.presentation.screens.settings.components.SwitchPref
import com.bnyro.contacts.presentation.screens.settings.components.SwitchPrefBase
Expand Down Expand Up @@ -113,12 +115,27 @@ fun SettingsScreen(themeModel: ThemeModel, smsModel: SmsModel, onBackPress: () -
color = MaterialTheme.colorScheme.surfaceVariant
)
SettingsCategory(title = stringResource(R.string.behavior))
Text(stringResource(R.string.enabled_tabs))
var enabledTabs by remember {
mutableStateOf(
Preferences.getStringSet(
Preferences.enabledTabsKey,
HomeRoutes.all.indices.map { it.toString() }.toSet()
).orEmpty().map { it.toInt() }.toList()
)
}
MultiBlockPreference(
preferenceKey = Preferences.enabledTabsKey,
entries = HomeRoutes.all.map { stringResource(it.stringRes) },
defaultSelections = enabledTabs
) {
enabledTabs = it
}
Text(stringResource(R.string.start_tab))
BlockPreference(
preferenceKey = Preferences.homeTabKey,
entries = listOf(R.string.dial, R.string.contacts, R.string.messages).map {
stringResource(it)
}
entries = HomeRoutes.all.filterIndexed { index, _ -> enabledTabs.contains(index) }
.map { stringResource(it.stringRes) }
)
SwitchPref(
prefKey = Preferences.collapseBottomBarKey,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,45 @@ fun BlockPreference(
}
}
}

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun MultiBlockPreference(
preferenceKey: String,
entries: List<String>,
defaultSelections: List<Int>,
requireAtLeastOne: Boolean = true,
onSelectionChange: (List<Int>) -> Unit = {}
) {
val scrollState = rememberScrollState()

SingleChoiceSegmentedButtonRow(
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 8.dp)
.horizontalScroll(scrollState)
) {
var selectedItems by rememberPreference(
key = preferenceKey,
defaultValue = defaultSelections
)

entries.forEachIndexed { index, entry ->
SegmentedButton(
selected = selectedItems.contains(index),
onClick = {
if (!selectedItems.contains(index)) {
selectedItems = selectedItems + index
} else if (!requireAtLeastOne || selectedItems.size > 1) {
selectedItems = selectedItems.filter { it != index }
}

onSelectionChange(selectedItems)
},
shape = SegmentedButtonDefaults.itemShape(index = index, count = entries.size)
) {
Text(entry)
}
}
}
}
29 changes: 22 additions & 7 deletions app/src/main/java/com/bnyro/contacts/ui/activities/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import com.bnyro.contacts.util.ContactsHelper
import com.bnyro.contacts.util.IntentHelper
import com.bnyro.contacts.util.Preferences
import com.bnyro.contacts.util.extension.parcelable
import com.bnyro.contacts.util.rememberPreference
import java.net.URLDecoder

class MainActivity : BaseActivity() {
Expand All @@ -44,7 +45,6 @@ class MainActivity : BaseActivity() {
contactsModel.initialContactId = getInitialContactId()
contactsModel.initialContactData = getInsertContactData()

val initialTabIndex = Preferences.getInt(Preferences.homeTabKey, 1)
setContent {
ConnectYouTheme(themeModel.themeMode) {
val context = LocalContext.current
Expand All @@ -54,18 +54,33 @@ class MainActivity : BaseActivity() {
}

if (authSuccess) {
NavContainer(HomeRoutes.all[initialTabIndex.coerceIn(0, 2)].route)
val enabledTabs by rememberPreference(
Preferences.enabledTabsKey,
HomeRoutes.all.indices.toList()
)
val initialTabIndex by rememberPreference(
Preferences.homeTabKey,
HomeRoutes.all.indexOfFirst { it.route is HomeRoutes.Contacts })

NavContainer(
enabledTabs = HomeRoutes.all.filterIndexed { index, _ ->
enabledTabs.contains(index)
},
initialTab = (HomeRoutes.all.getOrNull(initialTabIndex.takeIf {
enabledTabs.contains(it)
} ?: -1) ?: HomeRoutes.all[enabledTabs.first()]).route
)

getInsertOrEditNumber()?.let {
var showAddToContactDialog by remember {
mutableStateOf(true)
}

if (showAddToContactDialog) {
AddToContactDialog(it) {
showAddToContactDialog = false
}
}
if (showAddToContactDialog) {
AddToContactDialog(it) {
showAddToContactDialog = false
}
}
}
getSharedVcfUri()?.let {
ConfirmImportContactsDialog(contactsModel, it)
Expand Down
14 changes: 14 additions & 0 deletions app/src/main/java/com/bnyro/contacts/util/Preferences.kt
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ object Preferences {
private const val prefFile = "preferences"
private lateinit var preferences: SharedPreferences

const val enabledTabsKey = "enabledTabs"
const val homeTabKey = "homeTab"
const val selectedContactsRepo = "selectedContactsRepo"
const val themeKey = "theme"
Expand Down Expand Up @@ -89,6 +90,19 @@ fun rememberPreference(key: String, defaultValue: String): MutableState<String>
}
}

@Composable
fun rememberPreference(key: String, defaultValue: List<Int>): MutableState<List<Int>> {
val defaultSet = defaultValue.map { it.toString() }.toSet()

return remember {
mutableStatePreferenceOf(
Preferences.getStringSet(key, defaultSet)?.map { it.toInt() } ?: defaultValue
) {
Preferences.edit { putStringSet(key, it.map { value -> value.toString() }.toSet()) }
}
}
}

inline fun <T> mutableStatePreferenceOf(
value: T,
crossinline onStructuralInequality: (newValue: T) -> Unit
Expand Down
1 change: 1 addition & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@
<!-- Settings -->
<string name="settings">Settings</string>
<string name="start_tab">Start tab</string>
<string name="enabled_tabs">Enabled tabs</string>
<string name="theme">Theme</string>
<string name="system">System</string>
<string name="light">Light</string>
Expand Down

0 comments on commit 60c5529

Please sign in to comment.