show #tasks and #completedTasks in subject entry
This commit is contained in:
parent
366f236f98
commit
5f8b7d7a7b
8 changed files with 57 additions and 21 deletions
|
@ -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,
|
||||||
),
|
),
|
||||||
) {}
|
) {}
|
||||||
}
|
}
|
|
@ -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,
|
||||||
)
|
)
|
|
@ -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"
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
|
@ -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? {
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 }
|
||||||
|
|
|
@ -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)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Reference in a new issue