[UI] Add attendance summary page. Disable presence notifications.

This commit is contained in:
Kuba Szczodrzyński
2020-05-05 22:57:24 +02:00
parent 97412a3736
commit e068f1944f
21 changed files with 500 additions and 148 deletions

View File

@ -96,8 +96,8 @@ class EdudziennikWebAttendance(override val data: DataEdudziennik,
profileId,
Metadata.TYPE_ATTENDANCE,
id,
profile.empty,
profile.empty
profile.empty || baseType == Attendance.TYPE_PRESENT_CUSTOM || baseType == Attendance.TYPE_UNKNOWN,
profile.empty || baseType == Attendance.TYPE_PRESENT_CUSTOM || baseType == Attendance.TYPE_UNKNOWN
))
}
}

View File

@ -148,8 +148,8 @@ class IdziennikWebAttendance(override val data: DataIdziennik,
profileId,
Metadata.TYPE_ATTENDANCE,
attendanceObject.id,
profile?.empty ?: false,
profile?.empty ?: false
profile?.empty ?: false || baseType == TYPE_PRESENT_CUSTOM || baseType == TYPE_UNKNOWN,
profile?.empty ?: false || baseType == TYPE_PRESENT_CUSTOM || baseType == TYPE_UNKNOWN
))
}
}

View File

@ -77,8 +77,8 @@ class LibrusApiAttendances(override val data: DataLibrus,
profileId,
Metadata.TYPE_ATTENDANCE,
id,
profile?.empty ?: false,
profile?.empty ?: false
profile?.empty ?: false || type?.baseType == Attendance.TYPE_PRESENT_CUSTOM || type?.baseType == Attendance.TYPE_UNKNOWN,
profile?.empty ?: false || type?.baseType == Attendance.TYPE_PRESENT_CUSTOM || type?.baseType == Attendance.TYPE_UNKNOWN
))
}
}

View File

@ -72,8 +72,8 @@ class MobidziennikApiAttendance(val data: DataMobidziennik, rows: List<String>)
data.profileId,
Metadata.TYPE_ATTENDANCE,
id,
data.profile?.empty ?: false,
data.profile?.empty ?: false
data.profile?.empty ?: false || baseType == Attendance.TYPE_PRESENT_CUSTOM || baseType == Attendance.TYPE_UNKNOWN,
data.profile?.empty ?: false || baseType == Attendance.TYPE_PRESENT_CUSTOM || baseType == Attendance.TYPE_UNKNOWN
))
}
}

View File

@ -175,8 +175,8 @@ class MobidziennikWebAttendance(override val data: DataMobidziennik,
data.profileId,
Metadata.TYPE_ATTENDANCE,
id,
data.profile?.empty ?: false,
data.profile?.empty ?: false
data.profile?.empty ?: false || baseType == Attendance.TYPE_PRESENT_CUSTOM || baseType == TYPE_UNKNOWN,
data.profile?.empty ?: false || baseType == Attendance.TYPE_PRESENT_CUSTOM || baseType == TYPE_UNKNOWN
))
}
}

View File

@ -73,8 +73,8 @@ class VulcanApiAttendance(override val data: DataVulcan,
profileId,
Metadata.TYPE_ATTENDANCE,
attendanceObject.id,
profile.empty,
profile.empty
profile.empty || type.baseType == Attendance.TYPE_PRESENT_CUSTOM || type.baseType == Attendance.TYPE_UNKNOWN,
profile.empty || type.baseType == Attendance.TYPE_PRESENT_CUSTOM || type.baseType == Attendance.TYPE_UNKNOWN
))
}
}

View File

@ -68,4 +68,9 @@ open class Attendance(
@Ignore
var showAsUnseen: Boolean? = null
@delegate:Ignore
val typeObject by lazy {
AttendanceType(profileId, baseType.toLong(), baseType, typeName, typeShort, typeSymbol, typeColor)
}
}

View File

@ -21,4 +21,35 @@ data class AttendanceType (
val typeSymbol: String,
/** A color that the e-register would display, null falls back to app's default */
val typeColor: Int?
)
) : Comparable<AttendanceType> {
// attendance bar order:
// day_free, present, present_custom, unknown, belated_excused, belated, released, absent_excused, absent,
override fun compareTo(other: AttendanceType): Int {
val type1 = when (baseType) {
Attendance.TYPE_DAY_FREE -> 0
Attendance.TYPE_PRESENT -> 1
Attendance.TYPE_PRESENT_CUSTOM -> 2
Attendance.TYPE_UNKNOWN -> 3
Attendance.TYPE_BELATED_EXCUSED -> 4
Attendance.TYPE_BELATED -> 5
Attendance.TYPE_RELEASED -> 6
Attendance.TYPE_ABSENT_EXCUSED -> 7
Attendance.TYPE_ABSENT -> 8
else -> 9
}
val type2 = when (other.baseType) {
Attendance.TYPE_DAY_FREE -> 0
Attendance.TYPE_PRESENT -> 1
Attendance.TYPE_PRESENT_CUSTOM -> 2
Attendance.TYPE_UNKNOWN -> 3
Attendance.TYPE_BELATED_EXCUSED -> 4
Attendance.TYPE_BELATED -> 5
Attendance.TYPE_RELEASED -> 6
Attendance.TYPE_ABSENT_EXCUSED -> 7
Attendance.TYPE_ABSENT -> 8
else -> 9
}
return type1 - type2
}
}

View File

@ -24,5 +24,6 @@ class AttendanceFull(
// metadata
var seen = false
get() = field || baseType == TYPE_PRESENT
var notified = false
}

View File

@ -93,7 +93,7 @@ class AttendanceBar : View {
val textBounds = Rect()
textPaint.getTextBounds(e.count.toString(), 0, e.count.toString().length, textBounds)
if (width > textBounds.width() + 8.dp) {
if (width > textBounds.width() + 8.dp && height > textBounds.height() + 2.dp) {
textPaint.color = Colors.legibleTextColor(e.color)
canvas.drawText(e.count.toString(), left + width / 2, bottom - height / 2 + textBounds.height()/2, textPaint)
}

View File

@ -49,7 +49,6 @@ class AttendanceListFragment : LazyFragment(), CoroutineScope {
context ?: return null
app = activity.application as App
b = AttendanceListFragmentBinding.inflate(inflater)
b.refreshLayout.setParent(activity.swipeRefreshLayout)
return b.root
}
@ -67,7 +66,7 @@ class AttendanceListFragment : LazyFragment(), CoroutineScope {
// load & configure the adapter
adapter.items = withContext(Dispatchers.Default) { processAttendance(items) }
if (items.isNotNullNorEmpty() && b.list.adapter == null) {
if (adapter.items.isNotNullNorEmpty() && b.list.adapter == null) {
b.list.adapter = adapter
b.list.apply {
setHasFixedSize(true)
@ -76,6 +75,7 @@ class AttendanceListFragment : LazyFragment(), CoroutineScope {
}
}
adapter.notifyDataSetChanged()
setSwipeToRefresh(adapter.items.isNullOrEmpty())
if (firstRun) {
expandSubject(adapter)
@ -84,7 +84,7 @@ class AttendanceListFragment : LazyFragment(), CoroutineScope {
// show/hide relevant views
b.progressBar.isVisible = false
if (items.isNullOrEmpty()) {
if (adapter.items.isNullOrEmpty()) {
b.list.isVisible = false
b.noData.isVisible = true
} else {
@ -141,6 +141,8 @@ class AttendanceListFragment : LazyFragment(), CoroutineScope {
items.sortByDescending { it.rangeStart }
val iterator = items.listIterator()
if (!iterator.hasNext())
return items.toMutableList()
var element = iterator.next()
while (iterator.hasNext()) {
var nextElement = iterator.next()
@ -170,14 +172,19 @@ class AttendanceListFragment : LazyFragment(), CoroutineScope {
items.forEach { month ->
month.typeCountMap = month.items
.groupBy { it.baseType }
.groupBy { it.typeObject }
.map { it.key to it.value.size }
.sortedBy { it.first }
.toMap()
val totalCount = month.typeCountMap.entries.sumBy { it.value }
val totalCount = month.typeCountMap.entries.sumBy {
when (it.key.baseType) {
Attendance.TYPE_UNKNOWN -> 0
else -> it.value
}
}
val presenceCount = month.typeCountMap.entries.sumBy {
when (it.key) {
when (it.key.baseType) {
Attendance.TYPE_PRESENT,
Attendance.TYPE_PRESENT_CUSTOM,
Attendance.TYPE_BELATED,

View File

@ -4,35 +4,43 @@
package pl.szczodrzynski.edziennik.ui.modules.attendance
import android.graphics.Color
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.animation.AccelerateDecelerateInterpolator
import android.view.animation.Animation
import android.view.animation.Transformation
import android.widget.LinearLayout
import android.widget.TextView
import androidx.core.graphics.ColorUtils
import androidx.core.view.isInvisible
import androidx.core.view.isVisible
import androidx.lifecycle.Observer
import androidx.recyclerview.widget.LinearLayoutManager
import kotlinx.coroutines.*
import pl.szczodrzynski.edziennik.App
import pl.szczodrzynski.edziennik.MainActivity
import pl.szczodrzynski.edziennik.*
import pl.szczodrzynski.edziennik.data.db.entity.Attendance
import pl.szczodrzynski.edziennik.data.db.full.AttendanceFull
import pl.szczodrzynski.edziennik.databinding.AttendanceListFragmentBinding
import pl.szczodrzynski.edziennik.isNotNullNorEmpty
import pl.szczodrzynski.edziennik.startCoroutineTimer
import pl.szczodrzynski.edziennik.databinding.AttendanceSummaryFragmentBinding
import pl.szczodrzynski.edziennik.ui.modules.attendance.AttendanceFragment.Companion.VIEW_SUMMARY
import pl.szczodrzynski.edziennik.ui.modules.attendance.models.AttendanceSubject
import pl.szczodrzynski.edziennik.ui.modules.base.lazypager.LazyFragment
import pl.szczodrzynski.edziennik.ui.modules.grades.models.GradesSubject
import pl.szczodrzynski.edziennik.utils.models.Date
import java.text.DecimalFormat
import kotlin.coroutines.CoroutineContext
class AttendanceSummaryFragment : LazyFragment(), CoroutineScope {
companion object {
private const val TAG = "AttendanceSummaryFragment"
private var periodSelection = 0
}
private lateinit var app: App
private lateinit var activity: MainActivity
private lateinit var b: AttendanceListFragmentBinding
private lateinit var b: AttendanceSummaryFragmentBinding
private val job: Job = Job()
override val coroutineContext: CoroutineContext
@ -41,13 +49,13 @@ class AttendanceSummaryFragment : LazyFragment(), CoroutineScope {
// local/private variables go here
private val manager by lazy { app.attendanceManager }
private var expandSubjectId = 0L
private var attendance = listOf<AttendanceFull>()
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
activity = (getActivity() as MainActivity?) ?: return null
context ?: return null
app = activity.application as App
b = AttendanceListFragmentBinding.inflate(inflater)
b.refreshLayout.setParent(activity.swipeRefreshLayout)
b = AttendanceSummaryFragmentBinding.inflate(inflater)
return b.root
}
@ -63,16 +71,17 @@ class AttendanceSummaryFragment : LazyFragment(), CoroutineScope {
if (!isAdded) return@launch
// load & configure the adapter
adapter.items = withContext(Dispatchers.Default) { processAttendance(items) }
if (items.isNotNullNorEmpty() && b.list.adapter == null) {
attendance = items
adapter.items = withContext(Dispatchers.Default) { processAttendance() }
if (adapter.items.isNotNullNorEmpty() && b.list.adapter == null) {
b.list.adapter = adapter
b.list.apply {
setHasFixedSize(true)
layoutManager = LinearLayoutManager(context)
addOnScrollListener(onScrollListener)
}
}
adapter.notifyDataSetChanged()
setSwipeToRefresh(adapter.items.isNullOrEmpty())
if (firstRun) {
expandSubject(adapter)
@ -81,10 +90,12 @@ class AttendanceSummaryFragment : LazyFragment(), CoroutineScope {
// show/hide relevant views
b.progressBar.isVisible = false
if (items.isNullOrEmpty()) {
if (adapter.items.isNullOrEmpty()) {
b.statsLayout.isVisible = false
b.list.isVisible = false
b.noData.isVisible = true
} else {
b.statsLayout.isVisible = true
b.list.isVisible = true
b.noData.isVisible = false
}
@ -93,6 +104,36 @@ class AttendanceSummaryFragment : LazyFragment(), CoroutineScope {
adapter.onAttendanceClick = {
//GradeDetailsDialog(activity, it)
}
b.toggleGroup.check(when (periodSelection) {
0 -> R.id.allYear
1 -> R.id.semester1
2 -> R.id.semester2
else -> R.id.allYear
})
b.toggleGroup.addOnButtonCheckedListener { _, checkedId, isChecked ->
if (!isChecked)
return@addOnButtonCheckedListener
periodSelection = when (checkedId) {
R.id.allYear -> 0
R.id.semester1 -> 1
R.id.semester2 -> 2
else -> 0
}
this@AttendanceSummaryFragment.launch {
adapter.items = withContext(Dispatchers.Default) { processAttendance() }
if (adapter.items.isNullOrEmpty()) {
b.statsLayout.isVisible = false
b.list.isVisible = false
b.noData.isVisible = true
} else {
b.statsLayout.isVisible = true
b.list.isVisible = true
b.noData.isVisible = false
}
adapter.notifyDataSetChanged()
}
}
}; return true}
private fun expandSubject(adapter: AttendanceAdapter) {
@ -116,7 +157,14 @@ class AttendanceSummaryFragment : LazyFragment(), CoroutineScope {
}
@Suppress("SuspendFunctionOnCoroutineScope")
private fun processAttendance(attendance: List<AttendanceFull>): MutableList<Any> {
private fun processAttendance(): MutableList<Any> {
val attendance = when (periodSelection) {
0 -> attendance
1 -> attendance.filter { it.semester == 1 }
2 -> attendance.filter { it.semester == 2 }
else -> attendance
}
if (attendance.isEmpty())
return mutableListOf()
@ -129,16 +177,24 @@ class AttendanceSummaryFragment : LazyFragment(), CoroutineScope {
) }
.sortedBy { it.subjectName.toLowerCase() }
var totalCountSum = 0
var presenceCountSum = 0
items.forEach { subject ->
subject.typeCountMap = subject.items
.groupBy { it.baseType }
.groupBy { it.typeObject }
.map { it.key to it.value.size }
.sortedBy { it.first }
.toMap()
val totalCount = subject.typeCountMap.entries.sumBy { it.value }
val totalCount = subject.typeCountMap.entries.sumBy {
when (it.key.baseType) {
Attendance.TYPE_UNKNOWN -> 0
else -> it.value
}
}
val presenceCount = subject.typeCountMap.entries.sumBy {
when (it.key) {
when (it.key.baseType) {
Attendance.TYPE_PRESENT,
Attendance.TYPE_PRESENT_CUSTOM,
Attendance.TYPE_BELATED,
@ -147,6 +203,8 @@ class AttendanceSummaryFragment : LazyFragment(), CoroutineScope {
else -> 0
}
}
totalCountSum += totalCount
presenceCountSum += presenceCount
subject.percentage = if (totalCount == 0)
0f
@ -157,6 +215,91 @@ class AttendanceSummaryFragment : LazyFragment(), CoroutineScope {
subject.items.removeAll { it.baseType == Attendance.TYPE_PRESENT }
}
val typeCountMap = attendance
.groupBy { it.typeObject }
.map { it.key to it.value.size }
.sortedBy { it.first }
.toMap()
val percentage = if (totalCountSum == 0)
0f
else
presenceCountSum.toFloat() / totalCountSum.toFloat() * 100f
launch {
b.attendanceBar.setAttendanceData(typeCountMap.mapKeys { manager.getAttendanceColor(it.key) })
b.attendanceBar.isInvisible = typeCountMap.isEmpty()
b.previewContainer.removeAllViews()
val sum = typeCountMap.entries.sumBy { it.value }.toFloat()
typeCountMap.forEach { (type, count) ->
val layout = LinearLayout(activity)
val attendanceObject = Attendance(
profileId = 0,
id = 0,
baseType = type.baseType,
typeName = "",
typeShort = type.typeShort,
typeSymbol = type.typeSymbol,
typeColor = type.typeColor,
date = Date(0, 0, 0),
startTime = null,
semester = 0,
teacherId = 0,
subjectId = 0,
addedDate = 0
)
layout.addView(AttendanceView(activity, attendanceObject, manager))
layout.addView(TextView(activity).also {
it.setText(R.string.attendance_percentage_format, count/sum*100f)
it.setPadding(0, 0, 5.dp, 0)
})
layout.setPadding(0, 8.dp, 0, 8.dp)
b.previewContainer.addView(layout)
}
if (percentage == 0f) {
b.percentage.isInvisible = true
b.percentageCircle.isInvisible = true
}
else {
b.percentage.isVisible = true
b.percentageCircle.isVisible = true
b.percentage.setText(R.string.attendance_period_summary_format, percentage)
val df = DecimalFormat("0.##")
b.percentageCircle.setProgressTextAdapter { value ->
df.format(value) + "%"
}
b.percentageCircle.maxProgress = 100.0
animatePercentageIndicator(percentage.toDouble())
}
}
return items.toMutableList()
}
private fun animatePercentageIndicator(targetProgress: Double) {
val startingProgress = b.percentageCircle.progress
val progressChange = targetProgress - startingProgress
val a: Animation = object : Animation() {
override fun applyTransformation(interpolatedTime: Float, t: Transformation) {
val progress = startingProgress + (progressChange * interpolatedTime)
//if (interpolatedTime == 1f)
// progress = startingProgress + progressChange
val color = ColorUtils.blendARGB(Color.RED, Color.GREEN, progress.toFloat() / 100.0f)
b.percentageCircle.progressColor = color
b.percentageCircle.setProgress(progress, 100.0)
}
override fun willChangeBounds(): Boolean {
return false
}
}
a.duration = 1300
a.interpolator = AccelerateDecelerateInterpolator()
b.percentageCircle.startAnimation(a)
}
}

View File

@ -5,6 +5,7 @@
package pl.szczodrzynski.edziennik.ui.modules.attendance.models
import pl.szczodrzynski.edziennik.data.db.entity.Attendance
import pl.szczodrzynski.edziennik.data.db.entity.AttendanceType
import pl.szczodrzynski.edziennik.data.db.full.AttendanceFull
import pl.szczodrzynski.edziennik.ui.modules.grades.models.ExpandableItemModel
@ -20,6 +21,6 @@ data class AttendanceMonth(
var hasUnseen: Boolean = false
get() = field || items.any { it.baseType != Attendance.TYPE_PRESENT && !it.seen }
var typeCountMap: Map<Int, Int> = mapOf()
var typeCountMap: Map<AttendanceType, Int> = mapOf()
var percentage: Float = 0f
}

View File

@ -5,6 +5,7 @@
package pl.szczodrzynski.edziennik.ui.modules.attendance.models
import pl.szczodrzynski.edziennik.data.db.entity.Attendance
import pl.szczodrzynski.edziennik.data.db.entity.AttendanceType
import pl.szczodrzynski.edziennik.data.db.full.AttendanceFull
import pl.szczodrzynski.edziennik.ui.modules.grades.models.ExpandableItemModel
@ -20,6 +21,6 @@ data class AttendanceSubject(
var hasUnseen: Boolean = false
get() = field || items.any { it.baseType != Attendance.TYPE_PRESENT && !it.seen }
var typeCountMap: Map<Int, Int> = mapOf()
var typeCountMap: Map<AttendanceType, Int> = mapOf()
var percentage: Float = 0f
}

View File

@ -63,11 +63,11 @@ class MonthViewHolder(
val attendance = Attendance(
profileId = 0,
id = 0,
baseType = type,
baseType = type.baseType,
typeName = "",
typeShort = manager.getTypeShort(type),
typeSymbol = manager.getTypeShort(type),
typeColor = manager.getAttendanceColor(type),
typeShort = type.typeShort,
typeSymbol = type.typeSymbol,
typeColor = type.typeColor,
date = Date(0, 0, 0),
startTime = null,
semester = 0,
@ -80,7 +80,7 @@ class MonthViewHolder(
it.setText(R.string.attendance_percentage_format, count/sum*100f)
it.setPadding(0, 0, 5.dp, 0)
})
layout.setPadding(0, 8.dp, 0, 0)
layout.setPadding(0, 8.dp, 0, 8.dp)
b.previewContainer.addView(layout)
}

View File

@ -6,31 +6,24 @@ package pl.szczodrzynski.edziennik.ui.modules.attendance.viewholder
import android.view.LayoutInflater
import android.view.ViewGroup
import android.widget.LinearLayout
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.view.ContextThemeWrapper
import androidx.core.view.isInvisible
import androidx.core.view.isVisible
import androidx.recyclerview.widget.RecyclerView
import pl.szczodrzynski.edziennik.App
import pl.szczodrzynski.edziennik.R
import pl.szczodrzynski.edziennik.data.db.entity.Attendance
import pl.szczodrzynski.edziennik.databinding.AttendanceItemContainerBarBinding
import pl.szczodrzynski.edziennik.dp
import pl.szczodrzynski.edziennik.databinding.AttendanceItemContainerSubjectBinding
import pl.szczodrzynski.edziennik.setText
import pl.szczodrzynski.edziennik.ui.modules.attendance.AttendanceAdapter
import pl.szczodrzynski.edziennik.ui.modules.attendance.AttendanceAdapter.Companion.STATE_CLOSED
import pl.szczodrzynski.edziennik.ui.modules.attendance.AttendanceView
import pl.szczodrzynski.edziennik.ui.modules.attendance.models.AttendanceSubject
import pl.szczodrzynski.edziennik.ui.modules.grades.viewholder.BindableViewHolder
import pl.szczodrzynski.edziennik.utils.Themes
import pl.szczodrzynski.edziennik.utils.models.Date
class SubjectViewHolder(
inflater: LayoutInflater,
parent: ViewGroup,
val b: AttendanceItemContainerBarBinding = AttendanceItemContainerBarBinding.inflate(inflater, parent, false)
val b: AttendanceItemContainerSubjectBinding = AttendanceItemContainerSubjectBinding.inflate(inflater, parent, false)
) : RecyclerView.ViewHolder(b.root), BindableViewHolder<AttendanceSubject, AttendanceAdapter> {
companion object {
private const val TAG = "SubjectViewHolder"
@ -51,48 +44,14 @@ class SubjectViewHolder(
b.attendanceBar.setAttendanceData(item.typeCountMap.mapKeys { manager.getAttendanceColor(it.key) })
b.previewContainer.isInvisible = item.state != STATE_CLOSED
b.summaryContainer.isInvisible = item.state == STATE_CLOSED
b.percentage.isVisible = item.state == STATE_CLOSED
b.previewContainer.removeAllViews()
val sum = item.typeCountMap.entries.sumBy { it.value }.toFloat()
item.typeCountMap.forEach { (type, count) ->
val layout = LinearLayout(contextWrapper)
val attendance = Attendance(
profileId = 0,
id = 0,
baseType = type,
typeName = "",
typeShort = manager.getTypeShort(type),
typeSymbol = manager.getTypeShort(type),
typeColor = manager.getAttendanceColor(type),
date = Date(0, 0, 0),
startTime = null,
semester = 0,
teacherId = 0,
subjectId = 0,
addedDate = 0
)
layout.addView(AttendanceView(contextWrapper, attendance, manager))
layout.addView(TextView(contextWrapper).also {
it.setText(R.string.attendance_percentage_format, count/sum*100f)
it.setPadding(0, 0, 5.dp, 0)
})
layout.setPadding(0, 8.dp, 0, 0)
b.previewContainer.addView(layout)
}
b.percentage.isVisible = true
if (item.percentage == 0f) {
b.percentage.isVisible = false
b.percentage.text = null
b.summaryContainer.isVisible = false
b.summaryContainer.text = null
}
else {
b.percentage.setText(R.string.attendance_percentage_format, item.percentage)
b.summaryContainer.setText(R.string.attendance_period_summary_format, item.percentage)
}
}
}

View File

@ -9,6 +9,7 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import pl.szczodrzynski.edziennik.App
import pl.szczodrzynski.edziennik.data.db.entity.Attendance
import pl.szczodrzynski.edziennik.data.db.entity.AttendanceType
import pl.szczodrzynski.edziennik.data.db.full.AttendanceFull
import pl.szczodrzynski.edziennik.startCoroutineTimer
import kotlin.coroutines.CoroutineContext
@ -49,6 +50,12 @@ class AttendanceManager(val app: App) : CoroutineScope {
else -> 0xff64b5f6.toInt()
}
}
fun getAttendanceColor(typeObject: AttendanceType): Int {
return (if (useSymbols) typeObject.typeColor else null) ?: when (typeObject.baseType) {
Attendance.TYPE_PRESENT_CUSTOM -> typeObject.typeColor ?: 0xff64b5f6.toInt()
else -> getAttendanceColor(typeObject.baseType)
}
}
fun getAttendanceColor(attendance: Attendance): Int {
return (if (useSymbols) attendance.typeColor else null) ?: when (attendance.baseType) {
Attendance.TYPE_PRESENT_CUSTOM -> attendance.typeColor ?: 0xff64b5f6.toInt()