mirror of
https://github.com/szkolny-eu/szkolny-android.git
synced 2025-02-08 00:54:37 +01:00
[UI/Grades] Update views for university grades
This commit is contained in:
parent
6de7ee9cee
commit
30a77f1a99
@ -153,7 +153,9 @@ class UsosApiExamReports(
|
|||||||
if (sessionNumber > 1) {
|
if (sessionNumber > 1) {
|
||||||
val origId = examId * 10L + sessionNumber - 1
|
val origId = examId * 10L + sessionNumber - 1
|
||||||
val grades = data.gradeList.filter { it.id == origId }
|
val grades = data.gradeList.filter { it.id == origId }
|
||||||
grades.firstOrNull()?.parentId = gradeObject.id
|
val improvedGrade = grades.firstOrNull()
|
||||||
|
improvedGrade?.parentId = gradeObject.id
|
||||||
|
improvedGrade?.weight = 0.0f
|
||||||
gradeObject.isImprovement = true
|
gradeObject.isImprovement = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,6 +134,7 @@ class GradesAdapter(
|
|||||||
if (model.state == STATE_CLOSED) {
|
if (model.state == STATE_CLOSED) {
|
||||||
|
|
||||||
val subItems = when {
|
val subItems = when {
|
||||||
|
model is GradesSubject && manager.isUniversity -> listOf()
|
||||||
model is GradesSemester && model.grades.isEmpty() ->
|
model is GradesSemester && model.grades.isEmpty() ->
|
||||||
listOf(GradesEmpty())
|
listOf(GradesEmpty())
|
||||||
model is GradesSemester && manager.hideImproved ->
|
model is GradesSemester && manager.hideImproved ->
|
||||||
@ -147,10 +148,12 @@ class GradesAdapter(
|
|||||||
if (notifyAdapter) notifyItemInserted(position)
|
if (notifyAdapter) notifyItemInserted(position)
|
||||||
}
|
}
|
||||||
|
|
||||||
position++
|
|
||||||
model.state = STATE_OPENED
|
model.state = STATE_OPENED
|
||||||
items.addAll(position, subItems.filterNotNull())
|
if (subItems.isNotEmpty()) {
|
||||||
if (notifyAdapter) notifyItemRangeInserted(position, subItems.size)
|
position++
|
||||||
|
items.addAll(position, subItems.filterNotNull())
|
||||||
|
if (notifyAdapter) notifyItemRangeInserted(position, subItems.size)
|
||||||
|
}
|
||||||
|
|
||||||
if (model is GradesSubject) {
|
if (model is GradesSubject) {
|
||||||
// auto expand first semester
|
// auto expand first semester
|
||||||
|
@ -258,8 +258,40 @@ class GradesListFragment : Fragment(), CoroutineScope {
|
|||||||
subject.lastAddedDate = max(subject.lastAddedDate, grade.addedDate)
|
subject.lastAddedDate = max(subject.lastAddedDate, grade.addedDate)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
when (manager.orderBy) {
|
||||||
|
GradesManager.ORDER_BY_DATE_DESC -> items.sortByDescending { it.lastAddedDate }
|
||||||
|
GradesManager.ORDER_BY_DATE_ASC -> items.sortBy { it.lastAddedDate }
|
||||||
|
}
|
||||||
|
|
||||||
val stats = GradesStats()
|
val stats = GradesStats()
|
||||||
|
|
||||||
|
if (manager.isUniversity) {
|
||||||
|
val semesterSum = mutableListOf<Float>()
|
||||||
|
val semesterCount = mutableListOf<Float>()
|
||||||
|
val totalSum = mutableListOf<Float>()
|
||||||
|
val totalCount = mutableListOf<Float>()
|
||||||
|
val ectsPoints = mutableMapOf<Long, Float>()
|
||||||
|
for (grade in grades) {
|
||||||
|
if (grade.value == 0.0f || grade.weight == 0.0f)
|
||||||
|
continue
|
||||||
|
totalSum.add(grade.value * grade.weight)
|
||||||
|
totalCount.add(grade.weight)
|
||||||
|
if (grade.value < 3.0)
|
||||||
|
// exam not passed, reset points for this subject
|
||||||
|
ectsPoints[grade.subjectId] = 0.0f
|
||||||
|
else if (grade.subjectId !in ectsPoints)
|
||||||
|
// no points for this subject, simply assign
|
||||||
|
ectsPoints[grade.subjectId] = grade.weight
|
||||||
|
|
||||||
|
semesterSum.add(grade.value * grade.weight)
|
||||||
|
semesterCount.add(grade.weight)
|
||||||
|
}
|
||||||
|
stats.universitySem = semesterSum.sum() / semesterCount.sum()
|
||||||
|
stats.universityTotal = totalSum.sum() / totalCount.sum()
|
||||||
|
stats.universityEcts = ectsPoints.values.sum()
|
||||||
|
return (items + stats).toMutableList()
|
||||||
|
}
|
||||||
|
|
||||||
val sem1Expected = mutableListOf<Float>()
|
val sem1Expected = mutableListOf<Float>()
|
||||||
val sem2Expected = mutableListOf<Float>()
|
val sem2Expected = mutableListOf<Float>()
|
||||||
val yearlyExpected = mutableListOf<Float>()
|
val yearlyExpected = mutableListOf<Float>()
|
||||||
@ -330,11 +362,6 @@ class GradesListFragment : Fragment(), CoroutineScope {
|
|||||||
stats.pointSem2 = sem2Point.averageOrNull()?.toFloat() ?: 0f
|
stats.pointSem2 = sem2Point.averageOrNull()?.toFloat() ?: 0f
|
||||||
stats.pointYearly = yearlyPoint.averageOrNull()?.toFloat() ?: 0f
|
stats.pointYearly = yearlyPoint.averageOrNull()?.toFloat() ?: 0f
|
||||||
|
|
||||||
when (manager.orderBy) {
|
|
||||||
GradesManager.ORDER_BY_DATE_DESC -> items.sortByDescending { it.lastAddedDate }
|
|
||||||
GradesManager.ORDER_BY_DATE_ASC -> items.sortBy { it.lastAddedDate }
|
|
||||||
}
|
|
||||||
|
|
||||||
return (items + stats).toMutableList()
|
return (items + stats).toMutableList()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,4 +22,8 @@ class GradesStats {
|
|||||||
var pointSem1 = 0f
|
var pointSem1 = 0f
|
||||||
var pointSem2 = 0f
|
var pointSem2 = 0f
|
||||||
var pointYearly = 0f
|
var pointYearly = 0f
|
||||||
|
|
||||||
|
var universitySem = 0f
|
||||||
|
var universityTotal = 0f
|
||||||
|
var universityEcts = 0f
|
||||||
}
|
}
|
||||||
|
@ -31,9 +31,35 @@ class StatsViewHolder(
|
|||||||
|
|
||||||
override fun onBind(activity: AppCompatActivity, app: App, item: GradesStats, position: Int, adapter: GradesAdapter) {
|
override fun onBind(activity: AppCompatActivity, app: App, item: GradesStats, position: Int, adapter: GradesAdapter) {
|
||||||
val manager = app.gradesManager
|
val manager = app.gradesManager
|
||||||
|
val isUniversity = manager.isUniversity
|
||||||
val showAverages = mutableListOf<Int>()
|
val showAverages = mutableListOf<Int>()
|
||||||
val showPoint = mutableListOf<Int>()
|
val showPoint = mutableListOf<Int>()
|
||||||
|
|
||||||
|
b.universityTitle.isVisible = isUniversity
|
||||||
|
b.universityLayout.isVisible = isUniversity
|
||||||
|
b.universityDivider.isVisible = isUniversity
|
||||||
|
|
||||||
|
if (isUniversity) {
|
||||||
|
val format = DecimalFormat("#.00")
|
||||||
|
|
||||||
|
b.normalTitle.isVisible = false
|
||||||
|
b.normalLayout.isVisible = false
|
||||||
|
b.normalDivider.isVisible = false
|
||||||
|
b.helpButton.isVisible = false
|
||||||
|
b.pointTitle.isVisible = false
|
||||||
|
b.pointLayout.isVisible = false
|
||||||
|
b.pointDivider.isVisible = false
|
||||||
|
b.noData.isVisible = false
|
||||||
|
b.disclaimer.isVisible = true
|
||||||
|
b.customValueDivider.isVisible = false
|
||||||
|
b.customValueLayout.isVisible = false
|
||||||
|
|
||||||
|
b.universitySemester.text = format.format(item.universitySem)
|
||||||
|
b.universityTotal.text = format.format(item.universityTotal)
|
||||||
|
b.universityEcts.text = format.format(item.universityEcts)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
getSemesterString(app, item.normalSem1, item.normalSem1Proposed, item.normalSem1Final, item.sem1NotAllFinal).let { (average, notice) ->
|
getSemesterString(app, item.normalSem1, item.normalSem1Proposed, item.normalSem1Final, item.sem1NotAllFinal).let { (average, notice) ->
|
||||||
b.normalSemester1Layout.isVisible = average != null
|
b.normalSemester1Layout.isVisible = average != null
|
||||||
b.normalSemester1Notice.isVisible = notice != null
|
b.normalSemester1Notice.isVisible = notice != null
|
||||||
|
@ -62,9 +62,24 @@ class SubjectViewHolder(
|
|||||||
|
|
||||||
val firstSemester = item.semesters.firstOrNull() ?: return
|
val firstSemester = item.semesters.firstOrNull() ?: return
|
||||||
|
|
||||||
b.yearSummary.text = manager.getYearSummaryString(app, item.semesters.map { it.grades.size }.sum(), item.averages)
|
if (manager.isUniversity) {
|
||||||
|
val ectsPoints = item.semesters.firstOrNull()?.grades?.maxOf { it.weight }
|
||||||
|
b.yearSummary.text = if (ectsPoints != null)
|
||||||
|
contextWrapper.getString(
|
||||||
|
R.string.grades_ects_points_format,
|
||||||
|
ectsPoints
|
||||||
|
)
|
||||||
|
else
|
||||||
|
null
|
||||||
|
} else {
|
||||||
|
b.yearSummary.text = manager.getYearSummaryString(
|
||||||
|
app,
|
||||||
|
item.semesters.map { it.grades.size }.sum(),
|
||||||
|
item.averages
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
if (firstSemester.number != item.semester) {
|
if (firstSemester.number != item.semester && !manager.isUniversity) {
|
||||||
b.gradesContainer.addView(TextView(contextWrapper).apply {
|
b.gradesContainer.addView(TextView(contextWrapper).apply {
|
||||||
setTextColor(android.R.attr.textColorSecondary.resolveAttr(context))
|
setTextColor(android.R.attr.textColorSecondary.resolveAttr(context))
|
||||||
setText(R.string.grades_preview_other_semester, firstSemester.number)
|
setText(R.string.grades_preview_other_semester, firstSemester.number)
|
||||||
@ -92,16 +107,18 @@ class SubjectViewHolder(
|
|||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
b.previewContainer.addView(TextView(contextWrapper).apply {
|
if (!manager.isUniversity) {
|
||||||
setTextColor(android.R.attr.textColorSecondary.resolveAttr(context))
|
b.previewContainer.addView(TextView(contextWrapper).apply {
|
||||||
text = manager.getAverageString(app, firstSemester.averages, nameSemester = true, showSemester = firstSemester.number)
|
setTextColor(android.R.attr.textColorSecondary.resolveAttr(context))
|
||||||
//gravity = Gravity.END
|
text = manager.getAverageString(app, firstSemester.averages, nameSemester = true, showSemester = firstSemester.number)
|
||||||
layoutParams = LinearLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT).apply {
|
//gravity = Gravity.END
|
||||||
setMargins(0, 0, 8.dp, 0)
|
layoutParams = LinearLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT).apply {
|
||||||
}
|
setMargins(0, 0, 8.dp, 0)
|
||||||
maxLines = 1
|
}
|
||||||
ellipsize = TextUtils.TruncateAt.END
|
maxLines = 1
|
||||||
})
|
ellipsize = TextUtils.TruncateAt.END
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// add the topmost semester's grades to preview container (collapsed)
|
// add the topmost semester's grades to preview container (collapsed)
|
||||||
firstSemester.proposedGrade?.let {
|
firstSemester.proposedGrade?.let {
|
||||||
@ -139,7 +156,7 @@ class SubjectViewHolder(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// if showing semester 2, add yearly grades to preview container (collapsed)
|
// if showing semester 2, add yearly grades to preview container (collapsed)
|
||||||
if (firstSemester.number == item.semester) {
|
if (firstSemester.number == item.semester && !manager.isUniversity) {
|
||||||
b.previewContainer.addView(TextView(contextWrapper).apply {
|
b.previewContainer.addView(TextView(contextWrapper).apply {
|
||||||
text = manager.getAverageString(app, item.averages, nameSemester = true)
|
text = manager.getAverageString(app, item.averages, nameSemester = true)
|
||||||
layoutParams = LinearLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT).apply {
|
layoutParams = LinearLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT).apply {
|
||||||
|
@ -70,6 +70,8 @@ class GradesManager(val app: App) : CoroutineScope {
|
|||||||
get() = app.profile.config.grades.hideImproved
|
get() = app.profile.config.grades.hideImproved
|
||||||
val averageWithoutWeight
|
val averageWithoutWeight
|
||||||
get() = app.profile.config.grades.averageWithoutWeight
|
get() = app.profile.config.grades.averageWithoutWeight
|
||||||
|
val isUniversity
|
||||||
|
get() = app.profile.loginStoreType.schoolType == SchoolType.UNIVERSITY
|
||||||
|
|
||||||
|
|
||||||
fun getOrderByString() = when (orderBy) {
|
fun getOrderByString() = when (orderBy) {
|
||||||
|
@ -283,6 +283,107 @@
|
|||||||
android:layout_marginTop="8dp"
|
android:layout_marginTop="8dp"
|
||||||
android:background="@drawable/divider" />
|
android:background="@drawable/divider" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/universityTitle"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginHorizontal="8dp"
|
||||||
|
android:text="@string/grades_stats_university"
|
||||||
|
android:textAppearance="@style/NavView.TextView.Subtitle" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/universityLayout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:paddingHorizontal="8dp">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:gravity="center_horizontal"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/grades_stats_this_semester" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/universitySemester"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:fontFamily="sans-serif-light"
|
||||||
|
android:textSize="24sp"
|
||||||
|
tools:text="4,56" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="1dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:background="@drawable/divider" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:gravity="center_horizontal"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/grades_stats_all_grades" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/universityTotal"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:fontFamily="sans-serif-light"
|
||||||
|
android:textSize="24sp"
|
||||||
|
tools:text="4,67" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="1dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:background="@drawable/divider"
|
||||||
|
android:visibility="gone" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:gravity="center_horizontal"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:visibility="gone">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/grades_stats_ects_points" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/universityEcts"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:fontFamily="sans-serif-light"
|
||||||
|
android:textSize="24sp"
|
||||||
|
tools:text="120" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:id="@+id/universityDivider"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="1dp"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:background="@drawable/divider" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/disclaimer"
|
android:id="@+id/disclaimer"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
|
@ -448,6 +448,7 @@
|
|||||||
<string name="grades_config_minus_value">Własna wartość minusa</string>
|
<string name="grades_config_minus_value">Własna wartość minusa</string>
|
||||||
<string name="grades_config_plus_value">Własna wartość plusa</string>
|
<string name="grades_config_plus_value">Własna wartość plusa</string>
|
||||||
<string name="grades_config_title">Konfiguracja ocen</string>
|
<string name="grades_config_title">Konfiguracja ocen</string>
|
||||||
|
<string name="grades_ects_points_format">Punkty ECTS: %#.2f</string>
|
||||||
<string name="grades_editor_add_grade">Dodaj ocenę</string>
|
<string name="grades_editor_add_grade">Dodaj ocenę</string>
|
||||||
<string name="grades_editor_add_grade_title">Dodawanie oceny</string>
|
<string name="grades_editor_add_grade_title">Dodawanie oceny</string>
|
||||||
<string name="grades_editor_add_grade_weight">Podaj wagę oceny</string>
|
<string name="grades_editor_add_grade_weight">Podaj wagę oceny</string>
|
||||||
@ -474,9 +475,11 @@
|
|||||||
<string name="grades_semester_average_point_format">semestr %d: %spkt</string>
|
<string name="grades_semester_average_point_format">semestr %d: %spkt</string>
|
||||||
<string name="grades_semester_format">Semestr %d</string>
|
<string name="grades_semester_format">Semestr %d</string>
|
||||||
<string name="grades_semester_header_format">Semestr %d</string>
|
<string name="grades_semester_header_format">Semestr %d</string>
|
||||||
|
<string name="grades_stats_all_grades">wszystkie oceny</string>
|
||||||
<string name="grades_stats_custom_config_notice">Aktualne ustawienia ocen mogą wpływać na średnią. Jeśli uważasz, że się ona nie zgadza, kliknij Konfiguruj.</string>
|
<string name="grades_stats_custom_config_notice">Aktualne ustawienia ocen mogą wpływać na średnią. Jeśli uważasz, że się ona nie zgadza, kliknij Konfiguruj.</string>
|
||||||
<string name="grades_stats_custom_value_notice">Została ustawiona własna wartość plusa/minusa. Jeśli uważasz, że się ona nie zgadza, kliknij Konfiguruj.</string>
|
<string name="grades_stats_custom_value_notice">Została ustawiona własna wartość plusa/minusa. Jeśli uważasz, że się ona nie zgadza, kliknij Konfiguruj.</string>
|
||||||
<string name="grades_stats_disclaimer">*średnie ocen są poglądowe i mogą się różnić, w zależności od ustawień szkoły</string>
|
<string name="grades_stats_disclaimer">*średnie ocen są poglądowe i mogą się różnić, w zależności od ustawień szkoły</string>
|
||||||
|
<string name="grades_stats_ects_points">punkty ECTS</string>
|
||||||
<string name="grades_stats_expected">*przewidywana średnia</string>
|
<string name="grades_stats_expected">*przewidywana średnia</string>
|
||||||
<string name="grades_stats_from_final">*z ocen końcowych\nPrzewidywana: %s</string>
|
<string name="grades_stats_from_final">*z ocen końcowych\nPrzewidywana: %s</string>
|
||||||
<string name="grades_stats_from_final_no_expected">*z ocen końcowych</string>
|
<string name="grades_stats_from_final_no_expected">*z ocen końcowych</string>
|
||||||
@ -490,7 +493,9 @@
|
|||||||
<string name="grades_stats_proposed_avg">Śr. ocen proponowanych:\n%s</string>
|
<string name="grades_stats_proposed_avg">Śr. ocen proponowanych:\n%s</string>
|
||||||
<string name="grades_stats_semester_1">semestr 1</string>
|
<string name="grades_stats_semester_1">semestr 1</string>
|
||||||
<string name="grades_stats_semester_2">semestr 2</string>
|
<string name="grades_stats_semester_2">semestr 2</string>
|
||||||
|
<string name="grades_stats_this_semester">ten semestr</string>
|
||||||
<string name="grades_stats_title">Statystyka ocen</string>
|
<string name="grades_stats_title">Statystyka ocen</string>
|
||||||
|
<string name="grades_stats_university">Średnia ocen za studia</string>
|
||||||
<string name="grades_stats_yearly">całoroczna</string>
|
<string name="grades_stats_yearly">całoroczna</string>
|
||||||
<string name="grades_value_format">wartość: %s</string>
|
<string name="grades_value_format">wartość: %s</string>
|
||||||
<string name="grades_weight_format">waga %s</string>
|
<string name="grades_weight_format">waga %s</string>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user