diff --git a/app/src/main/java/org/cis_india/wsreader/helpers/Preferencesutils.kt b/app/src/main/java/org/cis_india/wsreader/helpers/Preferencesutils.kt index 899fe74..ef63f18 100644 --- a/app/src/main/java/org/cis_india/wsreader/helpers/Preferencesutils.kt +++ b/app/src/main/java/org/cis_india/wsreader/helpers/Preferencesutils.kt @@ -39,6 +39,11 @@ class PreferenceUtil(context: Context) { // Temporary preference keys const val LIBRARY_ONBOARDING_BOOL = "show_library_onboarding" + const val HOME_ONBOARDING_BOOL = "show_home_onboarding" + const val NAV_ONBOARDING_BOOL = "show_nav_onboarding" + + const val FIRST_ONBOARDING_BOOL = "first_onboarding" + const val LIBRARY_SWIPE_TOOLTIP_BOOL = "show_library_tooltip" } diff --git a/app/src/main/java/org/cis_india/wsreader/ui/navigation/BottomBarScreen.kt b/app/src/main/java/org/cis_india/wsreader/ui/navigation/BottomBarScreen.kt index 21ddce7..46d7897 100644 --- a/app/src/main/java/org/cis_india/wsreader/ui/navigation/BottomBarScreen.kt +++ b/app/src/main/java/org/cis_india/wsreader/ui/navigation/BottomBarScreen.kt @@ -21,29 +21,39 @@ import org.cis_india.wsreader.R sealed class BottomBarScreen( val route: String, val title: Int, - val icon: Int + val icon: Int, + val tap_target_coodinator_title: Int, + val tap_target_coodinator_description: Int, ) { data object Home : BottomBarScreen( route = "home", title = R.string.navigation_home, - icon = R.drawable.ic_nav_home + icon = R.drawable.ic_nav_home, + tap_target_coodinator_title = R.string.home_tap_target_coodinator_title, + tap_target_coodinator_description = R.string.home_tap_target_coodinator_description ) data object Categories : BottomBarScreen( route = "categories", title = R.string.navigation_categories, - icon = R.drawable.ic_nav_categories + icon = R.drawable.ic_nav_categories, + tap_target_coodinator_title = R.string.category_tap_target_coodinator_title, + tap_target_coodinator_description = R.string.category_tap_target_coodinator_description ) data object Library : BottomBarScreen( route = "library", title = R.string.navigation_library, - icon = R.drawable.ic_nav_library + icon = R.drawable.ic_nav_library, + tap_target_coodinator_title = R.string.library_tap_target_coodinator_title, + tap_target_coodinator_description = R.string.library_tap_target_coodinator_description ) data object Settings : BottomBarScreen( route = "settings", title = R.string.navigation_settings, - icon = R.drawable.ic_nav_settings + icon = R.drawable.ic_nav_settings, + tap_target_coodinator_title = R.string.settings_tap_target_coodinator_title, + tap_target_coodinator_description = R.string.settings_tap_target_coodinator_description ) } \ No newline at end of file diff --git a/app/src/main/java/org/cis_india/wsreader/ui/navigation/NavGraph.kt b/app/src/main/java/org/cis_india/wsreader/ui/navigation/NavGraph.kt index 1b4fc4d..164dcde 100644 --- a/app/src/main/java/org/cis_india/wsreader/ui/navigation/NavGraph.kt +++ b/app/src/main/java/org/cis_india/wsreader/ui/navigation/NavGraph.kt @@ -34,6 +34,7 @@ import org.cis_india.wsreader.ui.screens.library.composables.LibraryScreen import org.cis_india.wsreader.ui.screens.settings.composables.AboutScreen import org.cis_india.wsreader.ui.screens.settings.composables.OSLScreen import org.cis_india.wsreader.ui.screens.settings.composables.SettingsScreen +import org.cis_india.wsreader.ui.screens.settings.viewmodels.SettingsViewModel import org.cis_india.wsreader.ui.screens.welcome.composables.WelcomeScreen @@ -42,6 +43,7 @@ fun NavGraph( startDestination: String, navController: NavHostController, networkStatus: NetworkObserver.Status, + settingsViewModel: SettingsViewModel ) { NavHost( navController = navController, @@ -72,7 +74,7 @@ fun NavGraph( } else bottomNavPopEnter() }, popExitTransition = { bottomNavPopExit() }) { - HomeScreen(navController, networkStatus) + HomeScreen(navController, networkStatus, settingsViewModel) } /** Book Detail Screen */ diff --git a/app/src/main/java/org/cis_india/wsreader/ui/screens/home/composables/HomeScreen.kt b/app/src/main/java/org/cis_india/wsreader/ui/screens/home/composables/HomeScreen.kt index 0c117c6..d8586cc 100644 --- a/app/src/main/java/org/cis_india/wsreader/ui/screens/home/composables/HomeScreen.kt +++ b/app/src/main/java/org/cis_india/wsreader/ui/screens/home/composables/HomeScreen.kt @@ -74,6 +74,7 @@ import androidx.compose.ui.platform.LocalFocusManager import androidx.compose.ui.platform.LocalSoftwareKeyboardController import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.vectorResource +import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.input.ImeAction import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp @@ -82,6 +83,10 @@ import androidx.hilt.navigation.compose.hiltViewModel import androidx.navigation.NavController import androidx.navigation.compose.currentBackStackEntryAsState import androidx.navigation.compose.rememberNavController +import com.psoffritti.taptargetcompose.TapTargetCoordinator +import com.psoffritti.taptargetcompose.TapTargetScope +import com.psoffritti.taptargetcompose.TapTargetStyle +import com.psoffritti.taptargetcompose.TextDefinition import org.cis_india.wsreader.R import org.cis_india.wsreader.helpers.NetworkObserver import org.cis_india.wsreader.helpers.book.BookLanguage @@ -102,11 +107,12 @@ import org.cis_india.wsreader.ui.screens.main.bottomNavPadding import org.cis_india.wsreader.ui.theme.pacificoFont import org.cis_india.wsreader.ui.theme.poppinsFont import kotlinx.coroutines.delay +import org.cis_india.wsreader.ui.screens.settings.viewmodels.SettingsViewModel import java.util.Locale @Composable -fun HomeScreen(navController: NavController, networkStatus: NetworkObserver.Status) { +fun HomeScreen(navController: NavController, networkStatus: NetworkObserver.Status, settingsViewModel: SettingsViewModel = hiltViewModel()) { val viewModel: HomeViewModel = hiltViewModel() @@ -142,6 +148,18 @@ fun HomeScreen(navController: NavController, networkStatus: NetworkObserver.Stat } } + val showHomeTapTargets = remember { mutableStateOf(false) } + + + LaunchedEffect(settingsViewModel.showHomeOnboardingTapTargets.value) { + delay(500) // Delay to prevent flickering + if(settingsViewModel.showHomeOnboardingTapTargets.value) { + showHomeTapTargets.value = true + }else{ + showHomeTapTargets.value = false + } + } + val showLanguageSheet = remember { mutableStateOf(false) } BookLanguageSheet( showBookLanguage = showLanguageSheet, @@ -156,21 +174,27 @@ fun HomeScreen(navController: NavController, networkStatus: NetworkObserver.Stat onSortOptionChange = { viewModel.onAction(UserAction.SortOptionClicked(it)) } ) - HomeScreenScaffold( - viewModel = viewModel, - networkStatus = networkStatus, - navController = navController, - sysBackButtonState = sysBackButtonState, - showLanguageSheet = showLanguageSheet, - showSortSheet = showSortSheet - ) + TapTargetCoordinator( + showTapTargets = showHomeTapTargets.value, + onComplete = { settingsViewModel.homeOnboardingComplete() } + ) { + + HomeScreenScaffold( + viewModel = viewModel, + networkStatus = networkStatus, + navController = navController, + sysBackButtonState = sysBackButtonState, + showLanguageSheet = showLanguageSheet, + showSortSheet = showSortSheet + ) + } } @Composable -private fun HomeScreenScaffold( +private fun TapTargetScope.HomeScreenScaffold( viewModel: HomeViewModel, networkStatus: NetworkObserver.Status, navController: NavController, @@ -429,53 +453,121 @@ private fun SearchBookList(searchBarState: SearchBarState, navController: NavCon } @Composable -private fun HomeTopAppBar( +private fun TapTargetScope.HomeTopAppBar( bookLanguage: BookLanguage, onSearchIconClicked: () -> Unit, onLanguageIconClicked: () -> Unit, onSortIconClicked: () -> Unit ) { - Row( - modifier = Modifier - .fillMaxWidth() - .windowInsetsPadding(WindowInsets.statusBars), - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.SpaceBetween - ) { - Text( - text = if (bookLanguage == BookLanguage.AllBooks) - stringResource(id = R.string.home_header) else Locale(bookLanguage.isoCode).getDisplayLanguage(Locale.getDefault()), - fontSize = 28.sp, - color = MaterialTheme.colorScheme.onBackground, - fontFamily = pacificoFont - ) - Spacer(modifier = Modifier.weight(1f)) - IconButton(onClick = onLanguageIconClicked) { - Icon( - imageVector = Icons.Filled.Translate, - contentDescription = stringResource(id = R.string.home_language_icon_desc), - tint = MaterialTheme.colorScheme.onBackground, - modifier = Modifier.size(30.dp) - ) - } - IconButton(onClick = onSortIconClicked) { - Icon( - imageVector = Icons.Filled.Sort, - contentDescription = stringResource(id = R.string.home_sort_icon_desc), - tint = MaterialTheme.colorScheme.onBackground, - modifier = Modifier.size(30.dp) - ) - } - IconButton(onClick = onSearchIconClicked) { - Icon( - imageVector = ImageVector.vectorResource(id = R.drawable.ic_search), - contentDescription = stringResource(id = R.string.home_search_icon_desc), - tint = MaterialTheme.colorScheme.onBackground, - modifier = Modifier.size(30.dp) + + Row( + modifier = Modifier + .fillMaxWidth() + .windowInsetsPadding(WindowInsets.statusBars), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.SpaceBetween + ) { + Text( + text = if (bookLanguage == BookLanguage.AllBooks) + stringResource(id = R.string.home_header) else Locale(bookLanguage.isoCode).getDisplayLanguage(Locale.getDefault()), + fontSize = 28.sp, + color = MaterialTheme.colorScheme.onBackground, + fontFamily = pacificoFont ) + Spacer(modifier = Modifier.weight(1f)) + IconButton( + onClick = onLanguageIconClicked, + modifier = Modifier.tapTarget( + precedence = 0, + title = TextDefinition( + text = stringResource(R.string.language_guide_title), + textStyle = MaterialTheme.typography.titleLarge, + fontWeight = FontWeight.Bold, + color = MaterialTheme.colorScheme.onSecondaryContainer + ), + description = TextDefinition( + text = stringResource(R.string.language_guide_description), + textStyle = MaterialTheme.typography.bodyMedium, + color = MaterialTheme.colorScheme.onSecondaryContainer + ), + tapTargetStyle = TapTargetStyle( + backgroundColor = MaterialTheme.colorScheme.secondaryContainer, + tapTargetHighlightColor = MaterialTheme.colorScheme.onSecondaryContainer, + backgroundAlpha = 1f, + ), + ), + ) { + Icon( + imageVector = Icons.Filled.Translate, + contentDescription = stringResource(id = R.string.home_language_icon_desc), + tint = MaterialTheme.colorScheme.onBackground, + modifier = Modifier.size(30.dp) + ) + } + + + IconButton( + onClick = onSortIconClicked, + modifier = Modifier.tapTarget( + precedence = 1, + title = TextDefinition( + text = stringResource(R.string.sorting_guide_title), + textStyle = MaterialTheme.typography.titleLarge, + fontWeight = FontWeight.Bold, + color = MaterialTheme.colorScheme.onSecondaryContainer + ), + description = TextDefinition( + text = stringResource(R.string.sorting_guide_description), + textStyle = MaterialTheme.typography.bodyMedium, + color = MaterialTheme.colorScheme.onSecondaryContainer + ), + tapTargetStyle = TapTargetStyle( + backgroundColor = MaterialTheme.colorScheme.secondaryContainer, + tapTargetHighlightColor = MaterialTheme.colorScheme.onSecondaryContainer, + backgroundAlpha = 1f, + ), + ), + ) { + Icon( + imageVector = Icons.Filled.Sort, + contentDescription = stringResource(id = R.string.home_sort_icon_desc), + tint = MaterialTheme.colorScheme.onBackground, + modifier = Modifier.size(30.dp) + ) + } + + + IconButton( + onClick = onSearchIconClicked, + modifier = Modifier.tapTarget( + precedence = 2, + title = TextDefinition( + text = stringResource(R.string.search_guide_title), + textStyle = MaterialTheme.typography.titleLarge, + fontWeight = FontWeight.Bold, + color = MaterialTheme.colorScheme.onSecondaryContainer + ), + description = TextDefinition( + text = stringResource(R.string.search_guide_description), + textStyle = MaterialTheme.typography.bodyMedium, + color = MaterialTheme.colorScheme.onSecondaryContainer + ), + tapTargetStyle = TapTargetStyle( + backgroundColor = MaterialTheme.colorScheme.secondaryContainer, + tapTargetHighlightColor = MaterialTheme.colorScheme.onSecondaryContainer, + backgroundAlpha = 1f, + ), + ), + ) { + Icon( + imageVector = ImageVector.vectorResource(id = R.drawable.ic_search), + contentDescription = stringResource(id = R.string.home_search_icon_desc), + tint = MaterialTheme.colorScheme.onBackground, + modifier = Modifier.size(30.dp) + ) + } } } -} @Composable @@ -552,5 +644,7 @@ private fun SearchAppBar( @Composable @Preview(showBackground = true) fun HomeScreenPreview() { - HomeScreen(navController = rememberNavController(), NetworkObserver.Status.Unavailable) + TapTargetCoordinator(showTapTargets = true, onComplete = {}) { + HomeScreen(navController = rememberNavController(), NetworkObserver.Status.Unavailable) + } } \ No newline at end of file diff --git a/app/src/main/java/org/cis_india/wsreader/ui/screens/main/MainScreen.kt b/app/src/main/java/org/cis_india/wsreader/ui/screens/main/MainScreen.kt index a662ebf..8389732 100644 --- a/app/src/main/java/org/cis_india/wsreader/ui/screens/main/MainScreen.kt +++ b/app/src/main/java/org/cis_india/wsreader/ui/screens/main/MainScreen.kt @@ -49,18 +49,26 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.vectorResource +import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp +import androidx.hilt.navigation.compose.hiltViewModel import androidx.navigation.NavController import androidx.navigation.NavGraph.Companion.findStartDestination import androidx.navigation.NavHostController import androidx.navigation.compose.currentBackStackEntryAsState import androidx.navigation.compose.rememberNavController +import com.psoffritti.taptargetcompose.TapTargetCoordinator +import com.psoffritti.taptargetcompose.TapTargetScope +import com.psoffritti.taptargetcompose.TapTargetStyle +import com.psoffritti.taptargetcompose.TextDefinition import org.cis_india.wsreader.MainViewModel +import org.cis_india.wsreader.R import org.cis_india.wsreader.helpers.NetworkObserver import org.cis_india.wsreader.ui.navigation.BottomBarScreen import org.cis_india.wsreader.ui.navigation.NavGraph import org.cis_india.wsreader.ui.navigation.Screens +import org.cis_india.wsreader.ui.screens.settings.viewmodels.SettingsViewModel import org.cis_india.wsreader.ui.theme.poppinsFont /** @@ -70,21 +78,42 @@ val bottomNavPadding = 70.dp @SuppressLint("UnusedMaterial3ScaffoldPaddingParameter") @Composable -fun MainScreen( +fun MainScreen( intent: Intent, startDestination: String, networkStatus: NetworkObserver.Status, ) { + val settingsViewModel: SettingsViewModel = hiltViewModel() + val navController = rememberNavController() + + + val showNavTapTargets = remember { mutableStateOf(false) } + + + LaunchedEffect(settingsViewModel.showNavOnboardingTapTargets.value) { + if(settingsViewModel.showNavOnboardingTapTargets.value) { + showNavTapTargets.value = true + }else{ + showNavTapTargets.value = false + } + } + Scaffold( bottomBar = { - BottomBar(navController = navController) + TapTargetCoordinator( + showTapTargets = showNavTapTargets.value, + onComplete = {settingsViewModel.navOnboardingComplete()} + ) { + BottomBar(navController = navController) + } }, containerColor = MaterialTheme.colorScheme.background ) { NavGraph( startDestination = startDestination, navController = navController, - networkStatus = networkStatus + networkStatus = networkStatus, + settingsViewModel= settingsViewModel ) val shouldHandleShortCut = remember { mutableStateOf(false) } @@ -98,7 +127,7 @@ fun MainScreen( } @Composable -private fun BottomBar(navController: NavHostController) { +private fun TapTargetScope.BottomBar(navController: NavHostController) { val screens = listOf( BottomBarScreen.Home, BottomBarScreen.Categories, @@ -115,33 +144,37 @@ private fun BottomBar(navController: NavHostController) { enter = slideInVertically(initialOffsetY = { it }), exit = slideOutVertically(targetOffsetY = { it }), content = { - Row( - modifier = Modifier - .background(MaterialTheme.colorScheme.surfaceColorAtElevation(3.dp)) - .padding(12.dp) - .fillMaxWidth() - .windowInsetsPadding(WindowInsets.navigationBars), - horizontalArrangement = Arrangement.SpaceAround, - verticalAlignment = Alignment.CenterVertically, - ) { - screens.forEach { screen -> - CustomBottomNavigationItem( - screen = screen, isSelected = screen.route == currentDestination?.route - ) { - navController.navigate(screen.route) { - popUpTo(navController.graph.findStartDestination().id) - launchSingleTop = true + + Row( + modifier = Modifier + .background(MaterialTheme.colorScheme.surfaceColorAtElevation(3.dp)) + .padding(12.dp) + .fillMaxWidth() + .windowInsetsPadding(WindowInsets.navigationBars), + horizontalArrangement = Arrangement.SpaceAround, + verticalAlignment = Alignment.CenterVertically, + ) { + screens.forEachIndexed { index, screen -> + CustomBottomNavigationItem( + screen = screen, + isSelected = screen.route == currentDestination?.route, + index = index // used in tab target order. + ) { + navController.navigate(screen.route) { + popUpTo(navController.graph.findStartDestination().id) + launchSingleTop = true + } } } } - } }) } @Composable -private fun CustomBottomNavigationItem( +private fun TapTargetScope.CustomBottomNavigationItem( screen: BottomBarScreen, isSelected: Boolean, + index: Int, onClick: () -> Unit, ) { val background = @@ -156,7 +189,25 @@ private fun CustomBottomNavigationItem( .clickable(onClick = onClick) ) { Row( - modifier = Modifier.padding(12.dp), + modifier = Modifier.tapTarget( + precedence = index, + title = TextDefinition( + text = stringResource(screen.tap_target_coodinator_title), + textStyle = MaterialTheme.typography.titleLarge, + fontWeight = FontWeight.Bold, + color = MaterialTheme.colorScheme.onSecondaryContainer + ), + description = TextDefinition( + text = stringResource(screen.tap_target_coodinator_description), + textStyle = MaterialTheme.typography.bodyMedium, + color = MaterialTheme.colorScheme.onSecondaryContainer + ), + tapTargetStyle = TapTargetStyle( + backgroundColor = MaterialTheme.colorScheme.secondaryContainer, + tapTargetHighlightColor = MaterialTheme.colorScheme.onSecondaryContainer, + backgroundAlpha = 1f, + ), + ).padding(12.dp), verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(4.dp) ) { @@ -180,6 +231,7 @@ private fun CustomBottomNavigationItem( } } + @Composable private fun HandleShortcutIntent(intent: Intent, navController: NavController) { val data = intent.data diff --git a/app/src/main/java/org/cis_india/wsreader/ui/screens/settings/composables/SettingsScreen.kt b/app/src/main/java/org/cis_india/wsreader/ui/screens/settings/composables/SettingsScreen.kt index 5272e40..e8e8a78 100644 --- a/app/src/main/java/org/cis_india/wsreader/ui/screens/settings/composables/SettingsScreen.kt +++ b/app/src/main/java/org/cis_india/wsreader/ui/screens/settings/composables/SettingsScreen.kt @@ -42,6 +42,7 @@ import androidx.compose.foundation.verticalScroll import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.BrightnessMedium import androidx.compose.material.icons.filled.Contrast +import androidx.compose.material.icons.filled.Help import androidx.compose.material.icons.filled.Info import androidx.compose.material.icons.filled.Language import androidx.compose.material.icons.filled.LocalPolice @@ -204,6 +205,13 @@ private fun GeneralOptionsUI( val context = LocalContext.current val coroutineScope = rememberCoroutineScope() + val guideSwitch = remember { mutableStateOf(viewModel.getOnboardingGuideValue()) } + val guideDesc = if (guideSwitch.value) { + stringResource(id = R.string.onboarding_guide_inactive) + } else { + stringResource(id = R.string.onboarding_guide_active) + } + Column( modifier = Modifier .padding(horizontal = 14.dp) @@ -241,6 +249,16 @@ private fun GeneralOptionsUI( } ) + SettingItemWIthSwitch( + icon = Icons.Filled.Help, + mainText = stringResource(id = R.string.toggle_guide_title), + subText = guideDesc, + switchState = guideSwitch, + onCheckChange = { + viewModel.setOnboardingGuide(it) + guideSwitch.value = it + }) + } } diff --git a/app/src/main/java/org/cis_india/wsreader/ui/screens/settings/viewmodels/SettingsViewModel.kt b/app/src/main/java/org/cis_india/wsreader/ui/screens/settings/viewmodels/SettingsViewModel.kt index deda2d4..9d023da 100644 --- a/app/src/main/java/org/cis_india/wsreader/ui/screens/settings/viewmodels/SettingsViewModel.kt +++ b/app/src/main/java/org/cis_india/wsreader/ui/screens/settings/viewmodels/SettingsViewModel.kt @@ -19,6 +19,9 @@ package org.cis_india.wsreader.ui.screens.settings.viewmodels import android.os.Build import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.runtime.Composable +import androidx.compose.runtime.MutableState +import androidx.compose.runtime.State +import androidx.compose.runtime.mutableStateOf import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel @@ -43,6 +46,25 @@ class SettingsViewModel @Inject constructor( val amoledTheme: LiveData = _amoledTheme val materialYou: LiveData = _materialYou + private val _showHomeOnboardingTapTargets: MutableState = mutableStateOf( + value = preferenceUtil.getBoolean(PreferenceUtil.HOME_ONBOARDING_BOOL, true) + ) + + val showHomeOnboardingTapTargets: State = _showHomeOnboardingTapTargets + + private val _showNavOnboardingTapTargets: MutableState = mutableStateOf( + value = preferenceUtil.getBoolean(PreferenceUtil.NAV_ONBOARDING_BOOL, false) + ) + + val showNavOnboardingTapTargets: State = _showNavOnboardingTapTargets + + private val _firstOnboardingTapTargets: MutableState = mutableStateOf( + value = preferenceUtil.getBoolean(PreferenceUtil.FIRST_ONBOARDING_BOOL, true) + ) + + val firstOnboardingTapTargets: State = _firstOnboardingTapTargets + + init { _theme.value = ThemeMode.entries.toTypedArray()[getThemeValue()] _amoledTheme.value = getAmoledThemeValue() @@ -60,6 +82,22 @@ class SettingsViewModel @Inject constructor( preferenceUtil.putBoolean(PreferenceUtil.AMOLED_THEME_BOOL, newValue) } + fun setOnboardingGuide(newValue: Boolean) { + preferenceUtil.putBoolean(PreferenceUtil.HOME_ONBOARDING_BOOL, newValue) + + if (newValue) { + _showHomeOnboardingTapTargets.value = true + _showNavOnboardingTapTargets.value = false + preferenceUtil.putBoolean(PreferenceUtil.NAV_ONBOARDING_BOOL, false) + } else { + preferenceUtil.putBoolean(PreferenceUtil.HOME_ONBOARDING_BOOL, newValue) + preferenceUtil.putBoolean(PreferenceUtil.NAV_ONBOARDING_BOOL, false) + + _showHomeOnboardingTapTargets.value = false + _showNavOnboardingTapTargets.value = false + } + } + fun setMaterialYou(newValue: Boolean) { _materialYou.postValue(newValue) preferenceUtil.putBoolean(PreferenceUtil.MATERIAL_YOU_BOOL, newValue) @@ -79,6 +117,10 @@ class SettingsViewModel @Inject constructor( PreferenceUtil.AMOLED_THEME_BOOL, false ) + fun getOnboardingGuideValue() = preferenceUtil.getBoolean( + PreferenceUtil.HOME_ONBOARDING_BOOL, false + ) + fun getMaterialYouValue() = preferenceUtil.getBoolean( PreferenceUtil.MATERIAL_YOU_BOOL, Build.VERSION.SDK_INT >= Build.VERSION_CODES.S ) @@ -87,6 +129,25 @@ class SettingsViewModel @Inject constructor( PreferenceUtil.INTERNAL_READER_BOOL, true ) + fun homeOnboardingComplete() { + preferenceUtil.putBoolean(PreferenceUtil.HOME_ONBOARDING_BOOL, false) + _showHomeOnboardingTapTargets.value = false + + if(firstOnboardingTapTargets.value) { + preferenceUtil.putBoolean(PreferenceUtil.NAV_ONBOARDING_BOOL, true) + preferenceUtil.putBoolean(PreferenceUtil.FIRST_ONBOARDING_BOOL, false) + _showNavOnboardingTapTargets.value = true + _firstOnboardingTapTargets.value = false + } + + } + + + fun navOnboardingComplete() { + preferenceUtil.putBoolean(PreferenceUtil.NAV_ONBOARDING_BOOL, false) + _showNavOnboardingTapTargets.value = false + } + @Composable fun getCurrentTheme(): ThemeMode { return if (theme.value == ThemeMode.Auto) { diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 0b89e2e..8869dc8 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -16,6 +16,18 @@ Library Settings + Home Screen + Discover thousands of free, community-curated books and historical texts from the Wikisource library. + + Categories Section + Find exactly what you’re looking for by browsing through categories like plays, novels, and poetry. + + Your Library + Find all your books here. You can manage your collection, track your progress, or share favorites with friends. + + App Settings + Customize your reading experience, and adjust language preferences. + TIP! Swipe library items left or right to share or view book details. @@ -32,6 +44,17 @@ Browse by language Sort by + + Switch Language + Filter Books By Language + Sort Books + Tap to sort Books + Search function + Tap to search a book + + %1$s screen + Navigate to %1$s screen + Categories No books available in %s language for this category. @@ -124,6 +147,9 @@ Open source licenses. App Information Show App information & useful links + Show Onboarding Guide + Hide Onboarding Guide + Toggle Onboarding Guide Book cover image