From 0390a49fcc6911d58035d8ba1dfe25ff82907a0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20M=C4=9Bs=C3=AD=C4=8Dek?= Date: Wed, 8 May 2024 20:03:33 +0200 Subject: [PATCH 1/6] Update colors --- app/build.gradle.kts | 3 +-- app/src/main/AndroidManifest.xml | 7 +++++-- .../app/futured/androidprojecttemplate/App.kt | 2 ++ .../androidprojecttemplate/ui/NavGraph.kt | 5 +++++ .../ui/components/AddFloatingActionButton.kt | 4 ++-- .../ui/components/Showcase.kt | 6 +++--- .../ui/screens/detail/DetailScreen.kt | 19 +++++++++-------- .../ui/screens/home/HomeScreen.kt | 9 +++++--- .../androidprojecttemplate/ui/theme/Shape.kt | 2 +- .../androidprojecttemplate/ui/theme/Theme.kt | 21 ++++++++++--------- .../androidprojecttemplate/ui/theme/Type.kt | 4 ++-- buildSrc/src/main/kotlin/Dependencies.kt | 3 +-- buildSrc/src/main/kotlin/Versions.kt | 4 ++-- 13 files changed, 51 insertions(+), 38 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 1a4be0e..791aad7 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -160,8 +160,7 @@ dependencies { implementation(Dependencies.Compose.animation) implementation(Dependencies.Compose.foundation) implementation(Dependencies.Compose.foundation_layout) - implementation(Dependencies.Compose.material) - implementation(Dependencies.Compose.material_icons_extended) + implementation(Dependencies.Compose.material3) implementation(Dependencies.Compose.runtime_livedata) implementation(Dependencies.Compose.runtime) implementation(Dependencies.Compose.ui) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index edd0de6..a712bad 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,4 +1,5 @@ - + + android:supportsRtl="true" + tools:targetApi="tiramisu"> Unit) { AppTheme { - Surface(color = MaterialTheme.colors.background, modifier = modifier) { + Surface(color = MaterialTheme.colorScheme.background, modifier = modifier) { content() } } diff --git a/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/screens/detail/DetailScreen.kt b/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/screens/detail/DetailScreen.kt index 47b78ef..3462a0c 100644 --- a/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/screens/detail/DetailScreen.kt +++ b/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/screens/detail/DetailScreen.kt @@ -1,17 +1,19 @@ +@file:OptIn(ExperimentalMaterial3Api::class) + package app.futured.androidprojecttemplate.ui.screens.detail -import android.annotation.SuppressLint import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding -import androidx.compose.material.Icon -import androidx.compose.material.IconButton -import androidx.compose.material.Scaffold -import androidx.compose.material.Text -import androidx.compose.material.TopAppBar import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.ArrowBack +import androidx.compose.material.icons.automirrored.filled.ArrowBack +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.Scaffold +import androidx.compose.material3.Text +import androidx.compose.material3.TopAppBar import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -51,7 +53,6 @@ object Detail { object PreviewActions : Actions - @SuppressLint("ComposeModifierMissing") @Composable fun Content( actions: Actions, @@ -66,7 +67,7 @@ object Detail { IconButton( onClick = { actions.navigateBack() }, ) { - Icon(Icons.Default.ArrowBack, "") + Icon(Icons.AutoMirrored.Filled.ArrowBack, "") } }, ) diff --git a/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/screens/home/HomeScreen.kt b/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/screens/home/HomeScreen.kt index 95123d7..077da46 100644 --- a/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/screens/home/HomeScreen.kt +++ b/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/screens/home/HomeScreen.kt @@ -1,3 +1,5 @@ +@file:OptIn(ExperimentalMaterial3Api::class) + package app.futured.androidprojecttemplate.ui.screens.home import androidx.compose.foundation.clickable @@ -5,9 +7,10 @@ import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding -import androidx.compose.material.Scaffold -import androidx.compose.material.Text -import androidx.compose.material.TopAppBar +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.Scaffold +import androidx.compose.material3.Text +import androidx.compose.material3.TopAppBar import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier diff --git a/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/theme/Shape.kt b/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/theme/Shape.kt index 08c6a1b..5c56840 100644 --- a/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/theme/Shape.kt +++ b/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/theme/Shape.kt @@ -3,7 +3,7 @@ package app.futured.androidprojecttemplate.ui.theme import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.Shapes +import androidx.compose.material3.Shapes import androidx.compose.ui.unit.dp val shapes = Shapes( diff --git a/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/theme/Theme.kt b/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/theme/Theme.kt index e802ac0..dbdcea4 100644 --- a/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/theme/Theme.kt +++ b/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/theme/Theme.kt @@ -1,28 +1,29 @@ package app.futured.androidprojecttemplate.ui.theme import androidx.compose.foundation.isSystemInDarkTheme -import androidx.compose.material.MaterialTheme -import androidx.compose.material.darkColors -import androidx.compose.material.lightColors +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.darkColorScheme +import androidx.compose.material3.lightColorScheme import androidx.compose.runtime.Composable -private val LightColorPalette = lightColors( +private val LightColorPalette = lightColorScheme( primary = orange300, - primaryVariant = orange100, + primaryContainer = orange100, secondary = blue400, - secondaryVariant = blue200, + secondaryContainer = blue200, background = cloud50, - surface = pureWhite, + surface = orange100, onPrimary = pureWhite, onSecondary = pureWhite, onBackground = black900, onSurface = black900, ) -private val DarkColorPalette = darkColors( +private val DarkColorPalette = darkColorScheme( primary = orange300, - primaryVariant = orange100, + primaryContainer = orange300, secondary = blue400, + secondaryContainer = blue200, background = black900, surface = black700, onPrimary = pureWhite, @@ -43,7 +44,7 @@ fun AppTheme( } MaterialTheme( - colors = colors, + colorScheme = colors, typography = typography, shapes = shapes, content = content, diff --git a/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/theme/Type.kt b/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/theme/Type.kt index abb5d23..3f00486 100644 --- a/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/theme/Type.kt +++ b/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/theme/Type.kt @@ -1,13 +1,13 @@ package app.futured.androidprojecttemplate.ui.theme -import androidx.compose.material.Typography +import androidx.compose.material3.Typography import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.sp val typography = Typography( - body1 = TextStyle( + bodyMedium = TextStyle( fontFamily = FontFamily.Default, fontWeight = FontWeight.Normal, fontSize = 16.sp, diff --git a/buildSrc/src/main/kotlin/Dependencies.kt b/buildSrc/src/main/kotlin/Dependencies.kt index 2229a35..0ee66a6 100644 --- a/buildSrc/src/main/kotlin/Dependencies.kt +++ b/buildSrc/src/main/kotlin/Dependencies.kt @@ -16,8 +16,7 @@ object Dependencies { const val animation = "androidx.compose.animation:animation:${Versions.composeVersion}" const val foundation = "androidx.compose.foundation:foundation:${Versions.composeFoundationVersion}" const val foundation_layout = "androidx.compose.foundation:foundation-layout:${Versions.composeFoundationVersion}" - const val material = "androidx.compose.material:material:${Versions.composeMaterialVersion}" - const val material_icons_extended = "androidx.compose.material:material-icons-extended:${Versions.composeMaterialVersion}" + const val material3 = "androidx.compose.material3:material3:${Versions.composeMaterial3Version}" const val runtime_livedata = "androidx.compose.runtime:runtime-livedata:${Versions.composeVersion}" const val runtime = "androidx.compose.runtime:runtime:${Versions.composeVersion}" const val ui = "androidx.compose.ui:ui:${Versions.composeVersion}" diff --git a/buildSrc/src/main/kotlin/Versions.kt b/buildSrc/src/main/kotlin/Versions.kt index 1bf55cb..9505d78 100644 --- a/buildSrc/src/main/kotlin/Versions.kt +++ b/buildSrc/src/main/kotlin/Versions.kt @@ -15,7 +15,7 @@ object Versions { const val composeVersion = "1.6.7" const val composeFoundationVersion = "1.6.7" - const val composeMaterialVersion = "1.6.7" + const val composeMaterial3Version = "1.2.1" const val composeCompilerVersion = "1.5.13" // support @@ -30,7 +30,7 @@ object Versions { const val desugarLibs = "2.0.4" // navigation components - const val navigation = "2.7.7" + const val navigation = "2.8.0-alpha08" const val hiltNavigation = "1.2.0" // networking From 34e158a2bf0d4924f87ff7133b2b2f33c589727a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20M=C4=9Bs=C3=AD=C4=8Dek?= Date: Thu, 9 May 2024 11:55:58 +0200 Subject: [PATCH 2/6] Add template screen --- app/build.gradle.kts | 3 + .../navigation/Destinations.kt | 59 ++++++++- .../navigation/NavRouter.kt | 13 ++ .../navigation/NavRouterImpl.kt | 56 ++++++++ .../navigation/NavigationDestinations.kt | 21 --- .../navigation/Transitions.kt | 101 ++++++++++++++ .../androidprojecttemplate/tools/Constants.kt | 5 + .../tools/extensions/GeneralExtensions.kt | 28 ++++ .../tools/extensions/ModifierExtensions.kt | 27 ++++ .../extensions/SavedStateHandleExtensions.kt | 44 +++++++ .../androidprojecttemplate/ui/AppUI.kt | 2 + .../androidprojecttemplate/ui/NavGraph.kt | 37 ++++-- .../_templateScreen/_TEMPLATEScreen.kt | 124 ++++++++++++++++++ .../ui/screens/detail/DetailEvents.kt | 2 + .../ui/screens/detail/DetailScreen.kt | 39 ++++-- .../ui/screens/detail/DetailViewModel.kt | 9 +- .../ui/screens/home/HomeScreen.kt | 27 ++-- .../ui/screens/home/HomeViewModel.kt | 5 +- .../ui/screens/info/InfoEvent.kt | 7 + .../ui/screens/info/InfoScreen.kt | 69 ++++++++++ .../ui/screens/info/InfoViewModel.kt | 14 ++ .../ui/screens/info/InfoViewState.kt | 8 ++ .../ui/theme/Dimensions.kt | 118 +++++++++++++++++ buildSrc/src/main/kotlin/Dependencies.kt | 4 + buildSrc/src/main/kotlin/Versions.kt | 5 +- 25 files changed, 758 insertions(+), 69 deletions(-) create mode 100644 app/src/main/kotlin/app/futured/androidprojecttemplate/navigation/NavRouter.kt create mode 100644 app/src/main/kotlin/app/futured/androidprojecttemplate/navigation/NavRouterImpl.kt delete mode 100644 app/src/main/kotlin/app/futured/androidprojecttemplate/navigation/NavigationDestinations.kt create mode 100644 app/src/main/kotlin/app/futured/androidprojecttemplate/navigation/Transitions.kt create mode 100644 app/src/main/kotlin/app/futured/androidprojecttemplate/tools/extensions/GeneralExtensions.kt create mode 100644 app/src/main/kotlin/app/futured/androidprojecttemplate/tools/extensions/ModifierExtensions.kt create mode 100644 app/src/main/kotlin/app/futured/androidprojecttemplate/tools/extensions/SavedStateHandleExtensions.kt create mode 100644 app/src/main/kotlin/app/futured/androidprojecttemplate/ui/screens/_templateScreen/_TEMPLATEScreen.kt create mode 100644 app/src/main/kotlin/app/futured/androidprojecttemplate/ui/screens/info/InfoEvent.kt create mode 100644 app/src/main/kotlin/app/futured/androidprojecttemplate/ui/screens/info/InfoScreen.kt create mode 100644 app/src/main/kotlin/app/futured/androidprojecttemplate/ui/screens/info/InfoViewModel.kt create mode 100644 app/src/main/kotlin/app/futured/androidprojecttemplate/ui/screens/info/InfoViewState.kt create mode 100644 app/src/main/kotlin/app/futured/androidprojecttemplate/ui/theme/Dimensions.kt diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 791aad7..c11843c 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -156,6 +156,9 @@ dependencies { implementation(Dependencies.Support.vectordrawable) implementation(Dependencies.Support.preference) + // Accompanist + implementation(Dependencies.Accompanist.navigationMaterial) + // Compose implementation(Dependencies.Compose.animation) implementation(Dependencies.Compose.foundation) diff --git a/app/src/main/kotlin/app/futured/androidprojecttemplate/navigation/Destinations.kt b/app/src/main/kotlin/app/futured/androidprojecttemplate/navigation/Destinations.kt index 8ef728d..d5511a6 100644 --- a/app/src/main/kotlin/app/futured/androidprojecttemplate/navigation/Destinations.kt +++ b/app/src/main/kotlin/app/futured/androidprojecttemplate/navigation/Destinations.kt @@ -1,6 +1,7 @@ package app.futured.androidprojecttemplate.navigation -import androidx.compose.animation.AnimatedContentScope +import androidx.compose.animation.AnimatedVisibilityScope +import androidx.compose.foundation.layout.ColumnScope import androidx.compose.runtime.Composable import androidx.compose.ui.window.DialogProperties import androidx.navigation.NamedNavArgument @@ -11,19 +12,42 @@ import androidx.navigation.NavType import androidx.navigation.compose.composable import androidx.navigation.compose.dialog import androidx.navigation.navArgument +import app.futured.androidprojecttemplate.ui.screens.detail.DetailScreen +import app.futured.androidprojecttemplate.ui.screens.home.HomeScreen +import app.futured.androidprojecttemplate.ui.screens.info.InfoScreen +import com.google.accompanist.navigation.material.ExperimentalMaterialNavigationApi +import com.google.accompanist.navigation.material.bottomSheet typealias DestinationArgumentKey = String typealias DestinationArgumentValue = String +internal val screens = listOf( + Destination.Home, + Destination.Detail, +) + +internal val bottomSheetDialogs = listOf( + Destination.Info, +) + +internal val dialogs = listOf() + sealed class Destination( val route: String, val arguments: List = emptyList(), val deepLinks: List = emptyList(), + val destinationScreen: @Composable (router: NavRouter) -> Unit, ) { - data object Home : Destination(route = "home") + data object Home : Destination( + route = "home", + destinationScreen = { HomeScreen(navigation = it) }, + ) + data object Detail : Destination( route = "detail/{title}?subtitle={subtitle}?value={value}", - arguments = listOf( + destinationScreen = { DetailScreen(navigation = it) }, + arguments = + listOf( navArgument("title") { type = NavType.StringType }, @@ -42,18 +66,29 @@ sealed class Destination( .withArgument("subtitle", subtitle) .withArgument("value", value) } + + data object Info : Destination( + route = "info", + destinationScreen = { InfoScreen(navigation = it) }, + ) { + fun buildRoute() = route + } } /** * Registers provided [destination] as a composable in [NavGraphBuilder]. */ -fun NavGraphBuilder.composable( +fun NavGraphBuilder.composableScreen( destination: Destination, - content: @Composable AnimatedContentScope.(NavBackStackEntry) -> Unit, + content: @Composable AnimatedVisibilityScope.(NavBackStackEntry) -> Unit, ) = composable( route = destination.route, arguments = destination.arguments, deepLinks = destination.deepLinks, +// enterTransition = Transitions.enterTransition, +// exitTransition = Transitions.exitTransition, +// popEnterTransition = Transitions.popEnterTransition, +// popExitTransition = Transitions.popExitTransition, content = content, ) @@ -72,6 +107,20 @@ fun NavGraphBuilder.composableDialog( content = content, ) +/** + * Registers provided [destination] as a bottomSheet in [NavGraphBuilder]. + */ +@OptIn(ExperimentalMaterialNavigationApi::class) +fun NavGraphBuilder.composableBottomSheetDialog( + destination: Destination, + content: @Composable ColumnScope.(backstackEntry: NavBackStackEntry) -> Unit, +) = bottomSheet( + route = destination.route, + arguments = destination.arguments, + deepLinks = destination.deepLinks, + content = content, +) + /** * Replaces an argument placeholder defined by [key] in * route string with value provided in [argument]. diff --git a/app/src/main/kotlin/app/futured/androidprojecttemplate/navigation/NavRouter.kt b/app/src/main/kotlin/app/futured/androidprojecttemplate/navigation/NavRouter.kt new file mode 100644 index 0000000..a6a0b13 --- /dev/null +++ b/app/src/main/kotlin/app/futured/androidprojecttemplate/navigation/NavRouter.kt @@ -0,0 +1,13 @@ +package app.futured.androidprojecttemplate.navigation + +interface NavRouter { + fun popBackStack() + fun navigateBack(popUpToDestination: Destination, inclusive: Boolean = false) + + fun navigateToDetail(title: String, subtitle: String? = null, value: String? = null) + fun navigateToInfo() + + fun navigateBackWithResult(key: String, value: T) + fun setCurrentResult(key: String, value: T) + fun subscribeForResult(key: String, callback: (T) -> Unit) +} diff --git a/app/src/main/kotlin/app/futured/androidprojecttemplate/navigation/NavRouterImpl.kt b/app/src/main/kotlin/app/futured/androidprojecttemplate/navigation/NavRouterImpl.kt new file mode 100644 index 0000000..0b5444e --- /dev/null +++ b/app/src/main/kotlin/app/futured/androidprojecttemplate/navigation/NavRouterImpl.kt @@ -0,0 +1,56 @@ +package app.futured.androidprojecttemplate.navigation + +import androidx.navigation.NavController +import app.futured.androidprojecttemplate.tools.extensions.subscribeForResult +import timber.log.Timber + +/** + * Class that triggers navigation actions on provided [navController]. + */ +class NavRouterImpl(private val navController: NavController) : NavRouter { + override fun popBackStack() { + navController.navigateUp() + } + + override fun navigateBack(popUpToDestination: Destination, inclusive: Boolean) { + navController.popBackStack(route = popUpToDestination.route, inclusive = inclusive) + } + + override fun navigateToDetail(title: String, subtitle: String?, value: String?) = + Destination.Detail.buildRoute(title, subtitle, value).execute() + + override fun navigateToInfo() = Destination.Info.buildRoute().execute() + + override fun navigateBackWithResult(key: String, value: T) { + navController.previousBackStackEntry?.savedStateHandle?.also { + it[key] = value + navController.popBackStack() + } + } + + override fun setCurrentResult(key: String, value: T) { + navController.currentBackStackEntry?.savedStateHandle?.also { + it[key] = value + } + } + + override fun subscribeForResult(key: String, callback: (T) -> Unit) { + navController.currentBackStackEntry?.savedStateHandle?.subscribeForResult(key) { callback(it) } + } + + private fun String.execute( + popUpToDestinationRoute: String? = null, + isInclusive: Boolean = true, + ) { + Timber.d("## Navigate to $this, popupTo $popUpToDestinationRoute, inclusive $isInclusive") + if (popUpToDestinationRoute != null) { + navController.navigate(this) { + popUpTo(popUpToDestinationRoute) { + inclusive = isInclusive + } + } + } else { + navController.navigate(this) + } + } +} \ No newline at end of file diff --git a/app/src/main/kotlin/app/futured/androidprojecttemplate/navigation/NavigationDestinations.kt b/app/src/main/kotlin/app/futured/androidprojecttemplate/navigation/NavigationDestinations.kt deleted file mode 100644 index 40e2800..0000000 --- a/app/src/main/kotlin/app/futured/androidprojecttemplate/navigation/NavigationDestinations.kt +++ /dev/null @@ -1,21 +0,0 @@ -package app.futured.androidprojecttemplate.navigation - -import androidx.navigation.NavController - -interface NavigationDestinations { - fun popBackStack() - fun navigateToDetailScreen(title: String, subtitle: String? = null, value: String? = null) -} - -/** - * Class that triggers navigation actions on provided [navController]. - */ -class NavigationDestinationsImpl(private val navController: NavController) : NavigationDestinations { - - override fun popBackStack() { - navController.popBackStack() - } - - override fun navigateToDetailScreen(title: String, subtitle: String?, value: String?) = - navController.navigate(Destination.Detail.buildRoute(title, subtitle, value)) -} diff --git a/app/src/main/kotlin/app/futured/androidprojecttemplate/navigation/Transitions.kt b/app/src/main/kotlin/app/futured/androidprojecttemplate/navigation/Transitions.kt new file mode 100644 index 0000000..677ee09 --- /dev/null +++ b/app/src/main/kotlin/app/futured/androidprojecttemplate/navigation/Transitions.kt @@ -0,0 +1,101 @@ +package app.futured.androidprojecttemplate.navigation + +import androidx.compose.animation.AnimatedContentTransitionScope +import androidx.compose.animation.EnterTransition +import androidx.compose.animation.ExitTransition +import androidx.compose.animation.core.tween +import androidx.compose.animation.fadeIn +import androidx.compose.animation.fadeOut +import androidx.compose.animation.slideInHorizontally +import androidx.compose.animation.slideInVertically +import androidx.compose.animation.slideOutHorizontally +import androidx.compose.animation.slideOutVertically +import androidx.navigation.NavBackStackEntry +import app.futured.androidprojecttemplate.tools.Constants + +object Transitions { + enum class RoutePrefix { + MODAL_, + NORMAL_, + BOTTOM_NAV_, + } + + val enterTransition: (AnimatedContentTransitionScope.() -> EnterTransition?) = { + when (targetState.transitionPrefix()) { + RoutePrefix.NORMAL_ -> + slideInHorizontally( + initialOffsetX = { it }, + animationSpec = tween(Constants.Ui.SCREEN_ANIMATION_DURATION), + ) + + RoutePrefix.MODAL_ -> + slideInVertically( + initialOffsetY = { it }, + animationSpec = tween(Constants.Ui.SCREEN_ANIMATION_DURATION), + ) + + RoutePrefix.BOTTOM_NAV_ -> fadeIn(animationSpec = tween(Constants.Ui.SCREEN_FADE_DURATION)) + } + } + val exitTransition: (AnimatedContentTransitionScope.() -> ExitTransition?) = { + when (targetState.transitionPrefix()) { + RoutePrefix.NORMAL_ -> + slideOutHorizontally( + targetOffsetX = { -it }, + animationSpec = tween(Constants.Ui.SCREEN_ANIMATION_DURATION), + ) + + RoutePrefix.MODAL_ -> + slideOutVertically( + targetOffsetY = { -it }, + animationSpec = tween(Constants.Ui.SCREEN_ANIMATION_DURATION), + ) + + RoutePrefix.BOTTOM_NAV_ -> fadeOut(tween(Constants.Ui.SCREEN_FADE_DURATION)) + } + } + + val popEnterTransition: AnimatedContentTransitionScope.() -> EnterTransition = { + when (initialState.transitionPrefix()) { + RoutePrefix.NORMAL_ -> + slideInHorizontally( + initialOffsetX = { -it }, + animationSpec = tween(Constants.Ui.SCREEN_ANIMATION_DURATION), + ) + + RoutePrefix.MODAL_ -> + slideInVertically( + initialOffsetY = { -it }, + animationSpec = tween(Constants.Ui.SCREEN_ANIMATION_DURATION), + ) + + RoutePrefix.BOTTOM_NAV_ -> fadeIn(tween(Constants.Ui.SCREEN_FADE_DURATION)) + } + } + + val popExitTransition: AnimatedContentTransitionScope.() -> ExitTransition? = { + when (initialState.transitionPrefix()) { + RoutePrefix.NORMAL_ -> + slideOutHorizontally( + targetOffsetX = { it }, + animationSpec = tween(Constants.Ui.SCREEN_ANIMATION_DURATION), + ) + + RoutePrefix.MODAL_ -> + slideOutVertically( + targetOffsetY = { it }, + animationSpec = tween(Constants.Ui.SCREEN_ANIMATION_DURATION), + ) + + RoutePrefix.BOTTOM_NAV_ -> fadeOut(tween(Constants.Ui.SCREEN_FADE_DURATION)) + } + } +} + +private fun NavBackStackEntry.transitionPrefix(): Transitions.RoutePrefix = + when { + this.destination.route!!.startsWith("${Transitions.RoutePrefix.MODAL_}") -> Transitions.RoutePrefix.MODAL_ + this.destination.route!!.startsWith("${Transitions.RoutePrefix.NORMAL_}") -> Transitions.RoutePrefix.NORMAL_ + this.destination.route!!.startsWith("${Transitions.RoutePrefix.BOTTOM_NAV_}") -> Transitions.RoutePrefix.BOTTOM_NAV_ + else -> throw IllegalStateException("Unknown transition prefix") + } diff --git a/app/src/main/kotlin/app/futured/androidprojecttemplate/tools/Constants.kt b/app/src/main/kotlin/app/futured/androidprojecttemplate/tools/Constants.kt index 27203d2..77b20f6 100644 --- a/app/src/main/kotlin/app/futured/androidprojecttemplate/tools/Constants.kt +++ b/app/src/main/kotlin/app/futured/androidprojecttemplate/tools/Constants.kt @@ -6,4 +6,9 @@ interface Constants { const val BASE_PROD_URL = "https://reqres.in/" const val TIMEOUT_IN_SECONDS = 30L } + + object Ui { + const val SCREEN_ANIMATION_DURATION = 200 + const val SCREEN_FADE_DURATION = 100 + } } diff --git a/app/src/main/kotlin/app/futured/androidprojecttemplate/tools/extensions/GeneralExtensions.kt b/app/src/main/kotlin/app/futured/androidprojecttemplate/tools/extensions/GeneralExtensions.kt new file mode 100644 index 0000000..2539ce6 --- /dev/null +++ b/app/src/main/kotlin/app/futured/androidprojecttemplate/tools/extensions/GeneralExtensions.kt @@ -0,0 +1,28 @@ +package app.futured.androidprojecttemplate.tools.extensions + +inline fun T?.ifNull(defaultValue: () -> T): T = this ?: defaultValue.invoke() + +inline fun withValue(receiver: T, block: T.() -> Unit) { + receiver.block() +} + +inline fun withNonNullValue(receiver: T?, block: (T) -> Unit) { + if (receiver != null) block(receiver) +} + +inline fun safe(block: () -> T): T? { + return try { + block() + } catch (e: Exception) { + e.printStackTrace() + null + } +} + +fun T?.orThrow(): T = this ?: error("UnexpectedError") // Dev error + +inline fun ifElseNull(predicate: Boolean, block: () -> T?) = if (predicate) block.invoke() else null + +inline fun T.runWith(block: (T) -> Unit) { + block(this) +} diff --git a/app/src/main/kotlin/app/futured/androidprojecttemplate/tools/extensions/ModifierExtensions.kt b/app/src/main/kotlin/app/futured/androidprojecttemplate/tools/extensions/ModifierExtensions.kt new file mode 100644 index 0000000..c0de329 --- /dev/null +++ b/app/src/main/kotlin/app/futured/androidprojecttemplate/tools/extensions/ModifierExtensions.kt @@ -0,0 +1,27 @@ +package app.futured.androidprojecttemplate.tools.extensions + +import android.annotation.SuppressLint +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.heightIn +import androidx.compose.foundation.layout.navigationBarsPadding +import androidx.compose.foundation.layout.wrapContentSize +import androidx.compose.material3.MaterialTheme +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.platform.LocalConfiguration +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.dp + +@SuppressLint("ComposeModifierWithoutDefault", "ComposeComposableModifier") +@Composable +fun Modifier.bottomSheetSize( + background: Color = MaterialTheme.colorScheme.background, + maxHeight: Dp = LocalConfiguration.current.screenHeightDp.dp, +): Modifier = + fillMaxWidth() + .wrapContentSize() + .heightIn(max = maxHeight) + .background(background) + .navigationBarsPadding() diff --git a/app/src/main/kotlin/app/futured/androidprojecttemplate/tools/extensions/SavedStateHandleExtensions.kt b/app/src/main/kotlin/app/futured/androidprojecttemplate/tools/extensions/SavedStateHandleExtensions.kt new file mode 100644 index 0000000..2203b9f --- /dev/null +++ b/app/src/main/kotlin/app/futured/androidprojecttemplate/tools/extensions/SavedStateHandleExtensions.kt @@ -0,0 +1,44 @@ +package app.futured.androidprojecttemplate.tools.extensions + +import android.util.Base64.NO_PADDING +import android.util.Base64.NO_WRAP +import android.util.Base64.URL_SAFE +import android.util.Base64.decode +import android.util.Base64.encodeToString +import androidx.lifecycle.Observer +import androidx.lifecycle.SavedStateHandle +import kotlinx.serialization.encodeToString +import kotlinx.serialization.json.Json + +inline fun SavedStateHandle.getSerializedArgument(key: String): T? = get(key)?.deserializeFromNavArgument() + +inline fun SavedStateHandle.getRequiredSerializedArgument(key: String): T = + getSerializedArgument(key) ?: error("Required parameter is not present") + +inline fun SavedStateHandle.getArgument(key: String): T? = safe { get(key) } + +inline fun SavedStateHandle.getRequiredArgument(key: String): T = + getArgument(key) ?: getSerializedArgument(key) ?: error("Required parameter is not present") + +inline fun T.serializeAsNavArgument(): String? = + encodeToString(Json.encodeToString(this).encodeToByteArray(), NO_PADDING or NO_WRAP or URL_SAFE) + +inline fun String.deserializeFromNavArgument(): T? = + safe { Json.decodeFromString(decode(this, NO_PADDING or NO_WRAP or URL_SAFE).decodeToString()) } + +fun SavedStateHandle.subscribeForResult(key: String, callback: (T) -> Unit) { + val liveData = this.getLiveData(key) + val observer = object : Observer { + override fun onChanged(t: T) { + if (t != null) { + val value = remove(key) + if (value != null) { + callback(t) + } + liveData.removeObserver(this) + subscribeForResult(key, callback) + } + } + } + liveData.observeForever(observer) +} diff --git a/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/AppUI.kt b/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/AppUI.kt index ab0e7c3..f47e23a 100644 --- a/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/AppUI.kt +++ b/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/AppUI.kt @@ -2,7 +2,9 @@ package app.futured.androidprojecttemplate.ui import androidx.compose.runtime.Composable import app.futured.androidprojecttemplate.ui.theme.AppTheme +import com.google.accompanist.navigation.material.ExperimentalMaterialNavigationApi +@OptIn(ExperimentalMaterialNavigationApi::class) @Composable fun AppUI() { AppTheme { diff --git a/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/NavGraph.kt b/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/NavGraph.kt index d1ff03c..8bf34da 100644 --- a/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/NavGraph.kt +++ b/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/NavGraph.kt @@ -7,16 +7,24 @@ import androidx.navigation.NavHostController import androidx.navigation.compose.NavHost import androidx.navigation.compose.rememberNavController import app.futured.androidprojecttemplate.navigation.Destination -import app.futured.androidprojecttemplate.navigation.NavigationDestinations -import app.futured.androidprojecttemplate.navigation.NavigationDestinationsImpl -import app.futured.androidprojecttemplate.navigation.composable -import app.futured.androidprojecttemplate.ui.screens.detail.DetailScreen -import app.futured.androidprojecttemplate.ui.screens.home.HomeScreen +import app.futured.androidprojecttemplate.navigation.NavRouter +import app.futured.androidprojecttemplate.navigation.NavRouterImpl +import app.futured.androidprojecttemplate.navigation.bottomSheetDialogs +import app.futured.androidprojecttemplate.navigation.composableBottomSheetDialog +import app.futured.androidprojecttemplate.navigation.composableDialog +import app.futured.androidprojecttemplate.navigation.composableScreen +import app.futured.androidprojecttemplate.navigation.dialogs +import app.futured.androidprojecttemplate.navigation.screens +import com.google.accompanist.navigation.material.BottomSheetNavigator +import com.google.accompanist.navigation.material.ExperimentalMaterialNavigationApi +import com.google.accompanist.navigation.material.rememberBottomSheetNavigator +@OptIn(ExperimentalMaterialNavigationApi::class) @Composable fun NavGraph( - navController: NavHostController = rememberNavController(), - navigation: NavigationDestinations = remember { NavigationDestinationsImpl(navController) }, + bottomSheetNavigator: BottomSheetNavigator = rememberBottomSheetNavigator(), + navController: NavHostController = rememberNavController(bottomSheetNavigator), + navigation: NavRouter = remember { NavRouterImpl(navController) }, ) { LocalOnBackPressedDispatcherOwner.current?.onBackPressedDispatcher?.let { navController.popBackStack() @@ -26,12 +34,19 @@ fun NavGraph( navController = navController, startDestination = Destination.Home.route, ) { - composable(Destination.Home) { - HomeScreen(navigation) + // Destinations without navbar at the bottom + screens.forEach { destination -> + composableScreen(destination) { destination.destinationScreen(navigation) } } - composable(Destination.Detail) { - DetailScreen(navigation) + // Bottom sheet dialogs + bottomSheetDialogs.forEach { destination -> + composableBottomSheetDialog(destination) { destination.destinationScreen(navigation) } + } + + // Dialogs + dialogs.forEach { destination -> + composableDialog(destination) { destination.destinationScreen(navigation) } } } } diff --git a/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/screens/_templateScreen/_TEMPLATEScreen.kt b/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/screens/_templateScreen/_TEMPLATEScreen.kt new file mode 100644 index 0000000..6d7488d --- /dev/null +++ b/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/screens/_templateScreen/_TEMPLATEScreen.kt @@ -0,0 +1,124 @@ +@file:OptIn(ExperimentalMaterial3Api::class) + +package app.futured.androidprojecttemplate.ui.screens._templateScreen + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.padding +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.automirrored.filled.ArrowBack +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.Scaffold +import androidx.compose.material3.Text +import androidx.compose.material3.TopAppBar +import androidx.compose.runtime.Composable +import androidx.compose.runtime.Stable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.hilt.navigation.compose.hiltViewModel +import app.futured.androidprojecttemplate.navigation.NavRouter +import app.futured.androidprojecttemplate.tools.arch.BaseViewModel +import app.futured.androidprojecttemplate.tools.arch.EventsEffect +import app.futured.androidprojecttemplate.tools.arch.onEvent +import app.futured.androidprojecttemplate.tools.compose.ScreenPreviews +import app.futured.androidprojecttemplate.ui.components.Showcase +import app.futured.arkitekt.core.ViewState +import app.futured.arkitekt.core.event.Event +import dagger.hilt.android.lifecycle.HiltViewModel +import dagger.hilt.android.scopes.ViewModelScoped +import javax.inject.Inject + +/** + * This is a template for creating new screens: + * + * 1. Copy wherever you wanna create the screen. + * 2. Select all occurrences of "TEMPLATE" (Ctrl + G) and rename to your liking. + * 3. Extract all parts to respective files (alt+enter on interface/class signature -> extract from file). + */ +@Composable +fun TEMPLATEScreen( + navigation: NavRouter, + viewModel: TEMPLATEViewModel = hiltViewModel(), // createModalViewModel(), +) { + with(viewModel) { + EventsEffect { + onEvent { + navigation.popBackStack() + } + } + + TEMPLATE.Content( + actions = this, + ) + } +} + +object TEMPLATE { + @Stable + interface Actions { + fun onNavigateBack() + } + + @Composable + fun Content( + actions: Actions, + modifier: Modifier = Modifier, + ) { + Scaffold( + topBar = { + TopAppBar( + title = { Text(text = "TEMPLATEScreen") }, + navigationIcon = { + IconButton( + onClick = { actions.onNavigateBack() }, + ) { + Icon(Icons.AutoMirrored.Filled.ArrowBack, "") + } + }, + ) + }, + modifier = modifier, + ) { contentPadding -> + Column( + verticalArrangement = Arrangement.Center, + horizontalAlignment = Alignment.CenterHorizontally, + modifier = + Modifier + .fillMaxSize() + .padding(contentPadding), + ) { + Text(text = "TEMPLATE") + } + } + } +} + +@ScreenPreviews +@Composable +fun TEMPLATEContentPreview() = Showcase { + TEMPLATE.Content( + actions = + object : TEMPLATE.Actions { + override fun onNavigateBack() = Unit + }, + ) +} + +sealed class TEMPLATEEvent : Event() + +data object NavigateBackEvent : TEMPLATEEvent() + +@HiltViewModel +class TEMPLATEViewModel @Inject constructor( + override val viewState: TEMPLATEViewState, +) : BaseViewModel(), TEMPLATE.Actions { + override fun onNavigateBack() { + sendEvent(NavigateBackEvent) + } +} + +@ViewModelScoped +class TEMPLATEViewState @Inject constructor() : ViewState diff --git a/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/screens/detail/DetailEvents.kt b/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/screens/detail/DetailEvents.kt index 6dbe139..6449e1d 100644 --- a/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/screens/detail/DetailEvents.kt +++ b/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/screens/detail/DetailEvents.kt @@ -4,3 +4,5 @@ import app.futured.arkitekt.core.event.Event sealed class DetailEvents : Event() data object NavigateBackEvent : DetailEvents() + +data object NavigateToInfoEvent : DetailEvents() diff --git a/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/screens/detail/DetailScreen.kt b/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/screens/detail/DetailScreen.kt index 3462a0c..64c091e 100644 --- a/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/screens/detail/DetailScreen.kt +++ b/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/screens/detail/DetailScreen.kt @@ -4,10 +4,13 @@ package app.futured.androidprojecttemplate.ui.screens.detail import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.ArrowBack +import androidx.compose.material3.Button import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon import androidx.compose.material3.IconButton @@ -18,16 +21,17 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.hilt.navigation.compose.hiltViewModel -import app.futured.androidprojecttemplate.navigation.NavigationDestinations +import app.futured.androidprojecttemplate.navigation.NavRouter import app.futured.androidprojecttemplate.tools.arch.EventsEffect import app.futured.androidprojecttemplate.tools.arch.onEvent import app.futured.androidprojecttemplate.tools.compose.ScreenPreviews import app.futured.androidprojecttemplate.ui.components.AddFloatingActionButton import app.futured.androidprojecttemplate.ui.components.Showcase +import app.futured.androidprojecttemplate.ui.theme.Grid @Composable fun DetailScreen( - navigation: NavigationDestinations, + navigation: NavRouter, viewModel: DetailViewModel = hiltViewModel(), ) { with(viewModel) { @@ -35,6 +39,9 @@ fun DetailScreen( onEvent { navigation.popBackStack() } + onEvent { + navigation.navigateToInfo() + } } Detail.Content( @@ -45,13 +52,13 @@ fun DetailScreen( } object Detail { - interface Actions { - fun navigateBack() = Unit - fun incrementCounter() = Unit - } + fun onNavigateBack() - object PreviewActions : Actions + fun onNavigateToInfo() + + fun onIncrementCounter() + } @Composable fun Content( @@ -65,7 +72,7 @@ object Detail { title = { Text(text = "DetailScreen") }, navigationIcon = { IconButton( - onClick = { actions.navigateBack() }, + onClick = { actions.onNavigateBack() }, ) { Icon(Icons.AutoMirrored.Filled.ArrowBack, "") } @@ -75,7 +82,7 @@ object Detail { floatingActionButton = { AddFloatingActionButton( onClick = { - actions.incrementCounter() + actions.onIncrementCounter() }, ) }, @@ -85,10 +92,14 @@ object Detail { verticalArrangement = Arrangement.Center, horizontalAlignment = Alignment.CenterHorizontally, modifier = Modifier - .padding(contentPadding) - .fillMaxSize(), + .fillMaxSize() + .padding(contentPadding), ) { Text(text = "Detail: $counter") + Spacer(modifier = Modifier.height(Grid.d4)) + Button(onClick = { actions.onNavigateToInfo() }) { + Text(text = "Open bottom sheet") + } } } } @@ -99,7 +110,11 @@ object Detail { fun DetailContentPreview() { Showcase { Detail.Content( - Detail.PreviewActions, + actions = object : Detail.Actions { + override fun onNavigateBack() = Unit + override fun onNavigateToInfo() = Unit + override fun onIncrementCounter() = Unit + }, counter = 5, ) } diff --git a/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/screens/detail/DetailViewModel.kt b/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/screens/detail/DetailViewModel.kt index a243d72..265154a 100644 --- a/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/screens/detail/DetailViewModel.kt +++ b/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/screens/detail/DetailViewModel.kt @@ -8,12 +8,15 @@ import javax.inject.Inject class DetailViewModel @Inject constructor( override val viewState: DetailViewState, ) : BaseViewModel(), Detail.Actions { - - override fun navigateBack() { + override fun onNavigateBack() { sendEvent(NavigateBackEvent) } - override fun incrementCounter() { + override fun onIncrementCounter() { viewState.counter++ } + + override fun onNavigateToInfo() { + sendEvent(NavigateToInfoEvent) + } } diff --git a/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/screens/home/HomeScreen.kt b/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/screens/home/HomeScreen.kt index 077da46..134041c 100644 --- a/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/screens/home/HomeScreen.kt +++ b/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/screens/home/HomeScreen.kt @@ -12,10 +12,11 @@ import androidx.compose.material3.Scaffold import androidx.compose.material3.Text import androidx.compose.material3.TopAppBar import androidx.compose.runtime.Composable +import androidx.compose.runtime.Stable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.hilt.navigation.compose.hiltViewModel -import app.futured.androidprojecttemplate.navigation.NavigationDestinations +import app.futured.androidprojecttemplate.navigation.NavRouter import app.futured.androidprojecttemplate.tools.arch.EventsEffect import app.futured.androidprojecttemplate.tools.arch.onEvent import app.futured.androidprojecttemplate.tools.compose.ScreenPreviews @@ -24,13 +25,13 @@ import app.futured.androidprojecttemplate.ui.components.Showcase @Composable fun HomeScreen( - navigation: NavigationDestinations, + navigation: NavRouter, viewModel: HomeViewModel = hiltViewModel(), ) { with(viewModel) { EventsEffect { onEvent { - navigation.navigateToDetailScreen( + navigation.navigateToDetail( title = "Demo", subtitle = "Subtitle", value = "Demo Subtitle", @@ -47,15 +48,13 @@ fun HomeScreen( object Home { + @Stable interface Actions { + fun onNavigateToDetail() - fun navigateToDetailScreen() = Unit - - fun incrementCounter() = Unit + fun onIncrementCounter() } - object PreviewActions : Actions - @Composable fun Content( actions: Actions, @@ -67,7 +66,7 @@ object Home { floatingActionButton = { AddFloatingActionButton( onClick = { - actions.incrementCounter() + actions.onIncrementCounter() }, ) }, @@ -77,10 +76,10 @@ object Home { verticalArrangement = Arrangement.Center, horizontalAlignment = Alignment.CenterHorizontally, modifier = Modifier - .padding(contentPadding) .fillMaxSize() + .padding(contentPadding) .clickable { - actions.navigateToDetailScreen() + actions.onNavigateToDetail() }, ) { Text(text = "Home: $counter") @@ -94,7 +93,11 @@ object Home { fun HomeContentPreview() { Showcase { Home.Content( - Home.PreviewActions, + actions = + object : Home.Actions { + override fun onNavigateToDetail() = Unit + override fun onIncrementCounter() = Unit + }, counter = 5, ) } diff --git a/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/screens/home/HomeViewModel.kt b/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/screens/home/HomeViewModel.kt index c6a77bb..4dea20e 100644 --- a/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/screens/home/HomeViewModel.kt +++ b/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/screens/home/HomeViewModel.kt @@ -8,12 +8,11 @@ import javax.inject.Inject class HomeViewModel @Inject constructor( override val viewState: HomeViewState, ) : BaseViewModel(), Home.Actions { - - override fun incrementCounter() { + override fun onIncrementCounter() { viewState.counter++ } - override fun navigateToDetailScreen() { + override fun onNavigateToDetail() { sendEvent(NavigateToDetailEvent) } } diff --git a/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/screens/info/InfoEvent.kt b/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/screens/info/InfoEvent.kt new file mode 100644 index 0000000..9131b67 --- /dev/null +++ b/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/screens/info/InfoEvent.kt @@ -0,0 +1,7 @@ +package app.futured.androidprojecttemplate.ui.screens.info + +import app.futured.arkitekt.core.event.Event + +sealed class InfoEvent : Event() + +data object NavigateBackEvent : InfoEvent() diff --git a/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/screens/info/InfoScreen.kt b/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/screens/info/InfoScreen.kt new file mode 100644 index 0000000..9453be5 --- /dev/null +++ b/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/screens/info/InfoScreen.kt @@ -0,0 +1,69 @@ +package app.futured.androidprojecttemplate.ui.screens.info + +import androidx.compose.foundation.layout.Column +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.Stable +import androidx.compose.ui.Modifier +import androidx.hilt.navigation.compose.hiltViewModel +import app.futured.androidprojecttemplate.navigation.NavRouter +import app.futured.androidprojecttemplate.tools.arch.EventsEffect +import app.futured.androidprojecttemplate.tools.arch.onEvent +import app.futured.androidprojecttemplate.tools.compose.ScreenPreviews +import app.futured.androidprojecttemplate.tools.extensions.bottomSheetSize +import app.futured.androidprojecttemplate.ui.components.Showcase + +@Composable +fun InfoScreen( + navigation: NavRouter, + viewModel: InfoViewModel = hiltViewModel(), // createModalViewModel(), +) { + with(viewModel) { + EventsEffect { + onEvent { + navigation.popBackStack() + } + } + + Info.Content( + actions = this, + ) + } +} + +object Info { + + @Stable + interface Actions { + fun onNavigateBack() + } + + @Composable + fun Content( + actions: Actions, + modifier: Modifier = Modifier, + ) { + Column( + modifier = modifier.bottomSheetSize(), + ) { + Text( + text = + "This is a BottomSheet, a commonly used user interface component in Android and other mobile operating systems." + + " It is used to display content that slides up from the bottom of the screen, providing users with additional choices and " + + "actions. This particular BottomSheet is part of a mock-up, serving purely for testing purposes. " + + "Please note that the text displayed here is only placeholder text and does not represent any actual content or functionalities. " + + "The aim of this testing is to validate the design, layout, and overall user experience of the BottomSheet component.", + ) + } + } +} + +@ScreenPreviews +@Composable +fun InfoContentPreview() = Showcase { + Info.Content( + actions = object : Info.Actions { + override fun onNavigateBack() = Unit + }, + ) +} diff --git a/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/screens/info/InfoViewModel.kt b/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/screens/info/InfoViewModel.kt new file mode 100644 index 0000000..39cd395 --- /dev/null +++ b/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/screens/info/InfoViewModel.kt @@ -0,0 +1,14 @@ +package app.futured.androidprojecttemplate.ui.screens.info + +import app.futured.androidprojecttemplate.tools.arch.BaseViewModel +import dagger.hilt.android.lifecycle.HiltViewModel +import javax.inject.Inject + +@HiltViewModel +class InfoViewModel @Inject constructor( + override val viewState: InfoViewState, +) : BaseViewModel(), Info.Actions { + override fun onNavigateBack() { + sendEvent(NavigateBackEvent) + } +} diff --git a/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/screens/info/InfoViewState.kt b/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/screens/info/InfoViewState.kt new file mode 100644 index 0000000..17d186a --- /dev/null +++ b/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/screens/info/InfoViewState.kt @@ -0,0 +1,8 @@ +package app.futured.androidprojecttemplate.ui.screens.info + +import app.futured.arkitekt.core.ViewState +import dagger.hilt.android.scopes.ViewModelScoped +import javax.inject.Inject + +@ViewModelScoped +class InfoViewState @Inject constructor() : ViewState diff --git a/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/theme/Dimensions.kt b/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/theme/Dimensions.kt new file mode 100644 index 0000000..c3c40a0 --- /dev/null +++ b/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/theme/Dimensions.kt @@ -0,0 +1,118 @@ +@file:Suppress("MagicNumber") + +package app.futured.androidprojecttemplate.ui.theme + +import androidx.compose.ui.unit.dp + +object Grid { + val d0 = 0.dp + val d0_25 = 1.dp + val d0_375 = 1.5.dp + val d0_5 = 2.dp + val d0_75 = 3.dp + val d1 = 4.dp + val d1_25 = 5.dp + val d1_5 = 6.dp + val d2 = 8.dp + val d2_25 = 9.dp + val d2_5 = 10.dp + val d3 = 12.dp + val d3_5 = 14.dp + val d4 = 16.dp + val d5 = 20.dp + val d6 = 24.dp + val d7 = 28.dp + val d8 = 32.dp + val d9 = 36.dp + val d10 = 40.dp + val d11 = 44.dp + val d12 = 48.dp + val d13 = 52.dp + val d14 = 56.dp + val d15 = 60.dp + val d16 = 64.dp + val d17 = 68.dp + val d18 = 72.dp + val d19 = 76.dp + val d20 = 80.dp + val d21 = 84.dp + val d22 = 88.dp + val d23 = 92.dp + val d24 = 96.dp + val d25 = 100.dp + val d26 = 104.dp + val d27 = 108.dp + val d28 = 112.dp + val d29 = 116.dp + val d30 = 120.dp + val d31 = 124.dp + val d32 = 128.dp + val d33 = 132.dp + val d34 = 136.dp + val d35 = 140.dp + val d36 = 144.dp + val d37 = 148.dp + val d38 = 152.dp + val d39 = 156.dp + val d40 = 160.dp + val d41 = 164.dp + val d42 = 168.dp + val d43 = 172.dp + val d44 = 176.dp + val d45 = 180.dp + val d46 = 184.dp + val d47 = 188.dp + val d48 = 192.dp + val d49 = 196.dp + val d50 = 200.dp + val d51 = 204.dp + val d52 = 208.dp + val d53 = 212.dp + val d54 = 216.dp + val d55 = 220.dp + val d56 = 224.dp + val d57 = 228.dp + val d58 = 232.dp + val d59 = 236.dp + val d60 = 240.dp + val d61 = 244.dp + val d62 = 248.dp + val d63 = 252.dp + val d64 = 256.dp + val d65 = 260.dp + val d66 = 264.dp + val d67 = 268.dp + val d68 = 272.dp + val d69 = 276.dp + val d70 = 280.dp + val d71 = 284.dp + val d72 = 288.dp + val d73 = 292.dp + val d74 = 296.dp + val d75 = 300.dp + val d76 = 304.dp + val d77 = 308.dp + val d78 = 312.dp + val d79 = 316.dp + val d80 = 320.dp + val d81 = 324.dp + val d82 = 328.dp + val d83 = 332.dp + val d84 = 336.dp + val d85 = 340.dp + val d86 = 344.dp + val d87 = 348.dp + val d88 = 352.dp + val d89 = 356.dp + val d90 = 360.dp + val d91 = 364.dp + val d92 = 368.dp + val d93 = 372.dp + val d94 = 376.dp + val d95 = 380.dp + val d96 = 384.dp + val d97 = 388.dp + val d98 = 392.dp + val d99 = 396.dp + val d100 = 400.dp +} diff --git a/buildSrc/src/main/kotlin/Dependencies.kt b/buildSrc/src/main/kotlin/Dependencies.kt index 0ee66a6..15a5f49 100644 --- a/buildSrc/src/main/kotlin/Dependencies.kt +++ b/buildSrc/src/main/kotlin/Dependencies.kt @@ -40,6 +40,10 @@ object Dependencies { const val preference = "androidx.preference:preference-ktx:${Versions.preference}" } + object Accompanist { + const val navigationMaterial = "com.google.accompanist:accompanist-navigation-material:${Versions.accompanist}" + } + object NavigationComponents { const val navigation = "androidx.navigation:navigation-compose:${Versions.navigation}" const val navigationHilt = "androidx.hilt:hilt-navigation-compose:${Versions.hiltNavigation}" diff --git a/buildSrc/src/main/kotlin/Versions.kt b/buildSrc/src/main/kotlin/Versions.kt index 9505d78..6ac3c9d 100644 --- a/buildSrc/src/main/kotlin/Versions.kt +++ b/buildSrc/src/main/kotlin/Versions.kt @@ -7,8 +7,8 @@ object Versions { // plugins const val detekt = "1.23.6" - const val ktlintGradle = "12.1.0" - const val ktlint = "1.0.1" + const val ktlintGradle = "12.1.1" + const val ktlint = "1.2.1" // kotlin const val kotlin = "1.9.23" @@ -25,6 +25,7 @@ object Versions { const val constraintLayout = "1.0.1" const val vectorDrawable = "1.2.0-beta01" const val preference = "1.2.1" + const val accompanist = "0.34.0" const val activity = "1.9.0" const val desugarLibs = "2.0.4" From 47bb6b42affa2110ebe2846d5921a47258f171d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20M=C4=9Bs=C3=AD=C4=8Dek?= Date: Thu, 9 May 2024 12:09:01 +0200 Subject: [PATCH 3/6] Update navigation --- .../tools/extensions/ModifierExtensions.kt | 5 --- .../androidprojecttemplate/ui/NavGraph.kt | 39 ++++++++++++------- .../ui/screens/info/InfoScreen.kt | 3 ++ 3 files changed, 28 insertions(+), 19 deletions(-) diff --git a/app/src/main/kotlin/app/futured/androidprojecttemplate/tools/extensions/ModifierExtensions.kt b/app/src/main/kotlin/app/futured/androidprojecttemplate/tools/extensions/ModifierExtensions.kt index c0de329..25800d0 100644 --- a/app/src/main/kotlin/app/futured/androidprojecttemplate/tools/extensions/ModifierExtensions.kt +++ b/app/src/main/kotlin/app/futured/androidprojecttemplate/tools/extensions/ModifierExtensions.kt @@ -1,15 +1,12 @@ package app.futured.androidprojecttemplate.tools.extensions import android.annotation.SuppressLint -import androidx.compose.foundation.background import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.heightIn import androidx.compose.foundation.layout.navigationBarsPadding import androidx.compose.foundation.layout.wrapContentSize -import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalConfiguration import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp @@ -17,11 +14,9 @@ import androidx.compose.ui.unit.dp @SuppressLint("ComposeModifierWithoutDefault", "ComposeComposableModifier") @Composable fun Modifier.bottomSheetSize( - background: Color = MaterialTheme.colorScheme.background, maxHeight: Dp = LocalConfiguration.current.screenHeightDp.dp, ): Modifier = fillMaxWidth() .wrapContentSize() .heightIn(max = maxHeight) - .background(background) .navigationBarsPadding() diff --git a/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/NavGraph.kt b/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/NavGraph.kt index 8bf34da..98680c3 100644 --- a/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/NavGraph.kt +++ b/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/NavGraph.kt @@ -1,6 +1,8 @@ package app.futured.androidprojecttemplate.ui import androidx.activity.compose.LocalOnBackPressedDispatcherOwner +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.Composable import androidx.compose.runtime.remember import androidx.navigation.NavHostController @@ -15,8 +17,10 @@ import app.futured.androidprojecttemplate.navigation.composableDialog import app.futured.androidprojecttemplate.navigation.composableScreen import app.futured.androidprojecttemplate.navigation.dialogs import app.futured.androidprojecttemplate.navigation.screens +import app.futured.androidprojecttemplate.ui.theme.Grid import com.google.accompanist.navigation.material.BottomSheetNavigator import com.google.accompanist.navigation.material.ExperimentalMaterialNavigationApi +import com.google.accompanist.navigation.material.ModalBottomSheetLayout import com.google.accompanist.navigation.material.rememberBottomSheetNavigator @OptIn(ExperimentalMaterialNavigationApi::class) @@ -30,23 +34,30 @@ fun NavGraph( navController.popBackStack() } - NavHost( - navController = navController, - startDestination = Destination.Home.route, + ModalBottomSheetLayout( + bottomSheetNavigator = bottomSheetNavigator, + sheetShape = RoundedCornerShape(Grid.d3), + sheetElevation = Grid.d4, + sheetBackgroundColor = MaterialTheme.colorScheme.background, ) { - // Destinations without navbar at the bottom - screens.forEach { destination -> - composableScreen(destination) { destination.destinationScreen(navigation) } - } + NavHost( + navController = navController, + startDestination = Destination.Home.route, + ) { + // Destinations without navbar at the bottom + screens.forEach { destination -> + composableScreen(destination) { destination.destinationScreen(navigation) } + } - // Bottom sheet dialogs - bottomSheetDialogs.forEach { destination -> - composableBottomSheetDialog(destination) { destination.destinationScreen(navigation) } - } + // Bottom sheet dialogs + bottomSheetDialogs.forEach { destination -> + composableBottomSheetDialog(destination) { destination.destinationScreen(navigation) } + } - // Dialogs - dialogs.forEach { destination -> - composableDialog(destination) { destination.destinationScreen(navigation) } + // Dialogs + dialogs.forEach { destination -> + composableDialog(destination) { destination.destinationScreen(navigation) } + } } } } diff --git a/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/screens/info/InfoScreen.kt b/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/screens/info/InfoScreen.kt index 9453be5..6e6fb9b 100644 --- a/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/screens/info/InfoScreen.kt +++ b/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/screens/info/InfoScreen.kt @@ -1,6 +1,7 @@ package app.futured.androidprojecttemplate.ui.screens.info import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.padding import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.Stable @@ -12,6 +13,7 @@ import app.futured.androidprojecttemplate.tools.arch.onEvent import app.futured.androidprojecttemplate.tools.compose.ScreenPreviews import app.futured.androidprojecttemplate.tools.extensions.bottomSheetSize import app.futured.androidprojecttemplate.ui.components.Showcase +import app.futured.androidprojecttemplate.ui.theme.Grid @Composable fun InfoScreen( @@ -47,6 +49,7 @@ object Info { modifier = modifier.bottomSheetSize(), ) { Text( + modifier = Modifier.padding(Grid.d4), text = "This is a BottomSheet, a commonly used user interface component in Android and other mobile operating systems." + " It is used to display content that slides up from the bottom of the screen, providing users with additional choices and " + From 4e3522203c9cea8067ff93784ffa2cfb44b43f3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20M=C4=9Bs=C3=AD=C4=8Dek?= Date: Thu, 9 May 2024 12:10:07 +0200 Subject: [PATCH 4/6] Delete transitions --- .../navigation/Destinations.kt | 4 - .../navigation/Transitions.kt | 101 ------------------ .../androidprojecttemplate/ui/NavGraph.kt | 2 +- 3 files changed, 1 insertion(+), 106 deletions(-) delete mode 100644 app/src/main/kotlin/app/futured/androidprojecttemplate/navigation/Transitions.kt diff --git a/app/src/main/kotlin/app/futured/androidprojecttemplate/navigation/Destinations.kt b/app/src/main/kotlin/app/futured/androidprojecttemplate/navigation/Destinations.kt index d5511a6..889e3a8 100644 --- a/app/src/main/kotlin/app/futured/androidprojecttemplate/navigation/Destinations.kt +++ b/app/src/main/kotlin/app/futured/androidprojecttemplate/navigation/Destinations.kt @@ -85,10 +85,6 @@ fun NavGraphBuilder.composableScreen( route = destination.route, arguments = destination.arguments, deepLinks = destination.deepLinks, -// enterTransition = Transitions.enterTransition, -// exitTransition = Transitions.exitTransition, -// popEnterTransition = Transitions.popEnterTransition, -// popExitTransition = Transitions.popExitTransition, content = content, ) diff --git a/app/src/main/kotlin/app/futured/androidprojecttemplate/navigation/Transitions.kt b/app/src/main/kotlin/app/futured/androidprojecttemplate/navigation/Transitions.kt deleted file mode 100644 index 677ee09..0000000 --- a/app/src/main/kotlin/app/futured/androidprojecttemplate/navigation/Transitions.kt +++ /dev/null @@ -1,101 +0,0 @@ -package app.futured.androidprojecttemplate.navigation - -import androidx.compose.animation.AnimatedContentTransitionScope -import androidx.compose.animation.EnterTransition -import androidx.compose.animation.ExitTransition -import androidx.compose.animation.core.tween -import androidx.compose.animation.fadeIn -import androidx.compose.animation.fadeOut -import androidx.compose.animation.slideInHorizontally -import androidx.compose.animation.slideInVertically -import androidx.compose.animation.slideOutHorizontally -import androidx.compose.animation.slideOutVertically -import androidx.navigation.NavBackStackEntry -import app.futured.androidprojecttemplate.tools.Constants - -object Transitions { - enum class RoutePrefix { - MODAL_, - NORMAL_, - BOTTOM_NAV_, - } - - val enterTransition: (AnimatedContentTransitionScope.() -> EnterTransition?) = { - when (targetState.transitionPrefix()) { - RoutePrefix.NORMAL_ -> - slideInHorizontally( - initialOffsetX = { it }, - animationSpec = tween(Constants.Ui.SCREEN_ANIMATION_DURATION), - ) - - RoutePrefix.MODAL_ -> - slideInVertically( - initialOffsetY = { it }, - animationSpec = tween(Constants.Ui.SCREEN_ANIMATION_DURATION), - ) - - RoutePrefix.BOTTOM_NAV_ -> fadeIn(animationSpec = tween(Constants.Ui.SCREEN_FADE_DURATION)) - } - } - val exitTransition: (AnimatedContentTransitionScope.() -> ExitTransition?) = { - when (targetState.transitionPrefix()) { - RoutePrefix.NORMAL_ -> - slideOutHorizontally( - targetOffsetX = { -it }, - animationSpec = tween(Constants.Ui.SCREEN_ANIMATION_DURATION), - ) - - RoutePrefix.MODAL_ -> - slideOutVertically( - targetOffsetY = { -it }, - animationSpec = tween(Constants.Ui.SCREEN_ANIMATION_DURATION), - ) - - RoutePrefix.BOTTOM_NAV_ -> fadeOut(tween(Constants.Ui.SCREEN_FADE_DURATION)) - } - } - - val popEnterTransition: AnimatedContentTransitionScope.() -> EnterTransition = { - when (initialState.transitionPrefix()) { - RoutePrefix.NORMAL_ -> - slideInHorizontally( - initialOffsetX = { -it }, - animationSpec = tween(Constants.Ui.SCREEN_ANIMATION_DURATION), - ) - - RoutePrefix.MODAL_ -> - slideInVertically( - initialOffsetY = { -it }, - animationSpec = tween(Constants.Ui.SCREEN_ANIMATION_DURATION), - ) - - RoutePrefix.BOTTOM_NAV_ -> fadeIn(tween(Constants.Ui.SCREEN_FADE_DURATION)) - } - } - - val popExitTransition: AnimatedContentTransitionScope.() -> ExitTransition? = { - when (initialState.transitionPrefix()) { - RoutePrefix.NORMAL_ -> - slideOutHorizontally( - targetOffsetX = { it }, - animationSpec = tween(Constants.Ui.SCREEN_ANIMATION_DURATION), - ) - - RoutePrefix.MODAL_ -> - slideOutVertically( - targetOffsetY = { it }, - animationSpec = tween(Constants.Ui.SCREEN_ANIMATION_DURATION), - ) - - RoutePrefix.BOTTOM_NAV_ -> fadeOut(tween(Constants.Ui.SCREEN_FADE_DURATION)) - } - } -} - -private fun NavBackStackEntry.transitionPrefix(): Transitions.RoutePrefix = - when { - this.destination.route!!.startsWith("${Transitions.RoutePrefix.MODAL_}") -> Transitions.RoutePrefix.MODAL_ - this.destination.route!!.startsWith("${Transitions.RoutePrefix.NORMAL_}") -> Transitions.RoutePrefix.NORMAL_ - this.destination.route!!.startsWith("${Transitions.RoutePrefix.BOTTOM_NAV_}") -> Transitions.RoutePrefix.BOTTOM_NAV_ - else -> throw IllegalStateException("Unknown transition prefix") - } diff --git a/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/NavGraph.kt b/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/NavGraph.kt index 98680c3..3e80c27 100644 --- a/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/NavGraph.kt +++ b/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/NavGraph.kt @@ -31,7 +31,7 @@ fun NavGraph( navigation: NavRouter = remember { NavRouterImpl(navController) }, ) { LocalOnBackPressedDispatcherOwner.current?.onBackPressedDispatcher?.let { - navController.popBackStack() + navController.navigateUp() } ModalBottomSheetLayout( From 82e1a06e14f911350f6afa6d636e167a0c2353e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20M=C4=9Bs=C3=AD=C4=8Dek?= Date: Thu, 9 May 2024 12:16:55 +0200 Subject: [PATCH 5/6] Update constants --- .../androidprojecttemplate/navigation/NavRouterImpl.kt | 2 +- .../app/futured/androidprojecttemplate/tools/Constants.kt | 5 ----- .../ui/screens/_templateScreen/_TEMPLATEScreen.kt | 2 +- .../androidprojecttemplate/ui/screens/info/InfoScreen.kt | 2 +- 4 files changed, 3 insertions(+), 8 deletions(-) diff --git a/app/src/main/kotlin/app/futured/androidprojecttemplate/navigation/NavRouterImpl.kt b/app/src/main/kotlin/app/futured/androidprojecttemplate/navigation/NavRouterImpl.kt index 0b5444e..5d9dbde 100644 --- a/app/src/main/kotlin/app/futured/androidprojecttemplate/navigation/NavRouterImpl.kt +++ b/app/src/main/kotlin/app/futured/androidprojecttemplate/navigation/NavRouterImpl.kt @@ -53,4 +53,4 @@ class NavRouterImpl(private val navController: NavController) : NavRouter { navController.navigate(this) } } -} \ No newline at end of file +} diff --git a/app/src/main/kotlin/app/futured/androidprojecttemplate/tools/Constants.kt b/app/src/main/kotlin/app/futured/androidprojecttemplate/tools/Constants.kt index 77b20f6..27203d2 100644 --- a/app/src/main/kotlin/app/futured/androidprojecttemplate/tools/Constants.kt +++ b/app/src/main/kotlin/app/futured/androidprojecttemplate/tools/Constants.kt @@ -6,9 +6,4 @@ interface Constants { const val BASE_PROD_URL = "https://reqres.in/" const val TIMEOUT_IN_SECONDS = 30L } - - object Ui { - const val SCREEN_ANIMATION_DURATION = 200 - const val SCREEN_FADE_DURATION = 100 - } } diff --git a/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/screens/_templateScreen/_TEMPLATEScreen.kt b/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/screens/_templateScreen/_TEMPLATEScreen.kt index 6d7488d..be4678c 100644 --- a/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/screens/_templateScreen/_TEMPLATEScreen.kt +++ b/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/screens/_templateScreen/_TEMPLATEScreen.kt @@ -41,7 +41,7 @@ import javax.inject.Inject @Composable fun TEMPLATEScreen( navigation: NavRouter, - viewModel: TEMPLATEViewModel = hiltViewModel(), // createModalViewModel(), + viewModel: TEMPLATEViewModel = hiltViewModel(), ) { with(viewModel) { EventsEffect { diff --git a/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/screens/info/InfoScreen.kt b/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/screens/info/InfoScreen.kt index 6e6fb9b..d1fbe93 100644 --- a/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/screens/info/InfoScreen.kt +++ b/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/screens/info/InfoScreen.kt @@ -18,7 +18,7 @@ import app.futured.androidprojecttemplate.ui.theme.Grid @Composable fun InfoScreen( navigation: NavRouter, - viewModel: InfoViewModel = hiltViewModel(), // createModalViewModel(), + viewModel: InfoViewModel = hiltViewModel(), ) { with(viewModel) { EventsEffect { From 6c2d672be34af535e16cac246312a224fc6586f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20M=C4=9Bs=C3=AD=C4=8Dek?= Date: Thu, 9 May 2024 20:14:56 +0200 Subject: [PATCH 6/6] Delete bottomSheet --- app/build.gradle.kts | 3 - .../navigation/Destinations.kt | 32 +-------- .../navigation/NavRouter.kt | 1 - .../navigation/NavRouterImpl.kt | 2 - .../tools/extensions/ModifierExtensions.kt | 22 ------ .../androidprojecttemplate/ui/AppUI.kt | 2 - .../androidprojecttemplate/ui/NavGraph.kt | 45 +++--------- .../_templateScreen/_TEMPLATEScreen.kt | 3 +- .../ui/screens/detail/DetailEvents.kt | 2 - .../ui/screens/detail/DetailScreen.kt | 14 ---- .../ui/screens/detail/DetailViewModel.kt | 4 -- .../ui/screens/info/InfoEvent.kt | 7 -- .../ui/screens/info/InfoScreen.kt | 72 ------------------- .../ui/screens/info/InfoViewModel.kt | 14 ---- .../ui/screens/info/InfoViewState.kt | 8 --- buildSrc/src/main/kotlin/Dependencies.kt | 4 -- buildSrc/src/main/kotlin/Versions.kt | 7 +- 17 files changed, 17 insertions(+), 225 deletions(-) delete mode 100644 app/src/main/kotlin/app/futured/androidprojecttemplate/tools/extensions/ModifierExtensions.kt delete mode 100644 app/src/main/kotlin/app/futured/androidprojecttemplate/ui/screens/info/InfoEvent.kt delete mode 100644 app/src/main/kotlin/app/futured/androidprojecttemplate/ui/screens/info/InfoScreen.kt delete mode 100644 app/src/main/kotlin/app/futured/androidprojecttemplate/ui/screens/info/InfoViewModel.kt delete mode 100644 app/src/main/kotlin/app/futured/androidprojecttemplate/ui/screens/info/InfoViewState.kt diff --git a/app/build.gradle.kts b/app/build.gradle.kts index c11843c..791aad7 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -156,9 +156,6 @@ dependencies { implementation(Dependencies.Support.vectordrawable) implementation(Dependencies.Support.preference) - // Accompanist - implementation(Dependencies.Accompanist.navigationMaterial) - // Compose implementation(Dependencies.Compose.animation) implementation(Dependencies.Compose.foundation) diff --git a/app/src/main/kotlin/app/futured/androidprojecttemplate/navigation/Destinations.kt b/app/src/main/kotlin/app/futured/androidprojecttemplate/navigation/Destinations.kt index 889e3a8..1ee95fa 100644 --- a/app/src/main/kotlin/app/futured/androidprojecttemplate/navigation/Destinations.kt +++ b/app/src/main/kotlin/app/futured/androidprojecttemplate/navigation/Destinations.kt @@ -1,7 +1,7 @@ package app.futured.androidprojecttemplate.navigation +import androidx.compose.animation.AnimatedContentScope import androidx.compose.animation.AnimatedVisibilityScope -import androidx.compose.foundation.layout.ColumnScope import androidx.compose.runtime.Composable import androidx.compose.ui.window.DialogProperties import androidx.navigation.NamedNavArgument @@ -14,9 +14,6 @@ import androidx.navigation.compose.dialog import androidx.navigation.navArgument import app.futured.androidprojecttemplate.ui.screens.detail.DetailScreen import app.futured.androidprojecttemplate.ui.screens.home.HomeScreen -import app.futured.androidprojecttemplate.ui.screens.info.InfoScreen -import com.google.accompanist.navigation.material.ExperimentalMaterialNavigationApi -import com.google.accompanist.navigation.material.bottomSheet typealias DestinationArgumentKey = String typealias DestinationArgumentValue = String @@ -26,10 +23,6 @@ internal val screens = listOf( Destination.Detail, ) -internal val bottomSheetDialogs = listOf( - Destination.Info, -) - internal val dialogs = listOf() sealed class Destination( @@ -66,13 +59,6 @@ sealed class Destination( .withArgument("subtitle", subtitle) .withArgument("value", value) } - - data object Info : Destination( - route = "info", - destinationScreen = { InfoScreen(navigation = it) }, - ) { - fun buildRoute() = route - } } /** @@ -80,7 +66,7 @@ sealed class Destination( */ fun NavGraphBuilder.composableScreen( destination: Destination, - content: @Composable AnimatedVisibilityScope.(NavBackStackEntry) -> Unit, + content: @Composable AnimatedContentScope.(NavBackStackEntry) -> Unit, ) = composable( route = destination.route, arguments = destination.arguments, @@ -103,20 +89,6 @@ fun NavGraphBuilder.composableDialog( content = content, ) -/** - * Registers provided [destination] as a bottomSheet in [NavGraphBuilder]. - */ -@OptIn(ExperimentalMaterialNavigationApi::class) -fun NavGraphBuilder.composableBottomSheetDialog( - destination: Destination, - content: @Composable ColumnScope.(backstackEntry: NavBackStackEntry) -> Unit, -) = bottomSheet( - route = destination.route, - arguments = destination.arguments, - deepLinks = destination.deepLinks, - content = content, -) - /** * Replaces an argument placeholder defined by [key] in * route string with value provided in [argument]. diff --git a/app/src/main/kotlin/app/futured/androidprojecttemplate/navigation/NavRouter.kt b/app/src/main/kotlin/app/futured/androidprojecttemplate/navigation/NavRouter.kt index a6a0b13..e77eee0 100644 --- a/app/src/main/kotlin/app/futured/androidprojecttemplate/navigation/NavRouter.kt +++ b/app/src/main/kotlin/app/futured/androidprojecttemplate/navigation/NavRouter.kt @@ -5,7 +5,6 @@ interface NavRouter { fun navigateBack(popUpToDestination: Destination, inclusive: Boolean = false) fun navigateToDetail(title: String, subtitle: String? = null, value: String? = null) - fun navigateToInfo() fun navigateBackWithResult(key: String, value: T) fun setCurrentResult(key: String, value: T) diff --git a/app/src/main/kotlin/app/futured/androidprojecttemplate/navigation/NavRouterImpl.kt b/app/src/main/kotlin/app/futured/androidprojecttemplate/navigation/NavRouterImpl.kt index 5d9dbde..18f66e4 100644 --- a/app/src/main/kotlin/app/futured/androidprojecttemplate/navigation/NavRouterImpl.kt +++ b/app/src/main/kotlin/app/futured/androidprojecttemplate/navigation/NavRouterImpl.kt @@ -19,8 +19,6 @@ class NavRouterImpl(private val navController: NavController) : NavRouter { override fun navigateToDetail(title: String, subtitle: String?, value: String?) = Destination.Detail.buildRoute(title, subtitle, value).execute() - override fun navigateToInfo() = Destination.Info.buildRoute().execute() - override fun navigateBackWithResult(key: String, value: T) { navController.previousBackStackEntry?.savedStateHandle?.also { it[key] = value diff --git a/app/src/main/kotlin/app/futured/androidprojecttemplate/tools/extensions/ModifierExtensions.kt b/app/src/main/kotlin/app/futured/androidprojecttemplate/tools/extensions/ModifierExtensions.kt deleted file mode 100644 index 25800d0..0000000 --- a/app/src/main/kotlin/app/futured/androidprojecttemplate/tools/extensions/ModifierExtensions.kt +++ /dev/null @@ -1,22 +0,0 @@ -package app.futured.androidprojecttemplate.tools.extensions - -import android.annotation.SuppressLint -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.heightIn -import androidx.compose.foundation.layout.navigationBarsPadding -import androidx.compose.foundation.layout.wrapContentSize -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import androidx.compose.ui.platform.LocalConfiguration -import androidx.compose.ui.unit.Dp -import androidx.compose.ui.unit.dp - -@SuppressLint("ComposeModifierWithoutDefault", "ComposeComposableModifier") -@Composable -fun Modifier.bottomSheetSize( - maxHeight: Dp = LocalConfiguration.current.screenHeightDp.dp, -): Modifier = - fillMaxWidth() - .wrapContentSize() - .heightIn(max = maxHeight) - .navigationBarsPadding() diff --git a/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/AppUI.kt b/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/AppUI.kt index f47e23a..ab0e7c3 100644 --- a/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/AppUI.kt +++ b/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/AppUI.kt @@ -2,9 +2,7 @@ package app.futured.androidprojecttemplate.ui import androidx.compose.runtime.Composable import app.futured.androidprojecttemplate.ui.theme.AppTheme -import com.google.accompanist.navigation.material.ExperimentalMaterialNavigationApi -@OptIn(ExperimentalMaterialNavigationApi::class) @Composable fun AppUI() { AppTheme { diff --git a/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/NavGraph.kt b/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/NavGraph.kt index 3e80c27..52c9542 100644 --- a/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/NavGraph.kt +++ b/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/NavGraph.kt @@ -1,8 +1,6 @@ package app.futured.androidprojecttemplate.ui import androidx.activity.compose.LocalOnBackPressedDispatcherOwner -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.Composable import androidx.compose.runtime.remember import androidx.navigation.NavHostController @@ -11,53 +9,32 @@ import androidx.navigation.compose.rememberNavController import app.futured.androidprojecttemplate.navigation.Destination import app.futured.androidprojecttemplate.navigation.NavRouter import app.futured.androidprojecttemplate.navigation.NavRouterImpl -import app.futured.androidprojecttemplate.navigation.bottomSheetDialogs -import app.futured.androidprojecttemplate.navigation.composableBottomSheetDialog import app.futured.androidprojecttemplate.navigation.composableDialog import app.futured.androidprojecttemplate.navigation.composableScreen import app.futured.androidprojecttemplate.navigation.dialogs import app.futured.androidprojecttemplate.navigation.screens -import app.futured.androidprojecttemplate.ui.theme.Grid -import com.google.accompanist.navigation.material.BottomSheetNavigator -import com.google.accompanist.navigation.material.ExperimentalMaterialNavigationApi -import com.google.accompanist.navigation.material.ModalBottomSheetLayout -import com.google.accompanist.navigation.material.rememberBottomSheetNavigator -@OptIn(ExperimentalMaterialNavigationApi::class) @Composable fun NavGraph( - bottomSheetNavigator: BottomSheetNavigator = rememberBottomSheetNavigator(), - navController: NavHostController = rememberNavController(bottomSheetNavigator), + navController: NavHostController = rememberNavController(), navigation: NavRouter = remember { NavRouterImpl(navController) }, ) { LocalOnBackPressedDispatcherOwner.current?.onBackPressedDispatcher?.let { navController.navigateUp() } - ModalBottomSheetLayout( - bottomSheetNavigator = bottomSheetNavigator, - sheetShape = RoundedCornerShape(Grid.d3), - sheetElevation = Grid.d4, - sheetBackgroundColor = MaterialTheme.colorScheme.background, + NavHost( + navController = navController, + startDestination = Destination.Home.route, ) { - NavHost( - navController = navController, - startDestination = Destination.Home.route, - ) { - // Destinations without navbar at the bottom - screens.forEach { destination -> - composableScreen(destination) { destination.destinationScreen(navigation) } - } - - // Bottom sheet dialogs - bottomSheetDialogs.forEach { destination -> - composableBottomSheetDialog(destination) { destination.destinationScreen(navigation) } - } + // Destinations without navbar at the bottom + screens.forEach { destination -> + composableScreen(destination) { destination.destinationScreen(navigation) } + } - // Dialogs - dialogs.forEach { destination -> - composableDialog(destination) { destination.destinationScreen(navigation) } - } + // Dialogs + dialogs.forEach { destination -> + composableDialog(destination) { destination.destinationScreen(navigation) } } } } diff --git a/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/screens/_templateScreen/_TEMPLATEScreen.kt b/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/screens/_templateScreen/_TEMPLATEScreen.kt index be4678c..e3bdd1a 100644 --- a/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/screens/_templateScreen/_TEMPLATEScreen.kt +++ b/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/screens/_templateScreen/_TEMPLATEScreen.kt @@ -85,8 +85,7 @@ object TEMPLATE { Column( verticalArrangement = Arrangement.Center, horizontalAlignment = Alignment.CenterHorizontally, - modifier = - Modifier + modifier = Modifier .fillMaxSize() .padding(contentPadding), ) { diff --git a/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/screens/detail/DetailEvents.kt b/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/screens/detail/DetailEvents.kt index 6449e1d..6dbe139 100644 --- a/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/screens/detail/DetailEvents.kt +++ b/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/screens/detail/DetailEvents.kt @@ -4,5 +4,3 @@ import app.futured.arkitekt.core.event.Event sealed class DetailEvents : Event() data object NavigateBackEvent : DetailEvents() - -data object NavigateToInfoEvent : DetailEvents() diff --git a/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/screens/detail/DetailScreen.kt b/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/screens/detail/DetailScreen.kt index 64c091e..89cefc3 100644 --- a/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/screens/detail/DetailScreen.kt +++ b/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/screens/detail/DetailScreen.kt @@ -4,13 +4,10 @@ package app.futured.androidprojecttemplate.ui.screens.detail import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.ArrowBack -import androidx.compose.material3.Button import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon import androidx.compose.material3.IconButton @@ -27,7 +24,6 @@ import app.futured.androidprojecttemplate.tools.arch.onEvent import app.futured.androidprojecttemplate.tools.compose.ScreenPreviews import app.futured.androidprojecttemplate.ui.components.AddFloatingActionButton import app.futured.androidprojecttemplate.ui.components.Showcase -import app.futured.androidprojecttemplate.ui.theme.Grid @Composable fun DetailScreen( @@ -39,9 +35,6 @@ fun DetailScreen( onEvent { navigation.popBackStack() } - onEvent { - navigation.navigateToInfo() - } } Detail.Content( @@ -55,8 +48,6 @@ object Detail { interface Actions { fun onNavigateBack() - fun onNavigateToInfo() - fun onIncrementCounter() } @@ -96,10 +87,6 @@ object Detail { .padding(contentPadding), ) { Text(text = "Detail: $counter") - Spacer(modifier = Modifier.height(Grid.d4)) - Button(onClick = { actions.onNavigateToInfo() }) { - Text(text = "Open bottom sheet") - } } } } @@ -112,7 +99,6 @@ fun DetailContentPreview() { Detail.Content( actions = object : Detail.Actions { override fun onNavigateBack() = Unit - override fun onNavigateToInfo() = Unit override fun onIncrementCounter() = Unit }, counter = 5, diff --git a/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/screens/detail/DetailViewModel.kt b/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/screens/detail/DetailViewModel.kt index 265154a..15aa24c 100644 --- a/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/screens/detail/DetailViewModel.kt +++ b/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/screens/detail/DetailViewModel.kt @@ -15,8 +15,4 @@ class DetailViewModel @Inject constructor( override fun onIncrementCounter() { viewState.counter++ } - - override fun onNavigateToInfo() { - sendEvent(NavigateToInfoEvent) - } } diff --git a/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/screens/info/InfoEvent.kt b/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/screens/info/InfoEvent.kt deleted file mode 100644 index 9131b67..0000000 --- a/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/screens/info/InfoEvent.kt +++ /dev/null @@ -1,7 +0,0 @@ -package app.futured.androidprojecttemplate.ui.screens.info - -import app.futured.arkitekt.core.event.Event - -sealed class InfoEvent : Event() - -data object NavigateBackEvent : InfoEvent() diff --git a/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/screens/info/InfoScreen.kt b/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/screens/info/InfoScreen.kt deleted file mode 100644 index d1fbe93..0000000 --- a/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/screens/info/InfoScreen.kt +++ /dev/null @@ -1,72 +0,0 @@ -package app.futured.androidprojecttemplate.ui.screens.info - -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.padding -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.runtime.Stable -import androidx.compose.ui.Modifier -import androidx.hilt.navigation.compose.hiltViewModel -import app.futured.androidprojecttemplate.navigation.NavRouter -import app.futured.androidprojecttemplate.tools.arch.EventsEffect -import app.futured.androidprojecttemplate.tools.arch.onEvent -import app.futured.androidprojecttemplate.tools.compose.ScreenPreviews -import app.futured.androidprojecttemplate.tools.extensions.bottomSheetSize -import app.futured.androidprojecttemplate.ui.components.Showcase -import app.futured.androidprojecttemplate.ui.theme.Grid - -@Composable -fun InfoScreen( - navigation: NavRouter, - viewModel: InfoViewModel = hiltViewModel(), -) { - with(viewModel) { - EventsEffect { - onEvent { - navigation.popBackStack() - } - } - - Info.Content( - actions = this, - ) - } -} - -object Info { - - @Stable - interface Actions { - fun onNavigateBack() - } - - @Composable - fun Content( - actions: Actions, - modifier: Modifier = Modifier, - ) { - Column( - modifier = modifier.bottomSheetSize(), - ) { - Text( - modifier = Modifier.padding(Grid.d4), - text = - "This is a BottomSheet, a commonly used user interface component in Android and other mobile operating systems." + - " It is used to display content that slides up from the bottom of the screen, providing users with additional choices and " + - "actions. This particular BottomSheet is part of a mock-up, serving purely for testing purposes. " + - "Please note that the text displayed here is only placeholder text and does not represent any actual content or functionalities. " + - "The aim of this testing is to validate the design, layout, and overall user experience of the BottomSheet component.", - ) - } - } -} - -@ScreenPreviews -@Composable -fun InfoContentPreview() = Showcase { - Info.Content( - actions = object : Info.Actions { - override fun onNavigateBack() = Unit - }, - ) -} diff --git a/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/screens/info/InfoViewModel.kt b/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/screens/info/InfoViewModel.kt deleted file mode 100644 index 39cd395..0000000 --- a/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/screens/info/InfoViewModel.kt +++ /dev/null @@ -1,14 +0,0 @@ -package app.futured.androidprojecttemplate.ui.screens.info - -import app.futured.androidprojecttemplate.tools.arch.BaseViewModel -import dagger.hilt.android.lifecycle.HiltViewModel -import javax.inject.Inject - -@HiltViewModel -class InfoViewModel @Inject constructor( - override val viewState: InfoViewState, -) : BaseViewModel(), Info.Actions { - override fun onNavigateBack() { - sendEvent(NavigateBackEvent) - } -} diff --git a/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/screens/info/InfoViewState.kt b/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/screens/info/InfoViewState.kt deleted file mode 100644 index 17d186a..0000000 --- a/app/src/main/kotlin/app/futured/androidprojecttemplate/ui/screens/info/InfoViewState.kt +++ /dev/null @@ -1,8 +0,0 @@ -package app.futured.androidprojecttemplate.ui.screens.info - -import app.futured.arkitekt.core.ViewState -import dagger.hilt.android.scopes.ViewModelScoped -import javax.inject.Inject - -@ViewModelScoped -class InfoViewState @Inject constructor() : ViewState diff --git a/buildSrc/src/main/kotlin/Dependencies.kt b/buildSrc/src/main/kotlin/Dependencies.kt index 15a5f49..0ee66a6 100644 --- a/buildSrc/src/main/kotlin/Dependencies.kt +++ b/buildSrc/src/main/kotlin/Dependencies.kt @@ -40,10 +40,6 @@ object Dependencies { const val preference = "androidx.preference:preference-ktx:${Versions.preference}" } - object Accompanist { - const val navigationMaterial = "com.google.accompanist:accompanist-navigation-material:${Versions.accompanist}" - } - object NavigationComponents { const val navigation = "androidx.navigation:navigation-compose:${Versions.navigation}" const val navigationHilt = "androidx.hilt:hilt-navigation-compose:${Versions.hiltNavigation}" diff --git a/buildSrc/src/main/kotlin/Versions.kt b/buildSrc/src/main/kotlin/Versions.kt index 6ac3c9d..2bacd6d 100644 --- a/buildSrc/src/main/kotlin/Versions.kt +++ b/buildSrc/src/main/kotlin/Versions.kt @@ -6,9 +6,9 @@ object Versions { const val androidGradlePlugin = "8.4.0" // plugins - const val detekt = "1.23.6" - const val ktlintGradle = "12.1.1" - const val ktlint = "1.2.1" + const val detekt = "1.22.0" + const val ktlintGradle = "11.2.0" + const val ktlint = "0.48.2" // kotlin const val kotlin = "1.9.23" @@ -25,7 +25,6 @@ object Versions { const val constraintLayout = "1.0.1" const val vectorDrawable = "1.2.0-beta01" const val preference = "1.2.1" - const val accompanist = "0.34.0" const val activity = "1.9.0" const val desugarLibs = "2.0.4"