diff --git a/app/src/main/java/com/bnyro/contacts/navigation/HomeNavContainer.kt b/app/src/main/java/com/bnyro/contacts/navigation/HomeNavContainer.kt index f90ddc03..44d19c58 100644 --- a/app/src/main/java/com/bnyro/contacts/navigation/HomeNavContainer.kt +++ b/app/src/main/java/com/bnyro/contacts/navigation/HomeNavContainer.kt @@ -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 @@ -38,6 +37,7 @@ val RouteSaver = Saver, Int>( @Composable fun HomeNavContainer( + enabledTabs: List, initialTab: HomeRoutes, onNavigate: (NavRoutes) -> Unit, smsModel: SmsModel, @@ -70,7 +70,7 @@ fun HomeNavContainer( NavigationBar( tonalElevation = 5.dp ) { - HomeRoutes.all.forEach { + enabledTabs.forEach { NavigationBarItem( label = { Text(stringResource(it.stringRes)) @@ -96,7 +96,7 @@ fun HomeNavContainer( ) { if (orientation == Configuration.ORIENTATION_LANDSCAPE) { NavigationRail { - HomeRoutes.all.forEach { + enabledTabs.forEach { NavigationRailItem( selected = it.route == selectedRoute, onClick = { diff --git a/app/src/main/java/com/bnyro/contacts/navigation/NavContainer.kt b/app/src/main/java/com/bnyro/contacts/navigation/NavContainer.kt index 41472879..f4a78131 100644 --- a/app/src/main/java/com/bnyro/contacts/navigation/NavContainer.kt +++ b/app/src/main/java/com/bnyro/contacts/navigation/NavContainer.kt @@ -11,6 +11,7 @@ import com.bnyro.contacts.presentation.screens.sms.model.SmsModel @Composable fun NavContainer( + enabledTabs: List, initialTab: HomeRoutes, ) { val navController = rememberNavController() @@ -19,6 +20,7 @@ fun NavContainer( val themeModel: ThemeModel = viewModel() AppNavHost( navController, + enabledTabs = enabledTabs, initialTab = initialTab, modifier = Modifier .fillMaxSize(), diff --git a/app/src/main/java/com/bnyro/contacts/navigation/NavHost.kt b/app/src/main/java/com/bnyro/contacts/navigation/NavHost.kt index 3a168bdd..97273ca9 100644 --- a/app/src/main/java/com/bnyro/contacts/navigation/NavHost.kt +++ b/app/src/main/java/com/bnyro/contacts/navigation/NavHost.kt @@ -24,6 +24,7 @@ import com.bnyro.contacts.presentation.screens.sms.model.SmsModel fun AppNavHost( navController: NavHostController, modifier: Modifier = Modifier, + enabledTabs: List, initialTab: HomeRoutes, smsModel: SmsModel, contactsModel: ContactsModel, @@ -44,6 +45,7 @@ fun AppNavHost( targetOffset = { it / 4 }) + fadeOut() }) { HomeNavContainer( + enabledTabs = enabledTabs, initialTab = initialTab, onNavigate = { navController.navigate(it) diff --git a/app/src/main/java/com/bnyro/contacts/presentation/screens/settings/SettingsScreen.kt b/app/src/main/java/com/bnyro/contacts/presentation/screens/settings/SettingsScreen.kt index 4fa63170..d44b69f0 100644 --- a/app/src/main/java/com/bnyro/contacts/presentation/screens/settings/SettingsScreen.kt +++ b/app/src/main/java/com/bnyro/contacts/presentation/screens/settings/SettingsScreen.kt @@ -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 @@ -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, diff --git a/app/src/main/java/com/bnyro/contacts/presentation/screens/settings/components/BlockPreference.kt b/app/src/main/java/com/bnyro/contacts/presentation/screens/settings/components/BlockPreference.kt index 32ad6924..087f9785 100644 --- a/app/src/main/java/com/bnyro/contacts/presentation/screens/settings/components/BlockPreference.kt +++ b/app/src/main/java/com/bnyro/contacts/presentation/screens/settings/components/BlockPreference.kt @@ -47,3 +47,45 @@ fun BlockPreference( } } } + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun MultiBlockPreference( + preferenceKey: String, + entries: List, + defaultSelections: List, + requireAtLeastOne: Boolean = true, + onSelectionChange: (List) -> 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) + } + } + } +} diff --git a/app/src/main/java/com/bnyro/contacts/ui/activities/MainActivity.kt b/app/src/main/java/com/bnyro/contacts/ui/activities/MainActivity.kt index 1ec8e0d0..d185d595 100644 --- a/app/src/main/java/com/bnyro/contacts/ui/activities/MainActivity.kt +++ b/app/src/main/java/com/bnyro/contacts/ui/activities/MainActivity.kt @@ -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() { @@ -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 @@ -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) diff --git a/app/src/main/java/com/bnyro/contacts/util/Preferences.kt b/app/src/main/java/com/bnyro/contacts/util/Preferences.kt index 6c232b8c..d260960c 100644 --- a/app/src/main/java/com/bnyro/contacts/util/Preferences.kt +++ b/app/src/main/java/com/bnyro/contacts/util/Preferences.kt @@ -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" @@ -89,6 +90,19 @@ fun rememberPreference(key: String, defaultValue: String): MutableState } } +@Composable +fun rememberPreference(key: String, defaultValue: List): MutableState> { + 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 mutableStatePreferenceOf( value: T, crossinline onStructuralInequality: (newValue: T) -> Unit diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 50e9a8f7..e1032711 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -110,6 +110,7 @@ Settings Start tab + Enabled tabs Theme System Light