refactor feed to use UiState.Loading

This commit is contained in:
brreynie 2023-05-08 21:51:18 +02:00
parent d31276ef81
commit 6ba0018765
8 changed files with 131 additions and 101 deletions

View file

@ -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<Map<String, List<FeedEntry>>>,
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,
)
}

View file

@ -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.*

View file

@ -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<String, List<FeedEntry>>) : FeedUiState
}

View file

@ -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<Map<String, List<FeedEntry>>> = feedDAO.getFeedEntries()
val uiState: StateFlow<FeedUiState> = feedDAO.getFeedEntries()
.map { FeedUiState.Succes(it) }
.stateIn(
scope = viewModelScope,
initialValue = FeedUiState.Loading,
started = SharingStarted.Eagerly,
)
fun getFeedEntries(): Flow<Map<String, List<FeedEntry>>> {
return entries
}

View file

@ -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(),
)
}

View file

@ -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<Map<String, List<FeedEntry>>>,
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))
}
}
}

View file

@ -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,
)
}

View file

@ -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)
}
}