refactor subjectscreen to use uiState
This commit is contained in:
		
							parent
							
								
									a60422e004
								
							
						
					
					
						commit
						ec31e116b4
					
				
					 7 changed files with 84 additions and 42 deletions
				
			
		|  | @ -2,14 +2,16 @@ package be.ugent.sel.studeez.common.composable.feed | ||||||
| 
 | 
 | ||||||
| import androidx.lifecycle.viewModelScope | import androidx.lifecycle.viewModelScope | ||||||
| import be.ugent.sel.studeez.data.SelectedTask | 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.FeedDAO | ||||||
| import be.ugent.sel.studeez.domain.LogService | import be.ugent.sel.studeez.domain.LogService | ||||||
| import be.ugent.sel.studeez.domain.TaskDAO | import be.ugent.sel.studeez.domain.TaskDAO | ||||||
| import be.ugent.sel.studeez.navigation.StudeezDestinations | import be.ugent.sel.studeez.navigation.StudeezDestinations | ||||||
| import be.ugent.sel.studeez.screens.StudeezViewModel | import be.ugent.sel.studeez.screens.StudeezViewModel | ||||||
| import dagger.hilt.android.lifecycle.HiltViewModel | 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 kotlinx.coroutines.launch | ||||||
| import javax.inject.Inject | import javax.inject.Inject | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -6,10 +6,11 @@ import com.google.firebase.firestore.Exclude | ||||||
| data class Subject( | data class Subject( | ||||||
|     @DocumentId val id: String = "", |     @DocumentId val id: String = "", | ||||||
|     val name: String = "", |     val name: String = "", | ||||||
|     val time: Int = 0, |  | ||||||
|     val argb_color: Long = 0, |     val argb_color: Long = 0, | ||||||
|     @get:Exclude @set:Exclude |     @get:Exclude @set:Exclude | ||||||
|     var taskCount: Int = 0, |     var taskCount: Int = 0, | ||||||
|     @get:Exclude @set:Exclude |     @get:Exclude @set:Exclude | ||||||
|     var taskCompletedCount: Int = 0, |     var taskCompletedCount: Int = 0, | ||||||
|  |     @get:Exclude @set:Exclude | ||||||
|  |     var time: Int = 0, | ||||||
| ) | ) | ||||||
|  |  | ||||||
|  | @ -5,7 +5,7 @@ import com.google.firebase.firestore.DocumentId | ||||||
| data class Task( | data class Task( | ||||||
|     @DocumentId val id: String = "", |     @DocumentId val id: String = "", | ||||||
|     val name: String = "", |     val name: String = "", | ||||||
|     val completed: Boolean = false, |     var completed: Boolean = false, | ||||||
|     val time: Int = 0, |     val time: Int = 0, | ||||||
|     val subjectId: String = "", |     val subjectId: String = "", | ||||||
|     var archived: Boolean = false, |     var archived: Boolean = false, | ||||||
|  |  | ||||||
|  | @ -1,11 +1,14 @@ | ||||||
| package be.ugent.sel.studeez.screens.tasks | package be.ugent.sel.studeez.screens.tasks | ||||||
| 
 | 
 | ||||||
| import androidx.compose.foundation.layout.Column | import androidx.compose.foundation.layout.* | ||||||
| import androidx.compose.foundation.layout.padding |  | ||||||
| import androidx.compose.foundation.lazy.LazyColumn | import androidx.compose.foundation.lazy.LazyColumn | ||||||
| import androidx.compose.foundation.lazy.items | 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.Composable | ||||||
| import androidx.compose.runtime.collectAsState | import androidx.compose.runtime.collectAsState | ||||||
|  | import androidx.compose.runtime.getValue | ||||||
|  | import androidx.compose.ui.Alignment | ||||||
| import androidx.compose.ui.Modifier | import androidx.compose.ui.Modifier | ||||||
| import androidx.compose.ui.res.stringResource | import androidx.compose.ui.res.stringResource | ||||||
| import androidx.compose.ui.tooling.preview.Preview | 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.navbar.NavigationBarActions | ||||||
| import be.ugent.sel.studeez.common.composable.tasks.SubjectEntry | import be.ugent.sel.studeez.common.composable.tasks.SubjectEntry | ||||||
| import be.ugent.sel.studeez.data.local.models.task.Subject | 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 | import be.ugent.sel.studeez.R.string as AppText | ||||||
| 
 | 
 | ||||||
| @Composable | @Composable | ||||||
|  | @ -27,12 +28,13 @@ fun SubjectRoute( | ||||||
|     drawerActions: DrawerActions, |     drawerActions: DrawerActions, | ||||||
|     navigationBarActions: NavigationBarActions, |     navigationBarActions: NavigationBarActions, | ||||||
| ) { | ) { | ||||||
|  |     val uiState by viewModel.uiState.collectAsState() | ||||||
|     SubjectScreen( |     SubjectScreen( | ||||||
|         drawerActions = drawerActions, |         drawerActions = drawerActions, | ||||||
|         navigationBarActions = navigationBarActions, |         navigationBarActions = navigationBarActions, | ||||||
|         addSubject = { viewModel.addSubject(open) }, |         onAddSubject = { viewModel.onAddSubject(open) }, | ||||||
|         getSubjects = viewModel::getSubjects, |  | ||||||
|         onViewSubject = { viewModel.onViewSubject(it, open) }, |         onViewSubject = { viewModel.onViewSubject(it, open) }, | ||||||
|  |         uiState, | ||||||
|     ) |     ) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -40,9 +42,9 @@ fun SubjectRoute( | ||||||
| fun SubjectScreen( | fun SubjectScreen( | ||||||
|     drawerActions: DrawerActions, |     drawerActions: DrawerActions, | ||||||
|     navigationBarActions: NavigationBarActions, |     navigationBarActions: NavigationBarActions, | ||||||
|     addSubject: () -> Unit, |     onAddSubject: () -> Unit, | ||||||
|     getSubjects: () -> Flow<List<Subject>>, |  | ||||||
|     onViewSubject: (Subject) -> Unit, |     onViewSubject: (Subject) -> Unit, | ||||||
|  |     uiState: SubjectUiState, | ||||||
| ) { | ) { | ||||||
|     PrimaryScreenTemplate( |     PrimaryScreenTemplate( | ||||||
|         title = stringResource(AppText.my_subjects), |         title = stringResource(AppText.my_subjects), | ||||||
|  | @ -50,17 +52,29 @@ fun SubjectScreen( | ||||||
|         navigationBarActions = navigationBarActions, |         navigationBarActions = navigationBarActions, | ||||||
|         barAction = {}, |         barAction = {}, | ||||||
|     ) { |     ) { | ||||||
|         val subjects = getSubjects().collectAsState(initial = emptyList()) |         when (uiState) { | ||||||
|         Column( |             SubjectUiState.Loading -> Column( | ||||||
|             modifier = Modifier.padding(top = 5.dp) |                 modifier = Modifier | ||||||
|         ) { |                     .fillMaxWidth() | ||||||
|             NewTaskSubjectButton(onClick = addSubject, AppText.new_subject) |                     .fillMaxHeight(), | ||||||
|             LazyColumn { |                 verticalArrangement = Arrangement.Center, | ||||||
|                 items(subjects.value) { |                 horizontalAlignment = Alignment.CenterHorizontally | ||||||
|                     SubjectEntry( |             ) { | ||||||
|                         subject = it, |                 CircularProgressIndicator(color = MaterialTheme.colors.onBackground) | ||||||
|                         onViewSubject = { onViewSubject(it) }, |             } | ||||||
|                     ) |             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( |     SubjectScreen( | ||||||
|         drawerActions = DrawerActions({}, {}, {}, {}, {}), |         drawerActions = DrawerActions({}, {}, {}, {}, {}), | ||||||
|         navigationBarActions = NavigationBarActions({ false }, {}, {}, {}, {}, {}, {}, {}), |         navigationBarActions = NavigationBarActions({ false }, {}, {}, {}, {}, {}, {}, {}), | ||||||
|         addSubject = {}, |         onAddSubject = {}, | ||||||
|         getSubjects = { flowOf() }, |  | ||||||
|         onViewSubject = {}, |         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 | ||||||
|     ) |     ) | ||||||
| } | } | ||||||
|  | @ -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<Subject>) : SubjectUiState | ||||||
|  | } | ||||||
|  | @ -1,5 +1,6 @@ | ||||||
| package be.ugent.sel.studeez.screens.tasks | package be.ugent.sel.studeez.screens.tasks | ||||||
| 
 | 
 | ||||||
|  | import androidx.lifecycle.viewModelScope | ||||||
| import be.ugent.sel.studeez.data.SelectedSubject | import be.ugent.sel.studeez.data.SelectedSubject | ||||||
| import be.ugent.sel.studeez.data.local.models.task.Subject | import be.ugent.sel.studeez.data.local.models.task.Subject | ||||||
| import be.ugent.sel.studeez.domain.LogService | 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.navigation.StudeezDestinations | ||||||
| import be.ugent.sel.studeez.screens.StudeezViewModel | import be.ugent.sel.studeez.screens.StudeezViewModel | ||||||
| import dagger.hilt.android.lifecycle.HiltViewModel | import dagger.hilt.android.lifecycle.HiltViewModel | ||||||
| import kotlinx.coroutines.flow.Flow | import kotlinx.coroutines.flow.* | ||||||
| import javax.inject.Inject | import javax.inject.Inject | ||||||
| 
 | 
 | ||||||
| @HiltViewModel | @HiltViewModel | ||||||
|  | @ -16,12 +17,17 @@ class SubjectViewModel @Inject constructor( | ||||||
|     private val selectedSubject: SelectedSubject, |     private val selectedSubject: SelectedSubject, | ||||||
|     logService: LogService, |     logService: LogService, | ||||||
| ) : StudeezViewModel(logService) { | ) : StudeezViewModel(logService) { | ||||||
|     fun addSubject(open: (String) -> Unit) { |  | ||||||
|         open(StudeezDestinations.ADD_SUBJECT_FORM) |  | ||||||
|     } |  | ||||||
| 
 | 
 | ||||||
|     fun getSubjects(): Flow<List<Subject>> { |     val uiState: StateFlow<SubjectUiState> = subjectDAO.getSubjects() | ||||||
|         return 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) { |     fun onViewSubject(subject: Subject, open: (String) -> Unit) { | ||||||
|  |  | ||||||
|  | @ -1,12 +1,10 @@ | ||||||
| package be.ugent.sel.studeez.screens.tasks | package be.ugent.sel.studeez.screens.tasks | ||||||
| 
 | 
 | ||||||
| import android.util.Log |  | ||||||
| import be.ugent.sel.studeez.data.SelectedSubject | import be.ugent.sel.studeez.data.SelectedSubject | ||||||
| import be.ugent.sel.studeez.data.SelectedTask | 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.Subject | ||||||
| import be.ugent.sel.studeez.data.local.models.task.Task | import be.ugent.sel.studeez.data.local.models.task.Task | ||||||
| import be.ugent.sel.studeez.domain.LogService | 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.domain.TaskDAO | ||||||
| import be.ugent.sel.studeez.navigation.StudeezDestinations | import be.ugent.sel.studeez.navigation.StudeezDestinations | ||||||
| import be.ugent.sel.studeez.screens.StudeezViewModel | import be.ugent.sel.studeez.screens.StudeezViewModel | ||||||
|  | @ -17,7 +15,6 @@ import javax.inject.Inject | ||||||
| @HiltViewModel | @HiltViewModel | ||||||
| class TaskViewModel @Inject constructor( | class TaskViewModel @Inject constructor( | ||||||
|     private val taskDAO: TaskDAO, |     private val taskDAO: TaskDAO, | ||||||
|     private val subjectDAO: SubjectDAO, |  | ||||||
|     private val selectedSubject: SelectedSubject, |     private val selectedSubject: SelectedSubject, | ||||||
|     private val selectedTask: SelectedTask, |     private val selectedTask: SelectedTask, | ||||||
|     logService: LogService, |     logService: LogService, | ||||||
|  | @ -30,11 +27,6 @@ class TaskViewModel @Inject constructor( | ||||||
|         return taskDAO.getTasks(selectedSubject()) |         return taskDAO.getTasks(selectedSubject()) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     fun deleteSubject(open: (String) -> Unit) { |  | ||||||
|         subjectDAO.deleteSubject(selectedSubject()) |  | ||||||
|         open(StudeezDestinations.SUBJECT_SCREEN) |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     fun getSelectedSubject(): Subject { |     fun getSelectedSubject(): Subject { | ||||||
|         return selectedSubject() |         return selectedSubject() | ||||||
|     } |     } | ||||||
|  | @ -44,12 +36,11 @@ class TaskViewModel @Inject constructor( | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     fun archiveTask(task: Task) { |     fun archiveTask(task: Task) { | ||||||
|         task.archive() |         taskDAO.updateTask(task.copy(archived = true)) | ||||||
|         taskDAO.updateTask(task) |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     fun toggleTaskCompleted(task: Task, completed: Boolean) { |     fun toggleTaskCompleted(task: Task, completed: Boolean) { | ||||||
|         taskDAO.toggleTaskCompleted(task, completed) |         taskDAO.updateTask(task.copy(completed = completed)) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     fun editSubject(open: (String) -> Unit) { |     fun editSubject(open: (String) -> Unit) { | ||||||
|  |  | ||||||
		Reference in a new issue
	
	 brreynie
						brreynie