From d03775000a4299c08033fe7a7c83d3c00ac64cf3 Mon Sep 17 00:00:00 2001 From: brreynie Date: Sat, 29 Apr 2023 12:28:30 +0200 Subject: [PATCH 01/22] #21 basic subject list --- .idea/misc.xml | 1 - .../java/be/ugent/sel/studeez/StudeezApp.kt | 10 ++- .../studeez/common/composable/SubjectEntry.kt | 19 +++++ .../navbar/NavigationBarViewModel.kt | 5 +- .../data/local/models/SessionReport.kt | 2 +- .../studeez/data/local/models/task/Subject.kt | 11 +++ .../studeez/data/local/models/task/Task.kt | 9 +++ .../be/ugent/sel/studeez/di/DatabaseModule.kt | 21 +++-- .../be/ugent/sel/studeez/domain/SubjectDAO.kt | 13 ++++ ...ectionRoutes.kt => FireBaseCollections.kt} | 4 +- .../implementation/FireBaseSessionDAO.kt | 5 +- .../implementation/FireBaseSubjectDAO.kt | 35 +++++++++ .../domain/implementation/FirebaseTimerDAO.kt | 6 +- .../studeez/navigation/StudeezDestinations.kt | 2 +- .../sel/studeez/screens/tasks/TaskScreen.kt | 77 +++++++++++++++++++ .../studeez/screens/tasks/TaskViewModel.kt | 30 ++++++++ 16 files changed, 228 insertions(+), 22 deletions(-) create mode 100644 app/src/main/java/be/ugent/sel/studeez/common/composable/SubjectEntry.kt create mode 100644 app/src/main/java/be/ugent/sel/studeez/data/local/models/task/Subject.kt create mode 100644 app/src/main/java/be/ugent/sel/studeez/data/local/models/task/Task.kt create mode 100644 app/src/main/java/be/ugent/sel/studeez/domain/SubjectDAO.kt rename app/src/main/java/be/ugent/sel/studeez/domain/implementation/{FirebaseCollectionRoutes.kt => FireBaseCollections.kt} (70%) create mode 100644 app/src/main/java/be/ugent/sel/studeez/domain/implementation/FireBaseSubjectDAO.kt create mode 100644 app/src/main/java/be/ugent/sel/studeez/screens/tasks/TaskScreen.kt create mode 100644 app/src/main/java/be/ugent/sel/studeez/screens/tasks/TaskViewModel.kt diff --git a/.idea/misc.xml b/.idea/misc.xml index 4412b1a..aa62d28 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,4 +1,3 @@ - diff --git a/app/src/main/java/be/ugent/sel/studeez/StudeezApp.kt b/app/src/main/java/be/ugent/sel/studeez/StudeezApp.kt index c8a133b..d72bedf 100644 --- a/app/src/main/java/be/ugent/sel/studeez/StudeezApp.kt +++ b/app/src/main/java/be/ugent/sel/studeez/StudeezApp.kt @@ -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.sign_up.SignUpRoute import be.ugent.sel.studeez.screens.splash.SplashRoute +import be.ugent.sel.studeez.screens.tasks.TaskRoute import be.ugent.sel.studeez.screens.timer_overview.TimerOverviewRoute import be.ugent.sel.studeez.screens.timer_selection.TimerSelectionRoute import be.ugent.sel.studeez.ui.theme.StudeezTheme @@ -145,7 +146,14 @@ fun StudeezNavGraph( ) } - // TODO Tasks screen + composable(StudeezDestinations.TASKS_SCREEN) { + TaskRoute( + open = open, + viewModel = hiltViewModel(), + drawerActions = drawerActions, + navigationBarActions = navigationBarActions, + ) + } // TODO Sessions screen composable(StudeezDestinations.PROFILE_SCREEN) { diff --git a/app/src/main/java/be/ugent/sel/studeez/common/composable/SubjectEntry.kt b/app/src/main/java/be/ugent/sel/studeez/common/composable/SubjectEntry.kt new file mode 100644 index 0000000..928ab36 --- /dev/null +++ b/app/src/main/java/be/ugent/sel/studeez/common/composable/SubjectEntry.kt @@ -0,0 +1,19 @@ +package be.ugent.sel.studeez.common.composable + +import androidx.compose.material.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.tooling.preview.Preview +import be.ugent.sel.studeez.data.local.models.task.Subject + +@Composable +fun SubjectEntry( + subject: Subject, +) { + Text(text = subject.name) +} + +@Preview +@Composable +fun SubjectEntryPreview() { + SubjectEntry(subject = Subject(name = "Test Subject")) +} \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/common/composable/navbar/NavigationBarViewModel.kt b/app/src/main/java/be/ugent/sel/studeez/common/composable/navbar/NavigationBarViewModel.kt index 1e4bd0d..7b1d012 100644 --- a/app/src/main/java/be/ugent/sel/studeez/common/composable/navbar/NavigationBarViewModel.kt +++ b/app/src/main/java/be/ugent/sel/studeez/common/composable/navbar/NavigationBarViewModel.kt @@ -1,16 +1,15 @@ package be.ugent.sel.studeez.common.composable.navbar -import be.ugent.sel.studeez.domain.AccountDAO import be.ugent.sel.studeez.domain.LogService 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.TASKS_SCREEN import be.ugent.sel.studeez.screens.StudeezViewModel import dagger.hilt.android.lifecycle.HiltViewModel import javax.inject.Inject @HiltViewModel class NavigationBarViewModel @Inject constructor( - private val accountDAO: AccountDAO, logService: LogService ) : StudeezViewModel(logService) { @@ -19,7 +18,7 @@ class NavigationBarViewModel @Inject constructor( } fun onTasksClick(open: (String) -> Unit) { - // TODO + open(TASKS_SCREEN) } fun onSessionsClick(open: (String) -> Unit) { diff --git a/app/src/main/java/be/ugent/sel/studeez/data/local/models/SessionReport.kt b/app/src/main/java/be/ugent/sel/studeez/data/local/models/SessionReport.kt index af6b1c0..20a44a8 100644 --- a/app/src/main/java/be/ugent/sel/studeez/data/local/models/SessionReport.kt +++ b/app/src/main/java/be/ugent/sel/studeez/data/local/models/SessionReport.kt @@ -7,4 +7,4 @@ data class SessionReport( @DocumentId val id: String = "", val studyTime: Int = 0, val endTime: Timestamp = Timestamp(0, 0) - ) \ No newline at end of file +) \ No newline at end of file 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 new file mode 100644 index 0000000..034711a --- /dev/null +++ b/app/src/main/java/be/ugent/sel/studeez/data/local/models/task/Subject.kt @@ -0,0 +1,11 @@ +package be.ugent.sel.studeez.data.local.models.task + +import com.google.firebase.firestore.DocumentId + +data class Subject( + @DocumentId val id: String = "", + val name: String = "", + val tasks: List = mutableListOf(), + val time: Int = 0, + val color: Int = 0, +) \ No newline at end of file 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 new file mode 100644 index 0000000..62ebf7d --- /dev/null +++ b/app/src/main/java/be/ugent/sel/studeez/data/local/models/task/Task.kt @@ -0,0 +1,9 @@ +package be.ugent.sel.studeez.data.local.models.task + +import com.google.firebase.firestore.DocumentId + +data class Task( + @DocumentId val id: String = "", + val name: String = "", + val completed: Boolean = false, +) diff --git a/app/src/main/java/be/ugent/sel/studeez/di/DatabaseModule.kt b/app/src/main/java/be/ugent/sel/studeez/di/DatabaseModule.kt index 1b696fe..e4228bb 100644 --- a/app/src/main/java/be/ugent/sel/studeez/di/DatabaseModule.kt +++ b/app/src/main/java/be/ugent/sel/studeez/di/DatabaseModule.kt @@ -10,15 +10,24 @@ import dagger.hilt.components.SingletonComponent @Module @InstallIn(SingletonComponent::class) abstract class DatabaseModule { - @Binds abstract fun provideAccountDAO(impl: FirebaseAccountDAO): AccountDAO + @Binds + abstract fun provideAccountDAO(impl: FirebaseAccountDAO): AccountDAO - @Binds abstract fun provideUserDAO(impl: FirebaseUserDAO): UserDAO + @Binds + abstract fun provideUserDAO(impl: FirebaseUserDAO): UserDAO - @Binds abstract fun provideTimerDAO(impl: FirebaseTimerDAO): TimerDAO + @Binds + abstract fun provideTimerDAO(impl: FirebaseTimerDAO): TimerDAO - @Binds abstract fun provideLogService(impl: LogServiceImpl): LogService + @Binds + abstract fun provideLogService(impl: LogServiceImpl): LogService - @Binds abstract fun provideConfigurationService(impl: FirebaseConfigurationService): ConfigurationService + @Binds + abstract fun provideConfigurationService(impl: FirebaseConfigurationService): ConfigurationService - @Binds abstract fun provideSessionDAO(impl: FireBaseSessionDAO): SessionDAO + @Binds + abstract fun provideSessionDAO(impl: FireBaseSessionDAO): SessionDAO + + @Binds + abstract fun provideSubjectDAO(impl: FireBaseSubjectDAO): SubjectDAO } \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/domain/SubjectDAO.kt b/app/src/main/java/be/ugent/sel/studeez/domain/SubjectDAO.kt new file mode 100644 index 0000000..dd24b45 --- /dev/null +++ b/app/src/main/java/be/ugent/sel/studeez/domain/SubjectDAO.kt @@ -0,0 +1,13 @@ +package be.ugent.sel.studeez.domain + +import be.ugent.sel.studeez.data.local.models.task.Subject +import kotlinx.coroutines.flow.Flow + +interface SubjectDAO { + + fun getSubjects(): Flow> + + fun saveSubject(newSubject: Subject) + + fun deleteSubject(oldSubject: Subject) +} \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FirebaseCollectionRoutes.kt b/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FireBaseCollections.kt similarity index 70% rename from app/src/main/java/be/ugent/sel/studeez/domain/implementation/FirebaseCollectionRoutes.kt rename to app/src/main/java/be/ugent/sel/studeez/domain/implementation/FireBaseCollections.kt index 2471301..a36361c 100644 --- a/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FirebaseCollectionRoutes.kt +++ b/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FireBaseCollections.kt @@ -1,8 +1,8 @@ package be.ugent.sel.studeez.domain.implementation -object FirebaseCollectionRoutes { +object FireBaseCollections { const val SESSION_COLLECTION = "sessions" const val USER_COLLECTION = "users" const val TIMER_COLLECTION = "timers" - + const val SUBJECT_COLLECTION = "subjects" } \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FireBaseSessionDAO.kt b/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FireBaseSessionDAO.kt index 07afdda..a818236 100644 --- a/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FireBaseSessionDAO.kt +++ b/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FireBaseSessionDAO.kt @@ -31,8 +31,7 @@ class FireBaseSessionDAO @Inject constructor( } private fun currentUserSessionsCollection(): CollectionReference = - firestore.collection(FirebaseCollectionRoutes.USER_COLLECTION) + firestore.collection(FireBaseCollections.USER_COLLECTION) .document(auth.currentUserId) - .collection(FirebaseCollectionRoutes.SESSION_COLLECTION) - + .collection(FireBaseCollections.SESSION_COLLECTION) } \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FireBaseSubjectDAO.kt b/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FireBaseSubjectDAO.kt new file mode 100644 index 0000000..364bdfc --- /dev/null +++ b/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FireBaseSubjectDAO.kt @@ -0,0 +1,35 @@ +package be.ugent.sel.studeez.domain.implementation + +import be.ugent.sel.studeez.data.local.models.task.Subject +import be.ugent.sel.studeez.domain.AccountDAO +import be.ugent.sel.studeez.domain.SubjectDAO +import com.google.firebase.firestore.CollectionReference +import com.google.firebase.firestore.FirebaseFirestore +import com.google.firebase.firestore.ktx.snapshots +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.map +import javax.inject.Inject + +class FireBaseSubjectDAO @Inject constructor( + private val firestore: FirebaseFirestore, + private val auth: AccountDAO, +) : SubjectDAO { + override fun getSubjects(): Flow> { + return currentUserSubjectsCollection() + .snapshots() + .map { it.toObjects(Subject::class.java) } + } + + override fun saveSubject(newSubject: Subject) { + currentUserSubjectsCollection().add(newSubject) + } + + override fun deleteSubject(oldSubject: Subject) { + TODO("Not yet implemented") + } + + private fun currentUserSubjectsCollection(): CollectionReference = + firestore.collection(FireBaseCollections.USER_COLLECTION) + .document(auth.currentUserId) + .collection(FireBaseCollections.SUBJECT_COLLECTION) +} \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FirebaseTimerDAO.kt b/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FirebaseTimerDAO.kt index 901f9d6..1f37a18 100644 --- a/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FirebaseTimerDAO.kt +++ b/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FirebaseTimerDAO.kt @@ -1,11 +1,9 @@ package be.ugent.sel.studeez.domain.implementation import be.ugent.sel.studeez.data.local.models.timer_info.* -import be.ugent.sel.studeez.data.local.models.timer_info.TimerType.* import be.ugent.sel.studeez.domain.AccountDAO import be.ugent.sel.studeez.domain.TimerDAO import com.google.firebase.firestore.CollectionReference -import com.google.firebase.firestore.DocumentSnapshot import com.google.firebase.firestore.FirebaseFirestore import com.google.firebase.firestore.ktx.snapshots import kotlinx.coroutines.flow.Flow @@ -50,8 +48,8 @@ class FirebaseTimerDAO @Inject constructor( } private fun currentUserTimersCollection(): CollectionReference = - firestore.collection(FirebaseCollectionRoutes.USER_COLLECTION) + firestore.collection(FireBaseCollections.USER_COLLECTION) .document(auth.currentUserId) - .collection(FirebaseCollectionRoutes.TIMER_COLLECTION) + .collection(FireBaseCollections.TIMER_COLLECTION) } \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/navigation/StudeezDestinations.kt b/app/src/main/java/be/ugent/sel/studeez/navigation/StudeezDestinations.kt index ab10c22..c6d39cd 100644 --- a/app/src/main/java/be/ugent/sel/studeez/navigation/StudeezDestinations.kt +++ b/app/src/main/java/be/ugent/sel/studeez/navigation/StudeezDestinations.kt @@ -10,7 +10,7 @@ object StudeezDestinations { const val TIMER_SELECTION_SCREEN = "timer_selection" const val SESSION_SCREEN = "session" const val SESSION_RECAP = "session_recap" - // const val TASKS_SCREEN = "tasks" + const val TASKS_SCREEN = "tasks" // const val SESSIONS_SCREEN = "sessions" const val PROFILE_SCREEN = "profile" diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/tasks/TaskScreen.kt b/app/src/main/java/be/ugent/sel/studeez/screens/tasks/TaskScreen.kt new file mode 100644 index 0000000..c4ad625 --- /dev/null +++ b/app/src/main/java/be/ugent/sel/studeez/screens/tasks/TaskScreen.kt @@ -0,0 +1,77 @@ +package be.ugent.sel.studeez.screens.tasks + +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.items +import androidx.compose.material.Button +import androidx.compose.material.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.collectAsState +import androidx.compose.ui.tooling.preview.Preview +import be.ugent.sel.studeez.R +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 TaskRoute( + open: (String) -> Unit, + viewModel: TaskViewModel, + drawerActions: DrawerActions, + navigationBarActions: NavigationBarActions, +) { + TaskScreen( + drawerActions = drawerActions, + navigationBarActions = navigationBarActions, + addSubject = { viewModel.addSubject() }, + ) { viewModel.getSubjects() } +} + +@Composable +fun TaskScreen( + drawerActions: DrawerActions, + navigationBarActions: NavigationBarActions, + addSubject: () -> Unit, + getSubjects: () -> Flow>, +) { + PrimaryScreenTemplate( + title = resources().getString(R.string.tasks), + drawerActions = drawerActions, + navigationBarActions = navigationBarActions, + barAction = {}, + ) { + val subjects = getSubjects().collectAsState(initial = emptyList()) + Column { + LazyColumn { + items(subjects.value) { + SubjectEntry(subject = it) + } + } + AddSubjectButton(onClick = addSubject) + } + } +} + +@Composable +fun AddSubjectButton( + onClick: () -> Unit, +) { + Button(onClick = onClick) { + Text(text = "Test Button") + } +} + +@Preview +@Composable +fun TaskScreenPreview() { + TaskScreen( + drawerActions = DrawerActions({}, {}, {}, {}, {}), + navigationBarActions = NavigationBarActions({ false }, {}, {}, {}, {}), + {}, + ) { flowOf() } +} \ No newline at end of file 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 new file mode 100644 index 0000000..da489a5 --- /dev/null +++ b/app/src/main/java/be/ugent/sel/studeez/screens/tasks/TaskViewModel.kt @@ -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 TaskViewModel @Inject constructor( + private val subjectDAO: SubjectDAO, + logService: LogService, +) : StudeezViewModel(logService) { + fun addSubject() { + subjectDAO.saveSubject( + Subject( + name = "Test Subject", + tasks = listOf(), + time = 0, + color = 0, + ) + ) + } + + fun getSubjects(): Flow> { + return subjectDAO.getSubjects() + } +} \ No newline at end of file From 1e359b9e371a569fdcfcb06b79055923f47c0b4a Mon Sep 17 00:00:00 2001 From: brreynie Date: Sat, 29 Apr 2023 12:31:52 +0200 Subject: [PATCH 02/22] #21 change text in button --- .../main/java/be/ugent/sel/studeez/screens/tasks/TaskScreen.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/tasks/TaskScreen.kt b/app/src/main/java/be/ugent/sel/studeez/screens/tasks/TaskScreen.kt index c4ad625..5d11ef7 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/tasks/TaskScreen.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/tasks/TaskScreen.kt @@ -62,7 +62,7 @@ fun AddSubjectButton( onClick: () -> Unit, ) { Button(onClick = onClick) { - Text(text = "Test Button") + Text(text = "Add Subject") } } From 4bbc3af4b27eee822c28d1249f4fd22a5f59e002 Mon Sep 17 00:00:00 2001 From: brreynie Date: Mon, 1 May 2023 13:38:20 +0200 Subject: [PATCH 03/22] #21 style button to add subjects/tasks --- .../common/composable/ButtonComposable.kt | 53 ++++++++++++++++++- .../sel/studeez/screens/tasks/TaskScreen.kt | 13 +---- app/src/main/res/values/strings.xml | 2 + 3 files changed, 56 insertions(+), 12 deletions(-) diff --git a/app/src/main/java/be/ugent/sel/studeez/common/composable/ButtonComposable.kt b/app/src/main/java/be/ugent/sel/studeez/common/composable/ButtonComposable.kt index 3fa9bd2..8a2a939 100644 --- a/app/src/main/java/be/ugent/sel/studeez/common/composable/ButtonComposable.kt +++ b/app/src/main/java/be/ugent/sel/studeez/common/composable/ButtonComposable.kt @@ -2,10 +2,25 @@ package be.ugent.sel.studeez.common.composable import androidx.annotation.StringRes import androidx.compose.foundation.BorderStroke +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.* +import androidx.compose.material.Button +import androidx.compose.material.ButtonColors +import androidx.compose.material.ButtonDefaults +import androidx.compose.material.Icon +import androidx.compose.material.MaterialTheme +import androidx.compose.material.Text +import androidx.compose.material.TextButton +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.Add import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp @@ -93,4 +108,40 @@ fun DialogCancelButton(@StringRes text: Int, action: () -> Unit) { ) { Text(text = stringResource(text)) } +} + +@Composable +fun NewTaskSubjectButton( + onClick: () -> Unit, + @StringRes text: Int, +) { + Button( + onClick = onClick, + modifier = Modifier + .fillMaxWidth() + .height(60.dp) + .padding(10.dp, 5.dp), + colors = ButtonDefaults.buttonColors( + backgroundColor = Color.Transparent, + contentColor = Color.Gray, + ), + shape = RoundedCornerShape(2.dp), + border = BorderStroke(1.dp, Color.Gray), + elevation = null, + ) { + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.SpaceBetween, + verticalAlignment = Alignment.CenterVertically, + ) { + Text(text = stringResource(id = text)) + Icon(imageVector = Icons.Default.Add, contentDescription = stringResource(id = text)) + } + } +} + +@Preview +@Composable +fun NewTaskButtonPreview() { + NewTaskSubjectButton(onClick = {}, text = R.string.new_task) } \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/tasks/TaskScreen.kt b/app/src/main/java/be/ugent/sel/studeez/screens/tasks/TaskScreen.kt index 5d11ef7..5c8e576 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/tasks/TaskScreen.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/tasks/TaskScreen.kt @@ -3,12 +3,11 @@ package be.ugent.sel.studeez.screens.tasks import androidx.compose.foundation.layout.Column import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items -import androidx.compose.material.Button -import androidx.compose.material.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState import androidx.compose.ui.tooling.preview.Preview 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 @@ -52,19 +51,11 @@ fun TaskScreen( SubjectEntry(subject = it) } } - AddSubjectButton(onClick = addSubject) + NewTaskSubjectButton(onClick = addSubject, R.string.new_subject) } } } -@Composable -fun AddSubjectButton( - onClick: () -> Unit, -) { - Button(onClick = onClick) { - Text(text = "Add Subject") - } -} @Preview @Composable diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index bb643d3..22db344 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -42,6 +42,8 @@ Tasks + New Subject + New Task Sessions From c33aad5496a87ffce1adef873a7dceaac05a14d2 Mon Sep 17 00:00:00 2001 From: brreynie Date: Mon, 1 May 2023 15:15:54 +0200 Subject: [PATCH 04/22] #21 begin styling subject --- .../studeez/common/composable/SubjectEntry.kt | 45 ++++++++++++++++++- .../studeez/data/local/models/task/Subject.kt | 6 ++- .../sel/studeez/screens/tasks/TaskScreen.kt | 19 ++++++-- .../studeez/screens/tasks/TaskViewModel.kt | 2 +- app/src/main/res/values/strings.xml | 1 + 5 files changed, 65 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/be/ugent/sel/studeez/common/composable/SubjectEntry.kt b/app/src/main/java/be/ugent/sel/studeez/common/composable/SubjectEntry.kt index 928ab36..59a7cfe 100644 --- a/app/src/main/java/be/ugent/sel/studeez/common/composable/SubjectEntry.kt +++ b/app/src/main/java/be/ugent/sel/studeez/common/composable/SubjectEntry.kt @@ -1,19 +1,60 @@ package be.ugent.sel.studeez.common.composable +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.material.Card import androidx.compose.material.Text import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.Color import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import be.ugent.sel.studeez.R import be.ugent.sel.studeez.data.local.models.task.Subject @Composable fun SubjectEntry( subject: Subject, ) { - Text(text = subject.name) + Card( + modifier = Modifier + .fillMaxWidth() + .padding(10.dp), + ) { + Row( + horizontalArrangement = Arrangement.SpaceBetween, + verticalAlignment = Alignment.Top, + ) { + Row( + horizontalArrangement = Arrangement.spacedBy(10.dp), + verticalAlignment = Alignment.Top, + ) { + Box( + modifier = Modifier + .size(20.dp) + .clip(CircleShape) + .background(Color(subject.argb_color)) + .padding(4.dp), + ) + Text(text = subject.name) + } + StealthButton(text = R.string.view_task) { + + } + } + } } @Preview @Composable fun SubjectEntryPreview() { - SubjectEntry(subject = Subject(name = "Test Subject")) + SubjectEntry(subject = Subject(name = "Test Subject", argb_color = 0xFFF44336)) } \ No newline at end of file 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 034711a..0410790 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 @@ -7,5 +7,7 @@ data class Subject( val name: String = "", val tasks: List = mutableListOf(), val time: Int = 0, - val color: Int = 0, -) \ No newline at end of file + val argb_color: Long = 0, +) { +// fun getColor(): Color = Color(ARGB_color) +} \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/tasks/TaskScreen.kt b/app/src/main/java/be/ugent/sel/studeez/screens/tasks/TaskScreen.kt index 5c8e576..9db49ac 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/tasks/TaskScreen.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/tasks/TaskScreen.kt @@ -1,11 +1,15 @@ 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.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 @@ -47,8 +51,18 @@ fun TaskScreen( val subjects = getSubjects().collectAsState(initial = emptyList()) Column { LazyColumn { - items(subjects.value) { - SubjectEntry(subject = it) + 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) + } + } } } NewTaskSubjectButton(onClick = addSubject, R.string.new_subject) @@ -56,7 +70,6 @@ fun TaskScreen( } } - @Preview @Composable fun TaskScreenPreview() { 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 da489a5..cbd46c2 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 @@ -19,7 +19,7 @@ class TaskViewModel @Inject constructor( name = "Test Subject", tasks = listOf(), time = 0, - color = 0, + argb_color = 0xFFF44336, ) ) } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 22db344..1ee687c 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -44,6 +44,7 @@ Tasks New Subject New Task + View Sessions From 7ad104709178b65f016ad9b25fe8b26bf84056bc Mon Sep 17 00:00:00 2001 From: brreynie Date: Tue, 2 May 2023 21:11:27 +0200 Subject: [PATCH 05/22] #21 further styling subject --- .../common/composable/ButtonComposable.kt | 5 +- .../studeez/common/composable/SubjectEntry.kt | 65 ++++++++++++++++--- .../studeez/data/local/models/task/Subject.kt | 4 +- .../timer_functional/HoursMinutesSeconds.kt | 17 ++++- .../local/models/timer_functional/Time.kt | 11 +--- .../sel/studeez/screens/tasks/TaskScreen.kt | 31 +++++---- app/src/main/res/values/strings.xml | 1 - 7 files changed, 94 insertions(+), 40 deletions(-) diff --git a/app/src/main/java/be/ugent/sel/studeez/common/composable/ButtonComposable.kt b/app/src/main/java/be/ugent/sel/studeez/common/composable/ButtonComposable.kt index 8a2a939..286ea96 100644 --- a/app/src/main/java/be/ugent/sel/studeez/common/composable/ButtonComposable.kt +++ b/app/src/main/java/be/ugent/sel/studeez/common/composable/ButtonComposable.kt @@ -37,7 +37,7 @@ fun BasicTextButton(@StringRes text: Int, modifier: Modifier, action: () -> Unit @Composable fun BasicButton( @StringRes text: Int, - modifier: Modifier, + modifier: Modifier = Modifier, colors: ButtonColors = ButtonDefaults.buttonColors(), border: BorderStroke? = null, onClick: () -> Unit, @@ -65,12 +65,13 @@ fun BasicButtonPreview() { @Composable fun StealthButton( @StringRes text: Int, + modifier: Modifier = Modifier.card(), onClick: () -> Unit, ) { BasicButton( text = text, onClick = onClick, - modifier = Modifier.card(), + modifier = modifier, colors = ButtonDefaults.buttonColors( backgroundColor = MaterialTheme.colors.surface, contentColor = MaterialTheme.colors.onSurface diff --git a/app/src/main/java/be/ugent/sel/studeez/common/composable/SubjectEntry.kt b/app/src/main/java/be/ugent/sel/studeez/common/composable/SubjectEntry.kt index 59a7cfe..8de010c 100644 --- a/app/src/main/java/be/ugent/sel/studeez/common/composable/SubjectEntry.kt +++ b/app/src/main/java/be/ugent/sel/studeez/common/composable/SubjectEntry.kt @@ -3,22 +3,30 @@ package be.ugent.sel.studeez.common.composable import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width import androidx.compose.foundation.shape.CircleShape import androidx.compose.material.Card +import androidx.compose.material.Icon import androidx.compose.material.Text +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.List import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Color +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import be.ugent.sel.studeez.R import be.ugent.sel.studeez.data.local.models.task.Subject +import be.ugent.sel.studeez.data.local.models.timer_functional.HoursMinutesSeconds @Composable fun SubjectEntry( @@ -27,26 +35,58 @@ fun SubjectEntry( Card( modifier = Modifier .fillMaxWidth() - .padding(10.dp), + .padding(horizontal = 10.dp, vertical = 5.dp), ) { Row( horizontalArrangement = Arrangement.SpaceBetween, - verticalAlignment = Alignment.Top, + verticalAlignment = Alignment.CenterVertically, +// modifier = Modifier.fillMaxWidth(), ) { Row( - horizontalArrangement = Arrangement.spacedBy(10.dp), - verticalAlignment = Alignment.Top, + horizontalArrangement = Arrangement.spacedBy(8.dp), + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier.padding(start = 10.dp).weight(3f) ) { Box( modifier = Modifier .size(20.dp) .clip(CircleShape) - .background(Color(subject.argb_color)) - .padding(4.dp), + .background(Color(subject.argb_color)), ) - Text(text = subject.name) + Column( + verticalArrangement = Arrangement.spacedBy(0.dp) + ) { + Text( + text = subject.name, + fontWeight = FontWeight.Bold, + overflow = TextOverflow.Ellipsis, + maxLines = 1, +// modifier = Modifier.fillMaxWidth(), +// modifier = Modifier.width(200.dp) + ) + Row( + horizontalArrangement = Arrangement.spacedBy(10.dp), + verticalAlignment = Alignment.CenterVertically, + ) { + Text( + text = "${HoursMinutesSeconds(subject.time)}", + ) + Row( + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.spacedBy(3.dp) + ) { + Icon( + imageVector = Icons.Default.List, contentDescription = "tasks" + ) + Text(text = "4/9") + } + } + } } - StealthButton(text = R.string.view_task) { + StealthButton( + text = R.string.view_task, + modifier = Modifier.padding(start = 10.dp, end = 5.dp).weight(1f) + ) { } } @@ -56,5 +96,12 @@ fun SubjectEntry( @Preview @Composable fun SubjectEntryPreview() { - SubjectEntry(subject = Subject(name = "Test Subject", argb_color = 0xFFF44336)) + SubjectEntry( + subject = Subject( + name = "Test Subject longgggggggggggggggggggggggggggggggggggggggg", +// name = "Test Subject", + argb_color = 0xFFF44336, + time = 60 + ) + ) } \ No newline at end of file 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 0410790..5e8ea0f 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 @@ -8,6 +8,4 @@ data class Subject( val tasks: List = mutableListOf(), val time: Int = 0, val argb_color: Long = 0, -) { -// fun getColor(): Color = Color(ARGB_color) -} \ No newline at end of file +) \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/HoursMinutesSeconds.kt b/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/HoursMinutesSeconds.kt index 856aa26..57b03a7 100644 --- a/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/HoursMinutesSeconds.kt +++ b/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/HoursMinutesSeconds.kt @@ -1,4 +1,17 @@ package be.ugent.sel.studeez.data.local.models.timer_functional -data class HoursMinutesSeconds(val hours: String, val minutes: String, val seconds: String -) \ No newline at end of file +class HoursMinutesSeconds(val hours: Int, val minutes: Int, val seconds: Int) { + constructor(seconds: Int) : this( + hours = seconds / (60 * 60), + minutes = (seconds / 60) % 60, + seconds = seconds % 60, + ) + + override fun toString(): String { + return hours.toString().padStart(2, '0') + + ":" + + minutes.toString().padStart(2, '0') + + ":" + + seconds.toString().padStart(2, '0') + } +} \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/Time.kt b/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/Time.kt index ec7702d..aad96e0 100644 --- a/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/Time.kt +++ b/app/src/main/java/be/ugent/sel/studeez/data/local/models/timer_functional/Time.kt @@ -13,15 +13,6 @@ class Time(initialTime: Int) { } fun getAsHMS(): HoursMinutesSeconds { - val hours: Int = time / (60 * 60) - val minutes: Int = (time / (60)) % 60 - val seconds: Int = time % 60 - - return HoursMinutesSeconds( - hours.toString().padStart(2, '0'), - minutes.toString().padStart(2, '0'), - seconds.toString().padStart(2, '0') - ) + return HoursMinutesSeconds(time) } - } \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/tasks/TaskScreen.kt b/app/src/main/java/be/ugent/sel/studeez/screens/tasks/TaskScreen.kt index 9db49ac..ea9b6d4 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/tasks/TaskScreen.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/tasks/TaskScreen.kt @@ -49,20 +49,25 @@ fun TaskScreen( barAction = {}, ) { val subjects = getSubjects().collectAsState(initial = emptyList()) - Column { + 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) - } - } +// 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) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 1ee687c..8335853 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -82,5 +82,4 @@ About Studeez - From 1a2e19222714d80a1c532e5323edf688485a47bf Mon Sep 17 00:00:00 2001 From: brreynie Date: Tue, 2 May 2023 21:39:21 +0200 Subject: [PATCH 06/22] #22 boilerplate for task screen --- .../java/be/ugent/sel/studeez/StudeezApp.kt | 12 ++- .../navbar/NavigationBarViewModel.kt | 3 +- .../be/ugent/sel/studeez/di/DatabaseModule.kt | 3 + .../be/ugent/sel/studeez/domain/TaskDAO.kt | 13 +++ .../domain/implementation/FireBaseTaskDAO.kt | 26 ++++++ .../studeez/navigation/StudeezDestinations.kt | 6 +- .../studeez/screens/tasks/SubjectScreen.kt | 85 +++++++++++++++++++ .../studeez/screens/tasks/SubjectViewModel.kt | 30 +++++++ .../sel/studeez/screens/tasks/TaskScreen.kt | 72 +++------------- .../studeez/screens/tasks/TaskViewModel.kt | 31 ++++--- 10 files changed, 200 insertions(+), 81 deletions(-) create mode 100644 app/src/main/java/be/ugent/sel/studeez/domain/TaskDAO.kt create mode 100644 app/src/main/java/be/ugent/sel/studeez/domain/implementation/FireBaseTaskDAO.kt create mode 100644 app/src/main/java/be/ugent/sel/studeez/screens/tasks/SubjectScreen.kt create mode 100644 app/src/main/java/be/ugent/sel/studeez/screens/tasks/SubjectViewModel.kt diff --git a/app/src/main/java/be/ugent/sel/studeez/StudeezApp.kt b/app/src/main/java/be/ugent/sel/studeez/StudeezApp.kt index d72bedf..65cd3bb 100644 --- a/app/src/main/java/be/ugent/sel/studeez/StudeezApp.kt +++ b/app/src/main/java/be/ugent/sel/studeez/StudeezApp.kt @@ -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.sign_up.SignUpRoute 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.timer_overview.TimerOverviewRoute import be.ugent.sel.studeez.screens.timer_selection.TimerSelectionRoute @@ -146,14 +147,21 @@ fun StudeezNavGraph( ) } - composable(StudeezDestinations.TASKS_SCREEN) { - TaskRoute( + composable(StudeezDestinations.SUBJECT_SCREEN) { + SubjectRoute( open = open, viewModel = hiltViewModel(), drawerActions = drawerActions, navigationBarActions = navigationBarActions, ) } + + composable(StudeezDestinations.TASKS_SCREEN) { + TaskRoute( + viewModel = hiltViewModel() + ) + } + // TODO Sessions screen composable(StudeezDestinations.PROFILE_SCREEN) { diff --git a/app/src/main/java/be/ugent/sel/studeez/common/composable/navbar/NavigationBarViewModel.kt b/app/src/main/java/be/ugent/sel/studeez/common/composable/navbar/NavigationBarViewModel.kt index 7b1d012..8a39fc1 100644 --- a/app/src/main/java/be/ugent/sel/studeez/common/composable/navbar/NavigationBarViewModel.kt +++ b/app/src/main/java/be/ugent/sel/studeez/common/composable/navbar/NavigationBarViewModel.kt @@ -3,6 +3,7 @@ package be.ugent.sel.studeez.common.composable.navbar import be.ugent.sel.studeez.domain.LogService 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.SUBJECT_SCREEN import be.ugent.sel.studeez.navigation.StudeezDestinations.TASKS_SCREEN import be.ugent.sel.studeez.screens.StudeezViewModel import dagger.hilt.android.lifecycle.HiltViewModel @@ -18,7 +19,7 @@ class NavigationBarViewModel @Inject constructor( } fun onTasksClick(open: (String) -> Unit) { - open(TASKS_SCREEN) + open(SUBJECT_SCREEN) } fun onSessionsClick(open: (String) -> Unit) { diff --git a/app/src/main/java/be/ugent/sel/studeez/di/DatabaseModule.kt b/app/src/main/java/be/ugent/sel/studeez/di/DatabaseModule.kt index e4228bb..7ee4992 100644 --- a/app/src/main/java/be/ugent/sel/studeez/di/DatabaseModule.kt +++ b/app/src/main/java/be/ugent/sel/studeez/di/DatabaseModule.kt @@ -30,4 +30,7 @@ abstract class DatabaseModule { @Binds abstract fun provideSubjectDAO(impl: FireBaseSubjectDAO): SubjectDAO + + @Binds + abstract fun provideTaskDAO(impl: FireBaseTaskDAO): TaskDAO } \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/domain/TaskDAO.kt b/app/src/main/java/be/ugent/sel/studeez/domain/TaskDAO.kt new file mode 100644 index 0000000..8b9adef --- /dev/null +++ b/app/src/main/java/be/ugent/sel/studeez/domain/TaskDAO.kt @@ -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> + + fun saveTask(newTask: Task) + + fun deleteTask(oldTask: Task) +} \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FireBaseTaskDAO.kt b/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FireBaseTaskDAO.kt new file mode 100644 index 0000000..2485317 --- /dev/null +++ b/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FireBaseTaskDAO.kt @@ -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> { + TODO("Not yet implemented") + } + + override fun saveTask(newTask: Task) { + TODO("Not yet implemented") + } + + override fun deleteTask(oldTask: Task) { + TODO("Not yet implemented") + } + +} \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/navigation/StudeezDestinations.kt b/app/src/main/java/be/ugent/sel/studeez/navigation/StudeezDestinations.kt index c6d39cd..1d7ed4a 100644 --- a/app/src/main/java/be/ugent/sel/studeez/navigation/StudeezDestinations.kt +++ b/app/src/main/java/be/ugent/sel/studeez/navigation/StudeezDestinations.kt @@ -10,8 +10,10 @@ object StudeezDestinations { const val TIMER_SELECTION_SCREEN = "timer_selection" const val SESSION_SCREEN = "session" const val SESSION_RECAP = "session_recap" - const val TASKS_SCREEN = "tasks" - // const val SESSIONS_SCREEN = "sessions" + const val SUBJECT_SCREEN = "subjects" + const val TASKS_SCREEN = "tasks" + + // const val SESSIONS_SCREEN = "sessions" const val PROFILE_SCREEN = "profile" // const val TIMERS_SCREEN = "timers" 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 new file mode 100644 index 0000000..e9ab007 --- /dev/null +++ b/app/src/main/java/be/ugent/sel/studeez/screens/tasks/SubjectScreen.kt @@ -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>, +) { + 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() } +} \ 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 new file mode 100644 index 0000000..61645c1 --- /dev/null +++ b/app/src/main/java/be/ugent/sel/studeez/screens/tasks/SubjectViewModel.kt @@ -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> { + return subjectDAO.getSubjects() + } +} \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/tasks/TaskScreen.kt b/app/src/main/java/be/ugent/sel/studeez/screens/tasks/TaskScreen.kt index ea9b6d4..d167ddc 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/tasks/TaskScreen.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/tasks/TaskScreen.kt @@ -1,86 +1,34 @@ 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.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 be.ugent.sel.studeez.data.local.models.task.Task import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.flowOf @Composable fun TaskRoute( - open: (String) -> Unit, viewModel: TaskViewModel, - drawerActions: DrawerActions, - navigationBarActions: NavigationBarActions, ) { TaskScreen( - drawerActions = drawerActions, - navigationBarActions = navigationBarActions, - addSubject = { viewModel.addSubject() }, - ) { viewModel.getSubjects() } + addTask = viewModel::addTask, + getTasks = viewModel::getTasks, + ) } @Composable fun TaskScreen( - drawerActions: DrawerActions, - navigationBarActions: NavigationBarActions, - addSubject: () -> Unit, - getSubjects: () -> Flow>, + addTask: () -> Unit, + getTasks: () -> Flow>, ) { - 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 TaskScreenPreview() { TaskScreen( - drawerActions = DrawerActions({}, {}, {}, {}, {}), - navigationBarActions = NavigationBarActions({ false }, {}, {}, {}, {}), - {}, - ) { flowOf() } + addTask = {}, + getTasks = { flowOf() } + ) } \ No newline at end of file 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 cbd46c2..eabe81d 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,30 +1,33 @@ 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.SubjectDAO +import be.ugent.sel.studeez.domain.TaskDAO import be.ugent.sel.studeez.screens.StudeezViewModel import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.flowOf import javax.inject.Inject @HiltViewModel class TaskViewModel @Inject constructor( - private val subjectDAO: SubjectDAO, + private val taskDAO: TaskDAO, logService: LogService, ) : StudeezViewModel(logService) { - fun addSubject() { - subjectDAO.saveSubject( - Subject( - name = "Test Subject", - tasks = listOf(), - time = 0, - argb_color = 0xFFF44336, - ) - ) + fun addTask() { + } - fun getSubjects(): Flow> { - return subjectDAO.getSubjects() + fun getTasks() : Flow> { + return flowOf(listOf( + Task( + name = "Test Task", + completed = false, + ), + Task( + name = "Test Task 2", + completed = true, + ) + )) } } \ No newline at end of file From e1c05bb0d4b8f92c74c9e035f538a372699917b3 Mon Sep 17 00:00:00 2001 From: brreynie Date: Tue, 2 May 2023 22:18:56 +0200 Subject: [PATCH 07/22] "#22 styling of task overview" --- .../java/be/ugent/sel/studeez/StudeezApp.kt | 3 +- .../studeez/common/composable/SubjectEntry.kt | 26 +++--- .../be/ugent/sel/studeez/domain/TaskDAO.kt | 3 +- .../domain/implementation/FireBaseTaskDAO.kt | 17 +++- .../studeez/screens/tasks/SubjectScreen.kt | 16 +++- .../studeez/screens/tasks/SubjectViewModel.kt | 5 + .../sel/studeez/screens/tasks/TaskScreen.kt | 93 +++++++++++++++++-- .../studeez/screens/tasks/TaskViewModel.kt | 12 +-- app/src/main/res/values/strings.xml | 2 + 9 files changed, 140 insertions(+), 37 deletions(-) diff --git a/app/src/main/java/be/ugent/sel/studeez/StudeezApp.kt b/app/src/main/java/be/ugent/sel/studeez/StudeezApp.kt index 65cd3bb..315c68d 100644 --- a/app/src/main/java/be/ugent/sel/studeez/StudeezApp.kt +++ b/app/src/main/java/be/ugent/sel/studeez/StudeezApp.kt @@ -158,7 +158,8 @@ fun StudeezNavGraph( composable(StudeezDestinations.TASKS_SCREEN) { TaskRoute( - viewModel = hiltViewModel() + goBack = goBack, + viewModel = hiltViewModel(), ) } diff --git a/app/src/main/java/be/ugent/sel/studeez/common/composable/SubjectEntry.kt b/app/src/main/java/be/ugent/sel/studeez/common/composable/SubjectEntry.kt index 8de010c..0352327 100644 --- a/app/src/main/java/be/ugent/sel/studeez/common/composable/SubjectEntry.kt +++ b/app/src/main/java/be/ugent/sel/studeez/common/composable/SubjectEntry.kt @@ -8,7 +8,6 @@ import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size -import androidx.compose.foundation.layout.width import androidx.compose.foundation.shape.CircleShape import androidx.compose.material.Card import androidx.compose.material.Icon @@ -31,6 +30,7 @@ import be.ugent.sel.studeez.data.local.models.timer_functional.HoursMinutesSecon @Composable fun SubjectEntry( subject: Subject, + onViewSubject: () -> Unit, ) { Card( modifier = Modifier @@ -40,12 +40,13 @@ fun SubjectEntry( Row( horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically, -// modifier = Modifier.fillMaxWidth(), ) { Row( horizontalArrangement = Arrangement.spacedBy(8.dp), verticalAlignment = Alignment.CenterVertically, - modifier = Modifier.padding(start = 10.dp).weight(3f) + modifier = Modifier + .padding(start = 10.dp) + .weight(3f) ) { Box( modifier = Modifier @@ -61,8 +62,6 @@ fun SubjectEntry( fontWeight = FontWeight.Bold, overflow = TextOverflow.Ellipsis, maxLines = 1, -// modifier = Modifier.fillMaxWidth(), -// modifier = Modifier.width(200.dp) ) Row( horizontalArrangement = Arrangement.spacedBy(10.dp), @@ -78,16 +77,18 @@ fun SubjectEntry( Icon( imageVector = Icons.Default.List, contentDescription = "tasks" ) - Text(text = "4/9") + Text(text = subject.tasks.size.toString()) } } } } StealthButton( 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() { SubjectEntry( subject = Subject( - name = "Test Subject longgggggggggggggggggggggggggggggggggggggggg", -// name = "Test Subject", + name = "Test Subject", argb_color = 0xFFF44336, time = 60 - ) - ) + ), + ) {} } \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/domain/TaskDAO.kt b/app/src/main/java/be/ugent/sel/studeez/domain/TaskDAO.kt index 8b9adef..2fb5dde 100644 --- a/app/src/main/java/be/ugent/sel/studeez/domain/TaskDAO.kt +++ b/app/src/main/java/be/ugent/sel/studeez/domain/TaskDAO.kt @@ -1,11 +1,12 @@ 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 kotlinx.coroutines.flow.Flow interface TaskDAO { - fun getTasks(): Flow> + fun getTasks(subject: Subject): Flow> fun saveTask(newTask: Task) diff --git a/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FireBaseTaskDAO.kt b/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FireBaseTaskDAO.kt index 2485317..bfb1493 100644 --- a/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FireBaseTaskDAO.kt +++ b/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FireBaseTaskDAO.kt @@ -1,18 +1,31 @@ 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.domain.AccountDAO import be.ugent.sel.studeez.domain.TaskDAO import com.google.firebase.firestore.FirebaseFirestore import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.flowOf import javax.inject.Inject class FireBaseTaskDAO @Inject constructor( private val firestore: FirebaseFirestore, private val auth: AccountDAO, ) : TaskDAO { - override fun getTasks(): Flow> { - TODO("Not yet implemented") + override fun getTasks(subject: Subject): Flow> { + return flowOf( + listOf( + Task( + name = "Test Task", + completed = false, + ), + Task( + name = "Test Task 2", + completed = true, + ) + ) + ) } override fun saveTask(newTask: Task) { 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 e9ab007..3e7c3e1 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 @@ -31,7 +31,9 @@ fun SubjectRoute( drawerActions = drawerActions, navigationBarActions = navigationBarActions, addSubject = { viewModel.addSubject() }, - ) { viewModel.getSubjects() } + getSubjects = viewModel::getSubjects, + onViewSubject = { viewModel.onViewSubject(Subject(), open) }, + ) } @Composable @@ -40,6 +42,7 @@ fun SubjectScreen( navigationBarActions: NavigationBarActions, addSubject: () -> Unit, getSubjects: () -> Flow>, + onViewSubject: () -> Unit, ) { PrimaryScreenTemplate( title = resources().getString(R.string.tasks), @@ -66,7 +69,10 @@ fun SubjectScreen( // } // } items(subjects.value) { - SubjectEntry(subject = it) + SubjectEntry( + subject = it, + onViewSubject = onViewSubject, + ) } } NewTaskSubjectButton(onClick = addSubject, R.string.new_subject) @@ -80,6 +86,8 @@ fun SubjectScreenPreview() { SubjectScreen( drawerActions = DrawerActions({}, {}, {}, {}, {}), navigationBarActions = NavigationBarActions({ false }, {}, {}, {}, {}), - {}, - ) { flowOf() } + addSubject = {}, + getSubjects = { flowOf() }, + onViewSubject = {}, + ) } \ 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 61645c1..455ed49 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 @@ -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.domain.LogService 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 @@ -27,4 +28,8 @@ class SubjectViewModel @Inject constructor( fun getSubjects(): Flow> { return subjectDAO.getSubjects() } + + fun onViewSubject(subject: Subject, open: (String) -> Unit) { + open(StudeezDestinations.TASKS_SCREEN) + } } \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/tasks/TaskScreen.kt b/app/src/main/java/be/ugent/sel/studeez/screens/tasks/TaskScreen.kt index d167ddc..b35ecb1 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/tasks/TaskScreen.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/tasks/TaskScreen.kt @@ -1,34 +1,115 @@ 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.collectAsState +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color 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.resources import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.flowOf +data class TaskActions( + val addTask: () -> Unit, + val getSubject: () -> Subject, + val getTasks: () -> Flow>, + val deleteSubject: () -> Unit, +) + +fun getTaskActions(viewModel: TaskViewModel): TaskActions { + return TaskActions( + addTask = viewModel::addTask, + getTasks = viewModel::getTasks, + getSubject = { Subject(name = "Test Subject") }, + deleteSubject = {}, + ) +} + @Composable fun TaskRoute( + goBack: () -> Unit, viewModel: TaskViewModel, ) { TaskScreen( - addTask = viewModel::addTask, - getTasks = viewModel::getTasks, + goBack = goBack, + taskActions = getTaskActions(viewModel = viewModel), ) } @Composable fun TaskScreen( - addTask: () -> Unit, - getTasks: () -> Flow>, + goBack: () -> Unit, + 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 @Composable fun TaskScreenPreview() { TaskScreen( - addTask = {}, - getTasks = { flowOf() } + goBack = {}, + taskActions = TaskActions( + {}, + { Subject(name = "Test Subject") }, + { flowOf() }, + {}, + ) ) } \ No newline at end of file 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 eabe81d..c86b751 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,5 +1,6 @@ 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.TaskDAO @@ -19,15 +20,6 @@ class TaskViewModel @Inject constructor( } fun getTasks() : Flow> { - return flowOf(listOf( - Task( - name = "Test Task", - completed = false, - ), - Task( - name = "Test Task 2", - completed = true, - ) - )) + return taskDAO.getTasks(Subject()) } } \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 8335853..bb0d6fd 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -45,6 +45,8 @@ New Subject New Task View + Edit Task + Delete Subject Sessions From 056947e1dbf64215b2a8193a895e7e02cbee964b Mon Sep 17 00:00:00 2001 From: brreynie Date: Tue, 2 May 2023 22:57:35 +0200 Subject: [PATCH 08/22] #22 get tasks from firestore --- .../studeez/common/composable/SubjectEntry.kt | 2 +- .../ugent/sel/studeez/data/SelectedSubject.kt | 18 +++++++++++++ .../studeez/data/local/models/task/Subject.kt | 1 - .../implementation/FireBaseCollections.kt | 1 + .../domain/implementation/FireBaseTaskDAO.kt | 25 +++++++++---------- .../studeez/screens/tasks/SubjectScreen.kt | 6 ++--- .../studeez/screens/tasks/SubjectViewModel.kt | 6 ++++- .../studeez/screens/tasks/TaskViewModel.kt | 8 +++--- 8 files changed, 44 insertions(+), 23 deletions(-) create mode 100644 app/src/main/java/be/ugent/sel/studeez/data/SelectedSubject.kt diff --git a/app/src/main/java/be/ugent/sel/studeez/common/composable/SubjectEntry.kt b/app/src/main/java/be/ugent/sel/studeez/common/composable/SubjectEntry.kt index 0352327..e8b8741 100644 --- a/app/src/main/java/be/ugent/sel/studeez/common/composable/SubjectEntry.kt +++ b/app/src/main/java/be/ugent/sel/studeez/common/composable/SubjectEntry.kt @@ -77,7 +77,7 @@ fun SubjectEntry( Icon( imageVector = Icons.Default.List, contentDescription = "tasks" ) - Text(text = subject.tasks.size.toString()) + Text(text = "0/0") // TODO } } } diff --git a/app/src/main/java/be/ugent/sel/studeez/data/SelectedSubject.kt b/app/src/main/java/be/ugent/sel/studeez/data/SelectedSubject.kt new file mode 100644 index 0000000..6e2da9f --- /dev/null +++ b/app/src/main/java/be/ugent/sel/studeez/data/SelectedSubject.kt @@ -0,0 +1,18 @@ +package be.ugent.sel.studeez.data + +import be.ugent.sel.studeez.data.local.models.task.Subject +import javax.inject.Inject +import javax.inject.Singleton + +/** + * Used to communicate the selected subject from the subject overview to the task overview of that subject. + * Because this is a singleton-class the view-models of both screens observe the same data. + */ +@Singleton +class SelectedSubject @Inject constructor() { + private lateinit var subject: Subject + operator fun invoke() = subject + fun set(subject: Subject) { + this.subject = subject + } +} \ No newline at end of file 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 5e8ea0f..e84c2bb 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 @@ -5,7 +5,6 @@ import com.google.firebase.firestore.DocumentId data class Subject( @DocumentId val id: String = "", val name: String = "", - val tasks: List = mutableListOf(), val time: Int = 0, val argb_color: Long = 0, ) \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FireBaseCollections.kt b/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FireBaseCollections.kt index a36361c..78867c9 100644 --- a/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FireBaseCollections.kt +++ b/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FireBaseCollections.kt @@ -5,4 +5,5 @@ object FireBaseCollections { const val USER_COLLECTION = "users" const val TIMER_COLLECTION = "timers" const val SUBJECT_COLLECTION = "subjects" + const val TASK_COLLECTION = "tasks" } \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FireBaseTaskDAO.kt b/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FireBaseTaskDAO.kt index bfb1493..50c99f0 100644 --- a/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FireBaseTaskDAO.kt +++ b/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FireBaseTaskDAO.kt @@ -4,9 +4,11 @@ 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.AccountDAO import be.ugent.sel.studeez.domain.TaskDAO +import com.google.firebase.firestore.CollectionReference import com.google.firebase.firestore.FirebaseFirestore +import com.google.firebase.firestore.ktx.snapshots import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.flowOf +import kotlinx.coroutines.flow.map import javax.inject.Inject class FireBaseTaskDAO @Inject constructor( @@ -14,18 +16,9 @@ class FireBaseTaskDAO @Inject constructor( private val auth: AccountDAO, ) : TaskDAO { override fun getTasks(subject: Subject): Flow> { - return flowOf( - listOf( - Task( - name = "Test Task", - completed = false, - ), - Task( - name = "Test Task 2", - completed = true, - ) - ) - ) + return selectedSubjectTasksCollection(subject) + .snapshots() + .map { it.toObjects(Task::class.java) } } override fun saveTask(newTask: Task) { @@ -36,4 +29,10 @@ class FireBaseTaskDAO @Inject constructor( TODO("Not yet implemented") } + private fun selectedSubjectTasksCollection(subject: Subject): CollectionReference = + firestore.collection(FireBaseCollections.USER_COLLECTION) + .document(auth.currentUserId) + .collection(FireBaseCollections.SUBJECT_COLLECTION) + .document(subject.id) + .collection(FireBaseCollections.TASK_COLLECTION) } \ No newline at end of file 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 3e7c3e1..fbaee8e 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 @@ -32,7 +32,7 @@ fun SubjectRoute( navigationBarActions = navigationBarActions, addSubject = { viewModel.addSubject() }, getSubjects = viewModel::getSubjects, - onViewSubject = { viewModel.onViewSubject(Subject(), open) }, + onViewSubject = { viewModel.onViewSubject(it, open) }, ) } @@ -42,7 +42,7 @@ fun SubjectScreen( navigationBarActions: NavigationBarActions, addSubject: () -> Unit, getSubjects: () -> Flow>, - onViewSubject: () -> Unit, + onViewSubject: (Subject) -> Unit, ) { PrimaryScreenTemplate( title = resources().getString(R.string.tasks), @@ -71,7 +71,7 @@ fun SubjectScreen( items(subjects.value) { SubjectEntry( subject = it, - onViewSubject = onViewSubject, + onViewSubject = { onViewSubject(it) }, ) } } 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 455ed49..31c0c0f 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,7 @@ package be.ugent.sel.studeez.screens.tasks +import android.util.Log +import be.ugent.sel.studeez.data.SelectedSubject import be.ugent.sel.studeez.data.local.models.task.Subject import be.ugent.sel.studeez.domain.LogService import be.ugent.sel.studeez.domain.SubjectDAO @@ -12,13 +14,13 @@ import javax.inject.Inject @HiltViewModel class SubjectViewModel @Inject constructor( private val subjectDAO: SubjectDAO, + private val selectedSubject: SelectedSubject, logService: LogService, ) : StudeezViewModel(logService) { fun addSubject() { subjectDAO.saveSubject( Subject( name = "Test Subject", - tasks = listOf(), time = 0, argb_color = 0xFFF44336, ) @@ -30,6 +32,8 @@ class SubjectViewModel @Inject constructor( } fun onViewSubject(subject: Subject, open: (String) -> Unit) { + Log.v("MYLOG", subject.id) + selectedSubject.set(subject) open(StudeezDestinations.TASKS_SCREEN) } } \ No newline at end of file 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 c86b751..9dc7f2c 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,25 +1,25 @@ package be.ugent.sel.studeez.screens.tasks -import be.ugent.sel.studeez.data.local.models.task.Subject +import be.ugent.sel.studeez.data.SelectedSubject import be.ugent.sel.studeez.data.local.models.task.Task import be.ugent.sel.studeez.domain.LogService import be.ugent.sel.studeez.domain.TaskDAO import be.ugent.sel.studeez.screens.StudeezViewModel import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.flowOf import javax.inject.Inject @HiltViewModel class TaskViewModel @Inject constructor( private val taskDAO: TaskDAO, + private val selectedSubject: SelectedSubject, logService: LogService, ) : StudeezViewModel(logService) { fun addTask() { } - fun getTasks() : Flow> { - return taskDAO.getTasks(Subject()) + fun getTasks(): Flow> { + return taskDAO.getTasks(selectedSubject()) } } \ No newline at end of file From da4c51b726f6f137b367db3a89600b4248cc0876 Mon Sep 17 00:00:00 2001 From: brreynie Date: Tue, 2 May 2023 23:07:04 +0200 Subject: [PATCH 09/22] #25 delete subject --- .../main/java/be/ugent/sel/studeez/StudeezApp.kt | 1 + .../domain/implementation/FireBaseSubjectDAO.kt | 2 +- .../ugent/sel/studeez/screens/tasks/TaskScreen.kt | 9 +++++---- .../sel/studeez/screens/tasks/TaskViewModel.kt | 13 +++++++++++++ 4 files changed, 20 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/be/ugent/sel/studeez/StudeezApp.kt b/app/src/main/java/be/ugent/sel/studeez/StudeezApp.kt index 315c68d..e23e1fe 100644 --- a/app/src/main/java/be/ugent/sel/studeez/StudeezApp.kt +++ b/app/src/main/java/be/ugent/sel/studeez/StudeezApp.kt @@ -159,6 +159,7 @@ fun StudeezNavGraph( composable(StudeezDestinations.TASKS_SCREEN) { TaskRoute( goBack = goBack, + open = open, viewModel = hiltViewModel(), ) } diff --git a/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FireBaseSubjectDAO.kt b/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FireBaseSubjectDAO.kt index 364bdfc..04b1351 100644 --- a/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FireBaseSubjectDAO.kt +++ b/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FireBaseSubjectDAO.kt @@ -25,7 +25,7 @@ class FireBaseSubjectDAO @Inject constructor( } override fun deleteSubject(oldSubject: Subject) { - TODO("Not yet implemented") + currentUserSubjectsCollection().document(oldSubject.id).delete() } private fun currentUserSubjectsCollection(): CollectionReference = diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/tasks/TaskScreen.kt b/app/src/main/java/be/ugent/sel/studeez/screens/tasks/TaskScreen.kt index b35ecb1..bd8053b 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/tasks/TaskScreen.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/tasks/TaskScreen.kt @@ -34,23 +34,24 @@ data class TaskActions( val deleteSubject: () -> Unit, ) -fun getTaskActions(viewModel: TaskViewModel): TaskActions { +fun getTaskActions(viewModel: TaskViewModel, open: (String) -> Unit): TaskActions { return TaskActions( addTask = viewModel::addTask, getTasks = viewModel::getTasks, - getSubject = { Subject(name = "Test Subject") }, - deleteSubject = {}, + getSubject = viewModel::getSelectedSubject, + deleteSubject = { viewModel.deleteSubject(open) }, ) } @Composable fun TaskRoute( goBack: () -> Unit, + open: (String) -> Unit, viewModel: TaskViewModel, ) { TaskScreen( goBack = goBack, - taskActions = getTaskActions(viewModel = viewModel), + taskActions = getTaskActions(viewModel = viewModel, open = open), ) } 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 9dc7f2c..06dce41 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,9 +1,12 @@ package be.ugent.sel.studeez.screens.tasks 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.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 import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.Flow @@ -12,6 +15,7 @@ import javax.inject.Inject @HiltViewModel class TaskViewModel @Inject constructor( private val taskDAO: TaskDAO, + private val subjectDAO: SubjectDAO, private val selectedSubject: SelectedSubject, logService: LogService, ) : StudeezViewModel(logService) { @@ -22,4 +26,13 @@ class TaskViewModel @Inject constructor( fun getTasks(): Flow> { return taskDAO.getTasks(selectedSubject()) } + + fun deleteSubject(open: (String) -> Unit) { + subjectDAO.deleteSubject(selectedSubject()) + open(StudeezDestinations.SUBJECT_SCREEN) + } + + fun getSelectedSubject(): Subject { + return selectedSubject() + } } \ No newline at end of file From ffb67cd1b2af3e771cfb3f88ded39a1b39ef7b40 Mon Sep 17 00:00:00 2001 From: brreynie Date: Tue, 2 May 2023 23:15:42 +0200 Subject: [PATCH 10/22] fix navbar to show tasks as selected --- .../common/composable/navbar/NavigationBarComposable.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/be/ugent/sel/studeez/common/composable/navbar/NavigationBarComposable.kt b/app/src/main/java/be/ugent/sel/studeez/common/composable/navbar/NavigationBarComposable.kt index 7a3da18..a65216d 100644 --- a/app/src/main/java/be/ugent/sel/studeez/common/composable/navbar/NavigationBarComposable.kt +++ b/app/src/main/java/be/ugent/sel/studeez/common/composable/navbar/NavigationBarComposable.kt @@ -15,6 +15,7 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp 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.SUBJECT_SCREEN import be.ugent.sel.studeez.resources import be.ugent.sel.studeez.ui.theme.StudeezTheme import be.ugent.sel.studeez.R.string as AppText @@ -72,8 +73,7 @@ fun NavigationBar( ) }, label = { Text(text = resources().getString(AppText.tasks)) }, - // TODO selected = navigationBarActions.isSelectedTab(TASKS_SCREEN), - selected = false, + selected = navigationBarActions.isSelectedTab(SUBJECT_SCREEN), onClick = navigationBarActions.onTasksClick ) From b7a74a13d76ed39221fbc95c804599edc6ad718b Mon Sep 17 00:00:00 2001 From: brreynie Date: Wed, 3 May 2023 11:38:36 +0200 Subject: [PATCH 11/22] #22 style task entry --- .../composable/{ => tasks}/SubjectEntry.kt | 4 +- .../common/composable/tasks/TaskEntry.kt | 135 ++++++++++++++++++ .../studeez/data/local/models/task/Task.kt | 1 + .../sessionScreens/AbstractSessionScreen.kt | 3 +- .../studeez/screens/tasks/SubjectScreen.kt | 2 +- app/src/main/res/values/strings.xml | 1 + 6 files changed, 143 insertions(+), 3 deletions(-) rename app/src/main/java/be/ugent/sel/studeez/common/composable/{ => tasks}/SubjectEntry.kt (94%) create mode 100644 app/src/main/java/be/ugent/sel/studeez/common/composable/tasks/TaskEntry.kt diff --git a/app/src/main/java/be/ugent/sel/studeez/common/composable/SubjectEntry.kt b/app/src/main/java/be/ugent/sel/studeez/common/composable/tasks/SubjectEntry.kt similarity index 94% rename from app/src/main/java/be/ugent/sel/studeez/common/composable/SubjectEntry.kt rename to app/src/main/java/be/ugent/sel/studeez/common/composable/tasks/SubjectEntry.kt index e8b8741..54fc2a2 100644 --- a/app/src/main/java/be/ugent/sel/studeez/common/composable/SubjectEntry.kt +++ b/app/src/main/java/be/ugent/sel/studeez/common/composable/tasks/SubjectEntry.kt @@ -1,4 +1,4 @@ -package be.ugent.sel.studeez.common.composable +package be.ugent.sel.studeez.common.composable.tasks import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement @@ -24,6 +24,7 @@ import androidx.compose.ui.text.style.TextOverflow 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.StealthButton import be.ugent.sel.studeez.data.local.models.task.Subject import be.ugent.sel.studeez.data.local.models.timer_functional.HoursMinutesSeconds @@ -100,6 +101,7 @@ fun SubjectEntryPreview() { SubjectEntry( subject = Subject( name = "Test Subject", +// name = "Testttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt", argb_color = 0xFFF44336, time = 60 ), diff --git a/app/src/main/java/be/ugent/sel/studeez/common/composable/tasks/TaskEntry.kt b/app/src/main/java/be/ugent/sel/studeez/common/composable/tasks/TaskEntry.kt new file mode 100644 index 0000000..434919b --- /dev/null +++ b/app/src/main/java/be/ugent/sel/studeez/common/composable/tasks/TaskEntry.kt @@ -0,0 +1,135 @@ +package be.ugent.sel.studeez.common.composable.tasks + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.material.Card +import androidx.compose.material.Checkbox +import androidx.compose.material.CheckboxDefaults +import androidx.compose.material.Icon +import androidx.compose.material.IconButton +import androidx.compose.material.MaterialTheme +import androidx.compose.material.Text +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.Delete +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextOverflow +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.StealthButton +import be.ugent.sel.studeez.data.local.models.task.Task +import be.ugent.sel.studeez.data.local.models.timer_functional.HoursMinutesSeconds +import be.ugent.sel.studeez.resources + +@Composable +fun TaskEntry( + task: Task, +) { + Card( + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 10.dp, vertical = 5.dp), + ) { + val color = if (task.completed) Color.Gray else Color.Black + Row( + horizontalArrangement = Arrangement.SpaceBetween, + verticalAlignment = Alignment.CenterVertically, + ) { + Row( + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier + .padding(start = 10.dp) + .weight(22f), + ) { + Checkbox( + checked = task.completed, + onCheckedChange = {}, + colors = CheckboxDefaults.colors( + checkedColor = Color.Gray, + uncheckedColor = MaterialTheme.colors.onSurface, + ) + ) + Row( + horizontalArrangement = Arrangement.SpaceBetween, + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier.fillMaxWidth() + ) { + Text( + text = task.name, + overflow = TextOverflow.Ellipsis, + maxLines = 1, + color = color, + modifier = Modifier.weight(13f), + ) + Text( + text = "${HoursMinutesSeconds(task.time)}", + color = color, + modifier = Modifier.weight(5f) + ) + + } + } + Box(modifier = Modifier.weight(7f)) { + if (task.completed) { + IconButton( + onClick = { /*TODO*/ }, + modifier = Modifier + .padding(start = 20.dp) + ) { + Icon( + imageVector = Icons.Default.Delete, + contentDescription = resources().getString(R.string.delete_task), + ) + } + } else { + StealthButton( + text = R.string.start, + modifier = Modifier + .padding(end = 5.dp), + ) { + } + } + } + } + } +} + +@Preview +@Composable +fun TaskEntryPreview() { + TaskEntry( + task = Task( + name = "Test Task", + completed = false, + ), + ) +} + +@Preview +@Composable +fun CompletedTaskEntryPreview() { + TaskEntry( + task = Task( + name = "Test Task", + completed = true, + ) + ) +} + +@Preview +@Composable +fun OverflowTaskEntryPreview() { + TaskEntry( + task = Task( + name = "Test Taskkkkkkkkkkkkkkkkkkkkkkkkkkk", + completed = false, + ), + ) +} \ No newline at end of file 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 62ebf7d..bde6932 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 @@ -6,4 +6,5 @@ data class Task( @DocumentId val id: String = "", val name: String = "", val completed: Boolean = false, + val time: Int = 0, ) diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/session/sessionScreens/AbstractSessionScreen.kt b/app/src/main/java/be/ugent/sel/studeez/screens/session/sessionScreens/AbstractSessionScreen.kt index ca9d9c0..c3a4cd8 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/session/sessionScreens/AbstractSessionScreen.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/session/sessionScreens/AbstractSessionScreen.kt @@ -19,6 +19,7 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalEndlessTimer +import be.ugent.sel.studeez.data.local.models.timer_functional.HoursMinutesSeconds import be.ugent.sel.studeez.navigation.StudeezDestinations import be.ugent.sel.studeez.screens.session.SessionActions import kotlinx.coroutines.delay @@ -93,7 +94,7 @@ abstract class AbstractSessionScreen { val hms = sessionActions.getTimer().getHoursMinutesSeconds() Column { Text( - text = "${hms.hours} : ${hms.minutes} : ${hms.seconds}", + text = hms.toString(), modifier = Modifier .fillMaxWidth() .padding(50.dp), 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 fbaee8e..64c2b8f 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 @@ -12,9 +12,9 @@ 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.common.composable.tasks.SubjectEntry import be.ugent.sel.studeez.data.local.models.task.Subject import be.ugent.sel.studeez.resources import kotlinx.coroutines.flow.Flow diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index bb0d6fd..fbf6c5b 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -47,6 +47,7 @@ View Edit Task Delete Subject + Delete Task Sessions From 71590bd5a2c04bbb2508c151fbc92b8f07f57c99 Mon Sep 17 00:00:00 2001 From: brreynie Date: Wed, 3 May 2023 14:58:41 +0200 Subject: [PATCH 12/22] #23 toggle task completed and #24 delete task --- .../studeez/common/composable/tasks/TaskEntry.kt | 14 +++++++++----- .../sel/studeez/data/local/models/task/Task.kt | 1 + .../java/be/ugent/sel/studeez/domain/TaskDAO.kt | 2 ++ .../domain/implementation/FireBaseTaskDAO.kt | 14 ++++++++++---- .../ugent/sel/studeez/screens/tasks/TaskScreen.kt | 14 ++++++++++++-- .../sel/studeez/screens/tasks/TaskViewModel.kt | 8 ++++++++ 6 files changed, 42 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/be/ugent/sel/studeez/common/composable/tasks/TaskEntry.kt b/app/src/main/java/be/ugent/sel/studeez/common/composable/tasks/TaskEntry.kt index 434919b..458cafc 100644 --- a/app/src/main/java/be/ugent/sel/studeez/common/composable/tasks/TaskEntry.kt +++ b/app/src/main/java/be/ugent/sel/studeez/common/composable/tasks/TaskEntry.kt @@ -18,7 +18,6 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color -import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp @@ -31,13 +30,15 @@ import be.ugent.sel.studeez.resources @Composable fun TaskEntry( task: Task, + onCheckTask: (Boolean) -> Unit, + onDeleteTask: () -> Unit, ) { Card( modifier = Modifier .fillMaxWidth() .padding(horizontal = 10.dp, vertical = 5.dp), ) { - val color = if (task.completed) Color.Gray else Color.Black + val color = if (task.completed) Color.Gray else MaterialTheme.colors.onSurface Row( horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically, @@ -50,7 +51,7 @@ fun TaskEntry( ) { Checkbox( checked = task.completed, - onCheckedChange = {}, + onCheckedChange = onCheckTask, colors = CheckboxDefaults.colors( checkedColor = Color.Gray, uncheckedColor = MaterialTheme.colors.onSurface, @@ -79,7 +80,7 @@ fun TaskEntry( Box(modifier = Modifier.weight(7f)) { if (task.completed) { IconButton( - onClick = { /*TODO*/ }, + onClick = onDeleteTask, modifier = Modifier .padding(start = 20.dp) ) { @@ -109,6 +110,7 @@ fun TaskEntryPreview() { name = "Test Task", completed = false, ), + {}, {}, ) } @@ -119,7 +121,8 @@ fun CompletedTaskEntryPreview() { task = Task( name = "Test Task", completed = true, - ) + ), + {}, {}, ) } @@ -131,5 +134,6 @@ fun OverflowTaskEntryPreview() { name = "Test Taskkkkkkkkkkkkkkkkkkkkkkkkkkk", completed = false, ), + {}, {}, ) } \ No newline at end of file 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 bde6932..05a5020 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 @@ -7,4 +7,5 @@ data class Task( val name: String = "", val completed: Boolean = false, val time: Int = 0, + val subjectId: String = "", ) diff --git a/app/src/main/java/be/ugent/sel/studeez/domain/TaskDAO.kt b/app/src/main/java/be/ugent/sel/studeez/domain/TaskDAO.kt index 2fb5dde..38c639a 100644 --- a/app/src/main/java/be/ugent/sel/studeez/domain/TaskDAO.kt +++ b/app/src/main/java/be/ugent/sel/studeez/domain/TaskDAO.kt @@ -11,4 +11,6 @@ interface TaskDAO { fun saveTask(newTask: Task) fun deleteTask(oldTask: Task) + + fun toggleTaskCompleted(task: Task, completed: Boolean) } \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FireBaseTaskDAO.kt b/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FireBaseTaskDAO.kt index 50c99f0..09e8cdf 100644 --- a/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FireBaseTaskDAO.kt +++ b/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FireBaseTaskDAO.kt @@ -16,7 +16,7 @@ class FireBaseTaskDAO @Inject constructor( private val auth: AccountDAO, ) : TaskDAO { override fun getTasks(subject: Subject): Flow> { - return selectedSubjectTasksCollection(subject) + return selectedSubjectTasksCollection(subject.id) .snapshots() .map { it.toObjects(Task::class.java) } } @@ -26,13 +26,19 @@ class FireBaseTaskDAO @Inject constructor( } override fun deleteTask(oldTask: Task) { - TODO("Not yet implemented") + selectedSubjectTasksCollection(oldTask.subjectId).document(oldTask.id).delete() } - private fun selectedSubjectTasksCollection(subject: Subject): CollectionReference = + override fun toggleTaskCompleted(task: Task, completed: Boolean) { + selectedSubjectTasksCollection(task.subjectId) + .document(task.id) + .update("completed", completed) + } + + private fun selectedSubjectTasksCollection(subjectId: String): CollectionReference = firestore.collection(FireBaseCollections.USER_COLLECTION) .document(auth.currentUserId) .collection(FireBaseCollections.SUBJECT_COLLECTION) - .document(subject.id) + .document(subjectId) .collection(FireBaseCollections.TASK_COLLECTION) } \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/tasks/TaskScreen.kt b/app/src/main/java/be/ugent/sel/studeez/screens/tasks/TaskScreen.kt index bd8053b..316fe31 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/tasks/TaskScreen.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/tasks/TaskScreen.kt @@ -7,7 +7,6 @@ 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 @@ -20,6 +19,7 @@ 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.composable.tasks.TaskEntry 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 @@ -32,6 +32,8 @@ data class TaskActions( val getSubject: () -> Subject, val getTasks: () -> Flow>, val deleteSubject: () -> Unit, + val deleteTask: (Task) -> Unit, + val onCheckTask: (Task, Boolean) -> Unit, ) fun getTaskActions(viewModel: TaskViewModel, open: (String) -> Unit): TaskActions { @@ -40,6 +42,8 @@ fun getTaskActions(viewModel: TaskViewModel, open: (String) -> Unit): TaskAction getTasks = viewModel::getTasks, getSubject = viewModel::getSelectedSubject, deleteSubject = { viewModel.deleteSubject(open) }, + deleteTask = viewModel::deleteTask, + onCheckTask = { task, isChecked -> viewModel.toggleTaskCompleted(task, isChecked) }, ) } @@ -71,7 +75,11 @@ fun TaskScreen( ) { LazyColumn { items(tasks.value) { - Text(text = it.name) + TaskEntry( + task = it, + onCheckTask = { isChecked -> taskActions.onCheckTask(it, isChecked) }, + onDeleteTask = { taskActions.deleteTask(it) }, + ) } } NewTaskSubjectButton(onClick = taskActions.addTask, R.string.new_task) @@ -111,6 +119,8 @@ fun TaskScreenPreview() { { Subject(name = "Test Subject") }, { flowOf() }, {}, + {}, + { _, _ -> run {} }, ) ) } \ No newline at end of file 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 06dce41..105a200 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 @@ -35,4 +35,12 @@ class TaskViewModel @Inject constructor( fun getSelectedSubject(): Subject { return selectedSubject() } + + fun deleteTask(task: Task) { + taskDAO.deleteTask(task) + } + + fun toggleTaskCompleted(task: Task, completed: Boolean) { + taskDAO.toggleTaskCompleted(task, completed) + } } \ No newline at end of file From 831050f3f2bf8c1b60094d2b9e3d67c1dcba8b32 Mon Sep 17 00:00:00 2001 From: brreynie Date: Wed, 3 May 2023 21:48:23 +0200 Subject: [PATCH 13/22] #15 and #16 form to create and edit subject --- .../common/composable/ButtonComposable.kt | 22 ++++ .../common/composable/tasks/SubjectEntry.kt | 2 +- .../common/composable/tasks/TaskEntry.kt | 2 +- .../be/ugent/sel/studeez/domain/SubjectDAO.kt | 2 + .../implementation/FireBaseSubjectDAO.kt | 4 + .../screens/tasks/forms/SubjectFormScreen.kt | 106 ++++++++++++++++++ .../screens/tasks/forms/SubjectFormUiState.kt | 6 + .../tasks/forms/SubjectFormViewModel.kt | 63 +++++++++++ app/src/main/res/values/strings.xml | 3 +- 9 files changed, 207 insertions(+), 3 deletions(-) create mode 100644 app/src/main/java/be/ugent/sel/studeez/screens/tasks/forms/SubjectFormScreen.kt create mode 100644 app/src/main/java/be/ugent/sel/studeez/screens/tasks/forms/SubjectFormUiState.kt create mode 100644 app/src/main/java/be/ugent/sel/studeez/screens/tasks/forms/SubjectFormViewModel.kt diff --git a/app/src/main/java/be/ugent/sel/studeez/common/composable/ButtonComposable.kt b/app/src/main/java/be/ugent/sel/studeez/common/composable/ButtonComposable.kt index 286ea96..0d6d9e8 100644 --- a/app/src/main/java/be/ugent/sel/studeez/common/composable/ButtonComposable.kt +++ b/app/src/main/java/be/ugent/sel/studeez/common/composable/ButtonComposable.kt @@ -88,6 +88,28 @@ fun StealthButtonCardPreview() { } } + +@Composable +fun DeleteButton( + onClick: () -> Unit, +) { + BasicButton( + text = R.string.delete_subject, + modifier = Modifier.basicButton(), + onClick = onClick, + colors = ButtonDefaults.buttonColors( + backgroundColor = Color.Red, + contentColor = Color.White, + ), + ) +} + +@Preview +@Composable +fun DeleteButtonPreview() { + DeleteButton {} +} + @Composable fun DialogConfirmButton(@StringRes text: Int, action: () -> Unit) { Button( diff --git a/app/src/main/java/be/ugent/sel/studeez/common/composable/tasks/SubjectEntry.kt b/app/src/main/java/be/ugent/sel/studeez/common/composable/tasks/SubjectEntry.kt index 54fc2a2..5c19c80 100644 --- a/app/src/main/java/be/ugent/sel/studeez/common/composable/tasks/SubjectEntry.kt +++ b/app/src/main/java/be/ugent/sel/studeez/common/composable/tasks/SubjectEntry.kt @@ -84,7 +84,7 @@ fun SubjectEntry( } } StealthButton( - text = R.string.view_task, + text = R.string.view_tasks, modifier = Modifier .padding(start = 10.dp, end = 5.dp) .weight(1f) diff --git a/app/src/main/java/be/ugent/sel/studeez/common/composable/tasks/TaskEntry.kt b/app/src/main/java/be/ugent/sel/studeez/common/composable/tasks/TaskEntry.kt index 458cafc..fefb924 100644 --- a/app/src/main/java/be/ugent/sel/studeez/common/composable/tasks/TaskEntry.kt +++ b/app/src/main/java/be/ugent/sel/studeez/common/composable/tasks/TaskEntry.kt @@ -72,7 +72,7 @@ fun TaskEntry( Text( text = "${HoursMinutesSeconds(task.time)}", color = color, - modifier = Modifier.weight(5f) + modifier = Modifier.weight(7f) ) } diff --git a/app/src/main/java/be/ugent/sel/studeez/domain/SubjectDAO.kt b/app/src/main/java/be/ugent/sel/studeez/domain/SubjectDAO.kt index dd24b45..2749fac 100644 --- a/app/src/main/java/be/ugent/sel/studeez/domain/SubjectDAO.kt +++ b/app/src/main/java/be/ugent/sel/studeez/domain/SubjectDAO.kt @@ -10,4 +10,6 @@ interface SubjectDAO { fun saveSubject(newSubject: Subject) fun deleteSubject(oldSubject: Subject) + + fun updateSubject(newSubject: Subject) } \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FireBaseSubjectDAO.kt b/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FireBaseSubjectDAO.kt index 04b1351..7d90fbf 100644 --- a/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FireBaseSubjectDAO.kt +++ b/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FireBaseSubjectDAO.kt @@ -28,6 +28,10 @@ class FireBaseSubjectDAO @Inject constructor( currentUserSubjectsCollection().document(oldSubject.id).delete() } + override fun updateSubject(newSubject: Subject) { + currentUserSubjectsCollection().document(newSubject.id).set(newSubject) + } + private fun currentUserSubjectsCollection(): CollectionReference = firestore.collection(FireBaseCollections.USER_COLLECTION) .document(auth.currentUserId) diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/tasks/forms/SubjectFormScreen.kt b/app/src/main/java/be/ugent/sel/studeez/screens/tasks/forms/SubjectFormScreen.kt new file mode 100644 index 0000000..b2a8055 --- /dev/null +++ b/app/src/main/java/be/ugent/sel/studeez/screens/tasks/forms/SubjectFormScreen.kt @@ -0,0 +1,106 @@ +package be.ugent.sel.studeez.screens.tasks.forms + +import androidx.annotation.StringRes +import androidx.compose.foundation.layout.Column +import androidx.compose.material.OutlinedTextField +import androidx.compose.material.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.tooling.preview.Preview +import be.ugent.sel.studeez.R +import be.ugent.sel.studeez.common.composable.BasicButton +import be.ugent.sel.studeez.common.composable.DeleteButton +import be.ugent.sel.studeez.common.composable.SecondaryScreenTemplate +import be.ugent.sel.studeez.common.ext.basicButton +import be.ugent.sel.studeez.common.ext.fieldModifier +import be.ugent.sel.studeez.resources + +@Composable +fun SubjectAddRoute( + goBack: () -> Unit, + open: (String) -> Unit, + viewModel: SubjectFormViewModel, +) { + val uiState by viewModel.uiState + SubjectForm( + title = R.string.new_subject, + goBack = goBack, + uiState = uiState, + onConfirm = { viewModel.onCreate(open) }, + ) +} + +@Composable +fun SubjectEditRoute( + goBack: () -> Unit, + open: (String) -> Unit, + viewModel: SubjectFormViewModel, +) { + val uiState by viewModel.uiState + SubjectForm( + title = R.string.edit_subject, + goBack = goBack, + uiState = uiState, + onConfirm = { viewModel.onEdit(open) }, + ) { + DeleteButton(onClick = viewModel::onDelete) + } +} + +@Composable +fun SubjectForm( + @StringRes title: Int, + goBack: () -> Unit, + uiState: SubjectFormUiState, + onConfirm: () -> Unit, + extraButton: @Composable () -> Unit = {}, +) { + SecondaryScreenTemplate( + title = resources().getString(title), + popUp = goBack, + ) { + Column { + OutlinedTextField( + singleLine = true, + value = uiState.name, + onValueChange = {}, + placeholder = { Text(stringResource(id = R.string.username)) }, + modifier = Modifier.fieldModifier(), + ) + BasicButton( + text = R.string.confirm, + modifier = Modifier.basicButton(), + onClick = onConfirm, + ) + extraButton() + } + } +} + +@Preview +@Composable +fun AddSubjectFormPreview() { + SubjectForm( + title = R.string.new_subject, + goBack = {}, + uiState = SubjectFormUiState(), + onConfirm = {}, + ) +} + +@Preview +@Composable +fun EditSubjectFormPreview() { + SubjectForm( + title = R.string.edit_subject, + goBack = {}, + uiState = SubjectFormUiState( + name = "Test Subject", + ), + onConfirm = {}, + ) { + DeleteButton {} + } +} \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/tasks/forms/SubjectFormUiState.kt b/app/src/main/java/be/ugent/sel/studeez/screens/tasks/forms/SubjectFormUiState.kt new file mode 100644 index 0000000..6e8f9cf --- /dev/null +++ b/app/src/main/java/be/ugent/sel/studeez/screens/tasks/forms/SubjectFormUiState.kt @@ -0,0 +1,6 @@ +package be.ugent.sel.studeez.screens.tasks.forms + +data class SubjectFormUiState( + val name: String = "", + val color: Long = 0xFFF44336, +) \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/tasks/forms/SubjectFormViewModel.kt b/app/src/main/java/be/ugent/sel/studeez/screens/tasks/forms/SubjectFormViewModel.kt new file mode 100644 index 0000000..99ea85c --- /dev/null +++ b/app/src/main/java/be/ugent/sel/studeez/screens/tasks/forms/SubjectFormViewModel.kt @@ -0,0 +1,63 @@ +package be.ugent.sel.studeez.screens.tasks.forms + +import androidx.compose.runtime.mutableStateOf +import be.ugent.sel.studeez.data.SelectedSubject +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.navigation.StudeezDestinations +import be.ugent.sel.studeez.screens.StudeezViewModel +import dagger.hilt.android.lifecycle.HiltViewModel +import javax.inject.Inject + +@HiltViewModel +class SubjectFormViewModel @Inject constructor( + private val subjectDAO: SubjectDAO, + private val selectedSubject: SelectedSubject, + logService: LogService, +) : StudeezViewModel(logService) { + var uiState = mutableStateOf(SubjectFormUiState()) + private set + + private val name: String + get() = uiState.value.name + + private val color: Long + get() = uiState.value.color + + fun onNameChange(newValue: String) { + uiState.value = uiState.value.copy(name = newValue) + } + + fun onColorChange(newValue: Long) { + uiState.value = uiState.value.copy(color = newValue) + } + + fun onDelete() { + subjectDAO.deleteSubject(selectedSubject()) + } + + fun onCreate(open: (String) -> Unit) { + val newSubject = Subject( + name = name, + argb_color = color, + ) + subjectDAO.saveSubject( + newSubject + ) + selectedSubject.set(newSubject) + // TODO open newly created subject +// open(StudeezDestinations.TASKS_SCREEN) + } + + fun onEdit(open: (String) -> Unit) { + val newSubject = selectedSubject().copy( + name = name, + argb_color = color, + ) + subjectDAO.updateSubject( + newSubject + ) + open(StudeezDestinations.TASKS_SCREEN) + } +} \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index fbf6c5b..de9589f 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -44,10 +44,11 @@ Tasks New Subject New Task - View + Edit Subject Edit Task Delete Subject Delete Task + View Sessions From fc1d12e214c995c32827687e028d08e8cf8cd971 Mon Sep 17 00:00:00 2001 From: brreynie Date: Wed, 3 May 2023 22:06:30 +0200 Subject: [PATCH 14/22] #15 make form functional --- .../java/be/ugent/sel/studeez/StudeezApp.kt | 18 ++++++++++++++++++ .../studeez/navigation/StudeezDestinations.kt | 3 +++ .../sel/studeez/screens/tasks/SubjectScreen.kt | 15 +-------------- .../studeez/screens/tasks/SubjectViewModel.kt | 12 ++---------- .../sel/studeez/screens/tasks/TaskScreen.kt | 17 ++++------------- .../sel/studeez/screens/tasks/TaskViewModel.kt | 4 ++++ .../screens/tasks/forms/SubjectFormScreen.kt | 15 +++++++++++++-- .../tasks/forms/SubjectFormViewModel.kt | 4 +++- 8 files changed, 48 insertions(+), 40 deletions(-) diff --git a/app/src/main/java/be/ugent/sel/studeez/StudeezApp.kt b/app/src/main/java/be/ugent/sel/studeez/StudeezApp.kt index e23e1fe..276e250 100644 --- a/app/src/main/java/be/ugent/sel/studeez/StudeezApp.kt +++ b/app/src/main/java/be/ugent/sel/studeez/StudeezApp.kt @@ -42,6 +42,8 @@ import be.ugent.sel.studeez.screens.sign_up.SignUpRoute 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.forms.SubjectAddRoute +import be.ugent.sel.studeez.screens.tasks.forms.SubjectEditRoute import be.ugent.sel.studeez.screens.timer_overview.TimerOverviewRoute import be.ugent.sel.studeez.screens.timer_selection.TimerSelectionRoute import be.ugent.sel.studeez.ui.theme.StudeezTheme @@ -156,6 +158,22 @@ fun StudeezNavGraph( ) } + composable(StudeezDestinations.ADD_SUBJECT_FORM) { + SubjectAddRoute( + goBack = goBack, + open = open, + viewModel = hiltViewModel(), + ) + } + + composable(StudeezDestinations.EDIT_SUBJECT_FORM) { + SubjectEditRoute( + goBack = goBack, + open = open, + viewModel = hiltViewModel(), + ) + } + composable(StudeezDestinations.TASKS_SCREEN) { TaskRoute( goBack = goBack, diff --git a/app/src/main/java/be/ugent/sel/studeez/navigation/StudeezDestinations.kt b/app/src/main/java/be/ugent/sel/studeez/navigation/StudeezDestinations.kt index 1d7ed4a..f56b872 100644 --- a/app/src/main/java/be/ugent/sel/studeez/navigation/StudeezDestinations.kt +++ b/app/src/main/java/be/ugent/sel/studeez/navigation/StudeezDestinations.kt @@ -10,7 +10,10 @@ object StudeezDestinations { const val TIMER_SELECTION_SCREEN = "timer_selection" const val SESSION_SCREEN = "session" const val SESSION_RECAP = "session_recap" + const val SUBJECT_SCREEN = "subjects" + const val ADD_SUBJECT_FORM = "add_subject" + const val EDIT_SUBJECT_FORM = "edit_subject" const val TASKS_SCREEN = "tasks" // const val SESSIONS_SCREEN = "sessions" 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 64c2b8f..fef7e1d 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 @@ -30,7 +30,7 @@ fun SubjectRoute( SubjectScreen( drawerActions = drawerActions, navigationBarActions = navigationBarActions, - addSubject = { viewModel.addSubject() }, + addSubject = { viewModel.addSubject(open) }, getSubjects = viewModel::getSubjects, onViewSubject = { viewModel.onViewSubject(it, open) }, ) @@ -55,19 +55,6 @@ fun SubjectScreen( 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, 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 31c0c0f..f1d6071 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,6 +1,5 @@ package be.ugent.sel.studeez.screens.tasks -import android.util.Log import be.ugent.sel.studeez.data.SelectedSubject import be.ugent.sel.studeez.data.local.models.task.Subject import be.ugent.sel.studeez.domain.LogService @@ -17,14 +16,8 @@ class SubjectViewModel @Inject constructor( private val selectedSubject: SelectedSubject, logService: LogService, ) : StudeezViewModel(logService) { - fun addSubject() { - subjectDAO.saveSubject( - Subject( - name = "Test Subject", - time = 0, - argb_color = 0xFFF44336, - ) - ) + fun addSubject(open: (String) -> Unit) { + open(StudeezDestinations.ADD_SUBJECT_FORM) } fun getSubjects(): Flow> { @@ -32,7 +25,6 @@ class SubjectViewModel @Inject constructor( } fun onViewSubject(subject: Subject, open: (String) -> Unit) { - Log.v("MYLOG", subject.id) selectedSubject.set(subject) open(StudeezDestinations.TASKS_SCREEN) } diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/tasks/TaskScreen.kt b/app/src/main/java/be/ugent/sel/studeez/screens/tasks/TaskScreen.kt index 316fe31..bd41cff 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/tasks/TaskScreen.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/tasks/TaskScreen.kt @@ -31,9 +31,9 @@ data class TaskActions( val addTask: () -> Unit, val getSubject: () -> Subject, val getTasks: () -> Flow>, - val deleteSubject: () -> Unit, val deleteTask: (Task) -> Unit, val onCheckTask: (Task, Boolean) -> Unit, + val editSubject: () -> Unit, ) fun getTaskActions(viewModel: TaskViewModel, open: (String) -> Unit): TaskActions { @@ -41,9 +41,9 @@ fun getTaskActions(viewModel: TaskViewModel, open: (String) -> Unit): TaskAction addTask = viewModel::addTask, getTasks = viewModel::getTasks, getSubject = viewModel::getSelectedSubject, - deleteSubject = { viewModel.deleteSubject(open) }, deleteTask = viewModel::deleteTask, onCheckTask = { task, isChecked -> viewModel.toggleTaskCompleted(task, isChecked) }, + editSubject = { viewModel.editSubject(open) } ) } @@ -67,7 +67,7 @@ fun TaskScreen( SecondaryScreenTemplate( title = taskActions.getSubject().name, popUp = goBack, - barAction = { EditAction {} } // TODO implement + barAction = { EditAction(onClick = taskActions.editSubject) } ) { val tasks = taskActions.getTasks().collectAsState(initial = emptyList()) Column( @@ -83,15 +83,6 @@ fun TaskScreen( } } 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, - ) } } } @@ -119,8 +110,8 @@ fun TaskScreenPreview() { { Subject(name = "Test Subject") }, { flowOf() }, {}, - {}, { _, _ -> run {} }, + {}, ) ) } \ No newline at end of file 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 105a200..26b8c17 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 @@ -43,4 +43,8 @@ class TaskViewModel @Inject constructor( fun toggleTaskCompleted(task: Task, completed: Boolean) { taskDAO.toggleTaskCompleted(task, completed) } + + fun editSubject(open: (String) -> Unit) { + open(StudeezDestinations.EDIT_SUBJECT_FORM) + } } \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/tasks/forms/SubjectFormScreen.kt b/app/src/main/java/be/ugent/sel/studeez/screens/tasks/forms/SubjectFormScreen.kt index b2a8055..e97dc74 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/tasks/forms/SubjectFormScreen.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/tasks/forms/SubjectFormScreen.kt @@ -7,6 +7,7 @@ import androidx.compose.material.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview import be.ugent.sel.studeez.R @@ -29,6 +30,8 @@ fun SubjectAddRoute( goBack = goBack, uiState = uiState, onConfirm = { viewModel.onCreate(open) }, + onNameChange = viewModel::onNameChange, + onColorChange = {}, ) } @@ -44,8 +47,10 @@ fun SubjectEditRoute( goBack = goBack, uiState = uiState, onConfirm = { viewModel.onEdit(open) }, + onNameChange = viewModel::onNameChange, + onColorChange = {}, ) { - DeleteButton(onClick = viewModel::onDelete) + DeleteButton(onClick = { viewModel.onDelete(open) }) } } @@ -55,6 +60,8 @@ fun SubjectForm( goBack: () -> Unit, uiState: SubjectFormUiState, onConfirm: () -> Unit, + onNameChange: (String) -> Unit, + onColorChange: (Color) -> Unit, extraButton: @Composable () -> Unit = {}, ) { SecondaryScreenTemplate( @@ -65,7 +72,7 @@ fun SubjectForm( OutlinedTextField( singleLine = true, value = uiState.name, - onValueChange = {}, + onValueChange = onNameChange, placeholder = { Text(stringResource(id = R.string.username)) }, modifier = Modifier.fieldModifier(), ) @@ -87,6 +94,8 @@ fun AddSubjectFormPreview() { goBack = {}, uiState = SubjectFormUiState(), onConfirm = {}, + onNameChange = {}, + onColorChange = {}, ) } @@ -100,6 +109,8 @@ fun EditSubjectFormPreview() { name = "Test Subject", ), onConfirm = {}, + onNameChange = {}, + onColorChange = {}, ) { DeleteButton {} } diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/tasks/forms/SubjectFormViewModel.kt b/app/src/main/java/be/ugent/sel/studeez/screens/tasks/forms/SubjectFormViewModel.kt index 99ea85c..ec246f4 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/tasks/forms/SubjectFormViewModel.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/tasks/forms/SubjectFormViewModel.kt @@ -33,8 +33,9 @@ class SubjectFormViewModel @Inject constructor( uiState.value = uiState.value.copy(color = newValue) } - fun onDelete() { + fun onDelete(open: (String) -> Unit) { subjectDAO.deleteSubject(selectedSubject()) + open(StudeezDestinations.SUBJECT_SCREEN) } fun onCreate(open: (String) -> Unit) { @@ -48,6 +49,7 @@ class SubjectFormViewModel @Inject constructor( selectedSubject.set(newSubject) // TODO open newly created subject // open(StudeezDestinations.TASKS_SCREEN) + open(StudeezDestinations.SUBJECT_SCREEN) } fun onEdit(open: (String) -> Unit) { From 6a676c2fad9a2563a42aa3dc99781b91bcb6e859 Mon Sep 17 00:00:00 2001 From: brreynie Date: Wed, 3 May 2023 22:22:52 +0200 Subject: [PATCH 15/22] fix username -> name --- app/build.gradle | 2 ++ .../ugent/sel/studeez/screens/tasks/forms/SubjectFormScreen.kt | 2 +- app/src/main/res/values/strings.xml | 3 +++ 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index bca9a30..5dc6aa5 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -120,6 +120,8 @@ dependencies { implementation 'com.google.firebase:firebase-perf-ktx' implementation 'com.google.firebase:firebase-config-ktx' + // Colorpicker + implementation 'com.github.skydoves:colorpicker-compose:1.0.2' } // Allow references to generate code diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/tasks/forms/SubjectFormScreen.kt b/app/src/main/java/be/ugent/sel/studeez/screens/tasks/forms/SubjectFormScreen.kt index e97dc74..38ef6f5 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/tasks/forms/SubjectFormScreen.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/tasks/forms/SubjectFormScreen.kt @@ -73,7 +73,7 @@ fun SubjectForm( singleLine = true, value = uiState.name, onValueChange = onNameChange, - placeholder = { Text(stringResource(id = R.string.username)) }, + placeholder = { Text(stringResource(id = R.string.name)) }, modifier = Modifier.fieldModifier(), ) BasicButton( diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index de9589f..9e0efb9 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -50,6 +50,9 @@ Delete Task View + + Name + Sessions From 6765229d3763f0ccfe9aaf261a8f6f8679ba4170 Mon Sep 17 00:00:00 2001 From: brreynie Date: Wed, 3 May 2023 23:18:53 +0200 Subject: [PATCH 16/22] #13 and #17 form for creating, editing and deleting tasks --- .../java/be/ugent/sel/studeez/StudeezApp.kt | 22 +++- .../common/composable/ButtonComposable.kt | 5 +- .../ugent/sel/studeez/data/SelectedSubject.kt | 4 +- .../be/ugent/sel/studeez/data/SelectedTask.kt | 21 ++++ .../be/ugent/sel/studeez/domain/TaskDAO.kt | 2 + .../domain/implementation/FireBaseTaskDAO.kt | 6 +- .../studeez/navigation/StudeezDestinations.kt | 2 + .../sel/studeez/screens/tasks/TaskScreen.kt | 6 +- .../studeez/screens/tasks/TaskViewModel.kt | 4 +- .../screens/tasks/forms/SubjectFormScreen.kt | 14 ++- .../tasks/forms/SubjectFormViewModel.kt | 26 ++-- .../screens/tasks/forms/TaskFormScreen.kt | 113 ++++++++++++++++++ .../screens/tasks/forms/TaskFormUiState.kt | 5 + .../screens/tasks/forms/TaskFormViewModel.kt | 49 ++++++++ 14 files changed, 249 insertions(+), 30 deletions(-) create mode 100644 app/src/main/java/be/ugent/sel/studeez/data/SelectedTask.kt create mode 100644 app/src/main/java/be/ugent/sel/studeez/screens/tasks/forms/TaskFormScreen.kt create mode 100644 app/src/main/java/be/ugent/sel/studeez/screens/tasks/forms/TaskFormUiState.kt create mode 100644 app/src/main/java/be/ugent/sel/studeez/screens/tasks/forms/TaskFormViewModel.kt diff --git a/app/src/main/java/be/ugent/sel/studeez/StudeezApp.kt b/app/src/main/java/be/ugent/sel/studeez/StudeezApp.kt index 276e250..0c8ee3c 100644 --- a/app/src/main/java/be/ugent/sel/studeez/StudeezApp.kt +++ b/app/src/main/java/be/ugent/sel/studeez/StudeezApp.kt @@ -44,6 +44,8 @@ import be.ugent.sel.studeez.screens.tasks.SubjectRoute import be.ugent.sel.studeez.screens.tasks.TaskRoute import be.ugent.sel.studeez.screens.tasks.forms.SubjectAddRoute import be.ugent.sel.studeez.screens.tasks.forms.SubjectEditRoute +import be.ugent.sel.studeez.screens.tasks.forms.TaskAddRoute +import be.ugent.sel.studeez.screens.tasks.forms.TaskEditRoute import be.ugent.sel.studeez.screens.timer_overview.TimerOverviewRoute import be.ugent.sel.studeez.screens.timer_selection.TimerSelectionRoute import be.ugent.sel.studeez.ui.theme.StudeezTheme @@ -161,7 +163,7 @@ fun StudeezNavGraph( composable(StudeezDestinations.ADD_SUBJECT_FORM) { SubjectAddRoute( goBack = goBack, - open = open, + openAndPopUp = openAndPopUp, viewModel = hiltViewModel(), ) } @@ -169,7 +171,23 @@ fun StudeezNavGraph( composable(StudeezDestinations.EDIT_SUBJECT_FORM) { SubjectEditRoute( goBack = goBack, - open = open, + openAndPopUp = openAndPopUp, + viewModel = hiltViewModel(), + ) + } + + composable(StudeezDestinations.ADD_TASK_FORM) { + TaskAddRoute( + goBack = goBack, + openAndPopUp = openAndPopUp, + viewModel = hiltViewModel(), + ) + } + + composable(StudeezDestinations.EDIT_TASK_FORM) { + TaskEditRoute( + goBack = goBack, + openAndPopUp = openAndPopUp, viewModel = hiltViewModel(), ) } diff --git a/app/src/main/java/be/ugent/sel/studeez/common/composable/ButtonComposable.kt b/app/src/main/java/be/ugent/sel/studeez/common/composable/ButtonComposable.kt index 0d6d9e8..a98b24b 100644 --- a/app/src/main/java/be/ugent/sel/studeez/common/composable/ButtonComposable.kt +++ b/app/src/main/java/be/ugent/sel/studeez/common/composable/ButtonComposable.kt @@ -91,10 +91,11 @@ fun StealthButtonCardPreview() { @Composable fun DeleteButton( + @StringRes text: Int, onClick: () -> Unit, ) { BasicButton( - text = R.string.delete_subject, + text = text, modifier = Modifier.basicButton(), onClick = onClick, colors = ButtonDefaults.buttonColors( @@ -107,7 +108,7 @@ fun DeleteButton( @Preview @Composable fun DeleteButtonPreview() { - DeleteButton {} + DeleteButton(text = R.string.delete_subject) {} } @Composable diff --git a/app/src/main/java/be/ugent/sel/studeez/data/SelectedSubject.kt b/app/src/main/java/be/ugent/sel/studeez/data/SelectedSubject.kt index 6e2da9f..fbc7e48 100644 --- a/app/src/main/java/be/ugent/sel/studeez/data/SelectedSubject.kt +++ b/app/src/main/java/be/ugent/sel/studeez/data/SelectedSubject.kt @@ -5,7 +5,7 @@ import javax.inject.Inject import javax.inject.Singleton /** - * Used to communicate the selected subject from the subject overview to the task overview of that subject. + * Used to communicate the selected subject from the subject overview other screens. * Because this is a singleton-class the view-models of both screens observe the same data. */ @Singleton @@ -15,4 +15,6 @@ class SelectedSubject @Inject constructor() { fun set(subject: Subject) { this.subject = subject } + + fun isSet() = this::subject.isInitialized } \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/data/SelectedTask.kt b/app/src/main/java/be/ugent/sel/studeez/data/SelectedTask.kt new file mode 100644 index 0000000..9c3f042 --- /dev/null +++ b/app/src/main/java/be/ugent/sel/studeez/data/SelectedTask.kt @@ -0,0 +1,21 @@ +package be.ugent.sel.studeez.data + +import be.ugent.sel.studeez.data.local.models.task.Task +import javax.inject.Inject +import javax.inject.Singleton + +/** + * Used to communicate the selected task from the task overview other screens. + * Because this is a singleton-class the view-models of both screens observe the same data. + */ +@Singleton +class SelectedTask @Inject constructor() { + private lateinit var task: Task + + operator fun invoke() = task + fun set(task: Task) { + this.task = task + } + + fun isSet() = this::task.isInitialized +} \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/domain/TaskDAO.kt b/app/src/main/java/be/ugent/sel/studeez/domain/TaskDAO.kt index 38c639a..0f629ea 100644 --- a/app/src/main/java/be/ugent/sel/studeez/domain/TaskDAO.kt +++ b/app/src/main/java/be/ugent/sel/studeez/domain/TaskDAO.kt @@ -10,6 +10,8 @@ interface TaskDAO { fun saveTask(newTask: Task) + fun updateTask(newTask: Task) + fun deleteTask(oldTask: Task) fun toggleTaskCompleted(task: Task, completed: Boolean) diff --git a/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FireBaseTaskDAO.kt b/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FireBaseTaskDAO.kt index 09e8cdf..45d32f8 100644 --- a/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FireBaseTaskDAO.kt +++ b/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FireBaseTaskDAO.kt @@ -22,7 +22,11 @@ class FireBaseTaskDAO @Inject constructor( } override fun saveTask(newTask: Task) { - TODO("Not yet implemented") + selectedSubjectTasksCollection(newTask.subjectId).add(newTask) + } + + override fun updateTask(newTask: Task) { + selectedSubjectTasksCollection(newTask.id).document(newTask.id).set(newTask) } override fun deleteTask(oldTask: Task) { diff --git a/app/src/main/java/be/ugent/sel/studeez/navigation/StudeezDestinations.kt b/app/src/main/java/be/ugent/sel/studeez/navigation/StudeezDestinations.kt index f56b872..5f4053a 100644 --- a/app/src/main/java/be/ugent/sel/studeez/navigation/StudeezDestinations.kt +++ b/app/src/main/java/be/ugent/sel/studeez/navigation/StudeezDestinations.kt @@ -15,6 +15,8 @@ object StudeezDestinations { const val ADD_SUBJECT_FORM = "add_subject" const val EDIT_SUBJECT_FORM = "edit_subject" const val TASKS_SCREEN = "tasks" + const val ADD_TASK_FORM = "add_task" + const val EDIT_TASK_FORM = "edit_task" // const val SESSIONS_SCREEN = "sessions" const val PROFILE_SCREEN = "profile" diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/tasks/TaskScreen.kt b/app/src/main/java/be/ugent/sel/studeez/screens/tasks/TaskScreen.kt index bd41cff..e3ceca7 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/tasks/TaskScreen.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/tasks/TaskScreen.kt @@ -4,7 +4,6 @@ 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.icons.Icons @@ -12,15 +11,12 @@ import androidx.compose.material.icons.filled.Edit 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.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.composable.tasks.TaskEntry -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.resources @@ -38,7 +34,7 @@ data class TaskActions( fun getTaskActions(viewModel: TaskViewModel, open: (String) -> Unit): TaskActions { return TaskActions( - addTask = viewModel::addTask, + addTask = { viewModel.addTask(open) }, getTasks = viewModel::getTasks, getSubject = viewModel::getSelectedSubject, deleteTask = viewModel::deleteTask, 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 26b8c17..138d32c 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 @@ -19,8 +19,8 @@ class TaskViewModel @Inject constructor( private val selectedSubject: SelectedSubject, logService: LogService, ) : StudeezViewModel(logService) { - fun addTask() { - + fun addTask(open: (String) -> Unit) { + open(StudeezDestinations.ADD_TASK_FORM) } fun getTasks(): Flow> { diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/tasks/forms/SubjectFormScreen.kt b/app/src/main/java/be/ugent/sel/studeez/screens/tasks/forms/SubjectFormScreen.kt index 38ef6f5..f18dc2c 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/tasks/forms/SubjectFormScreen.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/tasks/forms/SubjectFormScreen.kt @@ -21,7 +21,7 @@ import be.ugent.sel.studeez.resources @Composable fun SubjectAddRoute( goBack: () -> Unit, - open: (String) -> Unit, + openAndPopUp: (String, String) -> Unit, viewModel: SubjectFormViewModel, ) { val uiState by viewModel.uiState @@ -29,7 +29,7 @@ fun SubjectAddRoute( title = R.string.new_subject, goBack = goBack, uiState = uiState, - onConfirm = { viewModel.onCreate(open) }, + onConfirm = { viewModel.onCreate(openAndPopUp) }, onNameChange = viewModel::onNameChange, onColorChange = {}, ) @@ -38,7 +38,7 @@ fun SubjectAddRoute( @Composable fun SubjectEditRoute( goBack: () -> Unit, - open: (String) -> Unit, + openAndPopUp: (String, String) -> Unit, viewModel: SubjectFormViewModel, ) { val uiState by viewModel.uiState @@ -46,11 +46,13 @@ fun SubjectEditRoute( title = R.string.edit_subject, goBack = goBack, uiState = uiState, - onConfirm = { viewModel.onEdit(open) }, + onConfirm = { viewModel.onEdit(openAndPopUp) }, onNameChange = viewModel::onNameChange, onColorChange = {}, ) { - DeleteButton(onClick = { viewModel.onDelete(open) }) + DeleteButton(text = R.string.delete_subject) { + viewModel.onDelete(openAndPopUp) + } } } @@ -112,6 +114,6 @@ fun EditSubjectFormPreview() { onNameChange = {}, onColorChange = {}, ) { - DeleteButton {} + DeleteButton(text = R.string.delete_subject) {} } } \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/tasks/forms/SubjectFormViewModel.kt b/app/src/main/java/be/ugent/sel/studeez/screens/tasks/forms/SubjectFormViewModel.kt index ec246f4..68ebd3e 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/tasks/forms/SubjectFormViewModel.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/tasks/forms/SubjectFormViewModel.kt @@ -16,7 +16,13 @@ class SubjectFormViewModel @Inject constructor( private val selectedSubject: SelectedSubject, logService: LogService, ) : StudeezViewModel(logService) { - var uiState = mutableStateOf(SubjectFormUiState()) + var uiState = mutableStateOf( + if (selectedSubject.isSet()) SubjectFormUiState( + name = selectedSubject().name, + color = selectedSubject().argb_color + ) + else SubjectFormUiState() + ) private set private val name: String @@ -33,12 +39,12 @@ class SubjectFormViewModel @Inject constructor( uiState.value = uiState.value.copy(color = newValue) } - fun onDelete(open: (String) -> Unit) { + fun onDelete(openAndPopUp: (String, String) -> Unit) { subjectDAO.deleteSubject(selectedSubject()) - open(StudeezDestinations.SUBJECT_SCREEN) + openAndPopUp(StudeezDestinations.SUBJECT_SCREEN, StudeezDestinations.EDIT_SUBJECT_FORM) } - fun onCreate(open: (String) -> Unit) { + fun onCreate(openAndPopUp: (String, String) -> Unit) { val newSubject = Subject( name = name, argb_color = color, @@ -46,20 +52,18 @@ class SubjectFormViewModel @Inject constructor( subjectDAO.saveSubject( newSubject ) - selectedSubject.set(newSubject) // TODO open newly created subject +// selectedSubject.set(newSubject) // open(StudeezDestinations.TASKS_SCREEN) - open(StudeezDestinations.SUBJECT_SCREEN) + openAndPopUp(StudeezDestinations.SUBJECT_SCREEN, StudeezDestinations.ADD_SUBJECT_FORM) } - fun onEdit(open: (String) -> Unit) { + fun onEdit(openAndPopUp: (String, String) -> Unit) { val newSubject = selectedSubject().copy( name = name, argb_color = color, ) - subjectDAO.updateSubject( - newSubject - ) - open(StudeezDestinations.TASKS_SCREEN) + subjectDAO.updateSubject(newSubject) + openAndPopUp(StudeezDestinations.TASKS_SCREEN, StudeezDestinations.EDIT_SUBJECT_FORM) } } \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/tasks/forms/TaskFormScreen.kt b/app/src/main/java/be/ugent/sel/studeez/screens/tasks/forms/TaskFormScreen.kt new file mode 100644 index 0000000..1d98d3d --- /dev/null +++ b/app/src/main/java/be/ugent/sel/studeez/screens/tasks/forms/TaskFormScreen.kt @@ -0,0 +1,113 @@ +package be.ugent.sel.studeez.screens.tasks.forms + +import androidx.annotation.StringRes +import androidx.compose.foundation.layout.Column +import androidx.compose.material.OutlinedTextField +import androidx.compose.material.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.tooling.preview.Preview +import be.ugent.sel.studeez.R +import be.ugent.sel.studeez.common.composable.BasicButton +import be.ugent.sel.studeez.common.composable.DeleteButton +import be.ugent.sel.studeez.common.composable.SecondaryScreenTemplate +import be.ugent.sel.studeez.common.ext.basicButton +import be.ugent.sel.studeez.common.ext.fieldModifier +import be.ugent.sel.studeez.resources + +@Composable +fun TaskAddRoute( + goBack: () -> Unit, + openAndPopUp: (String, String) -> Unit, + viewModel: TaskFormViewModel, +) { + val uiState by viewModel.uiState + TaskForm( + title = R.string.new_task, + goBack = goBack, + uiState = uiState, + onConfirm = { viewModel.onCreate(openAndPopUp) }, + onNameChange = viewModel::onNameChange + ) +} + +@Composable +fun TaskEditRoute( + goBack: () -> Unit, + openAndPopUp: (String, String) -> Unit, + viewModel: TaskFormViewModel, +) { + val uiState by viewModel.uiState + TaskForm( + title = R.string.edit_task, + goBack = goBack, + uiState = uiState, + onConfirm = { viewModel.onEdit(openAndPopUp) }, + onNameChange = viewModel::onNameChange + ) { + DeleteButton(text = R.string.delete_task) { + viewModel.onDelete(openAndPopUp) + } + } +} + +@Composable +fun TaskForm( + @StringRes title: Int, + goBack: () -> Unit, + uiState: TaskFormUiState, + onConfirm: () -> Unit, + onNameChange: (String) -> Unit, + extraButton: @Composable () -> Unit = {} +) { + SecondaryScreenTemplate( + title = resources().getString(title), + popUp = goBack, + ) { + Column { + OutlinedTextField( + singleLine = true, + value = uiState.name, + onValueChange = onNameChange, + placeholder = { Text(stringResource(id = R.string.name)) }, + modifier = Modifier.fieldModifier(), + ) + BasicButton( + text = R.string.confirm, + modifier = Modifier.basicButton(), + onClick = onConfirm, + ) + extraButton() + } + } +} + +@Preview +@Composable +fun AddTaskFormPreview() { + TaskForm( + title = R.string.new_task, + goBack = {}, + uiState = TaskFormUiState(), + onConfirm = {}, + onNameChange = {}, + ) +} + +@Preview +@Composable +fun EditTaskFormPreview() { + TaskForm( + title = R.string.edit_task, + goBack = {}, + uiState = TaskFormUiState( + name = "Test Task", + ), + onConfirm = {}, + onNameChange = {}, + ) { + DeleteButton(text = R.string.delete_task) {} + } +} \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/tasks/forms/TaskFormUiState.kt b/app/src/main/java/be/ugent/sel/studeez/screens/tasks/forms/TaskFormUiState.kt new file mode 100644 index 0000000..d967d59 --- /dev/null +++ b/app/src/main/java/be/ugent/sel/studeez/screens/tasks/forms/TaskFormUiState.kt @@ -0,0 +1,5 @@ +package be.ugent.sel.studeez.screens.tasks.forms + +data class TaskFormUiState( + val name: String = "", +) \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/tasks/forms/TaskFormViewModel.kt b/app/src/main/java/be/ugent/sel/studeez/screens/tasks/forms/TaskFormViewModel.kt new file mode 100644 index 0000000..03ad32b --- /dev/null +++ b/app/src/main/java/be/ugent/sel/studeez/screens/tasks/forms/TaskFormViewModel.kt @@ -0,0 +1,49 @@ +package be.ugent.sel.studeez.screens.tasks.forms + +import androidx.compose.runtime.mutableStateOf +import be.ugent.sel.studeez.data.SelectedSubject +import be.ugent.sel.studeez.data.SelectedTask +import be.ugent.sel.studeez.data.local.models.task.Task +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 javax.inject.Inject + +@HiltViewModel +class TaskFormViewModel @Inject constructor( + private val taskDAO: TaskDAO, + private val selectedSubject: SelectedSubject, + private val selectedTask: SelectedTask, + logService: LogService, +) : StudeezViewModel(logService) { + var uiState = mutableStateOf( + if (selectedTask.isSet()) TaskFormUiState(selectedTask().name) else TaskFormUiState() + ) + private set + + private val name: String + get() = uiState.value.name + + fun onNameChange(newValue: String) { + uiState.value = uiState.value.copy(name = newValue) + } + + fun onDelete(openAndPopUp: (String, String) -> Unit) { + taskDAO.deleteTask(selectedTask()) + openAndPopUp(StudeezDestinations.TASKS_SCREEN, StudeezDestinations.EDIT_TASK_FORM) + } + + fun onCreate(openAndPopUp: (String, String) -> Unit) { + val newTask = Task(name = name, subjectId = selectedSubject().id) + taskDAO.saveTask(newTask) + openAndPopUp(StudeezDestinations.TASKS_SCREEN, StudeezDestinations.ADD_TASK_FORM) + } + + fun onEdit(openAndPopUp: (String, String) -> Unit) { + val newTask = Task(name = name) + taskDAO.updateTask(newTask) + openAndPopUp(StudeezDestinations.TASKS_SCREEN, StudeezDestinations.EDIT_TASK_FORM) + } +} \ No newline at end of file From b0fb97c29c7e164f58e4a4905a47c40368807550 Mon Sep 17 00:00:00 2001 From: brreynie Date: Thu, 4 May 2023 12:02:59 +0200 Subject: [PATCH 17/22] Update app/src/main/java/be/ugent/sel/studeez/screens/tasks/forms/SubjectFormUiState.kt Co-authored-by: Tibo De Peuter --- .../ugent/sel/studeez/screens/tasks/forms/SubjectFormUiState.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/tasks/forms/SubjectFormUiState.kt b/app/src/main/java/be/ugent/sel/studeez/screens/tasks/forms/SubjectFormUiState.kt index 6e8f9cf..5418b74 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/tasks/forms/SubjectFormUiState.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/tasks/forms/SubjectFormUiState.kt @@ -2,5 +2,5 @@ package be.ugent.sel.studeez.screens.tasks.forms data class SubjectFormUiState( val name: String = "", - val color: Long = 0xFFF44336, + val color: Long = 0xFFFFD200, ) \ No newline at end of file From 1f1583dcd1989619a5c1ad764c2ae26865d532ad Mon Sep 17 00:00:00 2001 From: brreynie Date: Thu, 4 May 2023 12:12:00 +0200 Subject: [PATCH 18/22] fix overflow preview for subject entry --- .../common/composable/tasks/SubjectEntry.kt | 15 +++++++++++++-- app/src/main/res/values/strings.xml | 1 + 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/be/ugent/sel/studeez/common/composable/tasks/SubjectEntry.kt b/app/src/main/java/be/ugent/sel/studeez/common/composable/tasks/SubjectEntry.kt index 5c19c80..804126d 100644 --- a/app/src/main/java/be/ugent/sel/studeez/common/composable/tasks/SubjectEntry.kt +++ b/app/src/main/java/be/ugent/sel/studeez/common/composable/tasks/SubjectEntry.kt @@ -101,8 +101,19 @@ fun SubjectEntryPreview() { SubjectEntry( subject = Subject( name = "Test Subject", -// name = "Testttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt", - argb_color = 0xFFF44336, + argb_color = 0xFFFFD200, + time = 60 + ), + ) {} +} + +@Preview +@Composable +fun OverflowSubjectEntryPreview() { + SubjectEntry( + subject = Subject( + name = "Testttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt", + argb_color = 0xFFFFD200, time = 60 ), ) {} diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 9e0efb9..a069c87 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -42,6 +42,7 @@ Tasks + My Subjects New Subject New Task Edit Subject From e1b60b342d5410b5447efbe34689d05ecb518091 Mon Sep 17 00:00:00 2001 From: brreynie Date: Thu, 4 May 2023 12:21:04 +0200 Subject: [PATCH 19/22] fix stealthbutton and add button to not use hardcoded gray --- .../sel/studeez/common/composable/ButtonComposable.kt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/be/ugent/sel/studeez/common/composable/ButtonComposable.kt b/app/src/main/java/be/ugent/sel/studeez/common/composable/ButtonComposable.kt index a98b24b..7c03188 100644 --- a/app/src/main/java/be/ugent/sel/studeez/common/composable/ButtonComposable.kt +++ b/app/src/main/java/be/ugent/sel/studeez/common/composable/ButtonComposable.kt @@ -74,9 +74,9 @@ fun StealthButton( modifier = modifier, colors = ButtonDefaults.buttonColors( backgroundColor = MaterialTheme.colors.surface, - contentColor = MaterialTheme.colors.onSurface + contentColor = MaterialTheme.colors.onSurface.copy(alpha = 0.4f) ), - border = BorderStroke(1.dp, MaterialTheme.colors.onSurface) + border = BorderStroke(3.dp, MaterialTheme.colors.onSurface.copy(alpha = 0.4f)) ) } @@ -147,10 +147,10 @@ fun NewTaskSubjectButton( .padding(10.dp, 5.dp), colors = ButtonDefaults.buttonColors( backgroundColor = Color.Transparent, - contentColor = Color.Gray, + contentColor = MaterialTheme.colors.onSurface.copy(alpha = 0.4f), ), shape = RoundedCornerShape(2.dp), - border = BorderStroke(1.dp, Color.Gray), + border = BorderStroke(1.dp, MaterialTheme.colors.onSurface.copy(alpha = 0.4f)), elevation = null, ) { Row( From 9faea560561c0c58bd4311f7e1837dd43bf2c824 Mon Sep 17 00:00:00 2001 From: brreynie Date: Thu, 4 May 2023 12:33:51 +0200 Subject: [PATCH 20/22] localisation improvements --- .../common/composable/ButtonComposable.kt | 14 +++++++------- .../common/composable/tasks/SubjectEntry.kt | 8 +++++--- .../sel/studeez/screens/tasks/SubjectScreen.kt | 8 ++++---- .../sel/studeez/screens/tasks/TaskScreen.kt | 8 ++++---- .../screens/tasks/forms/SubjectFormScreen.kt | 18 +++++++++--------- .../screens/tasks/forms/TaskFormScreen.kt | 18 +++++++++--------- 6 files changed, 38 insertions(+), 36 deletions(-) diff --git a/app/src/main/java/be/ugent/sel/studeez/common/composable/ButtonComposable.kt b/app/src/main/java/be/ugent/sel/studeez/common/composable/ButtonComposable.kt index 7c03188..6c4169e 100644 --- a/app/src/main/java/be/ugent/sel/studeez/common/composable/ButtonComposable.kt +++ b/app/src/main/java/be/ugent/sel/studeez/common/composable/ButtonComposable.kt @@ -25,9 +25,9 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp -import be.ugent.sel.studeez.R import be.ugent.sel.studeez.common.ext.basicButton import be.ugent.sel.studeez.common.ext.card +import be.ugent.sel.studeez.R.string as AppText @Composable fun BasicTextButton(@StringRes text: Int, modifier: Modifier, action: () -> Unit) { @@ -59,7 +59,7 @@ fun BasicButton( @Preview @Composable fun BasicButtonPreview() { - BasicButton(text = R.string.add_timer, modifier = Modifier.basicButton()) {} + BasicButton(text = AppText.add_timer, modifier = Modifier.basicButton()) {} } @Composable @@ -83,7 +83,7 @@ fun StealthButton( @Preview @Composable fun StealthButtonCardPreview() { - StealthButton(text = R.string.edit) { + StealthButton(text = AppText.edit) { } } @@ -99,8 +99,8 @@ fun DeleteButton( modifier = Modifier.basicButton(), onClick = onClick, colors = ButtonDefaults.buttonColors( - backgroundColor = Color.Red, - contentColor = Color.White, + backgroundColor = MaterialTheme.colors.error, + contentColor = MaterialTheme.colors.onSurface, ), ) } @@ -108,7 +108,7 @@ fun DeleteButton( @Preview @Composable fun DeleteButtonPreview() { - DeleteButton(text = R.string.delete_subject) {} + DeleteButton(text = AppText.delete_subject) {} } @Composable @@ -167,5 +167,5 @@ fun NewTaskSubjectButton( @Preview @Composable fun NewTaskButtonPreview() { - NewTaskSubjectButton(onClick = {}, text = R.string.new_task) + NewTaskSubjectButton(onClick = {}, text = AppText.new_task) } \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/common/composable/tasks/SubjectEntry.kt b/app/src/main/java/be/ugent/sel/studeez/common/composable/tasks/SubjectEntry.kt index 804126d..a59100a 100644 --- a/app/src/main/java/be/ugent/sel/studeez/common/composable/tasks/SubjectEntry.kt +++ b/app/src/main/java/be/ugent/sel/studeez/common/composable/tasks/SubjectEntry.kt @@ -19,11 +19,12 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Color +import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp -import be.ugent.sel.studeez.R +import be.ugent.sel.studeez.R.string as AppText import be.ugent.sel.studeez.common.composable.StealthButton import be.ugent.sel.studeez.data.local.models.task.Subject import be.ugent.sel.studeez.data.local.models.timer_functional.HoursMinutesSeconds @@ -76,7 +77,8 @@ fun SubjectEntry( horizontalArrangement = Arrangement.spacedBy(3.dp) ) { Icon( - imageVector = Icons.Default.List, contentDescription = "tasks" + imageVector = Icons.Default.List, + contentDescription = stringResource(id = AppText.tasks) ) Text(text = "0/0") // TODO } @@ -84,7 +86,7 @@ fun SubjectEntry( } } StealthButton( - text = R.string.view_tasks, + text = AppText.view_tasks, modifier = Modifier .padding(start = 10.dp, end = 5.dp) .weight(1f) 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 fef7e1d..1813460 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 @@ -7,18 +7,18 @@ 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.res.stringResource 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.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 be.ugent.sel.studeez.resources import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.flowOf +import be.ugent.sel.studeez.R.string as AppText @Composable fun SubjectRoute( @@ -45,7 +45,7 @@ fun SubjectScreen( onViewSubject: (Subject) -> Unit, ) { PrimaryScreenTemplate( - title = resources().getString(R.string.tasks), + title = stringResource(AppText.my_subjects), drawerActions = drawerActions, navigationBarActions = navigationBarActions, barAction = {}, @@ -62,7 +62,7 @@ fun SubjectScreen( ) } } - NewTaskSubjectButton(onClick = addSubject, R.string.new_subject) + NewTaskSubjectButton(onClick = addSubject, AppText.new_subject) } } } diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/tasks/TaskScreen.kt b/app/src/main/java/be/ugent/sel/studeez/screens/tasks/TaskScreen.kt index e3ceca7..67f0e93 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/tasks/TaskScreen.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/tasks/TaskScreen.kt @@ -11,17 +11,17 @@ import androidx.compose.material.icons.filled.Edit import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource 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.SecondaryScreenTemplate import be.ugent.sel.studeez.common.composable.tasks.TaskEntry 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.resources import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.flowOf +import be.ugent.sel.studeez.R.string as AppText data class TaskActions( val addTask: () -> Unit, @@ -78,7 +78,7 @@ fun TaskScreen( ) } } - NewTaskSubjectButton(onClick = taskActions.addTask, R.string.new_task) + NewTaskSubjectButton(onClick = taskActions.addTask, AppText.new_task) } } } @@ -90,7 +90,7 @@ fun EditAction( IconButton(onClick = onClick) { Icon( imageVector = Icons.Default.Edit, - contentDescription = resources().getString(R.string.edit_task) + contentDescription = stringResource(AppText.edit_task) ) } diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/tasks/forms/SubjectFormScreen.kt b/app/src/main/java/be/ugent/sel/studeez/screens/tasks/forms/SubjectFormScreen.kt index f18dc2c..74bc7d2 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/tasks/forms/SubjectFormScreen.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/tasks/forms/SubjectFormScreen.kt @@ -10,13 +10,13 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview -import be.ugent.sel.studeez.R import be.ugent.sel.studeez.common.composable.BasicButton import be.ugent.sel.studeez.common.composable.DeleteButton import be.ugent.sel.studeez.common.composable.SecondaryScreenTemplate import be.ugent.sel.studeez.common.ext.basicButton import be.ugent.sel.studeez.common.ext.fieldModifier import be.ugent.sel.studeez.resources +import be.ugent.sel.studeez.R.string as AppText @Composable fun SubjectAddRoute( @@ -26,7 +26,7 @@ fun SubjectAddRoute( ) { val uiState by viewModel.uiState SubjectForm( - title = R.string.new_subject, + title = AppText.new_subject, goBack = goBack, uiState = uiState, onConfirm = { viewModel.onCreate(openAndPopUp) }, @@ -43,14 +43,14 @@ fun SubjectEditRoute( ) { val uiState by viewModel.uiState SubjectForm( - title = R.string.edit_subject, + title = AppText.edit_subject, goBack = goBack, uiState = uiState, onConfirm = { viewModel.onEdit(openAndPopUp) }, onNameChange = viewModel::onNameChange, onColorChange = {}, ) { - DeleteButton(text = R.string.delete_subject) { + DeleteButton(text = AppText.delete_subject) { viewModel.onDelete(openAndPopUp) } } @@ -75,11 +75,11 @@ fun SubjectForm( singleLine = true, value = uiState.name, onValueChange = onNameChange, - placeholder = { Text(stringResource(id = R.string.name)) }, + placeholder = { Text(stringResource(id = AppText.name)) }, modifier = Modifier.fieldModifier(), ) BasicButton( - text = R.string.confirm, + text = AppText.confirm, modifier = Modifier.basicButton(), onClick = onConfirm, ) @@ -92,7 +92,7 @@ fun SubjectForm( @Composable fun AddSubjectFormPreview() { SubjectForm( - title = R.string.new_subject, + title = AppText.new_subject, goBack = {}, uiState = SubjectFormUiState(), onConfirm = {}, @@ -105,7 +105,7 @@ fun AddSubjectFormPreview() { @Composable fun EditSubjectFormPreview() { SubjectForm( - title = R.string.edit_subject, + title = AppText.edit_subject, goBack = {}, uiState = SubjectFormUiState( name = "Test Subject", @@ -114,6 +114,6 @@ fun EditSubjectFormPreview() { onNameChange = {}, onColorChange = {}, ) { - DeleteButton(text = R.string.delete_subject) {} + DeleteButton(text = AppText.delete_subject) {} } } \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/tasks/forms/TaskFormScreen.kt b/app/src/main/java/be/ugent/sel/studeez/screens/tasks/forms/TaskFormScreen.kt index 1d98d3d..62b6c6c 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/tasks/forms/TaskFormScreen.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/tasks/forms/TaskFormScreen.kt @@ -9,13 +9,13 @@ import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview -import be.ugent.sel.studeez.R import be.ugent.sel.studeez.common.composable.BasicButton import be.ugent.sel.studeez.common.composable.DeleteButton import be.ugent.sel.studeez.common.composable.SecondaryScreenTemplate import be.ugent.sel.studeez.common.ext.basicButton import be.ugent.sel.studeez.common.ext.fieldModifier import be.ugent.sel.studeez.resources +import be.ugent.sel.studeez.R.string as AppText @Composable fun TaskAddRoute( @@ -25,7 +25,7 @@ fun TaskAddRoute( ) { val uiState by viewModel.uiState TaskForm( - title = R.string.new_task, + title = AppText.new_task, goBack = goBack, uiState = uiState, onConfirm = { viewModel.onCreate(openAndPopUp) }, @@ -41,13 +41,13 @@ fun TaskEditRoute( ) { val uiState by viewModel.uiState TaskForm( - title = R.string.edit_task, + title = AppText.edit_task, goBack = goBack, uiState = uiState, onConfirm = { viewModel.onEdit(openAndPopUp) }, onNameChange = viewModel::onNameChange ) { - DeleteButton(text = R.string.delete_task) { + DeleteButton(text = AppText.delete_task) { viewModel.onDelete(openAndPopUp) } } @@ -71,11 +71,11 @@ fun TaskForm( singleLine = true, value = uiState.name, onValueChange = onNameChange, - placeholder = { Text(stringResource(id = R.string.name)) }, + placeholder = { Text(stringResource(id = AppText.name)) }, modifier = Modifier.fieldModifier(), ) BasicButton( - text = R.string.confirm, + text = AppText.confirm, modifier = Modifier.basicButton(), onClick = onConfirm, ) @@ -88,7 +88,7 @@ fun TaskForm( @Composable fun AddTaskFormPreview() { TaskForm( - title = R.string.new_task, + title = AppText.new_task, goBack = {}, uiState = TaskFormUiState(), onConfirm = {}, @@ -100,7 +100,7 @@ fun AddTaskFormPreview() { @Composable fun EditTaskFormPreview() { TaskForm( - title = R.string.edit_task, + title = AppText.edit_task, goBack = {}, uiState = TaskFormUiState( name = "Test Task", @@ -108,6 +108,6 @@ fun EditTaskFormPreview() { onConfirm = {}, onNameChange = {}, ) { - DeleteButton(text = R.string.delete_task) {} + DeleteButton(text = AppText.delete_task) {} } } \ No newline at end of file From fec9565f6969d775e7246633d78bd57ccfc14b78 Mon Sep 17 00:00:00 2001 From: brreynie Date: Thu, 4 May 2023 12:36:28 +0200 Subject: [PATCH 21/22] fix hardcoded fieldname in taskDAO --- .../be/ugent/sel/studeez/data/local/models/task/Task.kt | 8 ++++++++ .../sel/studeez/domain/implementation/FireBaseTaskDAO.kt | 3 ++- 2 files changed, 10 insertions(+), 1 deletion(-) 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 05a5020..f2618db 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 @@ -9,3 +9,11 @@ data class Task( val time: Int = 0, val subjectId: String = "", ) + +object TaskDocument { + const val id = "id" + const val name = "name" + const val completed = "completed" + const val time = "time" + const val subjectId = "subjectId" +} diff --git a/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FireBaseTaskDAO.kt b/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FireBaseTaskDAO.kt index 45d32f8..b8855e6 100644 --- a/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FireBaseTaskDAO.kt +++ b/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FireBaseTaskDAO.kt @@ -2,6 +2,7 @@ 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.TaskDocument import be.ugent.sel.studeez.domain.AccountDAO import be.ugent.sel.studeez.domain.TaskDAO import com.google.firebase.firestore.CollectionReference @@ -36,7 +37,7 @@ class FireBaseTaskDAO @Inject constructor( override fun toggleTaskCompleted(task: Task, completed: Boolean) { selectedSubjectTasksCollection(task.subjectId) .document(task.id) - .update("completed", completed) + .update(TaskDocument.completed, completed) } private fun selectedSubjectTasksCollection(subjectId: String): CollectionReference = From b6e3c8d5be869200d62e0da4b8ce57136e7fe16f Mon Sep 17 00:00:00 2001 From: brreynie Date: Thu, 4 May 2023 21:38:16 +0200 Subject: [PATCH 22/22] small string fix --- .idea/misc.xml | 3 ++- .../ugent/sel/studeez/common/composable/tasks/SubjectEntry.kt | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.idea/misc.xml b/.idea/misc.xml index aa62d28..0ad17cb 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,6 +1,7 @@ + - + diff --git a/app/src/main/java/be/ugent/sel/studeez/common/composable/tasks/SubjectEntry.kt b/app/src/main/java/be/ugent/sel/studeez/common/composable/tasks/SubjectEntry.kt index a59100a..8655ba3 100644 --- a/app/src/main/java/be/ugent/sel/studeez/common/composable/tasks/SubjectEntry.kt +++ b/app/src/main/java/be/ugent/sel/studeez/common/composable/tasks/SubjectEntry.kt @@ -70,7 +70,7 @@ fun SubjectEntry( verticalAlignment = Alignment.CenterVertically, ) { Text( - text = "${HoursMinutesSeconds(subject.time)}", + text = HoursMinutesSeconds(subject.time).toString(), ) Row( verticalAlignment = Alignment.CenterVertically,