├── android ├── lib │ ├── dig │ │ ├── src │ │ │ └── main │ │ │ │ ├── AndroidManifest.xml │ │ │ │ ├── kotlin │ │ │ │ └── com │ │ │ │ │ └── dropbox │ │ │ │ │ └── forester │ │ │ │ │ └── android │ │ │ │ │ └── dig │ │ │ │ │ ├── DigTypography.kt │ │ │ │ │ ├── typography.kt │ │ │ │ │ ├── color │ │ │ │ │ ├── SystemThemeColors.kt │ │ │ │ │ ├── LocalColors.kt │ │ │ │ │ ├── StatefulColor.kt │ │ │ │ │ ├── material.kt │ │ │ │ │ └── Colors.kt │ │ │ │ │ ├── Dig.kt │ │ │ │ │ └── DigTheme.kt │ │ │ │ └── res │ │ │ │ └── drawable │ │ │ │ ├── activity_fill.xml │ │ │ │ ├── ic_activity_fill.xml │ │ │ │ ├── activity.xml │ │ │ │ ├── close.xml │ │ │ │ ├── chevron_right.xml │ │ │ │ ├── ic_activity_line.xml │ │ │ │ ├── dropbox.xml │ │ │ │ ├── switcher.xml │ │ │ │ ├── home_fill.xml │ │ │ │ ├── hashtag.xml │ │ │ │ ├── search.xml │ │ │ │ ├── person_fill.xml │ │ │ │ ├── clock.xml │ │ │ │ ├── ic_person_fill.xml │ │ │ │ ├── add_circle.xml │ │ │ │ ├── collection.xml │ │ │ │ ├── home.xml │ │ │ │ ├── fail.xml │ │ │ │ ├── sort_type.xml │ │ │ │ ├── person.xml │ │ │ │ ├── apps.xml │ │ │ │ ├── edit.xml │ │ │ │ ├── google.xml │ │ │ │ ├── notification_fill.xml │ │ │ │ ├── mention.xml │ │ │ │ ├── show.xml │ │ │ │ ├── notification.xml │ │ │ │ ├── finder.xml │ │ │ │ ├── finder_fill.xml │ │ │ │ ├── person_multiple.xml │ │ │ │ ├── settings.xml │ │ │ │ └── pokemon.xml │ │ └── build.gradle │ └── api │ │ ├── src │ │ └── main │ │ │ └── kotlin │ │ │ └── com │ │ │ └── dropbox │ │ │ └── forester │ │ │ └── android │ │ │ └── api │ │ │ ├── entity │ │ │ ├── user.kt │ │ │ ├── machine.kt │ │ │ ├── encounter.kt │ │ │ ├── contest.kt │ │ │ ├── berry.kt │ │ │ ├── evolution.kt │ │ │ ├── game.kt │ │ │ ├── location.kt │ │ │ ├── item.kt │ │ │ ├── resource.kt │ │ │ ├── misc.kt │ │ │ ├── move.kt │ │ │ └── pokemon.kt │ │ │ ├── RequestResult.kt │ │ │ └── PokeApi.kt │ │ ├── build.gradle │ │ └── impl │ │ ├── build.gradle │ │ └── src │ │ └── main │ │ └── kotlin │ │ └── com │ │ └── dropbox │ │ └── forester │ │ └── android │ │ └── api │ │ └── RealPokeApi.kt ├── common │ ├── scoping │ │ ├── src │ │ │ └── main │ │ │ │ ├── AndroidManifest.xml │ │ │ │ └── kotlin │ │ │ │ └── com │ │ │ │ └── dropbox │ │ │ │ └── forester │ │ │ │ └── android │ │ │ │ └── scoping │ │ │ │ ├── AppScope.kt │ │ │ │ ├── UserScope.kt │ │ │ │ ├── ComponentHolder.kt │ │ │ │ ├── UserDependencies.kt │ │ │ │ ├── SingleIn.kt │ │ │ │ └── binding.kt │ │ └── build.gradle │ └── repository_utils │ │ └── build.gradle ├── app │ ├── src │ │ └── main │ │ │ ├── res │ │ │ ├── mipmap-hdpi │ │ │ │ └── pokemon.webp │ │ │ ├── mipmap-anydpi-v26 │ │ │ │ └── ic_launcher.xml │ │ │ └── values │ │ │ │ ├── colors.xml │ │ │ │ └── theme.xml │ │ │ ├── kotlin │ │ │ └── com │ │ │ │ └── dropbox │ │ │ │ └── forester │ │ │ │ └── android │ │ │ │ └── app │ │ │ │ ├── navigation │ │ │ │ ├── BottomTabs.kt │ │ │ │ ├── Routing.kt │ │ │ │ └── Screen.kt │ │ │ │ ├── wiring │ │ │ │ ├── AppDependencies.kt │ │ │ │ ├── AppComponent.kt │ │ │ │ ├── UserComponent.kt │ │ │ │ └── AppModule.kt │ │ │ │ ├── ui │ │ │ │ ├── PokedexScaffold.kt │ │ │ │ └── PokedexBottomBar.kt │ │ │ │ ├── PokedexMainActivity.kt │ │ │ │ └── PokedexApp.kt │ │ │ └── AndroidManifest.xml │ └── build.gradle └── feat │ ├── pokedex_tab │ ├── src │ │ └── main │ │ │ ├── res │ │ │ ├── drawable │ │ │ │ ├── pin.webp │ │ │ │ ├── bolt.webp │ │ │ │ ├── helix.webp │ │ │ │ └── pokeball.webp │ │ │ └── raw │ │ │ │ └── pokeball_loading.json │ │ │ └── kotlin │ │ │ └── com │ │ │ └── dropbox │ │ │ └── forester │ │ │ └── android │ │ │ └── feat │ │ │ └── pokedex_tab │ │ │ ├── PokedexRepository.kt │ │ │ ├── PokedexBindings.kt │ │ │ ├── PokedexState.kt │ │ │ ├── PokedexComponent.kt │ │ │ ├── RealPokedexRepository.kt │ │ │ ├── PokedexViewModel.kt │ │ │ ├── Search.kt │ │ │ ├── Tile.kt │ │ │ ├── Tiles.kt │ │ │ └── PokedexTab.kt │ └── build.gradle │ └── account_tab │ ├── build.gradle │ └── src │ └── main │ └── kotlin │ └── com │ └── dropbox │ └── forester │ └── android │ └── feat │ └── account_tab │ └── AccountTab.kt ├── forester ├── gradle.properties ├── src │ └── main │ │ └── kotlin │ │ └── com │ │ └── dropbox │ │ └── forester │ │ ├── Scope.kt │ │ ├── Forest.kt │ │ ├── Graph.kt │ │ ├── Directed.kt │ │ ├── Undirected.kt │ │ ├── Node.kt │ │ ├── Shape.kt │ │ └── Forester.kt └── build.gradle.kts ├── .github ├── images │ ├── sample_class.png │ ├── sample_overview.png │ └── mapping_out_the_forest.png └── workflows │ └── publish.yml ├── gradle ├── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties └── libs.versions.toml ├── forester-gradle-plugin ├── gradle.properties ├── src │ └── main │ │ └── kotlin │ │ └── com │ │ └── dropbox │ │ └── forester │ │ └── plugin │ │ ├── ForesterPluginExt.kt │ │ ├── ForesterAnnotation.kt │ │ ├── ForesterAnnotationVisitor.kt │ │ ├── ForesterClassVisitor.kt │ │ └── ForesterPlugin.kt └── build.gradle.kts ├── forester-graph-plugin ├── src │ └── main │ │ └── kotlin │ │ └── com │ │ └── dropbox │ │ └── forester │ │ └── dagger │ │ ├── Node.kt │ │ ├── Graph.kt │ │ ├── Dependency.kt │ │ ├── Component.kt │ │ ├── Binding.kt │ │ └── ForesterGraphPlugin.kt └── build.gradle.kts ├── local.properties ├── .gitignore ├── settings.gradle.kts ├── gradle.properties ├── README.md ├── gradlew.bat └── gradlew /android/lib/dig/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /forester/gradle.properties: -------------------------------------------------------------------------------- 1 | POM_NAME=com.dropbox.forester 2 | POM_ARTIFACT_ID=forester 3 | POM_PACKAGING=jar -------------------------------------------------------------------------------- /android/common/scoping/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.github/images/sample_class.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dropbox/forester/main/.github/images/sample_class.png -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dropbox/forester/main/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /.github/images/sample_overview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dropbox/forester/main/.github/images/sample_overview.png -------------------------------------------------------------------------------- /.github/images/mapping_out_the_forest.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dropbox/forester/main/.github/images/mapping_out_the_forest.png -------------------------------------------------------------------------------- /forester-gradle-plugin/gradle.properties: -------------------------------------------------------------------------------- 1 | POM_NAME=com.dropbox.forester 2 | POM_ARTIFACT_ID=forester-gradle-plugin 3 | POM_PACKAGING=jar -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/pokemon.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dropbox/forester/main/android/app/src/main/res/mipmap-hdpi/pokemon.webp -------------------------------------------------------------------------------- /android/feat/pokedex_tab/src/main/res/drawable/pin.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dropbox/forester/main/android/feat/pokedex_tab/src/main/res/drawable/pin.webp -------------------------------------------------------------------------------- /android/feat/pokedex_tab/src/main/res/drawable/bolt.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dropbox/forester/main/android/feat/pokedex_tab/src/main/res/drawable/bolt.webp -------------------------------------------------------------------------------- /android/feat/pokedex_tab/src/main/res/drawable/helix.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dropbox/forester/main/android/feat/pokedex_tab/src/main/res/drawable/helix.webp -------------------------------------------------------------------------------- /android/feat/pokedex_tab/src/main/res/drawable/pokeball.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dropbox/forester/main/android/feat/pokedex_tab/src/main/res/drawable/pokeball.webp -------------------------------------------------------------------------------- /forester/src/main/kotlin/com/dropbox/forester/Scope.kt: -------------------------------------------------------------------------------- 1 | package com.dropbox.forester 2 | 3 | 4 | interface Group 5 | 6 | interface Scope { 7 | val groups: List 8 | } -------------------------------------------------------------------------------- /forester/src/main/kotlin/com/dropbox/forester/Forest.kt: -------------------------------------------------------------------------------- 1 | package com.dropbox.forester 2 | 3 | @MustBeDocumented 4 | @Retention(AnnotationRetention.RUNTIME) 5 | annotation class Forest -------------------------------------------------------------------------------- /forester/src/main/kotlin/com/dropbox/forester/Graph.kt: -------------------------------------------------------------------------------- 1 | package com.dropbox.forester 2 | 3 | @MustBeDocumented 4 | @Retention(AnnotationRetention.RUNTIME) 5 | annotation class Graph -------------------------------------------------------------------------------- /android/common/scoping/src/main/kotlin/com/dropbox/forester/android/scoping/AppScope.kt: -------------------------------------------------------------------------------- 1 | package com.dropbox.forester.android.scoping 2 | 3 | abstract class AppScope private constructor() 4 | -------------------------------------------------------------------------------- /android/common/scoping/src/main/kotlin/com/dropbox/forester/android/scoping/UserScope.kt: -------------------------------------------------------------------------------- 1 | package com.dropbox.forester.android.scoping 2 | 3 | abstract class UserScope private constructor() 4 | -------------------------------------------------------------------------------- /android/app/src/main/kotlin/com/dropbox/forester/android/app/navigation/BottomTabs.kt: -------------------------------------------------------------------------------- 1 | package com.dropbox.forester.android.app.navigation 2 | 3 | val BottomTabs = listOf(Screen.Home, Screen.Account) 4 | -------------------------------------------------------------------------------- /android/common/scoping/src/main/kotlin/com/dropbox/forester/android/scoping/ComponentHolder.kt: -------------------------------------------------------------------------------- 1 | package com.dropbox.forester.android.scoping 2 | 3 | interface ComponentHolder { 4 | val component: Any 5 | } -------------------------------------------------------------------------------- /forester-graph-plugin/src/main/kotlin/com/dropbox/forester/dagger/Node.kt: -------------------------------------------------------------------------------- 1 | package com.dropbox.forester.dagger 2 | 3 | import kotlinx.serialization.Serializable 4 | 5 | @Serializable 6 | sealed class Node 7 | -------------------------------------------------------------------------------- /android/lib/dig/src/main/kotlin/com/dropbox/forester/android/dig/DigTypography.kt: -------------------------------------------------------------------------------- 1 | package com.dropbox.forester.android.dig 2 | 3 | import androidx.compose.material.Typography 4 | 5 | val DigTypography = Typography() -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /forester-graph-plugin/src/main/kotlin/com/dropbox/forester/dagger/Graph.kt: -------------------------------------------------------------------------------- 1 | package com.dropbox.forester.dagger 2 | 3 | import kotlinx.serialization.Serializable 4 | 5 | @Serializable 6 | data class Graph( 7 | val name: String, 8 | val nodes: List 9 | ) -------------------------------------------------------------------------------- /forester/src/main/kotlin/com/dropbox/forester/Directed.kt: -------------------------------------------------------------------------------- 1 | package com.dropbox.forester 2 | 3 | import kotlin.reflect.KClass 4 | 5 | @MustBeDocumented 6 | @Retention(AnnotationRetention.RUNTIME) 7 | annotation class Directed( 8 | val nodes: Array> 9 | ) -------------------------------------------------------------------------------- /android/common/scoping/src/main/kotlin/com/dropbox/forester/android/scoping/UserDependencies.kt: -------------------------------------------------------------------------------- 1 | package com.dropbox.forester.android.scoping 2 | 3 | import com.squareup.anvil.annotations.ContributesTo 4 | 5 | @ContributesTo(UserScope::class) 6 | interface UserDependencies -------------------------------------------------------------------------------- /forester/src/main/kotlin/com/dropbox/forester/Undirected.kt: -------------------------------------------------------------------------------- 1 | package com.dropbox.forester 2 | 3 | import kotlin.reflect.KClass 4 | 5 | @MustBeDocumented 6 | @Retention(AnnotationRetention.RUNTIME) 7 | annotation class Undirected( 8 | val nodes: Array> 9 | ) -------------------------------------------------------------------------------- /android/common/scoping/src/main/kotlin/com/dropbox/forester/android/scoping/SingleIn.kt: -------------------------------------------------------------------------------- 1 | package com.dropbox.forester.android.scoping 2 | 3 | import javax.inject.Scope 4 | import kotlin.reflect.KClass 5 | 6 | @Scope 7 | @Retention(AnnotationRetention.RUNTIME) 8 | annotation class SingleIn(val scope: KClass<*>) -------------------------------------------------------------------------------- /forester-graph-plugin/src/main/kotlin/com/dropbox/forester/dagger/Dependency.kt: -------------------------------------------------------------------------------- 1 | package com.dropbox.forester.dagger 2 | 3 | import kotlinx.serialization.Serializable 4 | 5 | @Serializable 6 | data class Dependency( 7 | val key: String, 8 | val kind: String, 9 | val element: String? 10 | ) -------------------------------------------------------------------------------- /android/app/src/main/kotlin/com/dropbox/forester/android/app/wiring/AppDependencies.kt: -------------------------------------------------------------------------------- 1 | package com.dropbox.forester.android.app.wiring 2 | 3 | 4 | import com.dropbox.forester.android.scoping.AppScope 5 | import com.squareup.anvil.annotations.ContributesTo 6 | 7 | @ContributesTo(AppScope::class) 8 | interface AppDependencies -------------------------------------------------------------------------------- /forester-gradle-plugin/src/main/kotlin/com/dropbox/forester/plugin/ForesterPluginExt.kt: -------------------------------------------------------------------------------- 1 | package com.dropbox.forester.plugin 2 | 3 | import org.gradle.api.tasks.Input 4 | 5 | open class ForesterPluginExt { 6 | 7 | @Input 8 | var outputDir: String? = null 9 | 10 | @Input 11 | var update: Boolean = false 12 | } -------------------------------------------------------------------------------- /forester/src/main/kotlin/com/dropbox/forester/Node.kt: -------------------------------------------------------------------------------- 1 | package com.dropbox.forester 2 | 3 | import kotlin.reflect.KClass 4 | 5 | 6 | @MustBeDocumented 7 | @Retention(AnnotationRetention.RUNTIME) 8 | annotation class Node( 9 | val scopes: Array> = [], 10 | val shape: Shape = Shape.Rectangle 11 | ) 12 | -------------------------------------------------------------------------------- /android/lib/api/src/main/kotlin/com/dropbox/forester/android/api/entity/user.kt: -------------------------------------------------------------------------------- 1 | package com.dropbox.forester.android.api.entity 2 | 3 | import kotlinx.serialization.Serializable 4 | 5 | @Serializable 6 | data class User( 7 | val id: String, 8 | val name: String, 9 | val email: String, 10 | val avatarUrl: String 11 | ) -------------------------------------------------------------------------------- /android/lib/api/src/main/kotlin/com/dropbox/forester/android/api/entity/machine.kt: -------------------------------------------------------------------------------- 1 | package com.dropbox.forester.android.api.entity 2 | 3 | import kotlinx.serialization.Serializable 4 | 5 | @Serializable 6 | data class Machine( 7 | val id: Int, 8 | val item: NamedApiResource, 9 | val move: NamedApiResource, 10 | val versionGroup: NamedApiResource 11 | ) -------------------------------------------------------------------------------- /android/feat/pokedex_tab/src/main/kotlin/com/dropbox/forester/android/feat/pokedex_tab/PokedexRepository.kt: -------------------------------------------------------------------------------- 1 | package com.dropbox.forester.android.feat.pokedex_tab 2 | 3 | import com.dropbox.forester.android.api.RequestResult 4 | import com.dropbox.forester.android.api.entity.Pokemon 5 | 6 | interface PokedexRepository { 7 | suspend fun getPokemon(id: Int): RequestResult 8 | } -------------------------------------------------------------------------------- /android/common/repository_utils/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id("com.android.library") 3 | id("org.jetbrains.kotlin.android") 4 | } 5 | 6 | android { 7 | defaultConfig { 8 | minSdk = 27 9 | } 10 | compileSdk = 33 11 | compileSdkVersion = "android-33" 12 | namespace = "com.dropbox.forester.android.repository_utils" 13 | } 14 | 15 | dependencies { 16 | } -------------------------------------------------------------------------------- /local.properties: -------------------------------------------------------------------------------- 1 | ## This file must *NOT* be checked into Version Control Systems, 2 | # as it contains information specific to your local configuration. 3 | # 4 | # Location of the SDK. This is only used by Gradle. 5 | # For customization when using a Version Control System, please read the 6 | # header note. 7 | #Sat Apr 01 15:13:34 EDT 2023 8 | sdk.dir=/Users/mramotar/Library/Android/sdk 9 | -------------------------------------------------------------------------------- /android/feat/pokedex_tab/src/main/kotlin/com/dropbox/forester/android/feat/pokedex_tab/PokedexBindings.kt: -------------------------------------------------------------------------------- 1 | package com.dropbox.forester.android.feat.pokedex_tab 2 | 3 | import com.dropbox.forester.android.scoping.UserScope 4 | import com.squareup.anvil.annotations.ContributesTo 5 | 6 | @ContributesTo(UserScope::class) 7 | interface PokedexBindings { 8 | fun inject(viewModel: PokedexViewModel) 9 | } -------------------------------------------------------------------------------- /android/lib/api/src/main/kotlin/com/dropbox/forester/android/api/RequestResult.kt: -------------------------------------------------------------------------------- 1 | package com.dropbox.forester.android.api 2 | 3 | sealed class RequestResult { 4 | data class Success( 5 | val data: Output 6 | ) : RequestResult() 7 | 8 | data class Failure( 9 | val error: Throwable 10 | ) : RequestResult() 11 | } -------------------------------------------------------------------------------- /android/lib/dig/src/main/res/drawable/activity_fill.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /android/lib/dig/src/main/res/drawable/ic_activity_fill.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /forester-gradle-plugin/src/main/kotlin/com/dropbox/forester/plugin/ForesterAnnotation.kt: -------------------------------------------------------------------------------- 1 | package com.dropbox.forester.plugin 2 | 3 | enum class ForesterAnnotation(val descriptor: String) { 4 | Node("Lcom/dropbox/forester/Node;"), 5 | Forest("Lcom/dropbox/forester/Forest;"), 6 | Graph("Lcom/dropbox/forester/Graph;"), 7 | Directed("Lcom/dropbox/forester/Directed;"), 8 | Undirected("Lcom/dropbox/forester/Undirected;") 9 | } -------------------------------------------------------------------------------- /forester-graph-plugin/src/main/kotlin/com/dropbox/forester/dagger/Component.kt: -------------------------------------------------------------------------------- 1 | package com.dropbox.forester.dagger 2 | 3 | import kotlinx.serialization.Serializable 4 | 5 | @Serializable 6 | data class Component( 7 | val key: String, 8 | val component: String?, 9 | val subcomponent: Boolean, 10 | val componentPath: List, 11 | val scopes: List?, 12 | val dependencies: List 13 | ) : Node() -------------------------------------------------------------------------------- /forester-graph-plugin/src/main/kotlin/com/dropbox/forester/dagger/Binding.kt: -------------------------------------------------------------------------------- 1 | package com.dropbox.forester.dagger 2 | 3 | import kotlinx.serialization.Serializable 4 | 5 | @Serializable 6 | data class Binding( 7 | val key: String, 8 | val kind: String, 9 | val component: String, 10 | val module: String?, 11 | val scope: String?, 12 | val dependencies: List, 13 | val adjacentNodes: List? 14 | ) : Node() -------------------------------------------------------------------------------- /android/app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #FFBB86FC 4 | #FF6200EE 5 | #FF3700B3 6 | #FF03DAC5 7 | #FF018786 8 | #FF000000 9 | #FFFFFFFF 10 | -------------------------------------------------------------------------------- /android/lib/dig/src/main/res/drawable/activity.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /android/lib/dig/src/main/res/drawable/close.xml: -------------------------------------------------------------------------------- 1 | 6 | 11 | 12 | -------------------------------------------------------------------------------- /android/lib/dig/src/main/res/drawable/chevron_right.xml: -------------------------------------------------------------------------------- 1 | 6 | 11 | 12 | -------------------------------------------------------------------------------- /android/lib/api/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id("com.android.library") 3 | id("org.jetbrains.kotlin.android") 4 | id("org.jetbrains.kotlin.plugin.serialization") 5 | } 6 | 7 | android { 8 | defaultConfig { 9 | minSdk = 27 10 | } 11 | compileSdk = 33 12 | compileSdkVersion = "android-33" 13 | namespace = "com.dropbox.forester.android.v1.api" 14 | } 15 | 16 | dependencies { 17 | implementation(libs.kotlinx.serialization.core) 18 | } -------------------------------------------------------------------------------- /android/lib/dig/src/main/res/drawable/ic_activity_line.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /forester/src/main/kotlin/com/dropbox/forester/Shape.kt: -------------------------------------------------------------------------------- 1 | package com.dropbox.forester 2 | 3 | enum class Shape { 4 | Rectangle, 5 | Square, 6 | Page, 7 | Parallelogram, 8 | Document, 9 | Cylinder, 10 | Queue, 11 | Package, 12 | Step, 13 | Callout, 14 | StoredData, 15 | Person, 16 | Diamond, 17 | Oval, 18 | Circle, 19 | Hexagon, 20 | Cloud, 21 | Text, 22 | Code, 23 | SqlTable, 24 | Image, 25 | Class, 26 | SequenceDiagram 27 | } -------------------------------------------------------------------------------- /android/lib/dig/src/main/res/drawable/dropbox.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /android/lib/dig/src/main/res/drawable/switcher.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | 13 | -------------------------------------------------------------------------------- /android/lib/dig/src/main/res/drawable/home_fill.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /android/common/scoping/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id("com.android.library") 3 | id("org.jetbrains.kotlin.android") 4 | id("kotlin-kapt") 5 | id("com.squareup.anvil") 6 | } 7 | 8 | android { 9 | 10 | defaultConfig { 11 | minSdk = 27 12 | } 13 | 14 | compileSdk = 33 15 | compileSdkVersion = "android-33" 16 | 17 | namespace = "com.dropbox.forester.android.scoping" 18 | } 19 | 20 | dependencies { 21 | implementation libs.dagger 22 | kapt libs.dagger.compiler 23 | implementation libs.androidx.appCompat 24 | implementation libs.androidx.viewmodel 25 | } -------------------------------------------------------------------------------- /android/lib/dig/src/main/kotlin/com/dropbox/forester/android/dig/typography.kt: -------------------------------------------------------------------------------- 1 | package com.dropbox.forester.android.dig 2 | 3 | import androidx.compose.material.Typography 4 | import androidx.compose.runtime.Composable 5 | import androidx.compose.runtime.ProvidableCompositionLocal 6 | import androidx.compose.runtime.ReadOnlyComposable 7 | import androidx.compose.runtime.staticCompositionLocalOf 8 | 9 | internal val LocalTypography: ProvidableCompositionLocal 10 | @ReadOnlyComposable 11 | @Composable 12 | get() { 13 | return staticCompositionLocalOf { DigTypography } 14 | } -------------------------------------------------------------------------------- /android/lib/dig/src/main/res/drawable/hashtag.xml: -------------------------------------------------------------------------------- 1 | 6 | 10 | 11 | -------------------------------------------------------------------------------- /android/lib/dig/src/main/res/drawable/search.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /android/app/src/main/kotlin/com/dropbox/forester/android/app/wiring/AppComponent.kt: -------------------------------------------------------------------------------- 1 | package com.dropbox.forester.android.app.wiring 2 | 3 | import android.content.Context 4 | import com.dropbox.forester.android.scoping.AppScope 5 | import com.dropbox.forester.android.scoping.SingleIn 6 | import com.squareup.anvil.annotations.MergeComponent 7 | import dagger.BindsInstance 8 | import dagger.Component 9 | 10 | @SingleIn(AppScope::class) 11 | @MergeComponent(AppScope::class) 12 | interface AppComponent { 13 | @Component.Factory 14 | interface Factory { 15 | fun create( 16 | @BindsInstance applicationContext: Context, 17 | ): AppComponent 18 | } 19 | } -------------------------------------------------------------------------------- /android/lib/dig/src/main/res/drawable/person_fill.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /android/lib/dig/src/main/res/drawable/clock.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | 13 | -------------------------------------------------------------------------------- /android/lib/dig/src/main/res/drawable/ic_person_fill.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /android/lib/dig/src/main/res/drawable/add_circle.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .gradle 2 | build/ 3 | !gradle/wrapper/gradle-wrapper.jar 4 | !**/src/main/**/build/ 5 | !**/src/test/**/build/ 6 | 7 | ### IntelliJ IDEA ### 8 | .idea/ 9 | .idea/modules.xml 10 | .idea/jarRepositories.xml 11 | .idea/compiler.xml 12 | .idea/libraries/ 13 | *.iws 14 | *.iml 15 | *.ipr 16 | out/ 17 | !**/src/main/**/out/ 18 | !**/src/test/**/out/ 19 | 20 | ### Eclipse ### 21 | .apt_generated 22 | .classpath 23 | .factorypath 24 | .project 25 | .settings 26 | .springBeans 27 | .sts4-cache 28 | bin/ 29 | !**/src/main/**/bin/ 30 | !**/src/test/**/bin/ 31 | 32 | ### NetBeans ### 33 | /nbproject/private/ 34 | /nbbuild/ 35 | /dist/ 36 | /nbdist/ 37 | /.nb-gradle/ 38 | 39 | ### VS Code ### 40 | .vscode/ 41 | 42 | ### Mac OS ### 43 | .DS_Store -------------------------------------------------------------------------------- /android/lib/dig/src/main/res/drawable/collection.xml: -------------------------------------------------------------------------------- 1 | 6 | 10 | 14 | 18 | 19 | -------------------------------------------------------------------------------- /android/feat/pokedex_tab/src/main/kotlin/com/dropbox/forester/android/feat/pokedex_tab/PokedexState.kt: -------------------------------------------------------------------------------- 1 | package com.dropbox.forester.android.feat.pokedex_tab 2 | 3 | import com.dropbox.forester.android.api.entity.Pokemon 4 | 5 | data class PokedexState( 6 | val viewState: PokedexViewState 7 | ) 8 | 9 | sealed class PokedexViewState { 10 | 11 | object Initial : PokedexViewState() 12 | data class Data( 13 | val pokemon: Pokemon 14 | ) : PokedexViewState() 15 | 16 | object Loading : PokedexViewState() 17 | 18 | object Failure : PokedexViewState() 19 | } 20 | 21 | val InitialState = PokedexState(PokedexViewState.Initial) 22 | val Loading = PokedexState(PokedexViewState.Loading) 23 | val Failure = PokedexState(PokedexViewState.Failure) -------------------------------------------------------------------------------- /forester/build.gradle.kts: -------------------------------------------------------------------------------- 1 | @file:Suppress("UnstableApiUsage") 2 | 3 | import com.vanniktech.maven.publish.SonatypeHost.Companion.S01 4 | 5 | plugins { 6 | id("org.jetbrains.kotlin.jvm") 7 | id("org.jetbrains.kotlin.plugin.serialization") 8 | id("com.vanniktech.maven.publish") 9 | `maven-publish` 10 | } 11 | 12 | 13 | dependencies { 14 | implementation(libs.kotlinx.serialization.core) 15 | implementation(libs.kotlinx.serialization.json) 16 | implementation("org.jetbrains.kotlin:kotlin-reflect:1.8.10") 17 | } 18 | 19 | java { 20 | sourceCompatibility = JavaVersion.VERSION_11 21 | targetCompatibility = JavaVersion.VERSION_11 22 | } 23 | 24 | mavenPublishing { 25 | publishToMavenCentral(S01) 26 | signAllPublications() 27 | } -------------------------------------------------------------------------------- /android/app/src/main/kotlin/com/dropbox/forester/android/app/ui/PokedexScaffold.kt: -------------------------------------------------------------------------------- 1 | package com.dropbox.pokedex.android.ui 2 | 3 | import androidx.compose.material.Scaffold 4 | import androidx.compose.runtime.Composable 5 | import androidx.navigation.compose.rememberNavController 6 | import com.dropbox.forester.android.app.navigation.Routing 7 | import com.dropbox.forester.android.app.ui.PokedexBottomBar 8 | 9 | @Composable 10 | fun PokedexScaffold() { 11 | 12 | val navController = rememberNavController() 13 | Scaffold( 14 | bottomBar = { PokedexBottomBar(navController = navController) } 15 | ) { innerPadding -> 16 | Routing( 17 | navController = navController, 18 | innerPadding = innerPadding 19 | ) 20 | } 21 | } -------------------------------------------------------------------------------- /android/lib/dig/src/main/kotlin/com/dropbox/forester/android/dig/color/SystemThemeColors.kt: -------------------------------------------------------------------------------- 1 | package com.dropbox.forester.android.dig.color 2 | 3 | import androidx.compose.foundation.isSystemInDarkTheme 4 | import androidx.compose.runtime.Composable 5 | import androidx.compose.runtime.ReadOnlyComposable 6 | 7 | 8 | @ReadOnlyComposable 9 | @Composable 10 | fun darkColors() = PigColors.Dark.create() 11 | 12 | @ReadOnlyComposable 13 | @Composable 14 | fun systemThemeColors() = if (isSystemInDarkTheme()) PigColors.Dark.create() else PigColors.Light.create() 15 | 16 | @ReadOnlyComposable 17 | @Composable 18 | fun systemColorScheme() = systemThemeColors().asColorScheme() 19 | 20 | @ReadOnlyComposable 21 | @Composable 22 | fun darkColorScheme() = darkColors().asColorScheme() 23 | -------------------------------------------------------------------------------- /android/lib/dig/src/main/res/drawable/home.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /settings.gradle.kts: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | google() 4 | gradlePluginPortal() 5 | mavenCentral() 6 | mavenLocal() 7 | maven("https://maven.pkg.jetbrains.space/public/p/compose/dev") 8 | } 9 | 10 | plugins { 11 | id("org.jetbrains.compose").version(extra["compose.version"] as String) 12 | } 13 | } 14 | 15 | rootProject.name = "forester" 16 | 17 | include( 18 | ":forester", 19 | ":forester-gradle-plugin", 20 | ":forester-graph-plugin", 21 | ":android:app", 22 | ":android:lib:api", 23 | ":android:lib:api:impl", 24 | ":android:common:scoping", 25 | ":android:feat:account_tab", 26 | ":android:feat:pokedex_tab", 27 | ":android:lib:dig", 28 | ":android:common:repository_utils" 29 | ) -------------------------------------------------------------------------------- /android/lib/dig/src/main/res/drawable/fail.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | 13 | -------------------------------------------------------------------------------- /android/lib/dig/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id("com.android.library") 3 | id("org.jetbrains.kotlin.android") 4 | id("kotlin-kapt") 5 | id("com.squareup.anvil") 6 | } 7 | 8 | android { 9 | 10 | buildFeatures { 11 | compose = true 12 | } 13 | composeOptions { 14 | kotlinCompilerExtensionVersion = "1.4.4" 15 | } 16 | defaultConfig { 17 | minSdk = 27 18 | } 19 | 20 | compileSdk = 33 21 | compileSdkVersion = "android-33" 22 | 23 | namespace = "com.dropbox.forester.android.dig" 24 | } 25 | 26 | dependencies { 27 | implementation libs.jetbrains.compose.material 28 | implementation libs.jetbrains.compose.ui 29 | implementation libs.androidx.compose.material3 30 | implementation(libs.dagger) 31 | kapt(libs.dagger.compiler) 32 | } -------------------------------------------------------------------------------- /android/lib/api/impl/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id("com.android.library") 3 | id("org.jetbrains.kotlin.android") 4 | id("kotlin-kapt") 5 | id("com.squareup.anvil") 6 | id("org.jetbrains.kotlin.plugin.serialization") 7 | } 8 | 9 | android { 10 | defaultConfig { 11 | minSdk = 27 12 | } 13 | compileSdk = 33 14 | compileSdkVersion = "android-33" 15 | namespace = "com.dropbox.forester.android.v1.impl" 16 | } 17 | 18 | dependencies { 19 | implementation(libs.dagger) 20 | kapt(libs.dagger.compiler) 21 | implementation(libs.kotlinx.serialization.core) 22 | implementation(libs.kotlinx.serialization.json) 23 | implementation(libs.ktor.client.core) 24 | implementation(project(":android:lib:api")) 25 | implementation(project(":android:common:scoping")) 26 | } -------------------------------------------------------------------------------- /android/lib/api/src/main/kotlin/com/dropbox/forester/android/api/entity/encounter.kt: -------------------------------------------------------------------------------- 1 | package com.dropbox.pokedex.common.entity 2 | 3 | import com.dropbox.forester.android.api.entity.Name 4 | import com.dropbox.forester.android.api.entity.NamedApiResource 5 | import kotlinx.serialization.Serializable 6 | 7 | @Serializable 8 | data class EncounterMethod( 9 | val id: Int, 10 | val name: String, 11 | val order: Int, 12 | val names: List 13 | ) 14 | 15 | @Serializable 16 | data class EncounterCondition( 17 | val id: Int, 18 | val name: String, 19 | val names: List, 20 | val values: List 21 | ) 22 | 23 | @Serializable 24 | data class EncounterConditionValue( 25 | val id: Int, 26 | val name: String, 27 | val condition: NamedApiResource, 28 | val names: List 29 | ) -------------------------------------------------------------------------------- /android/feat/pokedex_tab/src/main/kotlin/com/dropbox/forester/android/feat/pokedex_tab/PokedexComponent.kt: -------------------------------------------------------------------------------- 1 | package com.dropbox.forester.android.feat.pokedex_tab 2 | 3 | import com.dropbox.forester.android.scoping.AppScope 4 | import com.dropbox.forester.android.scoping.SingleIn 5 | import com.dropbox.forester.android.scoping.UserScope 6 | import com.squareup.anvil.annotations.ContributesSubcomponent 7 | import com.squareup.anvil.annotations.ContributesTo 8 | 9 | 10 | @SingleIn(UserScope::class) 11 | @ContributesSubcomponent(scope = UserScope::class, parentScope = AppScope::class) 12 | interface PokedexComponent { 13 | @ContributesSubcomponent.Factory 14 | interface Factory { 15 | fun create(): PokedexComponent 16 | } 17 | 18 | @ContributesTo(AppScope::class) 19 | interface ParentBindings { 20 | fun pokedexComponentBuilder(): Factory 21 | } 22 | } -------------------------------------------------------------------------------- /android/lib/dig/src/main/res/drawable/sort_type.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | 15 | 16 | -------------------------------------------------------------------------------- /android/feat/pokedex_tab/src/main/kotlin/com/dropbox/forester/android/feat/pokedex_tab/RealPokedexRepository.kt: -------------------------------------------------------------------------------- 1 | package com.dropbox.forester.android.feat.pokedex_tab 2 | 3 | import com.dropbox.forester.android.api.PokeApi 4 | import com.dropbox.forester.android.api.RequestResult 5 | import com.dropbox.forester.android.api.entity.Pokemon 6 | import com.dropbox.forester.android.scoping.AppScope 7 | import com.squareup.anvil.annotations.ContributesBinding 8 | import javax.inject.Inject 9 | 10 | @ContributesBinding(AppScope::class) 11 | class RealPokedexRepository @Inject constructor(private val api: PokeApi) : PokedexRepository { 12 | override suspend fun getPokemon(id: Int): RequestResult = try { 13 | RequestResult.Success(api.getPokemon(id)) 14 | } catch (error: Throwable) { 15 | println("ERROR = $error") 16 | RequestResult.Failure(error) 17 | } 18 | } -------------------------------------------------------------------------------- /android/lib/dig/src/main/kotlin/com/dropbox/forester/android/dig/color/LocalColors.kt: -------------------------------------------------------------------------------- 1 | package com.dropbox.forester.android.dig.color 2 | 3 | import androidx.compose.material3.ColorScheme 4 | import androidx.compose.runtime.Composable 5 | import androidx.compose.runtime.ProvidableCompositionLocal 6 | import androidx.compose.runtime.ReadOnlyComposable 7 | import androidx.compose.runtime.staticCompositionLocalOf 8 | 9 | internal val LocalColors: ProvidableCompositionLocal 10 | @ReadOnlyComposable 11 | @Composable 12 | get() { 13 | val colors = systemThemeColors() 14 | return staticCompositionLocalOf { colors } 15 | } 16 | 17 | internal val LocalColorScheme: ProvidableCompositionLocal 18 | @ReadOnlyComposable 19 | @Composable 20 | get() { 21 | val colorScheme = systemColorScheme() 22 | return staticCompositionLocalOf { colorScheme } 23 | } -------------------------------------------------------------------------------- /android/lib/dig/src/main/res/drawable/person.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /android/app/src/main/kotlin/com/dropbox/forester/android/app/PokedexMainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.dropbox.forester.android.app 2 | 3 | import android.os.Bundle 4 | import androidx.activity.ComponentActivity 5 | import androidx.activity.compose.setContent 6 | import com.dropbox.forester.android.dig.DigTheme 7 | import com.dropbox.forester.android.dig.color.systemThemeColors 8 | import com.dropbox.pokedex.android.ui.PokedexScaffold 9 | import kotlinx.coroutines.CoroutineScope 10 | import kotlinx.coroutines.Dispatchers.Main 11 | 12 | class PokedexMainActivity : ComponentActivity() { 13 | 14 | private val scope: CoroutineScope = CoroutineScope(Main) 15 | 16 | override fun onCreate(savedInstanceState: Bundle?) { 17 | super.onCreate(savedInstanceState) 18 | setContent { 19 | DigTheme(systemThemeColors()) { 20 | PokedexScaffold() 21 | } 22 | } 23 | } 24 | } 25 | 26 | -------------------------------------------------------------------------------- /android/lib/dig/src/main/kotlin/com/dropbox/forester/android/dig/Dig.kt: -------------------------------------------------------------------------------- 1 | package com.dropbox.forester.android.dig 2 | 3 | 4 | import androidx.compose.material.Typography 5 | import androidx.compose.material3.ColorScheme 6 | import androidx.compose.runtime.Composable 7 | import androidx.compose.runtime.ReadOnlyComposable 8 | import com.dropbox.forester.android.dig.color.Colors 9 | import com.dropbox.forester.android.dig.color.LocalColors 10 | import com.dropbox.forester.android.dig.color.asColorScheme 11 | 12 | 13 | object Dig { 14 | val Colors: Colors 15 | @Composable 16 | @ReadOnlyComposable 17 | get() = LocalColors.current 18 | 19 | val ColorScheme: ColorScheme 20 | @Composable 21 | @ReadOnlyComposable 22 | get() = Colors.asColorScheme() 23 | 24 | val Typography: Typography 25 | @Composable 26 | @ReadOnlyComposable 27 | get() = LocalTypography.current 28 | } -------------------------------------------------------------------------------- /forester-graph-plugin/build.gradle.kts: -------------------------------------------------------------------------------- 1 | @file:Suppress("UnstableApiUsage") 2 | 3 | plugins { 4 | id("org.jetbrains.kotlin.jvm") 5 | id("org.jetbrains.kotlin.plugin.serialization") 6 | id("java-gradle-plugin") 7 | } 8 | 9 | dependencies { 10 | compileOnly(gradleApi()) 11 | implementation(libs.kotlin.gradle.plugin) 12 | compileOnly(libs.android.gradle.plugin) 13 | implementation(libs.kotlinx.serialization.core) 14 | implementation(libs.kotlinx.serialization.json) 15 | implementation("org.jetbrains.kotlin:kotlin-reflect:1.8.10") 16 | implementation(project(":forester")) 17 | implementation(libs.dagger) 18 | implementation(libs.dagger.spi) 19 | } 20 | 21 | tasks { 22 | compileKotlin { 23 | kotlinOptions { 24 | jvmTarget = "11" 25 | } 26 | } 27 | compileTestKotlin { 28 | kotlinOptions { 29 | jvmTarget = "11" 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /android/app/src/main/kotlin/com/dropbox/forester/android/app/PokedexApp.kt: -------------------------------------------------------------------------------- 1 | package com.dropbox.forester.android.app 2 | 3 | import android.app.Application 4 | import com.dropbox.forester.android.app.wiring.AppComponent 5 | import com.dropbox.forester.android.app.wiring.DaggerAppComponent 6 | import com.dropbox.forester.android.scoping.AppScope 7 | import com.dropbox.forester.android.scoping.ComponentHolder 8 | import com.dropbox.forester.android.scoping.SingleIn 9 | import com.squareup.anvil.annotations.ContributesBinding 10 | import javax.inject.Inject 11 | 12 | @SingleIn(AppScope::class) 13 | @ContributesBinding(AppScope::class, boundType = Application::class) 14 | class PokedexApp @Inject constructor() : Application(), ComponentHolder { 15 | override lateinit var component: AppComponent 16 | 17 | override fun onCreate() { 18 | component = DaggerAppComponent.factory().create(applicationContext) 19 | super.onCreate() 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | kotlin.code.style=official 2 | kotlin.native.enableDependencyPropagation=false 3 | android.useAndroidX=true 4 | kotlin.version=1.8.10 5 | agp.version=7.3.0 6 | compose.version=1.3.1 7 | org.gradle.jvmargs=-Xmx4096m 8 | 9 | GROUP=com.dropbox.forester 10 | VERSION_NAME=0.0.1-alpha02 11 | 12 | POM_DESCRIPTION=Mapping out the forest 13 | POM_PACKAGING= pom 14 | 15 | POM_URL=https://github.com/dropbox/forester 16 | POM_SCM_URL=https://github.com/dropbox/forester 17 | POM_SCM_CONNECTION=scm:git:git://github.com/dropbox/forester.git 18 | POM_SCM_DEV_CONNECTION=scm:git:ssh://git@github.com/dropbox/forester.git 19 | 20 | POM_LICENCE_NAME=The Apache Software License, Version 2.0 21 | POM_LICENCE_URL=https://www.apache.org/licenses/LICENSE-2.0.txt 22 | POM_LICENCE_DIST=repo 23 | 24 | POM_DEVELOPER_ID=dropbox 25 | POM_DEVELOPER_NAME=Dropbox, Inc. 26 | POM_DEVELOPER_URL=https://github.com/dropbox 27 | 28 | kotlin.mpp.enableGranularSourceSetsMetadata=true 29 | -------------------------------------------------------------------------------- /android/lib/dig/src/main/res/drawable/apps.xml: -------------------------------------------------------------------------------- 1 | 6 | 10 | 11 | -------------------------------------------------------------------------------- /android/app/src/main/kotlin/com/dropbox/forester/android/app/wiring/UserComponent.kt: -------------------------------------------------------------------------------- 1 | package com.dropbox.forester.android.app.wiring 2 | 3 | import com.dropbox.forester.android.api.entity.User 4 | import com.dropbox.forester.android.scoping.AppScope 5 | import com.dropbox.forester.android.scoping.SingleIn 6 | import com.dropbox.forester.android.scoping.UserScope 7 | import com.squareup.anvil.annotations.ContributesSubcomponent 8 | import com.squareup.anvil.annotations.ContributesTo 9 | import dagger.BindsInstance 10 | 11 | @SingleIn(UserScope::class) 12 | @ContributesSubcomponent(scope = UserScope::class, parentScope = AppScope::class) 13 | interface UserComponent { 14 | @ContributesSubcomponent.Factory 15 | interface Factory { 16 | fun create( 17 | @BindsInstance user: User 18 | ): UserComponent 19 | } 20 | 21 | @ContributesTo(AppScope::class) 22 | interface ParentBindings { 23 | fun userComponentFactory(): Factory 24 | } 25 | } -------------------------------------------------------------------------------- /android/app/src/main/kotlin/com/dropbox/forester/android/app/wiring/AppModule.kt: -------------------------------------------------------------------------------- 1 | package com.dropbox.forester.android.app.wiring 2 | 3 | import com.dropbox.forester.android.scoping.AppScope 4 | import com.dropbox.forester.android.scoping.SingleIn 5 | import com.squareup.anvil.annotations.ContributesTo 6 | import dagger.Module 7 | import dagger.Provides 8 | import io.ktor.client.* 9 | import io.ktor.client.engine.cio.* 10 | import io.ktor.client.plugins.contentnegotiation.* 11 | import io.ktor.serialization.kotlinx.json.* 12 | import kotlinx.serialization.json.Json 13 | 14 | @Module 15 | @ContributesTo(AppScope::class) 16 | object AppModule { 17 | @Provides 18 | @SingleIn(AppScope::class) 19 | fun provideHttpClient(): HttpClient { 20 | return HttpClient(CIO) { 21 | install(ContentNegotiation) { 22 | json(json = Json { 23 | ignoreUnknownKeys = true 24 | isLenient = true 25 | }) 26 | } 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /android/app/src/main/res/values/theme.xml: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 16 | 17 |