"#22 styling of task overview"
This commit is contained in:
		
							parent
							
								
									1a2e192227
								
							
						
					
					
						commit
						e1c05bb0d4
					
				
					 9 changed files with 140 additions and 37 deletions
				
			
		|  | @ -158,7 +158,8 @@ fun StudeezNavGraph( | ||||||
| 
 | 
 | ||||||
|         composable(StudeezDestinations.TASKS_SCREEN) { |         composable(StudeezDestinations.TASKS_SCREEN) { | ||||||
|             TaskRoute( |             TaskRoute( | ||||||
|                 viewModel = hiltViewModel() |                 goBack = goBack, | ||||||
|  |                 viewModel = hiltViewModel(), | ||||||
|             ) |             ) | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -8,7 +8,6 @@ import androidx.compose.foundation.layout.Row | ||||||
| import androidx.compose.foundation.layout.fillMaxWidth | import androidx.compose.foundation.layout.fillMaxWidth | ||||||
| import androidx.compose.foundation.layout.padding | import androidx.compose.foundation.layout.padding | ||||||
| import androidx.compose.foundation.layout.size | import androidx.compose.foundation.layout.size | ||||||
| import androidx.compose.foundation.layout.width |  | ||||||
| import androidx.compose.foundation.shape.CircleShape | import androidx.compose.foundation.shape.CircleShape | ||||||
| import androidx.compose.material.Card | import androidx.compose.material.Card | ||||||
| import androidx.compose.material.Icon | import androidx.compose.material.Icon | ||||||
|  | @ -31,6 +30,7 @@ import be.ugent.sel.studeez.data.local.models.timer_functional.HoursMinutesSecon | ||||||
| @Composable | @Composable | ||||||
| fun SubjectEntry( | fun SubjectEntry( | ||||||
|     subject: Subject, |     subject: Subject, | ||||||
|  |     onViewSubject: () -> Unit, | ||||||
| ) { | ) { | ||||||
|     Card( |     Card( | ||||||
|         modifier = Modifier |         modifier = Modifier | ||||||
|  | @ -40,12 +40,13 @@ fun SubjectEntry( | ||||||
|         Row( |         Row( | ||||||
|             horizontalArrangement = Arrangement.SpaceBetween, |             horizontalArrangement = Arrangement.SpaceBetween, | ||||||
|             verticalAlignment = Alignment.CenterVertically, |             verticalAlignment = Alignment.CenterVertically, | ||||||
| //            modifier = Modifier.fillMaxWidth(), |  | ||||||
|         ) { |         ) { | ||||||
|             Row( |             Row( | ||||||
|                 horizontalArrangement = Arrangement.spacedBy(8.dp), |                 horizontalArrangement = Arrangement.spacedBy(8.dp), | ||||||
|                 verticalAlignment = Alignment.CenterVertically, |                 verticalAlignment = Alignment.CenterVertically, | ||||||
|                 modifier = Modifier.padding(start = 10.dp).weight(3f) |                 modifier = Modifier | ||||||
|  |                     .padding(start = 10.dp) | ||||||
|  |                     .weight(3f) | ||||||
|             ) { |             ) { | ||||||
|                 Box( |                 Box( | ||||||
|                     modifier = Modifier |                     modifier = Modifier | ||||||
|  | @ -61,8 +62,6 @@ fun SubjectEntry( | ||||||
|                         fontWeight = FontWeight.Bold, |                         fontWeight = FontWeight.Bold, | ||||||
|                         overflow = TextOverflow.Ellipsis, |                         overflow = TextOverflow.Ellipsis, | ||||||
|                         maxLines = 1, |                         maxLines = 1, | ||||||
| //                        modifier = Modifier.fillMaxWidth(), |  | ||||||
| //                        modifier = Modifier.width(200.dp) |  | ||||||
|                     ) |                     ) | ||||||
|                     Row( |                     Row( | ||||||
|                         horizontalArrangement = Arrangement.spacedBy(10.dp), |                         horizontalArrangement = Arrangement.spacedBy(10.dp), | ||||||
|  | @ -78,16 +77,18 @@ fun SubjectEntry( | ||||||
|                             Icon( |                             Icon( | ||||||
|                                 imageVector = Icons.Default.List, contentDescription = "tasks" |                                 imageVector = Icons.Default.List, contentDescription = "tasks" | ||||||
|                             ) |                             ) | ||||||
|                             Text(text = "4/9") |                             Text(text = subject.tasks.size.toString()) | ||||||
|                         } |                         } | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|             StealthButton( |             StealthButton( | ||||||
|                 text = R.string.view_task, |                 text = R.string.view_task, | ||||||
|                 modifier = Modifier.padding(start = 10.dp, end = 5.dp).weight(1f) |                 modifier = Modifier | ||||||
|  |                     .padding(start = 10.dp, end = 5.dp) | ||||||
|  |                     .weight(1f) | ||||||
|             ) { |             ) { | ||||||
| 
 |                 onViewSubject() | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  | @ -98,10 +99,9 @@ fun SubjectEntry( | ||||||
| fun SubjectEntryPreview() { | fun SubjectEntryPreview() { | ||||||
|     SubjectEntry( |     SubjectEntry( | ||||||
|         subject = Subject( |         subject = Subject( | ||||||
|             name = "Test Subject longgggggggggggggggggggggggggggggggggggggggg", |             name = "Test Subject", | ||||||
| //            name = "Test Subject", |  | ||||||
|             argb_color = 0xFFF44336, |             argb_color = 0xFFF44336, | ||||||
|             time = 60 |             time = 60 | ||||||
|         ) |         ), | ||||||
|     ) |     ) {} | ||||||
| } | } | ||||||
|  | @ -1,11 +1,12 @@ | ||||||
| package be.ugent.sel.studeez.domain | package be.ugent.sel.studeez.domain | ||||||
| 
 | 
 | ||||||
|  | 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 kotlinx.coroutines.flow.Flow | import kotlinx.coroutines.flow.Flow | ||||||
| 
 | 
 | ||||||
| interface TaskDAO { | interface TaskDAO { | ||||||
| 
 | 
 | ||||||
|     fun getTasks(): Flow<List<Task>> |     fun getTasks(subject: Subject): Flow<List<Task>> | ||||||
| 
 | 
 | ||||||
|     fun saveTask(newTask: Task) |     fun saveTask(newTask: Task) | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1,18 +1,31 @@ | ||||||
| package be.ugent.sel.studeez.domain.implementation | package be.ugent.sel.studeez.domain.implementation | ||||||
| 
 | 
 | ||||||
|  | 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.AccountDAO | import be.ugent.sel.studeez.domain.AccountDAO | ||||||
| import be.ugent.sel.studeez.domain.TaskDAO | import be.ugent.sel.studeez.domain.TaskDAO | ||||||
| import com.google.firebase.firestore.FirebaseFirestore | import com.google.firebase.firestore.FirebaseFirestore | ||||||
| import kotlinx.coroutines.flow.Flow | import kotlinx.coroutines.flow.Flow | ||||||
|  | import kotlinx.coroutines.flow.flowOf | ||||||
| import javax.inject.Inject | import javax.inject.Inject | ||||||
| 
 | 
 | ||||||
| class FireBaseTaskDAO @Inject constructor( | class FireBaseTaskDAO @Inject constructor( | ||||||
|     private val firestore: FirebaseFirestore, |     private val firestore: FirebaseFirestore, | ||||||
|     private val auth: AccountDAO, |     private val auth: AccountDAO, | ||||||
| ) : TaskDAO { | ) : TaskDAO { | ||||||
|     override fun getTasks(): Flow<List<Task>> { |     override fun getTasks(subject: Subject): Flow<List<Task>> { | ||||||
|         TODO("Not yet implemented") |         return flowOf( | ||||||
|  |             listOf( | ||||||
|  |                 Task( | ||||||
|  |                     name = "Test Task", | ||||||
|  |                     completed = false, | ||||||
|  |                 ), | ||||||
|  |                 Task( | ||||||
|  |                     name = "Test Task 2", | ||||||
|  |                     completed = true, | ||||||
|  |                 ) | ||||||
|  |             ) | ||||||
|  |         ) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override fun saveTask(newTask: Task) { |     override fun saveTask(newTask: Task) { | ||||||
|  |  | ||||||
|  | @ -31,7 +31,9 @@ fun SubjectRoute( | ||||||
|         drawerActions = drawerActions, |         drawerActions = drawerActions, | ||||||
|         navigationBarActions = navigationBarActions, |         navigationBarActions = navigationBarActions, | ||||||
|         addSubject = { viewModel.addSubject() }, |         addSubject = { viewModel.addSubject() }, | ||||||
|     ) { viewModel.getSubjects() } |         getSubjects = viewModel::getSubjects, | ||||||
|  |         onViewSubject = { viewModel.onViewSubject(Subject(), open) }, | ||||||
|  |     ) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @Composable | @Composable | ||||||
|  | @ -40,6 +42,7 @@ fun SubjectScreen( | ||||||
|     navigationBarActions: NavigationBarActions, |     navigationBarActions: NavigationBarActions, | ||||||
|     addSubject: () -> Unit, |     addSubject: () -> Unit, | ||||||
|     getSubjects: () -> Flow<List<Subject>>, |     getSubjects: () -> Flow<List<Subject>>, | ||||||
|  |     onViewSubject: () -> Unit, | ||||||
| ) { | ) { | ||||||
|     PrimaryScreenTemplate( |     PrimaryScreenTemplate( | ||||||
|         title = resources().getString(R.string.tasks), |         title = resources().getString(R.string.tasks), | ||||||
|  | @ -66,7 +69,10 @@ fun SubjectScreen( | ||||||
| //                    } | //                    } | ||||||
| //                } | //                } | ||||||
|                 items(subjects.value) { |                 items(subjects.value) { | ||||||
|                     SubjectEntry(subject = it) |                     SubjectEntry( | ||||||
|  |                         subject = it, | ||||||
|  |                         onViewSubject = onViewSubject, | ||||||
|  |                     ) | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|             NewTaskSubjectButton(onClick = addSubject, R.string.new_subject) |             NewTaskSubjectButton(onClick = addSubject, R.string.new_subject) | ||||||
|  | @ -80,6 +86,8 @@ fun SubjectScreenPreview() { | ||||||
|     SubjectScreen( |     SubjectScreen( | ||||||
|         drawerActions = DrawerActions({}, {}, {}, {}, {}), |         drawerActions = DrawerActions({}, {}, {}, {}, {}), | ||||||
|         navigationBarActions = NavigationBarActions({ false }, {}, {}, {}, {}), |         navigationBarActions = NavigationBarActions({ false }, {}, {}, {}, {}), | ||||||
|         {}, |         addSubject = {}, | ||||||
|     ) { flowOf() } |         getSubjects = { flowOf() }, | ||||||
|  |         onViewSubject = {}, | ||||||
|  |     ) | ||||||
| } | } | ||||||
|  | @ -3,6 +3,7 @@ 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.Subject | ||||||
| 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.SubjectDAO | ||||||
|  | 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.Flow | ||||||
|  | @ -27,4 +28,8 @@ class SubjectViewModel @Inject constructor( | ||||||
|     fun getSubjects(): Flow<List<Subject>> { |     fun getSubjects(): Flow<List<Subject>> { | ||||||
|         return subjectDAO.getSubjects() |         return subjectDAO.getSubjects() | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     fun onViewSubject(subject: Subject, open: (String) -> Unit) { | ||||||
|  |         open(StudeezDestinations.TASKS_SCREEN) | ||||||
|  |     } | ||||||
| } | } | ||||||
|  | @ -1,34 +1,115 @@ | ||||||
| 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.ButtonDefaults | ||||||
|  | import androidx.compose.material.Icon | ||||||
|  | import androidx.compose.material.IconButton | ||||||
|  | import androidx.compose.material.Text | ||||||
|  | import androidx.compose.material.icons.Icons | ||||||
|  | import androidx.compose.material.icons.filled.Edit | ||||||
| import androidx.compose.runtime.Composable | import androidx.compose.runtime.Composable | ||||||
|  | import androidx.compose.runtime.collectAsState | ||||||
|  | import androidx.compose.ui.Modifier | ||||||
|  | import androidx.compose.ui.graphics.Color | ||||||
| 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.R | ||||||
|  | import be.ugent.sel.studeez.common.composable.BasicButton | ||||||
|  | import be.ugent.sel.studeez.common.composable.NewTaskSubjectButton | ||||||
|  | import be.ugent.sel.studeez.common.composable.SecondaryScreenTemplate | ||||||
|  | import be.ugent.sel.studeez.common.ext.basicButton | ||||||
|  | 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.resources | ||||||
| import kotlinx.coroutines.flow.Flow | import kotlinx.coroutines.flow.Flow | ||||||
| import kotlinx.coroutines.flow.flowOf | import kotlinx.coroutines.flow.flowOf | ||||||
| 
 | 
 | ||||||
|  | data class TaskActions( | ||||||
|  |     val addTask: () -> Unit, | ||||||
|  |     val getSubject: () -> Subject, | ||||||
|  |     val getTasks: () -> Flow<List<Task>>, | ||||||
|  |     val deleteSubject: () -> Unit, | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | fun getTaskActions(viewModel: TaskViewModel): TaskActions { | ||||||
|  |     return TaskActions( | ||||||
|  |         addTask = viewModel::addTask, | ||||||
|  |         getTasks = viewModel::getTasks, | ||||||
|  |         getSubject = { Subject(name = "Test Subject") }, | ||||||
|  |         deleteSubject = {}, | ||||||
|  |     ) | ||||||
|  | } | ||||||
|  | 
 | ||||||
| @Composable | @Composable | ||||||
| fun TaskRoute( | fun TaskRoute( | ||||||
|  |     goBack: () -> Unit, | ||||||
|     viewModel: TaskViewModel, |     viewModel: TaskViewModel, | ||||||
| ) { | ) { | ||||||
|     TaskScreen( |     TaskScreen( | ||||||
|         addTask = viewModel::addTask, |         goBack = goBack, | ||||||
|         getTasks = viewModel::getTasks, |         taskActions = getTaskActions(viewModel = viewModel), | ||||||
|     ) |     ) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @Composable | @Composable | ||||||
| fun TaskScreen( | fun TaskScreen( | ||||||
|     addTask: () -> Unit, |     goBack: () -> Unit, | ||||||
|     getTasks: () -> Flow<List<Task>>, |     taskActions: TaskActions, | ||||||
| ) { | ) { | ||||||
|  |     SecondaryScreenTemplate( | ||||||
|  |         title = taskActions.getSubject().name, | ||||||
|  |         popUp = goBack, | ||||||
|  |         barAction = { EditAction {} } // TODO implement | ||||||
|  |     ) { | ||||||
|  |         val tasks = taskActions.getTasks().collectAsState(initial = emptyList()) | ||||||
|  |         Column( | ||||||
|  |             modifier = Modifier.padding(top = 5.dp) | ||||||
|  |         ) { | ||||||
|  |             LazyColumn { | ||||||
|  |                 items(tasks.value) { | ||||||
|  |                     Text(text = it.name) | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             NewTaskSubjectButton(onClick = taskActions.addTask, R.string.new_task) | ||||||
|  |             BasicButton( | ||||||
|  |                 text = R.string.delete_subject, | ||||||
|  |                 modifier = Modifier.basicButton(), | ||||||
|  |                 colors = ButtonDefaults.buttonColors( | ||||||
|  |                     backgroundColor = Color.Red, | ||||||
|  |                     contentColor = Color.White, | ||||||
|  |                 ), | ||||||
|  |                 onClick = taskActions.deleteSubject, | ||||||
|  |             ) | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
|  | @Composable | ||||||
|  | fun EditAction( | ||||||
|  |     onClick: () -> Unit | ||||||
|  | ) { | ||||||
|  |     IconButton(onClick = onClick) { | ||||||
|  |         Icon( | ||||||
|  |             imageVector = Icons.Default.Edit, | ||||||
|  |             contentDescription = resources().getString(R.string.edit_task) | ||||||
|  |         ) | ||||||
|  | 
 | ||||||
|  |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @Preview | @Preview | ||||||
| @Composable | @Composable | ||||||
| fun TaskScreenPreview() { | fun TaskScreenPreview() { | ||||||
|     TaskScreen( |     TaskScreen( | ||||||
|         addTask = {}, |         goBack = {}, | ||||||
|         getTasks = { flowOf() } |         taskActions = TaskActions( | ||||||
|  |             {}, | ||||||
|  |             { Subject(name = "Test Subject") }, | ||||||
|  |             { flowOf() }, | ||||||
|  |             {}, | ||||||
|  |         ) | ||||||
|     ) |     ) | ||||||
| } | } | ||||||
|  | @ -1,5 +1,6 @@ | ||||||
| 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.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.TaskDAO | import be.ugent.sel.studeez.domain.TaskDAO | ||||||
|  | @ -19,15 +20,6 @@ class TaskViewModel @Inject constructor( | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     fun getTasks() : Flow<List<Task>> { |     fun getTasks() : Flow<List<Task>> { | ||||||
|         return flowOf(listOf( |         return taskDAO.getTasks(Subject()) | ||||||
|             Task( |  | ||||||
|                 name = "Test Task", |  | ||||||
|                 completed = false, |  | ||||||
|             ), |  | ||||||
|             Task( |  | ||||||
|                 name = "Test Task 2", |  | ||||||
|                 completed = true, |  | ||||||
|             ) |  | ||||||
|         )) |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | @ -45,6 +45,8 @@ | ||||||
|     <string name="new_subject">New Subject</string> |     <string name="new_subject">New Subject</string> | ||||||
|     <string name="new_task">New Task</string> |     <string name="new_task">New Task</string> | ||||||
|     <string name="view_task">View</string> |     <string name="view_task">View</string> | ||||||
|  |     <string name="edit_task">Edit Task</string> | ||||||
|  |     <string name="delete_subject">Delete Subject</string> | ||||||
| 
 | 
 | ||||||
|     <!-- Sessions --> |     <!-- Sessions --> | ||||||
|     <string name="sessions">Sessions</string> |     <string name="sessions">Sessions</string> | ||||||
|  |  | ||||||
		Reference in a new issue
	
	 brreynie
						brreynie