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
 | 
			
		||||
 | 
			
		||||
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,
 | 
			
		||||
        ),
 | 
			
		||||
    ) {}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -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,
 | 
			
		||||
)
 | 
			
		||||
    @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 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"
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -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<List<Subject>> {
 | 
			
		||||
        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? {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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<List<Task>> {
 | 
			
		||||
        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)
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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<Map<String, List<FeedEntry>>> {
 | 
			
		||||
        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()) }
 | 
			
		||||
                }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Reference in a new issue