From 6ba0018765a4d09bb048d13db64d112c234cacb0 Mon Sep 17 00:00:00 2001 From: brreynie Date: Mon, 8 May 2023 21:51:18 +0200 Subject: [PATCH] refactor feed to use UiState.Loading --- .../studeez/common/composable/feed/Feed.kt | 99 +++++++++++++++++++ .../composable/feed}/FeedEntry.kt | 2 +- .../common/composable/feed/FeedUiState.kt | 8 ++ .../composable/feed}/FeedViewModel.kt | 14 ++- .../sel/studeez/navigation/StudeezNavGraph.kt | 4 +- .../be/ugent/sel/studeez/screens/home/Feed.kt | 70 ------------- .../sel/studeez/screens/home/HomeScreen.kt | 16 ++- .../sel/studeez/screens/home/HomeViewModel.kt | 19 ---- 8 files changed, 131 insertions(+), 101 deletions(-) create mode 100644 app/src/main/java/be/ugent/sel/studeez/common/composable/feed/Feed.kt rename app/src/main/java/be/ugent/sel/studeez/{screens/home => common/composable/feed}/FeedEntry.kt (98%) create mode 100644 app/src/main/java/be/ugent/sel/studeez/common/composable/feed/FeedUiState.kt rename app/src/main/java/be/ugent/sel/studeez/{screens/home => common/composable/feed}/FeedViewModel.kt (75%) delete mode 100644 app/src/main/java/be/ugent/sel/studeez/screens/home/Feed.kt delete mode 100644 app/src/main/java/be/ugent/sel/studeez/screens/home/HomeViewModel.kt diff --git a/app/src/main/java/be/ugent/sel/studeez/common/composable/feed/Feed.kt b/app/src/main/java/be/ugent/sel/studeez/common/composable/feed/Feed.kt new file mode 100644 index 0000000..6c7c0c1 --- /dev/null +++ b/app/src/main/java/be/ugent/sel/studeez/common/composable/feed/Feed.kt @@ -0,0 +1,99 @@ +package be.ugent.sel.studeez.common.composable.feed + +import androidx.compose.foundation.layout.* +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.items +import androidx.compose.material.CircularProgressIndicator +import androidx.compose.material.MaterialTheme +import androidx.compose.material.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import be.ugent.sel.studeez.common.composable.DateText +import be.ugent.sel.studeez.data.local.models.FeedEntry +import be.ugent.sel.studeez.data.local.models.timer_functional.HoursMinutesSeconds +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.flowOf + +data class FeedActions( + val getFeedEntries: () -> Flow>>, + val continueTask: (String, String) -> Unit, +) + +fun getFeedActions( + viewmodel: FeedViewModel, + open: (String) -> Unit, +): FeedActions { + return FeedActions( + getFeedEntries = viewmodel::getFeedEntries, + continueTask = { subjectId, taskId -> + viewmodel.continueTask( + open, + subjectId, + taskId, + ) + }, + ) +} + +@Composable +fun Feed( + feedActions: FeedActions, + uiState: FeedUiState, +) { + when (uiState) { + FeedUiState.Loading -> { + Column( + modifier = Modifier + .fillMaxWidth() + .fillMaxHeight(), + verticalArrangement = Arrangement.Center, + horizontalAlignment = Alignment.CenterHorizontally + ) { + CircularProgressIndicator(color = MaterialTheme.colors.onBackground) + } + } + is FeedUiState.Succes -> { +// val feedEntries = feedActions.getFeedEntries().collectAsState(initial = emptyMap()) + val feedEntries = uiState.feedEntries + LazyColumn { + items(feedEntries.toList()) { (date, feedEntries) -> + Row( + horizontalArrangement = Arrangement.SpaceBetween, + modifier = Modifier + .fillMaxWidth() + .padding(10.dp), + verticalAlignment = Alignment.CenterVertically + ) { + val totalDayStudyTime: Int = feedEntries.sumOf { it.totalStudyTime } + DateText(date = date) + Text( + text = "${HoursMinutesSeconds(totalDayStudyTime)}", + fontSize = 15.sp, + fontWeight = FontWeight.Bold + ) + } + feedEntries.forEach { feedEntry -> + FeedEntry(feedEntry = feedEntry) { + feedActions.continueTask(feedEntry.subjectId, feedEntry.taskId) + } + } + Spacer(modifier = Modifier.height(20.dp)) + } + } + } + } +} + +@Preview +@Composable +fun FeedPreview() { + Feed( + feedActions = FeedActions({ flowOf() }, { _, _ -> run {} }), + uiState = FeedUiState.Loading, + ) +} \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/home/FeedEntry.kt b/app/src/main/java/be/ugent/sel/studeez/common/composable/feed/FeedEntry.kt similarity index 98% rename from app/src/main/java/be/ugent/sel/studeez/screens/home/FeedEntry.kt rename to app/src/main/java/be/ugent/sel/studeez/common/composable/feed/FeedEntry.kt index a7d1fc1..6dce710 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/home/FeedEntry.kt +++ b/app/src/main/java/be/ugent/sel/studeez/common/composable/feed/FeedEntry.kt @@ -1,4 +1,4 @@ -package be.ugent.sel.studeez.screens.home +package be.ugent.sel.studeez.common.composable.feed import androidx.compose.foundation.background import androidx.compose.foundation.layout.* diff --git a/app/src/main/java/be/ugent/sel/studeez/common/composable/feed/FeedUiState.kt b/app/src/main/java/be/ugent/sel/studeez/common/composable/feed/FeedUiState.kt new file mode 100644 index 0000000..1b938ca --- /dev/null +++ b/app/src/main/java/be/ugent/sel/studeez/common/composable/feed/FeedUiState.kt @@ -0,0 +1,8 @@ +package be.ugent.sel.studeez.common.composable.feed + +import be.ugent.sel.studeez.data.local.models.FeedEntry + +sealed interface FeedUiState { + object Loading : FeedUiState + data class Succes(val feedEntries: Map>) : FeedUiState +} \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/home/FeedViewModel.kt b/app/src/main/java/be/ugent/sel/studeez/common/composable/feed/FeedViewModel.kt similarity index 75% rename from app/src/main/java/be/ugent/sel/studeez/screens/home/FeedViewModel.kt rename to app/src/main/java/be/ugent/sel/studeez/common/composable/feed/FeedViewModel.kt index 1f57175..d31d83a 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/home/FeedViewModel.kt +++ b/app/src/main/java/be/ugent/sel/studeez/common/composable/feed/FeedViewModel.kt @@ -1,4 +1,4 @@ -package be.ugent.sel.studeez.screens.home +package be.ugent.sel.studeez.common.composable.feed import androidx.lifecycle.viewModelScope import be.ugent.sel.studeez.data.SelectedTask @@ -9,13 +9,13 @@ import be.ugent.sel.studeez.domain.TaskDAO import be.ugent.sel.studeez.navigation.StudeezDestinations import be.ugent.sel.studeez.screens.StudeezViewModel import dagger.hilt.android.lifecycle.HiltViewModel -import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.* import kotlinx.coroutines.launch import javax.inject.Inject @HiltViewModel class FeedViewModel @Inject constructor( - private val feedDAO: FeedDAO, + feedDAO: FeedDAO, private val taskDAO: TaskDAO, private val selectedTask: SelectedTask, logService: LogService @@ -23,6 +23,14 @@ class FeedViewModel @Inject constructor( private val entries: Flow>> = feedDAO.getFeedEntries() + val uiState: StateFlow = feedDAO.getFeedEntries() + .map { FeedUiState.Succes(it) } + .stateIn( + scope = viewModelScope, + initialValue = FeedUiState.Loading, + started = SharingStarted.Eagerly, + ) + fun getFeedEntries(): Flow>> { return entries } diff --git a/app/src/main/java/be/ugent/sel/studeez/navigation/StudeezNavGraph.kt b/app/src/main/java/be/ugent/sel/studeez/navigation/StudeezNavGraph.kt index bd12413..5becc44 100644 --- a/app/src/main/java/be/ugent/sel/studeez/navigation/StudeezNavGraph.kt +++ b/app/src/main/java/be/ugent/sel/studeez/navigation/StudeezNavGraph.kt @@ -15,7 +15,6 @@ import be.ugent.sel.studeez.common.composable.navbar.NavigationBarActions import be.ugent.sel.studeez.common.composable.navbar.NavigationBarViewModel import be.ugent.sel.studeez.common.composable.navbar.getNavigationBarActions import be.ugent.sel.studeez.screens.home.HomeRoute -import be.ugent.sel.studeez.screens.home.getFeedActions import be.ugent.sel.studeez.screens.log_in.LoginRoute import be.ugent.sel.studeez.screens.profile.EditProfileRoute import be.ugent.sel.studeez.screens.profile.ProfileRoute @@ -66,10 +65,9 @@ fun StudeezNavGraph( composable(StudeezDestinations.HOME_SCREEN) { HomeRoute( open, - viewModel = hiltViewModel(), drawerActions = drawerActions, navigationBarActions = navigationBarActions, - feedActions = getFeedActions(hiltViewModel(), open), + feedViewModel = hiltViewModel(), ) } diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/home/Feed.kt b/app/src/main/java/be/ugent/sel/studeez/screens/home/Feed.kt deleted file mode 100644 index 96a9623..0000000 --- a/app/src/main/java/be/ugent/sel/studeez/screens/home/Feed.kt +++ /dev/null @@ -1,70 +0,0 @@ -package be.ugent.sel.studeez.screens.home - -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.lazy.items -import androidx.compose.material.Text -import androidx.compose.runtime.Composable -import androidx.compose.runtime.collectAsState -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import be.ugent.sel.studeez.common.composable.DateText -import be.ugent.sel.studeez.data.local.models.FeedEntry -import be.ugent.sel.studeez.data.local.models.timer_functional.HoursMinutesSeconds -import kotlinx.coroutines.flow.Flow - -data class FeedActions( - val getFeedEntries: () -> Flow>>, - val continueTask: (String, String) -> Unit, -) - -fun getFeedActions( - viewmodel: FeedViewModel, - open: (String) -> Unit, -): FeedActions { - return FeedActions( - getFeedEntries = viewmodel::getFeedEntries, - continueTask = { subjectId, taskId -> - viewmodel.continueTask( - open, - subjectId, - taskId, - ) - }, - ) -} - -@Composable -fun Feed( - feedActions: FeedActions, -) { - val feedEntries = feedActions.getFeedEntries().collectAsState(initial = emptyMap()) - LazyColumn { - items(feedEntries.value.toList()) { (date, feedEntries) -> - Row( - horizontalArrangement = Arrangement.SpaceBetween, - modifier = Modifier - .fillMaxWidth() - .padding(10.dp), - verticalAlignment = Alignment.CenterVertically - ) { - val totalDayStudyTime: Int = feedEntries.sumOf { it.totalStudyTime } - DateText(date = date) - Text( - text = "${HoursMinutesSeconds(totalDayStudyTime)}", - fontSize = 15.sp, - fontWeight = FontWeight.Bold - ) - } - feedEntries.forEach { feedEntry -> - FeedEntry(feedEntry = feedEntry) { - feedActions.continueTask(feedEntry.subjectId, feedEntry.taskId) - } - } - Spacer(modifier = Modifier.height(20.dp)) - } - } -} \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/home/HomeScreen.kt b/app/src/main/java/be/ugent/sel/studeez/screens/home/HomeScreen.kt index 79f03e3..78d5ddb 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/home/HomeScreen.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/home/HomeScreen.kt @@ -5,10 +5,13 @@ import androidx.compose.material.IconButton import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Person import androidx.compose.runtime.Composable +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue import androidx.compose.ui.tooling.preview.Preview import be.ugent.sel.studeez.R import be.ugent.sel.studeez.common.composable.PrimaryScreenTemplate import be.ugent.sel.studeez.common.composable.drawer.DrawerActions +import be.ugent.sel.studeez.common.composable.feed.* import be.ugent.sel.studeez.common.composable.navbar.NavigationBarActions import be.ugent.sel.studeez.resources import kotlinx.coroutines.flow.flowOf @@ -16,16 +19,17 @@ import kotlinx.coroutines.flow.flowOf @Composable fun HomeRoute( open: (String) -> Unit, - viewModel: HomeViewModel, drawerActions: DrawerActions, navigationBarActions: NavigationBarActions, - feedActions: FeedActions, + feedViewModel: FeedViewModel, ) { + val feedUiState by feedViewModel.uiState.collectAsState() HomeScreen( drawerActions = drawerActions, open = open, navigationBarActions = navigationBarActions, - feedActions = feedActions, + feedActions = getFeedActions(feedViewModel, open), + feedUiState = feedUiState, ) } @@ -35,6 +39,7 @@ fun HomeScreen( drawerActions: DrawerActions, navigationBarActions: NavigationBarActions, feedActions: FeedActions, + feedUiState: FeedUiState, ) { PrimaryScreenTemplate( title = resources().getString(R.string.home), @@ -42,7 +47,7 @@ fun HomeScreen( navigationBarActions = navigationBarActions, // TODO barAction = { FriendsAction() } ) { - Feed(feedActions) + Feed(feedActions, feedUiState) } } @@ -63,6 +68,7 @@ fun HomeScreenPreview() { drawerActions = DrawerActions({}, {}, {}, {}, {}), navigationBarActions = NavigationBarActions({ false }, {}, {}, {}, {}, {}, {}, {}), open = {}, - feedActions = FeedActions({ flowOf() }, { _, _ -> run {} }) + feedActions = FeedActions({ flowOf() }, { _, _ -> run {} }), + feedUiState = FeedUiState.Loading, ) } diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/home/HomeViewModel.kt b/app/src/main/java/be/ugent/sel/studeez/screens/home/HomeViewModel.kt deleted file mode 100644 index b27f995..0000000 --- a/app/src/main/java/be/ugent/sel/studeez/screens/home/HomeViewModel.kt +++ /dev/null @@ -1,19 +0,0 @@ -package be.ugent.sel.studeez.screens.home - -import be.ugent.sel.studeez.domain.AccountDAO -import be.ugent.sel.studeez.domain.LogService -import be.ugent.sel.studeez.navigation.StudeezDestinations -import be.ugent.sel.studeez.screens.StudeezViewModel -import dagger.hilt.android.lifecycle.HiltViewModel -import javax.inject.Inject - -@HiltViewModel -class HomeViewModel @Inject constructor( - private val accountDAO: AccountDAO, - logService: LogService -) : StudeezViewModel(logService) { - - fun onStartSessionClick(open: (String) -> Unit) { - open(StudeezDestinations.TIMER_SELECTION_SCREEN) - } -} \ No newline at end of file