├── examples
├── search
│ ├── .gitignore
│ ├── src
│ │ ├── main
│ │ │ ├── res
│ │ │ │ ├── mipmap-hdpi
│ │ │ │ │ ├── ic_launcher.png
│ │ │ │ │ └── ic_launcher_round.png
│ │ │ │ ├── mipmap-mdpi
│ │ │ │ │ ├── ic_launcher.png
│ │ │ │ │ └── ic_launcher_round.png
│ │ │ │ ├── mipmap-xhdpi
│ │ │ │ │ ├── ic_launcher.png
│ │ │ │ │ └── ic_launcher_round.png
│ │ │ │ ├── mipmap-xxhdpi
│ │ │ │ │ ├── ic_launcher.png
│ │ │ │ │ └── ic_launcher_round.png
│ │ │ │ ├── mipmap-xxxhdpi
│ │ │ │ │ ├── ic_launcher.png
│ │ │ │ │ └── ic_launcher_round.png
│ │ │ │ ├── values
│ │ │ │ │ ├── colors.xml
│ │ │ │ │ ├── styles.xml
│ │ │ │ │ └── strings.xml
│ │ │ │ ├── mipmap-anydpi-v26
│ │ │ │ │ ├── ic_launcher.xml
│ │ │ │ │ └── ic_launcher_round.xml
│ │ │ │ ├── drawable
│ │ │ │ │ ├── ic_baseline_add_24.xml
│ │ │ │ │ ├── ic_baseline_search_24.xml
│ │ │ │ │ └── ic_launcher_background.xml
│ │ │ │ ├── layout
│ │ │ │ │ ├── location_item.xml
│ │ │ │ │ └── search_activity.xml
│ │ │ │ └── drawable-v24
│ │ │ │ │ └── ic_launcher_foreground.xml
│ │ │ ├── kotlin
│ │ │ │ └── composablearchitecture
│ │ │ │ │ └── example
│ │ │ │ │ └── search
│ │ │ │ │ ├── SearchApp.kt
│ │ │ │ │ ├── LocalDateAdapter.kt
│ │ │ │ │ ├── SearchActivity.kt
│ │ │ │ │ ├── SearchAdapter.kt
│ │ │ │ │ ├── ComposeSearchActivity.kt
│ │ │ │ │ ├── WeatherClient.kt
│ │ │ │ │ └── Search.kt
│ │ │ └── AndroidManifest.xml
│ │ ├── androidTest
│ │ │ └── kotlin
│ │ │ │ └── composablearchitecture
│ │ │ │ └── example
│ │ │ │ └── search
│ │ │ │ └── ExampleInstrumentedTest.kt
│ │ └── test
│ │ │ └── kotlin
│ │ │ └── composablearchitecture
│ │ │ └── example
│ │ │ └── search
│ │ │ ├── Mocks.kt
│ │ │ ├── LiveStoreTests.kt
│ │ │ └── SearchTests.kt
│ ├── proguard-rules.pro
│ └── build.gradle.kts
├── todos
│ ├── .gitignore
│ ├── src
│ │ ├── main
│ │ │ ├── res
│ │ │ │ ├── values
│ │ │ │ │ ├── strings.xml
│ │ │ │ │ ├── colors.xml
│ │ │ │ │ └── styles.xml
│ │ │ │ ├── mipmap-hdpi
│ │ │ │ │ ├── ic_launcher.png
│ │ │ │ │ └── ic_launcher_round.png
│ │ │ │ ├── mipmap-mdpi
│ │ │ │ │ ├── ic_launcher.png
│ │ │ │ │ └── ic_launcher_round.png
│ │ │ │ ├── mipmap-xhdpi
│ │ │ │ │ ├── ic_launcher.png
│ │ │ │ │ └── ic_launcher_round.png
│ │ │ │ ├── mipmap-xxhdpi
│ │ │ │ │ ├── ic_launcher.png
│ │ │ │ │ └── ic_launcher_round.png
│ │ │ │ ├── mipmap-xxxhdpi
│ │ │ │ │ ├── ic_launcher.png
│ │ │ │ │ └── ic_launcher_round.png
│ │ │ │ ├── mipmap-anydpi-v26
│ │ │ │ │ ├── ic_launcher.xml
│ │ │ │ │ └── ic_launcher_round.xml
│ │ │ │ ├── drawable
│ │ │ │ │ ├── ic_baseline_add_24.xml
│ │ │ │ │ └── ic_launcher_background.xml
│ │ │ │ ├── menu
│ │ │ │ │ └── todos_menu.xml
│ │ │ │ ├── layout
│ │ │ │ │ ├── todos_activity.xml
│ │ │ │ │ └── todo_item.xml
│ │ │ │ └── drawable-v24
│ │ │ │ │ └── ic_launcher_foreground.xml
│ │ │ ├── kotlin
│ │ │ │ └── composablearchitecture
│ │ │ │ │ └── example
│ │ │ │ │ └── todos
│ │ │ │ │ ├── TodosApp.kt
│ │ │ │ │ ├── TodosActivity.kt
│ │ │ │ │ ├── TodoAdapter.kt
│ │ │ │ │ └── Todos.kt
│ │ │ └── AndroidManifest.xml
│ │ ├── androidTest
│ │ │ └── kotlin
│ │ │ │ └── composablearchitecture
│ │ │ │ └── example
│ │ │ │ └── todos
│ │ │ │ └── ExampleInstrumentedTest.kt
│ │ └── test
│ │ │ └── kotlin
│ │ │ └── composablearchitecture
│ │ │ └── example
│ │ │ └── todos
│ │ │ ├── TodosSandbox.kt
│ │ │ └── TodosTest.kt
│ ├── build.gradle.kts
│ └── proguard-rules.pro
├── case-studies
│ ├── .gitignore
│ ├── src
│ │ ├── main
│ │ │ ├── res
│ │ │ │ ├── values
│ │ │ │ │ ├── strings.xml
│ │ │ │ │ ├── colors.xml
│ │ │ │ │ └── styles.xml
│ │ │ │ ├── mipmap-hdpi
│ │ │ │ │ ├── ic_launcher.png
│ │ │ │ │ └── ic_launcher_round.png
│ │ │ │ ├── mipmap-mdpi
│ │ │ │ │ ├── ic_launcher.png
│ │ │ │ │ └── ic_launcher_round.png
│ │ │ │ ├── mipmap-xhdpi
│ │ │ │ │ ├── ic_launcher.png
│ │ │ │ │ └── ic_launcher_round.png
│ │ │ │ ├── mipmap-xxhdpi
│ │ │ │ │ ├── ic_launcher.png
│ │ │ │ │ └── ic_launcher_round.png
│ │ │ │ ├── mipmap-xxxhdpi
│ │ │ │ │ ├── ic_launcher.png
│ │ │ │ │ └── ic_launcher_round.png
│ │ │ │ ├── drawable
│ │ │ │ │ ├── circle.xml
│ │ │ │ │ └── ic_launcher_background.xml
│ │ │ │ ├── mipmap-anydpi-v26
│ │ │ │ │ ├── ic_launcher.xml
│ │ │ │ │ └── ic_launcher_round.xml
│ │ │ │ ├── layout
│ │ │ │ │ └── main_activity.xml
│ │ │ │ └── drawable-v24
│ │ │ │ │ └── ic_launcher_foreground.xml
│ │ │ ├── kotlin
│ │ │ │ └── composablearchitecture
│ │ │ │ │ └── example
│ │ │ │ │ └── casestudies
│ │ │ │ │ ├── CaseStudiesApp.kt
│ │ │ │ │ └── AnimationActivity.kt
│ │ │ └── AndroidManifest.xml
│ │ └── androidTest
│ │ │ └── kotlin
│ │ │ └── composablearchitecture
│ │ │ └── example
│ │ │ └── casestudies
│ │ │ └── ExampleInstrumentedTest.kt
│ ├── build.gradle.kts
│ └── proguard-rules.pro
└── tic-tac-toe
│ ├── .gitignore
│ ├── src
│ ├── main
│ │ ├── res
│ │ │ ├── values
│ │ │ │ ├── strings.xml
│ │ │ │ ├── colors.xml
│ │ │ │ └── styles.xml
│ │ │ ├── mipmap-hdpi
│ │ │ │ ├── ic_launcher.png
│ │ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-mdpi
│ │ │ │ ├── ic_launcher.png
│ │ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-xhdpi
│ │ │ │ ├── ic_launcher.png
│ │ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-xxhdpi
│ │ │ │ ├── ic_launcher.png
│ │ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-xxxhdpi
│ │ │ │ ├── ic_launcher.png
│ │ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-anydpi-v26
│ │ │ │ ├── ic_launcher.xml
│ │ │ │ └── ic_launcher_round.xml
│ │ │ ├── drawable
│ │ │ │ ├── ic_baseline_add_24.xml
│ │ │ │ └── ic_launcher_background.xml
│ │ │ ├── drawable-v24
│ │ │ │ └── ic_launcher_foreground.xml
│ │ │ └── layout
│ │ │ │ └── tictactoe_activity.xml
│ │ ├── kotlin
│ │ │ └── composablearchitecture
│ │ │ │ └── example
│ │ │ │ └── tictactoe
│ │ │ │ ├── Array+Helpers.kt
│ │ │ │ ├── TicTacToeApp.kt
│ │ │ │ ├── TicTacToeActivity.kt
│ │ │ │ └── TicTacToe.kt
│ │ └── AndroidManifest.xml
│ ├── test
│ │ └── kotlin
│ │ │ └── composablearchitecture
│ │ │ └── example
│ │ │ └── tictactoe
│ │ │ ├── ExampleUnitTest.kt
│ │ │ └── TicTacToeTest.kt
│ └── androidTest
│ │ └── kotlin
│ │ └── composablearchitecture
│ │ └── example
│ │ └── tictactoe
│ │ └── ExampleInstrumentedTest.kt
│ ├── build.gradle.kts
│ └── proguard-rules.pro
├── composable-architecture-android
├── .gitignore
├── src
│ └── main
│ │ ├── AndroidManifest.xml
│ │ └── kotlin
│ │ └── composablearchitecture
│ │ └── android
│ │ └── ScopedViewModel.kt
└── build.gradle.kts
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── composable-architecture
├── src
│ ├── main
│ │ └── kotlin
│ │ │ └── composablearchitecture
│ │ │ ├── Helpers.kt
│ │ │ ├── Reducer+Debug.kt
│ │ │ ├── ArrowOptics+Helpers.kt
│ │ │ ├── Effect.kt
│ │ │ ├── Effect+Cancellation.kt
│ │ │ ├── Store.kt
│ │ │ └── Reducer.kt
│ └── test
│ │ └── kotlin
│ │ └── composablearchitecture
│ │ └── sandbox
│ │ ├── optional
│ │ └── Sandbox.kt
│ │ └── Sandbox.kt
└── build.gradle.kts
├── settings.gradle.kts
├── composable-architecture-test
├── build.gradle.kts
└── src
│ └── main
│ └── kotlin
│ └── composablearchitecture
│ └── test
│ ├── TestExecutorService.kt
│ └── TestStore.kt
├── gradle.properties
├── LICENSE
├── .gitignore
├── gradlew.bat
├── README.md
└── gradlew
/examples/search/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/examples/todos/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/examples/case-studies/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/examples/tic-tac-toe/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/composable-architecture-android/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/examples/tic-tac-toe/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Tic Tac Toe
3 |
4 |
--------------------------------------------------------------------------------
/examples/case-studies/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Case Studies
3 |
4 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wearemakery/kotlin-composable-architecture/HEAD/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/composable-architecture-android/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/examples/todos/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Todos
3 | new todo
4 |
5 |
--------------------------------------------------------------------------------
/examples/todos/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wearemakery/kotlin-composable-architecture/HEAD/examples/todos/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/examples/todos/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wearemakery/kotlin-composable-architecture/HEAD/examples/todos/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/examples/search/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wearemakery/kotlin-composable-architecture/HEAD/examples/search/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/examples/search/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wearemakery/kotlin-composable-architecture/HEAD/examples/search/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/examples/search/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wearemakery/kotlin-composable-architecture/HEAD/examples/search/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/examples/todos/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wearemakery/kotlin-composable-architecture/HEAD/examples/todos/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/examples/todos/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wearemakery/kotlin-composable-architecture/HEAD/examples/todos/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/examples/search/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wearemakery/kotlin-composable-architecture/HEAD/examples/search/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/examples/search/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wearemakery/kotlin-composable-architecture/HEAD/examples/search/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/examples/todos/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wearemakery/kotlin-composable-architecture/HEAD/examples/todos/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/examples/case-studies/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wearemakery/kotlin-composable-architecture/HEAD/examples/case-studies/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/examples/case-studies/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wearemakery/kotlin-composable-architecture/HEAD/examples/case-studies/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/examples/search/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wearemakery/kotlin-composable-architecture/HEAD/examples/search/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/examples/search/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wearemakery/kotlin-composable-architecture/HEAD/examples/search/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/examples/tic-tac-toe/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wearemakery/kotlin-composable-architecture/HEAD/examples/tic-tac-toe/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/examples/tic-tac-toe/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wearemakery/kotlin-composable-architecture/HEAD/examples/tic-tac-toe/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/examples/tic-tac-toe/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wearemakery/kotlin-composable-architecture/HEAD/examples/tic-tac-toe/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/examples/todos/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wearemakery/kotlin-composable-architecture/HEAD/examples/todos/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/examples/todos/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wearemakery/kotlin-composable-architecture/HEAD/examples/todos/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/examples/todos/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wearemakery/kotlin-composable-architecture/HEAD/examples/todos/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/examples/case-studies/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wearemakery/kotlin-composable-architecture/HEAD/examples/case-studies/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/examples/case-studies/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wearemakery/kotlin-composable-architecture/HEAD/examples/case-studies/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/examples/case-studies/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wearemakery/kotlin-composable-architecture/HEAD/examples/case-studies/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/examples/search/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wearemakery/kotlin-composable-architecture/HEAD/examples/search/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/examples/search/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wearemakery/kotlin-composable-architecture/HEAD/examples/search/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/examples/search/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wearemakery/kotlin-composable-architecture/HEAD/examples/search/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/examples/tic-tac-toe/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wearemakery/kotlin-composable-architecture/HEAD/examples/tic-tac-toe/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/examples/tic-tac-toe/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wearemakery/kotlin-composable-architecture/HEAD/examples/tic-tac-toe/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/examples/todos/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wearemakery/kotlin-composable-architecture/HEAD/examples/todos/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/examples/todos/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wearemakery/kotlin-composable-architecture/HEAD/examples/todos/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/examples/tic-tac-toe/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wearemakery/kotlin-composable-architecture/HEAD/examples/tic-tac-toe/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/examples/tic-tac-toe/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wearemakery/kotlin-composable-architecture/HEAD/examples/tic-tac-toe/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/examples/case-studies/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wearemakery/kotlin-composable-architecture/HEAD/examples/case-studies/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/examples/case-studies/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wearemakery/kotlin-composable-architecture/HEAD/examples/case-studies/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/examples/case-studies/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wearemakery/kotlin-composable-architecture/HEAD/examples/case-studies/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/examples/case-studies/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wearemakery/kotlin-composable-architecture/HEAD/examples/case-studies/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/examples/tic-tac-toe/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wearemakery/kotlin-composable-architecture/HEAD/examples/tic-tac-toe/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/examples/tic-tac-toe/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wearemakery/kotlin-composable-architecture/HEAD/examples/tic-tac-toe/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/examples/tic-tac-toe/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wearemakery/kotlin-composable-architecture/HEAD/examples/tic-tac-toe/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/examples/todos/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | id("shared-android")
3 | }
4 |
5 | android {
6 | defaultConfig {
7 | applicationId = "composablearchitecture.example.todos"
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/examples/case-studies/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wearemakery/kotlin-composable-architecture/HEAD/examples/case-studies/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/examples/tic-tac-toe/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | id("shared-android")
3 | }
4 |
5 | android {
6 | defaultConfig {
7 | applicationId = "composablearchitecture.example.tictactoe"
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/examples/tic-tac-toe/src/main/kotlin/composablearchitecture/example/tictactoe/Array+Helpers.kt:
--------------------------------------------------------------------------------
1 | package composablearchitecture.example.tictactoe
2 |
3 | inline fun Array>.copy() = map { it.clone() }.toTypedArray()
4 |
--------------------------------------------------------------------------------
/composable-architecture/src/main/kotlin/composablearchitecture/Helpers.kt:
--------------------------------------------------------------------------------
1 | package composablearchitecture
2 |
3 | fun Iterable.update(index: Int, elem: E) =
4 | mapIndexed { i, existing -> if (i == index) elem else existing }
5 |
--------------------------------------------------------------------------------
/examples/case-studies/src/main/kotlin/composablearchitecture/example/casestudies/CaseStudiesApp.kt:
--------------------------------------------------------------------------------
1 | package composablearchitecture.example.casestudies
2 |
3 | import android.app.Application
4 |
5 | class CaseStudiesApp : Application()
6 |
--------------------------------------------------------------------------------
/examples/case-studies/src/main/res/drawable/circle.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.1.1-bin.zip
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 |
--------------------------------------------------------------------------------
/examples/search/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #6200EE
4 | #3700B3
5 | #03DAC5
6 |
7 |
--------------------------------------------------------------------------------
/examples/todos/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #6200EE
4 | #3700B3
5 | #03DAC5
6 |
7 |
--------------------------------------------------------------------------------
/examples/case-studies/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #6200EE
4 | #3700B3
5 | #03DAC5
6 |
7 |
--------------------------------------------------------------------------------
/examples/tic-tac-toe/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #6200EE
4 | #3700B3
5 | #03DAC5
6 | #BBBBBB
7 |
8 |
--------------------------------------------------------------------------------
/settings.gradle.kts:
--------------------------------------------------------------------------------
1 | include(
2 | ":composable-architecture",
3 | ":composable-architecture-android",
4 | ":composable-architecture-test",
5 | ":examples:case-studies",
6 | ":examples:search",
7 | ":examples:tic-tac-toe",
8 | ":examples:todos"
9 | )
10 |
11 | rootProject.name = "composable-architecture"
12 |
--------------------------------------------------------------------------------
/examples/search/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/examples/todos/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/examples/case-studies/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/examples/search/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/examples/tic-tac-toe/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/examples/todos/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/examples/case-studies/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | id("shared-android")
3 | }
4 |
5 | android {
6 | defaultConfig {
7 | applicationId = "composablearchitecture.example.casestudies"
8 | }
9 | }
10 |
11 | dependencies {
12 | implementation("androidx.dynamicanimation:dynamicanimation:$androidxDynamicAnimationVersion")
13 | }
14 |
--------------------------------------------------------------------------------
/examples/case-studies/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/examples/tic-tac-toe/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/examples/tic-tac-toe/src/test/kotlin/composablearchitecture/example/tictactoe/ExampleUnitTest.kt:
--------------------------------------------------------------------------------
1 | package composablearchitecture.example.tictactoe
2 |
3 | import org.junit.Assert.assertEquals
4 | import org.junit.Test
5 |
6 | class ExampleUnitTest {
7 |
8 | @Test
9 | fun `Example test`() {
10 | assertEquals(2 + 2, 4)
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/examples/search/src/main/res/drawable/ic_baseline_add_24.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/examples/todos/src/main/res/drawable/ic_baseline_add_24.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/examples/tic-tac-toe/src/main/res/drawable/ic_baseline_add_24.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/composable-architecture-test/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | id("kotlin")
3 | }
4 |
5 | dependencies {
6 | implementation("io.arrow-kt:arrow-optics:$arrowVersion")
7 | implementation("org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion")
8 | implementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:$coroutinesVersion")
9 | implementation(project(":composable-architecture"))
10 | }
11 |
--------------------------------------------------------------------------------
/composable-architecture/src/main/kotlin/composablearchitecture/Reducer+Debug.kt:
--------------------------------------------------------------------------------
1 | package composablearchitecture
2 |
3 | @Suppress("unused")
4 | fun Reducer.debug(): Reducer =
5 | Reducer { state, action, environment ->
6 | val result = run(state, action, environment)
7 | println("state=${result.state}, action=$action")
8 | result
9 | }
10 |
--------------------------------------------------------------------------------
/examples/todos/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/examples/search/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/examples/case-studies/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/examples/search/src/main/kotlin/composablearchitecture/example/search/SearchApp.kt:
--------------------------------------------------------------------------------
1 | package composablearchitecture.example.search
2 |
3 | import android.app.Application
4 | import composablearchitecture.Store
5 |
6 | @Suppress("unused")
7 | class SearchApp : Application() {
8 |
9 | companion object {
10 | val store = Store(
11 | SearchState(),
12 | searchReducer,
13 | SearchEnvironment()
14 | )
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/examples/tic-tac-toe/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/examples/search/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Search
3 | This application demonstrates live-searching with the Composable Architecture. As you type the\nevents are debounced for 300ms, and when you stop typing an API request is made to load\nlocations. Then tapping on a location will load weather.
4 | New York, San Francisco, …
5 | Weather API provided by MetaWeather.com
6 |
7 |
--------------------------------------------------------------------------------
/examples/todos/src/main/res/menu/todos_menu.xml:
--------------------------------------------------------------------------------
1 |
2 |
14 |
--------------------------------------------------------------------------------
/composable-architecture/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | id("kotlin")
3 | id("kotlin-kapt")
4 | }
5 |
6 | dependencies {
7 | implementation("io.arrow-kt:arrow-optics:$arrowVersion")
8 | implementation("org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion")
9 | implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutinesVersion")
10 | kaptTest("io.arrow-kt:arrow-meta:$arrowVersion")
11 | testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:$coroutinesVersion")
12 | testImplementation(project(":composable-architecture-test"))
13 | }
14 |
--------------------------------------------------------------------------------
/examples/search/src/main/res/drawable/ic_baseline_search_24.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/examples/search/src/main/kotlin/composablearchitecture/example/search/LocalDateAdapter.kt:
--------------------------------------------------------------------------------
1 | package composablearchitecture.example.search
2 |
3 | import com.squareup.moshi.FromJson
4 | import com.squareup.moshi.ToJson
5 | import java.time.LocalDate
6 | import java.time.format.DateTimeFormatter
7 |
8 | object LocalDateAdapter {
9 |
10 | private val formatter = DateTimeFormatter.ISO_LOCAL_DATE
11 |
12 | @FromJson
13 | fun fromJson(json: String): LocalDate = LocalDate.parse(json, formatter)
14 |
15 | @ToJson
16 | fun toJson(date: LocalDate): String = formatter.format(date)
17 | }
18 |
--------------------------------------------------------------------------------
/examples/tic-tac-toe/src/main/kotlin/composablearchitecture/example/tictactoe/TicTacToeApp.kt:
--------------------------------------------------------------------------------
1 | package composablearchitecture.example.tictactoe
2 |
3 | import android.app.Application
4 | import composablearchitecture.Store
5 |
6 | @Suppress("unused")
7 | class TicTacToeApp : Application() {
8 |
9 | companion object {
10 | val gameStore = Store(
11 | initialState = GameState(),
12 | reducer = gameReducer,
13 | environment = GameEnvironment
14 | )
15 | }
16 |
17 | override fun onCreate() {
18 | super.onCreate()
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/composable-architecture-android/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | id("com.android.library")
3 | id("kotlin-android")
4 | }
5 |
6 | android {
7 | compileSdkVersion(androidCompileSdkVersion)
8 | sourceSets["main"].java.srcDir("src/main/kotlin")
9 | }
10 |
11 | dependencies {
12 | implementation("androidx.lifecycle:lifecycle-livedata-ktx:$androidxLifecycleVersion")
13 | implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:$androidxLifecycleVersion")
14 | implementation("io.arrow-kt:arrow-optics:$arrowVersion")
15 | implementation(project(":composable-architecture"))
16 | }
17 |
--------------------------------------------------------------------------------
/examples/todos/src/androidTest/kotlin/composablearchitecture/example/todos/ExampleInstrumentedTest.kt:
--------------------------------------------------------------------------------
1 | package composablearchitecture.example.todos
2 |
3 | import androidx.test.ext.junit.runners.AndroidJUnit4
4 | import androidx.test.platform.app.InstrumentationRegistry
5 | import org.junit.Assert.assertEquals
6 | import org.junit.Test
7 | import org.junit.runner.RunWith
8 |
9 | @RunWith(AndroidJUnit4::class)
10 | class ExampleInstrumentedTest {
11 | @Test
12 | fun useAppContext() {
13 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext
14 | assertEquals("composablearchitecture.example.todos", appContext.packageName)
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/examples/todos/src/main/kotlin/composablearchitecture/example/todos/TodosApp.kt:
--------------------------------------------------------------------------------
1 | package composablearchitecture.example.todos
2 |
3 | import android.app.Application
4 | import composablearchitecture.Store
5 | import java.util.UUID
6 |
7 | @Suppress("unused")
8 | class TodosApp : Application() {
9 |
10 | companion object {
11 | lateinit var store: Store
12 | }
13 |
14 | override fun onCreate() {
15 | super.onCreate()
16 | store = Store(
17 | initialState = AppState(),
18 | reducer = appReducer,
19 | environment = AppEnvironment(uuid = { UUID.randomUUID() })
20 | )
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/examples/search/src/androidTest/kotlin/composablearchitecture/example/search/ExampleInstrumentedTest.kt:
--------------------------------------------------------------------------------
1 | package composablearchitecture.example.search
2 |
3 | import androidx.test.ext.junit.runners.AndroidJUnit4
4 | import androidx.test.platform.app.InstrumentationRegistry
5 | import org.junit.Assert.assertEquals
6 | import org.junit.Test
7 | import org.junit.runner.RunWith
8 |
9 | @RunWith(AndroidJUnit4::class)
10 | class ExampleInstrumentedTest {
11 | @Test
12 | fun useAppContext() {
13 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext
14 | assertEquals("composablearchitecture.example.search", appContext.packageName)
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/examples/tic-tac-toe/src/androidTest/kotlin/composablearchitecture/example/tictactoe/ExampleInstrumentedTest.kt:
--------------------------------------------------------------------------------
1 | package composablearchitecture.example.tictactoe
2 |
3 | import androidx.test.ext.junit.runners.AndroidJUnit4
4 | import androidx.test.platform.app.InstrumentationRegistry
5 | import org.junit.Assert.assertEquals
6 | import org.junit.Test
7 | import org.junit.runner.RunWith
8 |
9 | @RunWith(AndroidJUnit4::class)
10 | class ExampleInstrumentedTest {
11 | @Test
12 | fun useAppContext() {
13 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext
14 | assertEquals("composablearchitecture.example.tictactoe", appContext.packageName)
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/examples/case-studies/src/androidTest/kotlin/composablearchitecture/example/casestudies/ExampleInstrumentedTest.kt:
--------------------------------------------------------------------------------
1 | package composablearchitecture.example.casestudies
2 |
3 | import androidx.test.ext.junit.runners.AndroidJUnit4
4 | import androidx.test.platform.app.InstrumentationRegistry
5 | import org.junit.Assert.assertEquals
6 | import org.junit.Test
7 | import org.junit.runner.RunWith
8 |
9 | @RunWith(AndroidJUnit4::class)
10 | class ExampleInstrumentedTest {
11 | @Test
12 | fun useAppContext() {
13 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext
14 | assertEquals("composablearchitecture.example.casestudies", appContext.packageName)
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/examples/case-studies/src/main/res/layout/main_activity.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
9 |
10 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/examples/search/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
22 |
--------------------------------------------------------------------------------
/examples/todos/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
22 |
--------------------------------------------------------------------------------
/examples/todos/src/main/res/layout/todos_activity.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
10 |
11 |
15 |
16 |
17 |
18 |
19 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/examples/case-studies/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
22 |
--------------------------------------------------------------------------------
/examples/tic-tac-toe/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
22 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Gradle
2 | org.gradle.jvmargs=-Xmx2048m
3 |
4 | # Gradle Kotlin
5 | kotlin.code.style=official
6 |
7 | # Gradle Android
8 | android.useAndroidX=true
9 |
10 | # Versions
11 | androidToolsBuildVersion=7.0.0
12 | androidxActivityVersion=1.3.0
13 | androidxAppcompatVersion=1.3.1
14 | androidxConstraintLayoutVersion=2.0.4
15 | androidxCoreVersion=1.6.0
16 | androidxDynamicAnimationVersion=1.0.0
17 | androidxEspressoVersion=3.4.0
18 | androidxJunitVersion=1.1.3
19 | androidxLifecycleVersion=2.3.1
20 | androidxRecyclerviewVersion=1.2.1
21 | arrowVersion=0.13.2
22 | coroutinesVersion=1.5.1
23 | junitVersion=4.13.2
24 | kotlinComposeVersion=1.0.0
25 | kotlinVersion=1.5.10
26 | moshiVersion=1.12.0
27 | okhttpVersion=4.9.1
28 | retrofitVersion=2.9.0
29 |
30 | # Android
31 | androidCompileSdkVersion=30
32 | androidMinSdkVersion=28
33 | androidTargetSdkVersion=30
34 |
--------------------------------------------------------------------------------
/examples/todos/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/examples/tic-tac-toe/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/composable-architecture-test/src/main/kotlin/composablearchitecture/test/TestExecutorService.kt:
--------------------------------------------------------------------------------
1 | package composablearchitecture.test
2 |
3 | import java.util.concurrent.AbstractExecutorService
4 | import java.util.concurrent.TimeUnit
5 |
6 | class TestExecutorService : AbstractExecutorService() {
7 |
8 | @Volatile
9 | private var terminated: Boolean = false
10 |
11 | override fun isTerminated(): Boolean = terminated
12 |
13 | override fun execute(command: Runnable) {
14 | command.run()
15 | }
16 |
17 | override fun shutdown() {
18 | terminated = true
19 | }
20 |
21 | override fun shutdownNow(): MutableList = mutableListOf()
22 |
23 | override fun isShutdown(): Boolean = terminated
24 |
25 | override fun awaitTermination(timeout: Long, timeUnit: TimeUnit): Boolean {
26 | shutdown()
27 | return terminated
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/examples/case-studies/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/composable-architecture/src/main/kotlin/composablearchitecture/ArrowOptics+Helpers.kt:
--------------------------------------------------------------------------------
1 | package composablearchitecture
2 |
3 | import arrow.core.Either
4 | import arrow.core.left
5 | import arrow.core.right
6 | import arrow.optics.Lens
7 | import arrow.optics.Optional
8 | import arrow.optics.dsl.index
9 | import arrow.optics.typeclasses.Index
10 |
11 | private fun listIndex(): Index, Int, A> = object : Index, Int, A> {
12 | override fun index(i: Int): Optional, A> = object : Optional, A> {
13 | override fun getOrModify(source: List): Either, A> =
14 | source.getOrNull(i)?.right() ?: source.left()
15 |
16 | override fun set(source: List, focus: A): List =
17 | source.update(i, focus)
18 | }
19 | }
20 |
21 | @Suppress("UNCHECKED_CAST")
22 | fun Lens.listIndex(i: Int): Optional where S : List {
23 | val index: Index = listIndex() as Index
24 | return index(index, i)
25 | }
26 |
--------------------------------------------------------------------------------
/examples/search/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
15 |
16 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 Makery, Kft.
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/examples/search/src/test/kotlin/composablearchitecture/example/search/Mocks.kt:
--------------------------------------------------------------------------------
1 | package composablearchitecture.example.search
2 |
3 | import arrow.core.Either
4 | import arrow.core.right
5 | import java.time.LocalDate
6 |
7 | val mockLocations = listOf(
8 | Location(1, "Brooklyn"),
9 | Location(2, "Los Angeles"),
10 | Location(3, "San Francisco")
11 | )
12 |
13 | val mockWeather = listOf(
14 | ConsolidatedWeather(
15 | LocalDate.now(),
16 | 90.0,
17 | 70.0,
18 | 80.0,
19 | "Clear"
20 | ),
21 | ConsolidatedWeather(
22 | LocalDate.now().plusDays(1),
23 | 70.0,
24 | 50.0,
25 | 60.0,
26 | "Rain"
27 | ),
28 | ConsolidatedWeather(
29 | LocalDate.now().plusDays(2),
30 | 100.0,
31 | 80.0,
32 | 90.0,
33 | "Cloudy"
34 | )
35 | )
36 |
37 | class MockWeatherClient : WeatherClient {
38 |
39 | override var searchLocation: suspend (String) -> Either> = {
40 | Either.catch { mockLocations }
41 | }
42 |
43 | override var weather: suspend (Int) -> Either = {
44 | Either.catch { LocationWeather(mockWeather, 1) }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/examples/todos/src/test/kotlin/composablearchitecture/example/todos/TodosSandbox.kt:
--------------------------------------------------------------------------------
1 | package composablearchitecture.example.todos
2 |
3 | import composablearchitecture.Store
4 | import kotlinx.coroutines.flow.collect
5 | import kotlinx.coroutines.launch
6 | import kotlinx.coroutines.runBlocking
7 | import kotlinx.coroutines.test.TestCoroutineDispatcher
8 | import java.util.UUID
9 |
10 | val todos = listOf(
11 | Todo(id = UUID.fromString("DEADBEEF-DEAD-BEEF-DEAD-BEEDDEADBEEF"))
12 | )
13 |
14 | fun main() {
15 | runBlocking {
16 | val dispatcher = TestCoroutineDispatcher()
17 |
18 | val store = Store(
19 | initialState = AppState(todos = todos),
20 | reducer = appReducer,
21 | environment = AppEnvironment(uuid = { UUID.randomUUID() }),
22 | mainDispatcher = dispatcher
23 | )
24 |
25 | val job = launch(dispatcher) { store.states.collect { println(it) } }
26 |
27 | store.send(
28 | AppAction.Todo(
29 | UUID.fromString("DEADBEEF-DEAD-BEEF-DEAD-BEEDDEADBEEF"),
30 | TodoAction.TextFieldChanged("Buy milk")
31 | )
32 | )
33 |
34 | job.cancel()
35 | println("✅")
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/examples/search/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | id("shared-android")
3 | }
4 |
5 | android {
6 | defaultConfig {
7 | applicationId = "composablearchitecture.example.search"
8 | }
9 | @Suppress("UnstableApiUsage")
10 | buildFeatures {
11 | compose = true
12 | aidl = false
13 | renderScript = false
14 | shaders = false
15 | }
16 | composeOptions {
17 | kotlinCompilerExtensionVersion = kotlinComposeVersion
18 | }
19 | }
20 |
21 | dependencies {
22 | implementation("androidx.activity:activity-compose:$kotlinComposeVersion")
23 | implementation("androidx.compose.foundation:foundation:$kotlinComposeVersion")
24 | implementation("androidx.compose.material:material:$kotlinComposeVersion")
25 | implementation("androidx.compose.ui:ui-tooling:$kotlinComposeVersion")
26 | implementation("androidx.compose.ui:ui:$kotlinComposeVersion")
27 | implementation("com.squareup.okhttp3:okhttp:$okhttpVersion")
28 | implementation("com.squareup.retrofit2:converter-moshi:$retrofitVersion")
29 | implementation("com.squareup.retrofit2:retrofit:$retrofitVersion")
30 | }
31 |
32 | configurations.all {
33 | resolutionStrategy.force("com.squareup.okhttp3:okhttp:$okhttpVersion")
34 | }
35 |
--------------------------------------------------------------------------------
/composable-architecture-android/src/main/kotlin/composablearchitecture/android/ScopedViewModel.kt:
--------------------------------------------------------------------------------
1 | package composablearchitecture.android
2 |
3 | import androidx.lifecycle.MutableLiveData
4 | import androidx.lifecycle.ViewModel
5 | import androidx.lifecycle.viewModelScope
6 | import arrow.optics.Lens
7 | import arrow.optics.Prism
8 | import composablearchitecture.Store
9 | import kotlinx.coroutines.Job
10 | import kotlinx.coroutines.flow.collect
11 | import kotlinx.coroutines.launch
12 |
13 | open class ScopedViewModel : ViewModel() {
14 |
15 | val state: MutableLiveData = MutableLiveData()
16 |
17 | protected lateinit var store: Store
18 |
19 | fun launch(
20 | globalStore: Store,
21 | lens: Lens,
22 | prism: Prism
23 | ): Job {
24 | store = globalStore.scope(lens, prism, viewModelScope)
25 | return viewModelScope.launch {
26 | store.states.collect { state.value = it }
27 | }
28 | }
29 |
30 | fun launch(globalStore: Store): Job {
31 | store = globalStore
32 | return viewModelScope.launch {
33 | store.states.collect { state.value = it }
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Built application files
2 | *.apk
3 | *.aar
4 | *.ap_
5 | *.aab
6 |
7 | # Files for the ART/Dalvik VM
8 | *.dex
9 |
10 | # Java class files
11 | *.class
12 |
13 | # Generated files
14 | bin/
15 | gen/
16 | out/
17 | # Uncomment the following line in case you need and you don't have the release build type files in your app
18 | # release/
19 |
20 | # Gradle files
21 | .gradle/
22 | build/
23 |
24 | # Local configuration file (sdk path, etc)
25 | local.properties
26 |
27 | # Proguard folder generated by Eclipse
28 | proguard/
29 |
30 | # Log Files
31 | *.log
32 |
33 | # Android Studio Navigation editor temp files
34 | .navigation/
35 |
36 | # Android Studio captures folder
37 | captures/
38 |
39 | # IntelliJ
40 | *.iml
41 | .idea/
42 |
43 | # Keystore files
44 | # Uncomment the following lines if you do not want to check your keystore files in.
45 | #*.jks
46 | #*.keystore
47 |
48 | # External native build folder generated in Android Studio 2.2 and later
49 | .externalNativeBuild
50 | .cxx/
51 |
52 | # Google Services (e.g. APIs or Firebase)
53 | # google-services.json
54 |
55 | # Freeline
56 | freeline.py
57 | freeline/
58 | freeline_project_description.json
59 |
60 | # fastlane
61 | fastlane/report.xml
62 | fastlane/Preview.html
63 | fastlane/screenshots
64 | fastlane/test_output
65 | fastlane/readme.md
66 |
67 | # Version control
68 | vcs.xml
69 |
70 | # lint
71 | lint/intermediates/
72 | lint/generated/
73 | lint/outputs/
74 | lint/tmp/
75 | # lint/reports/
76 |
--------------------------------------------------------------------------------
/examples/todos/src/main/res/layout/todo_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
8 |
9 |
17 |
18 |
28 |
29 |
30 |
31 |
32 |
35 |
36 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/composable-architecture/src/main/kotlin/composablearchitecture/Effect.kt:
--------------------------------------------------------------------------------
1 | package composablearchitecture
2 |
3 | import kotlinx.coroutines.flow.Flow
4 | import kotlinx.coroutines.flow.FlowCollector
5 | import kotlinx.coroutines.flow.emptyFlow
6 | import kotlinx.coroutines.flow.flattenConcat
7 | import kotlinx.coroutines.flow.flattenMerge
8 | import kotlinx.coroutines.flow.flow
9 | import kotlinx.coroutines.flow.flowOf
10 | import kotlinx.coroutines.flow.map
11 | import kotlinx.coroutines.flow.toList
12 |
13 | class Effect