1
0
mirror of https://github.com/wulkanowy/wulkanowy.git synced 2024-09-19 23:29:08 -05:00

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) 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( inline fun <T1, T2, R> Flow<Resource<T1>>.combineWithResourceData(
flow: Flow<T2>, flow: Flow<T2>,
crossinline block: suspend (T1, T2) -> R 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) context.resources.getString(R.string.pref_default_attendance_calculator_sorting_mode)
).asFlow().map(AttendanceCalculatorSortingMode::getByValue) ).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> private val gradeAverageModePref: Preference<GradeAverageMode>
get() = getObjectFlow( get() = getObjectFlow(
R.string.pref_key_grade_average_mode, 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. // intermediates that will be visible for barely any time.
.debounceIntermediates() .debounceIntermediates()
} }
.combineWithResourceData(preferencesRepository.attendanceCalculatorShowEmptySubjects) { attendanceDataList, showEmptySubjects ->
attendanceDataList.filter { it.total != 0 || showEmptySubjects }
}
.combineWithResourceData(preferencesRepository.attendanceCalculatorSortingModeFlow, List<AttendanceData>::sortedBy) .combineWithResourceData(preferencesRepository.attendanceCalculatorSortingModeFlow, List<AttendanceData>::sortedBy)
} }

View File

@ -1,6 +1,5 @@
package io.github.wulkanowy.ui.modules.attendance.calculator package io.github.wulkanowy.ui.modules.attendance.calculator
import android.annotation.SuppressLint
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.ViewGroup import android.view.ViewGroup
import androidx.core.view.isVisible import androidx.core.view.isVisible
@ -19,42 +18,47 @@ class AttendanceCalculatorAdapter @Inject constructor() :
override fun getItemCount() = items.size override fun getItemCount() = items.size
override fun onCreateViewHolder( override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ViewHolder(
parent: ViewGroup, viewType: Int
) = ViewHolder(
ItemAttendanceCalculatorHeaderBinding.inflate( ItemAttendanceCalculatorHeaderBinding.inflate(
LayoutInflater.from(parent.context), parent, false LayoutInflater.from(parent.context), parent, false
) )
) )
@SuppressLint("SetTextI18n")
override fun onBindViewHolder(parent: ViewHolder, position: Int) { override fun onBindViewHolder(parent: ViewHolder, position: Int) {
val context = parent.binding.root.context
val item = items[position]
with(parent.binding) { with(parent.binding) {
val item = items[position]
attendanceCalculatorPercentage.text = "${item.presencePercentage.roundToInt()}" attendanceCalculatorPercentage.text = "${item.presencePercentage.roundToInt()}"
if (item.lessonBalance > 0) { attendanceCalculatorSummaryBalance.text = when {
attendanceCalculatorSummaryBalance.text = root.context.getString( item.lessonBalance > 0 -> {
R.string.attendance_calculator_summary_balance_positive, context.getString(
item.lessonBalance 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) item.lessonBalance < 0 -> {
) context.getString(
} else { R.string.attendance_calculator_summary_balance_negative,
attendanceCalculatorSummaryBalance.text = root.context.getString( abs(item.lessonBalance)
R.string.attendance_calculator_summary_balance_neutral, )
) }
else -> context.getString(R.string.attendance_calculator_summary_balance_neutral)
} }
attendanceCalculatorWarning.isVisible = item.lessonBalance < 0 attendanceCalculatorWarning.isVisible = item.lessonBalance < 0
attendanceCalculatorTitle.text = item.subjectName attendanceCalculatorTitle.text = item.subjectName
attendanceCalculatorSummaryValues.text = root.context.getString( attendanceCalculatorSummaryValues.text = if (item.total == 0) {
R.string.attendance_calculator_summary_values, context.getString(R.string.attendance_calculator_summary_values_empty)
item.presences, } else {
item.total 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> <bool name="pref_default_attendance_present">true</bool>
<integer name="pref_default_attendance_target">50</integer> <integer name="pref_default_attendance_target">50</integer>
<string name="pref_default_attendance_calculator_sorting_mode">alphabetic</string> <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> <string name="pref_default_grade_average_mode">only_one_semester</string>
<bool name="pref_default_grade_average_force_calc">false</bool> <bool name="pref_default_grade_average_force_calc">false</bool>
<string name="pref_default_expand_grade_mode">one</string> <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_present">attendance_present</string>
<string name="pref_key_attendance_target">attendance_target</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_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_app_theme">app_theme</string>
<string name="pref_key_dashboard_tiles">dashboard_tiles</string> <string name="pref_key_dashboard_tiles">dashboard_tiles</string>
<string name="pref_key_grade_color_scheme">grade_color_scheme</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_neutral">right on target</string>
<string name="attendance_calculator_summary_balance_negative"><b>%1$d</b> under 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">%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_school">Absent for school reasons</string>
<string name="attendance_absence_excused">Excused absence</string> <string name="attendance_absence_excused">Excused absence</string>
<string name="attendance_absence_unexcused">Unexcused 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_grade_average_force_calc">Force average calculation by app</string>
<string name="pref_view_present">Show presence</string> <string name="pref_view_present">Show presence</string>
<string name="pref_attendance_target">Attendance target</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_attendance_calculator_sorting_mode">Attendance calculator sorting</string>
<string name="pref_view_app_theme">Theme</string> <string name="pref_view_app_theme">Theme</string>
<string name="pref_view_expand_grade">Grades expanding</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:key="@string/pref_key_attendance_calculator_sorting_mode"
app:title="@string/pref_view_attendance_calculator_sorting_mode" app:title="@string/pref_view_attendance_calculator_sorting_mode"
app:useSimpleSummaryProvider="true" /> 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>
<PreferenceCategory <PreferenceCategory
android:layout_height="wrap_content" android:layout_height="wrap_content"