Handle subjects with no attendances in attendance calculator better (#2478)

---------

Co-authored-by: Faierbel <RafalBO99@outlook.com>
This commit is contained in:
Michael 2024-03-11 20:19:24 +01:00 committed by GitHub
parent eb6fdd900e
commit 95e41b5570
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 53 additions and 25 deletions

View File

@ -71,6 +71,9 @@ fun <T, U> Resource<T>.mapData(block: (T) -> U) = when (this) {
is Resource.Error -> Resource.Error(this.error)
}
/**
* Injects another flow into this flow's resource data.
*/
inline fun <T1, T2, R> Flow<Resource<T1>>.combineWithResourceData(
flow: Flow<T2>,
crossinline block: suspend (T1, T2) -> R

View File

@ -54,6 +54,15 @@ class PreferencesRepository @Inject constructor(
context.resources.getString(R.string.pref_default_attendance_calculator_sorting_mode)
).asFlow().map(AttendanceCalculatorSortingMode::getByValue)
/**
* Subjects are empty when they don't have any attendances (total = 0, attendances = 0, absences = 0).
*/
val attendanceCalculatorShowEmptySubjects: Flow<Boolean>
get() = flowSharedPref.getBoolean(
context.getString(R.string.pref_key_attendance_calculator_show_empty_subjects),
context.resources.getBoolean(R.bool.pref_default_attendance_calculator_show_empty_subjects)
).asFlow()
private val gradeAverageModePref: Preference<GradeAverageMode>
get() = getObjectFlow(
R.string.pref_key_grade_average_mode,

View File

@ -49,6 +49,9 @@ class GetAttendanceCalculatorDataUseCase @Inject constructor(
// intermediates that will be visible for barely any time.
.debounceIntermediates()
}
.combineWithResourceData(preferencesRepository.attendanceCalculatorShowEmptySubjects) { attendanceDataList, showEmptySubjects ->
attendanceDataList.filter { it.total != 0 || showEmptySubjects }
}
.combineWithResourceData(preferencesRepository.attendanceCalculatorSortingModeFlow, List<AttendanceData>::sortedBy)
}

View File

@ -1,6 +1,5 @@
package io.github.wulkanowy.ui.modules.attendance.calculator
import android.annotation.SuppressLint
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.core.view.isVisible
@ -19,42 +18,47 @@ class AttendanceCalculatorAdapter @Inject constructor() :
override fun getItemCount() = items.size
override fun onCreateViewHolder(
parent: ViewGroup, viewType: Int
) = ViewHolder(
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ViewHolder(
ItemAttendanceCalculatorHeaderBinding.inflate(
LayoutInflater.from(parent.context), parent, false
)
)
@SuppressLint("SetTextI18n")
override fun onBindViewHolder(parent: ViewHolder, position: Int) {
val context = parent.binding.root.context
val item = items[position]
with(parent.binding) {
val item = items[position]
attendanceCalculatorPercentage.text = "${item.presencePercentage.roundToInt()}"
if (item.lessonBalance > 0) {
attendanceCalculatorSummaryBalance.text = root.context.getString(
R.string.attendance_calculator_summary_balance_positive,
item.lessonBalance
)
} else if (item.lessonBalance < 0) {
attendanceCalculatorSummaryBalance.text = root.context.getString(
R.string.attendance_calculator_summary_balance_negative,
abs(item.lessonBalance)
)
} else {
attendanceCalculatorSummaryBalance.text = root.context.getString(
R.string.attendance_calculator_summary_balance_neutral,
)
attendanceCalculatorSummaryBalance.text = when {
item.lessonBalance > 0 -> {
context.getString(
R.string.attendance_calculator_summary_balance_positive,
item.lessonBalance
)
}
item.lessonBalance < 0 -> {
context.getString(
R.string.attendance_calculator_summary_balance_negative,
abs(item.lessonBalance)
)
}
else -> context.getString(R.string.attendance_calculator_summary_balance_neutral)
}
attendanceCalculatorWarning.isVisible = item.lessonBalance < 0
attendanceCalculatorTitle.text = item.subjectName
attendanceCalculatorSummaryValues.text = root.context.getString(
R.string.attendance_calculator_summary_values,
item.presences,
item.total
)
attendanceCalculatorSummaryValues.text = if (item.total == 0) {
context.getString(R.string.attendance_calculator_summary_values_empty)
} else {
context.getString(
R.string.attendance_calculator_summary_values,
item.presences,
item.total
)
}
}
}

View File

@ -4,6 +4,7 @@
<bool name="pref_default_attendance_present">true</bool>
<integer name="pref_default_attendance_target">50</integer>
<string name="pref_default_attendance_calculator_sorting_mode">alphabetic</string>
<bool name="pref_default_attendance_calculator_show_empty_subjects">false</bool>
<string name="pref_default_grade_average_mode">only_one_semester</string>
<bool name="pref_default_grade_average_force_calc">false</bool>
<string name="pref_default_expand_grade_mode">one</string>

View File

@ -4,6 +4,7 @@
<string name="pref_key_attendance_present">attendance_present</string>
<string name="pref_key_attendance_target">attendance_target</string>
<string name="pref_key_attendance_calculator_sorting_mode">attendance_calculator_sorting_mode</string>
<string name="pref_key_attendance_calculator_show_empty_subjects">attendance_calculator_show_empty_subjects</string>
<string name="pref_key_app_theme">app_theme</string>
<string name="pref_key_dashboard_tiles">dashboard_tiles</string>
<string name="pref_key_grade_color_scheme">grade_color_scheme</string>

View File

@ -263,6 +263,7 @@
<string name="attendance_calculator_summary_balance_neutral">right on target</string>
<string name="attendance_calculator_summary_balance_negative"><b>%1$d</b> under target</string>
<string name="attendance_calculator_summary_values">%1$d/%2$d presences</string>
<string name="attendance_calculator_summary_values_empty">No attendances recorded</string>
<string name="attendance_absence_school">Absent for school reasons</string>
<string name="attendance_absence_excused">Excused absence</string>
<string name="attendance_absence_unexcused">Unexcused absence</string>
@ -721,6 +722,7 @@
<string name="pref_view_grade_average_force_calc">Force average calculation by app</string>
<string name="pref_view_present">Show presence</string>
<string name="pref_attendance_target">Attendance target</string>
<string name="pref_attendance_calculator_show_empty_subjects">Show subjects without any attendances</string>
<string name="pref_view_attendance_calculator_sorting_mode">Attendance calculator sorting</string>
<string name="pref_view_app_theme">Theme</string>
<string name="pref_view_expand_grade">Grades expanding</string>

View File

@ -104,6 +104,11 @@
app:key="@string/pref_key_attendance_calculator_sorting_mode"
app:title="@string/pref_view_attendance_calculator_sorting_mode"
app:useSimpleSummaryProvider="true" />
<SwitchPreferenceCompat
app:defaultValue="@bool/pref_default_attendance_calculator_show_empty_subjects"
app:iconSpaceReserved="false"
app:key="@string/pref_key_attendance_calculator_show_empty_subjects"
app:title="@string/pref_attendance_calculator_show_empty_subjects" />
</PreferenceCategory>
<PreferenceCategory
android:layout_height="wrap_content"