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 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
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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,
 | 
			
		||||
)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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<List<Subject>>,
 | 
			
		||||
    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
 | 
			
		||||
    )
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
 | 
			
		||||
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<List<Subject>> {
 | 
			
		||||
        return subjectDAO.getSubjects()
 | 
			
		||||
    val uiState: StateFlow<SubjectUiState> = 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) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Reference in a new issue