Skip to content

Commit b3910b8

Browse files
authored
Merge pull request #41 from CodandoTV/feature/33_state_to_state_flow
[ISSUE-33] - State to StateFlow
2 parents 67bb554 + 70dc348 commit b3910b8

File tree

6 files changed

+51
-35
lines changed

6 files changed

+51
-35
lines changed

buildSrc/src/main/java/Dependencies.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@ object Dependencies {
155155
const val composeMaterial3 = "androidx.compose.material3:material3:${Versions.composeMaterial3Version}"
156156
const val composeNavigation = "androidx.navigation:navigation-compose:${Versions.composeNavigationVersion}"
157157
const val composeIcons = "androidx.compose.material:material-icons-extended:${Versions.composeIcons}"
158+
const val lifecycleComposeRuntime = "androidx.lifecycle:lifecycle-runtime-compose:${Versions.lifecycleComposeRuntime}"
158159

159160
override val list: List<String>
160161
get() = listOf(
@@ -164,7 +165,8 @@ object Dependencies {
164165
Compose.composeUITooling,
165166
Compose.composeMaterial3,
166167
Compose.composeNavigation,
167-
Compose.composeIcons
168+
Compose.composeIcons,
169+
Compose.lifecycleComposeRuntime
168170
)
169171
}
170172
}

buildSrc/src/main/java/Versions.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ object Versions {
3434
const val composeActivity = "1.5.0"
3535
const val composeIcons = "1.4.3"
3636
const val composeNavigationVersion = "2.5.3"
37+
const val lifecycleComposeRuntime = "2.6.1"
3738

3839
const val coilVersion = "2.3.0"
3940

Original file line numberDiff line numberDiff line change
@@ -1,24 +1,30 @@
11
package com.codandotv.streamplayerapp.feature_list_streams.detail.presentation.screens
22

3-
import androidx.compose.runtime.State
4-
import androidx.compose.runtime.mutableStateOf
53
import androidx.lifecycle.DefaultLifecycleObserver
64
import androidx.lifecycle.LifecycleOwner
75
import androidx.lifecycle.ViewModel
86
import androidx.lifecycle.viewModelScope
97
import com.codandotv.streamplayerapp.core_networking.handleError.catchFailure
108
import com.codandotv.streamplayerapp.feature_list_streams.detail.domain.DetailStreamUseCase
119
import com.codandotv.streamplayerapp.feature_list_streams.detail.presentation.screens.DetailStreamsUIState.*
12-
import kotlinx.coroutines.flow.onCompletion
10+
import kotlinx.coroutines.flow.MutableStateFlow
11+
import kotlinx.coroutines.flow.SharingStarted
12+
import kotlinx.coroutines.flow.StateFlow
1313
import kotlinx.coroutines.flow.onStart
14+
import kotlinx.coroutines.flow.stateIn
15+
import kotlinx.coroutines.flow.update
1416
import kotlinx.coroutines.launch
1517

1618
class DetailStreamViewModel(
1719
private val useCase: DetailStreamUseCase,
1820
) : ViewModel(), DefaultLifecycleObserver {
1921

20-
private val _uiState = mutableStateOf<DetailStreamsUIState>(LoadingStreamUIState)
21-
val uiState: State<DetailStreamsUIState> = _uiState
22+
private val _uiState = MutableStateFlow<DetailStreamsUIState>(LoadingStreamUIState)
23+
val uiState : StateFlow<DetailStreamsUIState> = _uiState.stateIn(
24+
viewModelScope,
25+
SharingStarted.Eagerly,
26+
initialValue = _uiState.value
27+
)
2228

2329
override fun onCreate(owner: LifecycleOwner) {
2430
super.onCreate(owner)
@@ -29,15 +35,17 @@ class DetailStreamViewModel(
2935
.catchFailure {
3036
println(">>>> ${it.errorMessage}")
3137
}
32-
.collect {
33-
_uiState.value = DetailStreamsLoadedUIState(
34-
detailStream = it
35-
)
38+
.collect { detailStream ->
39+
_uiState.update {
40+
DetailStreamsLoadedUIState(
41+
detailStream = detailStream
42+
)
43+
}
3644
}
3745
}
3846
}
3947

4048
private fun onLoading() {
41-
_uiState.value = LoadingStreamUIState
49+
_uiState.update { LoadingStreamUIState }
4250
}
4351
}

feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/detail/presentation/screens/DetailStreamsScreen.kt

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import androidx.compose.material.icons.filled.*
77
import androidx.compose.material3.*
88
import androidx.compose.runtime.Composable
99
import androidx.compose.runtime.DisposableEffect
10-
import androidx.compose.runtime.remember
10+
import androidx.compose.runtime.getValue
1111
import androidx.compose.ui.Alignment
1212
import androidx.compose.ui.Modifier
1313
import androidx.compose.ui.graphics.Color
@@ -18,6 +18,7 @@ import androidx.compose.ui.unit.dp
1818
import androidx.compose.ui.unit.em
1919
import androidx.compose.ui.unit.sp
2020
import androidx.lifecycle.LifecycleOwner
21+
import androidx.lifecycle.compose.collectAsStateWithLifecycle
2122
import androidx.navigation.NavController
2223
import com.codandotv.streamplayerapp.core_shared_ui.resources.Colors.DarkDeepGray
2324
import com.codandotv.streamplayerapp.feature_list_streams.R
@@ -31,17 +32,15 @@ fun DetailStreamScreen(
3132
navController: NavController,
3233
disposable: () -> Unit = {}
3334
) {
34-
val uiStateRemember = remember {
35-
viewModel.uiState
36-
}
35+
val uiState by viewModel.uiState.collectAsStateWithLifecycle()
3736

3837
val lifecycleOwner = LocalLifecycleOwner.current
3938
Lifecycle(lifecycleOwner, viewModel, disposable)
4039

4140
Box(modifier = Modifier.fillMaxSize()) {
42-
when (val uiState = uiStateRemember.value) {
41+
when (uiState) {
4342
is DetailStreamsLoadedUIState -> {
44-
SetupDetailScreen(uiState, navController)
43+
SetupDetailScreen(uiState as DetailStreamsLoadedUIState, navController)
4544
}
4645
else -> {
4746
CircularProgressIndicator(
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,36 @@
11
package com.codandotv.streamplayerapp.feature_list_streams.list.presentation.screens
22

3-
import androidx.compose.runtime.State
4-
import androidx.compose.runtime.mutableStateOf
53
import androidx.lifecycle.DefaultLifecycleObserver
64
import androidx.lifecycle.LifecycleOwner
75
import androidx.lifecycle.ViewModel
86
import androidx.lifecycle.viewModelScope
97
import com.codandotv.streamplayerapp.core_networking.handleError.catchFailure
108
import com.codandotv.streamplayerapp.feature_list_streams.list.domain.ListStreamUseCase
119
import com.codandotv.streamplayerapp.feature_list_streams.list.presentation.ListStreamUimodel
10+
import kotlinx.coroutines.flow.MutableStateFlow
11+
import kotlinx.coroutines.flow.SharingStarted
1212
import kotlinx.coroutines.flow.onCompletion
1313
import kotlinx.coroutines.flow.onStart
14+
import kotlinx.coroutines.flow.stateIn
15+
import kotlinx.coroutines.flow.update
1416
import kotlinx.coroutines.launch
1517

1618
class ListStreamViewModel(
1719
private val uiModel: ListStreamUimodel,
1820
private val useCase: ListStreamUseCase,
1921
) : ViewModel(), DefaultLifecycleObserver {
2022

21-
val uiState = mutableStateOf(
23+
private val _uiState = MutableStateFlow(
2224
ListStreamsUIState(
2325
carousels = emptyList(),
2426
isLoading = false
2527
)
2628
)
29+
val uiState = _uiState.stateIn(
30+
viewModelScope,
31+
SharingStarted.Eagerly,
32+
initialValue = _uiState.value
33+
)
2734

2835
override fun onCreate(owner: LifecycleOwner) {
2936
super.onCreate(owner)
@@ -35,22 +42,24 @@ class ListStreamViewModel(
3542
println(">>>> ${it.errorMessage}")
3643
}
3744
.onCompletion { loaded() }
38-
.collect {
39-
this@ListStreamViewModel.uiState.value = uiModel.convertToCardContent(it)
45+
.collect { listStream ->
46+
_uiState.update {
47+
uiModel.convertToCardContent(listStream)
48+
}
4049
}
4150
}
4251
}
4352
}
4453

4554
private fun loaded() {
46-
this.uiState.value = this.uiState.value.copy(
47-
isLoading = false
48-
)
55+
this._uiState.update {
56+
it.copy(isLoading = false)
57+
}
4958
}
5059

5160
private fun onLoading() {
52-
this.uiState.value = this.uiState.value.copy(
53-
isLoading = true
54-
)
61+
this._uiState.update {
62+
it.copy(isLoading = true)
63+
}
5564
}
5665
}

feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/list/presentation/screens/ListStreamsScreen.kt

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@ import androidx.compose.material3.ExperimentalMaterial3Api
1010
import androidx.compose.material3.MaterialTheme
1111
import androidx.compose.material3.Scaffold
1212
import androidx.compose.runtime.*
13-
import androidx.compose.runtime.saveable.rememberSaveable
1413
import androidx.compose.ui.Alignment
1514
import androidx.compose.ui.Modifier
1615
import androidx.compose.ui.platform.LocalLifecycleOwner
1716
import androidx.compose.ui.unit.dp
17+
import androidx.lifecycle.compose.collectAsStateWithLifecycle
1818
import androidx.navigation.NavController
1919
import androidx.navigation.compose.rememberNavController
2020
import com.codandotv.streamplayerapp.core_navigation.bottomnavigation.StreamPlayerBottomNavigation
@@ -31,9 +31,7 @@ fun ListStreamsScreen(
3131
onNavigateDetailList: (String) -> Unit = {},
3232
disposable: () -> Unit = {}
3333
) {
34-
val uiState = rememberSaveable() {
35-
viewModel.uiState
36-
}
34+
val uiState by viewModel.uiState.collectAsStateWithLifecycle()
3735
val lifecycleOwner = LocalLifecycleOwner.current
3836

3937
DisposableEffect(lifecycleOwner) {
@@ -43,7 +41,6 @@ fun ListStreamsScreen(
4341

4442
onDispose {
4543
lifecycle.removeObserver(viewModel)
46-
uiState.value = viewModel.uiState.value
4744
disposable.invoke()
4845
}
4946
}
@@ -58,7 +55,7 @@ fun ListStreamsScreen(
5855
.fillMaxSize()
5956
.background(MaterialTheme.colorScheme.background)
6057
) {
61-
if (uiState.value.isLoading) {
58+
if (uiState.isLoading) {
6259
CircularProgressIndicator(
6360
modifier = Modifier.align(
6461
Alignment.Center
@@ -71,7 +68,7 @@ fun ListStreamsScreen(
7168
.align(Alignment.TopCenter)
7269
.verticalScroll(ScrollState(0))
7370
) {
74-
uiState.value.carousels.forEach {
71+
uiState.carousels.forEach {
7572
StreamsCarousel(
7673
title = it.categoryName,
7774
contentList = it.cards,

0 commit comments

Comments
 (0)