From 88cd18b8c6e90f46d0e4d5c4e6483f323718c4b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kuba=20Szczodrzy=C5=84ski?= Date: Sat, 1 Feb 2025 21:40:46 +0100 Subject: [PATCH] [UI/Grades] Allow filtering by semester for university grades --- .../usos/data/api/UsosApiExamReports.kt | 6 +-- .../edziennik/ui/grades/GradesListFragment.kt | 40 ++++++++++++++++++- .../main/res/layout/grades_list_fragment.xml | 36 ++++++++++++++--- 3 files changed, 73 insertions(+), 9 deletions(-) diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/usos/data/api/UsosApiExamReports.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/usos/data/api/UsosApiExamReports.kt index 8ad971db..48f461b4 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/usos/data/api/UsosApiExamReports.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/usos/data/api/UsosApiExamReports.kt @@ -137,9 +137,9 @@ class UsosApiExamReports( value = value, weight = if (countsIntoAverage == "T") gradeCategory?.weight ?: 0.0f else 0.0f, color = (if (passes == true) 0xFF465FB3 else 0xFFB71C1C).toInt(), - category = "$termId$$typeDescription", - description = listOfNotNull(classType, sessionDescription).join(" - "), - comment = comment, + category = typeDescription, + description = listOfNotNull(classType, sessionDescription, comment).join(" - "), + comment = termId, semester = 1, teacherId = modificationAuthorId, subjectId = data.getSubject( diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/grades/GradesListFragment.kt b/app/src/main/java/pl/szczodrzynski/edziennik/ui/grades/GradesListFragment.kt index 6abe853c..2a15246e 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/ui/grades/GradesListFragment.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/grades/GradesListFragment.kt @@ -28,6 +28,7 @@ import pl.szczodrzynski.edziennik.ui.grades.models.GradesAverages import pl.szczodrzynski.edziennik.ui.grades.models.GradesSemester import pl.szczodrzynski.edziennik.ui.grades.models.GradesStats import pl.szczodrzynski.edziennik.ui.grades.models.GradesSubject +import pl.szczodrzynski.edziennik.utils.TextInputDropDown import pl.szczodrzynski.edziennik.utils.managers.GradesManager import pl.szczodrzynski.navlib.bottomsheet.items.BottomSheetPrimaryItem import pl.szczodrzynski.navlib.bottomsheet.items.BottomSheetSeparatorItem @@ -85,6 +86,35 @@ class GradesListFragment : Fragment(), CoroutineScope { else -> grades } + if (manager.isUniversity) { + val termIds = grades.map { it.comment }.toSet().toMutableList() + val termNames: MutableMap = mutableMapOf() + // deserialize to a map of termId to (orderKey, termName) + val terms = app.profile.getStudentData("termNames", null) + ?.let { app.gson.fromJson(it, termNames::class.java) } + ?.mapValues { (_, value) -> value.split('$', limit = 2) } + ?.mapValues { (_, value) -> Pair(value[0].toIntOrNull() ?: 0, value[1]) } + ?: mapOf() + // sort by order key + termIds.sortByDescending { termId -> terms[termId]?.first ?: 0 } + // populate the dropdown + b.semesterLayout.isVisible = true + b.semesterDropdown.items = termIds.mapIndexed { id, termId -> + TextInputDropDown.Item( + id.toLong(), + terms[termId]?.second ?: termId ?: "-", + tag = termId, + ) + }.toMutableList() + b.semesterDropdown.select(index = 0) + b.semesterDropdown.setOnChangeListener { item -> + b.semesterDropdown.select(item) + adapter.items = processGrades(items) + adapter.notifyDataSetChanged() + return@setOnChangeListener true + } + } + // load & configure the adapter adapter.items = withContext(Dispatchers.Default) { processGrades(items) } if (items.isNotNullNorEmpty() && b.list.adapter == null) { @@ -188,6 +218,8 @@ class GradesListFragment : Fragment(), CoroutineScope { var semesterNumber = 0 var subject = GradesSubject(subjectId, "") var semester = GradesSemester(0, 1) + val isUniversity = manager.isUniversity + val filterTermId = b.semesterDropdown.selected?.tag val hideImproved = manager.hideImproved @@ -195,6 +227,9 @@ class GradesListFragment : Fragment(), CoroutineScope { // by the subject ID, so it's easier and probably // a bit faster to build all the models for (grade in grades) { + if (isUniversity && filterTermId != null && grade.comment != filterTermId) + continue + /*if (grade.parentId != null && grade.parentId != -1L) continue // the grade is hidden as a new, improved one is available*/ if (grade.subjectId != subjectId) { @@ -265,7 +300,7 @@ class GradesListFragment : Fragment(), CoroutineScope { val stats = GradesStats() - if (manager.isUniversity) { + if (isUniversity) { val semesterSum = mutableListOf() val semesterCount = mutableListOf() val totalSum = mutableListOf() @@ -283,6 +318,9 @@ class GradesListFragment : Fragment(), CoroutineScope { // no points for this subject, simply assign ectsPoints[grade.subjectId] = grade.weight + if (filterTermId != null && grade.comment != filterTermId) + continue + semesterSum.add(grade.value * grade.weight) semesterCount.add(grade.weight) } diff --git a/app/src/main/res/layout/grades_list_fragment.xml b/app/src/main/res/layout/grades_list_fragment.xml index 8427aa8f..d71010e2 100644 --- a/app/src/main/res/layout/grades_list_fragment.xml +++ b/app/src/main/res/layout/grades_list_fragment.xml @@ -37,13 +37,39 @@ app:drawableTopCompat="@drawable/ic_no_grades" tools:visibility="visible" /> - + android:orientation="vertical"> + + + + + + + +