├── .github └── workflows │ └── publish-docs.yml ├── .gitignore ├── .idea ├── .gitignore ├── .name ├── codeStyles │ ├── Project.xml │ └── codeStyleConfig.xml ├── compiler.xml ├── deploymentTargetDropDown.xml ├── gradle.xml ├── inspectionProfiles │ └── Project_Default.xml ├── misc.xml └── vcs.xml ├── LICENSE ├── README.md ├── RELEASE_NOTES.md ├── accompanist-navigation ├── .gitignore ├── build.gradle.kts ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ └── java │ └── cz │ └── levinzonr │ └── saferoute │ └── accompanist │ └── navigation │ ├── AnimatedNavHost.kt │ ├── NavGraphBuilder+Animation.kt │ ├── NavGraphBuilder+BottomSheet.kt │ ├── Transitions.kt │ └── transitions │ ├── AnimatedRouteTransition.kt │ └── BottomSheetRouteTransition.kt ├── annotations ├── .gitignore ├── build.gradle └── src │ └── main │ └── java │ └── cz │ └── levinzonr │ └── saferoute │ └── annotations │ ├── Route.kt │ ├── RouteArg.kt │ └── RouteArgType.kt ├── app ├── .gitignore ├── build.gradle.kts ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── cz │ │ └── levinzonr │ │ └── saferoute │ │ ├── App.kt │ │ ├── MainActivity.kt │ │ ├── components │ │ └── PlaceholderComponent.kt │ │ ├── data │ │ └── Pokemon.kt │ │ ├── screens │ │ ├── PokemonSelector.kt │ │ ├── Previews.kt │ │ ├── details │ │ │ ├── PokemonDetailsScreen.kt │ │ │ └── PokemonDetailsViewModel.kt │ │ ├── home │ │ │ └── HomeScreen.kt │ │ ├── list │ │ │ ├── PokemonListScreen.kt │ │ │ └── components │ │ │ │ └── PokemonItem.kt │ │ └── statssheet │ │ │ └── PokemonStatsSheet.kt │ │ ├── transitions │ │ ├── CustomDialogTransition.kt │ │ └── FadeInFadeOutTransition.kt │ │ └── ui │ │ └── theme │ │ ├── Color.kt │ │ ├── Shape.kt │ │ ├── Theme.kt │ │ └── Type.kt │ └── res │ ├── drawable-v24 │ └── ic_launcher_foreground.xml │ ├── drawable │ ├── dotted.png │ ├── ic_launcher_background.xml │ ├── news1.jpg │ ├── poke001.png │ ├── poke002.png │ ├── poke003.png │ ├── poke004.png │ ├── poke005.png │ ├── poke006.png │ ├── poke007.png │ ├── poke008.png │ ├── poke009.png │ ├── poke010.png │ ├── poke011.png │ ├── poke012.png │ ├── poke013.png │ ├── poke014.png │ ├── poke015.png │ ├── poke016.png │ ├── poke017.png │ ├── poke018.png │ ├── poke019.png │ ├── poke020.png │ ├── poke021.png │ ├── poke022.png │ ├── poke023.png │ ├── poke024.png │ ├── poke025.png │ ├── poke026.png │ ├── poke027.png │ ├── poke028.png │ ├── pokeball.png │ ├── pokeball_s.png │ └── search.png │ ├── mipmap-anydpi-v26 │ ├── ic_launcher.xml │ └── ic_launcher_round.xml │ ├── mipmap-hdpi │ ├── ic_launcher.webp │ └── ic_launcher_round.webp │ ├── mipmap-mdpi │ ├── ic_launcher.webp │ └── ic_launcher_round.webp │ ├── mipmap-xhdpi │ ├── ic_launcher.webp │ └── ic_launcher_round.webp │ ├── mipmap-xxhdpi │ ├── ic_launcher.webp │ └── ic_launcher_round.webp │ ├── mipmap-xxxhdpi │ ├── ic_launcher.webp │ └── ic_launcher_round.webp │ ├── values-night │ └── themes.xml │ └── values │ ├── colors.xml │ ├── strings.xml │ └── themes.xml ├── build.gradle.kts ├── buildSrc ├── build.gradle.kts ├── build │ ├── classes │ │ └── kotlin │ │ │ └── main │ │ │ ├── Deps.class │ │ │ └── META-INF │ │ │ └── buildSrc.kotlin_module │ ├── kotlin │ │ ├── buildSrcjar-classes.txt │ │ └── compileKotlin │ │ │ ├── build-history.bin │ │ │ ├── caches-jvm │ │ │ ├── inputs │ │ │ │ ├── source-to-output.tab │ │ │ │ ├── source-to-output.tab.keystream │ │ │ │ ├── source-to-output.tab.keystream.len │ │ │ │ ├── source-to-output.tab.len │ │ │ │ ├── source-to-output.tab.values.at │ │ │ │ ├── source-to-output.tab_i │ │ │ │ └── source-to-output.tab_i.len │ │ │ ├── jvm │ │ │ │ └── kotlin │ │ │ │ │ ├── class-attributes.tab │ │ │ │ │ ├── class-attributes.tab.keystream │ │ │ │ │ ├── class-attributes.tab.keystream.len │ │ │ │ │ ├── class-attributes.tab.len │ │ │ │ │ ├── class-attributes.tab.values.at │ │ │ │ │ ├── class-attributes.tab_i │ │ │ │ │ ├── class-attributes.tab_i.len │ │ │ │ │ ├── class-fq-name-to-source.tab │ │ │ │ │ ├── class-fq-name-to-source.tab.keystream │ │ │ │ │ ├── class-fq-name-to-source.tab.keystream.len │ │ │ │ │ ├── class-fq-name-to-source.tab.len │ │ │ │ │ ├── class-fq-name-to-source.tab.values.at │ │ │ │ │ ├── class-fq-name-to-source.tab_i │ │ │ │ │ ├── class-fq-name-to-source.tab_i.len │ │ │ │ │ ├── constants.tab │ │ │ │ │ ├── constants.tab.keystream │ │ │ │ │ ├── constants.tab.keystream.len │ │ │ │ │ ├── constants.tab.len │ │ │ │ │ ├── constants.tab.values.at │ │ │ │ │ ├── constants.tab_i │ │ │ │ │ ├── constants.tab_i.len │ │ │ │ │ ├── internal-name-to-source.tab │ │ │ │ │ ├── internal-name-to-source.tab.keystream │ │ │ │ │ ├── internal-name-to-source.tab.keystream.len │ │ │ │ │ ├── internal-name-to-source.tab.len │ │ │ │ │ ├── internal-name-to-source.tab.values.at │ │ │ │ │ ├── internal-name-to-source.tab_i │ │ │ │ │ ├── internal-name-to-source.tab_i.len │ │ │ │ │ ├── proto.tab │ │ │ │ │ ├── proto.tab.keystream │ │ │ │ │ ├── proto.tab.keystream.len │ │ │ │ │ ├── proto.tab.len │ │ │ │ │ ├── proto.tab.values.at │ │ │ │ │ ├── proto.tab_i │ │ │ │ │ ├── proto.tab_i.len │ │ │ │ │ ├── source-to-classes.tab │ │ │ │ │ ├── source-to-classes.tab.keystream │ │ │ │ │ ├── source-to-classes.tab.keystream.len │ │ │ │ │ ├── source-to-classes.tab.len │ │ │ │ │ ├── source-to-classes.tab.values.at │ │ │ │ │ ├── source-to-classes.tab_i │ │ │ │ │ └── source-to-classes.tab_i.len │ │ │ └── lookups │ │ │ │ ├── counters.tab │ │ │ │ ├── file-to-id.tab │ │ │ │ ├── file-to-id.tab.keystream │ │ │ │ ├── file-to-id.tab.keystream.len │ │ │ │ ├── file-to-id.tab.len │ │ │ │ ├── file-to-id.tab.values.at │ │ │ │ ├── file-to-id.tab_i │ │ │ │ ├── file-to-id.tab_i.len │ │ │ │ ├── id-to-file.tab │ │ │ │ ├── id-to-file.tab.keystream │ │ │ │ ├── id-to-file.tab.keystream.len │ │ │ │ ├── id-to-file.tab.len │ │ │ │ ├── id-to-file.tab.values.at │ │ │ │ ├── lookups.tab │ │ │ │ ├── lookups.tab.keystream │ │ │ │ ├── lookups.tab.keystream.len │ │ │ │ ├── lookups.tab.len │ │ │ │ ├── lookups.tab.values.at │ │ │ │ ├── lookups.tab_i │ │ │ │ └── lookups.tab_i.len │ │ │ └── last-build.bin │ ├── libs │ │ └── buildSrc.jar │ ├── pluginUnderTestMetadata │ │ └── plugin-under-test-metadata.properties │ ├── reports │ │ └── plugin-development │ │ │ └── validation-report.txt │ └── tmp │ │ └── jar │ │ └── MANIFEST.MF └── src │ └── main │ └── kotlin │ └── Deps.kt ├── codegen ├── .gitignore ├── build.gradle └── src │ └── main │ └── java │ └── com │ └── levinzonr │ └── saferoute │ └── codegen │ ├── codegen │ ├── NavControllerExtensionsCodegen.kt │ ├── NavGraphRoutesCodegen.kt │ ├── NavGraphsCodegen.kt │ ├── RouteArgsCodegen.kt │ ├── RouteArgsFactoryCodegen.kt │ ├── RouteArgsProviderCodegen.kt │ ├── RoutesActionsCodegen.kt │ ├── RoutesCodegen.kt │ ├── RoutesSpecsCodegen.kt │ ├── RoutesTransitionsCodegen.kt │ ├── extensions │ │ ├── ComposableFunction.kt │ │ ├── addArguments.kt │ │ ├── asList.kt │ │ ├── checkNullable.kt │ │ ├── createRouteAction.kt │ │ ├── deprecate.kt │ │ ├── toFunSpec.kt │ │ └── toRouteProperty.kt │ └── pathbuilder │ │ └── PathBuilder.kt │ ├── constants │ ├── ClassNames.kt │ ├── Constants.kt │ └── KDoc.kt │ ├── core │ ├── DataProcessor.kt │ ├── FilesGen.kt │ ├── GeneratorUnit.kt │ ├── LogLevel.kt │ ├── Logger.kt │ ├── ProcessingComponent.kt │ ├── RoutesGenerationProcessor.kt │ ├── Source.kt │ ├── TypeHelper.kt │ └── Writer.kt │ └── models │ ├── ArgumentData.kt │ ├── ArgumentType.kt │ ├── DeeplinkData.kt │ ├── ModelData.kt │ ├── NavGraphData.kt │ ├── OptionalArgData.kt │ └── RouteData.kt ├── core ├── .gitignore ├── build.gradle.kts ├── consumer-rules.pro ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ └── java │ └── cz │ └── levinzonr │ └── saferoute │ └── core │ ├── ComposableFun.kt │ ├── NavControllerExtensions.kt │ ├── NavGraphBuilderExtensions.kt │ ├── NavGraphSpec.kt │ ├── NavHostExtensions.kt │ ├── ProvideRouteSpectArgs.kt │ ├── RouteArgBuilder.kt │ ├── RouteSpec+LocalArgs.kt │ ├── RouteSpec.kt │ ├── annotations │ ├── AnnotationsDefaults.kt │ ├── Route.kt │ ├── RouteArg.kt │ ├── RouteDeeplink.kt │ └── RouteNavGraph.kt │ ├── router │ ├── Direction.kt │ ├── EmptyRouter.kt │ ├── Router.kt │ ├── RouterImpl.kt │ └── RouterProvider.kt │ ├── transitions │ ├── DefaultRouteTransition.kt │ ├── DialogRouteTransition.kt │ └── RouteTransition.kt │ └── util │ └── EmptyArgsFactory.kt ├── docs ├── arguments.md ├── assets │ ├── icon.svg │ └── logo.svg ├── configuration.md ├── index.md ├── route.md └── transitions.md ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── jitpack.yml ├── mkdocs.yml ├── processor-kapt ├── .gitignore ├── build.gradle └── src │ └── main │ ├── java │ └── cz │ │ └── levinzonr │ │ └── saferoute │ │ └── processor │ │ ├── RouteProcessor.kt │ │ ├── extensions │ │ └── fieldByName.kt │ │ ├── logger │ │ └── KaptLogger.kt │ │ ├── subprocessors │ │ ├── DataBuilder.kt │ │ ├── DeeplinkDataBuilder.kt │ │ └── KaptDataProcessor.kt │ │ └── typehelper │ │ └── TypeHelperImpl.kt │ └── resources │ └── META-INF │ └── services │ └── javax.annotation.processing.Processor ├── processor-ksp ├── .gitignore ├── build.gradle └── src │ └── main │ ├── java │ └── cz │ │ └── levinzonr │ │ └── saferoute │ │ └── processor │ │ └── ksp │ │ ├── KspDataProcessor.kt │ │ ├── KspLogger.kt │ │ ├── KspWriter.kt │ │ ├── SafeRouteKspProcessor.kt │ │ └── SafeRouteKspProvider.kt │ └── resources │ └── META-INF │ └── services │ └── com.google.devtools.ksp.processing.SymbolProcessorProvider ├── remove_app.sh └── settings.gradle.kts /.github/workflows/publish-docs.yml: -------------------------------------------------------------------------------- 1 | name: publish-docs 2 | on: 3 | push: 4 | branches: 5 | - master 6 | 7 | jobs: 8 | deploy: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/checkout@v2 12 | - uses: actions/setup-python@v2 13 | with: 14 | python-version: 3.x 15 | - run: pip install mkdocs-material 16 | - run: mkdocs gh-deploy --force 17 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/caches 5 | /.idea/libraries 6 | /.idea/modules.xml 7 | /.idea/workspace.xml 8 | /.idea/navEditor.xml 9 | /.idea/assetWizardSettings.xml 10 | .DS_Store 11 | /build 12 | /captures 13 | .externalNativeBuild 14 | .cxx 15 | local.properties 16 | -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | -------------------------------------------------------------------------------- /.idea/.name: -------------------------------------------------------------------------------- 1 | router -------------------------------------------------------------------------------- /.idea/codeStyles/codeStyleConfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /.idea/deploymentTargetDropDown.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 26 | 27 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/Project_Default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 25 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 22 | 23 | 24 | 25 | 26 | 27 | 29 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /accompanist-navigation/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /accompanist-navigation/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | id("com.android.library") 3 | id("kotlin-android") 4 | id("com.vanniktech.maven.publish") 5 | } 6 | 7 | 8 | android { 9 | compileSdk = 33 10 | 11 | defaultConfig { 12 | minSdk = 21 13 | targetSdk = 33 14 | version = 1 15 | 16 | testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" 17 | consumerProguardFiles("consumer-rules.pro") 18 | } 19 | 20 | buildTypes { 21 | release { 22 | isMinifyEnabled = false 23 | proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro") 24 | } 25 | } 26 | compileOptions { 27 | sourceCompatibility = JavaVersion.VERSION_1_8 28 | targetCompatibility = JavaVersion.VERSION_1_8 29 | } 30 | kotlinOptions { 31 | jvmTarget = "1.8" 32 | } 33 | 34 | buildFeatures { 35 | compose = true 36 | } 37 | composeOptions { 38 | kotlinCompilerExtensionVersion = "1.3.0" 39 | } 40 | 41 | } 42 | 43 | mavenPublish { 44 | releaseSigningEnabled = false 45 | } 46 | 47 | 48 | dependencies { 49 | 50 | implementation("androidx.core:core-ktx:1.7.0") 51 | implementation("androidx.navigation:navigation-compose:${Deps.composeNavigation}") 52 | implementation("androidx.compose.ui:ui:${Deps.compose}") 53 | api((project(":core"))) 54 | 55 | implementation("com.google.accompanist:accompanist-navigation-animation:${Deps.accompanist}") 56 | implementation("com.google.accompanist:accompanist-navigation-material:${Deps.accompanist}") 57 | 58 | 59 | testImplementation("junit:junit:4.+") 60 | androidTestImplementation( "androidx.test.ext:junit:1.1.3") 61 | androidTestImplementation("androidx.test.espresso:espresso-core:3.4.0") 62 | } 63 | -------------------------------------------------------------------------------- /accompanist-navigation/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle.kts. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile -------------------------------------------------------------------------------- /accompanist-navigation/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /accompanist-navigation/src/main/java/cz/levinzonr/saferoute/accompanist/navigation/AnimatedNavHost.kt: -------------------------------------------------------------------------------- 1 | package cz.levinzonr.saferoute.accompanist.navigation 2 | 3 | import androidx.compose.animation.ExperimentalAnimationApi 4 | import androidx.compose.animation.fadeIn 5 | import androidx.compose.animation.fadeOut 6 | import androidx.compose.runtime.Composable 7 | import androidx.compose.runtime.CompositionLocalProvider 8 | import androidx.compose.runtime.remember 9 | import androidx.compose.ui.Alignment 10 | import androidx.compose.ui.Modifier 11 | import androidx.navigation.NavGraphBuilder 12 | import androidx.navigation.NavHostController 13 | import com.google.accompanist.navigation.animation.AnimatedNavHost 14 | import com.google.accompanist.navigation.animation.rememberAnimatedNavController 15 | import cz.levinzonr.saferoute.core.RouteSpec 16 | import cz.levinzonr.saferoute.core.router.LocalRouter 17 | import cz.levinzonr.saferoute.core.router.Router 18 | import cz.levinzonr.saferoute.core.router.RouterImpl 19 | 20 | @Composable 21 | @ExperimentalAnimationApi 22 | fun SafeRouteAnimatedNavHost( 23 | modifier: Modifier = Modifier, 24 | navController: NavHostController = rememberAnimatedNavController(navigators = emptyArray()), 25 | startRouteSpec: RouteSpec<*>, 26 | contentAlignment: Alignment = Alignment.Center, 27 | route: String? = null, 28 | enterTransition: RouteEnterTransition = { fadeIn() }, 29 | exitTransition: RouteExitTransition = { fadeOut() }, 30 | popEnterTransition: RouteEnterTransition = enterTransition, 31 | popExitTransition: RouteExitTransition = exitTransition, 32 | builder: NavGraphBuilder.(Router) -> Unit 33 | ) { 34 | val router = remember(navController) { RouterImpl(navController) } 35 | CompositionLocalProvider(LocalRouter provides router) { 36 | AnimatedNavHost( 37 | navController = navController, 38 | startDestination = startRouteSpec.route, 39 | modifier = modifier, 40 | contentAlignment = contentAlignment, 41 | enterTransition = enterTransition, 42 | exitTransition = exitTransition, 43 | popEnterTransition = popEnterTransition, 44 | popExitTransition = popExitTransition, 45 | builder = { builder(router) }, 46 | route = route 47 | ) 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /accompanist-navigation/src/main/java/cz/levinzonr/saferoute/accompanist/navigation/NavGraphBuilder+Animation.kt: -------------------------------------------------------------------------------- 1 | package cz.levinzonr.saferoute.accompanist.navigation 2 | 3 | import androidx.compose.animation.AnimatedVisibilityScope 4 | import androidx.compose.animation.ExperimentalAnimationApi 5 | import androidx.compose.animation.core.tween 6 | import androidx.compose.animation.fadeIn 7 | import androidx.compose.animation.fadeOut 8 | import androidx.compose.runtime.Composable 9 | import androidx.navigation.NavBackStackEntry 10 | import androidx.navigation.NavGraphBuilder 11 | import com.google.accompanist.navigation.animation.composable 12 | import cz.levinzonr.saferoute.accompanist.navigation.transitions.AnimatedRouteTransition 13 | import cz.levinzonr.saferoute.core.ProvideRouteSpecArgs 14 | import cz.levinzonr.saferoute.core.RouteSpec 15 | 16 | @ExperimentalAnimationApi 17 | fun NavGraphBuilder.composable( 18 | spec: RouteSpec<*>, 19 | enterTransition: RouteEnterTransition = { fadeIn(animationSpec = tween(700)) }, 20 | exitTransition: RouteExitTransition = { fadeOut(animationSpec = tween(700)) }, 21 | popEnterTransition: RouteEnterTransition = enterTransition, 22 | popExitTransition: RouteExitTransition = exitTransition, 23 | content: @Composable AnimatedVisibilityScope.(NavBackStackEntry) -> Unit 24 | ) = composable( 25 | spec.route, 26 | spec.navArgs, 27 | spec.deepLinks, 28 | enterTransition, 29 | exitTransition, 30 | popEnterTransition, 31 | popExitTransition 32 | ) { 33 | ProvideRouteSpecArgs(spec = spec, entry = it) { 34 | content.invoke(this, it) 35 | } 36 | } 37 | 38 | @ExperimentalAnimationApi 39 | fun NavGraphBuilder.composable( 40 | spec: RouteSpec<*>, 41 | transition: AnimatedRouteTransition, 42 | content: @Composable AnimatedVisibilityScope.(NavBackStackEntry) -> Unit 43 | ) = composable( 44 | spec = spec, 45 | enterTransition = transition.enter, 46 | exitTransition = transition.exit, 47 | popEnterTransition = transition.popEnter, 48 | popExitTransition = transition.popExit, 49 | content = content 50 | ) 51 | 52 | @ExperimentalAnimationApi 53 | @Deprecated( 54 | message = "Use composable(Route) instead, args can be accessed using CompositionLocal APIs i.e LocalRouteArgs.current", 55 | replaceWith = ReplaceWith( 56 | "composable(spec, enterTransition, exitTransition, popEnterTransition, popExitTransition) {\n " + 57 | "val args = spec.currentArgs\n" + 58 | "content()\n " + 59 | " }", 60 | "cz.levinzonr.saferoute.accompanist.navigation", "cz.levinzonr.saferoute.core.currentArgs" 61 | ) 62 | ) 63 | fun NavGraphBuilder.composableWithArgs( 64 | spec: RouteSpec, 65 | enterTransition: RouteEnterTransition = { fadeIn() }, 66 | exitTransition: RouteExitTransition = { fadeOut() }, 67 | popEnterTransition: RouteEnterTransition = enterTransition, 68 | popExitTransition: RouteExitTransition = exitTransition, 69 | content: @Composable AnimatedVisibilityScope.(NavBackStackEntry, A) -> Unit 70 | ) = composable( 71 | spec.route, 72 | spec.navArgs, 73 | spec.deepLinks, 74 | enterTransition, 75 | exitTransition, 76 | popEnterTransition, 77 | popExitTransition 78 | ) { 79 | content.invoke(this, it, spec.argsFactory.LocalArgs.current) 80 | } 81 | -------------------------------------------------------------------------------- /accompanist-navigation/src/main/java/cz/levinzonr/saferoute/accompanist/navigation/NavGraphBuilder+BottomSheet.kt: -------------------------------------------------------------------------------- 1 | package cz.levinzonr.saferoute.accompanist.navigation 2 | 3 | import androidx.compose.foundation.layout.ColumnScope 4 | import androidx.compose.runtime.Composable 5 | import androidx.navigation.NavBackStackEntry 6 | import androidx.navigation.NavGraphBuilder 7 | import com.google.accompanist.navigation.material.ExperimentalMaterialNavigationApi 8 | import com.google.accompanist.navigation.material.bottomSheet 9 | import cz.levinzonr.saferoute.core.ProvideRouteSpecArgs 10 | import cz.levinzonr.saferoute.core.RouteSpec 11 | 12 | @ExperimentalMaterialNavigationApi 13 | fun NavGraphBuilder.bottomSheet( 14 | routeSpec: RouteSpec<*>, 15 | content: @Composable ColumnScope.(backstackEntry: NavBackStackEntry) -> Unit 16 | ) = bottomSheet(routeSpec.route, routeSpec.navArgs, routeSpec.deepLinks) { 17 | ProvideRouteSpecArgs(spec = routeSpec, entry = it) { 18 | content.invoke(this, it) 19 | } 20 | } 21 | 22 | @ExperimentalMaterialNavigationApi 23 | @Deprecated( 24 | message = "Use bottomSheet(Route) instead, args can be accessed using CompositionLocal APIs i.e LocalRouteArgs.current", 25 | replaceWith = ReplaceWith( 26 | "bottomSheet(spec) {\n " + 27 | "val args = spec.currentArgs\n" + 28 | "content()\n " + 29 | "}", 30 | "cz.levinzonr.saferoute.accompanist.navigation", "cz.levinzonr.saferoute.core.currentArgs" 31 | ) 32 | ) 33 | fun NavGraphBuilder.bottomSheetWithArgs( 34 | routeSpec: RouteSpec, 35 | content: @Composable ColumnScope.(backstackEntry: NavBackStackEntry, args: A) -> Unit 36 | ) = bottomSheet(routeSpec) { 37 | content.invoke(this, it, routeSpec.argsFactory.LocalArgs.current) 38 | } 39 | -------------------------------------------------------------------------------- /accompanist-navigation/src/main/java/cz/levinzonr/saferoute/accompanist/navigation/Transitions.kt: -------------------------------------------------------------------------------- 1 | package cz.levinzonr.saferoute.accompanist.navigation 2 | 3 | import androidx.compose.animation.AnimatedContentScope 4 | import androidx.compose.animation.EnterTransition 5 | import androidx.compose.animation.ExitTransition 6 | import androidx.compose.animation.ExperimentalAnimationApi 7 | import androidx.navigation.NavBackStackEntry 8 | 9 | @OptIn(ExperimentalAnimationApi::class) 10 | typealias RouteEnterTransition = AnimatedContentScope.() -> EnterTransition 11 | 12 | @OptIn(ExperimentalAnimationApi::class) 13 | typealias RouteExitTransition = AnimatedContentScope.() -> ExitTransition 14 | -------------------------------------------------------------------------------- /accompanist-navigation/src/main/java/cz/levinzonr/saferoute/accompanist/navigation/transitions/AnimatedRouteTransition.kt: -------------------------------------------------------------------------------- 1 | package cz.levinzonr.saferoute.accompanist.navigation.transitions 2 | 3 | import androidx.compose.animation.ExperimentalAnimationApi 4 | import androidx.compose.animation.fadeIn 5 | import androidx.compose.animation.fadeOut 6 | import androidx.compose.runtime.Composable 7 | import androidx.navigation.NavBackStackEntry 8 | import androidx.navigation.NavGraphBuilder 9 | import cz.levinzonr.saferoute.accompanist.navigation.RouteEnterTransition 10 | import cz.levinzonr.saferoute.accompanist.navigation.RouteExitTransition 11 | import cz.levinzonr.saferoute.accompanist.navigation.composable 12 | import cz.levinzonr.saferoute.core.RouteSpec 13 | import cz.levinzonr.saferoute.core.transitions.RouteTransition 14 | 15 | @ExperimentalAnimationApi 16 | abstract class AnimatedRouteTransition : RouteTransition { 17 | 18 | abstract val enter: RouteEnterTransition 19 | abstract val exit: RouteExitTransition 20 | abstract val popEnter: RouteEnterTransition 21 | abstract val popExit: RouteExitTransition 22 | 23 | override fun route( 24 | builder: NavGraphBuilder, 25 | spec: RouteSpec<*>, 26 | content: @Composable (NavBackStackEntry) -> Unit 27 | ) { 28 | builder.composable(spec, this) { 29 | content(it) 30 | } 31 | } 32 | 33 | object Default : AnimatedRouteTransition() { 34 | override val enter: RouteEnterTransition = { fadeIn() } 35 | override val exit: RouteExitTransition = { fadeOut() } 36 | override val popEnter: RouteEnterTransition = enter 37 | override val popExit: RouteExitTransition = exit 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /accompanist-navigation/src/main/java/cz/levinzonr/saferoute/accompanist/navigation/transitions/BottomSheetRouteTransition.kt: -------------------------------------------------------------------------------- 1 | package cz.levinzonr.saferoute.accompanist.navigation.transitions 2 | 3 | import androidx.compose.runtime.Composable 4 | import androidx.navigation.NavBackStackEntry 5 | import androidx.navigation.NavGraphBuilder 6 | import com.google.accompanist.navigation.material.ExperimentalMaterialNavigationApi 7 | import cz.levinzonr.saferoute.accompanist.navigation.bottomSheet 8 | import cz.levinzonr.saferoute.core.RouteSpec 9 | import cz.levinzonr.saferoute.core.transitions.RouteTransition 10 | 11 | @ExperimentalMaterialNavigationApi 12 | object BottomSheetRouteTransition : RouteTransition { 13 | 14 | override fun route( 15 | builder: NavGraphBuilder, 16 | spec: RouteSpec<*>, 17 | content: @Composable (NavBackStackEntry) -> Unit 18 | ) { 19 | builder.bottomSheet(spec) { content.invoke(it) } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /annotations/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /annotations/build.gradle: -------------------------------------------------------------------------------- 1 | 2 | 3 | apply plugin: "kotlin" 4 | apply plugin: "com.vanniktech.maven.publish" 5 | 6 | java { 7 | sourceCompatibility = JavaVersion.VERSION_1_7 8 | targetCompatibility = JavaVersion.VERSION_1_7 9 | } 10 | 11 | 12 | 13 | mavenPublish { 14 | releaseSigningEnabled = false 15 | } 16 | 17 | -------------------------------------------------------------------------------- /annotations/src/main/java/cz/levinzonr/saferoute/annotations/Route.kt: -------------------------------------------------------------------------------- 1 | package cz.levinzonr.saferoute.annotations 2 | /** 3 | * This annotation is used to declare an application route/destination 4 | * @param name - defines the name of the route, its root path and the prefix for generated arguments 5 | * @param args - list of route arguments that will be used for this route 6 | */ 7 | @Target(AnnotationTarget.FUNCTION) 8 | @Retention(AnnotationRetention.SOURCE) 9 | @MustBeDocumented 10 | @Deprecated( 11 | message = "Use annotations from the :core module instead", 12 | replaceWith = ReplaceWith("Route", "cz.levinzonr.saferoute.core.annotations.Route") 13 | ) 14 | annotation class Route( 15 | val name: String, 16 | val args: Array = [], 17 | val graph: String = "main", 18 | val start: Boolean = false, 19 | ) 20 | -------------------------------------------------------------------------------- /annotations/src/main/java/cz/levinzonr/saferoute/annotations/RouteArg.kt: -------------------------------------------------------------------------------- 1 | package cz.levinzonr.saferoute.annotations 2 | 3 | /** 4 | * An annotation to describe the argument of the route 5 | * @param name - the name of the argument 6 | * @param type - the type of the argument 7 | * @param isOptional - determines if argument should be optional or not 8 | * @param defaultValue - String representation of the default value of the argument, it will only be used if argument is optional 9 | */ 10 | @MustBeDocumented 11 | @Retention(AnnotationRetention.SOURCE) 12 | @Deprecated( 13 | message = "Use annotations from the :core module instead", 14 | replaceWith = ReplaceWith("RouteArg", "cz.levinzonr.saferoute.core.annotations.RouteArg") 15 | )annotation class RouteArg( 16 | val name: String, 17 | val type: RouteArgType = RouteArgType.StringType, 18 | val isOptional: Boolean = false, 19 | val defaultValue: String = VALUE_NULL 20 | ) { 21 | companion object { 22 | const val VALUE_NULL = "@null" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /annotations/src/main/java/cz/levinzonr/saferoute/annotations/RouteArgType.kt: -------------------------------------------------------------------------------- 1 | package cz.levinzonr.saferoute.annotations 2 | 3 | import kotlin.reflect.KClass 4 | 5 | /** 6 | * Describes the argument type 7 | */ 8 | @Deprecated( 9 | message = "Use annotations from :core module to specify ArgType using KClass<*> directly\n" + 10 | "For example: RouteArgType.StringType -> String::class\n", 11 | ) 12 | enum class RouteArgType(val clazz: KClass<*>) { 13 | /** 14 | * Represents non-nullable String type 15 | */ 16 | StringType(String::class), 17 | 18 | /** 19 | * Represents nullable String type 20 | */ 21 | StringNullableType(String::class), 22 | 23 | /** 24 | * Represents Int Type, cannot be null 25 | */ 26 | IntType(Int::class), 27 | 28 | /** 29 | * Represents float Type, cannot be null 30 | */ 31 | FloatType(Float::class), 32 | 33 | /** 34 | * Represents LongType, cannot be null 35 | */ 36 | LongType(Long::class), 37 | 38 | /** 39 | * Represents Boolean value, cannot be null 40 | */ 41 | BooleanType(Boolean::class) 42 | } 43 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /app/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | id("com.android.application") 3 | id("kotlin-android") 4 | id("kotlin-kapt") 5 | id("dagger.hilt.android.plugin") 6 | id("com.google.devtools.ksp") version "1.7.10-1.0.6" 7 | } 8 | 9 | android { 10 | compileSdk = 33 11 | buildToolsVersion = "33.0.0" 12 | 13 | defaultConfig { 14 | applicationId = "cz.levinzonr.router" 15 | minSdk = 23 16 | targetSdk = 32 17 | versionCode = 1 18 | versionName = "1.0" 19 | 20 | testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" 21 | vectorDrawables { 22 | useSupportLibrary = true 23 | } 24 | } 25 | 26 | buildTypes { 27 | release { 28 | isMinifyEnabled = false 29 | proguardFiles( 30 | getDefaultProguardFile("proguard-android-optimize.txt"), 31 | "proguard-rules.pro" 32 | ) 33 | } 34 | } 35 | compileOptions { 36 | sourceCompatibility = JavaVersion.VERSION_1_8 37 | targetCompatibility = JavaVersion.VERSION_1_8 38 | } 39 | kotlinOptions { 40 | jvmTarget = "1.8" 41 | } 42 | buildFeatures { 43 | compose = true 44 | } 45 | composeOptions { 46 | kotlinCompilerExtensionVersion = "1.3.0" 47 | } 48 | 49 | applicationVariants.all { 50 | kotlin.sourceSets { 51 | getByName(name) { 52 | kotlin.srcDir("build/generated/ksp/$name/kotlin") 53 | } 54 | } 55 | } 56 | 57 | } 58 | 59 | kapt { 60 | arguments { 61 | arg("safeRoute.defaultPackageName", "cz.levinzonr.saferoute.navigation") 62 | } 63 | } 64 | 65 | ksp { 66 | arg("safeRoute.defaultPackageName", "cz.levinzonr.saferoute.navigation") 67 | } 68 | 69 | 70 | dependencies { 71 | val hilt_version = "2.37" 72 | implementation(project(":accompanist-navigation")) 73 | ksp(project(":processor-ksp")) 74 | //ksp("cz.levinzonr.safe-routing:ksp-processor:2.5.0-beta02") 75 | 76 | /* kapt("cz.levinzonr.safe-routing:compiler:1.0.1") 77 | implementation("router:core:1")*/ 78 | 79 | implementation("androidx.hilt:hilt-navigation-compose:1.0.0") 80 | implementation("androidx.navigation:navigation-compose:${Deps.composeNavigation}") 81 | implementation("androidx.compose.ui:ui:${Deps.compose}") 82 | implementation("androidx.compose.material:material:${Deps.compose}") 83 | implementation("androidx.compose.ui:ui-tooling:${Deps.compose}") 84 | 85 | implementation("com.google.dagger:hilt-android:$hilt_version") 86 | kapt("com.google.dagger:hilt-android-compiler:$hilt_version") 87 | implementation("androidx.core:core-ktx:1.5.0") 88 | implementation("com.google.accompanist:accompanist-navigation-animation:${Deps.accompanist}") 89 | implementation("com.google.accompanist:accompanist-navigation-material:${Deps.accompanist}") 90 | 91 | 92 | 93 | implementation("androidx.appcompat:appcompat:1.2.0") 94 | implementation("com.google.android.material:material:1.3.0") 95 | implementation("androidx.activity:activity-compose:1.3.0-alpha07") 96 | } -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 13 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /app/src/main/java/cz/levinzonr/saferoute/App.kt: -------------------------------------------------------------------------------- 1 | package cz.levinzonr.saferoute 2 | 3 | import android.app.Application 4 | import dagger.hilt.android.HiltAndroidApp 5 | 6 | @HiltAndroidApp 7 | class App : Application() 8 | -------------------------------------------------------------------------------- /app/src/main/java/cz/levinzonr/saferoute/components/PlaceholderComponent.kt: -------------------------------------------------------------------------------- 1 | package cz.levinzonr.saferoute.components 2 | 3 | import androidx.compose.foundation.clickable 4 | import androidx.compose.foundation.layout.Box 5 | import androidx.compose.foundation.layout.fillMaxSize 6 | import androidx.compose.material.Text 7 | import androidx.compose.runtime.Composable 8 | import androidx.compose.ui.Alignment 9 | import androidx.compose.ui.Modifier 10 | import androidx.compose.ui.graphics.Color 11 | 12 | @Composable 13 | fun Placeholder(color: Color, title: String, onClick: () -> Unit = {}) { 14 | Box(modifier = Modifier.fillMaxSize().clickable { onClick.invoke() }, contentAlignment = Alignment.Center) { 15 | Text(text = title) 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /app/src/main/java/cz/levinzonr/saferoute/screens/PokemonSelector.kt: -------------------------------------------------------------------------------- 1 | package cz.levinzonr.saferoute.screens 2 | 3 | import androidx.compose.foundation.BorderStroke 4 | import androidx.compose.foundation.border 5 | import androidx.compose.foundation.clickable 6 | import androidx.compose.foundation.layout.Arrangement 7 | import androidx.compose.foundation.layout.Column 8 | import androidx.compose.foundation.layout.fillMaxHeight 9 | import androidx.compose.foundation.layout.fillMaxWidth 10 | import androidx.compose.foundation.layout.padding 11 | import androidx.compose.foundation.lazy.LazyColumn 12 | import androidx.compose.foundation.lazy.items 13 | import androidx.compose.foundation.shape.RoundedCornerShape 14 | import androidx.compose.material.MaterialTheme 15 | import androidx.compose.material.Surface 16 | import androidx.compose.material.Text 17 | import androidx.compose.runtime.Composable 18 | import androidx.compose.ui.Modifier 19 | import androidx.compose.ui.res.colorResource 20 | import androidx.compose.ui.unit.dp 21 | import cz.levinzonr.saferoute.core.annotations.Route 22 | import cz.levinzonr.saferoute.data.Pokemon 23 | import cz.levinzonr.saferoute.data.color 24 | import cz.levinzonr.saferoute.data.pokemons 25 | import cz.levinzonr.saferoute.transitions.CustomDialogTransition 26 | 27 | @Composable 28 | @Route( 29 | name = "PokemonSelector", 30 | transition = CustomDialogTransition::class 31 | ) 32 | fun PokemonSelector(onSelected: (Pokemon) -> Unit) { 33 | Surface( 34 | modifier = Modifier 35 | .fillMaxWidth() 36 | .fillMaxHeight(0.8f), 37 | shape = RoundedCornerShape(16.dp) 38 | ) { 39 | 40 | Column( 41 | modifier = Modifier.padding(32.dp), 42 | verticalArrangement = Arrangement.spacedBy(25.dp) 43 | ) { 44 | 45 | Text(text = "Choose pokemon to deeplink to", style = MaterialTheme.typography.h6) 46 | 47 | LazyColumn(verticalArrangement = Arrangement.spacedBy(12.dp)) { 48 | items(pokemons) { 49 | Text( 50 | text = "${it.id} ${it.name}", 51 | modifier = Modifier 52 | .fillMaxWidth() 53 | .border( 54 | BorderStroke(2.dp, colorResource(id = it.color())), 55 | shape = RoundedCornerShape(32.dp) 56 | ) 57 | .padding(12.dp) 58 | .clickable { onSelected(it) } 59 | ) 60 | } 61 | } 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /app/src/main/java/cz/levinzonr/saferoute/screens/Previews.kt: -------------------------------------------------------------------------------- 1 | package cz.levinzonr.saferoute.screens 2 | 3 | import androidx.compose.animation.ExperimentalAnimationApi 4 | import androidx.compose.runtime.Composable 5 | import androidx.compose.ui.tooling.preview.Preview 6 | import cz.levinzonr.saferoute.data.pokemons 7 | import cz.levinzonr.saferoute.screens.details.PokemonDetailsScreen 8 | import cz.levinzonr.saferoute.screens.home.HomeScreen 9 | import cz.levinzonr.saferoute.screens.list.PokemonListScreen 10 | import cz.levinzonr.saferoute.ui.theme.RouterTheme 11 | 12 | @Preview(showBackground = true) 13 | @Composable 14 | fun PreviewHomeScreen() { 15 | RouterTheme { 16 | HomeScreen(onShowPokedex = {}, onDeeplink = {}) 17 | } 18 | } 19 | 20 | @Preview 21 | @Composable 22 | fun PreviewPokemonListScreen() { 23 | RouterTheme { 24 | PokemonListScreen(onPokemonClick = {}) 25 | } 26 | } 27 | 28 | @ExperimentalAnimationApi 29 | @Preview(showBackground = true) 30 | @Composable 31 | fun PreviewPokemonDetailsScreen() { 32 | RouterTheme { 33 | PokemonDetailsScreen(onShowStatsClick = {}, pokemon = pokemons.first()) 34 | } 35 | } 36 | 37 | @Preview(showBackground = true) 38 | @Composable 39 | fun PreviewPokemonSelector() { 40 | RouterTheme { 41 | PokemonSelector(onSelected = {}) 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /app/src/main/java/cz/levinzonr/saferoute/screens/details/PokemonDetailsViewModel.kt: -------------------------------------------------------------------------------- 1 | package cz.levinzonr.saferoute.screens.details 2 | 3 | import androidx.lifecycle.SavedStateHandle 4 | import androidx.lifecycle.ViewModel 5 | import androidx.lifecycle.viewModelScope 6 | import cz.levinzonr.saferoute.data.Pokemon 7 | import cz.levinzonr.saferoute.data.pokemons 8 | import cz.levinzonr.saferoute.screens.details.args.PokemonDetailsRouteArgsFactory 9 | import dagger.hilt.android.lifecycle.HiltViewModel 10 | import kotlinx.coroutines.flow.MutableStateFlow 11 | import kotlinx.coroutines.launch 12 | import javax.inject.Inject 13 | 14 | @HiltViewModel 15 | class PokemonDetailsViewModel @Inject constructor( 16 | savedStateHandle: SavedStateHandle 17 | ) : ViewModel() { 18 | 19 | private val args = PokemonDetailsRouteArgsFactory.fromSavedStateHandle(savedStateHandle) 20 | 21 | val pokemon = MutableStateFlow(null) 22 | 23 | init { 24 | viewModelScope.launch { 25 | println(args.id) 26 | pokemons.find { args.id == it.id }?.let { 27 | println(it) 28 | pokemon.emit(it) 29 | } 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /app/src/main/java/cz/levinzonr/saferoute/screens/home/HomeScreen.kt: -------------------------------------------------------------------------------- 1 | package cz.levinzonr.saferoute.screens.home 2 | 3 | import androidx.compose.animation.ExperimentalAnimationApi 4 | import androidx.compose.foundation.clickable 5 | import androidx.compose.foundation.layout.Arrangement 6 | import androidx.compose.foundation.layout.Box 7 | import androidx.compose.foundation.layout.Column 8 | import androidx.compose.foundation.layout.Row 9 | import androidx.compose.foundation.layout.RowScope 10 | import androidx.compose.foundation.layout.fillMaxSize 11 | import androidx.compose.foundation.layout.height 12 | import androidx.compose.foundation.layout.padding 13 | import androidx.compose.foundation.shape.RoundedCornerShape 14 | import androidx.compose.material.Card 15 | import androidx.compose.material.MaterialTheme 16 | import androidx.compose.material.Text 17 | import androidx.compose.runtime.Composable 18 | import androidx.compose.ui.Alignment 19 | import androidx.compose.ui.Modifier 20 | import androidx.compose.ui.graphics.Color 21 | import androidx.compose.ui.res.colorResource 22 | import androidx.compose.ui.unit.dp 23 | import cz.levinzonr.saferoute.R 24 | import cz.levinzonr.saferoute.accompanist.navigation.transitions.AnimatedRouteTransition 25 | import cz.levinzonr.saferoute.core.annotations.Route 26 | import cz.levinzonr.saferoute.core.annotations.RouteNavGraph 27 | 28 | @OptIn(ExperimentalAnimationApi::class) 29 | @Composable 30 | @Route( 31 | transition = AnimatedRouteTransition.Default::class, 32 | navGraph = RouteNavGraph(start = true) 33 | ) 34 | @Route( 35 | name = "homeTest", 36 | transition = AnimatedRouteTransition.Default::class, 37 | navGraph = RouteNavGraph("test", start = true) 38 | ) 39 | fun HomeScreen( 40 | onShowPokedex: () -> Unit, 41 | onDeeplink: () -> Unit 42 | ) { 43 | Column( 44 | modifier = Modifier 45 | .fillMaxSize() 46 | .padding(24.dp), 47 | verticalArrangement = Arrangement.spacedBy(32.dp) 48 | ) { 49 | Text(text = "SafeRoute Navigation Home", style = MaterialTheme.typography.h3) 50 | Row( 51 | horizontalArrangement = Arrangement.spacedBy(12.dp), 52 | modifier = Modifier.fillMaxSize() 53 | ) { 54 | HomeButton(title = "Pokedex", color = colorResource(id = R.color.poke_light_teal)) { 55 | onShowPokedex.invoke() 56 | } 57 | HomeButton(title = "Pokelink", color = colorResource(id = R.color.poke_light_red)) { 58 | onDeeplink.invoke() 59 | } 60 | } 61 | } 62 | } 63 | 64 | @Composable 65 | private fun RowScope.HomeButton( 66 | title: String, 67 | color: Color, 68 | onClick: () -> Unit 69 | ) { 70 | Card( 71 | backgroundColor = color, 72 | shape = RoundedCornerShape(24.dp), 73 | modifier = Modifier 74 | .height(85.dp).weight(1f) 75 | .clickable { onClick.invoke() } 76 | ) { 77 | Box( 78 | modifier = Modifier 79 | .padding(vertical = 16.dp, horizontal = 24.dp) 80 | ) { 81 | Text( 82 | text = title, 83 | color = Color.White, 84 | style = MaterialTheme.typography.h6, 85 | modifier = Modifier.align(Alignment.CenterStart) 86 | ) 87 | } 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /app/src/main/java/cz/levinzonr/saferoute/screens/list/PokemonListScreen.kt: -------------------------------------------------------------------------------- 1 | package cz.levinzonr.saferoute.screens.list 2 | 3 | import androidx.compose.foundation.clickable 4 | import androidx.compose.foundation.layout.Arrangement 5 | import androidx.compose.foundation.layout.PaddingValues 6 | import androidx.compose.foundation.lazy.LazyColumn 7 | import androidx.compose.foundation.lazy.items 8 | import androidx.compose.material.Scaffold 9 | import androidx.compose.runtime.Composable 10 | import androidx.compose.ui.Modifier 11 | import androidx.compose.ui.unit.dp 12 | import cz.levinzonr.saferoute.core.annotations.Route 13 | import cz.levinzonr.saferoute.core.annotations.RouteNavGraph 14 | import cz.levinzonr.saferoute.data.Pokemon 15 | import cz.levinzonr.saferoute.data.pokemons 16 | import cz.levinzonr.saferoute.screens.list.components.PokemonItem 17 | import cz.levinzonr.saferoute.transitions.FadeInFadeOutTransition 18 | 19 | @Composable 20 | @Route( 21 | name = "PokemonList", 22 | transition = FadeInFadeOutTransition::class, 23 | navGraph = RouteNavGraph("pokedex", start = true) 24 | ) 25 | fun PokemonListScreen( 26 | onPokemonClick: (Pokemon) -> Unit, 27 | ) { 28 | 29 | Scaffold { 30 | LazyColumn( 31 | contentPadding = PaddingValues(16.dp), 32 | verticalArrangement = Arrangement.spacedBy(12.dp) 33 | ) { 34 | items(pokemons) { 35 | PokemonItem( 36 | pokemon = it, 37 | modifier = Modifier.clickable { onPokemonClick.invoke(it) } 38 | ) 39 | } 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /app/src/main/java/cz/levinzonr/saferoute/screens/list/components/PokemonItem.kt: -------------------------------------------------------------------------------- 1 | package cz.levinzonr.saferoute.screens.list.components 2 | 3 | import androidx.compose.foundation.Image 4 | import androidx.compose.foundation.layout.Arrangement 5 | import androidx.compose.foundation.layout.Row 6 | import androidx.compose.foundation.layout.fillMaxHeight 7 | import androidx.compose.foundation.layout.fillMaxSize 8 | import androidx.compose.foundation.layout.fillMaxWidth 9 | import androidx.compose.foundation.layout.height 10 | import androidx.compose.foundation.layout.padding 11 | import androidx.compose.foundation.shape.RoundedCornerShape 12 | import androidx.compose.material.Card 13 | import androidx.compose.material.MaterialTheme 14 | import androidx.compose.material.Text 15 | import androidx.compose.runtime.Composable 16 | import androidx.compose.ui.Alignment 17 | import androidx.compose.ui.Modifier 18 | import androidx.compose.ui.graphics.Color 19 | import androidx.compose.ui.res.colorResource 20 | import androidx.compose.ui.res.painterResource 21 | import androidx.compose.ui.tooling.preview.Preview 22 | import androidx.compose.ui.unit.dp 23 | import cz.levinzonr.saferoute.data.Pokemon 24 | import cz.levinzonr.saferoute.data.color 25 | import cz.levinzonr.saferoute.data.pokemons 26 | 27 | @Composable 28 | fun PokemonItem( 29 | modifier: Modifier = Modifier, 30 | pokemon: Pokemon 31 | ) { 32 | Card( 33 | backgroundColor = colorResource(id = pokemon.color()), 34 | shape = RoundedCornerShape(32.dp), 35 | modifier = modifier 36 | .fillMaxWidth() 37 | .height(100.dp) 38 | ) { 39 | Row( 40 | modifier = Modifier.fillMaxSize().padding(16.dp), 41 | horizontalArrangement = Arrangement.spacedBy(16.dp) 42 | ) { 43 | 44 | Image( 45 | painter = painterResource(id = pokemon.image), 46 | contentDescription = "poke", 47 | modifier = Modifier.fillMaxHeight() 48 | ) 49 | 50 | Text( 51 | text = pokemon.name.toString(), 52 | style = MaterialTheme.typography.h6, 53 | modifier = Modifier.align(Alignment.CenterVertically), 54 | color = Color.White 55 | ) 56 | } 57 | } 58 | } 59 | 60 | @Preview 61 | @Composable 62 | private fun PreviewPokemonItem() { 63 | MaterialTheme { 64 | PokemonItem(pokemon = pokemons.random()) 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /app/src/main/java/cz/levinzonr/saferoute/screens/statssheet/PokemonStatsSheet.kt: -------------------------------------------------------------------------------- 1 | package cz.levinzonr.saferoute.screens.statssheet 2 | 3 | import androidx.compose.foundation.Image 4 | import androidx.compose.foundation.layout.Arrangement 5 | import androidx.compose.foundation.layout.Column 6 | import androidx.compose.foundation.layout.fillMaxWidth 7 | import androidx.compose.foundation.layout.padding 8 | import androidx.compose.material.MaterialTheme 9 | import androidx.compose.material.Text 10 | import androidx.compose.runtime.Composable 11 | import androidx.compose.ui.Alignment 12 | import androidx.compose.ui.Modifier 13 | import androidx.compose.ui.res.painterResource 14 | import androidx.compose.ui.unit.dp 15 | import com.google.accompanist.navigation.material.ExperimentalMaterialNavigationApi 16 | import cz.levinzonr.saferoute.R 17 | import cz.levinzonr.saferoute.accompanist.navigation.transitions.BottomSheetRouteTransition 18 | import cz.levinzonr.saferoute.core.annotations.Route 19 | import cz.levinzonr.saferoute.core.annotations.RouteArg 20 | import cz.levinzonr.saferoute.core.annotations.RouteNavGraph 21 | import cz.levinzonr.saferoute.screens.statssheet.args.LocalPokemonStatsRouteArgs 22 | 23 | @OptIn(ExperimentalMaterialNavigationApi::class) 24 | @Composable 25 | @Route( 26 | name = "PokemonStats", 27 | transition = BottomSheetRouteTransition::class, 28 | args = [ 29 | RouteArg("name", type = String::class), 30 | RouteArg("category", type = String::class, isNullable = true), 31 | RouteArg("hp", type = Int::class), 32 | RouteArg("imageRes", type = Int::class, isOptional = true, defaultValue = R.drawable.poke001.toString()) 33 | ], 34 | navGraph = RouteNavGraph("pokedex", start = false) 35 | ) 36 | fun PokemonStatsSheet() { 37 | val args = LocalPokemonStatsRouteArgs.current 38 | Column( 39 | modifier = Modifier.padding(64.dp).fillMaxWidth(), 40 | horizontalAlignment = Alignment.CenterHorizontally, 41 | verticalArrangement = Arrangement.spacedBy(16.dp) 42 | ) { 43 | Image(painter = painterResource(id = args.imageRes), contentDescription = "") 44 | Text(text = args.name, style = MaterialTheme.typography.h6) 45 | Text(text = "Category: ${args.category}") 46 | Text(text = "HP: ${args.hp}") 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /app/src/main/java/cz/levinzonr/saferoute/transitions/CustomDialogTransition.kt: -------------------------------------------------------------------------------- 1 | package cz.levinzonr.saferoute.transitions 2 | 3 | import androidx.compose.ui.window.DialogProperties 4 | import cz.levinzonr.saferoute.core.transitions.DialogRouteTransition 5 | 6 | object CustomDialogTransition : DialogRouteTransition() { 7 | override val properties: DialogProperties 8 | get() = DialogProperties(dismissOnBackPress = false) 9 | } 10 | -------------------------------------------------------------------------------- /app/src/main/java/cz/levinzonr/saferoute/transitions/FadeInFadeOutTransition.kt: -------------------------------------------------------------------------------- 1 | package cz.levinzonr.saferoute.transitions 2 | 3 | import androidx.compose.animation.ExperimentalAnimationApi 4 | import androidx.compose.animation.expandIn 5 | import androidx.compose.animation.shrinkOut 6 | import cz.levinzonr.saferoute.accompanist.navigation.RouteEnterTransition 7 | import cz.levinzonr.saferoute.accompanist.navigation.RouteExitTransition 8 | import cz.levinzonr.saferoute.accompanist.navigation.transitions.AnimatedRouteTransition 9 | 10 | @OptIn(ExperimentalAnimationApi::class) 11 | object FadeInFadeOutTransition : AnimatedRouteTransition() { 12 | override val enter: RouteEnterTransition = { expandIn() } 13 | override val exit: RouteExitTransition = { shrinkOut() } 14 | override val popEnter: RouteEnterTransition = enter 15 | override val popExit: RouteExitTransition = exit 16 | } 17 | -------------------------------------------------------------------------------- /app/src/main/java/cz/levinzonr/saferoute/ui/theme/Color.kt: -------------------------------------------------------------------------------- 1 | package cz.levinzonr.saferoute.ui.theme 2 | 3 | import androidx.compose.ui.graphics.Color 4 | 5 | val Purple200 = Color(0xFFBB86FC) 6 | val Purple500 = Color(0xFF6200EE) 7 | val Purple700 = Color(0xFF3700B3) 8 | val Teal200 = Color(0xFF03DAC5) 9 | -------------------------------------------------------------------------------- /app/src/main/java/cz/levinzonr/saferoute/ui/theme/Shape.kt: -------------------------------------------------------------------------------- 1 | package cz.levinzonr.saferoute.ui.theme 2 | 3 | import androidx.compose.foundation.shape.RoundedCornerShape 4 | import androidx.compose.material.Shapes 5 | import androidx.compose.ui.unit.dp 6 | 7 | val Shapes = Shapes( 8 | small = RoundedCornerShape(4.dp), 9 | medium = RoundedCornerShape(4.dp), 10 | large = RoundedCornerShape(0.dp) 11 | ) 12 | -------------------------------------------------------------------------------- /app/src/main/java/cz/levinzonr/saferoute/ui/theme/Theme.kt: -------------------------------------------------------------------------------- 1 | package cz.levinzonr.saferoute.ui.theme 2 | 3 | import androidx.compose.foundation.isSystemInDarkTheme 4 | import androidx.compose.material.MaterialTheme 5 | import androidx.compose.material.darkColors 6 | import androidx.compose.material.lightColors 7 | import androidx.compose.runtime.Composable 8 | 9 | private val DarkColorPalette = darkColors( 10 | primary = Purple200, 11 | primaryVariant = Purple700, 12 | secondary = Teal200 13 | ) 14 | 15 | private val LightColorPalette = lightColors( 16 | primary = Purple500, 17 | primaryVariant = Purple700, 18 | secondary = Teal200 19 | 20 | /* Other default colors to override 21 | background = Color.White, 22 | surface = Color.White, 23 | onPrimary = Color.White, 24 | onSecondary = Color.Black, 25 | onBackground = Color.Black, 26 | onSurface = Color.Black, 27 | */ 28 | ) 29 | 30 | @Composable 31 | fun RouterTheme(darkTheme: Boolean = isSystemInDarkTheme(), content: @Composable() () -> Unit) { 32 | val colors = if (darkTheme) { 33 | LightColorPalette 34 | } else { 35 | LightColorPalette 36 | } 37 | 38 | MaterialTheme( 39 | colors = colors, 40 | typography = Typography, 41 | shapes = Shapes, 42 | content = content 43 | ) 44 | } 45 | -------------------------------------------------------------------------------- /app/src/main/java/cz/levinzonr/saferoute/ui/theme/Type.kt: -------------------------------------------------------------------------------- 1 | package cz.levinzonr.saferoute.ui.theme 2 | 3 | import androidx.compose.material.Typography 4 | import androidx.compose.ui.text.TextStyle 5 | import androidx.compose.ui.text.font.FontFamily 6 | import androidx.compose.ui.text.font.FontWeight 7 | import androidx.compose.ui.unit.sp 8 | 9 | // Set of Material typography styles to start with 10 | val Typography = Typography( 11 | body1 = TextStyle( 12 | fontFamily = FontFamily.Default, 13 | fontWeight = FontWeight.Normal, 14 | fontSize = 16.sp 15 | ) 16 | /* Other default text styles to override 17 | button = TextStyle( 18 | fontFamily = FontFamily.Default, 19 | fontWeight = FontWeight.W500, 20 | fontSize = 14.sp 21 | ), 22 | caption = TextStyle( 23 | fontFamily = FontFamily.Default, 24 | fontWeight = FontWeight.Normal, 25 | fontSize = 12.sp 26 | ) 27 | */ 28 | ) 29 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | 15 | 18 | 21 | 22 | 23 | 24 | 30 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/dotted.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/levinzonr/compose-safe-routing/8d65e08c2aa5dbe3d0f829e605887e42f36dcd85/app/src/main/res/drawable/dotted.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/news1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/levinzonr/compose-safe-routing/8d65e08c2aa5dbe3d0f829e605887e42f36dcd85/app/src/main/res/drawable/news1.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable/poke001.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/levinzonr/compose-safe-routing/8d65e08c2aa5dbe3d0f829e605887e42f36dcd85/app/src/main/res/drawable/poke001.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/poke002.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/levinzonr/compose-safe-routing/8d65e08c2aa5dbe3d0f829e605887e42f36dcd85/app/src/main/res/drawable/poke002.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/poke003.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/levinzonr/compose-safe-routing/8d65e08c2aa5dbe3d0f829e605887e42f36dcd85/app/src/main/res/drawable/poke003.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/poke004.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/levinzonr/compose-safe-routing/8d65e08c2aa5dbe3d0f829e605887e42f36dcd85/app/src/main/res/drawable/poke004.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/poke005.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/levinzonr/compose-safe-routing/8d65e08c2aa5dbe3d0f829e605887e42f36dcd85/app/src/main/res/drawable/poke005.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/poke006.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/levinzonr/compose-safe-routing/8d65e08c2aa5dbe3d0f829e605887e42f36dcd85/app/src/main/res/drawable/poke006.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/poke007.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/levinzonr/compose-safe-routing/8d65e08c2aa5dbe3d0f829e605887e42f36dcd85/app/src/main/res/drawable/poke007.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/poke008.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/levinzonr/compose-safe-routing/8d65e08c2aa5dbe3d0f829e605887e42f36dcd85/app/src/main/res/drawable/poke008.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/poke009.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/levinzonr/compose-safe-routing/8d65e08c2aa5dbe3d0f829e605887e42f36dcd85/app/src/main/res/drawable/poke009.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/poke010.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/levinzonr/compose-safe-routing/8d65e08c2aa5dbe3d0f829e605887e42f36dcd85/app/src/main/res/drawable/poke010.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/poke011.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/levinzonr/compose-safe-routing/8d65e08c2aa5dbe3d0f829e605887e42f36dcd85/app/src/main/res/drawable/poke011.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/poke012.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/levinzonr/compose-safe-routing/8d65e08c2aa5dbe3d0f829e605887e42f36dcd85/app/src/main/res/drawable/poke012.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/poke013.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/levinzonr/compose-safe-routing/8d65e08c2aa5dbe3d0f829e605887e42f36dcd85/app/src/main/res/drawable/poke013.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/poke014.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/levinzonr/compose-safe-routing/8d65e08c2aa5dbe3d0f829e605887e42f36dcd85/app/src/main/res/drawable/poke014.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/poke015.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/levinzonr/compose-safe-routing/8d65e08c2aa5dbe3d0f829e605887e42f36dcd85/app/src/main/res/drawable/poke015.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/poke016.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/levinzonr/compose-safe-routing/8d65e08c2aa5dbe3d0f829e605887e42f36dcd85/app/src/main/res/drawable/poke016.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/poke017.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/levinzonr/compose-safe-routing/8d65e08c2aa5dbe3d0f829e605887e42f36dcd85/app/src/main/res/drawable/poke017.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/poke018.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/levinzonr/compose-safe-routing/8d65e08c2aa5dbe3d0f829e605887e42f36dcd85/app/src/main/res/drawable/poke018.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/poke019.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/levinzonr/compose-safe-routing/8d65e08c2aa5dbe3d0f829e605887e42f36dcd85/app/src/main/res/drawable/poke019.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/poke020.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/levinzonr/compose-safe-routing/8d65e08c2aa5dbe3d0f829e605887e42f36dcd85/app/src/main/res/drawable/poke020.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/poke021.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/levinzonr/compose-safe-routing/8d65e08c2aa5dbe3d0f829e605887e42f36dcd85/app/src/main/res/drawable/poke021.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/poke022.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/levinzonr/compose-safe-routing/8d65e08c2aa5dbe3d0f829e605887e42f36dcd85/app/src/main/res/drawable/poke022.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/poke023.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/levinzonr/compose-safe-routing/8d65e08c2aa5dbe3d0f829e605887e42f36dcd85/app/src/main/res/drawable/poke023.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/poke024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/levinzonr/compose-safe-routing/8d65e08c2aa5dbe3d0f829e605887e42f36dcd85/app/src/main/res/drawable/poke024.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/poke025.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/levinzonr/compose-safe-routing/8d65e08c2aa5dbe3d0f829e605887e42f36dcd85/app/src/main/res/drawable/poke025.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/poke026.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/levinzonr/compose-safe-routing/8d65e08c2aa5dbe3d0f829e605887e42f36dcd85/app/src/main/res/drawable/poke026.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/poke027.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/levinzonr/compose-safe-routing/8d65e08c2aa5dbe3d0f829e605887e42f36dcd85/app/src/main/res/drawable/poke027.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/poke028.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/levinzonr/compose-safe-routing/8d65e08c2aa5dbe3d0f829e605887e42f36dcd85/app/src/main/res/drawable/poke028.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/pokeball.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/levinzonr/compose-safe-routing/8d65e08c2aa5dbe3d0f829e605887e42f36dcd85/app/src/main/res/drawable/pokeball.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/pokeball_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/levinzonr/compose-safe-routing/8d65e08c2aa5dbe3d0f829e605887e42f36dcd85/app/src/main/res/drawable/pokeball_s.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/levinzonr/compose-safe-routing/8d65e08c2aa5dbe3d0f829e605887e42f36dcd85/app/src/main/res/drawable/search.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/levinzonr/compose-safe-routing/8d65e08c2aa5dbe3d0f829e605887e42f36dcd85/app/src/main/res/mipmap-hdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/levinzonr/compose-safe-routing/8d65e08c2aa5dbe3d0f829e605887e42f36dcd85/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/levinzonr/compose-safe-routing/8d65e08c2aa5dbe3d0f829e605887e42f36dcd85/app/src/main/res/mipmap-mdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/levinzonr/compose-safe-routing/8d65e08c2aa5dbe3d0f829e605887e42f36dcd85/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/levinzonr/compose-safe-routing/8d65e08c2aa5dbe3d0f829e605887e42f36dcd85/app/src/main/res/mipmap-xhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/levinzonr/compose-safe-routing/8d65e08c2aa5dbe3d0f829e605887e42f36dcd85/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/levinzonr/compose-safe-routing/8d65e08c2aa5dbe3d0f829e605887e42f36dcd85/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/levinzonr/compose-safe-routing/8d65e08c2aa5dbe3d0f829e605887e42f36dcd85/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/levinzonr/compose-safe-routing/8d65e08c2aa5dbe3d0f829e605887e42f36dcd85/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/levinzonr/compose-safe-routing/8d65e08c2aa5dbe3d0f829e605887e42f36dcd85/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /app/src/main/res/values-night/themes.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16 | -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #FFBB86FC 4 | #FF6200EE 5 | #FF3700B3 6 | #FF03DAC5 7 | #FF018786 8 | #FF000000 9 | #FFFFFFFF 10 | 11 | 12 | #303943 13 | #429BED 14 | #B1736C 15 | #58ABF6 16 | #CA8179 17 | #9F5BBA 18 | #F7786B 19 | #2CDAB1 20 | #FFCE4B 21 | #7C538C 22 | #FA6555 23 | #4FC1A6 24 | #F6C747 25 | 26 | -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | router 3 | -------------------------------------------------------------------------------- /app/src/main/res/values/themes.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16 | 17 | 21 | 22 |