show #tasks and #completedTasks in subject entry

This commit is contained in:
brreynie 2023-05-09 15:30:37 +02:00
parent 366f236f98
commit 5f8b7d7a7b
8 changed files with 57 additions and 21 deletions

View file

@ -1,13 +1,7 @@
package be.ugent.sel.studeez.common.composable.tasks package be.ugent.sel.studeez.common.composable.tasks
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.*
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.shape.CircleShape import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material.Card import androidx.compose.material.Card
import androidx.compose.material.Icon import androidx.compose.material.Icon
@ -24,10 +18,10 @@ import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp 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.common.composable.StealthButton
import be.ugent.sel.studeez.data.local.models.task.Subject import be.ugent.sel.studeez.data.local.models.task.Subject
import be.ugent.sel.studeez.data.local.models.timer_functional.HoursMinutesSeconds import be.ugent.sel.studeez.data.local.models.timer_functional.HoursMinutesSeconds
import be.ugent.sel.studeez.R.string as AppText
@Composable @Composable
fun SubjectEntry( fun SubjectEntry(
@ -80,7 +74,7 @@ fun SubjectEntry(
imageVector = Icons.Default.List, imageVector = Icons.Default.List,
contentDescription = stringResource(id = AppText.tasks) 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( subject = Subject(
name = "Test Subject", name = "Test Subject",
argb_color = 0xFFFFD200, argb_color = 0xFFFFD200,
time = 60 time = 60,
taskCount = 5,
taskCompletedCount = 2,
), ),
) {} ) {}
} }
@ -116,7 +112,7 @@ fun OverflowSubjectEntryPreview() {
subject = Subject( subject = Subject(
name = "Testttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt", name = "Testttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt",
argb_color = 0xFFFFD200, argb_color = 0xFFFFD200,
time = 60 time = 60,
), ),
) {} ) {}
} }

View file

@ -1,10 +1,15 @@
package be.ugent.sel.studeez.data.local.models.task package be.ugent.sel.studeez.data.local.models.task
import com.google.firebase.firestore.DocumentId import com.google.firebase.firestore.DocumentId
import com.google.firebase.firestore.Exclude
data class Subject( data class Subject(
@DocumentId val id: String = "", @DocumentId val id: String = "",
val name: String = "", val name: String = "",
val time: Int = 0, val time: Int = 0,
val argb_color: Long = 0, val argb_color: Long = 0,
@get:Exclude @set:Exclude
var taskCount: Int = 0,
@get:Exclude @set:Exclude
var taskCompletedCount: Int = 0,
) )

View file

@ -8,6 +8,7 @@ data class Task(
val completed: Boolean = false, val completed: Boolean = false,
val time: Int = 0, val time: Int = 0,
val subjectId: String = "", val subjectId: String = "",
val archived: Boolean = false,
) )
object TaskDocument { object TaskDocument {
@ -16,4 +17,5 @@ object TaskDocument {
const val completed = "completed" const val completed = "completed"
const val time = "time" const val time = "time"
const val subjectId = "subjectId" const val subjectId = "subjectId"
const val archived = "archived"
} }

View file

@ -17,4 +17,8 @@ interface TaskDAO {
fun toggleTaskCompleted(task: Task, completed: Boolean) fun toggleTaskCompleted(task: Task, completed: Boolean)
suspend fun getTask(subjectId: String, taskId: String): Task suspend fun getTask(subjectId: String, taskId: String): Task
suspend fun getTaskCount(subject: Subject): Int
suspend fun getCompletedTaskCount(subject: Subject): Int
} }

View file

@ -1,9 +1,9 @@
package be.ugent.sel.studeez.domain.implementation package be.ugent.sel.studeez.domain.implementation
import be.ugent.sel.studeez.data.local.models.task.Subject import be.ugent.sel.studeez.data.local.models.task.Subject
import be.ugent.sel.studeez.data.local.models.task.Task
import be.ugent.sel.studeez.domain.AccountDAO import be.ugent.sel.studeez.domain.AccountDAO
import be.ugent.sel.studeez.domain.SubjectDAO 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.CollectionReference
import com.google.firebase.firestore.FirebaseFirestore import com.google.firebase.firestore.FirebaseFirestore
import com.google.firebase.firestore.ktx.snapshots import com.google.firebase.firestore.ktx.snapshots
@ -16,11 +16,19 @@ import javax.inject.Inject
class FireBaseSubjectDAO @Inject constructor( class FireBaseSubjectDAO @Inject constructor(
private val firestore: FirebaseFirestore, private val firestore: FirebaseFirestore,
private val auth: AccountDAO, private val auth: AccountDAO,
private val taskDAO: TaskDAO,
) : SubjectDAO { ) : SubjectDAO {
override fun getSubjects(): Flow<List<Subject>> { override fun getSubjects(): Flow<List<Subject>> {
return currentUserSubjectsCollection() return currentUserSubjectsCollection()
.snapshots() .snapshots()
.map { it.toObjects(Subject::class.java) } .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? { override suspend fun getSubject(subjectId: String): Subject? {

View file

@ -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.data.local.models.task.TaskDocument
import be.ugent.sel.studeez.domain.AccountDAO import be.ugent.sel.studeez.domain.AccountDAO
import be.ugent.sel.studeez.domain.TaskDAO import be.ugent.sel.studeez.domain.TaskDAO
import com.google.firebase.firestore.AggregateSource
import com.google.firebase.firestore.CollectionReference import com.google.firebase.firestore.CollectionReference
import com.google.firebase.firestore.FirebaseFirestore import com.google.firebase.firestore.FirebaseFirestore
import com.google.firebase.firestore.ktx.snapshots import com.google.firebase.firestore.ktx.snapshots
import com.google.firebase.firestore.ktx.toObject import com.google.firebase.firestore.ktx.toObject
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.map
import kotlinx.coroutines.tasks.await import kotlinx.coroutines.tasks.await
import javax.inject.Inject import javax.inject.Inject
@ -21,6 +21,7 @@ class FireBaseTaskDAO @Inject constructor(
) : TaskDAO { ) : TaskDAO {
override fun getTasks(subject: Subject): Flow<List<Task>> { override fun getTasks(subject: Subject): Flow<List<Task>> {
return selectedSubjectTasksCollection(subject.id) return selectedSubjectTasksCollection(subject.id)
.whereEqualTo(TaskDocument.archived, false)
.snapshots() .snapshots()
.map { it.toObjects(Task::class.java) } .map { it.toObjects(Task::class.java) }
} }
@ -29,6 +30,24 @@ class FireBaseTaskDAO @Inject constructor(
return selectedSubjectTasksCollection(subjectId).document(taskId).get().await().toObject()!! 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) { override fun saveTask(newTask: Task) {
selectedSubjectTasksCollection(newTask.subjectId).add(newTask) selectedSubjectTasksCollection(newTask.subjectId).add(newTask)
} }

View file

@ -7,22 +7,24 @@ import be.ugent.sel.studeez.data.local.models.task.Subject
import be.ugent.sel.studeez.data.local.models.task.Task import be.ugent.sel.studeez.data.local.models.task.Task
import be.ugent.sel.studeez.domain.FeedDAO import be.ugent.sel.studeez.domain.FeedDAO
import be.ugent.sel.studeez.domain.SessionDAO import be.ugent.sel.studeez.domain.SessionDAO
import be.ugent.sel.studeez.domain.SubjectDAO
import be.ugent.sel.studeez.domain.TaskDAO import be.ugent.sel.studeez.domain.TaskDAO
import com.google.firebase.Timestamp import com.google.firebase.Timestamp
import kotlinx.coroutines.flow.* import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import javax.inject.Inject import javax.inject.Inject
class FirebaseFeedDAO @Inject constructor( class FirebaseFeedDAO @Inject constructor(
private val sessionDAO: SessionDAO, private val sessionDAO: SessionDAO,
private val taskDAO: TaskDAO, private val taskDAO: TaskDAO,
private val subjectDAO: FireBaseSubjectDAO private val subjectDAO: SubjectDAO
) : FeedDAO { ) : FeedDAO {
/** /**
* Return a map as with key the day and value a list of feedentries for that day. * Return a map as with key the day and value a list of feedentries for that day.
*/ */
override fun getFeedEntries(): Flow<Map<String, List<FeedEntry>>> { override fun getFeedEntries(): Flow<Map<String, List<FeedEntry>>> {
return sessionDAO.getSessions().map {sessionReports -> return sessionDAO.getSessions().map { sessionReports ->
sessionReports sessionReports
.map { sessionReport -> sessionToFeedEntry(sessionReport) } .map { sessionReport -> sessionToFeedEntry(sessionReport) }
.sortedByDescending { it.endTime } .sortedByDescending { it.endTime }

View file

@ -54,6 +54,7 @@ fun SubjectScreen(
Column( Column(
modifier = Modifier.padding(top = 5.dp) modifier = Modifier.padding(top = 5.dp)
) { ) {
NewTaskSubjectButton(onClick = addSubject, AppText.new_subject)
LazyColumn { LazyColumn {
items(subjects.value) { items(subjects.value) {
SubjectEntry( SubjectEntry(
@ -62,7 +63,6 @@ fun SubjectScreen(
) )
} }
} }
NewTaskSubjectButton(onClick = addSubject, AppText.new_subject)
} }
} }
} }