From ec31e116b4c3e0bf5bcded46a7ce9fa35c3770ee Mon Sep 17 00:00:00 2001 From: brreynie Date: Tue, 9 May 2023 21:29:52 +0200 Subject: [PATCH] refactor subjectscreen to use uiState --- .../common/composable/feed/FeedViewModel.kt | 6 +- .../studeez/data/local/models/task/Subject.kt | 3 +- .../studeez/data/local/models/task/Task.kt | 2 +- .../studeez/screens/tasks/SubjectScreen.kt | 76 ++++++++++++++----- .../studeez/screens/tasks/SubjectUiState.kt | 8 ++ .../studeez/screens/tasks/SubjectViewModel.kt | 18 +++-- .../studeez/screens/tasks/TaskViewModel.kt | 13 +--- 7 files changed, 84 insertions(+), 42 deletions(-) create mode 100644 app/src/main/java/be/ugent/sel/studeez/screens/tasks/SubjectUiState.kt diff --git a/app/src/main/java/be/ugent/sel/studeez/common/composable/feed/FeedViewModel.kt b/app/src/main/java/be/ugent/sel/studeez/common/composable/feed/FeedViewModel.kt index 443d0c9..13d134b 100644 --- a/app/src/main/java/be/ugent/sel/studeez/common/composable/feed/FeedViewModel.kt +++ b/app/src/main/java/be/ugent/sel/studeez/common/composable/feed/FeedViewModel.kt @@ -2,14 +2,16 @@ package be.ugent.sel.studeez.common.composable.feed import androidx.lifecycle.viewModelScope import be.ugent.sel.studeez.data.SelectedTask -import be.ugent.sel.studeez.data.local.models.FeedEntry import be.ugent.sel.studeez.domain.FeedDAO import be.ugent.sel.studeez.domain.LogService 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.* +import kotlinx.coroutines.flow.SharingStarted +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.launch import javax.inject.Inject diff --git a/app/src/main/java/be/ugent/sel/studeez/data/local/models/task/Subject.kt b/app/src/main/java/be/ugent/sel/studeez/data/local/models/task/Subject.kt index 622ef3c..6f29e22 100644 --- a/app/src/main/java/be/ugent/sel/studeez/data/local/models/task/Subject.kt +++ b/app/src/main/java/be/ugent/sel/studeez/data/local/models/task/Subject.kt @@ -6,10 +6,11 @@ import com.google.firebase.firestore.Exclude data class Subject( @DocumentId val id: String = "", val name: String = "", - val time: Int = 0, val argb_color: Long = 0, @get:Exclude @set:Exclude var taskCount: Int = 0, @get:Exclude @set:Exclude var taskCompletedCount: Int = 0, + @get:Exclude @set:Exclude + var time: Int = 0, ) diff --git a/app/src/main/java/be/ugent/sel/studeez/data/local/models/task/Task.kt b/app/src/main/java/be/ugent/sel/studeez/data/local/models/task/Task.kt index 44d6d01..e42ce5d 100644 --- a/app/src/main/java/be/ugent/sel/studeez/data/local/models/task/Task.kt +++ b/app/src/main/java/be/ugent/sel/studeez/data/local/models/task/Task.kt @@ -5,7 +5,7 @@ import com.google.firebase.firestore.DocumentId data class Task( @DocumentId val id: String = "", val name: String = "", - val completed: Boolean = false, + var completed: Boolean = false, val time: Int = 0, val subjectId: String = "", var archived: Boolean = false, diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/tasks/SubjectScreen.kt b/app/src/main/java/be/ugent/sel/studeez/screens/tasks/SubjectScreen.kt index a3395ea..115c75e 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/tasks/SubjectScreen.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/tasks/SubjectScreen.kt @@ -1,11 +1,14 @@ package be.ugent.sel.studeez.screens.tasks -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.padding +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.runtime.Composable import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview @@ -16,8 +19,6 @@ import be.ugent.sel.studeez.common.composable.drawer.DrawerActions import be.ugent.sel.studeez.common.composable.navbar.NavigationBarActions import be.ugent.sel.studeez.common.composable.tasks.SubjectEntry import be.ugent.sel.studeez.data.local.models.task.Subject -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.flowOf import be.ugent.sel.studeez.R.string as AppText @Composable @@ -27,12 +28,13 @@ fun SubjectRoute( drawerActions: DrawerActions, navigationBarActions: NavigationBarActions, ) { + val uiState by viewModel.uiState.collectAsState() SubjectScreen( drawerActions = drawerActions, navigationBarActions = navigationBarActions, - addSubject = { viewModel.addSubject(open) }, - getSubjects = viewModel::getSubjects, + onAddSubject = { viewModel.onAddSubject(open) }, onViewSubject = { viewModel.onViewSubject(it, open) }, + uiState, ) } @@ -40,9 +42,9 @@ fun SubjectRoute( fun SubjectScreen( drawerActions: DrawerActions, navigationBarActions: NavigationBarActions, - addSubject: () -> Unit, - getSubjects: () -> Flow>, + onAddSubject: () -> Unit, onViewSubject: (Subject) -> Unit, + uiState: SubjectUiState, ) { PrimaryScreenTemplate( title = stringResource(AppText.my_subjects), @@ -50,17 +52,29 @@ fun SubjectScreen( navigationBarActions = navigationBarActions, barAction = {}, ) { - val subjects = getSubjects().collectAsState(initial = emptyList()) - Column( - modifier = Modifier.padding(top = 5.dp) - ) { - NewTaskSubjectButton(onClick = addSubject, AppText.new_subject) - LazyColumn { - items(subjects.value) { - SubjectEntry( - subject = it, - onViewSubject = { onViewSubject(it) }, - ) + when (uiState) { + SubjectUiState.Loading -> Column( + modifier = Modifier + .fillMaxWidth() + .fillMaxHeight(), + verticalArrangement = Arrangement.Center, + horizontalAlignment = Alignment.CenterHorizontally + ) { + CircularProgressIndicator(color = MaterialTheme.colors.onBackground) + } + is SubjectUiState.Succes -> { + Column( + modifier = Modifier.padding(top = 5.dp) + ) { + NewTaskSubjectButton(onClick = onAddSubject, AppText.new_subject) + LazyColumn { + items(uiState.subjects) { + SubjectEntry( + subject = it, + onViewSubject = { onViewSubject(it) }, + ) + } + } } } } @@ -73,8 +87,28 @@ fun SubjectScreenPreview() { SubjectScreen( drawerActions = DrawerActions({}, {}, {}, {}, {}), navigationBarActions = NavigationBarActions({ false }, {}, {}, {}, {}, {}, {}, {}), - addSubject = {}, - getSubjects = { flowOf() }, + onAddSubject = {}, onViewSubject = {}, + uiState = SubjectUiState.Succes( + listOf( + Subject( + name = "Test Subject", + argb_color = 0xFFFFD200, + taskCount = 5, taskCompletedCount = 2, + ) + ) + ) + ) +} + +@Preview +@Composable +fun SubjectScreenLoadingPreview() { + SubjectScreen( + drawerActions = DrawerActions({}, {}, {}, {}, {}), + navigationBarActions = NavigationBarActions({ false }, {}, {}, {}, {}, {}, {}, {}), + onAddSubject = {}, + onViewSubject = {}, + uiState = SubjectUiState.Loading ) } \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/tasks/SubjectUiState.kt b/app/src/main/java/be/ugent/sel/studeez/screens/tasks/SubjectUiState.kt new file mode 100644 index 0000000..38adae4 --- /dev/null +++ b/app/src/main/java/be/ugent/sel/studeez/screens/tasks/SubjectUiState.kt @@ -0,0 +1,8 @@ +package be.ugent.sel.studeez.screens.tasks + +import be.ugent.sel.studeez.data.local.models.task.Subject + +sealed interface SubjectUiState { + object Loading : SubjectUiState + data class Succes(val subjects: List) : SubjectUiState +} \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/tasks/SubjectViewModel.kt b/app/src/main/java/be/ugent/sel/studeez/screens/tasks/SubjectViewModel.kt index f1d6071..8587327 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/tasks/SubjectViewModel.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/tasks/SubjectViewModel.kt @@ -1,5 +1,6 @@ package be.ugent.sel.studeez.screens.tasks +import androidx.lifecycle.viewModelScope import be.ugent.sel.studeez.data.SelectedSubject import be.ugent.sel.studeez.data.local.models.task.Subject import be.ugent.sel.studeez.domain.LogService @@ -7,7 +8,7 @@ import be.ugent.sel.studeez.domain.SubjectDAO 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 javax.inject.Inject @HiltViewModel @@ -16,12 +17,17 @@ class SubjectViewModel @Inject constructor( private val selectedSubject: SelectedSubject, logService: LogService, ) : StudeezViewModel(logService) { - fun addSubject(open: (String) -> Unit) { - open(StudeezDestinations.ADD_SUBJECT_FORM) - } - fun getSubjects(): Flow> { - return subjectDAO.getSubjects() + val uiState: StateFlow = subjectDAO.getSubjects() + .map { SubjectUiState.Succes(it) } + .stateIn( + scope = viewModelScope, + initialValue = SubjectUiState.Loading, + started = SharingStarted.Eagerly, + ) + + fun onAddSubject(open: (String) -> Unit) { + open(StudeezDestinations.ADD_SUBJECT_FORM) } fun onViewSubject(subject: Subject, open: (String) -> Unit) { diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/tasks/TaskViewModel.kt b/app/src/main/java/be/ugent/sel/studeez/screens/tasks/TaskViewModel.kt index 2361399..e2adbc1 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/tasks/TaskViewModel.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/tasks/TaskViewModel.kt @@ -1,12 +1,10 @@ package be.ugent.sel.studeez.screens.tasks -import android.util.Log import be.ugent.sel.studeez.data.SelectedSubject import be.ugent.sel.studeez.data.SelectedTask import be.ugent.sel.studeez.data.local.models.task.Subject import be.ugent.sel.studeez.data.local.models.task.Task import be.ugent.sel.studeez.domain.LogService -import be.ugent.sel.studeez.domain.SubjectDAO import be.ugent.sel.studeez.domain.TaskDAO import be.ugent.sel.studeez.navigation.StudeezDestinations import be.ugent.sel.studeez.screens.StudeezViewModel @@ -17,7 +15,6 @@ import javax.inject.Inject @HiltViewModel class TaskViewModel @Inject constructor( private val taskDAO: TaskDAO, - private val subjectDAO: SubjectDAO, private val selectedSubject: SelectedSubject, private val selectedTask: SelectedTask, logService: LogService, @@ -30,11 +27,6 @@ class TaskViewModel @Inject constructor( return taskDAO.getTasks(selectedSubject()) } - fun deleteSubject(open: (String) -> Unit) { - subjectDAO.deleteSubject(selectedSubject()) - open(StudeezDestinations.SUBJECT_SCREEN) - } - fun getSelectedSubject(): Subject { return selectedSubject() } @@ -44,12 +36,11 @@ class TaskViewModel @Inject constructor( } fun archiveTask(task: Task) { - task.archive() - taskDAO.updateTask(task) + taskDAO.updateTask(task.copy(archived = true)) } fun toggleTaskCompleted(task: Task, completed: Boolean) { - taskDAO.toggleTaskCompleted(task, completed) + taskDAO.updateTask(task.copy(completed = completed)) } fun editSubject(open: (String) -> Unit) {