Skip to content

Commit b5e955c

Browse files
authored
Merge pull request #56 from Kotlin-Android-Open-Source/feat_add
Feat add
2 parents ae71fc9 + c6e30c9 commit b5e955c

File tree

27 files changed

+989
-218
lines changed

27 files changed

+989
-218
lines changed

app/src/main/java/com/hoc/flowmvi/MainActivity.kt

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,10 @@ import androidx.compose.material3.SnackbarHostState
1313
import androidx.compose.material3.Text
1414
import androidx.compose.material3.TopAppBarColors
1515
import androidx.compose.runtime.Composable
16+
import androidx.compose.runtime.getValue
1617
import androidx.compose.runtime.mutableStateOf
1718
import androidx.compose.runtime.remember
19+
import androidx.compose.runtime.setValue
1820
import androidx.compose.ui.Modifier
1921
import androidx.navigation.compose.NavHost
2022
import com.hoc.flowmvi.core_ui.AppBarState
@@ -69,7 +71,7 @@ private fun JetpackComposeMVICoroutinesFlowApp(
6971
) {
7072
val navController = appState.navController
7173
val snackbarHostState = remember { SnackbarHostState() }
72-
val (appBarState, setAppBarState) = remember { mutableStateOf<AppBarState?>(null) }
74+
var appBarState by remember { mutableStateOf<AppBarState?>(null) }
7375

7476
Scaffold(
7577
snackbarHost = { SnackbarHost(snackbarHostState) },
@@ -91,12 +93,12 @@ private fun JetpackComposeMVICoroutinesFlowApp(
9193
startDestination = startScreen.route
9294
) {
9395
usersListScreen(
94-
configAppBar = setAppBarState,
96+
configAppBar = { appBarState = it },
9597
navigateToAddUser = { navController.navigateToAddNewUser() }
9698
)
9799

98100
addNewUserScreen(
99-
configAppBar = setAppBarState,
101+
configAppBar = { appBarState = it },
100102
onBackClick = appState::onBackClick
101103
)
102104
}

app/src/main/java/com/hoc/flowmvi/core/DefaultCoroutineDispatchers.kt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,5 @@ import javax.inject.Inject
88
internal class DefaultCoroutineDispatchers @Inject constructor() : AppCoroutineDispatchers {
99
override val main: CoroutineDispatcher get() = Dispatchers.Main
1010
override val io: CoroutineDispatcher get() = Dispatchers.IO
11-
override val mainImmediate: CoroutineDispatcher get() = Dispatchers.Main.immediate
1211
override val default: CoroutineDispatcher get() = Dispatchers.Default
1312
}

buildSrc/src/main/kotlin/deps.kt

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ inline val PDsS.androidLib: PDS get() = id("com.android.library")
130130
inline val PDsS.kotlinAndroid: PDS get() = kotlin("android")
131131
inline val PDsS.kotlin: PDS get() = kotlin("jvm")
132132
inline val PDsS.kotlinKapt: PDS get() = kotlin("kapt")
133+
inline val PDsS.kotlinParcelize: PDS get() = id("kotlin-parcelize")
133134
inline val PDsS.daggerHiltAndroid: PDS get() = id("dagger.hilt.android.plugin")
134135

135136
inline val DependencyHandler.domain get() = project(":domain")
@@ -144,7 +145,9 @@ inline val DependencyHandler.mviBase get() = project(":mvi-base")
144145
inline val DependencyHandler.mviTesting get() = project(":mvi-testing")
145146
inline val DependencyHandler.testUtils get() = project(":test-utils")
146147

147-
fun DependencyHandler.implementationCompose() {
148+
fun DependencyHandler.implementationCompose(
149+
includeMaterial2: Boolean = false,
150+
) {
148151
arrayOf(
149152
platform(deps.compose.bom),
150153
// activity compose
@@ -160,7 +163,10 @@ fun DependencyHandler.implementationCompose() {
160163
deps.compose.layout,
161164
deps.compose.foundation,
162165
deps.compose.ui,
163-
deps.compose.material,
166+
*(
167+
if (includeMaterial2) arrayOf(deps.compose.material)
168+
else emptyArray()
169+
),
164170
deps.compose.material3,
165171
deps.compose.materialIconsExtended,
166172
deps.compose.runtime,

core-ui/build.gradle.kts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,5 +44,8 @@ dependencies {
4444
implementation(deps.lifecycle.runtimeKtx)
4545
implementation(deps.androidx.material)
4646

47+
implementation(deps.coroutines.core)
48+
implementation(deps.coroutines.android)
49+
4750
addUnitTest()
4851
}

core-ui/src/main/java/com/hoc/flowmvi/core_ui/AppBarState.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,4 @@ data class AppBarState(
1515
val colors: TopAppBarColors,
1616
)
1717

18-
typealias ConfigAppBar = (AppBarState) -> Unit
18+
typealias ConfigAppBar = (AppBarState?) -> Unit
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package com.hoc.flowmvi.core_ui
2+
3+
import android.util.Log
4+
import kotlinx.coroutines.Dispatchers
5+
import kotlinx.coroutines.currentCoroutineContext
6+
import kotlin.coroutines.ContinuationInterceptor
7+
8+
suspend fun debugCheckImmediateMainDispatcher() {
9+
if (BuildConfig.DEBUG) {
10+
val interceptor = currentCoroutineContext()[ContinuationInterceptor]
11+
Log.d(
12+
"###",
13+
"debugCheckImmediateMainDispatcher: $interceptor, ${Dispatchers.Main.immediate}, ${Dispatchers.Main}"
14+
)
15+
16+
check(interceptor === Dispatchers.Main.immediate) {
17+
"Expected ContinuationInterceptor to be Dispatchers.Main.immediate but was $interceptor"
18+
}
19+
}
20+
}

core-ui/src/main/java/com/hoc/flowmvi/core_ui/rememberFlowWithLifecycle.kt

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,17 @@ package com.hoc.flowmvi.core_ui
22

33
import androidx.compose.runtime.Composable
44
import androidx.compose.runtime.LaunchedEffect
5+
import androidx.compose.runtime.getValue
56
import androidx.compose.runtime.remember
7+
import androidx.compose.runtime.rememberUpdatedState
68
import androidx.compose.ui.platform.LocalLifecycleOwner
79
import androidx.lifecycle.Lifecycle
810
import androidx.lifecycle.flowWithLifecycle
911
import androidx.lifecycle.repeatOnLifecycle
1012
import kotlinx.coroutines.CoroutineScope
13+
import kotlinx.coroutines.Dispatchers
1114
import kotlinx.coroutines.flow.Flow
15+
import kotlinx.coroutines.withContext
1216

1317
@Composable
1418
fun <T> rememberFlowWithLifecycle(
@@ -31,9 +35,13 @@ fun <T> Flow<T>.collectInLaunchedEffectWithLifecycle(
3135
collector: suspend CoroutineScope.(T) -> Unit
3236
) {
3337
val flow = this
38+
val currentCollector by rememberUpdatedState(collector)
39+
3440
LaunchedEffect(flow, lifecycle, minActiveState, *keys) {
35-
lifecycle.repeatOnLifecycle(minActiveState) {
36-
flow.collect { collector(it) }
41+
withContext(Dispatchers.Main.immediate) {
42+
lifecycle.repeatOnLifecycle(minActiveState) {
43+
flow.collect { currentCollector(it) }
44+
}
3745
}
3846
}
3947
}

core/src/main/java/com/hoc/flowmvi/core/dispatchers/AppCoroutineDispatchers.kt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,5 @@ import kotlinx.coroutines.CoroutineDispatcher
55
interface AppCoroutineDispatchers {
66
val main: CoroutineDispatcher
77
val io: CoroutineDispatcher
8-
val mainImmediate: CoroutineDispatcher
98
val default: CoroutineDispatcher
109
}

data/src/main/java/com/hoc/flowmvi/data/DataModule.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ internal abstract class DataModule {
8484

8585
@Provides
8686
@BaseUrl
87-
fun baseUrl(): String = "https://mvi-coroutines-flow-server.herokuapp.com/"
87+
fun baseUrl(): String = "https://mvi-coroutines-flow-server.onrender.com/"
8888

8989
@OptIn(ExperimentalStdlibApi::class)
9090
@Provides

data/src/test/java/com/hoc/flowmvi/data/UserRepositoryImplRealAPITest.kt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ class UserRepositoryImplRealAPITest : KoinTest {
3838
object : AppCoroutineDispatchers {
3939
override val main: CoroutineDispatcher get() = Main
4040
override val io: CoroutineDispatcher get() = IO
41-
override val mainImmediate: CoroutineDispatcher get() = Main.immediate
4241
override val default: CoroutineDispatcher get() = IO
4342
}
4443
}

0 commit comments

Comments
 (0)