[UI/Grades] Group unknown subjects without specified name.

This commit is contained in:
Kuba Szczodrzyński 2022-03-14 17:05:16 +01:00
parent f8ac9e793a
commit 48b7adb564
No known key found for this signature in database
GPG Key ID: 70CB8A85BA1633CB
11 changed files with 116 additions and 12 deletions

View File

@ -36,6 +36,7 @@ class GradesAdapter(
private const val ITEM_TYPE_EMPTY = 2 private const val ITEM_TYPE_EMPTY = 2
private const val ITEM_TYPE_GRADE = 3 private const val ITEM_TYPE_GRADE = 3
private const val ITEM_TYPE_STATS = 4 private const val ITEM_TYPE_STATS = 4
private const val ITEM_TYPE_UNKNOWN_SUBJECT = 5
const val STATE_CLOSED = 0 const val STATE_CLOSED = 0
const val STATE_OPENED = 1 const val STATE_OPENED = 1
} }
@ -58,6 +59,7 @@ class GradesAdapter(
ITEM_TYPE_EMPTY -> EmptyViewHolder(inflater, parent) ITEM_TYPE_EMPTY -> EmptyViewHolder(inflater, parent)
ITEM_TYPE_GRADE -> GradeViewHolder(inflater, parent) ITEM_TYPE_GRADE -> GradeViewHolder(inflater, parent)
ITEM_TYPE_STATS -> StatsViewHolder(inflater, parent) ITEM_TYPE_STATS -> StatsViewHolder(inflater, parent)
ITEM_TYPE_UNKNOWN_SUBJECT -> UnknownSubjectViewHolder(inflater, parent)
else -> throw IllegalArgumentException("Incorrect viewType") else -> throw IllegalArgumentException("Incorrect viewType")
} }
} }
@ -69,6 +71,7 @@ class GradesAdapter(
is GradesEmpty -> ITEM_TYPE_EMPTY is GradesEmpty -> ITEM_TYPE_EMPTY
is Grade -> ITEM_TYPE_GRADE is Grade -> ITEM_TYPE_GRADE
is GradesStats -> ITEM_TYPE_STATS is GradesStats -> ITEM_TYPE_STATS
is GradesUnknownSubject -> ITEM_TYPE_UNKNOWN_SUBJECT
else -> throw IllegalArgumentException("Incorrect viewType") else -> throw IllegalArgumentException("Incorrect viewType")
} }
} }
@ -86,7 +89,7 @@ class GradesAdapter(
fun expandModel(model: ExpandableItemModel<*>?, view: View?, notifyAdapter: Boolean = true) { fun expandModel(model: ExpandableItemModel<*>?, view: View?, notifyAdapter: Boolean = true) {
model ?: return model ?: return
val position = items.indexOf(model) var position = items.indexOf(model)
if (position == -1) if (position == -1)
return return
@ -138,9 +141,16 @@ class GradesAdapter(
else -> model.items else -> model.items
} }
if (model is GradesSubject && model.isUnknown) {
position++
items.add(position, GradesUnknownSubject())
if (notifyAdapter) notifyItemInserted(position)
}
position++
model.state = STATE_OPENED model.state = STATE_OPENED
items.addAll(position + 1, subItems.filterNotNull()) items.addAll(position, subItems.filterNotNull())
if (notifyAdapter) notifyItemRangeInserted(position + 1, subItems.size) if (notifyAdapter) notifyItemRangeInserted(position, subItems.size)
if (model is GradesSubject) { if (model is GradesSubject) {
// auto expand first semester // auto expand first semester
@ -156,9 +166,10 @@ class GradesAdapter(
else -> semester.grades else -> semester.grades
} }
position++
semester.state = STATE_OPENED semester.state = STATE_OPENED
items.addAll(position + 2 + semesterIndex, grades) items.addAll(position + semesterIndex, grades)
if (notifyAdapter) notifyItemRangeInserted(position + 2 + semesterIndex, grades.size) if (notifyAdapter) notifyItemRangeInserted(position + semesterIndex, grades.size)
} }
} }
} }
@ -198,6 +209,7 @@ class GradesAdapter(
is EmptyViewHolder -> ITEM_TYPE_EMPTY is EmptyViewHolder -> ITEM_TYPE_EMPTY
is GradeViewHolder -> ITEM_TYPE_GRADE is GradeViewHolder -> ITEM_TYPE_GRADE
is StatsViewHolder -> ITEM_TYPE_STATS is StatsViewHolder -> ITEM_TYPE_STATS
is UnknownSubjectViewHolder -> ITEM_TYPE_UNKNOWN_SUBJECT
else -> throw IllegalArgumentException("Incorrect viewType") else -> throw IllegalArgumentException("Incorrect viewType")
} }
holder.itemView.setTag(R.string.tag_key_view_type, viewType) holder.itemView.setTag(R.string.tag_key_view_type, viewType)
@ -210,6 +222,7 @@ class GradesAdapter(
holder is EmptyViewHolder && item is GradesEmpty -> holder.onBind(activity, app, item, position, this) holder is EmptyViewHolder && item is GradesEmpty -> holder.onBind(activity, app, item, position, this)
holder is GradeViewHolder && item is GradeFull -> holder.onBind(activity, app, item, position, this) holder is GradeViewHolder && item is GradeFull -> holder.onBind(activity, app, item, position, this)
holder is StatsViewHolder && item is GradesStats -> holder.onBind(activity, app, item, position, this) holder is StatsViewHolder && item is GradesStats -> holder.onBind(activity, app, item, position, this)
holder is UnknownSubjectViewHolder && item is GradesUnknownSubject -> holder.onBind(activity, app, item, position, this)
} }
if (holder is SemesterViewHolder && item is GradesSemester) { if (holder is SemesterViewHolder && item is GradesSemester) {

View File

@ -182,6 +182,7 @@ class GradesListFragment : Fragment(), CoroutineScope {
@Suppress("SuspendFunctionOnCoroutineScope") @Suppress("SuspendFunctionOnCoroutineScope")
private fun processGrades(grades: List<GradeFull>): MutableList<Any> { private fun processGrades(grades: List<GradeFull>): MutableList<Any> {
val items = mutableListOf<GradesSubject>() val items = mutableListOf<GradesSubject>()
var unknownSubjectItem: GradesSubject? = null
var subjectId = -1L var subjectId = -1L
var semesterNumber = 0 var semesterNumber = 0
@ -200,17 +201,31 @@ class GradesListFragment : Fragment(), CoroutineScope {
subjectId = grade.subjectId subjectId = grade.subjectId
semesterNumber = 0 semesterNumber = 0
subject = items.firstOrNull { it.subjectId == subjectId } subject = items.firstOrNull { it.subjectId == subjectId } ?: run {
?: GradesSubject(grade.subjectId, grade.subjectLongName ?: "").also { if (grade.subjectLongName != null) {
return@run GradesSubject(grade.subjectId, grade.subjectLongName!!).also {
items += it items += it
it.semester = 2 it.semester = 2
} }
} }
if (unknownSubjectItem == null) {
unknownSubjectItem = GradesSubject(-1, "unknown").also {
items += it
it.semester = 2
it.isUnknown = true
}
}
return@run unknownSubjectItem!!
}
}
if (grade.semester != semesterNumber) { if (grade.semester != semesterNumber) {
semesterNumber = grade.semester semesterNumber = grade.semester
semester = subject.semesters.firstOrNull { it.number == semesterNumber } semester = subject.semesters.firstOrNull { it.number == semesterNumber }
?: GradesSemester(subject.subjectId, grade.semester).also { subject.semesters += it } ?: GradesSemester(subject.subjectId, grade.semester).also {
subject.semesters += it
it.hideEditor = subject.isUnknown
}
} }
grade.showAsUnseen = !grade.seen grade.showAsUnseen = !grade.seen
@ -221,6 +236,11 @@ class GradesListFragment : Fragment(), CoroutineScope {
semester.hasUnseen = true semester.hasUnseen = true
} }
if (subject.isUnknown) {
// unknown subjects may have final grades (i.e. Mobidziennik)
grade.type = Grade.TYPE_NORMAL
}
when (grade.type) { when (grade.type) {
Grade.TYPE_SEMESTER1_PROPOSED, Grade.TYPE_SEMESTER1_PROPOSED,
Grade.TYPE_SEMESTER2_PROPOSED -> semester.proposedGrade = grade Grade.TYPE_SEMESTER2_PROPOSED -> semester.proposedGrade = grade
@ -255,6 +275,10 @@ class GradesListFragment : Fragment(), CoroutineScope {
val yearlyPoint = mutableListOf<Float>() val yearlyPoint = mutableListOf<Float>()
for (item in items) { for (item in items) {
if (item.isUnknown) {
// do not count averages for "unknown" subjects
continue
}
item.semesters.forEach { sem -> item.semesters.forEach { sem ->
manager.calculateAverages(sem.averages) manager.calculateAverages(sem.averages)
if (sem.number == 1) { if (sem.number == 1) {

View File

@ -14,6 +14,7 @@ data class GradesSemester(
override var level = 2 override var level = 2
var hasUnseen = false var hasUnseen = false
var hideEditor = false
val averages = GradesAverages() val averages = GradesAverages()
var proposedGrade: GradeFull? = null var proposedGrade: GradeFull? = null

View File

@ -15,6 +15,7 @@ data class GradesSubject(
var lastAddedDate = 0L var lastAddedDate = 0L
var semester: Int = 1 var semester: Int = 1
var isUnknown = false
var hasUnseen: Boolean = false var hasUnseen: Boolean = false
get() = field || semesters.any { it.hasUnseen } get() = field || semesters.any { it.hasUnseen }

View File

@ -0,0 +1,7 @@
/*
* Copyright (c) Kuba Szczodrzyński 2022-3-14.
*/
package pl.szczodrzynski.edziennik.ui.grades.models
class GradesUnknownSubject

View File

@ -61,6 +61,8 @@ class SemesterViewHolder(
} }
} }
b.editButton.isVisible = !item.hideEditor
b.average.text = manager.getAverageString(app, item.averages) b.average.text = manager.getAverageString(app, item.averages)
b.proposedGrade.setGrade(item.proposedGrade, manager) b.proposedGrade.setGrade(item.proposedGrade, manager)
b.finalGrade.setGrade(item.finalGrade, manager) b.finalGrade.setGrade(item.finalGrade, manager)

View File

@ -19,9 +19,7 @@ import androidx.recyclerview.widget.RecyclerView
import pl.szczodrzynski.edziennik.App import pl.szczodrzynski.edziennik.App
import pl.szczodrzynski.edziennik.R import pl.szczodrzynski.edziennik.R
import pl.szczodrzynski.edziennik.databinding.GradesItemSubjectBinding import pl.szczodrzynski.edziennik.databinding.GradesItemSubjectBinding
import pl.szczodrzynski.edziennik.ext.dp import pl.szczodrzynski.edziennik.ext.*
import pl.szczodrzynski.edziennik.ext.resolveAttr
import pl.szczodrzynski.edziennik.ext.setText
import pl.szczodrzynski.edziennik.ui.grades.GradeView import pl.szczodrzynski.edziennik.ui.grades.GradeView
import pl.szczodrzynski.edziennik.ui.grades.GradesAdapter import pl.szczodrzynski.edziennik.ui.grades.GradesAdapter
import pl.szczodrzynski.edziennik.ui.grades.GradesAdapter.Companion.STATE_CLOSED import pl.szczodrzynski.edziennik.ui.grades.GradesAdapter.Companion.STATE_CLOSED
@ -41,7 +39,12 @@ class SubjectViewHolder(
val manager = app.gradesManager val manager = app.gradesManager
val contextWrapper = ContextThemeWrapper(activity, Themes.appTheme) val contextWrapper = ContextThemeWrapper(activity, Themes.appTheme)
if (!item.isUnknown) {
b.subjectName.text = item.subjectName b.subjectName.text = item.subjectName
}
else {
b.subjectName.text = R.string.grades_subject_unknown.resolveString(activity).asItalicSpannable()
}
b.dropdownIcon.rotation = when (item.state) { b.dropdownIcon.rotation = when (item.state) {
STATE_CLOSED -> 0f STATE_CLOSED -> 0f
else -> 180f else -> 180f

View File

@ -0,0 +1,29 @@
/*
* Copyright (c) Kuba Szczodrzyński 2022-3-14.
*/
package pl.szczodrzynski.edziennik.ui.grades.viewholder
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.RecyclerView
import pl.szczodrzynski.edziennik.App
import pl.szczodrzynski.edziennik.databinding.GradesItemUnknownSubjectBinding
import pl.szczodrzynski.edziennik.ui.grades.GradesAdapter
import pl.szczodrzynski.edziennik.ui.grades.models.GradesUnknownSubject
class UnknownSubjectViewHolder(
inflater: LayoutInflater,
parent: ViewGroup,
val b: GradesItemUnknownSubjectBinding = GradesItemUnknownSubjectBinding.inflate(inflater, parent, false)
) : RecyclerView.ViewHolder(b.root), BindableViewHolder<GradesUnknownSubject, GradesAdapter> {
companion object {
private const val TAG = "UnknownSubjectViewHolder"
}
override fun onBind(activity: AppCompatActivity, app: App, item: GradesUnknownSubject, position: Int, adapter: GradesAdapter) {
}
}

View File

@ -85,6 +85,9 @@ class HomeGradesCard(
grades.forEach { grade -> grades.forEach { grade ->
val model = ItemGradesSubjectModel.searchModelBySubjectId(subjects, grade.subjectId) val model = ItemGradesSubjectModel.searchModelBySubjectId(subjects, grade.subjectId)
?: run { ?: run {
if (grade.subjectLongName == null) {
return@forEach
}
subjects.add(ItemGradesSubjectModel( subjects.add(ItemGradesSubjectModel(
profile, profile,
Subject(profile.id, grade.subjectId, grade.subjectLongName, grade.subjectShortName), Subject(profile.id, grade.subjectId, grade.subjectLongName, grade.subjectShortName),

View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (c) Kuba Szczodrzyński 2022-3-14.
-->
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.mikepenz.iconics.view.IconicsTextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:text="@string/grades_subject_unknown_help"
android:textColor="?android:textColorSecondary" />
</LinearLayout>
</layout>

View File

@ -1549,4 +1549,6 @@
<string name="card_notes_header_title">Najnowsze notatki</string> <string name="card_notes_header_title">Najnowsze notatki</string>
<string name="login_summary_account_child">(uczeń)</string> <string name="login_summary_account_child">(uczeń)</string>
<string name="login_summary_account_parent">(rodzic)</string> <string name="login_summary_account_parent">(rodzic)</string>
<string name="grades_subject_unknown">- nieznany przedmiot -</string>
<string name="grades_subject_unknown_help">{cmd-information-outline} Oceny, których przedmiot nie został podany w dzienniku. Może to być na przykład taki, który nie jest prowadzony w tym roku szkolnym.</string>
</resources> </resources>