Skip to content

Commit 9b84d75

Browse files
authored
Merge pull request #237 from joreilly/circuit_updates
Circuit updates
2 parents 489c9c8 + b384d5c commit 9b84d75

File tree

20 files changed

+264
-274
lines changed

20 files changed

+264
-274
lines changed

androidApp/build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ dependencies {
116116
testImplementation("junit:junit:4.13.2")
117117
androidTestImplementation("androidx.test:runner:1.6.2")
118118

119-
implementation(project(":common"))
119+
implementation(projects.common)
120120
}
121121

122122

common/build.gradle.kts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,14 @@ kotlin {
6161
implementation(compose.foundation)
6262
implementation(compose.material3)
6363
implementation(compose.components.resources)
64+
implementation(libs.compose.adaptive)
65+
implementation(libs.compose.adaptive.layout)
6466
}
6567

6668
androidMain.dependencies {
6769
implementation(libs.ktor.client.android)
70+
// workaround for https://youtrack.jetbrains.com/issue/CMP-5959/Invalid-redirect-in-window-core#focus=Comments-27-10365630.0-0
71+
implementation("androidx.window:window-core:1.3.0")
6872
}
6973

7074
appleMain.dependencies {
@@ -135,3 +139,7 @@ room {
135139
schemaDirectory("$projectDir/schemas")
136140
}
137141

142+
143+
configurations.configureEach {
144+
exclude("androidx.window.core", "window-core")
145+
}

common/src/androidMain/kotlin/dev/johnoreilly/common/di/AndroidApplicationComponent.kt

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,12 @@ import android.app.Application
44
import android.content.Context
55
import androidx.room.Room
66
import androidx.sqlite.driver.bundled.BundledSQLiteDriver
7-
import com.slack.circuit.foundation.Circuit
87
import dev.johnoreilly.common.database.AppDatabase
98
import dev.johnoreilly.common.database.dbFileName
10-
import dev.johnoreilly.common.screens.CountryListPresenter
11-
import dev.johnoreilly.common.screens.CountryListScreen
12-
import dev.johnoreilly.common.screens.NetworkListPresenter
13-
import dev.johnoreilly.common.screens.NetworkListScreen
14-
import dev.johnoreilly.common.screens.StationListPresenter
15-
import dev.johnoreilly.common.screens.StationListScreen
169
import dev.johnoreilly.common.ui.BikeShareContent
17-
import dev.johnoreilly.common.ui.CountryListUi
18-
import dev.johnoreilly.common.ui.NetworkListUi
19-
import dev.johnoreilly.common.ui.StationListUI
2010
import io.ktor.client.engine.android.Android
2111
import kotlinx.coroutines.Dispatchers
2212
import me.tatarka.inject.annotations.Component
23-
import me.tatarka.inject.annotations.Provides
2413

2514

2615
@Component
@@ -29,16 +18,6 @@ abstract class AndroidApplicationComponent(val application: Application): Shared
2918

3019
abstract val bikeShareContent: BikeShareContent
3120

32-
@Provides
33-
fun provideCircuit(): Circuit = Circuit.Builder()
34-
.addPresenterFactory(CountryListPresenter.Factory(repository))
35-
.addPresenterFactory(NetworkListPresenter.Factory(repository))
36-
.addPresenterFactory(StationListPresenter.Factory(repository))
37-
.addUi<CountryListScreen, CountryListScreen.State> { state, modifier -> CountryListUi(state, modifier) }
38-
.addUi<NetworkListScreen, NetworkListScreen.State> { state, modifier -> NetworkListUi(state, modifier) }
39-
.addUi<StationListScreen, StationListScreen.State> { state, modifier -> StationListUI(state, modifier) }
40-
.build()
41-
4221
override fun getHttpClientEngine() = Android.create()
4322

4423
override fun getRoomDatabase() = createRoomDatabase(application)

common/src/androidMain/kotlin/dev/johnoreilly/common/ui/BikeShareContentAndroid.kt

Whitespace-only changes.
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package dev.johnoreilly.common.countrylist
2+
3+
import androidx.compose.runtime.Composable
4+
import androidx.compose.runtime.collectAsState
5+
import androidx.compose.runtime.getValue
6+
import com.slack.circuit.runtime.CircuitContext
7+
import com.slack.circuit.runtime.Navigator
8+
import com.slack.circuit.runtime.presenter.Presenter
9+
import com.slack.circuit.runtime.screen.Screen
10+
import dev.johnoreilly.common.screens.CountryListScreen
11+
import dev.johnoreilly.common.screens.NetworkListScreen
12+
import dev.johnoreilly.common.getCountryName
13+
import dev.johnoreilly.common.repository.CityBikesRepository
14+
import dev.johnoreilly.common.viewmodel.Country
15+
import me.tatarka.inject.annotations.Assisted
16+
import me.tatarka.inject.annotations.Inject
17+
18+
19+
@Inject
20+
class CountryListPresenterFactory(
21+
private val presenterFactory: (Navigator) -> CountryListPresenter,
22+
) : Presenter.Factory {
23+
override fun create(screen: Screen, navigator: Navigator, context: CircuitContext): Presenter<*>? {
24+
return when (screen) {
25+
CountryListScreen -> presenterFactory(navigator)
26+
else -> null
27+
}
28+
}
29+
}
30+
31+
@Inject
32+
class CountryListPresenter(
33+
@Assisted private val navigator: Navigator,
34+
private val cityBikesRepository: CityBikesRepository
35+
) : Presenter<CountryListScreen.State> {
36+
@Composable
37+
override fun present(): CountryListScreen.State {
38+
val groupedNetworkList by cityBikesRepository.groupedNetworkList.collectAsState()
39+
val countryCodeList = groupedNetworkList.keys.toList()
40+
val countryList = countryCodeList.map { countryCode -> Country(countryCode, getCountryName(countryCode)) }
41+
.sortedBy { it.displayName }
42+
return CountryListScreen.State(countryList) { event ->
43+
when (event) {
44+
is CountryListScreen.Event.CountryClicked -> navigator.goTo(NetworkListScreen(event.countryCode))
45+
}
46+
}
47+
}
48+
}

common/src/commonMain/kotlin/dev/johnoreilly/common/ui/CountryListUI.kt renamed to common/src/commonMain/kotlin/dev/johnoreilly/common/countrylist/CountryListUI.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
@file:OptIn(ExperimentalMaterial3Api::class)
22

3-
package dev.johnoreilly.common.ui
3+
package dev.johnoreilly.common.countrylist
44

55
import androidx.compose.foundation.Image
66
import androidx.compose.foundation.clickable

common/src/commonMain/kotlin/dev/johnoreilly/common/di/SharedApplicationComponent.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ import kotlin.annotation.AnnotationTarget.PROPERTY_GETTER
2525
@Target(CLASS, FUNCTION, PROPERTY_GETTER)
2626
annotation class Singleton
2727

28-
interface SharedApplicationComponent {
28+
interface SharedApplicationComponent: SharedUiComponent {
2929

3030
val countriesViewModel: CountriesViewModelShared
3131
val networksViewModel: NetworksViewModelShared
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package dev.johnoreilly.common.di
2+
3+
import com.slack.circuit.foundation.Circuit
4+
import com.slack.circuit.runtime.presenter.Presenter
5+
import com.slack.circuit.runtime.ui.Ui
6+
import dev.johnoreilly.common.screens.CountryListUiFactory
7+
import dev.johnoreilly.common.screens.NetworkListUiFactory
8+
import dev.johnoreilly.common.screens.StationListUiFactory
9+
import dev.johnoreilly.common.countrylist.CountryListPresenterFactory
10+
import dev.johnoreilly.common.networklist.NetworkListPresenterFactory
11+
import dev.johnoreilly.common.stationlist.StationListPresenterFactory
12+
import me.tatarka.inject.annotations.IntoSet
13+
import me.tatarka.inject.annotations.Provides
14+
15+
interface SharedUiComponent {
16+
@IntoSet
17+
@Provides
18+
fun bindCountryListPresenterFactory(factory: CountryListPresenterFactory): Presenter.Factory = factory
19+
20+
@IntoSet
21+
@Provides
22+
fun bindCountryListUiFactory(factory: CountryListUiFactory): Ui.Factory = factory
23+
24+
@IntoSet
25+
@Provides
26+
fun bindNetworkListPresenterFactory(factory: NetworkListPresenterFactory): Presenter.Factory = factory
27+
28+
@IntoSet
29+
@Provides
30+
fun bindNetworkListUiFactory(factory: NetworkListUiFactory): Ui.Factory = factory
31+
32+
@IntoSet
33+
@Provides
34+
fun bindStationListPresenterFactory(factory: StationListPresenterFactory): Presenter.Factory = factory
35+
36+
@IntoSet
37+
@Provides
38+
fun bindStationListUiFactory(factory: StationListUiFactory): Ui.Factory = factory
39+
40+
@Provides
41+
fun provideCircuit(
42+
uiFactories: Set<Ui.Factory>,
43+
presenterFactories: Set<Presenter.Factory>
44+
): Circuit = Circuit.Builder()
45+
.addUiFactories(uiFactories)
46+
.addPresenterFactories(presenterFactories)
47+
.build()
48+
49+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package dev.johnoreilly.common.networklist
2+
3+
import androidx.compose.runtime.Composable
4+
import androidx.compose.runtime.collectAsState
5+
import androidx.compose.runtime.getValue
6+
import com.slack.circuit.runtime.CircuitContext
7+
import com.slack.circuit.runtime.Navigator
8+
import com.slack.circuit.runtime.presenter.Presenter
9+
import com.slack.circuit.runtime.screen.Screen
10+
import dev.johnoreilly.common.screens.NetworkListScreen
11+
import dev.johnoreilly.common.screens.StationListScreen
12+
import dev.johnoreilly.common.getCountryName
13+
import dev.johnoreilly.common.repository.CityBikesRepository
14+
import me.tatarka.inject.annotations.Assisted
15+
import me.tatarka.inject.annotations.Inject
16+
17+
@Inject
18+
class NetworkListPresenterFactory(
19+
private val presenterFactory: (NetworkListScreen, Navigator) -> NetworkListPresenter
20+
) : Presenter.Factory {
21+
override fun create(screen: Screen, navigator: Navigator, context: CircuitContext): Presenter<*>? {
22+
return when (screen) {
23+
is NetworkListScreen -> presenterFactory(screen, navigator)
24+
else -> null
25+
}
26+
}
27+
}
28+
29+
@Inject
30+
class NetworkListPresenter(
31+
@Assisted private val screen: NetworkListScreen,
32+
@Assisted private val navigator: Navigator,
33+
private val cityBikesRepository: CityBikesRepository
34+
) : Presenter<NetworkListScreen.State> {
35+
@Composable
36+
override fun present(): NetworkListScreen.State {
37+
val groupedNetworkList by cityBikesRepository.groupedNetworkList.collectAsState()
38+
val networkList = groupedNetworkList[screen.countryCode]?.sortedBy { it.city } ?: emptyList()
39+
val oountryName = getCountryName(screen.countryCode)
40+
return NetworkListScreen.State(screen.countryCode, oountryName, networkList) { event ->
41+
when (event) {
42+
is NetworkListScreen.Event.NetworkClicked -> navigator.goTo(StationListScreen(event.networkId))
43+
NetworkListScreen.Event.BackClicked -> navigator.pop()
44+
}
45+
}
46+
}
47+
}

common/src/commonMain/kotlin/dev/johnoreilly/common/ui/NetworkListUI.kt renamed to common/src/commonMain/kotlin/dev/johnoreilly/common/networklist/NetworkListUI.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
@file:OptIn(ExperimentalMaterial3Api::class)
22

3-
package dev.johnoreilly.common.ui
3+
package dev.johnoreilly.common.networklist
44

55
import androidx.compose.foundation.clickable
66
import androidx.compose.foundation.layout.Row

0 commit comments

Comments
 (0)