Navigation.kt: Type-safety, non-null parameters for Screens, improved navigation + Included generated Room Database schemas to be able to build the project.
This commit is contained in:
parent
be9630ca24
commit
667a91f950
53 changed files with 922 additions and 465 deletions
|
|
@ -112,11 +112,15 @@ class Activity : AppCompatActivity() {
|
|||
themeContrast = state.value.themeContrast!!
|
||||
) {
|
||||
NavigationHost(
|
||||
startScreen = if (state.value.showStartScreen!!) Screen.START
|
||||
else Screen.LIBRARY
|
||||
startScreen = if (state.value.showStartScreen!!) Screen.Start
|
||||
else Screen.Library
|
||||
) {
|
||||
navigation(
|
||||
screens = arrayOf(Screen.LIBRARY, Screen.HISTORY, Screen.BROWSE),
|
||||
screens = arrayOf(
|
||||
Screen.Library.getRoute(),
|
||||
Screen.History.getRoute(),
|
||||
Screen.Browse.getRoute()
|
||||
),
|
||||
bottomBar = {
|
||||
BottomNavigationBar()
|
||||
},
|
||||
|
|
@ -125,8 +129,7 @@ class Activity : AppCompatActivity() {
|
|||
}
|
||||
) {
|
||||
// Library
|
||||
composable(
|
||||
screen = Screen.LIBRARY,
|
||||
composable<Screen.Library>(
|
||||
enterAnim = Transitions.FadeTransitionIn,
|
||||
exitAnim = Transitions.FadeTransitionOut
|
||||
) {
|
||||
|
|
@ -134,8 +137,7 @@ class Activity : AppCompatActivity() {
|
|||
}
|
||||
|
||||
// History
|
||||
composable(
|
||||
screen = Screen.HISTORY,
|
||||
composable<Screen.History>(
|
||||
enterAnim = Transitions.FadeTransitionIn,
|
||||
exitAnim = Transitions.FadeTransitionOut
|
||||
) {
|
||||
|
|
@ -143,8 +145,7 @@ class Activity : AppCompatActivity() {
|
|||
}
|
||||
|
||||
// Browse
|
||||
composable(
|
||||
screen = Screen.BROWSE,
|
||||
composable<Screen.Browse>(
|
||||
enterAnim = Transitions.FadeTransitionIn,
|
||||
exitAnim = Transitions.FadeTransitionOut
|
||||
) {
|
||||
|
|
@ -153,57 +154,54 @@ class Activity : AppCompatActivity() {
|
|||
}
|
||||
|
||||
// Book Info
|
||||
composable(screen = Screen.BOOK_INFO) {
|
||||
BookInfoScreenRoot()
|
||||
composable<Screen.BookInfo> {
|
||||
BookInfoScreenRoot(it)
|
||||
}
|
||||
|
||||
// Reader
|
||||
composable(screen = Screen.READER) {
|
||||
ReaderScreenRoot()
|
||||
composable<Screen.Reader> {
|
||||
ReaderScreenRoot(it)
|
||||
}
|
||||
|
||||
// Settings
|
||||
composable(screen = Screen.SETTINGS) {
|
||||
composable<Screen.Settings> {
|
||||
SettingsScreenRoot()
|
||||
}
|
||||
|
||||
// Nested settings categories
|
||||
composable(screen = Screen.GENERAL_SETTINGS) {
|
||||
composable<Screen.Settings.General> {
|
||||
GeneralSettingsRoot()
|
||||
}
|
||||
composable(screen = Screen.APPEARANCE_SETTINGS) {
|
||||
composable<Screen.Settings.Appearance> {
|
||||
AppearanceSettingsRoot()
|
||||
}
|
||||
composable(screen = Screen.READER_SETTINGS) {
|
||||
composable<Screen.Settings.ReaderSettings> {
|
||||
ReaderSettingsRoot()
|
||||
}
|
||||
|
||||
// About screen
|
||||
composable(screen = Screen.ABOUT) {
|
||||
composable<Screen.About> {
|
||||
AboutScreenRoot()
|
||||
}
|
||||
|
||||
// Nested about categories
|
||||
composable(screen = Screen.LICENSES) {
|
||||
composable<Screen.About.Licenses> {
|
||||
LicensesScreenRoot()
|
||||
}
|
||||
composable(screen = Screen.LICENSES_INFO) {
|
||||
LicenseInfoScreenRoot()
|
||||
composable<Screen.About.LicenseInfo> {
|
||||
LicenseInfoScreenRoot(it)
|
||||
}
|
||||
composable(screen = Screen.CREDITS) {
|
||||
composable<Screen.About.Credits> {
|
||||
CreditsScreenRoot()
|
||||
}
|
||||
|
||||
// Help screen
|
||||
composable(screen = Screen.HELP) {
|
||||
HelpScreenRoot()
|
||||
composable<Screen.Help> {
|
||||
HelpScreenRoot(it)
|
||||
}
|
||||
|
||||
// Start screen
|
||||
composable(
|
||||
screen = Screen.START,
|
||||
enterAnim = Transitions.FadeTransitionIn
|
||||
) {
|
||||
composable<Screen.Start>(enterAnim = Transitions.FadeTransitionIn) {
|
||||
StartScreenRoot()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,21 +30,21 @@ object Constants {
|
|||
// Navigation items for NavigationBars.
|
||||
val NAVIGATION_ITEMS = listOf(
|
||||
NavigationItem(
|
||||
screen = Screen.LIBRARY,
|
||||
screen = Screen.Library,
|
||||
title = R.string.library_screen,
|
||||
tooltip = R.string.library_content_desc,
|
||||
selectedIcon = R.drawable.library_screen_filled,
|
||||
unselectedIcon = R.drawable.library_screen_outlined
|
||||
),
|
||||
NavigationItem(
|
||||
screen = Screen.HISTORY,
|
||||
screen = Screen.History,
|
||||
title = R.string.history_screen,
|
||||
tooltip = R.string.history_content_desc,
|
||||
selectedIcon = R.drawable.history_screen_filled,
|
||||
unselectedIcon = R.drawable.history_screen_outlined
|
||||
),
|
||||
NavigationItem(
|
||||
screen = Screen.BROWSE,
|
||||
screen = Screen.Browse,
|
||||
title = R.string.browse_screen,
|
||||
tooltip = R.string.browse_content_desc,
|
||||
selectedIcon = R.drawable.browse_screen_filled,
|
||||
|
|
|
|||
|
|
@ -1,8 +1,11 @@
|
|||
package ua.acclorite.book_story.domain.util
|
||||
|
||||
import android.graphics.Bitmap
|
||||
import ua.acclorite.book_story.presentation.data.Navigator
|
||||
|
||||
typealias CoverImage = Bitmap
|
||||
typealias Selected = Boolean
|
||||
typealias ID = Int
|
||||
typealias LanguageCode = String
|
||||
typealias Route = String
|
||||
typealias OnNavigate = (Navigator.() -> Unit) -> Unit
|
||||
|
|
|
|||
|
|
@ -4,13 +4,18 @@ import androidx.compose.material.icons.Icons
|
|||
import androidx.compose.material.icons.automirrored.filled.ArrowBack
|
||||
import androidx.compose.runtime.Composable
|
||||
import ua.acclorite.book_story.R
|
||||
import ua.acclorite.book_story.presentation.data.Navigator
|
||||
import ua.acclorite.book_story.domain.util.OnNavigate
|
||||
|
||||
/**
|
||||
* Go back arrow button. Prevents double or triple clicking on it while going back action is performed.
|
||||
* Go back arrow button.
|
||||
* Prevents double or triple clicking on it while going back action is performed.
|
||||
*
|
||||
* @param onNavigate [OnNavigate].
|
||||
* @param enabled Whether this button is enabled.
|
||||
* @param customOnClick Call before going back.
|
||||
*/
|
||||
@Composable
|
||||
fun GoBackButton(navigator: Navigator, enabled: Boolean = true, customOnClick: () -> Unit = {}) {
|
||||
fun GoBackButton(onNavigate: OnNavigate, enabled: Boolean = true, customOnClick: () -> Unit = {}) {
|
||||
CustomIconButton(
|
||||
icon = Icons.AutoMirrored.Filled.ArrowBack,
|
||||
contentDescription = R.string.go_back_content_desc,
|
||||
|
|
@ -18,6 +23,8 @@ fun GoBackButton(navigator: Navigator, enabled: Boolean = true, customOnClick: (
|
|||
enabled = enabled
|
||||
) {
|
||||
customOnClick()
|
||||
navigator.navigateBack()
|
||||
onNavigate {
|
||||
navigateBack()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -21,7 +21,8 @@ import ua.acclorite.book_story.presentation.data.LocalNavigator
|
|||
import ua.acclorite.book_story.presentation.data.Screen
|
||||
|
||||
/**
|
||||
* More drop down. Navigates to Settings, About and Help screens.
|
||||
* More drop down.
|
||||
* Navigates to Settings, About and Help screens.
|
||||
*/
|
||||
@Composable
|
||||
fun MoreDropDown() {
|
||||
|
|
@ -55,7 +56,7 @@ fun MoreDropDown() {
|
|||
)
|
||||
},
|
||||
onClick = {
|
||||
navigator.navigate(Screen.SETTINGS, false)
|
||||
navigator.navigate(Screen.Settings)
|
||||
},
|
||||
contentPadding = PaddingValues(start = startPadding, end = endPadding)
|
||||
)
|
||||
|
|
@ -68,7 +69,7 @@ fun MoreDropDown() {
|
|||
)
|
||||
},
|
||||
onClick = {
|
||||
navigator.navigate(Screen.HELP, false)
|
||||
navigator.navigate(Screen.Help(false))
|
||||
},
|
||||
contentPadding = PaddingValues(start = startPadding, end = endPadding)
|
||||
)
|
||||
|
|
@ -81,7 +82,7 @@ fun MoreDropDown() {
|
|||
)
|
||||
},
|
||||
onClick = {
|
||||
navigator.navigate(Screen.ABOUT, false)
|
||||
navigator.navigate(Screen.About)
|
||||
},
|
||||
contentPadding = PaddingValues(start = startPadding, end = endPadding)
|
||||
)
|
||||
|
|
|
|||
|
|
@ -8,21 +8,25 @@ import androidx.compose.runtime.mutableStateOf
|
|||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import ua.acclorite.book_story.domain.util.Constants
|
||||
import ua.acclorite.book_story.domain.util.Route
|
||||
import ua.acclorite.book_story.presentation.data.LocalNavigator
|
||||
import ua.acclorite.book_story.presentation.data.Screen
|
||||
|
||||
/**
|
||||
* Bottom navigation bar, uses default [NavigationBar].
|
||||
*/
|
||||
@Composable
|
||||
fun BottomNavigationBar() {
|
||||
var currentScreen: Screen? by remember { mutableStateOf(null) }
|
||||
var currentScreen: Route? by remember { mutableStateOf(null) }
|
||||
val navigator = LocalNavigator.current
|
||||
|
||||
LaunchedEffect(Unit) {
|
||||
navigator.getCurrentScreen().collect {
|
||||
if (it == Screen.LIBRARY || it == Screen.HISTORY || it == Screen.BROWSE) {
|
||||
currentScreen = it
|
||||
navigator.currentScreen.collect { route ->
|
||||
if (
|
||||
Constants.NAVIGATION_ITEMS.any {
|
||||
navigator.run { it.screen.getRoute() } == route
|
||||
}
|
||||
) {
|
||||
currentScreen = route
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -31,7 +35,7 @@ fun BottomNavigationBar() {
|
|||
Constants.NAVIGATION_ITEMS.forEach {
|
||||
BottomNavigationBarItem(
|
||||
item = it,
|
||||
isSelected = currentScreen == it.screen
|
||||
isSelected = currentScreen == navigator.run { it.screen.getRoute() }
|
||||
) {
|
||||
navigator.navigate(it.screen, false)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,22 +24,26 @@ import androidx.compose.ui.Modifier
|
|||
import androidx.compose.ui.platform.LocalLayoutDirection
|
||||
import androidx.compose.ui.unit.dp
|
||||
import ua.acclorite.book_story.domain.util.Constants
|
||||
import ua.acclorite.book_story.domain.util.Route
|
||||
import ua.acclorite.book_story.presentation.data.LocalNavigator
|
||||
import ua.acclorite.book_story.presentation.data.Screen
|
||||
|
||||
/**
|
||||
* Custom Navigation Rail. It is used to be shown on Tablets.
|
||||
*/
|
||||
@Composable
|
||||
fun BoxScope.CustomNavigationRail() {
|
||||
var currentScreen: Screen? by remember { mutableStateOf(null) }
|
||||
var currentScreen: Route? by remember { mutableStateOf(null) }
|
||||
val navigator = LocalNavigator.current
|
||||
val layoutDirection = LocalLayoutDirection.current
|
||||
|
||||
LaunchedEffect(Unit) {
|
||||
navigator.getCurrentScreen().collect {
|
||||
if (it == Screen.LIBRARY || it == Screen.HISTORY || it == Screen.BROWSE) {
|
||||
currentScreen = it
|
||||
navigator.currentScreen.collect { route ->
|
||||
if (
|
||||
Constants.NAVIGATION_ITEMS.any {
|
||||
navigator.run { it.screen.getRoute() } == route
|
||||
}
|
||||
) {
|
||||
currentScreen = route
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -69,7 +73,7 @@ fun BoxScope.CustomNavigationRail() {
|
|||
Constants.NAVIGATION_ITEMS.forEach {
|
||||
CustomNavigationRailItem(
|
||||
item = it,
|
||||
isSelected = currentScreen == it.screen
|
||||
isSelected = currentScreen == navigator.run { it.screen.getRoute() }
|
||||
) {
|
||||
navigator.navigate(it.screen, false)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,60 +43,87 @@ import dagger.assisted.AssistedInject
|
|||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import dagger.hilt.android.lifecycle.withCreationCallback
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.parcelize.Parcelize
|
||||
import kotlinx.serialization.Serializable
|
||||
import ua.acclorite.book_story.domain.util.Route
|
||||
import ua.acclorite.book_story.presentation.components.CustomAnimatedVisibility
|
||||
import ua.acclorite.book_story.presentation.ui.Transitions
|
||||
import java.io.Serializable
|
||||
|
||||
|
||||
private const val CURRENT_SCREEN = "current_screen"
|
||||
private const val BACKSTACK = "back_stack"
|
||||
private const val USE_BACK_ANIM = "use_back_animation"
|
||||
private const val ARGUMENTS = "arguments"
|
||||
private const val SCREENS = "screens"
|
||||
|
||||
/**
|
||||
* Passed in [CompositionLocalProvider] and can be accessed through [LocalNavigator].current.
|
||||
*/
|
||||
val LocalNavigator = compositionLocalOf<Navigator> {
|
||||
error("Cannot initialize Navigator.")
|
||||
}
|
||||
|
||||
/**
|
||||
* All screens are listed here, later each screen will be passed as a param for [Navigator.composable] function.
|
||||
*/
|
||||
enum class Screen {
|
||||
LIBRARY,
|
||||
HISTORY,
|
||||
BROWSE,
|
||||
|
||||
BOOK_INFO,
|
||||
READER,
|
||||
|
||||
SETTINGS,
|
||||
GENERAL_SETTINGS,
|
||||
APPEARANCE_SETTINGS,
|
||||
READER_SETTINGS,
|
||||
|
||||
ABOUT,
|
||||
LICENSES,
|
||||
LICENSES_INFO,
|
||||
CREDITS,
|
||||
|
||||
HELP,
|
||||
START
|
||||
}
|
||||
|
||||
/**
|
||||
* Navigation Argument.
|
||||
* Screens. Should be [Serializable] to be able to pass them inside [SavedStateHandle].
|
||||
* Each screen should have unique name.
|
||||
*/
|
||||
@Immutable
|
||||
@Parcelize
|
||||
data class Argument<out T : Serializable>(
|
||||
val key: String,
|
||||
val value: T
|
||||
) : Parcelable
|
||||
sealed class Screen : Parcelable {
|
||||
|
||||
@Parcelize
|
||||
data object Library : Screen()
|
||||
|
||||
@Parcelize
|
||||
data object History : Screen()
|
||||
|
||||
@Parcelize
|
||||
data object Browse : Screen()
|
||||
|
||||
@Parcelize
|
||||
data class BookInfo(
|
||||
val bookId: Int
|
||||
) : Screen()
|
||||
|
||||
@Parcelize
|
||||
data class Reader(
|
||||
val bookId: Int
|
||||
) : Screen()
|
||||
|
||||
@Parcelize
|
||||
data object Settings : Screen() {
|
||||
@Parcelize
|
||||
data object General : Screen()
|
||||
|
||||
@Parcelize
|
||||
data object Appearance : Screen()
|
||||
|
||||
@Parcelize
|
||||
data object ReaderSettings : Screen()
|
||||
}
|
||||
|
||||
@Parcelize
|
||||
data object About : Screen() {
|
||||
@Parcelize
|
||||
data object Licenses : Screen()
|
||||
|
||||
@Parcelize
|
||||
data class LicenseInfo(val licenseId: String) : Screen()
|
||||
|
||||
@Parcelize
|
||||
data object Credits : Screen()
|
||||
}
|
||||
|
||||
@Parcelize
|
||||
data class Help(
|
||||
val fromStart: Boolean
|
||||
) : Screen()
|
||||
|
||||
@Parcelize
|
||||
data object Start : Screen()
|
||||
}
|
||||
|
||||
/**
|
||||
* Navigator. Using to navigate between screens.
|
||||
* Navigator. Used to navigate between screens.
|
||||
*
|
||||
* [Navigator.currentScreen] param represents current [Screen].
|
||||
* [Navigator.navigate] navigates to [Screen] passed as param.
|
||||
|
|
@ -104,139 +131,186 @@ data class Argument<out T : Serializable>(
|
|||
@HiltViewModel(assistedFactory = Navigator.Factory::class)
|
||||
class Navigator @AssistedInject constructor(
|
||||
private val savedStateHandle: SavedStateHandle,
|
||||
@Assisted startScreen: Screen
|
||||
@Assisted private val startScreen: Screen
|
||||
) : ViewModel() {
|
||||
|
||||
private val currentScreen = savedStateHandle.getStateFlow(CURRENT_SCREEN, startScreen)
|
||||
private val useBackAnimation = savedStateHandle.getStateFlow(USE_BACK_ANIM, false)
|
||||
private val backStack = savedStateHandle.getStateFlow(BACKSTACK, mutableListOf<Screen>())
|
||||
private val arguments = savedStateHandle
|
||||
.getStateFlow(ARGUMENTS, mutableListOf<Argument<Serializable>>())
|
||||
val currentScreen = savedStateHandle.getStateFlow(CURRENT_SCREEN, startScreen.getRoute())
|
||||
val useBackAnimation = savedStateHandle.getStateFlow(USE_BACK_ANIM, false)
|
||||
private val backStack = savedStateHandle.getStateFlow(BACKSTACK, mutableListOf<Route>())
|
||||
val screens = savedStateHandle.getStateFlow(SCREENS, mutableListOf<Screen>())
|
||||
|
||||
fun putArgument(argument: Argument<Serializable>) {
|
||||
init {
|
||||
putScreen(startScreen)
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves screen into [screens]. Later can be retrieved via [retrieveScreen].
|
||||
*
|
||||
* @param screen [Screen].
|
||||
*/
|
||||
fun putScreen(screen: Screen) {
|
||||
var found = false
|
||||
|
||||
for ((index, arg) in arguments.value.withIndex()) {
|
||||
if (arg.key == argument.key) {
|
||||
arguments.value[index] = argument
|
||||
for ((index, arg) in screens.value.withIndex()) {
|
||||
if (arg.getRoute() == screen.getRoute()) {
|
||||
screens.value[index] = screen
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
arguments.value.add(argument)
|
||||
screens.value.add(screen)
|
||||
}
|
||||
}
|
||||
|
||||
fun retrieveArgument(key: String): Serializable? {
|
||||
for (arg in arguments.value) {
|
||||
if (arg.key == key) {
|
||||
return arg.value
|
||||
/**
|
||||
* Retrieves screen that was put via [putScreen].
|
||||
*
|
||||
* @exception Exception if there is no such screen saved that specified in [S], throws an [Exception].
|
||||
*/
|
||||
inline fun <reified S : Screen> retrieveScreen(): S {
|
||||
for (arg in screens.value) {
|
||||
if (arg.getRoute() == getRoute<S>()) {
|
||||
return arg as S
|
||||
}
|
||||
}
|
||||
return null
|
||||
|
||||
throw Exception("Screen was not found.")
|
||||
}
|
||||
|
||||
fun clearArgument(key: String) {
|
||||
arguments.value.removeIf { it.key == key }
|
||||
}
|
||||
|
||||
fun navigate(screen: Screen, useBackAnimation: Boolean, vararg args: Argument<Serializable>) =
|
||||
viewModelScope.launch(Dispatchers.Default) {
|
||||
backStack.value.add(currentScreen.value)
|
||||
|
||||
args.forEach {
|
||||
putArgument(it)
|
||||
}
|
||||
|
||||
savedStateHandle[USE_BACK_ANIM] = useBackAnimation
|
||||
savedStateHandle[CURRENT_SCREEN] = screen
|
||||
}
|
||||
|
||||
fun navigateWithoutBackStack(
|
||||
/**
|
||||
* Navigates to the desired screen. Ignored if [currentScreen] is already [screen].
|
||||
*
|
||||
* @param screen [Screen] to navigate to.
|
||||
* @param useBackAnimation Whether back animation should be used(as when user goes back).
|
||||
* @param saveInBackStack Whether this screen should be saved in [backStack] (basically history of all opened screens).
|
||||
*/
|
||||
fun navigate(
|
||||
screen: Screen,
|
||||
useBackAnimation: Boolean,
|
||||
vararg args: Argument<Serializable>
|
||||
useBackAnimation: Boolean = false,
|
||||
saveInBackStack: Boolean = true
|
||||
) = viewModelScope.launch(Dispatchers.Default) {
|
||||
if (backStack.value.lastOrNull() == screen) {
|
||||
backStack.value.removeLast()
|
||||
if (screen.getRoute() == currentScreen.value) {
|
||||
return@launch
|
||||
}
|
||||
|
||||
args.forEach {
|
||||
putArgument(it)
|
||||
if (saveInBackStack) {
|
||||
backStack.value.add(currentScreen.value)
|
||||
}
|
||||
|
||||
putScreen(screen)
|
||||
|
||||
savedStateHandle[USE_BACK_ANIM] = useBackAnimation
|
||||
savedStateHandle[CURRENT_SCREEN] = screen
|
||||
savedStateHandle[CURRENT_SCREEN] = screen.getRoute()
|
||||
}
|
||||
|
||||
fun navigateBack(useBackAnimation: Boolean = true) =
|
||||
viewModelScope.launch(Dispatchers.Default) {
|
||||
if (canGoBack()) {
|
||||
savedStateHandle[USE_BACK_ANIM] = useBackAnimation
|
||||
savedStateHandle[CURRENT_SCREEN] = backStack.value.last()
|
||||
backStack.value.removeLast()
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Navigates user to the previous screen, if there is.
|
||||
* If there is nowhere to go, this call is ignored.
|
||||
*
|
||||
* @param useBackAnimation Whether user should see back animation when he goes to the previous screen.
|
||||
*/
|
||||
fun navigateBack(
|
||||
useBackAnimation: Boolean = true
|
||||
) = viewModelScope.launch(Dispatchers.Default) {
|
||||
if (canGoBack()) {
|
||||
savedStateHandle[USE_BACK_ANIM] = useBackAnimation
|
||||
savedStateHandle[CURRENT_SCREEN] = backStack.value.last()
|
||||
|
||||
backStack.value.removeLast()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the whole [backStack].
|
||||
*/
|
||||
fun clearBackStack() {
|
||||
backStack.value.clear()
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether there is screen to go back.
|
||||
*/
|
||||
fun canGoBack(): Boolean {
|
||||
return backStack.value.isNotEmpty()
|
||||
}
|
||||
|
||||
fun getCurrentScreen(): StateFlow<Screen> {
|
||||
return currentScreen
|
||||
}
|
||||
|
||||
fun getUseBackAnim(): StateFlow<Boolean> {
|
||||
return useBackAnimation
|
||||
/**
|
||||
* Gets route of specified [S].
|
||||
*/
|
||||
inline fun <reified S : Screen> getRoute(): Route {
|
||||
return S::class.simpleName!!
|
||||
}
|
||||
|
||||
/**
|
||||
* Animated Screen. Used in [NavigationHost]. Be sure to not use the same [screen] parameter twice, it'll override the highest one in your code.
|
||||
* Gets route of this screen.
|
||||
*/
|
||||
fun Screen.getRoute(): Route {
|
||||
return this::class.simpleName!!
|
||||
}
|
||||
|
||||
/**
|
||||
* Animated Screen. Used in [NavigationHost].
|
||||
* Each [composable] should have unique [Screen].
|
||||
*
|
||||
* @param screen The [Screen] that represents [content].
|
||||
* @param enterAnim Enter Animation.
|
||||
* @param backEnterAnim Enter Animation for navigating back.
|
||||
* @param exitAnim Exit Animation.
|
||||
* @param backExitAnim Exit Animation for navigating back.
|
||||
* @param content The Screen content to show when [Navigator.currentScreen] equals [screen].
|
||||
* @param content The Screen content to show when [Navigator.currentScreen] equals [S].
|
||||
*/
|
||||
@SuppressLint("ComposableNaming")
|
||||
@Composable
|
||||
fun composable(
|
||||
screen: Screen,
|
||||
inline fun <reified S : Screen> composable(
|
||||
enterAnim: EnterTransition = Transitions.SlidingTransitionIn,
|
||||
backEnterAnim: EnterTransition = Transitions.BackSlidingTransitionIn,
|
||||
exitAnim: ExitTransition = Transitions.SlidingTransitionOut,
|
||||
backExitAnim: ExitTransition = Transitions.BackSlidingTransitionOut,
|
||||
content: @Composable () -> Unit
|
||||
noinline content: @Composable (screen: S) -> Unit
|
||||
) {
|
||||
val currentRoute by currentScreen.collectAsState()
|
||||
val useBackAnimation by useBackAnimation.collectAsState()
|
||||
|
||||
CustomAnimatedVisibility(
|
||||
visible = getCurrentScreen().collectAsState().value == screen,
|
||||
enter = if (!useBackAnimation.collectAsState().value) enterAnim else backEnterAnim,
|
||||
exit = if (!useBackAnimation.collectAsState().value) exitAnim else backExitAnim
|
||||
visible = currentRoute == getRoute<S>(),
|
||||
enter = if (!useBackAnimation) enterAnim else backEnterAnim,
|
||||
exit = if (!useBackAnimation) exitAnim else backExitAnim
|
||||
) {
|
||||
content()
|
||||
val screen = remember { retrieveScreen<S>() }
|
||||
content(screen)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Navigator's navigation.
|
||||
* Shows BottomBar or Navigation Rail when any of the [screens] are currently showing.
|
||||
*
|
||||
* @param screens [Screen]s where navigation shows.
|
||||
* @param enterBarAnim Enter animation for navigation.
|
||||
* @param backEnterBarAnim Back enter animation for navigation.
|
||||
* @param exitBarAnim Exit animation for navigation.
|
||||
* @param backExitBarAnim Back exit animation for navigation.
|
||||
* @param bottomBar Bottom bar, sticks to the bottom.
|
||||
* @param navigationRail Navigation rail, sticks to the sides.
|
||||
* @param content Content, all [screens] should be inside as [composable].
|
||||
*/
|
||||
@OptIn(ExperimentalMaterial3WindowSizeClassApi::class)
|
||||
@SuppressLint("ComposableNaming")
|
||||
@Composable
|
||||
fun navigation(
|
||||
vararg screens: Screen,
|
||||
vararg screens: Route,
|
||||
enterBarAnim: EnterTransition = Transitions.SlidingTransitionIn,
|
||||
backEnterBarAnim: EnterTransition = Transitions.BackSlidingTransitionIn,
|
||||
exitBarAnim: ExitTransition = Transitions.SlidingTransitionOut,
|
||||
backExitBarAnim: ExitTransition = Transitions.BackSlidingTransitionOut,
|
||||
bottomBar: @Composable () -> Unit,
|
||||
navigationRail: @Composable BoxScope.() -> Unit,
|
||||
content: @Composable () -> Unit
|
||||
) {
|
||||
val activity = LocalContext.current as ComponentActivity
|
||||
val currentScreen by getCurrentScreen().collectAsState()
|
||||
val useBackAnimation by getUseBackAnim().collectAsState()
|
||||
val currentScreen by currentScreen.collectAsState()
|
||||
val useBackAnimation by useBackAnimation.collectAsState()
|
||||
val shouldShow by remember(currentScreen) {
|
||||
derivedStateOf {
|
||||
screens.any { it == currentScreen }
|
||||
|
|
@ -251,10 +325,10 @@ class Navigator @AssistedInject constructor(
|
|||
|
||||
CustomAnimatedVisibility(
|
||||
visible = shouldShow,
|
||||
enter = if (useBackAnimation) Transitions.BackSlidingTransitionIn
|
||||
else Transitions.SlidingTransitionIn,
|
||||
exit = if (useBackAnimation) Transitions.BackSlidingTransitionOut
|
||||
else Transitions.SlidingTransitionOut
|
||||
enter = if (useBackAnimation) backEnterBarAnim
|
||||
else enterBarAnim,
|
||||
exit = if (useBackAnimation) backExitBarAnim
|
||||
else exitBarAnim
|
||||
) {
|
||||
Scaffold(
|
||||
bottomBar = {
|
||||
|
|
@ -305,13 +379,13 @@ class Navigator @AssistedInject constructor(
|
|||
}
|
||||
|
||||
/**
|
||||
* Navigation Host. Contains [Navigator.composable]s in [content].
|
||||
* Custom Navigation Host. Contains [Navigator.composable]s in [content].
|
||||
* Based on [CustomAnimatedVisibility].
|
||||
*
|
||||
* @param startScreen Start Screen. Be sure to pass [Screen] that uses in one of your [Navigator.composable]s.
|
||||
* @param colorBetweenAnimations The color, that using between animations, recommended to set this to background or navigation bar color.
|
||||
* @param content Content of the [NavigationHost]. Highly recommended to use [Navigator.composable].
|
||||
*/
|
||||
|
||||
@Composable
|
||||
fun NavigationHost(
|
||||
startScreen: Screen,
|
||||
|
|
|
|||
|
|
@ -33,10 +33,10 @@ import androidx.compose.ui.text.buildAnnotatedString
|
|||
import androidx.compose.ui.unit.dp
|
||||
import androidx.hilt.navigation.compose.hiltViewModel
|
||||
import ua.acclorite.book_story.R
|
||||
import ua.acclorite.book_story.domain.util.OnNavigate
|
||||
import ua.acclorite.book_story.presentation.components.GoBackButton
|
||||
import ua.acclorite.book_story.presentation.components.collapsibleUntilExitScrollBehaviorWithLazyListState
|
||||
import ua.acclorite.book_story.presentation.data.LocalNavigator
|
||||
import ua.acclorite.book_story.presentation.data.Navigator
|
||||
import ua.acclorite.book_story.presentation.data.Screen
|
||||
import ua.acclorite.book_story.presentation.screens.about.components.AboutItem
|
||||
import ua.acclorite.book_story.presentation.screens.about.components.AboutUpdateDialog
|
||||
|
|
@ -53,7 +53,7 @@ fun AboutScreenRoot() {
|
|||
|
||||
AboutScreen(
|
||||
state = state,
|
||||
navigator = navigator,
|
||||
onNavigate = { navigator.it() },
|
||||
onEvent = aboutViewModel::onEvent
|
||||
)
|
||||
}
|
||||
|
|
@ -62,7 +62,7 @@ fun AboutScreenRoot() {
|
|||
@Composable
|
||||
private fun AboutScreen(
|
||||
state: State<AboutState>,
|
||||
navigator: Navigator,
|
||||
onNavigate: OnNavigate,
|
||||
onEvent: (AboutEvent) -> Unit
|
||||
) {
|
||||
val context = LocalContext.current
|
||||
|
|
@ -87,7 +87,7 @@ private fun AboutScreen(
|
|||
Text(stringResource(id = R.string.about_screen))
|
||||
},
|
||||
navigationIcon = {
|
||||
GoBackButton(navigator = navigator)
|
||||
GoBackButton(onNavigate = onNavigate)
|
||||
},
|
||||
scrollBehavior = scrollState.first,
|
||||
colors = TopAppBarDefaults.largeTopAppBarColors(
|
||||
|
|
@ -213,7 +213,9 @@ private fun AboutScreen(
|
|||
title = stringResource(id = R.string.licenses_option),
|
||||
description = null
|
||||
) {
|
||||
navigator.navigate(Screen.LICENSES, false)
|
||||
onNavigate {
|
||||
navigate(Screen.About.Licenses)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -222,7 +224,9 @@ private fun AboutScreen(
|
|||
title = stringResource(id = R.string.credits_option),
|
||||
description = null
|
||||
) {
|
||||
navigator.navigate(Screen.CREDITS, false)
|
||||
onNavigate {
|
||||
navigate(Screen.About.Credits)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -21,11 +21,11 @@ import androidx.compose.ui.res.stringResource
|
|||
import androidx.hilt.navigation.compose.hiltViewModel
|
||||
import ua.acclorite.book_story.R
|
||||
import ua.acclorite.book_story.domain.util.Constants
|
||||
import ua.acclorite.book_story.domain.util.OnNavigate
|
||||
import ua.acclorite.book_story.presentation.components.GoBackButton
|
||||
import ua.acclorite.book_story.presentation.components.collapsibleUntilExitScrollBehaviorWithLazyListState
|
||||
import ua.acclorite.book_story.presentation.components.customItems
|
||||
import ua.acclorite.book_story.presentation.data.LocalNavigator
|
||||
import ua.acclorite.book_story.presentation.data.Navigator
|
||||
import ua.acclorite.book_story.presentation.screens.about.data.AboutEvent
|
||||
import ua.acclorite.book_story.presentation.screens.about.data.AboutViewModel
|
||||
import ua.acclorite.book_story.presentation.screens.about.nested.credits.components.CreditItem
|
||||
|
|
@ -36,7 +36,7 @@ fun CreditsScreenRoot() {
|
|||
val aboutViewModel: AboutViewModel = hiltViewModel()
|
||||
|
||||
CreditsScreen(
|
||||
navigator = navigator,
|
||||
onNavigate = { navigator.it() },
|
||||
onAboutNavigateEvent = aboutViewModel::onEvent
|
||||
)
|
||||
}
|
||||
|
|
@ -44,7 +44,7 @@ fun CreditsScreenRoot() {
|
|||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
private fun CreditsScreen(
|
||||
navigator: Navigator,
|
||||
onNavigate: OnNavigate,
|
||||
onAboutNavigateEvent: (AboutEvent.OnNavigateToBrowserPage) -> Unit
|
||||
) {
|
||||
val scrollState = TopAppBarDefaults.collapsibleUntilExitScrollBehaviorWithLazyListState()
|
||||
|
|
@ -62,7 +62,7 @@ private fun CreditsScreen(
|
|||
Text(stringResource(id = R.string.credits_option))
|
||||
},
|
||||
navigationIcon = {
|
||||
GoBackButton(navigator = navigator)
|
||||
GoBackButton(onNavigate = onNavigate)
|
||||
},
|
||||
scrollBehavior = scrollState.first,
|
||||
colors = TopAppBarDefaults.largeTopAppBarColors(
|
||||
|
|
|
|||
|
|
@ -42,19 +42,20 @@ import androidx.compose.ui.text.style.TextOverflow
|
|||
import androidx.compose.ui.unit.dp
|
||||
import androidx.hilt.navigation.compose.hiltViewModel
|
||||
import ua.acclorite.book_story.R
|
||||
import ua.acclorite.book_story.domain.util.OnNavigate
|
||||
import ua.acclorite.book_story.presentation.components.CustomIconButton
|
||||
import ua.acclorite.book_story.presentation.components.GoBackButton
|
||||
import ua.acclorite.book_story.presentation.components.collapsibleUntilExitScrollBehaviorWithLazyListState
|
||||
import ua.acclorite.book_story.presentation.components.customItems
|
||||
import ua.acclorite.book_story.presentation.data.LocalNavigator
|
||||
import ua.acclorite.book_story.presentation.data.Navigator
|
||||
import ua.acclorite.book_story.presentation.data.Screen
|
||||
import ua.acclorite.book_story.presentation.screens.about.nested.license_info.data.LicenseInfoEvent
|
||||
import ua.acclorite.book_story.presentation.screens.about.nested.license_info.data.LicenseInfoState
|
||||
import ua.acclorite.book_story.presentation.screens.about.nested.license_info.data.LicenseInfoViewModel
|
||||
import ua.acclorite.book_story.presentation.ui.SlidingTransition
|
||||
|
||||
@Composable
|
||||
fun LicenseInfoScreenRoot() {
|
||||
fun LicenseInfoScreenRoot(screen: Screen.About.LicenseInfo) {
|
||||
val navigator = LocalNavigator.current
|
||||
val context = LocalContext.current
|
||||
val licenseInfoViewModel: LicenseInfoViewModel = hiltViewModel()
|
||||
|
|
@ -63,15 +64,16 @@ fun LicenseInfoScreenRoot() {
|
|||
|
||||
LaunchedEffect(Unit) {
|
||||
licenseInfoViewModel.init(
|
||||
navigator,
|
||||
context
|
||||
screen = screen,
|
||||
onNavigate = { navigator.it() },
|
||||
context = context
|
||||
)
|
||||
}
|
||||
|
||||
LicenseInfoScreen(
|
||||
state = state,
|
||||
onEvent = licenseInfoViewModel::onEvent,
|
||||
navigator = navigator
|
||||
onNavigate = { navigator.it() },
|
||||
onEvent = licenseInfoViewModel::onEvent
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -79,8 +81,8 @@ fun LicenseInfoScreenRoot() {
|
|||
@Composable
|
||||
private fun LicenseInfoScreen(
|
||||
state: State<LicenseInfoState>,
|
||||
onEvent: (LicenseInfoEvent) -> Unit,
|
||||
navigator: Navigator
|
||||
onNavigate: OnNavigate,
|
||||
onEvent: (LicenseInfoEvent) -> Unit
|
||||
) {
|
||||
val scrollState = TopAppBarDefaults.collapsibleUntilExitScrollBehaviorWithLazyListState()
|
||||
val context = LocalContext.current
|
||||
|
|
@ -106,7 +108,7 @@ private fun LicenseInfoScreen(
|
|||
)
|
||||
},
|
||||
navigationIcon = {
|
||||
GoBackButton(navigator = navigator)
|
||||
GoBackButton(onNavigate = onNavigate)
|
||||
},
|
||||
actions = {
|
||||
if (state.value.license?.website?.isNotBlank() == true) {
|
||||
|
|
|
|||
|
|
@ -13,7 +13,8 @@ import kotlinx.coroutines.flow.MutableStateFlow
|
|||
import kotlinx.coroutines.flow.asStateFlow
|
||||
import kotlinx.coroutines.flow.update
|
||||
import kotlinx.coroutines.launch
|
||||
import ua.acclorite.book_story.presentation.data.Navigator
|
||||
import ua.acclorite.book_story.domain.util.OnNavigate
|
||||
import ua.acclorite.book_story.presentation.data.Screen
|
||||
import javax.inject.Inject
|
||||
|
||||
@HiltViewModel
|
||||
|
|
@ -42,25 +43,20 @@ class LicenseInfoViewModel @Inject constructor() : ViewModel() {
|
|||
}
|
||||
}
|
||||
|
||||
fun init(navigator: Navigator, context: Context) {
|
||||
fun init(screen: Screen.About.LicenseInfo, onNavigate: OnNavigate, context: Context) {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
_state.update {
|
||||
it.copy(license = null)
|
||||
}
|
||||
|
||||
val licenseId = navigator.retrieveArgument("license") as? String
|
||||
|
||||
if (licenseId == null) {
|
||||
navigator.navigateBack()
|
||||
return@launch
|
||||
}
|
||||
|
||||
val license = Libs.Builder().withContext(context).build().libraries.find {
|
||||
it.uniqueId == licenseId
|
||||
it.uniqueId == screen.licenseId
|
||||
}
|
||||
|
||||
if (license == null) {
|
||||
navigator.navigateBack()
|
||||
onNavigate {
|
||||
navigateBack()
|
||||
}
|
||||
return@launch
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -28,13 +28,12 @@ import androidx.compose.ui.res.stringResource
|
|||
import androidx.compose.ui.unit.dp
|
||||
import androidx.hilt.navigation.compose.hiltViewModel
|
||||
import ua.acclorite.book_story.R
|
||||
import ua.acclorite.book_story.domain.util.OnNavigate
|
||||
import ua.acclorite.book_story.presentation.components.CustomAnimatedVisibility
|
||||
import ua.acclorite.book_story.presentation.components.GoBackButton
|
||||
import ua.acclorite.book_story.presentation.components.collapsibleUntilExitScrollBehaviorWithLazyListState
|
||||
import ua.acclorite.book_story.presentation.components.customItems
|
||||
import ua.acclorite.book_story.presentation.data.Argument
|
||||
import ua.acclorite.book_story.presentation.data.LocalNavigator
|
||||
import ua.acclorite.book_story.presentation.data.Navigator
|
||||
import ua.acclorite.book_story.presentation.data.Screen
|
||||
import ua.acclorite.book_story.presentation.screens.about.nested.licenses.components.LicenseItem
|
||||
import ua.acclorite.book_story.presentation.screens.about.nested.licenses.data.LicensesState
|
||||
|
|
@ -54,7 +53,7 @@ fun LicensesScreenRoot() {
|
|||
|
||||
LicensesScreen(
|
||||
state = state,
|
||||
navigator = navigator
|
||||
onNavigate = { navigator.it() }
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -62,7 +61,7 @@ fun LicensesScreenRoot() {
|
|||
@Composable
|
||||
private fun LicensesScreen(
|
||||
state: State<LicensesState>,
|
||||
navigator: Navigator
|
||||
onNavigate: OnNavigate
|
||||
) {
|
||||
val scrollState = TopAppBarDefaults.collapsibleUntilExitScrollBehaviorWithLazyListState()
|
||||
|
||||
|
|
@ -78,7 +77,7 @@ private fun LicensesScreen(
|
|||
Text(stringResource(id = R.string.licenses_option))
|
||||
},
|
||||
navigationIcon = {
|
||||
GoBackButton(navigator = navigator)
|
||||
GoBackButton(onNavigate = onNavigate)
|
||||
},
|
||||
scrollBehavior = scrollState.first,
|
||||
colors = TopAppBarDefaults.largeTopAppBarColors(
|
||||
|
|
@ -105,11 +104,9 @@ private fun LicensesScreen(
|
|||
|
||||
customItems(state.value.licenses, key = { it.uniqueId }) {
|
||||
LicenseItem(library = it) {
|
||||
navigator.navigate(
|
||||
Screen.LICENSES_INFO,
|
||||
false,
|
||||
Argument("license", it.uniqueId)
|
||||
)
|
||||
onNavigate {
|
||||
navigate(Screen.About.LicenseInfo(it.uniqueId))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -57,13 +57,14 @@ import androidx.compose.ui.text.style.TextOverflow
|
|||
import androidx.compose.ui.unit.dp
|
||||
import androidx.hilt.navigation.compose.hiltViewModel
|
||||
import ua.acclorite.book_story.R
|
||||
import ua.acclorite.book_story.domain.util.OnNavigate
|
||||
import ua.acclorite.book_story.presentation.components.AnimatedTopAppBar
|
||||
import ua.acclorite.book_story.presentation.components.CustomAnimatedVisibility
|
||||
import ua.acclorite.book_story.presentation.components.CustomIconButton
|
||||
import ua.acclorite.book_story.presentation.components.CustomSnackbar
|
||||
import ua.acclorite.book_story.presentation.components.GoBackButton
|
||||
import ua.acclorite.book_story.presentation.data.LocalNavigator
|
||||
import ua.acclorite.book_story.presentation.data.Navigator
|
||||
import ua.acclorite.book_story.presentation.data.Screen
|
||||
import ua.acclorite.book_story.presentation.screens.book_info.components.BookInfoBackground
|
||||
import ua.acclorite.book_story.presentation.screens.book_info.components.BookInfoDescriptionSection
|
||||
import ua.acclorite.book_story.presentation.screens.book_info.components.BookInfoInfoSection
|
||||
|
|
@ -87,7 +88,7 @@ import ua.acclorite.book_story.presentation.ui.DefaultTransition
|
|||
import ua.acclorite.book_story.presentation.ui.Transitions
|
||||
|
||||
@Composable
|
||||
fun BookInfoScreenRoot() {
|
||||
fun BookInfoScreenRoot(screen: Screen.BookInfo) {
|
||||
val navigator = LocalNavigator.current
|
||||
|
||||
val viewModel: BookInfoViewModel = hiltViewModel()
|
||||
|
|
@ -99,13 +100,14 @@ fun BookInfoScreenRoot() {
|
|||
|
||||
LaunchedEffect(Unit) {
|
||||
viewModel.init(
|
||||
navigator
|
||||
screen = screen,
|
||||
onNavigate = { navigator.it() }
|
||||
)
|
||||
}
|
||||
|
||||
BookInfoScreen(
|
||||
state = state,
|
||||
navigator = navigator,
|
||||
onNavigate = { navigator.it() },
|
||||
onEvent = viewModel::onEvent,
|
||||
onLibraryEvent = libraryViewModel::onEvent,
|
||||
onBrowseEvent = browseViewModel::onEvent,
|
||||
|
|
@ -117,7 +119,7 @@ fun BookInfoScreenRoot() {
|
|||
@Composable
|
||||
private fun BookInfoScreen(
|
||||
state: State<BookInfoState>,
|
||||
navigator: Navigator,
|
||||
onNavigate: OnNavigate,
|
||||
onEvent: (BookInfoEvent) -> Unit,
|
||||
onLibraryEvent: (LibraryEvent) -> Unit,
|
||||
onBrowseEvent: (BrowseEvent) -> Unit,
|
||||
|
|
@ -203,7 +205,7 @@ private fun BookInfoScreen(
|
|||
onEvent(BookInfoEvent.OnShowHideEditTitle)
|
||||
}
|
||||
} else {
|
||||
GoBackButton(navigator = navigator, enabled = !state.value.isRefreshing) {
|
||||
GoBackButton(onNavigate = onNavigate, enabled = !state.value.isRefreshing) {
|
||||
onEvent(BookInfoEvent.OnCancelUpdate)
|
||||
}
|
||||
}
|
||||
|
|
@ -329,7 +331,7 @@ private fun BookInfoScreen(
|
|||
FloatingActionButton(
|
||||
onClick = {
|
||||
if (!state.value.isRefreshing) {
|
||||
onEvent(BookInfoEvent.OnNavigateToReaderScreen(navigator))
|
||||
onEvent(BookInfoEvent.OnNavigateToReaderScreen(onNavigate = onNavigate))
|
||||
}
|
||||
},
|
||||
shape = MaterialTheme.shapes.large,
|
||||
|
|
@ -387,7 +389,9 @@ private fun BookInfoScreen(
|
|||
|
||||
if (!state.value.isRefreshing) {
|
||||
onEvent(BookInfoEvent.OnCancelUpdate)
|
||||
navigator.navigateBack()
|
||||
onNavigate {
|
||||
navigateBack()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -16,6 +16,11 @@ import ua.acclorite.book_story.presentation.screens.library.data.LibraryEvent
|
|||
|
||||
/**
|
||||
* Delete dialog. Deletes current book.
|
||||
*
|
||||
* @param onEvent [BookInfoEvent] callback.
|
||||
* @param onLibraryLoadEvent [LibraryEvent] callback.
|
||||
* @param onHistoryLoadEvent [HistoryEvent] callback.
|
||||
* @param onBrowseLoadEvent [BrowseEvent] callback.
|
||||
*/
|
||||
@Composable
|
||||
fun BookInfoDeleteDialog(
|
||||
|
|
@ -40,7 +45,7 @@ fun BookInfoDeleteDialog(
|
|||
onAction = {
|
||||
onEvent(
|
||||
BookInfoEvent.OnDeleteBook(
|
||||
navigator = navigator,
|
||||
onNavigate = { navigator.it() },
|
||||
refreshList = {
|
||||
onLibraryLoadEvent(LibraryEvent.OnLoadList)
|
||||
onBrowseLoadEvent(BrowseEvent.OnLoadList)
|
||||
|
|
|
|||
|
|
@ -21,7 +21,13 @@ import ua.acclorite.book_story.presentation.screens.history.data.HistoryEvent
|
|||
import ua.acclorite.book_story.presentation.screens.library.data.LibraryEvent
|
||||
|
||||
/**
|
||||
* Move dialog. Moves current book to the selected category.
|
||||
* Move dialog.
|
||||
* Moves current book to the selected category.
|
||||
*
|
||||
* @param state [BookInfoState].
|
||||
* @param onEvent [BookInfoEvent] callback.
|
||||
* @param onLibraryEvent [LibraryEvent] callback.
|
||||
* @param onHistoryUpdateEvent [HistoryEvent] callback.
|
||||
*/
|
||||
@Composable
|
||||
fun BookInfoMoveDialog(
|
||||
|
|
@ -60,7 +66,7 @@ fun BookInfoMoveDialog(
|
|||
updatePage = {
|
||||
onLibraryEvent(LibraryEvent.OnUpdateCurrentPage(it))
|
||||
},
|
||||
navigator = navigator
|
||||
onNavigate = { navigator.it() }
|
||||
)
|
||||
)
|
||||
Toast.makeText(
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import androidx.compose.runtime.Immutable
|
|||
import androidx.compose.ui.focus.FocusRequester
|
||||
import ua.acclorite.book_story.domain.model.Book
|
||||
import ua.acclorite.book_story.domain.model.Category
|
||||
import ua.acclorite.book_story.presentation.data.Navigator
|
||||
import ua.acclorite.book_story.domain.util.OnNavigate
|
||||
|
||||
@Immutable
|
||||
sealed class BookInfoEvent {
|
||||
|
|
@ -23,11 +23,13 @@ sealed class BookInfoEvent {
|
|||
data class OnUpdateTitle(val refreshList: (Book) -> Unit) : BookInfoEvent()
|
||||
data object OnShowHideDeleteDialog : BookInfoEvent()
|
||||
data object OnShowHideMoveDialog : BookInfoEvent()
|
||||
data class OnDeleteBook(val refreshList: () -> Unit, val navigator: Navigator) : BookInfoEvent()
|
||||
data class OnDeleteBook(val refreshList: () -> Unit, val onNavigate: OnNavigate) :
|
||||
BookInfoEvent()
|
||||
|
||||
data class OnMoveBook(
|
||||
val refreshList: (Book) -> Unit,
|
||||
val updatePage: (Int) -> Unit,
|
||||
val navigator: Navigator
|
||||
val onNavigate: OnNavigate
|
||||
) : BookInfoEvent()
|
||||
|
||||
data class OnSelectCategory(val category: Category) : BookInfoEvent()
|
||||
|
|
@ -51,7 +53,7 @@ sealed class BookInfoEvent {
|
|||
) : BookInfoEvent()
|
||||
|
||||
data class OnNavigateToReaderScreen(
|
||||
val navigator: Navigator
|
||||
val onNavigate: OnNavigate
|
||||
) : BookInfoEvent()
|
||||
|
||||
data object OnDismissConfirmUpdateDialog : BookInfoEvent()
|
||||
|
|
|
|||
|
|
@ -22,15 +22,14 @@ import ua.acclorite.book_story.domain.model.Category
|
|||
import ua.acclorite.book_story.domain.model.History
|
||||
import ua.acclorite.book_story.domain.model.NullableBook
|
||||
import ua.acclorite.book_story.domain.use_case.DeleteBooks
|
||||
import ua.acclorite.book_story.domain.use_case.GetBookById
|
||||
import ua.acclorite.book_story.domain.use_case.GetBookFromFile
|
||||
import ua.acclorite.book_story.domain.use_case.GetBooksById
|
||||
import ua.acclorite.book_story.domain.use_case.GetText
|
||||
import ua.acclorite.book_story.domain.use_case.InsertHistory
|
||||
import ua.acclorite.book_story.domain.use_case.UpdateBookWithText
|
||||
import ua.acclorite.book_story.domain.use_case.UpdateBooks
|
||||
import ua.acclorite.book_story.domain.use_case.UpdateCoverImageOfBook
|
||||
import ua.acclorite.book_story.presentation.data.Argument
|
||||
import ua.acclorite.book_story.presentation.data.Navigator
|
||||
import ua.acclorite.book_story.domain.util.OnNavigate
|
||||
import ua.acclorite.book_story.presentation.data.Screen
|
||||
import java.io.File
|
||||
import java.util.Date
|
||||
|
|
@ -45,7 +44,7 @@ class BookInfoViewModel @Inject constructor(
|
|||
private val insertHistory: InsertHistory,
|
||||
private val deleteBooks: DeleteBooks,
|
||||
private val getBookFromFile: GetBookFromFile,
|
||||
private val getBookById: GetBooksById,
|
||||
private val getBookById: GetBookById,
|
||||
private val getText: GetText
|
||||
) : ViewModel() {
|
||||
|
||||
|
|
@ -76,11 +75,8 @@ class BookInfoViewModel @Inject constructor(
|
|||
image
|
||||
)
|
||||
|
||||
val newCoverImage = getBookById.execute(
|
||||
listOf(
|
||||
_state.value.book.id
|
||||
)
|
||||
).first().coverImage
|
||||
val newCoverImage =
|
||||
getBookById.execute(_state.value.book.id)?.coverImage ?: return@launch
|
||||
|
||||
_state.update {
|
||||
it.copy(
|
||||
|
|
@ -197,7 +193,9 @@ class BookInfoViewModel @Inject constructor(
|
|||
deleteBooks.execute(listOf(_state.value.book))
|
||||
event.refreshList()
|
||||
|
||||
event.navigator.navigateBack()
|
||||
event.onNavigate {
|
||||
navigateBack()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -240,7 +238,12 @@ class BookInfoViewModel @Inject constructor(
|
|||
it != _state.value.selectedCategory
|
||||
}.size - 1
|
||||
)
|
||||
event.navigator.navigate(Screen.LIBRARY, true)
|
||||
event.onNavigate {
|
||||
navigate(
|
||||
Screen.Library,
|
||||
useBackAnimation = true
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -553,9 +556,35 @@ class BookInfoViewModel @Inject constructor(
|
|||
}
|
||||
|
||||
if (_state.value.textChanged) {
|
||||
val newBook = getBookById.execute(
|
||||
listOf(_state.value.book.id)
|
||||
).first()
|
||||
val newBook = getBookById.execute(_state.value.book.id)
|
||||
|
||||
if (newBook == null) {
|
||||
onEvent(
|
||||
BookInfoEvent.OnShowSnackbar(
|
||||
text = event.context.getString(
|
||||
R.string.error_something_went_wrong_with_file
|
||||
),
|
||||
action = event.context.getString(R.string.retry),
|
||||
onAction = {
|
||||
onEvent(
|
||||
BookInfoEvent.OnLoadUpdate(
|
||||
snackbarState = event.snackbarState,
|
||||
context = event.context
|
||||
)
|
||||
)
|
||||
},
|
||||
durationMillis = 4000L,
|
||||
snackbarState = event.snackbarState
|
||||
)
|
||||
)
|
||||
delay(500)
|
||||
_state.update {
|
||||
it.copy(
|
||||
isRefreshing = false
|
||||
)
|
||||
}
|
||||
return@launch
|
||||
}
|
||||
|
||||
_state.update {
|
||||
it.copy(
|
||||
|
|
@ -611,36 +640,29 @@ class BookInfoViewModel @Inject constructor(
|
|||
)
|
||||
)
|
||||
}
|
||||
event.navigator.navigate(
|
||||
Screen.READER,
|
||||
false,
|
||||
Argument(
|
||||
"book", _state.value.book.id
|
||||
event.onNavigate {
|
||||
navigate(
|
||||
Screen.Reader(_state.value.book.id)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun init(navigator: Navigator) {
|
||||
fun init(screen: Screen.BookInfo, onNavigate: OnNavigate) {
|
||||
viewModelScope.launch {
|
||||
val bookId = navigator.retrieveArgument("book") as? Int
|
||||
val book = getBookById.execute(screen.bookId)
|
||||
|
||||
if (bookId == null) {
|
||||
navigator.navigateBack()
|
||||
return@launch
|
||||
}
|
||||
|
||||
val book = getBookById.execute(listOf(bookId))
|
||||
|
||||
if (book.isEmpty()) {
|
||||
navigator.navigateBack()
|
||||
if (book == null) {
|
||||
onNavigate {
|
||||
navigateBack()
|
||||
}
|
||||
return@launch
|
||||
}
|
||||
|
||||
_state.update {
|
||||
BookInfoState(book = book.first())
|
||||
BookInfoState(book = book)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@ import androidx.hilt.navigation.compose.hiltViewModel
|
|||
import com.google.accompanist.permissions.ExperimentalPermissionsApi
|
||||
import com.google.accompanist.permissions.rememberPermissionState
|
||||
import ua.acclorite.book_story.R
|
||||
import ua.acclorite.book_story.domain.util.OnNavigate
|
||||
import ua.acclorite.book_story.presentation.components.AnimatedTopAppBar
|
||||
import ua.acclorite.book_story.presentation.components.CustomAnimatedVisibility
|
||||
import ua.acclorite.book_story.presentation.components.CustomIconButton
|
||||
|
|
@ -55,7 +56,6 @@ import ua.acclorite.book_story.presentation.components.customItems
|
|||
import ua.acclorite.book_story.presentation.components.is_messages.IsEmpty
|
||||
import ua.acclorite.book_story.presentation.components.is_messages.IsError
|
||||
import ua.acclorite.book_story.presentation.data.LocalNavigator
|
||||
import ua.acclorite.book_story.presentation.data.Navigator
|
||||
import ua.acclorite.book_story.presentation.data.Screen
|
||||
import ua.acclorite.book_story.presentation.screens.browse.components.BrowseFileItem
|
||||
import ua.acclorite.book_story.presentation.screens.browse.components.BrowseStoragePermissionDialog
|
||||
|
|
@ -78,7 +78,7 @@ fun BrowseScreenRoot() {
|
|||
|
||||
BrowseScreen(
|
||||
state = state,
|
||||
navigator = navigator,
|
||||
onNavigate = { navigator.it() },
|
||||
onEvent = viewModel::onEvent,
|
||||
onLibraryEvent = libraryViewModel::onEvent
|
||||
)
|
||||
|
|
@ -92,7 +92,7 @@ fun BrowseScreenRoot() {
|
|||
@Composable
|
||||
private fun BrowseScreen(
|
||||
state: State<BrowseState>,
|
||||
navigator: Navigator,
|
||||
onNavigate: OnNavigate,
|
||||
onEvent: (BrowseEvent) -> Unit,
|
||||
onLibraryEvent: (LibraryEvent) -> Unit
|
||||
) {
|
||||
|
|
@ -303,7 +303,11 @@ private fun BrowseScreen(
|
|||
message = stringResource(id = R.string.browse_empty),
|
||||
icon = painterResource(id = R.drawable.empty_browse),
|
||||
actionTitle = stringResource(id = R.string.get_help),
|
||||
action = { navigator.navigate(Screen.HELP, false) }
|
||||
action = {
|
||||
onNavigate {
|
||||
navigate(Screen.Help(false))
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -328,7 +332,9 @@ private fun BrowseScreen(
|
|||
return@BackHandler
|
||||
}
|
||||
|
||||
navigator.navigate(Screen.LIBRARY, false)
|
||||
onNavigate {
|
||||
navigate(Screen.Library)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -27,7 +27,12 @@ import ua.acclorite.book_story.presentation.screens.browse.data.BrowseState
|
|||
import ua.acclorite.book_story.presentation.screens.library.data.LibraryEvent
|
||||
|
||||
/**
|
||||
* Adding dialog. Adds all selected books to the Library.
|
||||
* Adding dialog.
|
||||
* Adds all selected books to the Library.
|
||||
*
|
||||
* @param state [BrowseState].
|
||||
* @param onEvent [BrowseEvent] callback.
|
||||
* @param onLibraryEvent [LibraryEvent] callback.
|
||||
*/
|
||||
@Composable
|
||||
fun BrowseAddingDialog(
|
||||
|
|
@ -49,7 +54,7 @@ fun BrowseAddingDialog(
|
|||
onAction = {
|
||||
onEvent(
|
||||
BrowseEvent.OnAddBooks(
|
||||
navigator,
|
||||
onNavigate = { navigator.it() },
|
||||
resetScroll = {
|
||||
onLibraryEvent(LibraryEvent.OnUpdateCurrentPage(0))
|
||||
onLibraryEvent(LibraryEvent.OnLoadList)
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@ import androidx.compose.ui.focus.FocusRequester
|
|||
import com.google.accompanist.permissions.ExperimentalPermissionsApi
|
||||
import com.google.accompanist.permissions.PermissionState
|
||||
import ua.acclorite.book_story.domain.model.NullableBook
|
||||
import ua.acclorite.book_story.domain.util.OnNavigate
|
||||
import ua.acclorite.book_story.domain.util.Selected
|
||||
import ua.acclorite.book_story.presentation.data.Navigator
|
||||
import java.io.File
|
||||
|
||||
@Immutable
|
||||
|
|
@ -21,7 +21,8 @@ sealed class BrowseEvent {
|
|||
) : BrowseEvent()
|
||||
|
||||
data class OnStoragePermissionDismiss(
|
||||
val permissionState: PermissionState, val showErrorMessage: () -> Unit
|
||||
val permissionState: PermissionState,
|
||||
val showErrorMessage: () -> Unit
|
||||
) : BrowseEvent()
|
||||
|
||||
data object OnRefreshList : BrowseEvent()
|
||||
|
|
@ -41,7 +42,7 @@ sealed class BrowseEvent {
|
|||
data object OnAddingDialogDismiss : BrowseEvent()
|
||||
data object OnGetBooksFromFiles : BrowseEvent()
|
||||
data class OnAddBooks(
|
||||
val navigator: Navigator,
|
||||
val onNavigate: OnNavigate,
|
||||
val resetScroll: () -> Unit,
|
||||
val onFailed: () -> Unit,
|
||||
val onSuccess: () -> Unit
|
||||
|
|
|
|||
|
|
@ -396,10 +396,9 @@ class BrowseViewModel @Inject constructor(
|
|||
}
|
||||
|
||||
event.resetScroll()
|
||||
event.navigator.navigate(
|
||||
Screen.LIBRARY,
|
||||
false
|
||||
)
|
||||
event.onNavigate {
|
||||
navigate(Screen.Library)
|
||||
}
|
||||
event.onSuccess()
|
||||
|
||||
_state.update {
|
||||
|
|
|
|||
|
|
@ -33,13 +33,13 @@ import androidx.compose.ui.res.stringResource
|
|||
import androidx.compose.ui.unit.dp
|
||||
import androidx.hilt.navigation.compose.hiltViewModel
|
||||
import ua.acclorite.book_story.R
|
||||
import ua.acclorite.book_story.domain.util.OnNavigate
|
||||
import ua.acclorite.book_story.presentation.components.CustomIconButton
|
||||
import ua.acclorite.book_story.presentation.components.GoBackButton
|
||||
import ua.acclorite.book_story.presentation.components.collapsibleUntilExitScrollBehaviorWithLazyListState
|
||||
import ua.acclorite.book_story.presentation.data.LocalNavigator
|
||||
import ua.acclorite.book_story.presentation.data.MainEvent
|
||||
import ua.acclorite.book_story.presentation.data.MainViewModel
|
||||
import ua.acclorite.book_story.presentation.data.Navigator
|
||||
import ua.acclorite.book_story.presentation.data.Screen
|
||||
import ua.acclorite.book_story.presentation.screens.browse.data.BrowseEvent
|
||||
import ua.acclorite.book_story.presentation.screens.browse.data.BrowseViewModel
|
||||
|
|
@ -63,7 +63,7 @@ import ua.acclorite.book_story.presentation.screens.start.data.StartEvent
|
|||
import ua.acclorite.book_story.presentation.screens.start.data.StartViewModel
|
||||
|
||||
@Composable
|
||||
fun HelpScreenRoot() {
|
||||
fun HelpScreenRoot(screen: Screen.Help) {
|
||||
val navigator = LocalNavigator.current
|
||||
val helpViewModel: HelpViewModel = hiltViewModel()
|
||||
val browseViewModel: BrowseViewModel = hiltViewModel()
|
||||
|
|
@ -73,12 +73,12 @@ fun HelpScreenRoot() {
|
|||
val state = helpViewModel.state.collectAsState()
|
||||
|
||||
LaunchedEffect(Unit) {
|
||||
helpViewModel.init(navigator)
|
||||
helpViewModel.init(screen = screen)
|
||||
}
|
||||
|
||||
HelpScreen(
|
||||
state = state,
|
||||
navigator = navigator,
|
||||
onNavigate = { navigator.it() },
|
||||
onEvent = helpViewModel::onEvent,
|
||||
onMainEvent = mainViewModel::onEvent,
|
||||
onBrowseEvent = browseViewModel::onEvent,
|
||||
|
|
@ -92,7 +92,7 @@ fun HelpScreenRoot() {
|
|||
@Composable
|
||||
private fun HelpScreen(
|
||||
state: State<HelpState>,
|
||||
navigator: Navigator,
|
||||
onNavigate: OnNavigate,
|
||||
onEvent: (HelpEvent) -> Unit,
|
||||
onMainEvent: (MainEvent) -> Unit,
|
||||
onBrowseEvent: (BrowseEvent) -> Unit,
|
||||
|
|
@ -113,7 +113,7 @@ private fun HelpScreen(
|
|||
},
|
||||
navigationIcon = {
|
||||
if (!state.value.fromStart) {
|
||||
GoBackButton(navigator = navigator)
|
||||
GoBackButton(onNavigate = onNavigate)
|
||||
}
|
||||
},
|
||||
actions = {
|
||||
|
|
@ -125,8 +125,10 @@ private fun HelpScreen(
|
|||
) {
|
||||
onStartEvent(StartEvent.OnResetStartScreen)
|
||||
onMainEvent(MainEvent.OnChangeShowStartScreen(true))
|
||||
navigator.navigateWithoutBackStack(Screen.START, false)
|
||||
navigator.clearBackStack()
|
||||
onNavigate {
|
||||
navigate(Screen.Start, saveInBackStack = false)
|
||||
clearBackStack()
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -149,11 +151,11 @@ private fun HelpScreen(
|
|||
.fillMaxWidth(),
|
||||
shape = RoundedCornerShape(100),
|
||||
onClick = {
|
||||
navigator.clearArgument("from_start")
|
||||
|
||||
onBrowseEvent(BrowseEvent.OnLoadList)
|
||||
onMainEvent(MainEvent.OnChangeShowStartScreen(false))
|
||||
navigator.navigateWithoutBackStack(Screen.BROWSE, false)
|
||||
onNavigate {
|
||||
navigate(Screen.Browse, saveInBackStack = false)
|
||||
}
|
||||
}
|
||||
) {
|
||||
Text(text = stringResource(id = R.string.done))
|
||||
|
|
@ -203,6 +205,7 @@ private fun HelpScreen(
|
|||
item {
|
||||
HelpAddBooksItem(
|
||||
state = state,
|
||||
onNavigate = onNavigate,
|
||||
onEvent = onEvent
|
||||
)
|
||||
}
|
||||
|
|
@ -210,6 +213,7 @@ private fun HelpScreen(
|
|||
item {
|
||||
HelpCustomizeApp(
|
||||
state = state,
|
||||
onNavigate = onNavigate,
|
||||
onEvent = onEvent
|
||||
)
|
||||
}
|
||||
|
|
@ -217,6 +221,7 @@ private fun HelpScreen(
|
|||
item {
|
||||
HelpMoveOrDeleteBooks(
|
||||
state = state,
|
||||
onNavigate = onNavigate,
|
||||
onEvent = onEvent
|
||||
)
|
||||
}
|
||||
|
|
@ -224,6 +229,7 @@ private fun HelpScreen(
|
|||
item {
|
||||
HelpEditBook(
|
||||
state = state,
|
||||
onNavigate = onNavigate,
|
||||
onEvent = onEvent
|
||||
)
|
||||
}
|
||||
|
|
@ -231,6 +237,7 @@ private fun HelpScreen(
|
|||
item {
|
||||
HelpReadBook(
|
||||
state = state,
|
||||
onNavigate = onNavigate,
|
||||
onEvent = onEvent
|
||||
)
|
||||
}
|
||||
|
|
@ -238,6 +245,7 @@ private fun HelpScreen(
|
|||
item {
|
||||
HelpCustomizeReader(
|
||||
state = state,
|
||||
onNavigate = onNavigate,
|
||||
onEvent = onEvent
|
||||
)
|
||||
}
|
||||
|
|
@ -245,6 +253,7 @@ private fun HelpScreen(
|
|||
item {
|
||||
HelpUpdateBook(
|
||||
state = state,
|
||||
onNavigate = onNavigate,
|
||||
onEvent = onEvent
|
||||
)
|
||||
}
|
||||
|
|
@ -252,6 +261,7 @@ private fun HelpScreen(
|
|||
item {
|
||||
HelpManageHistory(
|
||||
state = state,
|
||||
onNavigate = onNavigate,
|
||||
onEvent = onEvent
|
||||
)
|
||||
}
|
||||
|
|
@ -266,6 +276,7 @@ private fun HelpScreen(
|
|||
item {
|
||||
HelpSetUpTranslator(
|
||||
state = state,
|
||||
onNavigate = onNavigate,
|
||||
onEvent = onEvent
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import androidx.compose.runtime.State
|
|||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.buildAnnotatedString
|
||||
import ua.acclorite.book_story.R
|
||||
import ua.acclorite.book_story.presentation.data.LocalNavigator
|
||||
import ua.acclorite.book_story.domain.util.OnNavigate
|
||||
import ua.acclorite.book_story.presentation.data.Screen
|
||||
import ua.acclorite.book_story.presentation.screens.help.components.HelpAnnotation
|
||||
import ua.acclorite.book_story.presentation.screens.help.components.HelpItem
|
||||
|
|
@ -16,10 +16,9 @@ import ua.acclorite.book_story.presentation.screens.help.data.HelpState
|
|||
@Composable
|
||||
fun LazyItemScope.HelpAddBooksItem(
|
||||
state: State<HelpState>,
|
||||
onNavigate: OnNavigate,
|
||||
onEvent: (HelpEvent) -> Unit
|
||||
) {
|
||||
val navigator = LocalNavigator.current
|
||||
|
||||
HelpItem(
|
||||
title = stringResource(id = R.string.help_title_how_to_add_books),
|
||||
description = buildAnnotatedString {
|
||||
|
|
@ -49,16 +48,18 @@ fun LazyItemScope.HelpAddBooksItem(
|
|||
)
|
||||
},
|
||||
onTagClick = { tag ->
|
||||
when (tag) {
|
||||
"browse" -> {
|
||||
if (!state.value.fromStart) {
|
||||
navigator.navigate(Screen.BROWSE, true)
|
||||
onNavigate {
|
||||
when (tag) {
|
||||
"browse" -> {
|
||||
if (!state.value.fromStart) {
|
||||
navigate(Screen.Browse, useBackAnimation = true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
"library" -> {
|
||||
if (!state.value.fromStart) {
|
||||
navigator.navigate(Screen.LIBRARY, true)
|
||||
"library" -> {
|
||||
if (!state.value.fromStart) {
|
||||
navigate(Screen.Library, useBackAnimation = true)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import androidx.compose.runtime.State
|
|||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.buildAnnotatedString
|
||||
import ua.acclorite.book_story.R
|
||||
import ua.acclorite.book_story.presentation.data.LocalNavigator
|
||||
import ua.acclorite.book_story.domain.util.OnNavigate
|
||||
import ua.acclorite.book_story.presentation.data.Screen
|
||||
import ua.acclorite.book_story.presentation.screens.help.components.HelpAnnotation
|
||||
import ua.acclorite.book_story.presentation.screens.help.components.HelpItem
|
||||
|
|
@ -16,10 +16,9 @@ import ua.acclorite.book_story.presentation.screens.help.data.HelpState
|
|||
@Composable
|
||||
fun LazyItemScope.HelpCustomizeApp(
|
||||
state: State<HelpState>,
|
||||
onNavigate: OnNavigate,
|
||||
onEvent: (HelpEvent) -> Unit
|
||||
) {
|
||||
val navigator = LocalNavigator.current
|
||||
|
||||
HelpItem(
|
||||
title = stringResource(id = R.string.help_title_how_to_customize_app),
|
||||
description = buildAnnotatedString {
|
||||
|
|
@ -44,10 +43,12 @@ fun LazyItemScope.HelpCustomizeApp(
|
|||
)
|
||||
},
|
||||
onTagClick = { tag ->
|
||||
when (tag) {
|
||||
"settings" -> {
|
||||
if (!state.value.fromStart) {
|
||||
navigator.navigate(Screen.SETTINGS, true)
|
||||
onNavigate {
|
||||
when (tag) {
|
||||
"settings" -> {
|
||||
if (!state.value.fromStart) {
|
||||
navigate(Screen.Settings, useBackAnimation = true)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import androidx.compose.runtime.State
|
|||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.buildAnnotatedString
|
||||
import ua.acclorite.book_story.R
|
||||
import ua.acclorite.book_story.presentation.data.LocalNavigator
|
||||
import ua.acclorite.book_story.domain.util.OnNavigate
|
||||
import ua.acclorite.book_story.presentation.data.Screen
|
||||
import ua.acclorite.book_story.presentation.screens.help.components.HelpAnnotation
|
||||
import ua.acclorite.book_story.presentation.screens.help.components.HelpItem
|
||||
|
|
@ -16,10 +16,9 @@ import ua.acclorite.book_story.presentation.screens.help.data.HelpState
|
|||
@Composable
|
||||
fun LazyItemScope.HelpCustomizeReader(
|
||||
state: State<HelpState>,
|
||||
onNavigate: OnNavigate,
|
||||
onEvent: (HelpEvent) -> Unit
|
||||
) {
|
||||
val navigator = LocalNavigator.current
|
||||
|
||||
HelpItem(
|
||||
title = stringResource(id = R.string.help_title_how_to_customize_reader),
|
||||
description = buildAnnotatedString {
|
||||
|
|
@ -44,10 +43,12 @@ fun LazyItemScope.HelpCustomizeReader(
|
|||
)
|
||||
},
|
||||
onTagClick = { tag ->
|
||||
when (tag) {
|
||||
"settings" -> {
|
||||
if (!state.value.fromStart) {
|
||||
navigator.navigate(Screen.SETTINGS, true)
|
||||
onNavigate {
|
||||
when (tag) {
|
||||
"settings" -> {
|
||||
if (!state.value.fromStart) {
|
||||
navigate(Screen.Settings, useBackAnimation = true)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import androidx.compose.runtime.State
|
|||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.buildAnnotatedString
|
||||
import ua.acclorite.book_story.R
|
||||
import ua.acclorite.book_story.presentation.data.LocalNavigator
|
||||
import ua.acclorite.book_story.domain.util.OnNavigate
|
||||
import ua.acclorite.book_story.presentation.data.Screen
|
||||
import ua.acclorite.book_story.presentation.screens.help.components.HelpAnnotation
|
||||
import ua.acclorite.book_story.presentation.screens.help.components.HelpItem
|
||||
|
|
@ -16,10 +16,9 @@ import ua.acclorite.book_story.presentation.screens.help.data.HelpState
|
|||
@Composable
|
||||
fun LazyItemScope.HelpEditBook(
|
||||
state: State<HelpState>,
|
||||
onNavigate: OnNavigate,
|
||||
onEvent: (HelpEvent) -> Unit
|
||||
) {
|
||||
val navigator = LocalNavigator.current
|
||||
|
||||
HelpItem(
|
||||
title = stringResource(id = R.string.help_title_how_to_edit_book),
|
||||
description = buildAnnotatedString {
|
||||
|
|
@ -44,10 +43,12 @@ fun LazyItemScope.HelpEditBook(
|
|||
)
|
||||
},
|
||||
onTagClick = { tag ->
|
||||
when (tag) {
|
||||
"library" -> {
|
||||
if (!state.value.fromStart) {
|
||||
navigator.navigate(Screen.LIBRARY, true)
|
||||
onNavigate {
|
||||
when (tag) {
|
||||
"library" -> {
|
||||
if (!state.value.fromStart) {
|
||||
navigate(Screen.Library, useBackAnimation = true)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import androidx.compose.runtime.State
|
|||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.buildAnnotatedString
|
||||
import ua.acclorite.book_story.R
|
||||
import ua.acclorite.book_story.presentation.data.LocalNavigator
|
||||
import ua.acclorite.book_story.domain.util.OnNavigate
|
||||
import ua.acclorite.book_story.presentation.data.Screen
|
||||
import ua.acclorite.book_story.presentation.screens.help.components.HelpAnnotation
|
||||
import ua.acclorite.book_story.presentation.screens.help.components.HelpItem
|
||||
|
|
@ -16,10 +16,9 @@ import ua.acclorite.book_story.presentation.screens.help.data.HelpState
|
|||
@Composable
|
||||
fun LazyItemScope.HelpManageHistory(
|
||||
state: State<HelpState>,
|
||||
onNavigate: OnNavigate,
|
||||
onEvent: (HelpEvent) -> Unit
|
||||
) {
|
||||
val navigator = LocalNavigator.current
|
||||
|
||||
HelpItem(
|
||||
title = stringResource(id = R.string.help_title_how_to_manage_history),
|
||||
description = buildAnnotatedString {
|
||||
|
|
@ -44,10 +43,12 @@ fun LazyItemScope.HelpManageHistory(
|
|||
)
|
||||
},
|
||||
onTagClick = { tag ->
|
||||
when (tag) {
|
||||
"history" -> {
|
||||
if (!state.value.fromStart) {
|
||||
navigator.navigate(Screen.HISTORY, true)
|
||||
onNavigate {
|
||||
when (tag) {
|
||||
"history" -> {
|
||||
if (!state.value.fromStart) {
|
||||
navigate(Screen.History, useBackAnimation = true)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import androidx.compose.runtime.State
|
|||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.buildAnnotatedString
|
||||
import ua.acclorite.book_story.R
|
||||
import ua.acclorite.book_story.presentation.data.LocalNavigator
|
||||
import ua.acclorite.book_story.domain.util.OnNavigate
|
||||
import ua.acclorite.book_story.presentation.data.Screen
|
||||
import ua.acclorite.book_story.presentation.screens.help.components.HelpAnnotation
|
||||
import ua.acclorite.book_story.presentation.screens.help.components.HelpItem
|
||||
|
|
@ -16,10 +16,9 @@ import ua.acclorite.book_story.presentation.screens.help.data.HelpState
|
|||
@Composable
|
||||
fun LazyItemScope.HelpMoveOrDeleteBooks(
|
||||
state: State<HelpState>,
|
||||
onNavigate: OnNavigate,
|
||||
onEvent: (HelpEvent) -> Unit
|
||||
) {
|
||||
val navigator = LocalNavigator.current
|
||||
|
||||
HelpItem(
|
||||
title = stringResource(id = R.string.help_title_how_to_move_or_delete_books),
|
||||
description = buildAnnotatedString {
|
||||
|
|
@ -44,10 +43,12 @@ fun LazyItemScope.HelpMoveOrDeleteBooks(
|
|||
)
|
||||
},
|
||||
onTagClick = { tag ->
|
||||
when (tag) {
|
||||
"library" -> {
|
||||
if (!state.value.fromStart) {
|
||||
navigator.navigate(Screen.LIBRARY, true)
|
||||
onNavigate {
|
||||
when (tag) {
|
||||
"library" -> {
|
||||
if (!state.value.fromStart) {
|
||||
navigate(Screen.Library, useBackAnimation = true)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import androidx.compose.runtime.State
|
|||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.buildAnnotatedString
|
||||
import ua.acclorite.book_story.R
|
||||
import ua.acclorite.book_story.presentation.data.LocalNavigator
|
||||
import ua.acclorite.book_story.domain.util.OnNavigate
|
||||
import ua.acclorite.book_story.presentation.data.Screen
|
||||
import ua.acclorite.book_story.presentation.screens.help.components.HelpAnnotation
|
||||
import ua.acclorite.book_story.presentation.screens.help.components.HelpItem
|
||||
|
|
@ -16,10 +16,9 @@ import ua.acclorite.book_story.presentation.screens.help.data.HelpState
|
|||
@Composable
|
||||
fun LazyItemScope.HelpReadBook(
|
||||
state: State<HelpState>,
|
||||
onNavigate: OnNavigate,
|
||||
onEvent: (HelpEvent) -> Unit
|
||||
) {
|
||||
val navigator = LocalNavigator.current
|
||||
|
||||
HelpItem(
|
||||
title = stringResource(id = R.string.help_title_how_to_read_book),
|
||||
description = buildAnnotatedString {
|
||||
|
|
@ -44,10 +43,12 @@ fun LazyItemScope.HelpReadBook(
|
|||
)
|
||||
},
|
||||
onTagClick = { tag ->
|
||||
when (tag) {
|
||||
"library" -> {
|
||||
if (!state.value.fromStart) {
|
||||
navigator.navigate(Screen.LIBRARY, true)
|
||||
onNavigate {
|
||||
when (tag) {
|
||||
"library" -> {
|
||||
if (!state.value.fromStart) {
|
||||
navigate(Screen.Library, useBackAnimation = true)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import androidx.compose.runtime.State
|
|||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.buildAnnotatedString
|
||||
import ua.acclorite.book_story.R
|
||||
import ua.acclorite.book_story.presentation.data.LocalNavigator
|
||||
import ua.acclorite.book_story.domain.util.OnNavigate
|
||||
import ua.acclorite.book_story.presentation.data.Screen
|
||||
import ua.acclorite.book_story.presentation.screens.help.components.HelpAnnotation
|
||||
import ua.acclorite.book_story.presentation.screens.help.components.HelpItem
|
||||
|
|
@ -16,10 +16,9 @@ import ua.acclorite.book_story.presentation.screens.help.data.HelpState
|
|||
@Composable
|
||||
fun LazyItemScope.HelpSetUpTranslator(
|
||||
state: State<HelpState>,
|
||||
onNavigate: OnNavigate,
|
||||
onEvent: (HelpEvent) -> Unit
|
||||
) {
|
||||
val navigator = LocalNavigator.current
|
||||
|
||||
HelpItem(
|
||||
title = stringResource(id = R.string.help_title_how_to_set_up_translator),
|
||||
description = buildAnnotatedString {
|
||||
|
|
@ -44,10 +43,12 @@ fun LazyItemScope.HelpSetUpTranslator(
|
|||
)
|
||||
},
|
||||
onTagClick = { tag ->
|
||||
when (tag) {
|
||||
"reader_settings" -> {
|
||||
if (!state.value.fromStart) {
|
||||
navigator.navigate(Screen.READER_SETTINGS, true)
|
||||
onNavigate {
|
||||
when (tag) {
|
||||
"reader_settings" -> {
|
||||
if (!state.value.fromStart) {
|
||||
navigate(Screen.Settings.ReaderSettings, useBackAnimation = true)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import androidx.compose.runtime.State
|
|||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.buildAnnotatedString
|
||||
import ua.acclorite.book_story.R
|
||||
import ua.acclorite.book_story.presentation.data.LocalNavigator
|
||||
import ua.acclorite.book_story.domain.util.OnNavigate
|
||||
import ua.acclorite.book_story.presentation.data.Screen
|
||||
import ua.acclorite.book_story.presentation.screens.help.components.HelpAnnotation
|
||||
import ua.acclorite.book_story.presentation.screens.help.components.HelpItem
|
||||
|
|
@ -16,10 +16,9 @@ import ua.acclorite.book_story.presentation.screens.help.data.HelpState
|
|||
@Composable
|
||||
fun LazyItemScope.HelpUpdateBook(
|
||||
state: State<HelpState>,
|
||||
onNavigate: OnNavigate,
|
||||
onEvent: (HelpEvent) -> Unit
|
||||
) {
|
||||
val navigator = LocalNavigator.current
|
||||
|
||||
HelpItem(
|
||||
title = stringResource(id = R.string.help_title_how_to_update_book),
|
||||
description = buildAnnotatedString {
|
||||
|
|
@ -44,10 +43,12 @@ fun LazyItemScope.HelpUpdateBook(
|
|||
)
|
||||
},
|
||||
onTagClick = { tag ->
|
||||
when (tag) {
|
||||
"library" -> {
|
||||
if (!state.value.fromStart) {
|
||||
navigator.navigate(Screen.LIBRARY, true)
|
||||
onNavigate {
|
||||
when (tag) {
|
||||
"library" -> {
|
||||
if (!state.value.fromStart) {
|
||||
navigate(Screen.Library, useBackAnimation = true)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import kotlinx.coroutines.flow.MutableStateFlow
|
|||
import kotlinx.coroutines.flow.asStateFlow
|
||||
import kotlinx.coroutines.flow.update
|
||||
import kotlinx.coroutines.launch
|
||||
import ua.acclorite.book_story.presentation.data.Navigator
|
||||
import ua.acclorite.book_story.presentation.data.Screen
|
||||
import javax.inject.Inject
|
||||
|
||||
@HiltViewModel
|
||||
|
|
@ -75,13 +75,11 @@ class HelpViewModel @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
fun init(navigator: Navigator) {
|
||||
fun init(screen: Screen.Help) {
|
||||
viewModelScope.launch {
|
||||
val isFromStart = navigator.retrieveArgument("from_start") as? Boolean ?: false
|
||||
|
||||
_state.update {
|
||||
it.copy(
|
||||
fromStart = isFromStart
|
||||
fromStart = screen.fromStart
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ import androidx.compose.ui.res.stringResource
|
|||
import androidx.compose.ui.unit.dp
|
||||
import androidx.hilt.navigation.compose.hiltViewModel
|
||||
import ua.acclorite.book_story.R
|
||||
import ua.acclorite.book_story.domain.util.OnNavigate
|
||||
import ua.acclorite.book_story.presentation.components.AnimatedTopAppBar
|
||||
import ua.acclorite.book_story.presentation.components.CategoryTitle
|
||||
import ua.acclorite.book_story.presentation.components.CustomAnimatedVisibility
|
||||
|
|
@ -47,9 +48,7 @@ import ua.acclorite.book_story.presentation.components.CustomSnackbar
|
|||
import ua.acclorite.book_story.presentation.components.MoreDropDown
|
||||
import ua.acclorite.book_story.presentation.components.customItems
|
||||
import ua.acclorite.book_story.presentation.components.is_messages.IsEmpty
|
||||
import ua.acclorite.book_story.presentation.data.Argument
|
||||
import ua.acclorite.book_story.presentation.data.LocalNavigator
|
||||
import ua.acclorite.book_story.presentation.data.Navigator
|
||||
import ua.acclorite.book_story.presentation.data.Screen
|
||||
import ua.acclorite.book_story.presentation.screens.history.components.HistoryDeleteWholeHistoryDialog
|
||||
import ua.acclorite.book_story.presentation.screens.history.components.HistoryItem
|
||||
|
|
@ -71,7 +70,7 @@ fun HistoryScreenRoot() {
|
|||
|
||||
HistoryScreen(
|
||||
state = state,
|
||||
navigator = navigator,
|
||||
onNavigate = { navigator.it() },
|
||||
onEvent = viewModel::onEvent,
|
||||
onLibraryEvent = libraryViewModel::onEvent
|
||||
)
|
||||
|
|
@ -84,7 +83,7 @@ fun HistoryScreenRoot() {
|
|||
@Composable
|
||||
private fun HistoryScreen(
|
||||
state: State<HistoryState>,
|
||||
navigator: Navigator,
|
||||
onNavigate: OnNavigate,
|
||||
onEvent: (HistoryEvent) -> Unit,
|
||||
onLibraryEvent: (LibraryEvent) -> Unit
|
||||
) {
|
||||
|
|
@ -230,17 +229,17 @@ private fun HistoryScreen(
|
|||
history = it,
|
||||
isOnClickEnabled = !state.value.isRefreshing,
|
||||
onBodyClick = {
|
||||
navigator.navigate(
|
||||
Screen.BOOK_INFO,
|
||||
false,
|
||||
Argument("book", it.bookId)
|
||||
)
|
||||
onNavigate {
|
||||
navigate(
|
||||
Screen.BookInfo(it.bookId)
|
||||
)
|
||||
}
|
||||
},
|
||||
onTitleClick = {
|
||||
onEvent(
|
||||
HistoryEvent.OnNavigateToReaderScreen(
|
||||
navigator,
|
||||
it.book!!
|
||||
onNavigate = onNavigate,
|
||||
book = it.book!!
|
||||
)
|
||||
)
|
||||
},
|
||||
|
|
@ -300,7 +299,9 @@ private fun HistoryScreen(
|
|||
return@BackHandler
|
||||
}
|
||||
|
||||
navigator.navigate(Screen.LIBRARY, false)
|
||||
onNavigate {
|
||||
navigate(Screen.Library)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import androidx.compose.runtime.Immutable
|
|||
import androidx.compose.ui.focus.FocusRequester
|
||||
import ua.acclorite.book_story.domain.model.Book
|
||||
import ua.acclorite.book_story.domain.model.History
|
||||
import ua.acclorite.book_story.presentation.data.Navigator
|
||||
import ua.acclorite.book_story.domain.util.OnNavigate
|
||||
|
||||
@Immutable
|
||||
sealed class HistoryEvent {
|
||||
|
|
@ -27,7 +27,7 @@ sealed class HistoryEvent {
|
|||
data class OnRequestFocus(val focusRequester: FocusRequester) : HistoryEvent()
|
||||
data class OnUpdateBook(val book: Book) : HistoryEvent()
|
||||
data class OnNavigateToReaderScreen(
|
||||
val navigator: Navigator,
|
||||
val onNavigate: OnNavigate,
|
||||
val book: Book
|
||||
) : HistoryEvent()
|
||||
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@ import ua.acclorite.book_story.domain.use_case.GetBooksById
|
|||
import ua.acclorite.book_story.domain.use_case.GetHistory
|
||||
import ua.acclorite.book_story.domain.use_case.InsertHistory
|
||||
import ua.acclorite.book_story.domain.util.Resource
|
||||
import ua.acclorite.book_story.presentation.data.Argument
|
||||
import ua.acclorite.book_story.presentation.data.Screen
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Calendar
|
||||
|
|
@ -266,13 +265,9 @@ class HistoryViewModel @Inject constructor(
|
|||
)
|
||||
)
|
||||
}
|
||||
event.navigator.navigate(
|
||||
Screen.READER,
|
||||
false,
|
||||
Argument(
|
||||
"book", event.book.id
|
||||
)
|
||||
)
|
||||
event.onNavigate {
|
||||
navigate(Screen.Reader(event.book.id))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -62,6 +62,7 @@ import kotlinx.coroutines.launch
|
|||
import ua.acclorite.book_story.R
|
||||
import ua.acclorite.book_story.domain.model.Book
|
||||
import ua.acclorite.book_story.domain.model.Category
|
||||
import ua.acclorite.book_story.domain.util.OnNavigate
|
||||
import ua.acclorite.book_story.domain.util.Selected
|
||||
import ua.acclorite.book_story.presentation.components.AnimatedTopAppBar
|
||||
import ua.acclorite.book_story.presentation.components.CustomAnimatedVisibility
|
||||
|
|
@ -71,9 +72,7 @@ import ua.acclorite.book_story.presentation.components.MoreDropDown
|
|||
import ua.acclorite.book_story.presentation.components.customItems
|
||||
import ua.acclorite.book_story.presentation.components.header
|
||||
import ua.acclorite.book_story.presentation.components.is_messages.IsEmpty
|
||||
import ua.acclorite.book_story.presentation.data.Argument
|
||||
import ua.acclorite.book_story.presentation.data.LocalNavigator
|
||||
import ua.acclorite.book_story.presentation.data.Navigator
|
||||
import ua.acclorite.book_story.presentation.data.Screen
|
||||
import ua.acclorite.book_story.presentation.screens.browse.data.BrowseEvent
|
||||
import ua.acclorite.book_story.presentation.screens.browse.data.BrowseViewModel
|
||||
|
|
@ -100,7 +99,7 @@ fun LibraryScreenRoot() {
|
|||
|
||||
LibraryScreen(
|
||||
state = state,
|
||||
navigator = navigator,
|
||||
onNavigate = { navigator.it() },
|
||||
onEvent = viewModel::onEvent,
|
||||
onBrowseEvent = browseViewModel::onEvent,
|
||||
onHistoryEvent = historyViewModel::onEvent
|
||||
|
|
@ -114,7 +113,7 @@ fun LibraryScreenRoot() {
|
|||
@Composable
|
||||
private fun LibraryScreen(
|
||||
state: State<LibraryState>,
|
||||
navigator: Navigator,
|
||||
onNavigate: OnNavigate,
|
||||
onEvent: (LibraryEvent) -> Unit,
|
||||
onHistoryEvent: (HistoryEvent) -> Unit,
|
||||
onBrowseEvent: (BrowseEvent) -> Unit
|
||||
|
|
@ -338,11 +337,9 @@ private fun LibraryScreen(
|
|||
if (state.value.hasSelectedItems) {
|
||||
onEvent(LibraryEvent.OnSelectBook(it))
|
||||
} else {
|
||||
navigator.navigate(
|
||||
Screen.BOOK_INFO,
|
||||
false,
|
||||
Argument("book", it.first.id)
|
||||
)
|
||||
onNavigate {
|
||||
navigate(Screen.BookInfo(it.first.id))
|
||||
}
|
||||
}
|
||||
},
|
||||
onLongClick = {
|
||||
|
|
@ -353,8 +350,8 @@ private fun LibraryScreen(
|
|||
onButtonClick = {
|
||||
onEvent(
|
||||
LibraryEvent.OnNavigateToReaderScreen(
|
||||
navigator,
|
||||
it.first
|
||||
onNavigate = onNavigate,
|
||||
book = it.first
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
@ -381,7 +378,9 @@ private fun LibraryScreen(
|
|||
modifier = Modifier.align(Alignment.Center),
|
||||
actionTitle = stringResource(id = R.string.add_book)
|
||||
) {
|
||||
navigator.navigate(Screen.BROWSE, false)
|
||||
onNavigate {
|
||||
navigate(Screen.Browse)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,8 +5,8 @@ import androidx.compose.runtime.Immutable
|
|||
import androidx.compose.ui.focus.FocusRequester
|
||||
import ua.acclorite.book_story.domain.model.Book
|
||||
import ua.acclorite.book_story.domain.model.Category
|
||||
import ua.acclorite.book_story.domain.util.OnNavigate
|
||||
import ua.acclorite.book_story.domain.util.Selected
|
||||
import ua.acclorite.book_story.presentation.data.Navigator
|
||||
|
||||
@Immutable
|
||||
sealed class LibraryEvent {
|
||||
|
|
@ -30,7 +30,7 @@ sealed class LibraryEvent {
|
|||
data class OnDeleteBooks(val refreshList: () -> Unit) : LibraryEvent()
|
||||
data class OnUpdateBook(val book: Book) : LibraryEvent()
|
||||
data class OnNavigateToReaderScreen(
|
||||
val navigator: Navigator,
|
||||
val onNavigate: OnNavigate,
|
||||
val book: Book
|
||||
) : LibraryEvent()
|
||||
}
|
||||
|
|
@ -18,7 +18,6 @@ import ua.acclorite.book_story.domain.use_case.DeleteBooks
|
|||
import ua.acclorite.book_story.domain.use_case.GetBooks
|
||||
import ua.acclorite.book_story.domain.use_case.InsertHistory
|
||||
import ua.acclorite.book_story.domain.use_case.UpdateBooks
|
||||
import ua.acclorite.book_story.presentation.data.Argument
|
||||
import ua.acclorite.book_story.presentation.data.Screen
|
||||
import java.util.Date
|
||||
import javax.inject.Inject
|
||||
|
|
@ -338,13 +337,9 @@ class LibraryViewModel @Inject constructor(
|
|||
)
|
||||
)
|
||||
}
|
||||
event.navigator.navigate(
|
||||
Screen.READER,
|
||||
false,
|
||||
Argument(
|
||||
"book", event.book.id
|
||||
)
|
||||
)
|
||||
event.onNavigate {
|
||||
navigate(Screen.Reader(event.book.id))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@ import androidx.compose.ui.unit.sp
|
|||
import androidx.hilt.navigation.compose.hiltViewModel
|
||||
import ua.acclorite.book_story.R
|
||||
import ua.acclorite.book_story.domain.util.Constants
|
||||
import ua.acclorite.book_story.domain.util.OnNavigate
|
||||
import ua.acclorite.book_story.presentation.components.CustomAnimatedVisibility
|
||||
import ua.acclorite.book_story.presentation.components.CustomSelectionContainer
|
||||
import ua.acclorite.book_story.presentation.components.customItems
|
||||
|
|
@ -59,7 +60,7 @@ import ua.acclorite.book_story.presentation.data.LocalNavigator
|
|||
import ua.acclorite.book_story.presentation.data.MainEvent
|
||||
import ua.acclorite.book_story.presentation.data.MainState
|
||||
import ua.acclorite.book_story.presentation.data.MainViewModel
|
||||
import ua.acclorite.book_story.presentation.data.Navigator
|
||||
import ua.acclorite.book_story.presentation.data.Screen
|
||||
import ua.acclorite.book_story.presentation.screens.history.data.HistoryEvent
|
||||
import ua.acclorite.book_story.presentation.screens.history.data.HistoryViewModel
|
||||
import ua.acclorite.book_story.presentation.screens.library.data.LibraryEvent
|
||||
|
|
@ -77,7 +78,7 @@ import ua.acclorite.book_story.presentation.screens.reader.data.ReaderState
|
|||
import ua.acclorite.book_story.presentation.screens.reader.data.ReaderViewModel
|
||||
|
||||
@Composable
|
||||
fun ReaderScreenRoot() {
|
||||
fun ReaderScreenRoot(screen: Screen.Reader) {
|
||||
val navigator = LocalNavigator.current
|
||||
val context = LocalContext.current as ComponentActivity
|
||||
|
||||
|
|
@ -103,8 +104,9 @@ fun ReaderScreenRoot() {
|
|||
|
||||
LaunchedEffect(Unit) {
|
||||
viewModel.init(
|
||||
navigator,
|
||||
context,
|
||||
screen = screen,
|
||||
onNavigate = { navigator.it() },
|
||||
context = context,
|
||||
refreshList = {
|
||||
libraryViewModel.onEvent(LibraryEvent.OnUpdateBook(it))
|
||||
historyViewModel.onEvent(HistoryEvent.OnLoadList)
|
||||
|
|
@ -139,8 +141,8 @@ fun ReaderScreenRoot() {
|
|||
ReaderScreen(
|
||||
state = state,
|
||||
mainState = mainState,
|
||||
navigator = navigator,
|
||||
lazyListState = lazyListState,
|
||||
onNavigate = { navigator.it() },
|
||||
onEvent = viewModel::onEvent,
|
||||
onMainEvent = mainViewModel::onEvent,
|
||||
onLibraryEvent = libraryViewModel::onEvent,
|
||||
|
|
@ -153,8 +155,8 @@ fun ReaderScreenRoot() {
|
|||
private fun ReaderScreen(
|
||||
state: State<ReaderState>,
|
||||
mainState: State<MainState>,
|
||||
navigator: Navigator,
|
||||
lazyListState: LazyListState,
|
||||
onNavigate: OnNavigate,
|
||||
onEvent: (ReaderEvent) -> Unit,
|
||||
onMainEvent: (MainEvent) -> Unit,
|
||||
onLibraryEvent: (LibraryEvent) -> Unit,
|
||||
|
|
@ -278,6 +280,7 @@ private fun ReaderScreen(
|
|||
) {
|
||||
ReaderTopBar(
|
||||
state = state,
|
||||
onNavigate = onNavigate,
|
||||
onEvent = onEvent,
|
||||
onLibraryUpdateEvent = onLibraryEvent,
|
||||
onHistoryUpdateEvent = onHistoryEvent
|
||||
|
|
@ -399,6 +402,7 @@ private fun ReaderScreen(
|
|||
DisableSelection {
|
||||
ReaderEndItem(
|
||||
state = state,
|
||||
onNavigate = onNavigate,
|
||||
onEvent = onEvent,
|
||||
onLibraryEvent = onLibraryEvent,
|
||||
onHistoryUpdateEvent = onHistoryEvent,
|
||||
|
|
@ -427,13 +431,14 @@ private fun ReaderScreen(
|
|||
onEvent(
|
||||
ReaderEvent.OnGoBack(
|
||||
context,
|
||||
navigator,
|
||||
refreshList = {
|
||||
onLibraryEvent(LibraryEvent.OnUpdateBook(it))
|
||||
onHistoryEvent(HistoryEvent.OnUpdateBook(it))
|
||||
},
|
||||
navigate = {
|
||||
it.navigateBack()
|
||||
onNavigate {
|
||||
navigateBack()
|
||||
}
|
||||
}
|
||||
)
|
||||
)
|
||||
|
|
@ -461,13 +466,14 @@ private fun ReaderScreen(
|
|||
onEvent(
|
||||
ReaderEvent.OnGoBack(
|
||||
context,
|
||||
navigator,
|
||||
refreshList = {
|
||||
onLibraryEvent(LibraryEvent.OnUpdateBook(it))
|
||||
onHistoryEvent(HistoryEvent.OnUpdateBook(it))
|
||||
},
|
||||
navigate = {
|
||||
it.navigateBack()
|
||||
onNavigate {
|
||||
navigateBack()
|
||||
}
|
||||
}
|
||||
)
|
||||
)
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ import androidx.compose.ui.text.style.TextOverflow
|
|||
import androidx.compose.ui.unit.dp
|
||||
import ua.acclorite.book_story.R
|
||||
import ua.acclorite.book_story.domain.model.Category
|
||||
import ua.acclorite.book_story.presentation.data.LocalNavigator
|
||||
import ua.acclorite.book_story.domain.util.OnNavigate
|
||||
import ua.acclorite.book_story.presentation.data.Screen
|
||||
import ua.acclorite.book_story.presentation.screens.history.data.HistoryEvent
|
||||
import ua.acclorite.book_story.presentation.screens.library.data.LibraryEvent
|
||||
|
|
@ -41,6 +41,7 @@ import ua.acclorite.book_story.presentation.screens.reader.data.ReaderState
|
|||
* Reader end item. Displays at the end of the book.
|
||||
*
|
||||
* @param state [ReaderState].
|
||||
* @param onNavigate Navigator callback.
|
||||
* @param onEvent [ReaderEvent] callback.
|
||||
* @param onLibraryEvent [LibraryEvent] callback.
|
||||
* @param onHistoryUpdateEvent [HistoryEvent] callback.
|
||||
|
|
@ -49,13 +50,12 @@ import ua.acclorite.book_story.presentation.screens.reader.data.ReaderState
|
|||
@Composable
|
||||
fun ReaderEndItem(
|
||||
state: State<ReaderState>,
|
||||
onNavigate: OnNavigate,
|
||||
onEvent: (ReaderEvent) -> Unit,
|
||||
onLibraryEvent: (LibraryEvent) -> Unit,
|
||||
onHistoryUpdateEvent: (HistoryEvent.OnUpdateBook) -> Unit,
|
||||
) {
|
||||
val navigator = LocalNavigator.current
|
||||
val context = LocalContext.current as ComponentActivity
|
||||
|
||||
val buttonText = remember {
|
||||
context.getString(
|
||||
if (state.value.book.category != Category.ALREADY_READ) R.string.move_to_read
|
||||
|
|
@ -106,7 +106,7 @@ fun ReaderEndItem(
|
|||
updatePage = {
|
||||
onLibraryEvent(LibraryEvent.OnUpdateCurrentPage(it))
|
||||
},
|
||||
navigator = navigator,
|
||||
onNavigate = onNavigate,
|
||||
context = context
|
||||
)
|
||||
)
|
||||
|
|
@ -120,13 +120,14 @@ fun ReaderEndItem(
|
|||
onEvent(
|
||||
ReaderEvent.OnGoBack(
|
||||
context,
|
||||
navigator,
|
||||
refreshList = {
|
||||
onLibraryEvent(LibraryEvent.OnUpdateBook(it))
|
||||
onHistoryUpdateEvent(HistoryEvent.OnUpdateBook(it))
|
||||
},
|
||||
navigate = {
|
||||
it.navigate(Screen.LIBRARY, true)
|
||||
onNavigate {
|
||||
navigate(Screen.Library, useBackAnimation = true)
|
||||
}
|
||||
}
|
||||
)
|
||||
)
|
||||
|
|
|
|||
|
|
@ -27,8 +27,8 @@ import androidx.compose.ui.text.font.FontFamily
|
|||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.sp
|
||||
import ua.acclorite.book_story.R
|
||||
import ua.acclorite.book_story.domain.util.OnNavigate
|
||||
import ua.acclorite.book_story.presentation.components.CustomIconButton
|
||||
import ua.acclorite.book_story.presentation.data.LocalNavigator
|
||||
import ua.acclorite.book_story.presentation.data.Screen
|
||||
import ua.acclorite.book_story.presentation.data.removeDigits
|
||||
import ua.acclorite.book_story.presentation.data.removeTrailingZero
|
||||
|
|
@ -42,6 +42,7 @@ import ua.acclorite.book_story.presentation.ui.Colors
|
|||
* Reader top bar. Displays title of the book.
|
||||
*
|
||||
* @param state [ReaderState].
|
||||
* @param onNavigate Navigator callback.
|
||||
* @param onEvent [ReaderEvent] callback.
|
||||
* @param onLibraryUpdateEvent [LibraryEvent] callback.
|
||||
* @param onHistoryUpdateEvent [HistoryEvent] callback.
|
||||
|
|
@ -50,13 +51,12 @@ import ua.acclorite.book_story.presentation.ui.Colors
|
|||
@Composable
|
||||
fun ReaderTopBar(
|
||||
state: State<ReaderState>,
|
||||
onNavigate: OnNavigate,
|
||||
onEvent: (ReaderEvent) -> Unit,
|
||||
onLibraryUpdateEvent: (LibraryEvent.OnUpdateBook) -> Unit,
|
||||
onHistoryUpdateEvent: (HistoryEvent.OnUpdateBook) -> Unit
|
||||
) {
|
||||
val navigator = LocalNavigator.current
|
||||
val context = LocalContext.current as ComponentActivity
|
||||
|
||||
val progress by remember(state.value.book.progress) {
|
||||
derivedStateOf {
|
||||
(state.value.book.progress * 100)
|
||||
|
|
@ -77,13 +77,14 @@ fun ReaderTopBar(
|
|||
onEvent(
|
||||
ReaderEvent.OnGoBack(
|
||||
context,
|
||||
navigator,
|
||||
refreshList = {
|
||||
onLibraryUpdateEvent(LibraryEvent.OnUpdateBook(it))
|
||||
onHistoryUpdateEvent(HistoryEvent.OnUpdateBook(it))
|
||||
},
|
||||
navigate = {
|
||||
it.navigateBack()
|
||||
onNavigate {
|
||||
navigateBack()
|
||||
}
|
||||
}
|
||||
)
|
||||
)
|
||||
|
|
@ -108,16 +109,18 @@ fun ReaderTopBar(
|
|||
onEvent(
|
||||
ReaderEvent.OnGoBack(
|
||||
context,
|
||||
navigator,
|
||||
refreshList = {
|
||||
onLibraryUpdateEvent(LibraryEvent.OnUpdateBook(it))
|
||||
onHistoryUpdateEvent(HistoryEvent.OnUpdateBook(it))
|
||||
},
|
||||
navigate = {
|
||||
it.navigateWithoutBackStack(
|
||||
Screen.BOOK_INFO,
|
||||
true
|
||||
)
|
||||
onNavigate {
|
||||
navigate(
|
||||
Screen.BookInfo(state.value.book.id),
|
||||
useBackAnimation = true,
|
||||
saveInBackStack = false
|
||||
)
|
||||
}
|
||||
}
|
||||
)
|
||||
)
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@ import ua.acclorite.book_story.domain.model.LineWithTranslation
|
|||
import ua.acclorite.book_story.domain.model.SelectableLanguage
|
||||
import ua.acclorite.book_story.domain.util.ID
|
||||
import ua.acclorite.book_story.domain.util.LanguageCode
|
||||
import ua.acclorite.book_story.domain.util.OnNavigate
|
||||
import ua.acclorite.book_story.domain.util.UIText
|
||||
import ua.acclorite.book_story.presentation.data.Navigator
|
||||
|
||||
@Immutable
|
||||
sealed class ReaderEvent {
|
||||
|
|
@ -20,8 +20,10 @@ sealed class ReaderEvent {
|
|||
val onTextIsEmpty: () -> Unit
|
||||
) : ReaderEvent()
|
||||
|
||||
data class OnShowHideMenu(val show: Boolean? = null, val context: ComponentActivity) :
|
||||
ReaderEvent()
|
||||
data class OnShowHideMenu(
|
||||
val show: Boolean? = null,
|
||||
val context: ComponentActivity
|
||||
) : ReaderEvent()
|
||||
|
||||
data class OnShowHideTranslatorBottomSheet(val show: Boolean? = null) : ReaderEvent()
|
||||
|
||||
|
|
@ -63,9 +65,8 @@ sealed class ReaderEvent {
|
|||
|
||||
data class OnGoBack(
|
||||
val context: ComponentActivity,
|
||||
val navigator: Navigator,
|
||||
val refreshList: (Book) -> Unit,
|
||||
val navigate: (Navigator) -> Unit
|
||||
val navigate: () -> Unit,
|
||||
val refreshList: (Book) -> Unit
|
||||
) : ReaderEvent()
|
||||
|
||||
data class OnChangeProgress(
|
||||
|
|
@ -82,7 +83,7 @@ sealed class ReaderEvent {
|
|||
val context: ComponentActivity,
|
||||
val onUpdateCategories: (Book) -> Unit,
|
||||
val updatePage: (Int) -> Unit,
|
||||
val navigator: Navigator
|
||||
val onNavigate: OnNavigate
|
||||
) : ReaderEvent()
|
||||
|
||||
data class OnOpenTranslator(
|
||||
|
|
|
|||
|
|
@ -42,9 +42,9 @@ import ua.acclorite.book_story.domain.use_case.TranslateText
|
|||
import ua.acclorite.book_story.domain.use_case.UpdateBooks
|
||||
import ua.acclorite.book_story.domain.util.ID
|
||||
import ua.acclorite.book_story.domain.util.LanguageCode
|
||||
import ua.acclorite.book_story.domain.util.OnNavigate
|
||||
import ua.acclorite.book_story.domain.util.Resource
|
||||
import ua.acclorite.book_story.domain.util.UIText
|
||||
import ua.acclorite.book_story.presentation.data.Navigator
|
||||
import ua.acclorite.book_story.presentation.data.Screen
|
||||
import ua.acclorite.book_story.presentation.data.removeKey
|
||||
import ua.acclorite.book_story.presentation.data.removeKeys
|
||||
|
|
@ -912,7 +912,7 @@ class ReaderViewModel @Inject constructor(
|
|||
}
|
||||
|
||||
insetsController.show(WindowInsetsCompat.Type.systemBars())
|
||||
event.navigate(event.navigator)
|
||||
event.navigate()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -967,7 +967,6 @@ class ReaderViewModel @Inject constructor(
|
|||
onEvent(
|
||||
ReaderEvent.OnGoBack(
|
||||
event.context,
|
||||
event.navigator,
|
||||
refreshList = {},
|
||||
navigate = {}
|
||||
)
|
||||
|
|
@ -995,7 +994,12 @@ class ReaderViewModel @Inject constructor(
|
|||
}.size - 1
|
||||
)
|
||||
|
||||
event.navigator.navigate(Screen.LIBRARY, true)
|
||||
event.onNavigate {
|
||||
navigate(
|
||||
Screen.Library,
|
||||
useBackAnimation = true
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1226,23 +1230,19 @@ class ReaderViewModel @Inject constructor(
|
|||
}
|
||||
|
||||
fun init(
|
||||
navigator: Navigator,
|
||||
screen: Screen.Reader,
|
||||
onNavigate: OnNavigate,
|
||||
context: ComponentActivity,
|
||||
refreshList: (Book) -> Unit,
|
||||
onError: (UIText) -> Unit
|
||||
) {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
val bookId = navigator.retrieveArgument("book") as? Int
|
||||
|
||||
if (bookId == null) {
|
||||
navigator.navigateBack()
|
||||
return@launch
|
||||
}
|
||||
|
||||
val book = getBookById.execute(bookId)
|
||||
val book = getBookById.execute(screen.bookId)
|
||||
|
||||
if (book == null) {
|
||||
navigator.navigateBack()
|
||||
onNavigate {
|
||||
navigateBack()
|
||||
}
|
||||
return@launch
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -24,10 +24,10 @@ import androidx.compose.ui.input.nestedscroll.nestedScroll
|
|||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import ua.acclorite.book_story.R
|
||||
import ua.acclorite.book_story.domain.util.OnNavigate
|
||||
import ua.acclorite.book_story.presentation.components.GoBackButton
|
||||
import ua.acclorite.book_story.presentation.components.collapsibleUntilExitScrollBehaviorWithLazyListState
|
||||
import ua.acclorite.book_story.presentation.data.LocalNavigator
|
||||
import ua.acclorite.book_story.presentation.data.Navigator
|
||||
import ua.acclorite.book_story.presentation.data.Screen
|
||||
import ua.acclorite.book_story.presentation.screens.settings.components.SettingsCategoryItem
|
||||
|
||||
|
|
@ -35,13 +35,13 @@ import ua.acclorite.book_story.presentation.screens.settings.components.Settings
|
|||
fun SettingsScreenRoot() {
|
||||
val navigator = LocalNavigator.current
|
||||
|
||||
SettingsScreen(navigator = navigator)
|
||||
SettingsScreen(onNavigate = { navigator.it() })
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
private fun SettingsScreen(
|
||||
navigator: Navigator
|
||||
onNavigate: OnNavigate
|
||||
) {
|
||||
val scrollState = TopAppBarDefaults.collapsibleUntilExitScrollBehaviorWithLazyListState()
|
||||
|
||||
|
|
@ -57,7 +57,7 @@ private fun SettingsScreen(
|
|||
Text(stringResource(id = R.string.settings_screen))
|
||||
},
|
||||
navigationIcon = {
|
||||
GoBackButton(navigator = navigator)
|
||||
GoBackButton(onNavigate = onNavigate)
|
||||
},
|
||||
scrollBehavior = scrollState.first,
|
||||
colors = TopAppBarDefaults.largeTopAppBarColors(
|
||||
|
|
@ -83,7 +83,9 @@ private fun SettingsScreen(
|
|||
text = stringResource(id = R.string.general_settings),
|
||||
description = stringResource(id = R.string.general_settings_desc)
|
||||
) {
|
||||
navigator.navigate(Screen.GENERAL_SETTINGS, false)
|
||||
onNavigate {
|
||||
navigate(Screen.Settings.General)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -93,7 +95,9 @@ private fun SettingsScreen(
|
|||
text = stringResource(id = R.string.appearance_settings),
|
||||
description = stringResource(id = R.string.appearance_settings_desc)
|
||||
) {
|
||||
navigator.navigate(Screen.APPEARANCE_SETTINGS, false)
|
||||
onNavigate {
|
||||
navigate(Screen.Settings.Appearance)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -103,7 +107,9 @@ private fun SettingsScreen(
|
|||
text = stringResource(id = R.string.reader_settings),
|
||||
description = stringResource(id = R.string.reader_settings_desc)
|
||||
) {
|
||||
navigator.navigate(Screen.READER_SETTINGS, false)
|
||||
onNavigate {
|
||||
navigate(Screen.Settings.ReaderSettings)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ import androidx.compose.ui.unit.dp
|
|||
import androidx.hilt.navigation.compose.hiltViewModel
|
||||
import ua.acclorite.book_story.R
|
||||
import ua.acclorite.book_story.domain.model.ButtonItem
|
||||
import ua.acclorite.book_story.domain.util.OnNavigate
|
||||
import ua.acclorite.book_story.presentation.components.CategoryTitle
|
||||
import ua.acclorite.book_story.presentation.components.GoBackButton
|
||||
import ua.acclorite.book_story.presentation.components.collapsibleUntilExitScrollBehaviorWithLazyListState
|
||||
|
|
@ -36,7 +37,6 @@ import ua.acclorite.book_story.presentation.data.LocalNavigator
|
|||
import ua.acclorite.book_story.presentation.data.MainEvent
|
||||
import ua.acclorite.book_story.presentation.data.MainState
|
||||
import ua.acclorite.book_story.presentation.data.MainViewModel
|
||||
import ua.acclorite.book_story.presentation.data.Navigator
|
||||
import ua.acclorite.book_story.presentation.screens.settings.components.ColorPickerWithTitle
|
||||
import ua.acclorite.book_story.presentation.screens.settings.components.SegmentedButtonWithTitle
|
||||
import ua.acclorite.book_story.presentation.screens.settings.nested.appearance.components.theme_switcher.AppearanceSettingsThemeSwitcher
|
||||
|
|
@ -58,7 +58,7 @@ fun AppearanceSettingsRoot() {
|
|||
|
||||
AppearanceSettings(
|
||||
state = state,
|
||||
navigator = navigator,
|
||||
onNavigate = { navigator.it() },
|
||||
onMainEvent = mainViewModel::onEvent
|
||||
)
|
||||
}
|
||||
|
|
@ -67,7 +67,7 @@ fun AppearanceSettingsRoot() {
|
|||
@Composable
|
||||
private fun AppearanceSettings(
|
||||
state: State<MainState>,
|
||||
navigator: Navigator,
|
||||
onNavigate: OnNavigate,
|
||||
onMainEvent: (MainEvent) -> Unit
|
||||
) {
|
||||
val scrollState = TopAppBarDefaults.collapsibleUntilExitScrollBehaviorWithLazyListState()
|
||||
|
|
@ -91,7 +91,7 @@ private fun AppearanceSettings(
|
|||
Text(stringResource(id = R.string.appearance_settings))
|
||||
},
|
||||
navigationIcon = {
|
||||
GoBackButton(navigator = navigator)
|
||||
GoBackButton(onNavigate = onNavigate)
|
||||
},
|
||||
scrollBehavior = scrollState.first,
|
||||
colors = TopAppBarDefaults.largeTopAppBarColors(
|
||||
|
|
|
|||
|
|
@ -31,13 +31,13 @@ import com.google.accompanist.permissions.rememberPermissionState
|
|||
import ua.acclorite.book_story.R
|
||||
import ua.acclorite.book_story.domain.model.ButtonItem
|
||||
import ua.acclorite.book_story.domain.util.Constants
|
||||
import ua.acclorite.book_story.domain.util.OnNavigate
|
||||
import ua.acclorite.book_story.presentation.components.GoBackButton
|
||||
import ua.acclorite.book_story.presentation.components.collapsibleUntilExitScrollBehaviorWithLazyListState
|
||||
import ua.acclorite.book_story.presentation.data.LocalNavigator
|
||||
import ua.acclorite.book_story.presentation.data.MainEvent
|
||||
import ua.acclorite.book_story.presentation.data.MainState
|
||||
import ua.acclorite.book_story.presentation.data.MainViewModel
|
||||
import ua.acclorite.book_story.presentation.data.Navigator
|
||||
import ua.acclorite.book_story.presentation.screens.settings.components.ChipsWithTitle
|
||||
import ua.acclorite.book_story.presentation.screens.settings.components.SwitchWithTitle
|
||||
import ua.acclorite.book_story.presentation.screens.settings.data.SettingsEvent
|
||||
|
|
@ -53,7 +53,7 @@ fun GeneralSettingsRoot() {
|
|||
|
||||
GeneralSettings(
|
||||
state = state,
|
||||
navigator = navigator,
|
||||
onNavigate = { navigator.it() },
|
||||
onSettingsEvent = settingsViewModel::onEvent,
|
||||
onMainEvent = mainViewModel::onEvent
|
||||
)
|
||||
|
|
@ -64,7 +64,7 @@ fun GeneralSettingsRoot() {
|
|||
@Composable
|
||||
private fun GeneralSettings(
|
||||
state: State<MainState>,
|
||||
navigator: Navigator,
|
||||
onNavigate: OnNavigate,
|
||||
onSettingsEvent: (SettingsEvent) -> Unit,
|
||||
onMainEvent: (MainEvent) -> Unit
|
||||
) {
|
||||
|
|
@ -87,7 +87,7 @@ private fun GeneralSettings(
|
|||
Text(stringResource(id = R.string.general_settings))
|
||||
},
|
||||
navigationIcon = {
|
||||
GoBackButton(navigator = navigator)
|
||||
GoBackButton(onNavigate = onNavigate)
|
||||
},
|
||||
scrollBehavior = scrollState.first,
|
||||
colors = TopAppBarDefaults.largeTopAppBarColors(
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ import androidx.hilt.navigation.compose.hiltViewModel
|
|||
import ua.acclorite.book_story.R
|
||||
import ua.acclorite.book_story.domain.model.ButtonItem
|
||||
import ua.acclorite.book_story.domain.util.Constants
|
||||
import ua.acclorite.book_story.domain.util.OnNavigate
|
||||
import ua.acclorite.book_story.presentation.components.CategoryTitle
|
||||
import ua.acclorite.book_story.presentation.components.GoBackButton
|
||||
import ua.acclorite.book_story.presentation.components.collapsibleUntilExitScrollBehaviorWithLazyListState
|
||||
|
|
@ -36,7 +37,6 @@ import ua.acclorite.book_story.presentation.data.LocalNavigator
|
|||
import ua.acclorite.book_story.presentation.data.MainEvent
|
||||
import ua.acclorite.book_story.presentation.data.MainState
|
||||
import ua.acclorite.book_story.presentation.data.MainViewModel
|
||||
import ua.acclorite.book_story.presentation.data.Navigator
|
||||
import ua.acclorite.book_story.presentation.screens.reader.components.translator_bottom_sheet.ReaderTranslatorBottomSheetLanguageChooser
|
||||
import ua.acclorite.book_story.presentation.screens.settings.components.ChipsWithTitle
|
||||
import ua.acclorite.book_story.presentation.screens.settings.components.SliderWithTitle
|
||||
|
|
@ -58,7 +58,7 @@ fun ReaderSettingsRoot() {
|
|||
ReaderSettings(
|
||||
state = state,
|
||||
settingsState = settingsState,
|
||||
navigator = navigator,
|
||||
onNavigate = { navigator.it() },
|
||||
onMainEvent = mainViewModel::onEvent,
|
||||
onEvent = settingsViewModel::onEvent
|
||||
)
|
||||
|
|
@ -69,7 +69,7 @@ fun ReaderSettingsRoot() {
|
|||
private fun ReaderSettings(
|
||||
state: State<MainState>,
|
||||
settingsState: State<SettingsState>,
|
||||
navigator: Navigator,
|
||||
onNavigate: OnNavigate,
|
||||
onMainEvent: (MainEvent) -> Unit,
|
||||
onEvent: (SettingsEvent) -> Unit
|
||||
) {
|
||||
|
|
@ -145,7 +145,7 @@ private fun ReaderSettings(
|
|||
Text(stringResource(id = R.string.reader_settings))
|
||||
},
|
||||
navigationIcon = {
|
||||
GoBackButton(navigator = navigator)
|
||||
GoBackButton(onNavigate = onNavigate)
|
||||
},
|
||||
scrollBehavior = scrollState.first,
|
||||
colors = TopAppBarDefaults.largeTopAppBarColors(
|
||||
|
|
|
|||
|
|
@ -35,7 +35,12 @@ import ua.acclorite.book_story.presentation.screens.start.data.StartEvent
|
|||
import ua.acclorite.book_story.presentation.screens.start.data.StartState
|
||||
|
||||
/**
|
||||
* Done screen.
|
||||
* Start Done screen.
|
||||
*
|
||||
* @param state [StartState].
|
||||
* @param onEvent [StartEvent] callback.
|
||||
* @param onMainEvent [MainEvent] callback.
|
||||
* @param onBrowseEvent [BrowseEvent] callback.
|
||||
*/
|
||||
@Composable
|
||||
fun StartDone(
|
||||
|
|
@ -72,7 +77,7 @@ fun StartDone(
|
|||
onClick = {
|
||||
onEvent(
|
||||
StartEvent.OnGoToBrowse(
|
||||
navigator,
|
||||
onNavigate = { navigator.it() },
|
||||
onCompletedStartGuide = {
|
||||
onBrowseEvent(BrowseEvent.OnLoadList)
|
||||
onMainEvent(
|
||||
|
|
@ -91,9 +96,7 @@ fun StartDone(
|
|||
shape = RoundedCornerShape(100),
|
||||
onClick = {
|
||||
onEvent(
|
||||
StartEvent.OnGoToHelp(
|
||||
navigator
|
||||
)
|
||||
StartEvent.OnGoToHelp { navigator.it() }
|
||||
)
|
||||
}
|
||||
) {
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import androidx.activity.ComponentActivity
|
|||
import androidx.compose.runtime.Immutable
|
||||
import com.google.accompanist.permissions.ExperimentalPermissionsApi
|
||||
import com.google.accompanist.permissions.PermissionState
|
||||
import ua.acclorite.book_story.presentation.data.Navigator
|
||||
import ua.acclorite.book_story.domain.util.OnNavigate
|
||||
|
||||
@Immutable
|
||||
sealed class StartEvent {
|
||||
|
|
@ -23,10 +23,10 @@ sealed class StartEvent {
|
|||
val onEnableUpdates: () -> Unit
|
||||
) : StartEvent()
|
||||
|
||||
data class OnGoToBrowse(val navigator: Navigator, val onCompletedStartGuide: () -> Unit) :
|
||||
data class OnGoToBrowse(val onNavigate: OnNavigate, val onCompletedStartGuide: () -> Unit) :
|
||||
StartEvent()
|
||||
|
||||
data class OnGoToHelp(val navigator: Navigator) : StartEvent()
|
||||
data class OnGoToHelp(val onNavigate: OnNavigate) : StartEvent()
|
||||
|
||||
data object OnResetStartScreen : StartEvent()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,7 +21,6 @@ import kotlinx.coroutines.flow.update
|
|||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.yield
|
||||
import ua.acclorite.book_story.domain.use_case.CheckForUpdates
|
||||
import ua.acclorite.book_story.presentation.data.Argument
|
||||
import ua.acclorite.book_story.presentation.data.Screen
|
||||
import javax.inject.Inject
|
||||
|
||||
|
|
@ -239,13 +238,16 @@ class StartViewModel @Inject constructor(
|
|||
}
|
||||
|
||||
is StartEvent.OnGoToBrowse -> {
|
||||
event.navigator.navigateWithoutBackStack(Screen.BROWSE, false)
|
||||
event.onNavigate {
|
||||
navigate(Screen.Browse, saveInBackStack = false)
|
||||
}
|
||||
event.onCompletedStartGuide()
|
||||
}
|
||||
|
||||
is StartEvent.OnGoToHelp -> {
|
||||
event.navigator.putArgument(Argument("from_start", true))
|
||||
event.navigator.navigateWithoutBackStack(Screen.HELP, false)
|
||||
event.onNavigate {
|
||||
navigate(Screen.Help(true), saveInBackStack = false)
|
||||
}
|
||||
}
|
||||
|
||||
is StartEvent.OnResetStartScreen -> {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue