From 5f8b7d7a7b653ed2d56d842327261b001d8d7f1d Mon Sep 17 00:00:00 2001 From: brreynie Date: Tue, 9 May 2023 15:30:37 +0200 Subject: [PATCH 01/20] show #tasks and #completedTasks in subject entry --- .../common/composable/tasks/SubjectEntry.kt | 18 +++++++--------- .../studeez/data/local/models/task/Subject.kt | 7 ++++++- .../studeez/data/local/models/task/Task.kt | 2 ++ .../be/ugent/sel/studeez/domain/TaskDAO.kt | 4 ++++ .../implementation/FireBaseSubjectDAO.kt | 10 ++++++++- .../domain/implementation/FireBaseTaskDAO.kt | 21 ++++++++++++++++++- .../domain/implementation/FirebaseFeedDAO.kt | 14 +++++++------ .../studeez/screens/tasks/SubjectScreen.kt | 2 +- 8 files changed, 57 insertions(+), 21 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 8655ba3..a6b89bf 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 @@ -1,13 +1,7 @@ package be.ugent.sel.studeez.common.composable.tasks 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.* import androidx.compose.foundation.shape.CircleShape import androidx.compose.material.Card import androidx.compose.material.Icon @@ -24,10 +18,10 @@ 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.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 +import be.ugent.sel.studeez.R.string as AppText @Composable fun SubjectEntry( @@ -80,7 +74,7 @@ fun SubjectEntry( imageVector = Icons.Default.List, contentDescription = stringResource(id = AppText.tasks) ) - Text(text = "0/0") // TODO + Text(text = "${subject.taskCompletedCount}/${subject.taskCount}") // TODO } } } @@ -104,7 +98,9 @@ fun SubjectEntryPreview() { subject = Subject( name = "Test Subject", argb_color = 0xFFFFD200, - time = 60 + time = 60, + taskCount = 5, + taskCompletedCount = 2, ), ) {} } @@ -116,7 +112,7 @@ fun OverflowSubjectEntryPreview() { subject = Subject( name = "Testttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt", argb_color = 0xFFFFD200, - time = 60 + 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 e84c2bb..622ef3c 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 @@ -1,10 +1,15 @@ package be.ugent.sel.studeez.data.local.models.task import com.google.firebase.firestore.DocumentId +import com.google.firebase.firestore.Exclude data class Subject( @DocumentId val id: String = "", val name: String = "", val time: Int = 0, val argb_color: Long = 0, -) \ No newline at end of file + @get:Exclude @set:Exclude + var taskCount: Int = 0, + @get:Exclude @set:Exclude + var taskCompletedCount: Int = 0, +) 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 f2618db..91242b0 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 @@ -8,6 +8,7 @@ data class Task( val completed: Boolean = false, val time: Int = 0, val subjectId: String = "", + val archived: Boolean = false, ) object TaskDocument { @@ -16,4 +17,5 @@ object TaskDocument { const val completed = "completed" const val time = "time" const val subjectId = "subjectId" + const val archived = "archived" } 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 988a10d..4c7ee44 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 @@ -17,4 +17,8 @@ interface TaskDAO { fun toggleTaskCompleted(task: Task, completed: Boolean) suspend fun getTask(subjectId: String, taskId: String): Task + + suspend fun getTaskCount(subject: Subject): Int + + suspend fun getCompletedTaskCount(subject: Subject): Int } \ 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 e022863..9156771 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 @@ -1,9 +1,9 @@ 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.SubjectDAO +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 @@ -16,11 +16,19 @@ import javax.inject.Inject class FireBaseSubjectDAO @Inject constructor( private val firestore: FirebaseFirestore, private val auth: AccountDAO, + private val taskDAO: TaskDAO, ) : SubjectDAO { override fun getSubjects(): Flow> { return currentUserSubjectsCollection() .snapshots() .map { it.toObjects(Subject::class.java) } + .map { subjects -> + subjects.map { subject -> + subject.taskCount = taskDAO.getTaskCount(subject) + subject.taskCompletedCount = taskDAO.getCompletedTaskCount(subject) + subject + } + } } override suspend fun getSubject(subjectId: String): Subject? { 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 963c93b..bf32776 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 @@ -5,12 +5,12 @@ 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.AggregateSource import com.google.firebase.firestore.CollectionReference import com.google.firebase.firestore.FirebaseFirestore import com.google.firebase.firestore.ktx.snapshots import com.google.firebase.firestore.ktx.toObject import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.map import kotlinx.coroutines.tasks.await import javax.inject.Inject @@ -21,6 +21,7 @@ class FireBaseTaskDAO @Inject constructor( ) : TaskDAO { override fun getTasks(subject: Subject): Flow> { return selectedSubjectTasksCollection(subject.id) + .whereEqualTo(TaskDocument.archived, false) .snapshots() .map { it.toObjects(Task::class.java) } } @@ -29,6 +30,24 @@ class FireBaseTaskDAO @Inject constructor( return selectedSubjectTasksCollection(subjectId).document(taskId).get().await().toObject()!! } + override suspend fun getTaskCount(subject: Subject): Int { + return selectedSubjectTasksCollection(subject.id) + .count() + .get(AggregateSource.SERVER) + .await() + .count.toInt() + } + + override suspend fun getCompletedTaskCount(subject: Subject): Int { + return selectedSubjectTasksCollection(subject.id) + .whereEqualTo(TaskDocument.completed, true) + .whereEqualTo(TaskDocument.archived, false) + .count() + .get(AggregateSource.SERVER) + .await() + .count.toInt() + } + override fun saveTask(newTask: Task) { selectedSubjectTasksCollection(newTask.subjectId).add(newTask) } diff --git a/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FirebaseFeedDAO.kt b/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FirebaseFeedDAO.kt index c116fbf..fa579bb 100644 --- a/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FirebaseFeedDAO.kt +++ b/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FirebaseFeedDAO.kt @@ -7,30 +7,32 @@ 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.FeedDAO import be.ugent.sel.studeez.domain.SessionDAO +import be.ugent.sel.studeez.domain.SubjectDAO import be.ugent.sel.studeez.domain.TaskDAO import com.google.firebase.Timestamp -import kotlinx.coroutines.flow.* +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.map import javax.inject.Inject class FirebaseFeedDAO @Inject constructor( private val sessionDAO: SessionDAO, private val taskDAO: TaskDAO, - private val subjectDAO: FireBaseSubjectDAO + private val subjectDAO: SubjectDAO ) : FeedDAO { /** * Return a map as with key the day and value a list of feedentries for that day. */ override fun getFeedEntries(): Flow>> { - return sessionDAO.getSessions().map {sessionReports -> + return sessionDAO.getSessions().map { sessionReports -> sessionReports - .map { sessionReport -> sessionToFeedEntry(sessionReport) } + .map { sessionReport -> sessionToFeedEntry(sessionReport) } .sortedByDescending { it.endTime } .groupBy { getFormattedTime(it) } .mapValues { (_, entries) -> entries - .groupBy { it.taskId } - .map { fuseFeedEntries(it.component2()) } + .groupBy { it.taskId } + .map { fuseFeedEntries(it.component2()) } } } } 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 15a3925..a3395ea 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 @@ -54,6 +54,7 @@ fun SubjectScreen( Column( modifier = Modifier.padding(top = 5.dp) ) { + NewTaskSubjectButton(onClick = addSubject, AppText.new_subject) LazyColumn { items(subjects.value) { SubjectEntry( @@ -62,7 +63,6 @@ fun SubjectScreen( ) } } - NewTaskSubjectButton(onClick = addSubject, AppText.new_subject) } } } From e35f1438547925c25067580fd1e5dc83c33dc59f Mon Sep 17 00:00:00 2001 From: brreynie Date: Tue, 9 May 2023 16:00:15 +0200 Subject: [PATCH 02/20] archive tasks --- .../common/composable/tasks/TaskEntry.kt | 18 ++++-------------- .../sel/studeez/data/local/models/task/Task.kt | 8 ++++++-- .../domain/implementation/FireBaseTaskDAO.kt | 6 ++++-- .../sel/studeez/screens/tasks/TaskScreen.kt | 11 +++++++---- .../sel/studeez/screens/tasks/TaskViewModel.kt | 6 ++++++ 5 files changed, 27 insertions(+), 22 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 bf3a7cf..35e7a44 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 @@ -1,17 +1,7 @@ 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.foundation.layout.* +import androidx.compose.material.* import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Delete import androidx.compose.runtime.Composable @@ -31,7 +21,7 @@ import be.ugent.sel.studeez.resources fun TaskEntry( task: Task, onCheckTask: (Boolean) -> Unit, - onDeleteTask: () -> Unit, + onArchiveTask: () -> Unit, onStartTask: () -> Unit ) { Card( @@ -81,7 +71,7 @@ fun TaskEntry( Box(modifier = Modifier.weight(7f)) { if (task.completed) { IconButton( - onClick = onDeleteTask, + onClick = onArchiveTask, modifier = Modifier .padding(start = 20.dp) ) { 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 91242b0..44d6d01 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 @@ -8,8 +8,12 @@ data class Task( val completed: Boolean = false, val time: Int = 0, val subjectId: String = "", - val archived: Boolean = false, -) + var archived: Boolean = false, +) { + fun archive() { + this.archived = true + } +} object TaskDocument { const val id = "id" 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 bf32776..4443b87 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 @@ -32,6 +32,7 @@ class FireBaseTaskDAO @Inject constructor( override suspend fun getTaskCount(subject: Subject): Int { return selectedSubjectTasksCollection(subject.id) + .whereEqualTo(TaskDocument.archived, false) .count() .get(AggregateSource.SERVER) .await() @@ -53,7 +54,7 @@ class FireBaseTaskDAO @Inject constructor( } override fun updateTask(newTask: Task) { - selectedSubjectTasksCollection(newTask.id).document(newTask.id).set(newTask) + selectedSubjectTasksCollection(newTask.subjectId).document(newTask.id).set(newTask) } override fun deleteTask(oldTask: Task) { @@ -63,7 +64,8 @@ class FireBaseTaskDAO @Inject constructor( override fun toggleTaskCompleted(task: Task, completed: Boolean) { selectedSubjectTasksCollection(task.subjectId) .document(task.id) - .update(TaskDocument.completed, completed) +// .update(TaskDocument.completed, completed) + .set(task.copy(completed = completed)) } private fun selectedSubjectTasksCollection(subjectId: String): 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 8a35717..1b56bc6 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 @@ -30,7 +30,8 @@ data class TaskActions( val deleteTask: (Task) -> Unit, val onCheckTask: (Task, Boolean) -> Unit, val editSubject: () -> Unit, - val startTask: (Task) -> Unit + val startTask: (Task) -> Unit, + val archiveTask: (Task) -> Unit, ) fun getTaskActions(viewModel: TaskViewModel, open: (String) -> Unit): TaskActions { @@ -41,7 +42,8 @@ fun getTaskActions(viewModel: TaskViewModel, open: (String) -> Unit): TaskAction deleteTask = viewModel::deleteTask, onCheckTask = { task, isChecked -> viewModel.toggleTaskCompleted(task, isChecked) }, editSubject = { viewModel.editSubject(open) }, - startTask = { task -> viewModel.startTask(task, open) } + startTask = { task -> viewModel.startTask(task, open) }, + archiveTask = viewModel::archiveTask ) } @@ -76,7 +78,7 @@ fun TaskScreen( TaskEntry( task = it, onCheckTask = { isChecked -> taskActions.onCheckTask(it, isChecked) }, - onDeleteTask = { taskActions.deleteTask(it) }, + onArchiveTask = { taskActions.archiveTask(it) }, onStartTask = { taskActions.startTask(it) } ) } @@ -111,7 +113,8 @@ fun TaskScreenPreview() { {}, { _, _ -> 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 37f1c91..2361399 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 android.util.Log import be.ugent.sel.studeez.data.SelectedSubject import be.ugent.sel.studeez.data.SelectedTask import be.ugent.sel.studeez.data.local.models.task.Subject @@ -42,6 +43,11 @@ class TaskViewModel @Inject constructor( taskDAO.deleteTask(task) } + fun archiveTask(task: Task) { + task.archive() + taskDAO.updateTask(task) + } + fun toggleTaskCompleted(task: Task, completed: Boolean) { taskDAO.toggleTaskCompleted(task, completed) } From 8a395fbd4e71400e22785318650bae4f064b65de Mon Sep 17 00:00:00 2001 From: brreynie Date: Tue, 9 May 2023 20:30:15 +0200 Subject: [PATCH 03/20] implement TaskDAO as a very simple fluent interface --- .../domain/implementation/FireBaseTaskDAO.kt | 24 +++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) 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 4443b87..049bb54 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 @@ -8,6 +8,7 @@ import be.ugent.sel.studeez.domain.TaskDAO import com.google.firebase.firestore.AggregateSource import com.google.firebase.firestore.CollectionReference import com.google.firebase.firestore.FirebaseFirestore +import com.google.firebase.firestore.Query import com.google.firebase.firestore.ktx.snapshots import com.google.firebase.firestore.ktx.toObject import kotlinx.coroutines.flow.Flow @@ -21,7 +22,7 @@ class FireBaseTaskDAO @Inject constructor( ) : TaskDAO { override fun getTasks(subject: Subject): Flow> { return selectedSubjectTasksCollection(subject.id) - .whereEqualTo(TaskDocument.archived, false) + .nonArchived() .snapshots() .map { it.toObjects(Task::class.java) } } @@ -32,7 +33,7 @@ class FireBaseTaskDAO @Inject constructor( override suspend fun getTaskCount(subject: Subject): Int { return selectedSubjectTasksCollection(subject.id) - .whereEqualTo(TaskDocument.archived, false) + .nonArchived() .count() .get(AggregateSource.SERVER) .await() @@ -41,8 +42,8 @@ class FireBaseTaskDAO @Inject constructor( override suspend fun getCompletedTaskCount(subject: Subject): Int { return selectedSubjectTasksCollection(subject.id) - .whereEqualTo(TaskDocument.completed, true) - .whereEqualTo(TaskDocument.archived, false) + .completed() + .nonArchived() .count() .get(AggregateSource.SERVER) .await() @@ -74,4 +75,19 @@ class FireBaseTaskDAO @Inject constructor( .collection(FireBaseCollections.SUBJECT_COLLECTION) .document(subjectId) .collection(FireBaseCollections.TASK_COLLECTION) + + // Extend CollectionReference and Query with some filters + + private fun CollectionReference.nonArchived(): Query = + this.whereEqualTo(TaskDocument.archived, false) + + private fun Query.nonArchived(): Query = + this.whereEqualTo(TaskDocument.archived, false) + + private fun CollectionReference.completed(): Query = + this.whereEqualTo(TaskDocument.completed, true) + + private fun Query.completed(): Query = + this.whereEqualTo(TaskDocument.completed, true) + } \ No newline at end of file From a60422e00480496754e31e123f652bf1b9d237fd Mon Sep 17 00:00:00 2001 From: brreynie Date: Tue, 9 May 2023 21:01:19 +0200 Subject: [PATCH 04/20] refactor DAO's --- .../be/ugent/sel/studeez/domain/SubjectDAO.kt | 5 ++ .../be/ugent/sel/studeez/domain/TaskDAO.kt | 6 --- .../implementation/FireBaseSubjectDAO.kt | 36 ++++++++++++- .../domain/implementation/FireBaseTaskDAO.kt | 51 +++++-------------- 4 files changed, 52 insertions(+), 46 deletions(-) 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 da6abbe..bad8106 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 @@ -12,5 +12,10 @@ interface SubjectDAO { fun deleteSubject(oldSubject: Subject) fun updateSubject(newSubject: Subject) + + suspend fun getTaskCount(subject: Subject): Int + suspend fun getCompletedTaskCount(subject: Subject): Int + fun getStudyTime(subject: Subject): Flow + suspend fun getSubject(subjectId: String): Subject? } \ 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 4c7ee44..8a2dd41 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 @@ -14,11 +14,5 @@ interface TaskDAO { fun deleteTask(oldTask: Task) - fun toggleTaskCompleted(task: Task, completed: Boolean) - suspend fun getTask(subjectId: String, taskId: String): Task - - suspend fun getTaskCount(subject: Subject): Int - - suspend fun getCompletedTaskCount(subject: Subject): Int } \ 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 9156771..3e9ae13 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 @@ -4,6 +4,7 @@ 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 be.ugent.sel.studeez.domain.TaskDAO +import com.google.firebase.firestore.AggregateSource import com.google.firebase.firestore.CollectionReference import com.google.firebase.firestore.FirebaseFirestore import com.google.firebase.firestore.ktx.snapshots @@ -24,8 +25,8 @@ class FireBaseSubjectDAO @Inject constructor( .map { it.toObjects(Subject::class.java) } .map { subjects -> subjects.map { subject -> - subject.taskCount = taskDAO.getTaskCount(subject) - subject.taskCompletedCount = taskDAO.getCompletedTaskCount(subject) + subject.taskCount = getTaskCount(subject) + subject.taskCompletedCount = getCompletedTaskCount(subject) subject } } @@ -47,8 +48,39 @@ class FireBaseSubjectDAO @Inject constructor( currentUserSubjectsCollection().document(newSubject.id).set(newSubject) } + override suspend fun getTaskCount(subject: Subject): Int { + return subjectTasksCollection(subject) + .nonArchived() + .count() + .get(AggregateSource.SERVER) + .await() + .count.toInt() + } + + override suspend fun getCompletedTaskCount(subject: Subject): Int { + return subjectTasksCollection(subject) + .nonArchived() + .completed() + .count() + .get(AggregateSource.SERVER) + .await() + .count.toInt() + } + + override fun getStudyTime(subject: Subject): Flow { + return taskDAO.getTasks(subject) + .map { tasks -> tasks.sumOf { it.time } } + } + private fun currentUserSubjectsCollection(): CollectionReference = firestore.collection(FireBaseCollections.USER_COLLECTION) .document(auth.currentUserId) .collection(FireBaseCollections.SUBJECT_COLLECTION) + + private fun subjectTasksCollection(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/domain/implementation/FireBaseTaskDAO.kt b/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FireBaseTaskDAO.kt index 049bb54..bde5c6f 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 @@ -5,7 +5,6 @@ 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.AggregateSource import com.google.firebase.firestore.CollectionReference import com.google.firebase.firestore.FirebaseFirestore import com.google.firebase.firestore.Query @@ -31,44 +30,20 @@ class FireBaseTaskDAO @Inject constructor( return selectedSubjectTasksCollection(subjectId).document(taskId).get().await().toObject()!! } - override suspend fun getTaskCount(subject: Subject): Int { - return selectedSubjectTasksCollection(subject.id) - .nonArchived() - .count() - .get(AggregateSource.SERVER) - .await() - .count.toInt() - } - - override suspend fun getCompletedTaskCount(subject: Subject): Int { - return selectedSubjectTasksCollection(subject.id) - .completed() - .nonArchived() - .count() - .get(AggregateSource.SERVER) - .await() - .count.toInt() - } - override fun saveTask(newTask: Task) { selectedSubjectTasksCollection(newTask.subjectId).add(newTask) } override fun updateTask(newTask: Task) { - selectedSubjectTasksCollection(newTask.subjectId).document(newTask.id).set(newTask) + selectedSubjectTasksCollection(newTask.subjectId) + .document(newTask.id) + .set(newTask) } override fun deleteTask(oldTask: Task) { selectedSubjectTasksCollection(oldTask.subjectId).document(oldTask.id).delete() } - override fun toggleTaskCompleted(task: Task, completed: Boolean) { - selectedSubjectTasksCollection(task.subjectId) - .document(task.id) -// .update(TaskDocument.completed, completed) - .set(task.copy(completed = completed)) - } - private fun selectedSubjectTasksCollection(subjectId: String): CollectionReference = firestore.collection(FireBaseCollections.USER_COLLECTION) .document(auth.currentUserId) @@ -76,18 +51,18 @@ class FireBaseTaskDAO @Inject constructor( .document(subjectId) .collection(FireBaseCollections.TASK_COLLECTION) - // Extend CollectionReference and Query with some filters +} - private fun CollectionReference.nonArchived(): Query = - this.whereEqualTo(TaskDocument.archived, false) +// Extend CollectionReference and Query with some filters - private fun Query.nonArchived(): Query = - this.whereEqualTo(TaskDocument.archived, false) +fun CollectionReference.nonArchived(): Query = + this.whereEqualTo(TaskDocument.archived, false) - private fun CollectionReference.completed(): Query = - this.whereEqualTo(TaskDocument.completed, true) +fun Query.nonArchived(): Query = + this.whereEqualTo(TaskDocument.archived, false) - private fun Query.completed(): Query = - this.whereEqualTo(TaskDocument.completed, true) +fun CollectionReference.completed(): Query = + this.whereEqualTo(TaskDocument.completed, true) -} \ No newline at end of file +fun Query.completed(): Query = + this.whereEqualTo(TaskDocument.completed, true) From ec31e116b4c3e0bf5bcded46a7ce9fa35c3770ee Mon Sep 17 00:00:00 2001 From: brreynie Date: Tue, 9 May 2023 21:29:52 +0200 Subject: [PATCH 05/20] refactor subjectscreen to use uiState --- .../common/composable/feed/FeedViewModel.kt | 6 +- .../studeez/data/local/models/task/Subject.kt | 3 +- .../studeez/data/local/models/task/Task.kt | 2 +- .../studeez/screens/tasks/SubjectScreen.kt | 76 ++++++++++++++----- .../studeez/screens/tasks/SubjectUiState.kt | 8 ++ .../studeez/screens/tasks/SubjectViewModel.kt | 18 +++-- .../studeez/screens/tasks/TaskViewModel.kt | 13 +--- 7 files changed, 84 insertions(+), 42 deletions(-) create mode 100644 app/src/main/java/be/ugent/sel/studeez/screens/tasks/SubjectUiState.kt diff --git a/app/src/main/java/be/ugent/sel/studeez/common/composable/feed/FeedViewModel.kt b/app/src/main/java/be/ugent/sel/studeez/common/composable/feed/FeedViewModel.kt index 443d0c9..13d134b 100644 --- a/app/src/main/java/be/ugent/sel/studeez/common/composable/feed/FeedViewModel.kt +++ b/app/src/main/java/be/ugent/sel/studeez/common/composable/feed/FeedViewModel.kt @@ -2,14 +2,16 @@ package be.ugent.sel.studeez.common.composable.feed import androidx.lifecycle.viewModelScope import be.ugent.sel.studeez.data.SelectedTask -import be.ugent.sel.studeez.data.local.models.FeedEntry import be.ugent.sel.studeez.domain.FeedDAO import be.ugent.sel.studeez.domain.LogService import be.ugent.sel.studeez.domain.TaskDAO import be.ugent.sel.studeez.navigation.StudeezDestinations import be.ugent.sel.studeez.screens.StudeezViewModel import dagger.hilt.android.lifecycle.HiltViewModel -import kotlinx.coroutines.flow.* +import kotlinx.coroutines.flow.SharingStarted +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.launch import javax.inject.Inject 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 622ef3c..6f29e22 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 @@ -6,10 +6,11 @@ import com.google.firebase.firestore.Exclude data class Subject( @DocumentId val id: String = "", val name: String = "", - val time: Int = 0, val argb_color: Long = 0, @get:Exclude @set:Exclude var taskCount: Int = 0, @get:Exclude @set:Exclude var taskCompletedCount: Int = 0, + @get:Exclude @set:Exclude + var time: Int = 0, ) 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 44d6d01..e42ce5d 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 @@ -5,7 +5,7 @@ import com.google.firebase.firestore.DocumentId data class Task( @DocumentId val id: String = "", val name: String = "", - val completed: Boolean = false, + var completed: Boolean = false, val time: Int = 0, val subjectId: String = "", var archived: Boolean = false, 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 a3395ea..115c75e 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 @@ -1,11 +1,14 @@ package be.ugent.sel.studeez.screens.tasks -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.* import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items +import androidx.compose.material.CircularProgressIndicator +import androidx.compose.material.MaterialTheme import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview @@ -16,8 +19,6 @@ import be.ugent.sel.studeez.common.composable.drawer.DrawerActions import be.ugent.sel.studeez.common.composable.navbar.NavigationBarActions import be.ugent.sel.studeez.common.composable.tasks.SubjectEntry import be.ugent.sel.studeez.data.local.models.task.Subject -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.flowOf import be.ugent.sel.studeez.R.string as AppText @Composable @@ -27,12 +28,13 @@ fun SubjectRoute( drawerActions: DrawerActions, navigationBarActions: NavigationBarActions, ) { + val uiState by viewModel.uiState.collectAsState() SubjectScreen( drawerActions = drawerActions, navigationBarActions = navigationBarActions, - addSubject = { viewModel.addSubject(open) }, - getSubjects = viewModel::getSubjects, + onAddSubject = { viewModel.onAddSubject(open) }, onViewSubject = { viewModel.onViewSubject(it, open) }, + uiState, ) } @@ -40,9 +42,9 @@ fun SubjectRoute( fun SubjectScreen( drawerActions: DrawerActions, navigationBarActions: NavigationBarActions, - addSubject: () -> Unit, - getSubjects: () -> Flow>, + onAddSubject: () -> Unit, onViewSubject: (Subject) -> Unit, + uiState: SubjectUiState, ) { PrimaryScreenTemplate( title = stringResource(AppText.my_subjects), @@ -50,17 +52,29 @@ fun SubjectScreen( navigationBarActions = navigationBarActions, barAction = {}, ) { - val subjects = getSubjects().collectAsState(initial = emptyList()) - Column( - modifier = Modifier.padding(top = 5.dp) - ) { - NewTaskSubjectButton(onClick = addSubject, AppText.new_subject) - LazyColumn { - items(subjects.value) { - SubjectEntry( - subject = it, - onViewSubject = { onViewSubject(it) }, - ) + when (uiState) { + SubjectUiState.Loading -> Column( + modifier = Modifier + .fillMaxWidth() + .fillMaxHeight(), + verticalArrangement = Arrangement.Center, + horizontalAlignment = Alignment.CenterHorizontally + ) { + CircularProgressIndicator(color = MaterialTheme.colors.onBackground) + } + is SubjectUiState.Succes -> { + Column( + modifier = Modifier.padding(top = 5.dp) + ) { + NewTaskSubjectButton(onClick = onAddSubject, AppText.new_subject) + LazyColumn { + items(uiState.subjects) { + SubjectEntry( + subject = it, + onViewSubject = { onViewSubject(it) }, + ) + } + } } } } @@ -73,8 +87,28 @@ fun SubjectScreenPreview() { SubjectScreen( drawerActions = DrawerActions({}, {}, {}, {}, {}), navigationBarActions = NavigationBarActions({ false }, {}, {}, {}, {}, {}, {}, {}), - addSubject = {}, - getSubjects = { flowOf() }, + onAddSubject = {}, onViewSubject = {}, + uiState = SubjectUiState.Succes( + listOf( + Subject( + name = "Test Subject", + argb_color = 0xFFFFD200, + taskCount = 5, taskCompletedCount = 2, + ) + ) + ) + ) +} + +@Preview +@Composable +fun SubjectScreenLoadingPreview() { + SubjectScreen( + drawerActions = DrawerActions({}, {}, {}, {}, {}), + navigationBarActions = NavigationBarActions({ false }, {}, {}, {}, {}, {}, {}, {}), + onAddSubject = {}, + onViewSubject = {}, + uiState = SubjectUiState.Loading ) } \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/tasks/SubjectUiState.kt b/app/src/main/java/be/ugent/sel/studeez/screens/tasks/SubjectUiState.kt new file mode 100644 index 0000000..38adae4 --- /dev/null +++ b/app/src/main/java/be/ugent/sel/studeez/screens/tasks/SubjectUiState.kt @@ -0,0 +1,8 @@ +package be.ugent.sel.studeez.screens.tasks + +import be.ugent.sel.studeez.data.local.models.task.Subject + +sealed interface SubjectUiState { + object Loading : SubjectUiState + data class Succes(val subjects: List) : SubjectUiState +} \ 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 f1d6071..8587327 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,6 @@ package be.ugent.sel.studeez.screens.tasks +import androidx.lifecycle.viewModelScope import be.ugent.sel.studeez.data.SelectedSubject import be.ugent.sel.studeez.data.local.models.task.Subject import be.ugent.sel.studeez.domain.LogService @@ -7,7 +8,7 @@ import be.ugent.sel.studeez.domain.SubjectDAO import be.ugent.sel.studeez.navigation.StudeezDestinations import be.ugent.sel.studeez.screens.StudeezViewModel import dagger.hilt.android.lifecycle.HiltViewModel -import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.* import javax.inject.Inject @HiltViewModel @@ -16,12 +17,17 @@ class SubjectViewModel @Inject constructor( private val selectedSubject: SelectedSubject, logService: LogService, ) : StudeezViewModel(logService) { - fun addSubject(open: (String) -> Unit) { - open(StudeezDestinations.ADD_SUBJECT_FORM) - } - fun getSubjects(): Flow> { - return subjectDAO.getSubjects() + val uiState: StateFlow = subjectDAO.getSubjects() + .map { SubjectUiState.Succes(it) } + .stateIn( + scope = viewModelScope, + initialValue = SubjectUiState.Loading, + started = SharingStarted.Eagerly, + ) + + fun onAddSubject(open: (String) -> Unit) { + open(StudeezDestinations.ADD_SUBJECT_FORM) } fun onViewSubject(subject: Subject, open: (String) -> Unit) { 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 2361399..e2adbc1 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,12 +1,10 @@ package be.ugent.sel.studeez.screens.tasks -import android.util.Log import be.ugent.sel.studeez.data.SelectedSubject import be.ugent.sel.studeez.data.SelectedTask import be.ugent.sel.studeez.data.local.models.task.Subject import be.ugent.sel.studeez.data.local.models.task.Task import be.ugent.sel.studeez.domain.LogService -import be.ugent.sel.studeez.domain.SubjectDAO import be.ugent.sel.studeez.domain.TaskDAO import be.ugent.sel.studeez.navigation.StudeezDestinations import be.ugent.sel.studeez.screens.StudeezViewModel @@ -17,7 +15,6 @@ import javax.inject.Inject @HiltViewModel class TaskViewModel @Inject constructor( private val taskDAO: TaskDAO, - private val subjectDAO: SubjectDAO, private val selectedSubject: SelectedSubject, private val selectedTask: SelectedTask, logService: LogService, @@ -30,11 +27,6 @@ class TaskViewModel @Inject constructor( return taskDAO.getTasks(selectedSubject()) } - fun deleteSubject(open: (String) -> Unit) { - subjectDAO.deleteSubject(selectedSubject()) - open(StudeezDestinations.SUBJECT_SCREEN) - } - fun getSelectedSubject(): Subject { return selectedSubject() } @@ -44,12 +36,11 @@ class TaskViewModel @Inject constructor( } fun archiveTask(task: Task) { - task.archive() - taskDAO.updateTask(task) + taskDAO.updateTask(task.copy(archived = true)) } fun toggleTaskCompleted(task: Task, completed: Boolean) { - taskDAO.toggleTaskCompleted(task, completed) + taskDAO.updateTask(task.copy(completed = completed)) } fun editSubject(open: (String) -> Unit) { From e9cc4f4a0c9eaae4b6375176ae8a967be6e25284 Mon Sep 17 00:00:00 2001 From: brreynie Date: Tue, 9 May 2023 21:37:26 +0200 Subject: [PATCH 06/20] show studytime --- .../common/composable/tasks/SubjectEntry.kt | 20 +++++++++++++------ .../studeez/screens/tasks/SubjectScreen.kt | 7 +++++++ .../studeez/screens/tasks/SubjectViewModel.kt | 4 ++++ 3 files changed, 25 insertions(+), 6 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 a6b89bf..5db2af3 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 @@ -9,6 +9,8 @@ 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.runtime.collectAsState +import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip @@ -21,13 +23,17 @@ import androidx.compose.ui.unit.dp 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 +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.flowOf import be.ugent.sel.studeez.R.string as AppText @Composable fun SubjectEntry( subject: Subject, onViewSubject: () -> Unit, + getStudyTime: () -> Flow, ) { + val studytime by getStudyTime().collectAsState(initial = 0) Card( modifier = Modifier .fillMaxWidth() @@ -64,7 +70,7 @@ fun SubjectEntry( verticalAlignment = Alignment.CenterVertically, ) { Text( - text = HoursMinutesSeconds(subject.time).toString(), + text = HoursMinutesSeconds(studytime).toString(), ) Row( verticalAlignment = Alignment.CenterVertically, @@ -74,7 +80,7 @@ fun SubjectEntry( imageVector = Icons.Default.List, contentDescription = stringResource(id = AppText.tasks) ) - Text(text = "${subject.taskCompletedCount}/${subject.taskCount}") // TODO + Text(text = "${subject.taskCompletedCount}/${subject.taskCount}") } } } @@ -98,11 +104,12 @@ fun SubjectEntryPreview() { subject = Subject( name = "Test Subject", argb_color = 0xFFFFD200, - time = 60, taskCount = 5, taskCompletedCount = 2, ), - ) {} + onViewSubject = {}, + getStudyTime = { flowOf() } + ) } @Preview @@ -112,7 +119,8 @@ fun OverflowSubjectEntryPreview() { subject = Subject( name = "Testttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt", argb_color = 0xFFFFD200, - time = 60, ), - ) {} + onViewSubject = {}, + getStudyTime = { flowOf() } + ) } \ 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 115c75e..7ff5636 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 @@ -19,6 +19,8 @@ import be.ugent.sel.studeez.common.composable.drawer.DrawerActions import be.ugent.sel.studeez.common.composable.navbar.NavigationBarActions import be.ugent.sel.studeez.common.composable.tasks.SubjectEntry import be.ugent.sel.studeez.data.local.models.task.Subject +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.flowOf import be.ugent.sel.studeez.R.string as AppText @Composable @@ -34,6 +36,7 @@ fun SubjectRoute( navigationBarActions = navigationBarActions, onAddSubject = { viewModel.onAddSubject(open) }, onViewSubject = { viewModel.onViewSubject(it, open) }, + getStudyTime = viewModel::getStudyTime, uiState, ) } @@ -44,6 +47,7 @@ fun SubjectScreen( navigationBarActions: NavigationBarActions, onAddSubject: () -> Unit, onViewSubject: (Subject) -> Unit, + getStudyTime: (Subject) -> Flow, uiState: SubjectUiState, ) { PrimaryScreenTemplate( @@ -72,6 +76,7 @@ fun SubjectScreen( SubjectEntry( subject = it, onViewSubject = { onViewSubject(it) }, + getStudyTime = { getStudyTime(it) }, ) } } @@ -89,6 +94,7 @@ fun SubjectScreenPreview() { navigationBarActions = NavigationBarActions({ false }, {}, {}, {}, {}, {}, {}, {}), onAddSubject = {}, onViewSubject = {}, + getStudyTime = { flowOf() }, uiState = SubjectUiState.Succes( listOf( Subject( @@ -109,6 +115,7 @@ fun SubjectScreenLoadingPreview() { navigationBarActions = NavigationBarActions({ false }, {}, {}, {}, {}, {}, {}, {}), onAddSubject = {}, onViewSubject = {}, + getStudyTime = { flowOf() }, uiState = SubjectUiState.Loading ) } \ 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 8587327..f384489 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 @@ -30,6 +30,10 @@ class SubjectViewModel @Inject constructor( open(StudeezDestinations.ADD_SUBJECT_FORM) } + fun getStudyTime(subject: Subject): Flow { + return subjectDAO.getStudyTime(subject) + } + fun onViewSubject(subject: Subject, open: (String) -> Unit) { selectedSubject.set(subject) open(StudeezDestinations.TASKS_SCREEN) From 0e4200057b5fdb2df45c31bdb7b227b44e451fb8 Mon Sep 17 00:00:00 2001 From: brreynie Date: Tue, 9 May 2023 21:56:25 +0200 Subject: [PATCH 07/20] fix selectedSubject --- .../sel/studeez/navigation/StudeezNavGraph.kt | 12 ++--- .../{tasks => subjects}/SubjectScreen.kt | 2 +- .../{tasks => subjects}/SubjectUiState.kt | 2 +- .../{tasks => subjects}/SubjectViewModel.kt | 2 +- .../form}/SubjectFormScreen.kt | 8 +-- .../form}/SubjectFormUiState.kt | 2 +- .../form}/SubjectFormViewModel.kt | 54 ++++++++++++------- .../tasks/{forms => form}/TaskFormScreen.kt | 2 +- .../tasks/{forms => form}/TaskFormUiState.kt | 2 +- .../{forms => form}/TaskFormViewModel.kt | 5 +- 10 files changed, 53 insertions(+), 38 deletions(-) rename app/src/main/java/be/ugent/sel/studeez/screens/{tasks => subjects}/SubjectScreen.kt (98%) rename app/src/main/java/be/ugent/sel/studeez/screens/{tasks => subjects}/SubjectUiState.kt (81%) rename app/src/main/java/be/ugent/sel/studeez/screens/{tasks => subjects}/SubjectViewModel.kt (96%) rename app/src/main/java/be/ugent/sel/studeez/screens/{tasks/forms => subjects/form}/SubjectFormScreen.kt (95%) rename app/src/main/java/be/ugent/sel/studeez/screens/{tasks/forms => subjects/form}/SubjectFormUiState.kt (64%) rename app/src/main/java/be/ugent/sel/studeez/screens/{tasks/forms => subjects/form}/SubjectFormViewModel.kt (67%) rename app/src/main/java/be/ugent/sel/studeez/screens/tasks/{forms => form}/TaskFormScreen.kt (98%) rename app/src/main/java/be/ugent/sel/studeez/screens/tasks/{forms => form}/TaskFormUiState.kt (53%) rename app/src/main/java/be/ugent/sel/studeez/screens/tasks/{forms => form}/TaskFormViewModel.kt (93%) diff --git a/app/src/main/java/be/ugent/sel/studeez/navigation/StudeezNavGraph.kt b/app/src/main/java/be/ugent/sel/studeez/navigation/StudeezNavGraph.kt index 5becc44..6ef1606 100644 --- a/app/src/main/java/be/ugent/sel/studeez/navigation/StudeezNavGraph.kt +++ b/app/src/main/java/be/ugent/sel/studeez/navigation/StudeezNavGraph.kt @@ -24,12 +24,12 @@ import be.ugent.sel.studeez.screens.sessions.SessionsRoute import be.ugent.sel.studeez.screens.settings.SettingsRoute 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.subjects.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.subjects.form.SubjectCreateRoute +import be.ugent.sel.studeez.screens.subjects.form.SubjectEditRoute +import be.ugent.sel.studeez.screens.tasks.form.TaskAddRoute +import be.ugent.sel.studeez.screens.tasks.form.TaskEditRoute import be.ugent.sel.studeez.screens.timer_form.TimerAddRoute import be.ugent.sel.studeez.screens.timer_form.TimerEditRoute import be.ugent.sel.studeez.screens.timer_form.timer_type_select.TimerTypeSelectScreen @@ -81,7 +81,7 @@ fun StudeezNavGraph( } composable(StudeezDestinations.ADD_SUBJECT_FORM) { - SubjectAddRoute( + SubjectCreateRoute( goBack = goBack, openAndPopUp = openAndPopUp, viewModel = hiltViewModel(), 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/subjects/SubjectScreen.kt similarity index 98% rename from app/src/main/java/be/ugent/sel/studeez/screens/tasks/SubjectScreen.kt rename to app/src/main/java/be/ugent/sel/studeez/screens/subjects/SubjectScreen.kt index 7ff5636..ab2cff4 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/tasks/SubjectScreen.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/subjects/SubjectScreen.kt @@ -1,4 +1,4 @@ -package be.ugent.sel.studeez.screens.tasks +package be.ugent.sel.studeez.screens.subjects import androidx.compose.foundation.layout.* import androidx.compose.foundation.lazy.LazyColumn diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/tasks/SubjectUiState.kt b/app/src/main/java/be/ugent/sel/studeez/screens/subjects/SubjectUiState.kt similarity index 81% rename from app/src/main/java/be/ugent/sel/studeez/screens/tasks/SubjectUiState.kt rename to app/src/main/java/be/ugent/sel/studeez/screens/subjects/SubjectUiState.kt index 38adae4..2e44e27 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/tasks/SubjectUiState.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/subjects/SubjectUiState.kt @@ -1,4 +1,4 @@ -package be.ugent.sel.studeez.screens.tasks +package be.ugent.sel.studeez.screens.subjects import be.ugent.sel.studeez.data.local.models.task.Subject 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/subjects/SubjectViewModel.kt similarity index 96% rename from app/src/main/java/be/ugent/sel/studeez/screens/tasks/SubjectViewModel.kt rename to app/src/main/java/be/ugent/sel/studeez/screens/subjects/SubjectViewModel.kt index f384489..c158529 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/tasks/SubjectViewModel.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/subjects/SubjectViewModel.kt @@ -1,4 +1,4 @@ -package be.ugent.sel.studeez.screens.tasks +package be.ugent.sel.studeez.screens.subjects import androidx.lifecycle.viewModelScope import be.ugent.sel.studeez.data.SelectedSubject 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/subjects/form/SubjectFormScreen.kt similarity index 95% rename from app/src/main/java/be/ugent/sel/studeez/screens/tasks/forms/SubjectFormScreen.kt rename to app/src/main/java/be/ugent/sel/studeez/screens/subjects/form/SubjectFormScreen.kt index 74bc7d2..19e6816 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/subjects/form/SubjectFormScreen.kt @@ -1,4 +1,4 @@ -package be.ugent.sel.studeez.screens.tasks.forms +package be.ugent.sel.studeez.screens.subjects.form import androidx.annotation.StringRes import androidx.compose.foundation.layout.Column @@ -19,10 +19,10 @@ import be.ugent.sel.studeez.resources import be.ugent.sel.studeez.R.string as AppText @Composable -fun SubjectAddRoute( +fun SubjectCreateRoute( goBack: () -> Unit, openAndPopUp: (String, String) -> Unit, - viewModel: SubjectFormViewModel, + viewModel: SubjectCreateFormViewModel, ) { val uiState by viewModel.uiState SubjectForm( @@ -39,7 +39,7 @@ fun SubjectAddRoute( fun SubjectEditRoute( goBack: () -> Unit, openAndPopUp: (String, String) -> Unit, - viewModel: SubjectFormViewModel, + viewModel: SubjectEditFormViewModel, ) { val uiState by viewModel.uiState SubjectForm( 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/subjects/form/SubjectFormUiState.kt similarity index 64% rename from app/src/main/java/be/ugent/sel/studeez/screens/tasks/forms/SubjectFormUiState.kt rename to app/src/main/java/be/ugent/sel/studeez/screens/subjects/form/SubjectFormUiState.kt index 5418b74..9fdba01 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/subjects/form/SubjectFormUiState.kt @@ -1,4 +1,4 @@ -package be.ugent.sel.studeez.screens.tasks.forms +package be.ugent.sel.studeez.screens.subjects.form data class SubjectFormUiState( val name: String = "", 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/subjects/form/SubjectFormViewModel.kt similarity index 67% rename from app/src/main/java/be/ugent/sel/studeez/screens/tasks/forms/SubjectFormViewModel.kt rename to app/src/main/java/be/ugent/sel/studeez/screens/subjects/form/SubjectFormViewModel.kt index 68ebd3e..37a9e5b 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/subjects/form/SubjectFormViewModel.kt @@ -1,5 +1,6 @@ -package be.ugent.sel.studeez.screens.tasks.forms +package be.ugent.sel.studeez.screens.subjects.form +import androidx.compose.runtime.MutableState import androidx.compose.runtime.mutableStateOf import be.ugent.sel.studeez.data.SelectedSubject import be.ugent.sel.studeez.data.local.models.task.Subject @@ -10,25 +11,17 @@ 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, +abstract class SubjectFormViewModel( + protected val subjectDAO: SubjectDAO, + protected val selectedSubject: SelectedSubject, logService: LogService, ) : StudeezViewModel(logService) { - var uiState = mutableStateOf( - if (selectedSubject.isSet()) SubjectFormUiState( - name = selectedSubject().name, - color = selectedSubject().argb_color - ) - else SubjectFormUiState() - ) - private set + abstract val uiState: MutableState - private val name: String + protected val name: String get() = uiState.value.name - private val color: Long + protected val color: Long get() = uiState.value.color fun onNameChange(newValue: String) { @@ -38,11 +31,15 @@ class SubjectFormViewModel @Inject constructor( fun onColorChange(newValue: Long) { uiState.value = uiState.value.copy(color = newValue) } +} - fun onDelete(openAndPopUp: (String, String) -> Unit) { - subjectDAO.deleteSubject(selectedSubject()) - openAndPopUp(StudeezDestinations.SUBJECT_SCREEN, StudeezDestinations.EDIT_SUBJECT_FORM) - } +@HiltViewModel +class SubjectCreateFormViewModel @Inject constructor( + subjectDAO: SubjectDAO, + selectedSubject: SelectedSubject, + logService: LogService, +) : SubjectFormViewModel(subjectDAO, selectedSubject, logService) { + override val uiState = mutableStateOf(SubjectFormUiState()) fun onCreate(openAndPopUp: (String, String) -> Unit) { val newSubject = Subject( @@ -57,6 +54,25 @@ class SubjectFormViewModel @Inject constructor( // open(StudeezDestinations.TASKS_SCREEN) openAndPopUp(StudeezDestinations.SUBJECT_SCREEN, StudeezDestinations.ADD_SUBJECT_FORM) } +} + +@HiltViewModel +class SubjectEditFormViewModel @Inject constructor( + subjectDAO: SubjectDAO, + selectedSubject: SelectedSubject, + logService: LogService, +) : SubjectFormViewModel(subjectDAO, selectedSubject, logService) { + override val uiState = mutableStateOf( + SubjectFormUiState( + name = selectedSubject().name, + color = selectedSubject().argb_color + ) + ) + + fun onDelete(openAndPopUp: (String, String) -> Unit) { + subjectDAO.deleteSubject(selectedSubject()) + openAndPopUp(StudeezDestinations.SUBJECT_SCREEN, StudeezDestinations.EDIT_SUBJECT_FORM) + } fun onEdit(openAndPopUp: (String, String) -> Unit) { val newSubject = selectedSubject().copy( 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/form/TaskFormScreen.kt similarity index 98% rename from app/src/main/java/be/ugent/sel/studeez/screens/tasks/forms/TaskFormScreen.kt rename to app/src/main/java/be/ugent/sel/studeez/screens/tasks/form/TaskFormScreen.kt index 62b6c6c..b09dc66 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/form/TaskFormScreen.kt @@ -1,4 +1,4 @@ -package be.ugent.sel.studeez.screens.tasks.forms +package be.ugent.sel.studeez.screens.tasks.form import androidx.annotation.StringRes import androidx.compose.foundation.layout.Column 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/form/TaskFormUiState.kt similarity index 53% rename from app/src/main/java/be/ugent/sel/studeez/screens/tasks/forms/TaskFormUiState.kt rename to app/src/main/java/be/ugent/sel/studeez/screens/tasks/form/TaskFormUiState.kt index d967d59..6156fb7 100644 --- 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/form/TaskFormUiState.kt @@ -1,4 +1,4 @@ -package be.ugent.sel.studeez.screens.tasks.forms +package be.ugent.sel.studeez.screens.tasks.form data class TaskFormUiState( val name: String = "", 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/form/TaskFormViewModel.kt similarity index 93% rename from app/src/main/java/be/ugent/sel/studeez/screens/tasks/forms/TaskFormViewModel.kt rename to app/src/main/java/be/ugent/sel/studeez/screens/tasks/form/TaskFormViewModel.kt index 03ad32b..8ae91ae 100644 --- 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/form/TaskFormViewModel.kt @@ -1,4 +1,4 @@ -package be.ugent.sel.studeez.screens.tasks.forms +package be.ugent.sel.studeez.screens.tasks.form import androidx.compose.runtime.mutableStateOf import be.ugent.sel.studeez.data.SelectedSubject @@ -11,8 +11,7 @@ import be.ugent.sel.studeez.screens.StudeezViewModel import dagger.hilt.android.lifecycle.HiltViewModel import javax.inject.Inject -@HiltViewModel -class TaskFormViewModel @Inject constructor( +abstract class TaskFormViewModel( private val taskDAO: TaskDAO, private val selectedSubject: SelectedSubject, private val selectedTask: SelectedTask, From e333a0f6266982e372203f716eb3d59b146786e1 Mon Sep 17 00:00:00 2001 From: brreynie Date: Tue, 9 May 2023 22:03:38 +0200 Subject: [PATCH 08/20] fix selectedTask --- .../sel/studeez/navigation/StudeezNavGraph.kt | 4 +- .../screens/tasks/form/TaskFormScreen.kt | 6 +-- .../screens/tasks/form/TaskFormViewModel.kt | 46 +++++++++++++------ 3 files changed, 37 insertions(+), 19 deletions(-) diff --git a/app/src/main/java/be/ugent/sel/studeez/navigation/StudeezNavGraph.kt b/app/src/main/java/be/ugent/sel/studeez/navigation/StudeezNavGraph.kt index 6ef1606..37085f1 100644 --- a/app/src/main/java/be/ugent/sel/studeez/navigation/StudeezNavGraph.kt +++ b/app/src/main/java/be/ugent/sel/studeez/navigation/StudeezNavGraph.kt @@ -28,7 +28,7 @@ import be.ugent.sel.studeez.screens.subjects.SubjectRoute import be.ugent.sel.studeez.screens.tasks.TaskRoute import be.ugent.sel.studeez.screens.subjects.form.SubjectCreateRoute import be.ugent.sel.studeez.screens.subjects.form.SubjectEditRoute -import be.ugent.sel.studeez.screens.tasks.form.TaskAddRoute +import be.ugent.sel.studeez.screens.tasks.form.TaskCreateRoute import be.ugent.sel.studeez.screens.tasks.form.TaskEditRoute import be.ugent.sel.studeez.screens.timer_form.TimerAddRoute import be.ugent.sel.studeez.screens.timer_form.TimerEditRoute @@ -105,7 +105,7 @@ fun StudeezNavGraph( } composable(StudeezDestinations.ADD_TASK_FORM) { - TaskAddRoute( + TaskCreateRoute( goBack = goBack, openAndPopUp = openAndPopUp, viewModel = hiltViewModel(), diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/tasks/form/TaskFormScreen.kt b/app/src/main/java/be/ugent/sel/studeez/screens/tasks/form/TaskFormScreen.kt index b09dc66..92302ea 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/tasks/form/TaskFormScreen.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/tasks/form/TaskFormScreen.kt @@ -18,10 +18,10 @@ import be.ugent.sel.studeez.resources import be.ugent.sel.studeez.R.string as AppText @Composable -fun TaskAddRoute( +fun TaskCreateRoute( goBack: () -> Unit, openAndPopUp: (String, String) -> Unit, - viewModel: TaskFormViewModel, + viewModel: TaskCreateFormViewModel, ) { val uiState by viewModel.uiState TaskForm( @@ -37,7 +37,7 @@ fun TaskAddRoute( fun TaskEditRoute( goBack: () -> Unit, openAndPopUp: (String, String) -> Unit, - viewModel: TaskFormViewModel, + viewModel: TaskEditFormViewModel, ) { val uiState by viewModel.uiState TaskForm( diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/tasks/form/TaskFormViewModel.kt b/app/src/main/java/be/ugent/sel/studeez/screens/tasks/form/TaskFormViewModel.kt index 8ae91ae..07cba5d 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/tasks/form/TaskFormViewModel.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/tasks/form/TaskFormViewModel.kt @@ -1,5 +1,6 @@ package be.ugent.sel.studeez.screens.tasks.form +import androidx.compose.runtime.MutableState import androidx.compose.runtime.mutableStateOf import be.ugent.sel.studeez.data.SelectedSubject import be.ugent.sel.studeez.data.SelectedTask @@ -12,37 +13,54 @@ import dagger.hilt.android.lifecycle.HiltViewModel import javax.inject.Inject abstract class TaskFormViewModel( - private val taskDAO: TaskDAO, - private val selectedSubject: SelectedSubject, - private val selectedTask: SelectedTask, + protected val taskDAO: TaskDAO, + protected val selectedSubject: SelectedSubject, + protected val selectedTask: SelectedTask, logService: LogService, ) : StudeezViewModel(logService) { - var uiState = mutableStateOf( - if (selectedTask.isSet()) TaskFormUiState(selectedTask().name) else TaskFormUiState() - ) - private set + abstract val uiState: MutableState - private val name: String + protected 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) - } +@HiltViewModel +class TaskCreateFormViewModel @Inject constructor( + taskDAO: TaskDAO, + selectedSubject: SelectedSubject, + selectedTask: SelectedTask, + logService: LogService, +) : TaskFormViewModel(taskDAO, selectedSubject, selectedTask, logService) { + override val uiState = mutableStateOf(TaskFormUiState()) 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) } +} + +@HiltViewModel +class TaskEditFormViewModel @Inject constructor( + taskDAO: TaskDAO, + selectedSubject: SelectedSubject, + selectedTask: SelectedTask, + logService: LogService, +) : TaskFormViewModel(taskDAO, selectedSubject, selectedTask, logService) { + override val uiState = mutableStateOf(TaskFormUiState()) + + fun onDelete(openAndPopUp: (String, String) -> Unit) { + taskDAO.deleteTask(selectedTask()) + openAndPopUp(StudeezDestinations.TASKS_SCREEN, StudeezDestinations.EDIT_TASK_FORM) + } fun onEdit(openAndPopUp: (String, String) -> Unit) { - val newTask = Task(name = name) + val newTask = selectedTask().copy(name = name) taskDAO.updateTask(newTask) openAndPopUp(StudeezDestinations.TASKS_SCREEN, StudeezDestinations.EDIT_TASK_FORM) } -} \ No newline at end of file +} From d4c017ef1b7780d803748e3d9c64d6ea894b7ca3 Mon Sep 17 00:00:00 2001 From: brreynie Date: Tue, 9 May 2023 22:11:52 +0200 Subject: [PATCH 09/20] add time to task when saving session report --- .../studeez/screens/session_recap/SessionRecapViewModel.kt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/session_recap/SessionRecapViewModel.kt b/app/src/main/java/be/ugent/sel/studeez/screens/session_recap/SessionRecapViewModel.kt index 5fb4943..5fdd95c 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/session_recap/SessionRecapViewModel.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/session_recap/SessionRecapViewModel.kt @@ -1,9 +1,11 @@ package be.ugent.sel.studeez.screens.session_recap +import be.ugent.sel.studeez.data.SelectedTask import be.ugent.sel.studeez.data.SessionReportState import be.ugent.sel.studeez.data.local.models.SessionReport import be.ugent.sel.studeez.domain.LogService import be.ugent.sel.studeez.domain.SessionDAO +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 @@ -13,6 +15,8 @@ import javax.inject.Inject class SessionRecapViewModel @Inject constructor( sessionReportState: SessionReportState, private val sessionDAO: SessionDAO, + private val taskDAO: TaskDAO, + private val selectedTask: SelectedTask, logService: LogService ) : StudeezViewModel(logService) { @@ -24,6 +28,8 @@ class SessionRecapViewModel @Inject constructor( fun saveSession(open: (String, String) -> Unit) { sessionDAO.saveSession(getSessionReport()) + val newTask = selectedTask().copy(time = selectedTask().time + report.studyTime) + taskDAO.updateTask(newTask) open(StudeezDestinations.HOME_SCREEN, StudeezDestinations.SESSION_RECAP) } From c3424b99964615b0477995761f1b751e81d0ce3b Mon Sep 17 00:00:00 2001 From: brreynie Date: Tue, 9 May 2023 22:26:11 +0200 Subject: [PATCH 10/20] archive subjects --- .../sel/studeez/data/local/models/task/Subject.kt | 10 ++++++++-- .../domain/implementation/FireBaseSubjectDAO.kt | 15 ++++++++++++--- .../domain/implementation/FireBaseTaskDAO.kt | 10 +++++----- .../screens/subjects/form/SubjectFormViewModel.kt | 2 +- .../ugent/sel/studeez/screens/tasks/TaskScreen.kt | 3 --- 5 files changed, 26 insertions(+), 14 deletions(-) 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 6f29e22..74ebe9f 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,10 +7,16 @@ data class Subject( @DocumentId val id: String = "", val name: String = "", val argb_color: Long = 0, + var archived: Boolean = false, @get:Exclude @set:Exclude var taskCount: Int = 0, @get:Exclude @set:Exclude var taskCompletedCount: Int = 0, - @get:Exclude @set:Exclude - var time: Int = 0, ) + +object SubjectDocument { + const val id = "id" + const val name = "name" + const val archived = "archived" + const val argb_color = "argb_color" +} \ 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 3e9ae13..b023986 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 @@ -1,12 +1,14 @@ 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.SubjectDocument import be.ugent.sel.studeez.domain.AccountDAO import be.ugent.sel.studeez.domain.SubjectDAO import be.ugent.sel.studeez.domain.TaskDAO import com.google.firebase.firestore.AggregateSource import com.google.firebase.firestore.CollectionReference import com.google.firebase.firestore.FirebaseFirestore +import com.google.firebase.firestore.Query import com.google.firebase.firestore.ktx.snapshots import com.google.firebase.firestore.ktx.toObject import kotlinx.coroutines.flow.Flow @@ -21,6 +23,7 @@ class FireBaseSubjectDAO @Inject constructor( ) : SubjectDAO { override fun getSubjects(): Flow> { return currentUserSubjectsCollection() + .subjectNotArchived() .snapshots() .map { it.toObjects(Subject::class.java) } .map { subjects -> @@ -50,7 +53,7 @@ class FireBaseSubjectDAO @Inject constructor( override suspend fun getTaskCount(subject: Subject): Int { return subjectTasksCollection(subject) - .nonArchived() + .taskNotArchived() .count() .get(AggregateSource.SERVER) .await() @@ -59,8 +62,8 @@ class FireBaseSubjectDAO @Inject constructor( override suspend fun getCompletedTaskCount(subject: Subject): Int { return subjectTasksCollection(subject) - .nonArchived() - .completed() + .taskNotArchived() + .taskNotCompleted() .count() .get(AggregateSource.SERVER) .await() @@ -83,4 +86,10 @@ class FireBaseSubjectDAO @Inject constructor( .collection(FireBaseCollections.SUBJECT_COLLECTION) .document(subject.id) .collection(FireBaseCollections.TASK_COLLECTION) + + fun CollectionReference.subjectNotArchived(): Query = + this.whereEqualTo(SubjectDocument.archived, false) + + fun Query.subjectNotArchived(): Query = + this.whereEqualTo(SubjectDocument.archived, false) } \ 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 bde5c6f..685b237 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 @@ -21,7 +21,7 @@ class FireBaseTaskDAO @Inject constructor( ) : TaskDAO { override fun getTasks(subject: Subject): Flow> { return selectedSubjectTasksCollection(subject.id) - .nonArchived() + .taskNotArchived() .snapshots() .map { it.toObjects(Task::class.java) } } @@ -55,14 +55,14 @@ class FireBaseTaskDAO @Inject constructor( // Extend CollectionReference and Query with some filters -fun CollectionReference.nonArchived(): Query = +fun CollectionReference.taskNotArchived(): Query = this.whereEqualTo(TaskDocument.archived, false) -fun Query.nonArchived(): Query = +fun Query.taskNotArchived(): Query = this.whereEqualTo(TaskDocument.archived, false) -fun CollectionReference.completed(): Query = +fun CollectionReference.taskNotCompleted(): Query = this.whereEqualTo(TaskDocument.completed, true) -fun Query.completed(): Query = +fun Query.taskNotCompleted(): Query = this.whereEqualTo(TaskDocument.completed, true) diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/subjects/form/SubjectFormViewModel.kt b/app/src/main/java/be/ugent/sel/studeez/screens/subjects/form/SubjectFormViewModel.kt index 37a9e5b..533123b 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/subjects/form/SubjectFormViewModel.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/subjects/form/SubjectFormViewModel.kt @@ -70,7 +70,7 @@ class SubjectEditFormViewModel @Inject constructor( ) fun onDelete(openAndPopUp: (String, String) -> Unit) { - subjectDAO.deleteSubject(selectedSubject()) + subjectDAO.updateSubject(selectedSubject().copy(archived = true)) openAndPopUp(StudeezDestinations.SUBJECT_SCREEN, StudeezDestinations.EDIT_SUBJECT_FORM) } 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 1b56bc6..7760d84 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 @@ -27,7 +27,6 @@ data class TaskActions( val addTask: () -> Unit, val getSubject: () -> Subject, val getTasks: () -> Flow>, - val deleteTask: (Task) -> Unit, val onCheckTask: (Task, Boolean) -> Unit, val editSubject: () -> Unit, val startTask: (Task) -> Unit, @@ -39,7 +38,6 @@ fun getTaskActions(viewModel: TaskViewModel, open: (String) -> Unit): TaskAction addTask = { viewModel.addTask(open) }, getTasks = viewModel::getTasks, getSubject = viewModel::getSelectedSubject, - deleteTask = viewModel::deleteTask, onCheckTask = { task, isChecked -> viewModel.toggleTaskCompleted(task, isChecked) }, editSubject = { viewModel.editSubject(open) }, startTask = { task -> viewModel.startTask(task, open) }, @@ -110,7 +108,6 @@ fun TaskScreenPreview() { {}, { Subject(name = "Test Subject") }, { flowOf() }, - {}, { _, _ -> run {} }, {}, {}, From 6a560fee795e95cf7d726454849f91e7dda31d61 Mon Sep 17 00:00:00 2001 From: lbarraga Date: Tue, 9 May 2023 22:29:07 +0200 Subject: [PATCH 11/20] button on feed not visible when task is checked --- .../common/composable/ButtonComposable.kt | 3 ++- .../common/composable/feed/FeedEntry.kt | 25 +++++++++++++------ .../studeez/data/local/models/FeedEntry.kt | 3 ++- .../domain/implementation/FirebaseFeedDAO.kt | 3 ++- 4 files changed, 24 insertions(+), 10 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 73ae1b5..0ba2ffe 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 @@ -20,6 +20,7 @@ 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.draw.scale import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview @@ -84,7 +85,7 @@ fun StealthButton( backgroundColor = MaterialTheme.colors.surface, contentColor = MaterialTheme.colors.onSurface.copy(alpha = 0.4f) ), - border = BorderStroke(3.dp, MaterialTheme.colors.onSurface.copy(alpha = 0.4f)) + border = BorderStroke(2.dp, MaterialTheme.colors.onSurface.copy(alpha = 0.4f)) ) } diff --git a/app/src/main/java/be/ugent/sel/studeez/common/composable/feed/FeedEntry.kt b/app/src/main/java/be/ugent/sel/studeez/common/composable/feed/FeedEntry.kt index 6dce710..76c9075 100644 --- a/app/src/main/java/be/ugent/sel/studeez/common/composable/feed/FeedEntry.kt +++ b/app/src/main/java/be/ugent/sel/studeez/common/composable/feed/FeedEntry.kt @@ -4,7 +4,10 @@ import androidx.compose.foundation.background import androidx.compose.foundation.layout.* 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.Info import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -16,6 +19,7 @@ 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.common.ext.fieldModifier import be.ugent.sel.studeez.data.local.models.FeedEntry import be.ugent.sel.studeez.data.local.models.timer_functional.HoursMinutesSeconds @@ -69,13 +73,20 @@ fun FeedEntry( Text(text = HoursMinutesSeconds(feedEntry.totalStudyTime).toString()) } } - StealthButton( - text = R.string.continue_task, - modifier = Modifier - .padding(start = 10.dp, end = 5.dp) - .weight(6f) - ) { - continueWithTask() + if (!feedEntry.isArchived) { + StealthButton( + text = R.string.continue_task, + modifier = Modifier + .padding(start = 10.dp, end = 5.dp) + .weight(6f) + ) { + continueWithTask() + } + } else { + Row { + Icon(imageVector = Icons.Default.Info, contentDescription = null) + Text(text = "Deleted", modifier = Modifier.padding(horizontal = 5.dp)) + } } } } diff --git a/app/src/main/java/be/ugent/sel/studeez/data/local/models/FeedEntry.kt b/app/src/main/java/be/ugent/sel/studeez/data/local/models/FeedEntry.kt index e24cd24..8733c48 100644 --- a/app/src/main/java/be/ugent/sel/studeez/data/local/models/FeedEntry.kt +++ b/app/src/main/java/be/ugent/sel/studeez/data/local/models/FeedEntry.kt @@ -9,5 +9,6 @@ data class FeedEntry( val taskId: String = "", // Name of task is not unique val subjectId: String = "", val totalStudyTime: Int = 0, - val endTime: Timestamp = Timestamp(0, 0) + val endTime: Timestamp = Timestamp(0, 0), + val isArchived: Boolean = false ) diff --git a/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FirebaseFeedDAO.kt b/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FirebaseFeedDAO.kt index c116fbf..88142fb 100644 --- a/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FirebaseFeedDAO.kt +++ b/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FirebaseFeedDAO.kt @@ -72,7 +72,8 @@ class FirebaseFeedDAO @Inject constructor( taskId = task.id, subjectId = subject.id, totalStudyTime = sessionReport.studyTime, - endTime = sessionReport.endTime + endTime = sessionReport.endTime, + isArchived = task.completed ) } } \ No newline at end of file From a5b98d6bf824110efe31f7d59348da733bcda76b Mon Sep 17 00:00:00 2001 From: brreynie Date: Tue, 9 May 2023 22:38:23 +0200 Subject: [PATCH 12/20] move new-task button to top --- .../be/ugent/sel/studeez/data/local/models/task/Task.kt | 6 +----- .../java/be/ugent/sel/studeez/screens/tasks/TaskScreen.kt | 2 +- 2 files changed, 2 insertions(+), 6 deletions(-) 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 e42ce5d..ff2748d 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,11 +9,7 @@ data class Task( val time: Int = 0, val subjectId: String = "", var archived: Boolean = false, -) { - fun archive() { - this.archived = true - } -} +) object TaskDocument { const val id = "id" 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 7760d84..acdb64b 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 @@ -71,6 +71,7 @@ fun TaskScreen( Column( modifier = Modifier.padding(top = 5.dp) ) { + NewTaskSubjectButton(onClick = taskActions.addTask, AppText.new_task) LazyColumn { items(tasks.value) { TaskEntry( @@ -81,7 +82,6 @@ fun TaskScreen( ) } } - NewTaskSubjectButton(onClick = taskActions.addTask, AppText.new_task) } } } From 7706c2d070af9a9a8e7f24fc29fa0c9afaf2f5d0 Mon Sep 17 00:00:00 2001 From: brreynie Date: Tue, 9 May 2023 22:44:08 +0200 Subject: [PATCH 13/20] #22 sort tasks by completed --- .../be/ugent/sel/studeez/screens/tasks/TaskScreen.kt | 10 +++++++++- 1 file changed, 9 insertions(+), 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 acdb64b..516b836 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 @@ -73,7 +73,15 @@ fun TaskScreen( ) { NewTaskSubjectButton(onClick = taskActions.addTask, AppText.new_task) LazyColumn { - items(tasks.value) { + items(tasks.value.filter { !it.completed }) { + TaskEntry( + task = it, + onCheckTask = { isChecked -> taskActions.onCheckTask(it, isChecked) }, + onArchiveTask = { taskActions.archiveTask(it) }, + onStartTask = { taskActions.startTask(it) } + ) + } + items(tasks.value.filter { it.completed }) { TaskEntry( task = it, onCheckTask = { isChecked -> taskActions.onCheckTask(it, isChecked) }, From 875732fd2dd0604917742e496720c4619f9f888f Mon Sep 17 00:00:00 2001 From: lbarraga Date: Tue, 9 May 2023 23:12:52 +0200 Subject: [PATCH 14/20] changed stealthbutton to blue + disbale feed continue when task or subject is archived --- .../common/composable/ButtonComposable.kt | 12 +++++++-- .../common/composable/feed/FeedEntry.kt | 27 ++++++++----------- .../sel/studeez/common/ext/ModifierExt.kt | 11 ++++++++ .../domain/implementation/FirebaseFeedDAO.kt | 2 +- 4 files changed, 33 insertions(+), 19 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 0ba2ffe..c96994d 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,6 +2,7 @@ package be.ugent.sel.studeez.common.composable import androidx.annotation.StringRes import androidx.compose.foundation.BorderStroke +import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxWidth @@ -49,6 +50,7 @@ fun BasicButton( modifier: Modifier = Modifier, colors: ButtonColors = ButtonDefaults.buttonColors(), border: BorderStroke? = null, + enabled: Boolean = true, onClick: () -> Unit, ) { Button( @@ -57,6 +59,7 @@ fun BasicButton( shape = defaultButtonShape(), colors = colors, border = border, + enabled = enabled, ) { Text( text = stringResource(text), @@ -75,17 +78,22 @@ fun BasicButtonPreview() { fun StealthButton( @StringRes text: Int, modifier: Modifier = Modifier.card(), + enabled: Boolean = true, onClick: () -> Unit, ) { + //val clickablemodifier = if (disabled) Modifier.clickable(indication = null) else modifier + val borderColor = if (enabled) MaterialTheme.colors.primary + else MaterialTheme.colors.onSurface.copy(alpha = 0.3f) BasicButton( text = text, onClick = onClick, modifier = modifier, + enabled = enabled, colors = ButtonDefaults.buttonColors( backgroundColor = MaterialTheme.colors.surface, - contentColor = MaterialTheme.colors.onSurface.copy(alpha = 0.4f) + contentColor = borderColor ), - border = BorderStroke(2.dp, MaterialTheme.colors.onSurface.copy(alpha = 0.4f)) + border = BorderStroke(2.dp, borderColor) ) } diff --git a/app/src/main/java/be/ugent/sel/studeez/common/composable/feed/FeedEntry.kt b/app/src/main/java/be/ugent/sel/studeez/common/composable/feed/FeedEntry.kt index 76c9075..179a9c0 100644 --- a/app/src/main/java/be/ugent/sel/studeez/common/composable/feed/FeedEntry.kt +++ b/app/src/main/java/be/ugent/sel/studeez/common/composable/feed/FeedEntry.kt @@ -4,10 +4,7 @@ import androidx.compose.foundation.background import androidx.compose.foundation.layout.* 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.Info import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -19,9 +16,9 @@ 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.common.ext.fieldModifier import be.ugent.sel.studeez.data.local.models.FeedEntry import be.ugent.sel.studeez.data.local.models.timer_functional.HoursMinutesSeconds +import be.ugent.sel.studeez.R.string as AppText @Composable fun FeedEntry( @@ -73,21 +70,19 @@ fun FeedEntry( Text(text = HoursMinutesSeconds(feedEntry.totalStudyTime).toString()) } } - if (!feedEntry.isArchived) { - StealthButton( - text = R.string.continue_task, - modifier = Modifier - .padding(start = 10.dp, end = 5.dp) - .weight(6f) - ) { + val buttonText: Int = if (feedEntry.isArchived) AppText.deleted else AppText.continue_task + StealthButton( + text = buttonText, + enabled = !feedEntry.isArchived, + modifier = Modifier + .padding(start = 10.dp, end = 5.dp) + .weight(6f) + ) { + if (!feedEntry.isArchived) { continueWithTask() } - } else { - Row { - Icon(imageVector = Icons.Default.Info, contentDescription = null) - Text(text = "Deleted", modifier = Modifier.padding(horizontal = 5.dp)) - } } + } } } diff --git a/app/src/main/java/be/ugent/sel/studeez/common/ext/ModifierExt.kt b/app/src/main/java/be/ugent/sel/studeez/common/ext/ModifierExt.kt index 7280ab3..8c96232 100644 --- a/app/src/main/java/be/ugent/sel/studeez/common/ext/ModifierExt.kt +++ b/app/src/main/java/be/ugent/sel/studeez/common/ext/ModifierExt.kt @@ -1,14 +1,25 @@ package be.ugent.sel.studeez.common.ext +import androidx.compose.foundation.clickable +import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.layout.* +import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.composed import androidx.compose.ui.unit.dp fun Modifier.textButton(): Modifier { return this.fillMaxWidth().padding(16.dp, 8.dp, 16.dp, 0.dp) } +fun Modifier.noRippleClickable(onClick: () -> Unit): Modifier = composed { + clickable(indication = null, + interactionSource = remember { MutableInteractionSource() }) { + onClick() + } +} + fun Modifier.basicButton(): Modifier { return this.fillMaxWidth().padding(16.dp, 8.dp) } diff --git a/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FirebaseFeedDAO.kt b/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FirebaseFeedDAO.kt index b46b9d0..6c445bf 100644 --- a/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FirebaseFeedDAO.kt +++ b/app/src/main/java/be/ugent/sel/studeez/domain/implementation/FirebaseFeedDAO.kt @@ -75,7 +75,7 @@ class FirebaseFeedDAO @Inject constructor( subjectId = subject.id, totalStudyTime = sessionReport.studyTime, endTime = sessionReport.endTime, - isArchived = task.completed + isArchived = task.archived || subject.archived ) } } \ No newline at end of file From 43ccab6d083812a674fe3898dc372aad6212812b Mon Sep 17 00:00:00 2001 From: brreynie Date: Tue, 9 May 2023 23:20:24 +0200 Subject: [PATCH 15/20] fix missing rescource string --- app/src/main/res/values/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index d58be52..e5ed407 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -31,6 +31,7 @@ Continue + Deleted This is your feed Create you first subject and tasks to get started From 08b86c15dd12861a8dfa602daa863c8c10ae85e5 Mon Sep 17 00:00:00 2001 From: brreynie Date: Tue, 9 May 2023 23:23:11 +0200 Subject: [PATCH 16/20] fix hint not very clear --- app/src/main/res/values/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index e5ed407..70c4558 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -33,7 +33,7 @@ Continue Deleted This is your feed - Create you first subject and tasks to get started + Click here to create you first subject and tasks to get started Tasks From 25ed3dfdd22a783f39463db3820cde5cb7c5a1d0 Mon Sep 17 00:00:00 2001 From: brreynie Date: Tue, 9 May 2023 23:25:39 +0200 Subject: [PATCH 17/20] add feedentry overflow preview -> needs fixing --- .../common/composable/feed/FeedEntry.kt | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/be/ugent/sel/studeez/common/composable/feed/FeedEntry.kt b/app/src/main/java/be/ugent/sel/studeez/common/composable/feed/FeedEntry.kt index 179a9c0..ff950d6 100644 --- a/app/src/main/java/be/ugent/sel/studeez/common/composable/feed/FeedEntry.kt +++ b/app/src/main/java/be/ugent/sel/studeez/common/composable/feed/FeedEntry.kt @@ -14,7 +14,6 @@ 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.FeedEntry import be.ugent.sel.studeez.data.local.models.timer_functional.HoursMinutesSeconds @@ -70,7 +69,8 @@ fun FeedEntry( Text(text = HoursMinutesSeconds(feedEntry.totalStudyTime).toString()) } } - val buttonText: Int = if (feedEntry.isArchived) AppText.deleted else AppText.continue_task + val buttonText: Int = + if (feedEntry.isArchived) AppText.deleted else AppText.continue_task StealthButton( text = buttonText, enabled = !feedEntry.isArchived, @@ -90,6 +90,20 @@ fun FeedEntry( @Preview @Composable fun FeedEntryPreview() { + FeedEntry( + continueWithTask = {}, + feedEntry = FeedEntry( + argb_color = 0xFFFFD200, + subJectName = "Test Subject", + taskName = "Test Task", + totalStudyTime = 20, + ) + ) +} + +@Preview +@Composable +fun FeedEntryOverflowPreview() { FeedEntry( continueWithTask = {}, feedEntry = FeedEntry( From 3c1bc9bb1b6024b770636a7c573e826f3261fc1b Mon Sep 17 00:00:00 2001 From: brreynie Date: Tue, 9 May 2023 23:51:05 +0200 Subject: [PATCH 18/20] refactored all states to communicate between viewmodels --- .../ugent/sel/studeez/data/EditTimerState.kt | 11 ----- .../ugent/sel/studeez/data/SelectedState.kt | 45 +++++++++++++++++++ .../ugent/sel/studeez/data/SelectedSubject.kt | 20 --------- .../be/ugent/sel/studeez/data/SelectedTask.kt | 21 --------- .../sel/studeez/data/SelectedTimerState.kt | 14 ------ .../sel/studeez/data/SessionReportState.kt | 14 ------ .../screens/session/SessionViewModel.kt | 20 ++++----- .../session_recap/SessionRecapViewModel.kt | 11 +++-- .../screens/timer_form/TimerFormViewModel.kt | 9 ++-- .../TimerTypeSelectViewModel.kt | 6 +-- .../timer_overview/TimerOverviewViewModel.kt | 12 ++--- .../TimerSelectionViewModel.kt | 10 ++--- .../InvisibleSessionManagerTest.kt | 10 ++--- 13 files changed, 78 insertions(+), 125 deletions(-) delete mode 100644 app/src/main/java/be/ugent/sel/studeez/data/EditTimerState.kt create mode 100644 app/src/main/java/be/ugent/sel/studeez/data/SelectedState.kt delete mode 100644 app/src/main/java/be/ugent/sel/studeez/data/SelectedSubject.kt delete mode 100644 app/src/main/java/be/ugent/sel/studeez/data/SelectedTask.kt delete mode 100644 app/src/main/java/be/ugent/sel/studeez/data/SelectedTimerState.kt delete mode 100644 app/src/main/java/be/ugent/sel/studeez/data/SessionReportState.kt diff --git a/app/src/main/java/be/ugent/sel/studeez/data/EditTimerState.kt b/app/src/main/java/be/ugent/sel/studeez/data/EditTimerState.kt deleted file mode 100644 index dceec8c..0000000 --- a/app/src/main/java/be/ugent/sel/studeez/data/EditTimerState.kt +++ /dev/null @@ -1,11 +0,0 @@ -package be.ugent.sel.studeez.data - -import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalTimer -import be.ugent.sel.studeez.data.local.models.timer_info.TimerInfo -import javax.inject.Inject -import javax.inject.Singleton - -@Singleton -class EditTimerState @Inject constructor(){ - lateinit var timerInfo: TimerInfo -} \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/data/SelectedState.kt b/app/src/main/java/be/ugent/sel/studeez/data/SelectedState.kt new file mode 100644 index 0000000..c52939f --- /dev/null +++ b/app/src/main/java/be/ugent/sel/studeez/data/SelectedState.kt @@ -0,0 +1,45 @@ +package be.ugent.sel.studeez.data + +import be.ugent.sel.studeez.data.local.models.SessionReport +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.timer_functional.FunctionalTimer +import be.ugent.sel.studeez.data.local.models.timer_info.TimerInfo +import javax.inject.Inject +import javax.inject.Singleton + +/** + * Used to cummunicate between viewmodels. + */ +abstract class SelectedState { + abstract var value: T + operator fun invoke() = value + fun set(newValue: T) { + this.value = newValue + } +} + +@Singleton +class SelectedSessionReport @Inject constructor() : SelectedState() { + override lateinit var value: SessionReport +} + +@Singleton +class SelectedTask @Inject constructor() : SelectedState() { + override lateinit var value: Task +} + +@Singleton +class SelectedTimer @Inject constructor() : SelectedState() { + override lateinit var value: FunctionalTimer +} + +@Singleton +class SelectedSubject @Inject constructor() : SelectedState() { + override lateinit var value: Subject +} + +@Singleton +class SelectedTimerInfo @Inject constructor() : SelectedState() { + override lateinit var value: TimerInfo +} \ No newline at end of file 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 deleted file mode 100644 index fbc7e48..0000000 --- a/app/src/main/java/be/ugent/sel/studeez/data/SelectedSubject.kt +++ /dev/null @@ -1,20 +0,0 @@ -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 other screens. - * 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 - } - - 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 deleted file mode 100644 index 9c3f042..0000000 --- a/app/src/main/java/be/ugent/sel/studeez/data/SelectedTask.kt +++ /dev/null @@ -1,21 +0,0 @@ -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/data/SelectedTimerState.kt b/app/src/main/java/be/ugent/sel/studeez/data/SelectedTimerState.kt deleted file mode 100644 index f8fcebd..0000000 --- a/app/src/main/java/be/ugent/sel/studeez/data/SelectedTimerState.kt +++ /dev/null @@ -1,14 +0,0 @@ -package be.ugent.sel.studeez.data - -import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalTimer -import javax.inject.Inject -import javax.inject.Singleton - -/** - * Used to communicate the SelectedTimer from the selection screen to the session screen. - * Because this is a singleton-class the view-models of both screens observe the same data. - */ -@Singleton -class SelectedTimerState @Inject constructor(){ - var selectedTimer: FunctionalTimer? = null -} \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/data/SessionReportState.kt b/app/src/main/java/be/ugent/sel/studeez/data/SessionReportState.kt deleted file mode 100644 index 47770d0..0000000 --- a/app/src/main/java/be/ugent/sel/studeez/data/SessionReportState.kt +++ /dev/null @@ -1,14 +0,0 @@ -package be.ugent.sel.studeez.data - -import be.ugent.sel.studeez.data.local.models.SessionReport -import javax.inject.Inject -import javax.inject.Singleton - -/** - * Used to communicate the SelectedTimer from the selection screen to the session screen. - * Because this is a singleton-class the view-models of both screens observe the same data. - */ -@Singleton -class SessionReportState @Inject constructor(){ - var sessionReport: SessionReport? = null -} \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/session/SessionViewModel.kt b/app/src/main/java/be/ugent/sel/studeez/screens/session/SessionViewModel.kt index cd4c93a..0be4147 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/session/SessionViewModel.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/session/SessionViewModel.kt @@ -1,9 +1,8 @@ package be.ugent.sel.studeez.screens.session +import be.ugent.sel.studeez.data.SelectedSessionReport import be.ugent.sel.studeez.data.SelectedTask -import be.ugent.sel.studeez.data.SelectedTimerState -import be.ugent.sel.studeez.data.SessionReportState -import be.ugent.sel.studeez.data.local.models.task.Task +import be.ugent.sel.studeez.data.SelectedTimer import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalTimer import be.ugent.sel.studeez.domain.LogService import be.ugent.sel.studeez.navigation.StudeezDestinations @@ -13,24 +12,21 @@ import javax.inject.Inject @HiltViewModel class SessionViewModel @Inject constructor( - private val selectedTimerState: SelectedTimerState, - private val sessionReportState: SessionReportState, + private val selectedTimer: SelectedTimer, + private val sessionReport: SelectedSessionReport, private val selectedTask: SelectedTask, logService: LogService ) : StudeezViewModel(logService) { - - private val task : Task = selectedTask() - - fun getTimer() : FunctionalTimer { - return selectedTimerState.selectedTimer!! + fun getTimer(): FunctionalTimer { + return selectedTimer() } fun getTask(): String { - return task.name + return selectedTask().name } fun endSession(openAndPopUp: (String, String) -> Unit) { - sessionReportState.sessionReport = getTimer().getSessionReport(task.subjectId, task.id) + sessionReport.set(getTimer().getSessionReport(selectedTask().subjectId, selectedTask().id)) openAndPopUp(StudeezDestinations.SESSION_RECAP, StudeezDestinations.SESSION_SCREEN) } } \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/session_recap/SessionRecapViewModel.kt b/app/src/main/java/be/ugent/sel/studeez/screens/session_recap/SessionRecapViewModel.kt index 5fdd95c..c11e28f 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/session_recap/SessionRecapViewModel.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/session_recap/SessionRecapViewModel.kt @@ -1,7 +1,7 @@ package be.ugent.sel.studeez.screens.session_recap +import be.ugent.sel.studeez.data.SelectedSessionReport import be.ugent.sel.studeez.data.SelectedTask -import be.ugent.sel.studeez.data.SessionReportState import be.ugent.sel.studeez.data.local.models.SessionReport import be.ugent.sel.studeez.domain.LogService import be.ugent.sel.studeez.domain.SessionDAO @@ -13,22 +13,21 @@ import javax.inject.Inject @HiltViewModel class SessionRecapViewModel @Inject constructor( - sessionReportState: SessionReportState, + private val selectedSessionReport: SelectedSessionReport, private val sessionDAO: SessionDAO, private val taskDAO: TaskDAO, private val selectedTask: SelectedTask, logService: LogService ) : StudeezViewModel(logService) { - private val report: SessionReport = sessionReportState.sessionReport!! - fun getSessionReport(): SessionReport { - return report + return selectedSessionReport() } fun saveSession(open: (String, String) -> Unit) { sessionDAO.saveSession(getSessionReport()) - val newTask = selectedTask().copy(time = selectedTask().time + report.studyTime) + val newTask = + selectedTask().copy(time = selectedTask().time + selectedSessionReport().studyTime) taskDAO.updateTask(newTask) open(StudeezDestinations.HOME_SCREEN, StudeezDestinations.SESSION_RECAP) } diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/timer_form/TimerFormViewModel.kt b/app/src/main/java/be/ugent/sel/studeez/screens/timer_form/TimerFormViewModel.kt index 4c2079c..8a0a4d4 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/timer_form/TimerFormViewModel.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/timer_form/TimerFormViewModel.kt @@ -1,6 +1,6 @@ package be.ugent.sel.studeez.screens.timer_form -import be.ugent.sel.studeez.data.EditTimerState +import be.ugent.sel.studeez.data.SelectedTimerInfo import be.ugent.sel.studeez.data.local.models.timer_info.TimerInfo import be.ugent.sel.studeez.domain.LogService import be.ugent.sel.studeez.domain.TimerDAO @@ -10,15 +10,12 @@ import javax.inject.Inject @HiltViewModel class TimerFormViewModel @Inject constructor( - private val editTimerState: EditTimerState, + private val selectedTimerInfo: SelectedTimerInfo, private val timerDAO: TimerDAO, logService: LogService ) : StudeezViewModel(logService) { - - private val timerInfo: TimerInfo = editTimerState.timerInfo - fun getTimerInfo(): TimerInfo { - return timerInfo + return selectedTimerInfo() } fun editTimer(timerInfo: TimerInfo, goBack: () -> Unit) { diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/timer_form/timer_type_select/TimerTypeSelectViewModel.kt b/app/src/main/java/be/ugent/sel/studeez/screens/timer_form/timer_type_select/TimerTypeSelectViewModel.kt index 569a36c..c3ed2c4 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/timer_form/timer_type_select/TimerTypeSelectViewModel.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/timer_form/timer_type_select/TimerTypeSelectViewModel.kt @@ -1,6 +1,6 @@ package be.ugent.sel.studeez.screens.timer_form.timer_type_select -import be.ugent.sel.studeez.data.EditTimerState +import be.ugent.sel.studeez.data.SelectedTimerInfo import be.ugent.sel.studeez.data.local.models.timer_info.TimerInfo import be.ugent.sel.studeez.domain.LogService import be.ugent.sel.studeez.navigation.StudeezDestinations @@ -10,13 +10,13 @@ import javax.inject.Inject @HiltViewModel class TimerTypeSelectViewModel @Inject constructor( - private val editTimerState: EditTimerState, + private val selectedTimerInfo: SelectedTimerInfo, logService: LogService ) : StudeezViewModel(logService) { fun onTimerTypeChosen(timerInfo: TimerInfo, open: (String) -> Unit) { - editTimerState.timerInfo = timerInfo + selectedTimerInfo.set(timerInfo) open(StudeezDestinations.ADD_TIMER_SCREEN) } } \ No newline at end of file diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/timer_overview/TimerOverviewViewModel.kt b/app/src/main/java/be/ugent/sel/studeez/screens/timer_overview/TimerOverviewViewModel.kt index 3e10053..395a155 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/timer_overview/TimerOverviewViewModel.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/timer_overview/TimerOverviewViewModel.kt @@ -1,6 +1,6 @@ package be.ugent.sel.studeez.screens.timer_overview -import be.ugent.sel.studeez.data.EditTimerState +import be.ugent.sel.studeez.data.SelectedTimerInfo import be.ugent.sel.studeez.data.local.models.timer_info.TimerInfo import be.ugent.sel.studeez.domain.ConfigurationService import be.ugent.sel.studeez.domain.LogService @@ -15,11 +15,11 @@ import javax.inject.Inject class TimerOverviewViewModel @Inject constructor( private val configurationService: ConfigurationService, private val timerDAO: TimerDAO, - private val editTimerState: EditTimerState, + private val selectedTimerInfo: SelectedTimerInfo, logService: LogService ) : StudeezViewModel(logService) { - fun getUserTimers() : Flow> { + fun getUserTimers(): Flow> { return timerDAO.getUserTimers() } @@ -27,8 +27,8 @@ class TimerOverviewViewModel @Inject constructor( return configurationService.getDefaultTimers() } - fun update(timerInfo: TimerInfo, open: (String) -> Unit) { - editTimerState.timerInfo = timerInfo + fun update(timerInfo: TimerInfo, open: (String) -> Unit) { + selectedTimerInfo.set(timerInfo) open(StudeezDestinations.TIMER_EDIT_SCREEN) } @@ -36,7 +36,7 @@ class TimerOverviewViewModel @Inject constructor( open(StudeezDestinations.TIMER_TYPE_CHOOSING_SCREEN) } - fun delete(timerInfo: TimerInfo) =timerDAO.deleteTimer(timerInfo) + fun delete(timerInfo: TimerInfo) = timerDAO.deleteTimer(timerInfo) fun save(timerInfo: TimerInfo) = timerDAO.saveTimer(timerInfo) diff --git a/app/src/main/java/be/ugent/sel/studeez/screens/timer_selection/TimerSelectionViewModel.kt b/app/src/main/java/be/ugent/sel/studeez/screens/timer_selection/TimerSelectionViewModel.kt index a4f646d..c6c6793 100644 --- a/app/src/main/java/be/ugent/sel/studeez/screens/timer_selection/TimerSelectionViewModel.kt +++ b/app/src/main/java/be/ugent/sel/studeez/screens/timer_selection/TimerSelectionViewModel.kt @@ -1,10 +1,8 @@ package be.ugent.sel.studeez.screens.timer_selection import androidx.compose.runtime.MutableState -import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember -import be.ugent.sel.studeez.data.SelectedTimerState +import be.ugent.sel.studeez.data.SelectedTimer import be.ugent.sel.studeez.data.local.models.timer_functional.HoursMinutesSeconds import be.ugent.sel.studeez.data.local.models.timer_info.TimerInfo import be.ugent.sel.studeez.domain.LogService @@ -18,7 +16,7 @@ import javax.inject.Inject @HiltViewModel class TimerSelectionViewModel @Inject constructor( private val timerDAO: TimerDAO, - private val selectedTimerState: SelectedTimerState, + private val selectedTimer: SelectedTimer, logService: LogService ) : StudeezViewModel(logService) { @@ -26,12 +24,12 @@ class TimerSelectionViewModel @Inject constructor( HoursMinutesSeconds(1, 0, 0).getTotalSeconds() ) - fun getAllTimers() : Flow> { + fun getAllTimers(): Flow> { return timerDAO.getAllTimers() } fun startSession(open: (String) -> Unit, timerInfo: TimerInfo) { - selectedTimerState.selectedTimer = timerInfo.getFunctionalTimer() + selectedTimer.set(timerInfo.getFunctionalTimer()) open(StudeezDestinations.SESSION_SCREEN) } } \ No newline at end of file diff --git a/app/src/test/java/be/ugent/sel/studeez/timer_functional/InvisibleSessionManagerTest.kt b/app/src/test/java/be/ugent/sel/studeez/timer_functional/InvisibleSessionManagerTest.kt index f9e34c3..12b6799 100644 --- a/app/src/test/java/be/ugent/sel/studeez/timer_functional/InvisibleSessionManagerTest.kt +++ b/app/src/test/java/be/ugent/sel/studeez/timer_functional/InvisibleSessionManagerTest.kt @@ -1,8 +1,6 @@ package be.ugent.sel.studeez.timer_functional import android.media.MediaPlayer -import be.ugent.sel.studeez.data.SelectedTimerState -import be.ugent.sel.studeez.data.SessionReportState import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalCustomTimer import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalEndlessTimer import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalPomodoroTimer @@ -18,14 +16,14 @@ import org.mockito.kotlin.mock @ExperimentalCoroutinesApi class InvisibleSessionManagerTest { - private var timerState: SelectedTimerState = SelectedTimerState() + private var timerState: SelectedTimer = SelectedTimer() private lateinit var viewModel: SessionViewModel private var mediaPlayer: MediaPlayer = mock() @Test fun InvisibleEndlessTimerTest() = runTest { timerState.selectedTimer = FunctionalEndlessTimer() - viewModel = SessionViewModel(timerState, SessionReportState(), mock()) + viewModel = SessionViewModel(timerState, SessionReport(), mock()) InvisibleSessionManager.setParameters(viewModel, mediaPlayer) val test = launch { @@ -47,7 +45,7 @@ class InvisibleSessionManagerTest { val breakTime = 5 val repeats = 1 timerState.selectedTimer = FunctionalPomodoroTimer(studyTime, breakTime, repeats) - viewModel = SessionViewModel(timerState, SessionReportState(), mock()) + viewModel = SessionViewModel(timerState, SessionReport(), mock()) InvisibleSessionManager.setParameters(viewModel, mediaPlayer) val test = launch { @@ -80,7 +78,7 @@ class InvisibleSessionManagerTest { @Test fun InvisibleCustomTimerTest() = runTest { timerState.selectedTimer = FunctionalCustomTimer(5) - viewModel = SessionViewModel(timerState, SessionReportState(), mock()) + viewModel = SessionViewModel(timerState, SessionReport(), mock()) InvisibleSessionManager.setParameters(viewModel, mediaPlayer) val test = launch { From efd92ce832d23d7bd18eb7fcf3119758a9f8a039 Mon Sep 17 00:00:00 2001 From: brreynie Date: Wed, 10 May 2023 09:59:17 +0200 Subject: [PATCH 19/20] fix tests unable to compile --- .../InvisibleSessionManagerTest.kt | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/app/src/test/java/be/ugent/sel/studeez/timer_functional/InvisibleSessionManagerTest.kt b/app/src/test/java/be/ugent/sel/studeez/timer_functional/InvisibleSessionManagerTest.kt index 12b6799..54f673d 100644 --- a/app/src/test/java/be/ugent/sel/studeez/timer_functional/InvisibleSessionManagerTest.kt +++ b/app/src/test/java/be/ugent/sel/studeez/timer_functional/InvisibleSessionManagerTest.kt @@ -1,9 +1,13 @@ package be.ugent.sel.studeez.timer_functional import android.media.MediaPlayer +import be.ugent.sel.studeez.data.SelectedSessionReport +import be.ugent.sel.studeez.data.SelectedTimer import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalCustomTimer import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalEndlessTimer import be.ugent.sel.studeez.data.local.models.timer_functional.FunctionalPomodoroTimer +import be.ugent.sel.studeez.domain.LogService +import be.ugent.sel.studeez.domain.implementation.LogServiceImpl import be.ugent.sel.studeez.screens.session.InvisibleSessionManager import be.ugent.sel.studeez.screens.session.SessionViewModel import kotlinx.coroutines.ExperimentalCoroutinesApi @@ -16,14 +20,14 @@ import org.mockito.kotlin.mock @ExperimentalCoroutinesApi class InvisibleSessionManagerTest { - private var timerState: SelectedTimer = SelectedTimer() + private var selectedTimer: SelectedTimer = SelectedTimer() private lateinit var viewModel: SessionViewModel private var mediaPlayer: MediaPlayer = mock() @Test fun InvisibleEndlessTimerTest() = runTest { - timerState.selectedTimer = FunctionalEndlessTimer() - viewModel = SessionViewModel(timerState, SessionReport(), mock()) + selectedTimer.set(FunctionalEndlessTimer()) + viewModel = SessionViewModel(selectedTimer, SelectedSessionReport(), mock(), LogServiceImpl()) InvisibleSessionManager.setParameters(viewModel, mediaPlayer) val test = launch { @@ -44,8 +48,8 @@ class InvisibleSessionManagerTest { val studyTime = 10 val breakTime = 5 val repeats = 1 - timerState.selectedTimer = FunctionalPomodoroTimer(studyTime, breakTime, repeats) - viewModel = SessionViewModel(timerState, SessionReport(), mock()) + selectedTimer.set(FunctionalPomodoroTimer(studyTime, breakTime, repeats)) + viewModel = SessionViewModel(selectedTimer, SelectedSessionReport(), mock(), LogServiceImpl()) InvisibleSessionManager.setParameters(viewModel, mediaPlayer) val test = launch { @@ -77,8 +81,8 @@ class InvisibleSessionManagerTest { @Test fun InvisibleCustomTimerTest() = runTest { - timerState.selectedTimer = FunctionalCustomTimer(5) - viewModel = SessionViewModel(timerState, SessionReport(), mock()) + selectedTimer.set(FunctionalCustomTimer(5)) + viewModel = SessionViewModel(selectedTimer, SelectedSessionReport(), mock(), LogServiceImpl()) InvisibleSessionManager.setParameters(viewModel, mediaPlayer) val test = launch { From 59044658e6e3b3a60c4c9ed71732bd9875760d68 Mon Sep 17 00:00:00 2001 From: brreynie Date: Wed, 10 May 2023 10:27:08 +0200 Subject: [PATCH 20/20] Update app/src/main/java/be/ugent/sel/studeez/common/ext/ModifierExt.kt Co-authored-by: lbarraga --- .../java/be/ugent/sel/studeez/common/ext/ModifierExt.kt | 7 ------- 1 file changed, 7 deletions(-) diff --git a/app/src/main/java/be/ugent/sel/studeez/common/ext/ModifierExt.kt b/app/src/main/java/be/ugent/sel/studeez/common/ext/ModifierExt.kt index 8c96232..66ade69 100644 --- a/app/src/main/java/be/ugent/sel/studeez/common/ext/ModifierExt.kt +++ b/app/src/main/java/be/ugent/sel/studeez/common/ext/ModifierExt.kt @@ -13,13 +13,6 @@ fun Modifier.textButton(): Modifier { return this.fillMaxWidth().padding(16.dp, 8.dp, 16.dp, 0.dp) } -fun Modifier.noRippleClickable(onClick: () -> Unit): Modifier = composed { - clickable(indication = null, - interactionSource = remember { MutableInteractionSource() }) { - onClick() - } -} - fun Modifier.basicButton(): Modifier { return this.fillMaxWidth().padding(16.dp, 8.dp) }