#22 boilerplate for task screen
This commit is contained in:
		
							parent
							
								
									7ad1047091
								
							
						
					
					
						commit
						1a2e192227
					
				
					 10 changed files with 200 additions and 81 deletions
				
			
		|  | @ -40,6 +40,7 @@ import be.ugent.sel.studeez.screens.session.SessionRoute | ||||||
| import be.ugent.sel.studeez.screens.session_recap.SessionRecapRoute | import be.ugent.sel.studeez.screens.session_recap.SessionRecapRoute | ||||||
| import be.ugent.sel.studeez.screens.sign_up.SignUpRoute | import be.ugent.sel.studeez.screens.sign_up.SignUpRoute | ||||||
| import be.ugent.sel.studeez.screens.splash.SplashRoute | import be.ugent.sel.studeez.screens.splash.SplashRoute | ||||||
|  | import be.ugent.sel.studeez.screens.tasks.SubjectRoute | ||||||
| import be.ugent.sel.studeez.screens.tasks.TaskRoute | import be.ugent.sel.studeez.screens.tasks.TaskRoute | ||||||
| import be.ugent.sel.studeez.screens.timer_overview.TimerOverviewRoute | import be.ugent.sel.studeez.screens.timer_overview.TimerOverviewRoute | ||||||
| import be.ugent.sel.studeez.screens.timer_selection.TimerSelectionRoute | import be.ugent.sel.studeez.screens.timer_selection.TimerSelectionRoute | ||||||
|  | @ -146,14 +147,21 @@ fun StudeezNavGraph( | ||||||
|             ) |             ) | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         composable(StudeezDestinations.TASKS_SCREEN) { |         composable(StudeezDestinations.SUBJECT_SCREEN) { | ||||||
|             TaskRoute( |             SubjectRoute( | ||||||
|                 open = open, |                 open = open, | ||||||
|                 viewModel = hiltViewModel(), |                 viewModel = hiltViewModel(), | ||||||
|                 drawerActions = drawerActions, |                 drawerActions = drawerActions, | ||||||
|                 navigationBarActions = navigationBarActions, |                 navigationBarActions = navigationBarActions, | ||||||
|             ) |             ) | ||||||
|         } |         } | ||||||
|  | 
 | ||||||
|  |         composable(StudeezDestinations.TASKS_SCREEN) { | ||||||
|  |             TaskRoute( | ||||||
|  |                 viewModel = hiltViewModel() | ||||||
|  |             ) | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|         // TODO Sessions screen |         // TODO Sessions screen | ||||||
| 
 | 
 | ||||||
|         composable(StudeezDestinations.PROFILE_SCREEN) { |         composable(StudeezDestinations.PROFILE_SCREEN) { | ||||||
|  |  | ||||||
|  | @ -3,6 +3,7 @@ package be.ugent.sel.studeez.common.composable.navbar | ||||||
| import be.ugent.sel.studeez.domain.LogService | import be.ugent.sel.studeez.domain.LogService | ||||||
| import be.ugent.sel.studeez.navigation.StudeezDestinations.HOME_SCREEN | import be.ugent.sel.studeez.navigation.StudeezDestinations.HOME_SCREEN | ||||||
| import be.ugent.sel.studeez.navigation.StudeezDestinations.PROFILE_SCREEN | import be.ugent.sel.studeez.navigation.StudeezDestinations.PROFILE_SCREEN | ||||||
|  | import be.ugent.sel.studeez.navigation.StudeezDestinations.SUBJECT_SCREEN | ||||||
| import be.ugent.sel.studeez.navigation.StudeezDestinations.TASKS_SCREEN | import be.ugent.sel.studeez.navigation.StudeezDestinations.TASKS_SCREEN | ||||||
| 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 | ||||||
|  | @ -18,7 +19,7 @@ class NavigationBarViewModel @Inject constructor( | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     fun onTasksClick(open: (String) -> Unit) { |     fun onTasksClick(open: (String) -> Unit) { | ||||||
|         open(TASKS_SCREEN) |         open(SUBJECT_SCREEN) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     fun onSessionsClick(open: (String) -> Unit) { |     fun onSessionsClick(open: (String) -> Unit) { | ||||||
|  |  | ||||||
|  | @ -30,4 +30,7 @@ abstract class DatabaseModule { | ||||||
| 
 | 
 | ||||||
|     @Binds |     @Binds | ||||||
|     abstract fun provideSubjectDAO(impl: FireBaseSubjectDAO): SubjectDAO |     abstract fun provideSubjectDAO(impl: FireBaseSubjectDAO): SubjectDAO | ||||||
|  | 
 | ||||||
|  |     @Binds | ||||||
|  |     abstract fun provideTaskDAO(impl: FireBaseTaskDAO): TaskDAO | ||||||
| } | } | ||||||
							
								
								
									
										13
									
								
								app/src/main/java/be/ugent/sel/studeez/domain/TaskDAO.kt
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								app/src/main/java/be/ugent/sel/studeez/domain/TaskDAO.kt
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,13 @@ | ||||||
|  | package be.ugent.sel.studeez.domain | ||||||
|  | 
 | ||||||
|  | import be.ugent.sel.studeez.data.local.models.task.Task | ||||||
|  | import kotlinx.coroutines.flow.Flow | ||||||
|  | 
 | ||||||
|  | interface TaskDAO { | ||||||
|  | 
 | ||||||
|  |     fun getTasks(): Flow<List<Task>> | ||||||
|  | 
 | ||||||
|  |     fun saveTask(newTask: Task) | ||||||
|  | 
 | ||||||
|  |     fun deleteTask(oldTask: Task) | ||||||
|  | } | ||||||
|  | @ -0,0 +1,26 @@ | ||||||
|  | package be.ugent.sel.studeez.domain.implementation | ||||||
|  | 
 | ||||||
|  | import be.ugent.sel.studeez.data.local.models.task.Task | ||||||
|  | import be.ugent.sel.studeez.domain.AccountDAO | ||||||
|  | import be.ugent.sel.studeez.domain.TaskDAO | ||||||
|  | import com.google.firebase.firestore.FirebaseFirestore | ||||||
|  | import kotlinx.coroutines.flow.Flow | ||||||
|  | import javax.inject.Inject | ||||||
|  | 
 | ||||||
|  | class FireBaseTaskDAO @Inject constructor( | ||||||
|  |     private val firestore: FirebaseFirestore, | ||||||
|  |     private val auth: AccountDAO, | ||||||
|  | ) : TaskDAO { | ||||||
|  |     override fun getTasks(): Flow<List<Task>> { | ||||||
|  |         TODO("Not yet implemented") | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     override fun saveTask(newTask: Task) { | ||||||
|  |         TODO("Not yet implemented") | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     override fun deleteTask(oldTask: Task) { | ||||||
|  |         TODO("Not yet implemented") | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | @ -10,7 +10,9 @@ object StudeezDestinations { | ||||||
|     const val TIMER_SELECTION_SCREEN = "timer_selection" |     const val TIMER_SELECTION_SCREEN = "timer_selection" | ||||||
|     const val SESSION_SCREEN = "session" |     const val SESSION_SCREEN = "session" | ||||||
|     const val SESSION_RECAP = "session_recap" |     const val SESSION_RECAP = "session_recap" | ||||||
|  |     const val SUBJECT_SCREEN = "subjects" | ||||||
|     const val TASKS_SCREEN = "tasks" |     const val TASKS_SCREEN = "tasks" | ||||||
|  | 
 | ||||||
|     //    const val SESSIONS_SCREEN = "sessions" |     //    const val SESSIONS_SCREEN = "sessions" | ||||||
|     const val PROFILE_SCREEN = "profile" |     const val PROFILE_SCREEN = "profile" | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -0,0 +1,85 @@ | ||||||
|  | package be.ugent.sel.studeez.screens.tasks | ||||||
|  | 
 | ||||||
|  | import androidx.compose.foundation.layout.Column | ||||||
|  | import androidx.compose.foundation.layout.padding | ||||||
|  | import androidx.compose.foundation.lazy.LazyColumn | ||||||
|  | import androidx.compose.foundation.lazy.items | ||||||
|  | import androidx.compose.runtime.Composable | ||||||
|  | import androidx.compose.runtime.collectAsState | ||||||
|  | import androidx.compose.ui.Modifier | ||||||
|  | import androidx.compose.ui.tooling.preview.Preview | ||||||
|  | import androidx.compose.ui.unit.dp | ||||||
|  | import be.ugent.sel.studeez.R | ||||||
|  | import be.ugent.sel.studeez.common.composable.NewTaskSubjectButton | ||||||
|  | import be.ugent.sel.studeez.common.composable.PrimaryScreenTemplate | ||||||
|  | import be.ugent.sel.studeez.common.composable.SubjectEntry | ||||||
|  | import be.ugent.sel.studeez.common.composable.drawer.DrawerActions | ||||||
|  | import be.ugent.sel.studeez.common.composable.navbar.NavigationBarActions | ||||||
|  | import be.ugent.sel.studeez.data.local.models.task.Subject | ||||||
|  | import be.ugent.sel.studeez.resources | ||||||
|  | import kotlinx.coroutines.flow.Flow | ||||||
|  | import kotlinx.coroutines.flow.flowOf | ||||||
|  | 
 | ||||||
|  | @Composable | ||||||
|  | fun SubjectRoute( | ||||||
|  |     open: (String) -> Unit, | ||||||
|  |     viewModel: SubjectViewModel, | ||||||
|  |     drawerActions: DrawerActions, | ||||||
|  |     navigationBarActions: NavigationBarActions, | ||||||
|  | ) { | ||||||
|  |     SubjectScreen( | ||||||
|  |         drawerActions = drawerActions, | ||||||
|  |         navigationBarActions = navigationBarActions, | ||||||
|  |         addSubject = { viewModel.addSubject() }, | ||||||
|  |     ) { viewModel.getSubjects() } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | @Composable | ||||||
|  | fun SubjectScreen( | ||||||
|  |     drawerActions: DrawerActions, | ||||||
|  |     navigationBarActions: NavigationBarActions, | ||||||
|  |     addSubject: () -> Unit, | ||||||
|  |     getSubjects: () -> Flow<List<Subject>>, | ||||||
|  | ) { | ||||||
|  |     PrimaryScreenTemplate( | ||||||
|  |         title = resources().getString(R.string.tasks), | ||||||
|  |         drawerActions = drawerActions, | ||||||
|  |         navigationBarActions = navigationBarActions, | ||||||
|  |         barAction = {}, | ||||||
|  |     ) { | ||||||
|  |         val subjects = getSubjects().collectAsState(initial = emptyList()) | ||||||
|  |         Column( | ||||||
|  |             modifier = Modifier.padding(top = 5.dp) | ||||||
|  |         ) { | ||||||
|  |             LazyColumn { | ||||||
|  | //                if (subjects.value.isNotEmpty()) { | ||||||
|  | //                    item { | ||||||
|  | //                        SubjectEntry(subject = subjects.value[0]) | ||||||
|  | //                    } | ||||||
|  | //                } | ||||||
|  | //                if (subjects.value.size > 1) { | ||||||
|  | //                    items(subjects.value.subList(1, subjects.value.lastIndex + 1)) { | ||||||
|  | //                        Column { | ||||||
|  | //                            Divider(modifier = Modifier.padding(10.dp, 0.dp)) | ||||||
|  | //                            SubjectEntry(subject = it) | ||||||
|  | //                        } | ||||||
|  | //                    } | ||||||
|  | //                } | ||||||
|  |                 items(subjects.value) { | ||||||
|  |                     SubjectEntry(subject = it) | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             NewTaskSubjectButton(onClick = addSubject, R.string.new_subject) | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | @Preview | ||||||
|  | @Composable | ||||||
|  | fun SubjectScreenPreview() { | ||||||
|  |     SubjectScreen( | ||||||
|  |         drawerActions = DrawerActions({}, {}, {}, {}, {}), | ||||||
|  |         navigationBarActions = NavigationBarActions({ false }, {}, {}, {}, {}), | ||||||
|  |         {}, | ||||||
|  |     ) { flowOf() } | ||||||
|  | } | ||||||
|  | @ -0,0 +1,30 @@ | ||||||
|  | package be.ugent.sel.studeez.screens.tasks | ||||||
|  | 
 | ||||||
|  | import be.ugent.sel.studeez.data.local.models.task.Subject | ||||||
|  | import be.ugent.sel.studeez.domain.LogService | ||||||
|  | import be.ugent.sel.studeez.domain.SubjectDAO | ||||||
|  | import be.ugent.sel.studeez.screens.StudeezViewModel | ||||||
|  | import dagger.hilt.android.lifecycle.HiltViewModel | ||||||
|  | import kotlinx.coroutines.flow.Flow | ||||||
|  | import javax.inject.Inject | ||||||
|  | 
 | ||||||
|  | @HiltViewModel | ||||||
|  | class SubjectViewModel @Inject constructor( | ||||||
|  |     private val subjectDAO: SubjectDAO, | ||||||
|  |     logService: LogService, | ||||||
|  | ) : StudeezViewModel(logService) { | ||||||
|  |     fun addSubject() { | ||||||
|  |         subjectDAO.saveSubject( | ||||||
|  |             Subject( | ||||||
|  |                 name = "Test Subject", | ||||||
|  |                 tasks = listOf(), | ||||||
|  |                 time = 0, | ||||||
|  |                 argb_color = 0xFFF44336, | ||||||
|  |             ) | ||||||
|  |         ) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fun getSubjects(): Flow<List<Subject>> { | ||||||
|  |         return subjectDAO.getSubjects() | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -1,86 +1,34 @@ | ||||||
| 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.padding |  | ||||||
| import androidx.compose.foundation.lazy.LazyColumn |  | ||||||
| import androidx.compose.foundation.lazy.items |  | ||||||
| import androidx.compose.material.Divider |  | ||||||
| import androidx.compose.runtime.Composable | import androidx.compose.runtime.Composable | ||||||
| import androidx.compose.runtime.collectAsState |  | ||||||
| import androidx.compose.ui.Modifier |  | ||||||
| import androidx.compose.ui.tooling.preview.Preview | import androidx.compose.ui.tooling.preview.Preview | ||||||
| import androidx.compose.ui.unit.dp | import be.ugent.sel.studeez.data.local.models.task.Task | ||||||
| import be.ugent.sel.studeez.R |  | ||||||
| import be.ugent.sel.studeez.common.composable.NewTaskSubjectButton |  | ||||||
| import be.ugent.sel.studeez.common.composable.PrimaryScreenTemplate |  | ||||||
| import be.ugent.sel.studeez.common.composable.SubjectEntry |  | ||||||
| import be.ugent.sel.studeez.common.composable.drawer.DrawerActions |  | ||||||
| import be.ugent.sel.studeez.common.composable.navbar.NavigationBarActions |  | ||||||
| import be.ugent.sel.studeez.data.local.models.task.Subject |  | ||||||
| import be.ugent.sel.studeez.resources |  | ||||||
| import kotlinx.coroutines.flow.Flow | import kotlinx.coroutines.flow.Flow | ||||||
| import kotlinx.coroutines.flow.flowOf | import kotlinx.coroutines.flow.flowOf | ||||||
| 
 | 
 | ||||||
| @Composable | @Composable | ||||||
| fun TaskRoute( | fun TaskRoute( | ||||||
|     open: (String) -> Unit, |  | ||||||
|     viewModel: TaskViewModel, |     viewModel: TaskViewModel, | ||||||
|     drawerActions: DrawerActions, |  | ||||||
|     navigationBarActions: NavigationBarActions, |  | ||||||
| ) { | ) { | ||||||
|     TaskScreen( |     TaskScreen( | ||||||
|         drawerActions = drawerActions, |         addTask = viewModel::addTask, | ||||||
|         navigationBarActions = navigationBarActions, |         getTasks = viewModel::getTasks, | ||||||
|         addSubject = { viewModel.addSubject() }, |     ) | ||||||
|     ) { viewModel.getSubjects() } |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @Composable | @Composable | ||||||
| fun TaskScreen( | fun TaskScreen( | ||||||
|     drawerActions: DrawerActions, |     addTask: () -> Unit, | ||||||
|     navigationBarActions: NavigationBarActions, |     getTasks: () -> Flow<List<Task>>, | ||||||
|     addSubject: () -> Unit, |  | ||||||
|     getSubjects: () -> Flow<List<Subject>>, |  | ||||||
| ) { | ) { | ||||||
|     PrimaryScreenTemplate( | 
 | ||||||
|         title = resources().getString(R.string.tasks), |  | ||||||
|         drawerActions = drawerActions, |  | ||||||
|         navigationBarActions = navigationBarActions, |  | ||||||
|         barAction = {}, |  | ||||||
|     ) { |  | ||||||
|         val subjects = getSubjects().collectAsState(initial = emptyList()) |  | ||||||
|         Column( |  | ||||||
|             modifier = Modifier.padding(top = 5.dp) |  | ||||||
|         ) { |  | ||||||
|             LazyColumn { |  | ||||||
| //                if (subjects.value.isNotEmpty()) { |  | ||||||
| //                    item { |  | ||||||
| //                        SubjectEntry(subject = subjects.value[0]) |  | ||||||
| //                    } |  | ||||||
| //                } |  | ||||||
| //                if (subjects.value.size > 1) { |  | ||||||
| //                    items(subjects.value.subList(1, subjects.value.lastIndex + 1)) { |  | ||||||
| //                        Column { |  | ||||||
| //                            Divider(modifier = Modifier.padding(10.dp, 0.dp)) |  | ||||||
| //                            SubjectEntry(subject = it) |  | ||||||
| //                        } |  | ||||||
| //                    } |  | ||||||
| //                } |  | ||||||
|                 items(subjects.value) { |  | ||||||
|                     SubjectEntry(subject = it) |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|             NewTaskSubjectButton(onClick = addSubject, R.string.new_subject) |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @Preview | @Preview | ||||||
| @Composable | @Composable | ||||||
| fun TaskScreenPreview() { | fun TaskScreenPreview() { | ||||||
|     TaskScreen( |     TaskScreen( | ||||||
|         drawerActions = DrawerActions({}, {}, {}, {}, {}), |         addTask = {}, | ||||||
|         navigationBarActions = NavigationBarActions({ false }, {}, {}, {}, {}), |         getTasks = { flowOf() } | ||||||
|         {}, |     ) | ||||||
|     ) { flowOf() } |  | ||||||
| } | } | ||||||
|  | @ -1,30 +1,33 @@ | ||||||
| package be.ugent.sel.studeez.screens.tasks | package be.ugent.sel.studeez.screens.tasks | ||||||
| 
 | 
 | ||||||
| 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.LogService | ||||||
| import be.ugent.sel.studeez.domain.SubjectDAO | import be.ugent.sel.studeez.domain.TaskDAO | ||||||
| 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.Flow | ||||||
|  | import kotlinx.coroutines.flow.flowOf | ||||||
| import javax.inject.Inject | import javax.inject.Inject | ||||||
| 
 | 
 | ||||||
| @HiltViewModel | @HiltViewModel | ||||||
| class TaskViewModel @Inject constructor( | class TaskViewModel @Inject constructor( | ||||||
|     private val subjectDAO: SubjectDAO, |     private val taskDAO: TaskDAO, | ||||||
|     logService: LogService, |     logService: LogService, | ||||||
| ) : StudeezViewModel(logService) { | ) : StudeezViewModel(logService) { | ||||||
|     fun addSubject() { |     fun addTask() { | ||||||
|         subjectDAO.saveSubject( | 
 | ||||||
|             Subject( |  | ||||||
|                 name = "Test Subject", |  | ||||||
|                 tasks = listOf(), |  | ||||||
|                 time = 0, |  | ||||||
|                 argb_color = 0xFFF44336, |  | ||||||
|             ) |  | ||||||
|         ) |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     fun getSubjects(): Flow<List<Subject>> { |     fun getTasks() : Flow<List<Task>> { | ||||||
|         return subjectDAO.getSubjects() |         return flowOf(listOf( | ||||||
|  |             Task( | ||||||
|  |                 name = "Test Task", | ||||||
|  |                 completed = false, | ||||||
|  |             ), | ||||||
|  |             Task( | ||||||
|  |                 name = "Test Task 2", | ||||||
|  |                 completed = true, | ||||||
|  |             ) | ||||||
|  |         )) | ||||||
|     } |     } | ||||||
| } | } | ||||||
		Reference in a new issue
	
	 brreynie
						brreynie