mirror of
https://github.com/szkolny-eu/szkolny-android.git
synced 2025-01-31 05:48:19 +01:00
[UI] Add listing attendance by type.
This commit is contained in:
parent
c49755c0eb
commit
192dd0c4c7
@ -15,6 +15,7 @@ import pl.szczodrzynski.edziennik.data.db.entity.Attendance.Companion.TYPE_ABSEN
|
|||||||
import pl.szczodrzynski.edziennik.data.db.entity.Attendance.Companion.TYPE_ABSENT_EXCUSED
|
import pl.szczodrzynski.edziennik.data.db.entity.Attendance.Companion.TYPE_ABSENT_EXCUSED
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Attendance.Companion.TYPE_BELATED
|
import pl.szczodrzynski.edziennik.data.db.entity.Attendance.Companion.TYPE_BELATED
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Attendance.Companion.TYPE_PRESENT
|
import pl.szczodrzynski.edziennik.data.db.entity.Attendance.Companion.TYPE_PRESENT
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.Attendance.Companion.TYPE_PRESENT_CUSTOM
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Attendance.Companion.TYPE_RELEASED
|
import pl.szczodrzynski.edziennik.data.db.entity.Attendance.Companion.TYPE_RELEASED
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Attendance.Companion.TYPE_UNKNOWN
|
import pl.szczodrzynski.edziennik.data.db.entity.Attendance.Companion.TYPE_UNKNOWN
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
||||||
@ -132,13 +133,22 @@ class MobidziennikWebAttendance(override val data: DataMobidziennik,
|
|||||||
}
|
}
|
||||||
entry = entry.removePrefix(typeSymbol)
|
entry = entry.removePrefix(typeSymbol)
|
||||||
|
|
||||||
|
var isCounted = true
|
||||||
val baseType = when (typeSymbol) {
|
val baseType = when (typeSymbol) {
|
||||||
"." -> TYPE_PRESENT
|
"." -> TYPE_PRESENT
|
||||||
"|" -> TYPE_ABSENT
|
"|" -> TYPE_ABSENT
|
||||||
"+" -> TYPE_ABSENT_EXCUSED
|
"+" -> TYPE_ABSENT_EXCUSED
|
||||||
"s" -> TYPE_BELATED
|
"s" -> TYPE_BELATED
|
||||||
"z" -> TYPE_RELEASED
|
"z" -> TYPE_RELEASED
|
||||||
else -> TYPE_UNKNOWN
|
else -> {
|
||||||
|
isCounted = false
|
||||||
|
when (typeSymbol) {
|
||||||
|
"e" -> TYPE_PRESENT_CUSTOM
|
||||||
|
"en" -> TYPE_ABSENT
|
||||||
|
"ep" -> TYPE_PRESENT_CUSTOM
|
||||||
|
else -> TYPE_UNKNOWN
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
val typeName = types?.get(typeSymbol) ?: ""
|
val typeName = types?.get(typeSymbol) ?: ""
|
||||||
|
|
||||||
@ -166,6 +176,7 @@ class MobidziennikWebAttendance(override val data: DataMobidziennik,
|
|||||||
subjectId = subjectId
|
subjectId = subjectId
|
||||||
).also {
|
).also {
|
||||||
it.lessonTopic = topic
|
it.lessonTopic = topic
|
||||||
|
it.isCounted = isCounted
|
||||||
}
|
}
|
||||||
|
|
||||||
data.attendanceList.add(attendanceObject)
|
data.attendanceList.add(attendanceObject)
|
||||||
|
@ -43,7 +43,7 @@ import pl.szczodrzynski.edziennik.data.db.migration.*
|
|||||||
LibrusLesson::class,
|
LibrusLesson::class,
|
||||||
TimetableManual::class,
|
TimetableManual::class,
|
||||||
Metadata::class
|
Metadata::class
|
||||||
], version = 86)
|
], version = 87)
|
||||||
@TypeConverters(
|
@TypeConverters(
|
||||||
ConverterTime::class,
|
ConverterTime::class,
|
||||||
ConverterDate::class,
|
ConverterDate::class,
|
||||||
@ -171,7 +171,8 @@ abstract class AppDb : RoomDatabase() {
|
|||||||
Migration83(),
|
Migration83(),
|
||||||
Migration84(),
|
Migration84(),
|
||||||
Migration85(),
|
Migration85(),
|
||||||
Migration86()
|
Migration86(),
|
||||||
|
Migration87()
|
||||||
).allowMainThreadQueries().build()
|
).allowMainThreadQueries().build()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -65,6 +65,8 @@ open class Attendance(
|
|||||||
var lessonTopic: String? = null
|
var lessonTopic: String? = null
|
||||||
@ColumnInfo(name = "attendanceLessonNumber")
|
@ColumnInfo(name = "attendanceLessonNumber")
|
||||||
var lessonNumber: Int? = null
|
var lessonNumber: Int? = null
|
||||||
|
@ColumnInfo(name = "attendanceIsCounted")
|
||||||
|
var isCounted: Boolean = true
|
||||||
|
|
||||||
@Ignore
|
@Ignore
|
||||||
var showAsUnseen: Boolean? = null
|
var showAsUnseen: Boolean? = null
|
||||||
|
@ -0,0 +1,14 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Kuba Szczodrzyński 2020-5-8.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package pl.szczodrzynski.edziennik.data.db.migration
|
||||||
|
|
||||||
|
import androidx.room.migration.Migration
|
||||||
|
import androidx.sqlite.db.SupportSQLiteDatabase
|
||||||
|
|
||||||
|
class Migration87 : Migration(86, 87) {
|
||||||
|
override fun migrate(database: SupportSQLiteDatabase) {
|
||||||
|
database.execSQL("ALTER TABLE attendances ADD COLUMN attendanceIsCounted INTEGER NOT NULL DEFAULT 1")
|
||||||
|
}
|
||||||
|
}
|
@ -19,10 +19,7 @@ import pl.szczodrzynski.edziennik.App
|
|||||||
import pl.szczodrzynski.edziennik.R
|
import pl.szczodrzynski.edziennik.R
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.AttendanceFull
|
import pl.szczodrzynski.edziennik.data.db.full.AttendanceFull
|
||||||
import pl.szczodrzynski.edziennik.startCoroutineTimer
|
import pl.szczodrzynski.edziennik.startCoroutineTimer
|
||||||
import pl.szczodrzynski.edziennik.ui.modules.attendance.models.AttendanceDayRange
|
import pl.szczodrzynski.edziennik.ui.modules.attendance.models.*
|
||||||
import pl.szczodrzynski.edziennik.ui.modules.attendance.models.AttendanceEmpty
|
|
||||||
import pl.szczodrzynski.edziennik.ui.modules.attendance.models.AttendanceMonth
|
|
||||||
import pl.szczodrzynski.edziennik.ui.modules.attendance.models.AttendanceSubject
|
|
||||||
import pl.szczodrzynski.edziennik.ui.modules.attendance.viewholder.*
|
import pl.szczodrzynski.edziennik.ui.modules.attendance.viewholder.*
|
||||||
import pl.szczodrzynski.edziennik.ui.modules.grades.models.ExpandableItemModel
|
import pl.szczodrzynski.edziennik.ui.modules.grades.models.ExpandableItemModel
|
||||||
import pl.szczodrzynski.edziennik.ui.modules.grades.viewholder.BindableViewHolder
|
import pl.szczodrzynski.edziennik.ui.modules.grades.viewholder.BindableViewHolder
|
||||||
@ -39,7 +36,8 @@ class AttendanceAdapter(
|
|||||||
private const val ITEM_TYPE_DAY_RANGE = 1
|
private const val ITEM_TYPE_DAY_RANGE = 1
|
||||||
private const val ITEM_TYPE_MONTH = 2
|
private const val ITEM_TYPE_MONTH = 2
|
||||||
private const val ITEM_TYPE_SUBJECT = 3
|
private const val ITEM_TYPE_SUBJECT = 3
|
||||||
private const val ITEM_TYPE_EMPTY = 4
|
private const val ITEM_TYPE_TYPE = 4
|
||||||
|
private const val ITEM_TYPE_EMPTY = 5
|
||||||
const val STATE_CLOSED = 0
|
const val STATE_CLOSED = 0
|
||||||
const val STATE_OPENED = 1
|
const val STATE_OPENED = 1
|
||||||
}
|
}
|
||||||
@ -60,6 +58,7 @@ class AttendanceAdapter(
|
|||||||
ITEM_TYPE_DAY_RANGE -> DayRangeViewHolder(inflater, parent)
|
ITEM_TYPE_DAY_RANGE -> DayRangeViewHolder(inflater, parent)
|
||||||
ITEM_TYPE_MONTH -> MonthViewHolder(inflater, parent)
|
ITEM_TYPE_MONTH -> MonthViewHolder(inflater, parent)
|
||||||
ITEM_TYPE_SUBJECT -> SubjectViewHolder(inflater, parent)
|
ITEM_TYPE_SUBJECT -> SubjectViewHolder(inflater, parent)
|
||||||
|
ITEM_TYPE_TYPE -> TypeViewHolder(inflater, parent)
|
||||||
ITEM_TYPE_EMPTY -> EmptyViewHolder(inflater, parent)
|
ITEM_TYPE_EMPTY -> EmptyViewHolder(inflater, parent)
|
||||||
else -> throw IllegalArgumentException("Incorrect viewType")
|
else -> throw IllegalArgumentException("Incorrect viewType")
|
||||||
}
|
}
|
||||||
@ -71,6 +70,7 @@ class AttendanceAdapter(
|
|||||||
is AttendanceDayRange -> ITEM_TYPE_DAY_RANGE
|
is AttendanceDayRange -> ITEM_TYPE_DAY_RANGE
|
||||||
is AttendanceMonth -> ITEM_TYPE_MONTH
|
is AttendanceMonth -> ITEM_TYPE_MONTH
|
||||||
is AttendanceSubject -> ITEM_TYPE_SUBJECT
|
is AttendanceSubject -> ITEM_TYPE_SUBJECT
|
||||||
|
is AttendanceTypeGroup -> ITEM_TYPE_TYPE
|
||||||
is AttendanceEmpty -> ITEM_TYPE_EMPTY
|
is AttendanceEmpty -> ITEM_TYPE_EMPTY
|
||||||
else -> throw IllegalArgumentException("Incorrect viewType")
|
else -> throw IllegalArgumentException("Incorrect viewType")
|
||||||
}
|
}
|
||||||
@ -102,7 +102,7 @@ class AttendanceAdapter(
|
|||||||
).setDuration(200).start();
|
).setDuration(200).start();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (model is AttendanceDayRange || model is AttendanceMonth) {
|
if (model is AttendanceDayRange || model is AttendanceMonth || model is AttendanceTypeGroup) {
|
||||||
// hide the preview, show summary
|
// hide the preview, show summary
|
||||||
val preview = view?.findViewById<View>(R.id.previewContainer)
|
val preview = view?.findViewById<View>(R.id.previewContainer)
|
||||||
val summary = view?.findViewById<View>(R.id.summaryContainer)
|
val summary = view?.findViewById<View>(R.id.summaryContainer)
|
||||||
@ -158,6 +158,7 @@ class AttendanceAdapter(
|
|||||||
is DayRangeViewHolder -> ITEM_TYPE_DAY_RANGE
|
is DayRangeViewHolder -> ITEM_TYPE_DAY_RANGE
|
||||||
is MonthViewHolder -> ITEM_TYPE_MONTH
|
is MonthViewHolder -> ITEM_TYPE_MONTH
|
||||||
is SubjectViewHolder -> ITEM_TYPE_SUBJECT
|
is SubjectViewHolder -> ITEM_TYPE_SUBJECT
|
||||||
|
is TypeViewHolder -> ITEM_TYPE_TYPE
|
||||||
is EmptyViewHolder -> ITEM_TYPE_EMPTY
|
is EmptyViewHolder -> ITEM_TYPE_EMPTY
|
||||||
else -> throw IllegalArgumentException("Incorrect viewType")
|
else -> throw IllegalArgumentException("Incorrect viewType")
|
||||||
}
|
}
|
||||||
@ -170,6 +171,7 @@ class AttendanceAdapter(
|
|||||||
holder is DayRangeViewHolder && item is AttendanceDayRange -> holder.onBind(activity, app, item, position, this)
|
holder is DayRangeViewHolder && item is AttendanceDayRange -> holder.onBind(activity, app, item, position, this)
|
||||||
holder is MonthViewHolder && item is AttendanceMonth -> holder.onBind(activity, app, item, position, this)
|
holder is MonthViewHolder && item is AttendanceMonth -> holder.onBind(activity, app, item, position, this)
|
||||||
holder is SubjectViewHolder && item is AttendanceSubject -> holder.onBind(activity, app, item, position, this)
|
holder is SubjectViewHolder && item is AttendanceSubject -> holder.onBind(activity, app, item, position, this)
|
||||||
|
holder is TypeViewHolder && item is AttendanceTypeGroup -> holder.onBind(activity, app, item, position, this)
|
||||||
holder is EmptyViewHolder && item is AttendanceEmpty -> holder.onBind(activity, app, item, position, this)
|
holder is EmptyViewHolder && item is AttendanceEmpty -> holder.onBind(activity, app, item, position, this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,10 +27,11 @@ import kotlin.coroutines.CoroutineContext
|
|||||||
class AttendanceFragment : Fragment(), CoroutineScope {
|
class AttendanceFragment : Fragment(), CoroutineScope {
|
||||||
companion object {
|
companion object {
|
||||||
private const val TAG = "AttendanceFragment"
|
private const val TAG = "AttendanceFragment"
|
||||||
const val VIEW_DAYS = 0
|
const val VIEW_SUMMARY = 0
|
||||||
const val VIEW_MONTHS = 1
|
const val VIEW_DAYS = 1
|
||||||
const val VIEW_SUMMARY = 2
|
const val VIEW_MONTHS = 2
|
||||||
const val VIEW_LIST = 3
|
const val VIEW_TYPES = 3
|
||||||
|
const val VIEW_LIST = 4
|
||||||
var pageSelection = 1
|
var pageSelection = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,6 +94,10 @@ class AttendanceFragment : Fragment(), CoroutineScope {
|
|||||||
arguments = Bundle("viewType" to VIEW_MONTHS)
|
arguments = Bundle("viewType" to VIEW_MONTHS)
|
||||||
} to getString(R.string.attendance_tab_months),
|
} to getString(R.string.attendance_tab_months),
|
||||||
|
|
||||||
|
AttendanceListFragment().apply {
|
||||||
|
arguments = Bundle("viewType" to VIEW_TYPES)
|
||||||
|
} to getString(R.string.attendance_tab_types),
|
||||||
|
|
||||||
AttendanceListFragment().apply {
|
AttendanceListFragment().apply {
|
||||||
arguments = Bundle("viewType" to VIEW_LIST)
|
arguments = Bundle("viewType" to VIEW_LIST)
|
||||||
} to getString(R.string.attendance_tab_list)
|
} to getString(R.string.attendance_tab_list)
|
||||||
|
@ -21,6 +21,7 @@ import pl.szczodrzynski.edziennik.isNotNullNorEmpty
|
|||||||
import pl.szczodrzynski.edziennik.startCoroutineTimer
|
import pl.szczodrzynski.edziennik.startCoroutineTimer
|
||||||
import pl.szczodrzynski.edziennik.ui.modules.attendance.models.AttendanceDayRange
|
import pl.szczodrzynski.edziennik.ui.modules.attendance.models.AttendanceDayRange
|
||||||
import pl.szczodrzynski.edziennik.ui.modules.attendance.models.AttendanceMonth
|
import pl.szczodrzynski.edziennik.ui.modules.attendance.models.AttendanceMonth
|
||||||
|
import pl.szczodrzynski.edziennik.ui.modules.attendance.models.AttendanceTypeGroup
|
||||||
import pl.szczodrzynski.edziennik.ui.modules.base.lazypager.LazyFragment
|
import pl.szczodrzynski.edziennik.ui.modules.base.lazypager.LazyFragment
|
||||||
import pl.szczodrzynski.edziennik.ui.modules.grades.models.GradesSubject
|
import pl.szczodrzynski.edziennik.ui.modules.grades.models.GradesSubject
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||||
@ -146,7 +147,7 @@ class AttendanceListFragment : LazyFragment(), CoroutineScope {
|
|||||||
var element = iterator.next()
|
var element = iterator.next()
|
||||||
while (iterator.hasNext()) {
|
while (iterator.hasNext()) {
|
||||||
var nextElement = iterator.next()
|
var nextElement = iterator.next()
|
||||||
while (Date.diffDays(element.rangeStart, nextElement.rangeStart) <= 1) {
|
while (Date.diffDays(element.rangeStart, nextElement.rangeStart) <= 1 && iterator.hasNext()) {
|
||||||
if (element.rangeEnd == null)
|
if (element.rangeEnd == null)
|
||||||
element.rangeEnd = element.rangeStart
|
element.rangeEnd = element.rangeStart
|
||||||
|
|
||||||
@ -173,7 +174,7 @@ class AttendanceListFragment : LazyFragment(), CoroutineScope {
|
|||||||
items.forEach { month ->
|
items.forEach { month ->
|
||||||
month.typeCountMap = month.items
|
month.typeCountMap = month.items
|
||||||
.groupBy { it.typeObject }
|
.groupBy { it.typeObject }
|
||||||
.map { it.key to it.value.size }
|
.map { it.key to it.value.count { a -> a.isCounted } }
|
||||||
.sortedBy { it.first }
|
.sortedBy { it.first }
|
||||||
.toMap()
|
.toMap()
|
||||||
|
|
||||||
@ -205,6 +206,25 @@ class AttendanceListFragment : LazyFragment(), CoroutineScope {
|
|||||||
|
|
||||||
return items.toMutableList()
|
return items.toMutableList()
|
||||||
}
|
}
|
||||||
|
else if (viewType == AttendanceFragment.VIEW_TYPES) {
|
||||||
|
val items = attendance
|
||||||
|
.groupBy { it.typeObject }
|
||||||
|
.map { AttendanceTypeGroup(
|
||||||
|
type = it.key,
|
||||||
|
items = it.value.toMutableList()
|
||||||
|
) }
|
||||||
|
|
||||||
|
items.forEach { type ->
|
||||||
|
type.percentage = if (attendance.isEmpty())
|
||||||
|
0f
|
||||||
|
else
|
||||||
|
type.items.size.toFloat() / attendance.size.toFloat() * 100f
|
||||||
|
|
||||||
|
type.semesterCount = type.items.count { it.semester == app.profile.currentSemester }
|
||||||
|
}
|
||||||
|
|
||||||
|
return items.toMutableList()
|
||||||
|
}
|
||||||
return attendance.filter { it.baseType != Attendance.TYPE_PRESENT }.toMutableList()
|
return attendance.filter { it.baseType != Attendance.TYPE_PRESENT }.toMutableList()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -78,6 +78,7 @@ class AttendanceSummaryFragment : LazyFragment(), CoroutineScope {
|
|||||||
b.list.apply {
|
b.list.apply {
|
||||||
setHasFixedSize(true)
|
setHasFixedSize(true)
|
||||||
layoutManager = LinearLayoutManager(context)
|
layoutManager = LinearLayoutManager(context)
|
||||||
|
isNestedScrollingEnabled = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
adapter.notifyDataSetChanged()
|
adapter.notifyDataSetChanged()
|
||||||
@ -183,7 +184,7 @@ class AttendanceSummaryFragment : LazyFragment(), CoroutineScope {
|
|||||||
items.forEach { subject ->
|
items.forEach { subject ->
|
||||||
subject.typeCountMap = subject.items
|
subject.typeCountMap = subject.items
|
||||||
.groupBy { it.typeObject }
|
.groupBy { it.typeObject }
|
||||||
.map { it.key to it.value.size }
|
.map { it.key to it.value.count { a -> a.isCounted } }
|
||||||
.sortedBy { it.first }
|
.sortedBy { it.first }
|
||||||
.toMap()
|
.toMap()
|
||||||
|
|
||||||
@ -217,7 +218,7 @@ class AttendanceSummaryFragment : LazyFragment(), CoroutineScope {
|
|||||||
|
|
||||||
val typeCountMap = attendance
|
val typeCountMap = attendance
|
||||||
.groupBy { it.typeObject }
|
.groupBy { it.typeObject }
|
||||||
.map { it.key to it.value.size }
|
.map { it.key to it.value.count { a -> a.isCounted } }
|
||||||
.sortedBy { it.first }
|
.sortedBy { it.first }
|
||||||
.toMap()
|
.toMap()
|
||||||
|
|
||||||
|
@ -0,0 +1,25 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Kuba Szczodrzyński 2020-5-8.
|
||||||
|
*/
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
data class AttendanceTypeGroup(
|
||||||
|
val type: AttendanceType,
|
||||||
|
override val items: MutableList<AttendanceFull> = mutableListOf()
|
||||||
|
) : ExpandableItemModel<AttendanceFull>(items) {
|
||||||
|
override var level = 1
|
||||||
|
|
||||||
|
var lastAddedDate = 0L
|
||||||
|
|
||||||
|
var hasUnseen: Boolean = false
|
||||||
|
get() = field || items.any { it.baseType != Attendance.TYPE_PRESENT && !it.seen }
|
||||||
|
|
||||||
|
var percentage: Float = 0f
|
||||||
|
var semesterCount: Int = 0
|
||||||
|
}
|
@ -21,6 +21,7 @@ import pl.szczodrzynski.edziennik.ui.modules.attendance.models.AttendanceMonth
|
|||||||
import pl.szczodrzynski.edziennik.ui.modules.grades.models.ExpandableItemModel
|
import pl.szczodrzynski.edziennik.ui.modules.grades.models.ExpandableItemModel
|
||||||
import pl.szczodrzynski.edziennik.ui.modules.grades.viewholder.BindableViewHolder
|
import pl.szczodrzynski.edziennik.ui.modules.grades.viewholder.BindableViewHolder
|
||||||
import pl.szczodrzynski.edziennik.utils.Themes
|
import pl.szczodrzynski.edziennik.utils.Themes
|
||||||
|
import pl.szczodrzynski.edziennik.utils.models.Week
|
||||||
|
|
||||||
class AttendanceViewHolder(
|
class AttendanceViewHolder(
|
||||||
inflater: LayoutInflater,
|
inflater: LayoutInflater,
|
||||||
@ -42,6 +43,7 @@ class AttendanceViewHolder(
|
|||||||
b.type.text = item.typeName
|
b.type.text = item.typeName
|
||||||
b.subjectName.text = item.subjectLongName ?: item.lessonTopic
|
b.subjectName.text = item.subjectLongName ?: item.lessonTopic
|
||||||
b.dateTime.text = listOf(
|
b.dateTime.text = listOf(
|
||||||
|
Week.getFullDayName(item.date.weekDay),
|
||||||
item.date.formattedStringShort,
|
item.date.formattedStringShort,
|
||||||
item.startTime?.stringHM,
|
item.startTime?.stringHM,
|
||||||
item.lessonNumber?.let { app.getString(R.string.attendance_lesson_number_format, it) }
|
item.lessonNumber?.let { app.getString(R.string.attendance_lesson_number_format, it) }
|
||||||
|
@ -16,7 +16,7 @@ import pl.szczodrzynski.edziennik.App
|
|||||||
import pl.szczodrzynski.edziennik.R
|
import pl.szczodrzynski.edziennik.R
|
||||||
import pl.szczodrzynski.edziennik.concat
|
import pl.szczodrzynski.edziennik.concat
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Attendance
|
import pl.szczodrzynski.edziennik.data.db.entity.Attendance
|
||||||
import pl.szczodrzynski.edziennik.databinding.AttendanceItemContainerBinding
|
import pl.szczodrzynski.edziennik.databinding.AttendanceItemDayRangeBinding
|
||||||
import pl.szczodrzynski.edziennik.ui.modules.attendance.AttendanceAdapter
|
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.AttendanceAdapter.Companion.STATE_CLOSED
|
||||||
import pl.szczodrzynski.edziennik.ui.modules.attendance.AttendanceView
|
import pl.szczodrzynski.edziennik.ui.modules.attendance.AttendanceView
|
||||||
@ -27,7 +27,7 @@ import pl.szczodrzynski.edziennik.utils.Themes
|
|||||||
class DayRangeViewHolder(
|
class DayRangeViewHolder(
|
||||||
inflater: LayoutInflater,
|
inflater: LayoutInflater,
|
||||||
parent: ViewGroup,
|
parent: ViewGroup,
|
||||||
val b: AttendanceItemContainerBinding = AttendanceItemContainerBinding.inflate(inflater, parent, false)
|
val b: AttendanceItemDayRangeBinding = AttendanceItemDayRangeBinding.inflate(inflater, parent, false)
|
||||||
) : RecyclerView.ViewHolder(b.root), BindableViewHolder<AttendanceDayRange, AttendanceAdapter> {
|
) : RecyclerView.ViewHolder(b.root), BindableViewHolder<AttendanceDayRange, AttendanceAdapter> {
|
||||||
companion object {
|
companion object {
|
||||||
private const val TAG = "DayRangeViewHolder"
|
private const val TAG = "DayRangeViewHolder"
|
||||||
|
@ -15,7 +15,7 @@ import androidx.core.view.isVisible
|
|||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import pl.szczodrzynski.edziennik.*
|
import pl.szczodrzynski.edziennik.*
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Attendance
|
import pl.szczodrzynski.edziennik.data.db.entity.Attendance
|
||||||
import pl.szczodrzynski.edziennik.databinding.AttendanceItemContainerBarBinding
|
import pl.szczodrzynski.edziennik.databinding.AttendanceItemMonthBinding
|
||||||
import pl.szczodrzynski.edziennik.ui.modules.attendance.AttendanceAdapter
|
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.AttendanceAdapter.Companion.STATE_CLOSED
|
||||||
import pl.szczodrzynski.edziennik.ui.modules.attendance.AttendanceView
|
import pl.szczodrzynski.edziennik.ui.modules.attendance.AttendanceView
|
||||||
@ -27,7 +27,7 @@ import pl.szczodrzynski.edziennik.utils.models.Date
|
|||||||
class MonthViewHolder(
|
class MonthViewHolder(
|
||||||
inflater: LayoutInflater,
|
inflater: LayoutInflater,
|
||||||
parent: ViewGroup,
|
parent: ViewGroup,
|
||||||
val b: AttendanceItemContainerBarBinding = AttendanceItemContainerBarBinding.inflate(inflater, parent, false)
|
val b: AttendanceItemMonthBinding = AttendanceItemMonthBinding.inflate(inflater, parent, false)
|
||||||
) : RecyclerView.ViewHolder(b.root), BindableViewHolder<AttendanceMonth, AttendanceAdapter> {
|
) : RecyclerView.ViewHolder(b.root), BindableViewHolder<AttendanceMonth, AttendanceAdapter> {
|
||||||
companion object {
|
companion object {
|
||||||
private const val TAG = "MonthViewHolder"
|
private const val TAG = "MonthViewHolder"
|
||||||
@ -80,7 +80,7 @@ class MonthViewHolder(
|
|||||||
it.setText(R.string.attendance_percentage_format, count/sum*100f)
|
it.setText(R.string.attendance_percentage_format, count/sum*100f)
|
||||||
it.setPadding(0, 0, 5.dp, 0)
|
it.setPadding(0, 0, 5.dp, 0)
|
||||||
})
|
})
|
||||||
layout.setPadding(0, 8.dp, 0, 8.dp)
|
layout.setPadding(0, 8.dp, 0, 0)
|
||||||
b.previewContainer.addView(layout)
|
b.previewContainer.addView(layout)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ import androidx.core.view.isVisible
|
|||||||
import androidx.recyclerview.widget.RecyclerView
|
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.AttendanceItemContainerSubjectBinding
|
import pl.szczodrzynski.edziennik.databinding.AttendanceItemSubjectBinding
|
||||||
import pl.szczodrzynski.edziennik.setText
|
import pl.szczodrzynski.edziennik.setText
|
||||||
import pl.szczodrzynski.edziennik.ui.modules.attendance.AttendanceAdapter
|
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.AttendanceAdapter.Companion.STATE_CLOSED
|
||||||
@ -23,7 +23,7 @@ import pl.szczodrzynski.edziennik.utils.Themes
|
|||||||
class SubjectViewHolder(
|
class SubjectViewHolder(
|
||||||
inflater: LayoutInflater,
|
inflater: LayoutInflater,
|
||||||
parent: ViewGroup,
|
parent: ViewGroup,
|
||||||
val b: AttendanceItemContainerSubjectBinding = AttendanceItemContainerSubjectBinding.inflate(inflater, parent, false)
|
val b: AttendanceItemSubjectBinding = AttendanceItemSubjectBinding.inflate(inflater, parent, false)
|
||||||
) : RecyclerView.ViewHolder(b.root), BindableViewHolder<AttendanceSubject, AttendanceAdapter> {
|
) : RecyclerView.ViewHolder(b.root), BindableViewHolder<AttendanceSubject, AttendanceAdapter> {
|
||||||
companion object {
|
companion object {
|
||||||
private const val TAG = "SubjectViewHolder"
|
private const val TAG = "SubjectViewHolder"
|
||||||
|
@ -0,0 +1,64 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Kuba Szczodrzyński 2020-5-8.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package pl.szczodrzynski.edziennik.ui.modules.attendance.viewholder
|
||||||
|
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import androidx.appcompat.view.ContextThemeWrapper
|
||||||
|
import androidx.core.view.isVisible
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import pl.szczodrzynski.edziennik.App
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.Attendance
|
||||||
|
import pl.szczodrzynski.edziennik.databinding.AttendanceItemTypeBinding
|
||||||
|
import pl.szczodrzynski.edziennik.ui.modules.attendance.AttendanceAdapter
|
||||||
|
import pl.szczodrzynski.edziennik.ui.modules.attendance.models.AttendanceTypeGroup
|
||||||
|
import pl.szczodrzynski.edziennik.ui.modules.grades.viewholder.BindableViewHolder
|
||||||
|
import pl.szczodrzynski.edziennik.utils.Themes
|
||||||
|
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||||
|
|
||||||
|
class TypeViewHolder(
|
||||||
|
inflater: LayoutInflater,
|
||||||
|
parent: ViewGroup,
|
||||||
|
val b: AttendanceItemTypeBinding = AttendanceItemTypeBinding.inflate(inflater, parent, false)
|
||||||
|
) : RecyclerView.ViewHolder(b.root), BindableViewHolder<AttendanceTypeGroup, AttendanceAdapter> {
|
||||||
|
companion object {
|
||||||
|
private const val TAG = "TypeViewHolder"
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onBind(activity: AppCompatActivity, app: App, item: AttendanceTypeGroup, position: Int, adapter: AttendanceAdapter) {
|
||||||
|
val manager = app.attendanceManager
|
||||||
|
val contextWrapper = ContextThemeWrapper(activity, Themes.appTheme)
|
||||||
|
|
||||||
|
val type = item.type
|
||||||
|
b.title.text = type.typeName
|
||||||
|
|
||||||
|
b.dropdownIcon.rotation = when (item.state) {
|
||||||
|
AttendanceAdapter.STATE_CLOSED -> 0f
|
||||||
|
else -> 180f
|
||||||
|
}
|
||||||
|
|
||||||
|
b.unread.isVisible = item.hasUnseen
|
||||||
|
|
||||||
|
b.previewContainer.visibility = if (item.state == AttendanceAdapter.STATE_CLOSED) View.VISIBLE else View.INVISIBLE
|
||||||
|
|
||||||
|
b.type.setAttendance(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
|
||||||
|
), manager, bigView = false)
|
||||||
|
}
|
||||||
|
}
|
@ -86,6 +86,7 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginHorizontal="8dp"
|
android:layout_marginHorizontal="8dp"
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
|
android:paddingBottom="8dp"
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
app:flexWrap="wrap"
|
app:flexWrap="wrap"
|
||||||
tools:visibility="visible">
|
tools:visibility="visible">
|
||||||
@ -93,7 +94,7 @@
|
|||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:paddingVertical="8dp">
|
android:paddingTop="8dp">
|
||||||
|
|
||||||
<pl.szczodrzynski.edziennik.ui.modules.attendance.AttendanceView
|
<pl.szczodrzynski.edziennik.ui.modules.attendance.AttendanceView
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
106
app/src/main/res/layout/attendance_item_type.xml
Normal file
106
app/src/main/res/layout/attendance_item_type.xml
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
~ Copyright (c) Kuba Szczodrzyński 2020-5-8.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:background="?selectableItemBackground">
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="1dp"
|
||||||
|
android:background="@drawable/divider"/>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="8dp"
|
||||||
|
android:layout_marginLeft="8dp"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:layout_width="32dp"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<pl.szczodrzynski.edziennik.ui.modules.attendance.AttendanceView
|
||||||
|
android:id="@+id/type"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center_horizontal"
|
||||||
|
tools:background="@drawable/bg_rounded_4dp"
|
||||||
|
tools:backgroundTint="#43a047"
|
||||||
|
tools:paddingHorizontal="5dp"
|
||||||
|
tools:singleLine="true"
|
||||||
|
tools:text="ob"
|
||||||
|
tools:textSize="14sp" />
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/title"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_margin="8dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:ellipsize="end"
|
||||||
|
android:fontFamily="sans-serif"
|
||||||
|
android:maxLines="2"
|
||||||
|
android:textColor="?android:textColorPrimary"
|
||||||
|
android:textSize="20sp"
|
||||||
|
tools:text="obecność" />
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:id="@+id/unread"
|
||||||
|
android:layout_width="12dp"
|
||||||
|
android:layout_height="12dp"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:layout_marginEnd="8dp"
|
||||||
|
android:layout_marginRight="8dp"
|
||||||
|
android:visibility="gone"
|
||||||
|
android:background="@drawable/unread_red_circle"
|
||||||
|
tools:visibility="visible"/>
|
||||||
|
|
||||||
|
<com.mikepenz.iconics.view.IconicsImageView
|
||||||
|
android:id="@+id/dropdownIcon"
|
||||||
|
android:layout_width="24dp"
|
||||||
|
android:layout_height="36dp"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:layout_marginEnd="8dp"
|
||||||
|
android:layout_marginRight="8dp"
|
||||||
|
android:scaleType="centerInside"
|
||||||
|
app:iiv_color="?android:textColorSecondary"
|
||||||
|
app:iiv_icon="cmd-chevron-down"
|
||||||
|
app:iiv_size="18dp"
|
||||||
|
tools:background="@android:drawable/ic_menu_more" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="8dp"
|
||||||
|
android:layout_marginLeft="8dp"
|
||||||
|
android:layout_marginBottom="8dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/previewContainer"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:layout_marginEnd="8dp"
|
||||||
|
android:layout_marginRight="8dp"
|
||||||
|
android:textSize="14sp"
|
||||||
|
android:visibility="gone"
|
||||||
|
tools:text="57,67% • 521 przez cały rok • 134 w tym semestrze"
|
||||||
|
tools:text1="Cały rok: 3 oceny • suma: 320 pkt"
|
||||||
|
tools:text2="Cały rok: 15 ocen • średnia: 2,62"
|
||||||
|
tools:visibility="visible" />
|
||||||
|
</FrameLayout>
|
||||||
|
</LinearLayout>
|
||||||
|
</layout>
|
@ -1304,4 +1304,5 @@
|
|||||||
<string name="yesterday">wczoraj</string>
|
<string name="yesterday">wczoraj</string>
|
||||||
<string name="you_are_offline_text">Jesteś offline. Spróbuj włączyć Wi-Fi lub dane komórkowe.</string>
|
<string name="you_are_offline_text">Jesteś offline. Spróbuj włączyć Wi-Fi lub dane komórkowe.</string>
|
||||||
<string name="you_are_offline_title">Połączenie sieciowe</string>
|
<string name="you_are_offline_title">Połączenie sieciowe</string>
|
||||||
|
<string name="attendance_tab_types">Wg typu</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user