mirror of
https://github.com/szkolny-eu/szkolny-android.git
synced 2025-02-20 13:54:43 +01:00
[Grades] Implement new Grades module (UI & API changes).
This commit is contained in:
parent
4e8fdd2225
commit
f17a02be54
@ -190,6 +190,8 @@ dependencies {
|
||||
implementation 'com.github.jetradarmobile:android-snowfall:1.2.0'
|
||||
|
||||
implementation "io.coil-kt:coil:0.9.2"
|
||||
|
||||
implementation 'com.github.kuba2k2:NumberSlidingPicker:2921225f76'
|
||||
}
|
||||
repositories {
|
||||
mavenCentral()
|
||||
|
@ -45,6 +45,7 @@ import pl.szczodrzynski.edziennik.sync.SyncWorker
|
||||
import pl.szczodrzynski.edziennik.sync.UpdateWorker
|
||||
import pl.szczodrzynski.edziennik.ui.modules.base.CrashActivity
|
||||
import pl.szczodrzynski.edziennik.utils.*
|
||||
import pl.szczodrzynski.edziennik.utils.managers.GradesManager
|
||||
import pl.szczodrzynski.edziennik.utils.managers.NotificationChannelsManager
|
||||
import pl.szczodrzynski.edziennik.utils.managers.UserActionManager
|
||||
import java.util.concurrent.TimeUnit
|
||||
@ -65,6 +66,7 @@ class App : MultiDexApplication(), Configuration.Provider, CoroutineScope {
|
||||
|
||||
val notificationChannelsManager by lazy { NotificationChannelsManager(this) }
|
||||
val userActionManager by lazy { UserActionManager(this) }
|
||||
val gradesManager by lazy { GradesManager(this) }
|
||||
|
||||
val db
|
||||
get() = App.db
|
||||
|
@ -1080,3 +1080,15 @@ fun Throwable.toErrorCode() = when (this) {
|
||||
private fun ApiResponse.Error.toErrorCode() = when (this.code) {
|
||||
else -> ERROR_API_EXCEPTION
|
||||
}
|
||||
|
||||
inline fun <A, B, R> ifNotNull(a: A?, b: B?, code: (A, B) -> R): R? {
|
||||
if (a != null && b != null) {
|
||||
return code(a, b)
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
@kotlin.jvm.JvmName("averageOrNullOfInt")
|
||||
fun Iterable<Int>.averageOrNull() = this.average().let { if (it.isNaN()) null else it }
|
||||
@kotlin.jvm.JvmName("averageOrNullOfFloat")
|
||||
fun Iterable<Float>.averageOrNull() = this.average().let { if (it.isNaN()) null else it }
|
||||
|
@ -6,17 +6,11 @@ package pl.szczodrzynski.edziennik.config
|
||||
|
||||
import pl.szczodrzynski.edziennik.config.utils.get
|
||||
import pl.szczodrzynski.edziennik.config.utils.set
|
||||
import pl.szczodrzynski.edziennik.utils.managers.GradesManager
|
||||
|
||||
class ConfigGrades(private val config: Config) {
|
||||
companion object {
|
||||
const val ORDER_BY_DATE_DESC = 0
|
||||
const val ORDER_BY_SUBJECT_ASC = 1
|
||||
const val ORDER_BY_DATE_ASC = 2
|
||||
const val ORDER_BY_SUBJECT_DESC = 3
|
||||
}
|
||||
|
||||
private var mOrderBy: Int? = null
|
||||
var orderBy: Int
|
||||
get() { mOrderBy = mOrderBy ?: config.values.get("gradesOrderBy", 0); return mOrderBy ?: ORDER_BY_DATE_DESC }
|
||||
get() { mOrderBy = mOrderBy ?: config.values.get("gradesOrderBy", 0); return mOrderBy ?: GradesManager.ORDER_BY_DATE_DESC }
|
||||
set(value) { config.set("gradesOrderBy", value); mOrderBy = value }
|
||||
}
|
||||
}
|
||||
|
@ -5,9 +5,10 @@
|
||||
package pl.szczodrzynski.edziennik.config
|
||||
|
||||
import pl.szczodrzynski.edziennik.config.utils.get
|
||||
import pl.szczodrzynski.edziennik.config.utils.getFloat
|
||||
import pl.szczodrzynski.edziennik.config.utils.set
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Profile.Companion.COLOR_MODE_WEIGHTED
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Profile.Companion.YEAR_ALL_GRADES
|
||||
import pl.szczodrzynski.edziennik.utils.managers.GradesManager.Companion.COLOR_MODE_WEIGHTED
|
||||
import pl.szczodrzynski.edziennik.utils.managers.GradesManager.Companion.YEAR_ALL_GRADES
|
||||
|
||||
class ProfileConfigGrades(private val config: ProfileConfig) {
|
||||
private var mColorMode: Int? = null
|
||||
@ -24,4 +25,18 @@ class ProfileConfigGrades(private val config: ProfileConfig) {
|
||||
var countZeroToAvg: Boolean
|
||||
get() { mCountZeroToAvg = mCountZeroToAvg ?: config.values.get("countZeroToAvg", true); return mCountZeroToAvg ?: true }
|
||||
set(value) { config.set("countZeroToAvg", value); mCountZeroToAvg = value }
|
||||
|
||||
private var mPlusValue: Float? = null
|
||||
var plusValue: Float?
|
||||
get() { mPlusValue = mPlusValue ?: config.values.getFloat("plusValue"); return mPlusValue }
|
||||
set(value) { config.set("plusValue", value); mPlusValue = value }
|
||||
private var mMinusValue: Float? = null
|
||||
var minusValue: Float?
|
||||
get() { mMinusValue = mMinusValue ?: config.values.getFloat("minusValue"); return mMinusValue }
|
||||
set(value) { config.set("minusValue", value); mMinusValue = value }
|
||||
|
||||
private var mDontCountGrades: List<String>? = null
|
||||
var dontCountGrades: List<String>
|
||||
get() { mDontCountGrades = mDontCountGrades ?: config.values.get("dontCountGrades", listOf()); return mDontCountGrades ?: listOf() }
|
||||
set(value) { config.set("dontCountGrades", value); mDontCountGrades = value }
|
||||
}
|
||||
|
@ -94,10 +94,14 @@ fun HashMap<String, String?>.getLongList(key: String, default: List<Long>?): Lis
|
||||
return this[key]?.let { gson.fromJson<List<Long>>(it, object: TypeToken<List<Long>>(){}.type) } ?: default
|
||||
}
|
||||
|
||||
fun HashMap<String, String?>.getFloat(key: String): Float? {
|
||||
return this[key]?.toFloatOrNull()
|
||||
}
|
||||
|
||||
fun List<ConfigEntry>.toHashMap(profileId: Int, map: HashMap<String, String?>) {
|
||||
map.clear()
|
||||
forEach {
|
||||
if (it.profileId == profileId)
|
||||
map[it.key] = it.value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ import pl.szczodrzynski.edziennik.BuildConfig
|
||||
import pl.szczodrzynski.edziennik.HOUR
|
||||
import pl.szczodrzynski.edziennik.MainActivity
|
||||
import pl.szczodrzynski.edziennik.config.Config
|
||||
import pl.szczodrzynski.edziennik.config.ConfigGrades.Companion.ORDER_BY_DATE_DESC
|
||||
import pl.szczodrzynski.edziennik.utils.managers.GradesManager.Companion.ORDER_BY_DATE_DESC
|
||||
|
||||
class ConfigMigration(app: App, config: Config) {
|
||||
init { config.apply {
|
||||
|
@ -6,8 +6,8 @@ package pl.szczodrzynski.edziennik.config.utils
|
||||
|
||||
import pl.szczodrzynski.edziennik.config.ProfileConfig
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Profile.Companion.AGENDA_DEFAULT
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Profile.Companion.COLOR_MODE_WEIGHTED
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Profile.Companion.YEAR_ALL_GRADES
|
||||
import pl.szczodrzynski.edziennik.utils.managers.GradesManager.Companion.COLOR_MODE_WEIGHTED
|
||||
import pl.szczodrzynski.edziennik.utils.managers.GradesManager.Companion.YEAR_ALL_GRADES
|
||||
|
||||
class ProfileConfigMigration(config: ProfileConfig) {
|
||||
init { config.apply {
|
||||
@ -21,4 +21,4 @@ class ProfileConfigMigration(config: ProfileConfig) {
|
||||
dataVersion = 1
|
||||
}
|
||||
}}
|
||||
}
|
||||
}
|
||||
|
@ -14,7 +14,12 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.ENDPOINT_EDUDZI
|
||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.EdudziennikWeb
|
||||
import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade.*
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_NORMAL
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_POINT_SUM
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_SEMESTER1_FINAL
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_SEMESTER1_PROPOSED
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_SEMESTER2_FINAL
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_SEMESTER2_PROPOSED
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
||||
import pl.szczodrzynski.edziennik.get
|
||||
@ -90,7 +95,7 @@ class EdudziennikWebGrades(override val data: DataEdudziennik,
|
||||
val columnName = info.child(4).text().trim()
|
||||
val comment = info.ownText()
|
||||
|
||||
val description = columnName + if (comment.isNotBlank()) " - $comment" else ""
|
||||
val description = columnName + if (comment.isNotBlank()) " - $comment" else null
|
||||
|
||||
val teacherName = info.child(1).text()
|
||||
val teacher = data.getTeacherByLastFirst(teacherName)
|
||||
@ -109,20 +114,20 @@ class EdudziennikWebGrades(override val data: DataEdudziennik,
|
||||
} ?: -1
|
||||
|
||||
val gradeObject = Grade(
|
||||
profileId,
|
||||
id,
|
||||
fullName,
|
||||
color,
|
||||
description,
|
||||
name,
|
||||
value,
|
||||
if (gradeCountToAverage) weight else 0f,
|
||||
semester,
|
||||
teacher.id,
|
||||
subject.id
|
||||
).apply {
|
||||
type = gradeType
|
||||
}
|
||||
profileId = profileId,
|
||||
id = id,
|
||||
name = name,
|
||||
type = gradeType,
|
||||
value = value,
|
||||
weight = if (gradeCountToAverage) weight else 0f,
|
||||
color = color,
|
||||
category = fullName,
|
||||
description = description,
|
||||
comment = null,
|
||||
semester = semester,
|
||||
teacherId = teacher.id,
|
||||
subjectId = subject.id
|
||||
)
|
||||
|
||||
data.gradeList.add(gradeObject)
|
||||
data.metadataList.add(Metadata(
|
||||
@ -139,23 +144,23 @@ class EdudziennikWebGrades(override val data: DataEdudziennik,
|
||||
|
||||
if (proposed != null && proposed.isNotBlank()) {
|
||||
val proposedGradeObject = Grade(
|
||||
profileId,
|
||||
(-1 * subject.id) - 1,
|
||||
"",
|
||||
-1,
|
||||
"",
|
||||
proposed,
|
||||
proposed.toFloatOrNull() ?: 0f,
|
||||
0f,
|
||||
semester,
|
||||
-1,
|
||||
subject.id
|
||||
).apply {
|
||||
type = when (semester) {
|
||||
1 -> TYPE_SEMESTER1_PROPOSED
|
||||
else -> TYPE_SEMESTER2_PROPOSED
|
||||
}
|
||||
}
|
||||
profileId = profileId,
|
||||
id = (-1 * subject.id) - 1,
|
||||
name = proposed,
|
||||
type = when (semester) {
|
||||
1 -> TYPE_SEMESTER1_PROPOSED
|
||||
else -> TYPE_SEMESTER2_PROPOSED
|
||||
},
|
||||
value = proposed.toFloatOrNull() ?: 0f,
|
||||
weight = 0f,
|
||||
color = -1,
|
||||
category = null,
|
||||
description = null,
|
||||
comment = null,
|
||||
semester = semester,
|
||||
teacherId = -1,
|
||||
subjectId = subject.id
|
||||
)
|
||||
|
||||
data.gradeList.add(proposedGradeObject)
|
||||
data.metadataList.add(Metadata(
|
||||
@ -172,23 +177,23 @@ class EdudziennikWebGrades(override val data: DataEdudziennik,
|
||||
|
||||
if (final != null && final.isNotBlank()) {
|
||||
val finalGradeObject = Grade(
|
||||
profileId,
|
||||
(-1 * subject.id) - 2,
|
||||
"",
|
||||
-1,
|
||||
"",
|
||||
final,
|
||||
final.toFloatOrNull() ?: 0f,
|
||||
0f,
|
||||
semester,
|
||||
-1,
|
||||
subject.id
|
||||
).apply {
|
||||
type = when (semester) {
|
||||
1 -> TYPE_SEMESTER1_FINAL
|
||||
else -> TYPE_SEMESTER2_FINAL
|
||||
}
|
||||
}
|
||||
profileId = profileId,
|
||||
id = (-1 * subject.id) - 2,
|
||||
name = final,
|
||||
type = when (semester) {
|
||||
1 -> TYPE_SEMESTER1_FINAL
|
||||
else -> TYPE_SEMESTER2_FINAL
|
||||
},
|
||||
value = final.toFloatOrNull() ?: 0f,
|
||||
weight = 0f,
|
||||
color = -1,
|
||||
category = null,
|
||||
description = null,
|
||||
comment = null,
|
||||
semester = semester,
|
||||
teacherId = -1,
|
||||
subjectId = subject.id
|
||||
)
|
||||
|
||||
data.gradeList.add(finalGradeObject)
|
||||
data.metadataList.add(Metadata(
|
||||
|
@ -14,6 +14,7 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.IdziennikWeb
|
||||
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
||||
import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_NORMAL
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||
@ -63,17 +64,19 @@ class IdziennikWebGrades(override val data: DataIdziennik,
|
||||
}
|
||||
|
||||
val gradeObject = Grade(
|
||||
profileId,
|
||||
id,
|
||||
category,
|
||||
colorInt,
|
||||
"",
|
||||
name,
|
||||
value,
|
||||
weight,
|
||||
semester,
|
||||
teacher.id,
|
||||
subject.id)
|
||||
profileId = profileId,
|
||||
id = id,
|
||||
name = name,
|
||||
type = TYPE_NORMAL,
|
||||
value = value,
|
||||
weight = weight,
|
||||
color = colorInt,
|
||||
category = category,
|
||||
description = null,
|
||||
comment = null,
|
||||
semester = semester,
|
||||
teacherId = teacher.id,
|
||||
subjectId = subject.id)
|
||||
|
||||
when (grade.getInt("Typ")) {
|
||||
0 -> {
|
||||
@ -98,17 +101,19 @@ class IdziennikWebGrades(override val data: DataIdziennik,
|
||||
}
|
||||
|
||||
val historyObject = Grade(
|
||||
profileId,
|
||||
gradeObject.id * -1,
|
||||
historyItem.get("Kategoria").asString,
|
||||
colorInt,
|
||||
historyItem.get("Uzasadnienie").asString,
|
||||
historyItem.get("Ocena").asString,
|
||||
value,
|
||||
if (value > 0f && countToTheAverage) weight * -1f else 0f,
|
||||
historyItem.get("Semestr").asInt,
|
||||
teacher.id,
|
||||
subject.id)
|
||||
profileId = profileId,
|
||||
id = gradeObject.id * -1,
|
||||
name = historyItem.getString("Ocena") ?: "",
|
||||
type = TYPE_NORMAL,
|
||||
value = value,
|
||||
weight = if (value > 0f && countToTheAverage) weight * -1f else 0f,
|
||||
color = colorInt,
|
||||
category = historyItem.getString("Kategoria"),
|
||||
description = historyItem.getString("Uzasadnienie"),
|
||||
comment = null,
|
||||
semester = historyItem.getInt("Semestr") ?: 1,
|
||||
teacherId = teacher.id,
|
||||
subjectId = subject.id)
|
||||
historyObject.parentId = gradeObject.id
|
||||
|
||||
val addedDate = historyItem.getString("Data_wystaw")?.let { Date.fromY_m_d(it).inMillis } ?: System.currentTimeMillis()
|
||||
|
@ -13,8 +13,8 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.IdziennikWeb
|
||||
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
||||
import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade.TYPE_SEMESTER1_PROPOSED
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade.TYPE_YEAR_PROPOSED
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_SEMESTER1_PROPOSED
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_YEAR_PROPOSED
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
||||
import pl.szczodrzynski.edziennik.getJsonArray
|
||||
@ -54,20 +54,20 @@ class IdziennikWebProposedGrades(override val data: DataIdziennik,
|
||||
|
||||
if (semester1Proposed != "") {
|
||||
val gradeObject = Grade(
|
||||
profileId,
|
||||
semester1Id,
|
||||
"",
|
||||
-1,
|
||||
"",
|
||||
semester1Value.toString(),
|
||||
semester1Value.toFloat(),
|
||||
0f,
|
||||
1,
|
||||
-1,
|
||||
subjectObject.id
|
||||
).apply {
|
||||
type = TYPE_SEMESTER1_PROPOSED
|
||||
}
|
||||
profileId = profileId,
|
||||
id = semester1Id,
|
||||
name = semester1Value.toString(),
|
||||
type = TYPE_SEMESTER1_PROPOSED,
|
||||
value = semester1Value.toFloat(),
|
||||
weight = 0f,
|
||||
color = -1,
|
||||
category = null,
|
||||
description = null,
|
||||
comment = null,
|
||||
semester = 1,
|
||||
teacherId = -1,
|
||||
subjectId = subjectObject.id
|
||||
)
|
||||
|
||||
data.gradeList.add(gradeObject)
|
||||
data.metadataList.add(Metadata(
|
||||
@ -82,20 +82,20 @@ class IdziennikWebProposedGrades(override val data: DataIdziennik,
|
||||
|
||||
if (semester2Proposed != "") {
|
||||
val gradeObject = Grade(
|
||||
profileId,
|
||||
semester2Id,
|
||||
"",
|
||||
-1,
|
||||
"",
|
||||
semester2Value.toString(),
|
||||
semester2Value.toFloat(),
|
||||
0f,
|
||||
2,
|
||||
-1,
|
||||
subjectObject.id
|
||||
).apply {
|
||||
type = TYPE_YEAR_PROPOSED
|
||||
}
|
||||
profileId = profileId,
|
||||
id = semester2Id,
|
||||
name = semester2Value.toString(),
|
||||
type = TYPE_YEAR_PROPOSED,
|
||||
value = semester2Value.toFloat(),
|
||||
weight = 0f,
|
||||
color = -1,
|
||||
category = null,
|
||||
description = null,
|
||||
comment = null,
|
||||
semester = 2,
|
||||
teacherId = -1,
|
||||
subjectId = subjectObject.id
|
||||
)
|
||||
|
||||
val addedDate = if (data.profile.empty)
|
||||
data.profile.dateSemester1Start.inMillis
|
||||
|
@ -10,6 +10,7 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.librus.ENDPOINT_LIBRUS_API_
|
||||
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.LibrusApi
|
||||
import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_POINT_SUM
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.GradeCategory
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
||||
@ -31,18 +32,20 @@ class LibrusApiBehaviourGrades(override val data: DataLibrus,
|
||||
|
||||
if (data.startPointsSemester1 > 0) {
|
||||
val semester1StartGradeObject = Grade(
|
||||
profileId,
|
||||
-101,
|
||||
data.app.getString(R.string.grade_start_points),
|
||||
0xffbdbdbd.toInt(),
|
||||
data.app.getString(R.string.grade_start_points_format, 1),
|
||||
nameFormat.format(data.startPointsSemester1),
|
||||
data.startPointsSemester1.toFloat(),
|
||||
-1f,
|
||||
1,
|
||||
-1,
|
||||
1
|
||||
).apply { type = Grade.TYPE_POINT_SUM }
|
||||
profileId = profileId,
|
||||
id = -101,
|
||||
name = nameFormat.format(data.startPointsSemester1),
|
||||
type = TYPE_POINT_SUM,
|
||||
value = data.startPointsSemester1.toFloat(),
|
||||
weight = 0f,
|
||||
color = 0xffbdbdbd.toInt(),
|
||||
category = data.app.getString(R.string.grade_start_points),
|
||||
description = data.app.getString(R.string.grade_start_points_format, 1),
|
||||
comment = null,
|
||||
semester = 1,
|
||||
teacherId = -1,
|
||||
subjectId = 1
|
||||
)
|
||||
|
||||
data.gradeList.add(semester1StartGradeObject)
|
||||
data.metadataList.add(Metadata(
|
||||
@ -57,18 +60,20 @@ class LibrusApiBehaviourGrades(override val data: DataLibrus,
|
||||
|
||||
if (data.startPointsSemester2 > 0) {
|
||||
val semester2StartGradeObject = Grade(
|
||||
profileId,
|
||||
-102,
|
||||
data.app.getString(R.string.grade_start_points),
|
||||
0xffbdbdbd.toInt(),
|
||||
data.app.getString(R.string.grade_start_points_format, 2),
|
||||
nameFormat.format(data.startPointsSemester2),
|
||||
data.startPointsSemester2.toFloat(),
|
||||
-1f,
|
||||
2,
|
||||
-1,
|
||||
1
|
||||
).apply { type = Grade.TYPE_POINT_SUM }
|
||||
profileId = profileId,
|
||||
id = -102,
|
||||
name = nameFormat.format(data.startPointsSemester2),
|
||||
type = TYPE_POINT_SUM,
|
||||
value = data.startPointsSemester2.toFloat(),
|
||||
weight = -1f,
|
||||
color = 0xffbdbdbd.toInt(),
|
||||
category = data.app.getString(R.string.grade_start_points),
|
||||
description = data.app.getString(R.string.grade_start_points_format, 2),
|
||||
comment = null,
|
||||
semester = 2,
|
||||
teacherId = -1,
|
||||
subjectId = 1
|
||||
)
|
||||
|
||||
data.gradeList.add(semester2StartGradeObject)
|
||||
data.metadataList.add(Metadata(
|
||||
@ -123,19 +128,20 @@ class LibrusApiBehaviourGrades(override val data: DataLibrus,
|
||||
val valueTo = category?.valueTo ?: 0f
|
||||
|
||||
val gradeObject = Grade(
|
||||
profileId,
|
||||
id,
|
||||
categoryName,
|
||||
color,
|
||||
description,
|
||||
name,
|
||||
valueFrom,
|
||||
-1f,
|
||||
semester,
|
||||
teacherId,
|
||||
1
|
||||
profileId = profileId,
|
||||
id = id,
|
||||
name = name,
|
||||
type = TYPE_POINT_SUM,
|
||||
value = valueFrom,
|
||||
weight = -1f,
|
||||
color = color,
|
||||
category = categoryName,
|
||||
description = description,
|
||||
comment = null,
|
||||
semester = semester,
|
||||
teacherId = teacherId,
|
||||
subjectId = 1
|
||||
).apply {
|
||||
type = Grade.TYPE_POINT_SUM
|
||||
valueMax = valueTo
|
||||
}
|
||||
|
||||
|
@ -10,8 +10,8 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.librus.ENDPOINT_LIBRUS_API_
|
||||
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.LibrusApi
|
||||
import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade.TYPE_DESCRIPTIVE_TEXT
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade.TYPE_TEXT
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_DESCRIPTIVE_TEXT
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_TEXT
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.GradeCategory
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
||||
@ -53,20 +53,20 @@ class LibrusApiDescriptiveGrades(override val data: DataLibrus,
|
||||
val addedDate = Date.fromIso(grade.getString("AddDate") ?: return@forEach)
|
||||
|
||||
val gradeObject = Grade(
|
||||
profileId,
|
||||
id,
|
||||
category?.text ?: "",
|
||||
category?.color ?: -1,
|
||||
description,
|
||||
" ",
|
||||
0f,
|
||||
0f,
|
||||
semester,
|
||||
teacherId,
|
||||
subjectId
|
||||
).apply {
|
||||
this.type = type
|
||||
}
|
||||
profileId = profileId,
|
||||
id = id,
|
||||
name = " ",
|
||||
type = type,
|
||||
value = 0f,
|
||||
weight = 0f,
|
||||
color = category?.color ?: -1,
|
||||
category = category?.text,
|
||||
description = description,
|
||||
comment = null,
|
||||
semester = semester,
|
||||
teacherId = teacherId,
|
||||
subjectId = subjectId
|
||||
)
|
||||
|
||||
data.gradeList.add(gradeObject)
|
||||
data.metadataList.add(Metadata(
|
||||
|
@ -6,7 +6,13 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.librus.ENDPOINT_LIBRUS_API_
|
||||
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.LibrusApi
|
||||
import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade.*
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_NORMAL
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_SEMESTER1_FINAL
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_SEMESTER1_PROPOSED
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_SEMESTER2_FINAL
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_SEMESTER2_PROPOSED
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_YEAR_FINAL
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_YEAR_PROPOSED
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.GradeCategory
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
||||
@ -54,32 +60,28 @@ class LibrusApiGrades(override val data: DataLibrus,
|
||||
} ?: ""
|
||||
|
||||
val gradeObject = Grade(
|
||||
profileId,
|
||||
id,
|
||||
category?.text ?: "",
|
||||
category?.color ?: -1,
|
||||
description,
|
||||
name,
|
||||
value,
|
||||
weight,
|
||||
semester,
|
||||
teacherId,
|
||||
subjectId
|
||||
profileId = profileId,
|
||||
id = id,
|
||||
name = name,
|
||||
type = when {
|
||||
grade.getBoolean("IsConstituent") ?: false -> TYPE_NORMAL
|
||||
grade.getBoolean("IsSemester") ?: false -> if (semester == 1) TYPE_SEMESTER1_FINAL else TYPE_SEMESTER2_FINAL
|
||||
grade.getBoolean("IsSemesterProposition") ?: false -> if (semester == 1) TYPE_SEMESTER1_PROPOSED else TYPE_SEMESTER2_PROPOSED
|
||||
grade.getBoolean("IsFinal") ?: false -> TYPE_YEAR_FINAL
|
||||
grade.getBoolean("IsFinalProposition") ?: false -> TYPE_YEAR_PROPOSED
|
||||
else -> TYPE_NORMAL
|
||||
},
|
||||
value = value,
|
||||
weight = weight,
|
||||
color = category?.color ?: -1,
|
||||
category = category?.text ?: "",
|
||||
description = description,
|
||||
comment = null,
|
||||
semester = semester,
|
||||
teacherId = teacherId,
|
||||
subjectId = subjectId
|
||||
)
|
||||
|
||||
when {
|
||||
grade.getBoolean("IsConstituent") ?: false ->
|
||||
gradeObject.type = TYPE_NORMAL
|
||||
grade.getBoolean("IsSemester") ?: false -> // semester final
|
||||
gradeObject.type = if (gradeObject.semester == 1) TYPE_SEMESTER1_FINAL else TYPE_SEMESTER2_FINAL
|
||||
grade.getBoolean("IsSemesterProposition") ?: false -> // semester proposed
|
||||
gradeObject.type = if (gradeObject.semester == 1) TYPE_SEMESTER1_PROPOSED else TYPE_SEMESTER2_PROPOSED
|
||||
grade.getBoolean("IsFinal") ?: false -> // year final
|
||||
gradeObject.type = TYPE_YEAR_FINAL
|
||||
grade.getBoolean("IsFinalProposition") ?: false -> // year final
|
||||
gradeObject.type = TYPE_YEAR_PROPOSED
|
||||
}
|
||||
|
||||
grade.getJsonObject("Improvement")?.also {
|
||||
val historicalId = it.getLong("Id")
|
||||
data.gradeList.firstOrNull { grade -> grade.id == historicalId }?.also { grade ->
|
||||
|
@ -10,7 +10,7 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.librus.ENDPOINT_LIBRUS_API_
|
||||
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.LibrusApi
|
||||
import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade.TYPE_POINT_AVG
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_POINT_AVG
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.GradeCategory
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
||||
@ -44,19 +44,20 @@ class LibrusApiPointGrades(override val data: DataLibrus,
|
||||
val addedDate = Date.fromIso(grade.getString("AddDate") ?: return@forEach)
|
||||
|
||||
val gradeObject = Grade(
|
||||
profileId,
|
||||
id,
|
||||
category?.text ?: "",
|
||||
category?.color ?: -1,
|
||||
"",
|
||||
name,
|
||||
value,
|
||||
category?.weight ?: 0f,
|
||||
semester,
|
||||
teacherId,
|
||||
subjectId
|
||||
profileId = profileId,
|
||||
id = id,
|
||||
name = name,
|
||||
type = TYPE_POINT_AVG,
|
||||
value = value,
|
||||
weight = category?.weight ?: 0f,
|
||||
color = category?.color ?: -1,
|
||||
category = category?.text ?: "",
|
||||
description = null,
|
||||
comment = null,
|
||||
semester = semester,
|
||||
teacherId = teacherId,
|
||||
subjectId = subjectId
|
||||
).apply {
|
||||
type = TYPE_POINT_AVG
|
||||
valueMax = category?.valueTo ?: 0f
|
||||
}
|
||||
|
||||
|
@ -10,7 +10,7 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.librus.ENDPOINT_LIBRUS_API_
|
||||
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.LibrusApi
|
||||
import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade.TYPE_DESCRIPTIVE
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_DESCRIPTIVE
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.GradeCategory
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
||||
@ -48,20 +48,20 @@ class LibrusApiTextGrades(override val data: DataLibrus,
|
||||
val addedDate = Date.fromIso(grade.getString("AddDate") ?: return@forEach)
|
||||
|
||||
val gradeObject = Grade(
|
||||
profileId,
|
||||
id,
|
||||
category?.text ?: "",
|
||||
category?.color ?: -1,
|
||||
description,
|
||||
name,
|
||||
0f,
|
||||
0f,
|
||||
semester,
|
||||
teacherId,
|
||||
subjectId
|
||||
).apply {
|
||||
type = TYPE_DESCRIPTIVE
|
||||
}
|
||||
profileId = profileId,
|
||||
id = id,
|
||||
name = name,
|
||||
type = TYPE_DESCRIPTIVE,
|
||||
value = 0f,
|
||||
weight = 0f,
|
||||
color = category?.color ?: -1,
|
||||
category = category?.text ?: "",
|
||||
description = description,
|
||||
comment = null,
|
||||
semester = semester,
|
||||
teacherId = teacherId,
|
||||
subjectId = subjectId
|
||||
)
|
||||
|
||||
data.gradeList.add(gradeObject)
|
||||
data.metadataList.add(Metadata(
|
||||
|
@ -7,7 +7,13 @@ package pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.data.api
|
||||
import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.DataMobidziennik
|
||||
import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade.*
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_NORMAL
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_SEMESTER1_FINAL
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_SEMESTER1_PROPOSED
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_SEMESTER2_FINAL
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_SEMESTER2_PROPOSED
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_YEAR_FINAL
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_YEAR_PROPOSED
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
||||
|
||||
class MobidziennikApiGrades(val data: DataMobidziennik, rows: List<String>) {
|
||||
@ -61,18 +67,19 @@ class MobidziennikApiGrades(val data: DataMobidziennik, rows: List<String>) {
|
||||
}
|
||||
|
||||
val gradeObject = Grade(
|
||||
data.profileId,
|
||||
id,
|
||||
category,
|
||||
color,
|
||||
description,
|
||||
name,
|
||||
value,
|
||||
weight,
|
||||
semester,
|
||||
teacherId,
|
||||
subjectId)
|
||||
gradeObject.type = type
|
||||
profileId = data.profileId,
|
||||
id = id,
|
||||
name = name,
|
||||
type = type,
|
||||
value = value,
|
||||
weight = weight,
|
||||
color = color,
|
||||
category = category,
|
||||
description = description,
|
||||
comment = null,
|
||||
semester = semester,
|
||||
teacherId = teacherId,
|
||||
subjectId = subjectId)
|
||||
|
||||
if (data.profile?.empty == true) {
|
||||
addedDate = data.profile.dateSemester1Start.inMillis
|
||||
|
@ -11,6 +11,7 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.DataMobidzienn
|
||||
import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.ENDPOINT_MOBIDZIENNIK_WEB_GRADES
|
||||
import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.data.MobidziennikWeb
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_NORMAL
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
||||
import pl.szczodrzynski.edziennik.fixWhiteSpaces
|
||||
@ -112,17 +113,19 @@ class MobidziennikWebGrades(override val data: DataMobidziennik,
|
||||
}
|
||||
|
||||
val gradeObject = Grade(
|
||||
profileId,
|
||||
gradeId,
|
||||
gradeCategory,
|
||||
gradeColor,
|
||||
"NLDŚR, $gradeDescription",
|
||||
gradeName,
|
||||
gradeValue,
|
||||
0f,
|
||||
gradeSemester,
|
||||
teacherId,
|
||||
subjectId
|
||||
profileId = profileId,
|
||||
id = gradeId,
|
||||
name = gradeName,
|
||||
type = TYPE_NORMAL,
|
||||
value = gradeValue,
|
||||
weight = 0f,
|
||||
color = gradeColor,
|
||||
category = gradeCategory,
|
||||
description = "NLDŚR, $gradeDescription",
|
||||
comment = null,
|
||||
semester = gradeSemester,
|
||||
teacherId = teacherId,
|
||||
subjectId = subjectId
|
||||
)
|
||||
|
||||
gradeObject.classAverage = gradeClassAverage
|
||||
|
@ -11,6 +11,7 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.ENDPOINT_VULCAN_API_
|
||||
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.VulcanApi
|
||||
import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_NORMAL
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
||||
import java.text.DecimalFormat
|
||||
@ -88,17 +89,19 @@ class VulcanApiGrades(override val data: DataVulcan,
|
||||
}.toInt()
|
||||
|
||||
val gradeObject = Grade(
|
||||
profileId,
|
||||
id,
|
||||
category,
|
||||
color,
|
||||
finalDescription,
|
||||
name,
|
||||
value ?: 0.0f,
|
||||
weight,
|
||||
data.studentSemesterNumber,
|
||||
teacherId,
|
||||
subjectId
|
||||
profileId = profileId,
|
||||
id = id,
|
||||
name = name,
|
||||
type = TYPE_NORMAL,
|
||||
value = value ?: 0.0f,
|
||||
weight = weight,
|
||||
color = color,
|
||||
category = category,
|
||||
description = finalDescription,
|
||||
comment = null,
|
||||
semester = data.studentSemesterNumber,
|
||||
teacherId = teacherId,
|
||||
subjectId = subjectId
|
||||
)
|
||||
|
||||
data.gradeList.add(gradeObject)
|
||||
|
@ -8,6 +8,10 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.DataVulcan
|
||||
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.ENDPOINT_VULCAN_API_GRADES_SUMMARY
|
||||
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.VulcanApi
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_SEMESTER1_FINAL
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_SEMESTER1_PROPOSED
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_SEMESTER2_FINAL
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_SEMESTER2_PROPOSED
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
||||
import pl.szczodrzynski.edziennik.getJsonArray
|
||||
import pl.szczodrzynski.edziennik.getJsonObject
|
||||
@ -53,23 +57,25 @@ class VulcanApiProposedGrades(override val data: DataVulcan,
|
||||
val color = Utils.getVulcanGradeColor(name)
|
||||
|
||||
val gradeObject = Grade(
|
||||
profileId,
|
||||
id,
|
||||
"",
|
||||
color,
|
||||
"",
|
||||
name,
|
||||
value,
|
||||
0f,
|
||||
data.studentSemesterNumber,
|
||||
-1,
|
||||
subjectId
|
||||
profileId = profileId,
|
||||
id = id,
|
||||
name = name,
|
||||
type = if (data.studentSemesterNumber == 1) {
|
||||
if (isFinal) TYPE_SEMESTER1_FINAL else TYPE_SEMESTER1_PROPOSED
|
||||
} else {
|
||||
if (isFinal) TYPE_SEMESTER2_FINAL else TYPE_SEMESTER2_PROPOSED
|
||||
},
|
||||
value = value,
|
||||
weight = 0f,
|
||||
color = color,
|
||||
category = "",
|
||||
description = null,
|
||||
comment = null,
|
||||
semester = data.studentSemesterNumber,
|
||||
teacherId = -1,
|
||||
subjectId = subjectId
|
||||
)
|
||||
if (data.studentSemesterNumber == 1) {
|
||||
gradeObject.type = if (isFinal) Grade.TYPE_SEMESTER1_FINAL else Grade.TYPE_SEMESTER1_PROPOSED
|
||||
} else {
|
||||
gradeObject.type = if (isFinal) Grade.TYPE_SEMESTER2_FINAL else Grade.TYPE_SEMESTER2_PROPOSED
|
||||
}
|
||||
|
||||
data.gradeList.add(gradeObject)
|
||||
data.metadataList.add(Metadata(
|
||||
profileId,
|
||||
|
@ -42,7 +42,7 @@ import pl.szczodrzynski.edziennik.data.db.migration.*
|
||||
ConfigEntry::class,
|
||||
LibrusLesson::class,
|
||||
Metadata::class
|
||||
], version = 77)
|
||||
], version = 78)
|
||||
@TypeConverters(
|
||||
ConverterTime::class,
|
||||
ConverterDate::class,
|
||||
@ -160,7 +160,8 @@ abstract class AppDb : RoomDatabase() {
|
||||
Migration74(),
|
||||
Migration75(),
|
||||
Migration76(),
|
||||
Migration77()
|
||||
Migration77(),
|
||||
Migration78()
|
||||
).allowMainThreadQueries().build()
|
||||
}
|
||||
}
|
||||
|
@ -63,8 +63,8 @@ public abstract class MetadataDao {
|
||||
@Transaction
|
||||
public void setSeen(int profileId, Object o, boolean seen) {
|
||||
if (o instanceof Grade) {
|
||||
if (add(new Metadata(profileId, TYPE_GRADE, ((Grade) o).id, seen, false, 0)) == -1) {
|
||||
updateSeen(profileId, TYPE_GRADE, ((Grade) o).id, seen);
|
||||
if (add(new Metadata(profileId, TYPE_GRADE, ((Grade) o).getId(), seen, false, 0)) == -1) {
|
||||
updateSeen(profileId, TYPE_GRADE, ((Grade) o).getId(), seen);
|
||||
}
|
||||
}
|
||||
if (o instanceof Attendance) {
|
||||
@ -102,8 +102,8 @@ public abstract class MetadataDao {
|
||||
@Transaction
|
||||
public void setNotified(int profileId, Object o, boolean notified) {
|
||||
if (o instanceof Grade) {
|
||||
if (add(new Metadata(profileId, TYPE_GRADE, ((Grade) o).id, false, notified, 0)) == -1) {
|
||||
updateNotified(profileId, TYPE_GRADE, ((Grade) o).id, notified);
|
||||
if (add(new Metadata(profileId, TYPE_GRADE, ((Grade) o).getId(), false, notified, 0)) == -1) {
|
||||
updateNotified(profileId, TYPE_GRADE, ((Grade) o).getId(), notified);
|
||||
}
|
||||
}
|
||||
if (o instanceof Attendance) {
|
||||
|
@ -1,104 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Kacper Ziubryniewicz 2020-1-6
|
||||
*/
|
||||
|
||||
package pl.szczodrzynski.edziennik.data.db.entity;
|
||||
|
||||
import androidx.room.ColumnInfo;
|
||||
import androidx.room.Entity;
|
||||
import androidx.room.Ignore;
|
||||
import androidx.room.Index;
|
||||
|
||||
@Entity(tableName = "grades",
|
||||
primaryKeys = {"profileId", "gradeId"},
|
||||
indices = {@Index(value = {"profileId"})})
|
||||
public class Grade {
|
||||
public int profileId;
|
||||
|
||||
@ColumnInfo(name = "gradeId")
|
||||
public long id;
|
||||
|
||||
@ColumnInfo(name = "gradeCategory")
|
||||
public String category;
|
||||
@ColumnInfo(name = "gradeColor")
|
||||
public int color;
|
||||
@ColumnInfo(name = "gradeDescription")
|
||||
public String description;
|
||||
@ColumnInfo(name = "gradeComment")
|
||||
public String comment;
|
||||
@ColumnInfo(name = "gradeName")
|
||||
public String name;
|
||||
@ColumnInfo(name = "gradeValue")
|
||||
public float value;
|
||||
@ColumnInfo(name = "gradeValueMax")
|
||||
public float valueMax;
|
||||
@ColumnInfo(name = "gradeWeight")
|
||||
public float weight;
|
||||
@ColumnInfo(name = "gradeSemester")
|
||||
public int semester;
|
||||
@ColumnInfo(name = "gradeClassAverage")
|
||||
public float classAverage = -1;
|
||||
public static final int TYPE_NORMAL = 0;
|
||||
public static final int TYPE_SEMESTER1_PROPOSED = 1;
|
||||
public static final int TYPE_SEMESTER1_FINAL = 2;
|
||||
public static final int TYPE_SEMESTER2_PROPOSED = 3;
|
||||
public static final int TYPE_SEMESTER2_FINAL = 4;
|
||||
public static final int TYPE_YEAR_PROPOSED = 5;
|
||||
public static final int TYPE_YEAR_FINAL = 6;
|
||||
public static final int TYPE_POINT_AVG = 10;
|
||||
public static final int TYPE_POINT_SUM = 20;
|
||||
public static final int TYPE_DESCRIPTIVE = 30;
|
||||
public static final int TYPE_DESCRIPTIVE_TEXT = 31;
|
||||
public static final int TYPE_TEXT = 40;
|
||||
@ColumnInfo(name = "gradeType")
|
||||
public int type = TYPE_NORMAL;
|
||||
@ColumnInfo(name = "gradePointGrade")
|
||||
public boolean pointGrade = false;
|
||||
|
||||
/**
|
||||
* Applies for historical grades. It's the new/replacement grade's ID.
|
||||
*/
|
||||
@ColumnInfo(name = "gradeParentId")
|
||||
public long parentId = -1;
|
||||
|
||||
/**
|
||||
* Applies for current grades. If the grade was worse and this is the improved one.
|
||||
*/
|
||||
@ColumnInfo(name = "gradeIsImprovement")
|
||||
public boolean isImprovement = false;
|
||||
|
||||
public long teacherId;
|
||||
public long subjectId;
|
||||
|
||||
@Ignore
|
||||
public Grade() {}
|
||||
|
||||
public Grade(int profileId, long id, String category, int color, String description, String name, float value, float weight, int semester, long teacherId, long subjectId) {
|
||||
this.profileId = profileId;
|
||||
this.id = id;
|
||||
this.category = category;
|
||||
this.color = color;
|
||||
this.description = description;
|
||||
this.name = name;
|
||||
this.value = value;
|
||||
this.weight = weight;
|
||||
this.semester = semester;
|
||||
this.teacherId = teacherId;
|
||||
this.subjectId = subjectId;
|
||||
}
|
||||
|
||||
/*@Ignore
|
||||
public Grade(int profileId, long id, String description, String name, float value, float weight, int semester, long teacherId, long categoryId, long subjectId) {
|
||||
this.profileId = profileId;
|
||||
this.id = id;
|
||||
this.description = description;
|
||||
this.name = name;
|
||||
this.value = value;
|
||||
this.weight = weight;
|
||||
this.semester = semester;
|
||||
this.teacherId = teacherId;
|
||||
//this.categoryId = categoryId;
|
||||
this.subjectId = subjectId;
|
||||
}*/
|
||||
}
|
||||
|
@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright (c) Kacper Ziubryniewicz 2020-1-6
|
||||
*/
|
||||
package pl.szczodrzynski.edziennik.data.db.entity
|
||||
|
||||
import androidx.room.ColumnInfo
|
||||
import androidx.room.Entity
|
||||
import androidx.room.Index
|
||||
|
||||
/*public Grade(int profileId, long id, String category, int color, String description, String name, float value, float weight, int semester, long teacherId, long subjectId) {
|
||||
this.profileId = profileId;
|
||||
this.id = id;
|
||||
this.category = category;
|
||||
this.color = color;
|
||||
this.description = description;
|
||||
this.name = name;
|
||||
this.value = value;
|
||||
this.weight = weight;
|
||||
this.semester = semester;
|
||||
this.teacherId = teacherId;
|
||||
this.subjectId = subjectId;
|
||||
}*/
|
||||
|
||||
@Entity(tableName = "grades",
|
||||
primaryKeys = ["profileId", "gradeId"],
|
||||
indices = [Index(value = ["profileId"])])
|
||||
open class Grade(
|
||||
val profileId: Int,
|
||||
@ColumnInfo(name = "gradeId")
|
||||
val id: Long,
|
||||
@ColumnInfo(name = "gradeName")
|
||||
var name: String,
|
||||
@ColumnInfo(name = "gradeType")
|
||||
var type: Int,
|
||||
|
||||
@ColumnInfo(name = "gradeValue")
|
||||
var value: Float,
|
||||
@ColumnInfo(name = "gradeWeight")
|
||||
var weight: Float,
|
||||
@ColumnInfo(name = "gradeColor")
|
||||
var color: Int,
|
||||
@ColumnInfo(name = "gradeCategory")
|
||||
var category: String?,
|
||||
@ColumnInfo(name = "gradeDescription")
|
||||
var description: String?,
|
||||
@ColumnInfo(name = "gradeComment")
|
||||
var comment: String?,
|
||||
|
||||
@ColumnInfo(name = "gradeSemester")
|
||||
val semester: Int,
|
||||
val teacherId: Long,
|
||||
val subjectId: Long
|
||||
) {
|
||||
companion object {
|
||||
const val TYPE_NORMAL = 0
|
||||
const val TYPE_SEMESTER1_PROPOSED = 1
|
||||
const val TYPE_SEMESTER1_FINAL = 2
|
||||
const val TYPE_SEMESTER2_PROPOSED = 3
|
||||
const val TYPE_SEMESTER2_FINAL = 4
|
||||
const val TYPE_YEAR_PROPOSED = 5
|
||||
const val TYPE_YEAR_FINAL = 6
|
||||
const val TYPE_POINT_AVG = 10
|
||||
const val TYPE_POINT_SUM = 20
|
||||
const val TYPE_DESCRIPTIVE = 30
|
||||
const val TYPE_DESCRIPTIVE_TEXT = 31
|
||||
const val TYPE_TEXT = 40
|
||||
}
|
||||
|
||||
@ColumnInfo(name = "gradeValueMax")
|
||||
var valueMax: Float? = null
|
||||
@ColumnInfo(name = "gradeClassAverage")
|
||||
var classAverage: Float? = null
|
||||
|
||||
/**
|
||||
* Applies for historical grades. It's the new/replacement grade's ID.
|
||||
*/
|
||||
@ColumnInfo(name = "gradeParentId")
|
||||
var parentId: Long? = null
|
||||
/**
|
||||
* Applies for current grades. If the grade was worse and this is the improved one.
|
||||
*/
|
||||
@ColumnInfo(name = "gradeIsImprovement")
|
||||
var isImprovement = false
|
||||
}
|
||||
|
@ -53,15 +53,8 @@ open class Profile(
|
||||
const val REGISTRATION_UNSPECIFIED = 0
|
||||
const val REGISTRATION_DISABLED = 1
|
||||
const val REGISTRATION_ENABLED = 2
|
||||
const val COLOR_MODE_DEFAULT = 0
|
||||
const val COLOR_MODE_WEIGHTED = 1
|
||||
const val AGENDA_DEFAULT = 0
|
||||
const val AGENDA_CALENDAR = 1
|
||||
const val YEAR_1_AVG_2_AVG = 0
|
||||
const val YEAR_1_SEM_2_AVG = 1
|
||||
const val YEAR_1_AVG_2_SEM = 2
|
||||
const val YEAR_1_SEM_2_SEM = 3
|
||||
const val YEAR_ALL_GRADES = 4
|
||||
}
|
||||
|
||||
override var image: String? = null
|
||||
|
@ -1,23 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Kacper Ziubryniewicz 2020-1-6
|
||||
*/
|
||||
|
||||
package pl.szczodrzynski.edziennik.data.db.full;
|
||||
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade;
|
||||
|
||||
public class GradeFull extends Grade {
|
||||
//public String category = "";
|
||||
//public int color;
|
||||
|
||||
public String subjectLongName = "";
|
||||
public String subjectShortName = "";
|
||||
|
||||
public String teacherFullName = "";
|
||||
|
||||
// metadata
|
||||
public boolean seen;
|
||||
public boolean notified;
|
||||
public long addedDate;
|
||||
}
|
||||
|
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright (c) Kacper Ziubryniewicz 2020-1-6
|
||||
*/
|
||||
package pl.szczodrzynski.edziennik.data.db.full
|
||||
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade
|
||||
|
||||
class GradeFull(
|
||||
profileId: Int, id: Long, name: String, type: Int,
|
||||
value: Float, weight: Float, color: Int,
|
||||
category: String?, description: String?, comment: String?,
|
||||
semester: Int, teacherId: Long, subjectId: Long
|
||||
) : Grade(
|
||||
profileId, id, name, type,
|
||||
value, weight, color,
|
||||
category, description, comment,
|
||||
semester, teacherId, subjectId
|
||||
) {
|
||||
var subjectLongName: String? = null
|
||||
var subjectShortName: String? = null
|
||||
var teacherFullName: String? = null
|
||||
// metadata
|
||||
var seen = false
|
||||
var notified = false
|
||||
var addedDate: Long = 0
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
package pl.szczodrzynski.edziennik.data.db.migration
|
||||
|
||||
import androidx.room.migration.Migration
|
||||
import androidx.sqlite.db.SupportSQLiteDatabase
|
||||
|
||||
class Migration78 : Migration(77, 78) {
|
||||
override fun migrate(database: SupportSQLiteDatabase) {
|
||||
// grades migration to kotlin
|
||||
database.execSQL("ALTER TABLE grades RENAME TO _grades;")
|
||||
database.execSQL("""CREATE TABLE grades (
|
||||
profileId INTEGER NOT NULL,
|
||||
gradeId INTEGER NOT NULL,
|
||||
gradeName TEXT NOT NULL,
|
||||
gradeType INTEGER NOT NULL,
|
||||
gradeValue REAL NOT NULL,
|
||||
gradeWeight REAL NOT NULL,
|
||||
gradeColor INTEGER NOT NULL,
|
||||
gradeCategory TEXT,
|
||||
gradeDescription TEXT,
|
||||
gradeComment TEXT,
|
||||
gradeSemester INTEGER NOT NULL,
|
||||
teacherId INTEGER NOT NULL,
|
||||
subjectId INTEGER NOT NULL,
|
||||
gradeValueMax REAL DEFAULT NULL,
|
||||
gradeClassAverage REAL DEFAULT NULL,
|
||||
gradeParentId INTEGER DEFAULT NULL,
|
||||
gradeIsImprovement INTEGER NOT NULL,
|
||||
PRIMARY KEY(profileId, gradeId)
|
||||
);""")
|
||||
database.execSQL("DROP INDEX IF EXISTS index_grades_profileId;")
|
||||
database.execSQL("CREATE INDEX index_grades_profileId ON grades (profileId);")
|
||||
database.execSQL("""INSERT INTO grades (profileId, gradeId, gradeName, gradeType, gradeValue, gradeWeight, gradeColor, gradeCategory, gradeDescription, gradeComment, gradeSemester, teacherId, subjectId, gradeValueMax, gradeClassAverage, gradeParentId, gradeIsImprovement)
|
||||
SELECT profileId, gradeId, gradeName, gradeType, gradeValue, gradeWeight, gradeColor,
|
||||
CASE gradeCategory WHEN '' THEN NULL WHEN ' ' THEN NULL ELSE gradeCategory END,
|
||||
CASE gradeDescription WHEN '' THEN NULL WHEN ' ' THEN NULL ELSE gradeDescription END,
|
||||
CASE gradeComment WHEN '' THEN NULL WHEN ' ' THEN NULL ELSE gradeComment END,
|
||||
gradeSemester, teacherId, subjectId,
|
||||
CASE gradeValueMax WHEN 0 THEN NULL ELSE gradeValueMax END,
|
||||
CASE gradeClassAverage WHEN -1 THEN NULL ELSE gradeClassAverage END,
|
||||
CASE gradeParentId WHEN -1 THEN NULL ELSE gradeParentId END,
|
||||
gradeIsImprovement FROM _grades;""")
|
||||
database.execSQL("DROP TABLE _grades;")
|
||||
}
|
||||
}
|
@ -1,129 +0,0 @@
|
||||
package pl.szczodrzynski.edziennik.ui.dialogs.grade;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.PorterDuffColorFilter;
|
||||
import android.os.AsyncTask;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.core.graphics.ColorUtils;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
|
||||
import com.afollestad.materialdialogs.MaterialDialog;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.List;
|
||||
|
||||
import pl.szczodrzynski.edziennik.App;
|
||||
import pl.szczodrzynski.edziennik.R;
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade;
|
||||
import pl.szczodrzynski.edziennik.data.db.full.GradeFull;
|
||||
import pl.szczodrzynski.edziennik.databinding.DialogGradeDetailsBinding;
|
||||
import pl.szczodrzynski.edziennik.ui.modules.grades.GradesListAdapter;
|
||||
import pl.szczodrzynski.edziennik.utils.Colors;
|
||||
|
||||
import static pl.szczodrzynski.edziennik.data.db.entity.Profile.COLOR_MODE_DEFAULT;
|
||||
|
||||
public class GradeDetailsDialog {
|
||||
private App app;
|
||||
private Context context;
|
||||
private int profileId;
|
||||
|
||||
public GradeDetailsDialog(Context context) {
|
||||
this.context = context;
|
||||
this.profileId = App.Companion.getProfileId();
|
||||
}
|
||||
public GradeDetailsDialog(Context context, int profileId) {
|
||||
this.context = context;
|
||||
this.profileId = profileId;
|
||||
}
|
||||
|
||||
public MaterialDialog dialog;
|
||||
private DialogGradeDetailsBinding b;
|
||||
private DialogInterface.OnDismissListener dismissListener;
|
||||
public boolean callDismissListener = true;
|
||||
|
||||
public GradeDetailsDialog withDismissListener(DialogInterface.OnDismissListener dismissListener) {
|
||||
this.dismissListener = dismissListener;
|
||||
return this;
|
||||
}
|
||||
public void performDismiss(DialogInterface dialogInterface) {
|
||||
if (callDismissListener && dismissListener != null) {
|
||||
dismissListener.onDismiss(dialogInterface);
|
||||
}
|
||||
callDismissListener = true;
|
||||
}
|
||||
|
||||
public void show(App _app, GradeFull grade)
|
||||
{
|
||||
this.app = _app;
|
||||
dialog = new MaterialDialog.Builder(context)
|
||||
.customView(R.layout.dialog_grade_details, true)
|
||||
.positiveText(R.string.close)
|
||||
.autoDismiss(false)
|
||||
.onPositive((dialog, which) -> dialog.dismiss())
|
||||
.dismissListener(this::performDismiss)
|
||||
.show();
|
||||
|
||||
View root = dialog.getCustomView();
|
||||
assert root != null;
|
||||
|
||||
b = DialogGradeDetailsBinding.bind(root);
|
||||
|
||||
b.setGrade(grade);
|
||||
|
||||
int gradeColor;
|
||||
if (App.Companion.getConfig().getFor(profileId).getGrades().getColorMode() == COLOR_MODE_DEFAULT) {
|
||||
gradeColor = grade.color;
|
||||
}
|
||||
else {
|
||||
gradeColor = Colors.gradeToColor(grade);
|
||||
}
|
||||
|
||||
DecimalFormat format = new DecimalFormat("#.##");
|
||||
if (grade.weight < 0) {
|
||||
grade.weight *= -1;
|
||||
}
|
||||
if (grade.type == Grade.TYPE_DESCRIPTIVE || grade.type == Grade.TYPE_DESCRIPTIVE_TEXT || grade.type == Grade.TYPE_TEXT || grade.type == Grade.TYPE_POINT_SUM) {
|
||||
b.setWeightText(null);
|
||||
grade.weight = 0;
|
||||
}
|
||||
else {
|
||||
if (grade.type == Grade.TYPE_POINT_AVG) {
|
||||
b.setWeightText(app.getString(R.string.grades_max_points_format, format.format(grade.valueMax)));
|
||||
}
|
||||
else if (grade.weight == 0) {
|
||||
b.setWeightText(app.getString(R.string.grades_weight_not_counted));
|
||||
}
|
||||
else {
|
||||
b.setWeightText(app.getString(R.string.grades_weight_format, format.format(grade.weight)));
|
||||
}
|
||||
}
|
||||
|
||||
b.setCommentVisible(false);
|
||||
|
||||
b.setDevMode(App.Companion.getDevMode());
|
||||
|
||||
b.gradeName.setTextColor(ColorUtils.calculateLuminance(gradeColor) > 0.3 ? 0xff000000 : 0xffffffff);
|
||||
b.gradeName.getBackground().setColorFilter(new PorterDuffColorFilter(gradeColor, PorterDuff.Mode.MULTIPLY));
|
||||
|
||||
AsyncTask.execute(() -> {
|
||||
|
||||
List<GradeFull> historyList = app.db.gradeDao().getAllWithParentIdNow(profileId, grade.id);
|
||||
|
||||
if (historyList.size() == 0) {
|
||||
b.setHistoryVisible(false);
|
||||
return;
|
||||
}
|
||||
b.setHistoryVisible(true);
|
||||
b.gradeHistoryNest.post(() -> {
|
||||
b.gradeHistoryNest.setNestedScrollingEnabled(false);
|
||||
b.gradeHistoryList.setHasFixedSize(false);
|
||||
b.gradeHistoryList.setNestedScrollingEnabled(false);
|
||||
b.gradeHistoryList.setLayoutManager(new LinearLayoutManager(context));
|
||||
b.gradeHistoryList.setAdapter(new GradesListAdapter(context, historyList));
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
@ -0,0 +1,83 @@
|
||||
package pl.szczodrzynski.edziennik.ui.dialogs.grade
|
||||
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.graphics.ColorUtils
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import kotlinx.coroutines.*
|
||||
import pl.szczodrzynski.edziennik.App
|
||||
import pl.szczodrzynski.edziennik.R
|
||||
import pl.szczodrzynski.edziennik.data.db.full.GradeFull
|
||||
import pl.szczodrzynski.edziennik.databinding.DialogGradeDetailsBinding
|
||||
import pl.szczodrzynski.edziennik.setTintColor
|
||||
import pl.szczodrzynski.edziennik.ui.modules.grades.GradesAdapter
|
||||
import pl.szczodrzynski.edziennik.utils.SimpleDividerItemDecoration
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
|
||||
class GradeDetailsDialog(
|
||||
val activity: AppCompatActivity,
|
||||
val grade: GradeFull,
|
||||
val onShowListener: ((tag: String) -> Unit)? = null,
|
||||
val onDismissListener: ((tag: String) -> Unit)? = null
|
||||
) : CoroutineScope {
|
||||
companion object {
|
||||
private const val TAG = "GradeDetailsDialog"
|
||||
}
|
||||
|
||||
private lateinit var app: App
|
||||
private lateinit var b: DialogGradeDetailsBinding
|
||||
private lateinit var dialog: AlertDialog
|
||||
|
||||
private val job = Job()
|
||||
override val coroutineContext: CoroutineContext
|
||||
get() = job + Dispatchers.Main
|
||||
|
||||
// local variables go here
|
||||
|
||||
init { run {
|
||||
if (activity.isFinishing)
|
||||
return@run
|
||||
onShowListener?.invoke(TAG)
|
||||
app = activity.applicationContext as App
|
||||
b = DialogGradeDetailsBinding.inflate(activity.layoutInflater)
|
||||
dialog = MaterialAlertDialogBuilder(activity)
|
||||
.setView(b.root)
|
||||
.setPositiveButton(R.string.close, null)
|
||||
.setOnDismissListener {
|
||||
onDismissListener?.invoke(TAG)
|
||||
}
|
||||
.show()
|
||||
val manager = app.gradesManager
|
||||
|
||||
val gradeColor = manager.getColor(grade)
|
||||
b.grade = grade
|
||||
b.weightText = manager.getWeightString(app, grade)
|
||||
b.commentVisible = false
|
||||
b.devMode = App.debugMode
|
||||
b.gradeName.setTextColor(if (ColorUtils.calculateLuminance(gradeColor) > 0.3) -0x1000000 else -0x1)
|
||||
b.gradeName.background.setTintColor(gradeColor)
|
||||
|
||||
b.gradeValue = if (grade.weight == 0f || grade.value < 0f) -1f else manager.getGradeValue(grade)
|
||||
|
||||
launch {
|
||||
val historyList = withContext(Dispatchers.Default) {
|
||||
app.db.gradeDao().getAllWithParentIdNow(App.profileId, grade.id)
|
||||
}
|
||||
if (historyList.isEmpty()) {
|
||||
b.historyVisible = false
|
||||
return@launch
|
||||
}
|
||||
b.historyVisible = true
|
||||
//b.gradeHistoryNest.isNestedScrollingEnabled = false
|
||||
b.gradeHistoryList.adapter = GradesAdapter(activity, {
|
||||
GradeDetailsDialog(activity, it)
|
||||
}).also { it.items = historyList.toMutableList() }
|
||||
b.gradeHistoryList.apply {
|
||||
setHasFixedSize(true)
|
||||
layoutManager = LinearLayoutManager(context)
|
||||
addItemDecoration(SimpleDividerItemDecoration(context))
|
||||
}
|
||||
}
|
||||
}}
|
||||
}
|
@ -6,14 +6,20 @@ package pl.szczodrzynski.edziennik.ui.dialogs.settings
|
||||
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.view.isVisible
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import pl.szczodrzynski.edziennik.App
|
||||
import pl.szczodrzynski.edziennik.MainActivity
|
||||
import pl.szczodrzynski.edziennik.R
|
||||
import pl.szczodrzynski.edziennik.config.ConfigGrades
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
||||
import it.sephiroth.android.library.numberpicker.doOnStopTrackingTouch
|
||||
import pl.szczodrzynski.edziennik.*
|
||||
import pl.szczodrzynski.edziennik.databinding.DialogConfigGradesBinding
|
||||
import pl.szczodrzynski.edziennik.setOnSelectedListener
|
||||
import pl.szczodrzynski.edziennik.utils.managers.GradesManager.Companion.COLOR_MODE_DEFAULT
|
||||
import pl.szczodrzynski.edziennik.utils.managers.GradesManager.Companion.COLOR_MODE_WEIGHTED
|
||||
import pl.szczodrzynski.edziennik.utils.managers.GradesManager.Companion.ORDER_BY_DATE_DESC
|
||||
import pl.szczodrzynski.edziennik.utils.managers.GradesManager.Companion.ORDER_BY_SUBJECT_ASC
|
||||
import pl.szczodrzynski.edziennik.utils.managers.GradesManager.Companion.YEAR_1_AVG_2_AVG
|
||||
import pl.szczodrzynski.edziennik.utils.managers.GradesManager.Companion.YEAR_1_AVG_2_SEM
|
||||
import pl.szczodrzynski.edziennik.utils.managers.GradesManager.Companion.YEAR_1_SEM_2_AVG
|
||||
import pl.szczodrzynski.edziennik.utils.managers.GradesManager.Companion.YEAR_1_SEM_2_SEM
|
||||
import pl.szczodrzynski.edziennik.utils.managers.GradesManager.Companion.YEAR_ALL_GRADES
|
||||
|
||||
class GradesConfigDialog(
|
||||
val activity: AppCompatActivity,
|
||||
@ -42,6 +48,7 @@ class GradesConfigDialog(
|
||||
.setView(b.root)
|
||||
.setPositiveButton(R.string.ok) { dialog, _ -> dialog.dismiss() }
|
||||
.setOnDismissListener {
|
||||
saveConfig()
|
||||
onDismissListener?.invoke(TAG)
|
||||
if (reloadOnDismiss) (activity as? MainActivity)?.reloadTarget()
|
||||
}
|
||||
@ -52,42 +59,71 @@ class GradesConfigDialog(
|
||||
}}
|
||||
|
||||
private fun loadConfig() {
|
||||
b.customPlusCheckBox.isChecked = profileConfig.plusValue != null
|
||||
b.customPlusValue.isVisible = b.customPlusCheckBox.isChecked
|
||||
b.customMinusCheckBox.isChecked = profileConfig.minusValue != null
|
||||
b.customMinusValue.isVisible = b.customMinusCheckBox.isChecked
|
||||
|
||||
b.customPlusValue.progress = profileConfig.plusValue ?: 0.5f
|
||||
b.customMinusValue.progress = profileConfig.minusValue ?: 0.25f
|
||||
|
||||
when (config.orderBy) {
|
||||
ConfigGrades.ORDER_BY_DATE_DESC -> b.sortGradesByDateRadio
|
||||
ConfigGrades.ORDER_BY_SUBJECT_ASC -> b.sortGradesBySubjectRadio
|
||||
ORDER_BY_DATE_DESC -> b.sortGradesByDateRadio
|
||||
ORDER_BY_SUBJECT_ASC -> b.sortGradesBySubjectRadio
|
||||
else -> null
|
||||
}?.isChecked = true
|
||||
|
||||
when (profileConfig.colorMode) {
|
||||
Profile.COLOR_MODE_DEFAULT -> b.gradeColorFromERegister
|
||||
Profile.COLOR_MODE_WEIGHTED -> b.gradeColorByValue
|
||||
COLOR_MODE_DEFAULT -> b.gradeColorFromERegister
|
||||
COLOR_MODE_WEIGHTED -> b.gradeColorByValue
|
||||
else -> null
|
||||
}?.isChecked = true
|
||||
|
||||
when (profileConfig.yearAverageMode) {
|
||||
Profile.YEAR_ALL_GRADES -> b.gradeAverageMode4
|
||||
Profile.YEAR_1_AVG_2_AVG -> b.gradeAverageMode0
|
||||
Profile.YEAR_1_SEM_2_AVG -> b.gradeAverageMode1
|
||||
Profile.YEAR_1_AVG_2_SEM -> b.gradeAverageMode2
|
||||
Profile.YEAR_1_SEM_2_SEM -> b.gradeAverageMode3
|
||||
YEAR_ALL_GRADES -> b.gradeAverageMode4
|
||||
YEAR_1_AVG_2_AVG -> b.gradeAverageMode0
|
||||
YEAR_1_SEM_2_AVG -> b.gradeAverageMode1
|
||||
YEAR_1_AVG_2_SEM -> b.gradeAverageMode2
|
||||
YEAR_1_SEM_2_SEM -> b.gradeAverageMode3
|
||||
else -> null
|
||||
}?.isChecked = true
|
||||
|
||||
b.dontCountZeroToAverage.isChecked = !profileConfig.countZeroToAvg
|
||||
}
|
||||
|
||||
private fun saveConfig() {
|
||||
profileConfig.plusValue = if (b.customPlusCheckBox.isChecked) b.customPlusValue.progress else null
|
||||
profileConfig.minusValue = if (b.customMinusCheckBox.isChecked) b.customMinusValue.progress else null
|
||||
}
|
||||
|
||||
private fun initView() {
|
||||
b.sortGradesByDateRadio.setOnSelectedListener { config.orderBy = ConfigGrades.ORDER_BY_DATE_DESC }
|
||||
b.sortGradesBySubjectRadio.setOnSelectedListener { config.orderBy = ConfigGrades.ORDER_BY_SUBJECT_ASC }
|
||||
b.customPlusCheckBox.onChange { _, isChecked ->
|
||||
b.customPlusValue.isVisible = isChecked
|
||||
}
|
||||
b.customMinusCheckBox.onChange { _, isChecked ->
|
||||
b.customMinusValue.isVisible = isChecked
|
||||
}
|
||||
|
||||
b.gradeColorFromERegister.setOnSelectedListener { profileConfig.colorMode = Profile.COLOR_MODE_DEFAULT }
|
||||
b.gradeColorByValue.setOnSelectedListener { profileConfig.colorMode = Profile.COLOR_MODE_WEIGHTED }
|
||||
// who the hell named those methods
|
||||
// THIS SHIT DOES NOT EVEN WORK
|
||||
b.customPlusValue.doOnStopTrackingTouch {
|
||||
profileConfig.plusValue = it.progress
|
||||
}
|
||||
b.customMinusValue.doOnStopTrackingTouch {
|
||||
profileConfig.minusValue = it.progress
|
||||
}
|
||||
|
||||
b.gradeAverageMode4.setOnSelectedListener { profileConfig.yearAverageMode = Profile.YEAR_ALL_GRADES }
|
||||
b.gradeAverageMode0.setOnSelectedListener { profileConfig.yearAverageMode = Profile.YEAR_1_AVG_2_AVG }
|
||||
b.gradeAverageMode1.setOnSelectedListener { profileConfig.yearAverageMode = Profile.YEAR_1_SEM_2_AVG }
|
||||
b.gradeAverageMode2.setOnSelectedListener { profileConfig.yearAverageMode = Profile.YEAR_1_AVG_2_SEM }
|
||||
b.gradeAverageMode3.setOnSelectedListener { profileConfig.yearAverageMode = Profile.YEAR_1_SEM_2_SEM }
|
||||
b.sortGradesByDateRadio.setOnSelectedListener { config.orderBy = ORDER_BY_DATE_DESC }
|
||||
b.sortGradesBySubjectRadio.setOnSelectedListener { config.orderBy = ORDER_BY_SUBJECT_ASC }
|
||||
|
||||
b.gradeColorFromERegister.setOnSelectedListener { profileConfig.colorMode = COLOR_MODE_DEFAULT }
|
||||
b.gradeColorByValue.setOnSelectedListener { profileConfig.colorMode = COLOR_MODE_WEIGHTED }
|
||||
|
||||
b.gradeAverageMode4.setOnSelectedListener { profileConfig.yearAverageMode = YEAR_ALL_GRADES }
|
||||
b.gradeAverageMode0.setOnSelectedListener { profileConfig.yearAverageMode = YEAR_1_AVG_2_AVG }
|
||||
b.gradeAverageMode1.setOnSelectedListener { profileConfig.yearAverageMode = YEAR_1_SEM_2_AVG }
|
||||
b.gradeAverageMode2.setOnSelectedListener { profileConfig.yearAverageMode = YEAR_1_AVG_2_SEM }
|
||||
b.gradeAverageMode3.setOnSelectedListener { profileConfig.yearAverageMode = YEAR_1_SEM_2_SEM }
|
||||
|
||||
b.dontCountZeroToAverage.setOnCheckedChangeListener { _, isChecked -> profileConfig.countZeroToAvg = !isChecked }
|
||||
}
|
||||
|
@ -0,0 +1,118 @@
|
||||
/*
|
||||
* Copyright (c) Kuba Szczodrzyński 2020-3-1.
|
||||
*/
|
||||
|
||||
package pl.szczodrzynski.edziennik.ui.modules.grades
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.graphics.Typeface
|
||||
import android.text.TextUtils
|
||||
import android.util.AttributeSet
|
||||
import android.util.TypedValue.COMPLEX_UNIT_SP
|
||||
import android.view.Gravity
|
||||
import android.view.View
|
||||
import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
|
||||
import android.widget.LinearLayout
|
||||
import androidx.appcompat.widget.AppCompatTextView
|
||||
import androidx.core.graphics.ColorUtils
|
||||
import pl.szczodrzynski.edziennik.R
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_SEMESTER1_FINAL
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_SEMESTER1_PROPOSED
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_SEMESTER2_FINAL
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_SEMESTER2_PROPOSED
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_YEAR_FINAL
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_YEAR_PROPOSED
|
||||
import pl.szczodrzynski.edziennik.dp
|
||||
import pl.szczodrzynski.edziennik.resolveAttr
|
||||
import pl.szczodrzynski.edziennik.setTintColor
|
||||
import pl.szczodrzynski.edziennik.utils.managers.GradesManager
|
||||
|
||||
class GradeView : AppCompatTextView {
|
||||
|
||||
@JvmOverloads
|
||||
constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) : super(context, attrs, defStyleAttr)
|
||||
|
||||
constructor(context: Context, grade: Grade, manager: GradesManager, periodGradesTextual: Boolean = false) : this(context, null) {
|
||||
setGrade(grade, manager, false, periodGradesTextual)
|
||||
}
|
||||
|
||||
@SuppressLint("RestrictedApi")
|
||||
fun setGrade(grade: Grade?, manager: GradesManager, bigView: Boolean = false, periodGradesTextual: Boolean = false) {
|
||||
if (grade == null) {
|
||||
visibility = View.GONE
|
||||
return
|
||||
}
|
||||
visibility = View.VISIBLE
|
||||
|
||||
val gradeName = grade.name
|
||||
|
||||
val gradeColor = manager.getColor(grade)
|
||||
|
||||
text = if (periodGradesTextual)
|
||||
when (grade.type) {
|
||||
TYPE_SEMESTER1_PROPOSED, TYPE_SEMESTER2_PROPOSED -> context.getString(
|
||||
R.string.grade_semester_proposed_format,
|
||||
gradeName
|
||||
)
|
||||
TYPE_SEMESTER1_FINAL, TYPE_SEMESTER2_FINAL -> context.getString(
|
||||
R.string.grade_semester_final_format,
|
||||
gradeName
|
||||
)
|
||||
TYPE_YEAR_PROPOSED -> context.getString(
|
||||
R.string.grade_year_proposed_format,
|
||||
gradeName
|
||||
)
|
||||
TYPE_YEAR_FINAL -> context.getString(
|
||||
R.string.grade_year_final_format,
|
||||
gradeName
|
||||
)
|
||||
else -> gradeName
|
||||
}
|
||||
else
|
||||
gradeName
|
||||
|
||||
setTextColor(when (grade.type) {
|
||||
TYPE_SEMESTER1_PROPOSED,
|
||||
TYPE_SEMESTER2_PROPOSED,
|
||||
TYPE_YEAR_PROPOSED -> android.R.attr.textColorPrimary.resolveAttr(context)
|
||||
else -> if (ColorUtils.calculateLuminance(gradeColor) > 0.3)
|
||||
0x99000000.toInt()
|
||||
else
|
||||
0x99ffffff.toInt()
|
||||
})
|
||||
|
||||
typeface = Typeface.create("serif-monospace", Typeface.BOLD)
|
||||
setBackgroundResource(when (grade.type) {
|
||||
TYPE_SEMESTER1_PROPOSED,
|
||||
TYPE_SEMESTER2_PROPOSED,
|
||||
TYPE_YEAR_PROPOSED -> if (bigView) R.drawable.bg_rounded_8dp_outline else R.drawable.bg_rounded_4dp_outline
|
||||
else -> if (bigView) R.drawable.bg_rounded_8dp else R.drawable.bg_rounded_4dp
|
||||
})
|
||||
background.setTintColor(gradeColor)
|
||||
gravity = Gravity.CENTER
|
||||
|
||||
if (bigView) {
|
||||
setTextSize(COMPLEX_UNIT_SP, 24f)
|
||||
setAutoSizeTextTypeUniformWithConfiguration(
|
||||
14,
|
||||
32,
|
||||
1,
|
||||
COMPLEX_UNIT_SP
|
||||
)
|
||||
setPadding(2.dp, 2.dp, 2.dp, 2.dp)
|
||||
}
|
||||
else {
|
||||
setTextSize(COMPLEX_UNIT_SP, 16f)
|
||||
setPadding(5.dp, 0, 5.dp, 0)
|
||||
layoutParams = LinearLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT).apply {
|
||||
setMargins(0, 0, 5.dp, 0)
|
||||
}
|
||||
maxLines = 1
|
||||
ellipsize = TextUtils.TruncateAt.END
|
||||
measure(WRAP_CONTENT, WRAP_CONTENT)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,187 @@
|
||||
/*
|
||||
* Copyright (c) Kuba Szczodrzyński 2020-2-29.
|
||||
*/
|
||||
|
||||
package pl.szczodrzynski.edziennik.ui.modules.grades
|
||||
|
||||
import android.animation.ObjectAnimator
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import pl.szczodrzynski.edziennik.App
|
||||
import pl.szczodrzynski.edziennik.R
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade
|
||||
import pl.szczodrzynski.edziennik.data.db.full.GradeFull
|
||||
import pl.szczodrzynski.edziennik.onClick
|
||||
import pl.szczodrzynski.edziennik.ui.modules.grades.models.*
|
||||
import pl.szczodrzynski.edziennik.ui.modules.grades.viewholder.*
|
||||
|
||||
class GradesAdapter(
|
||||
val activity: AppCompatActivity,
|
||||
var onGradeClick: ((item: GradeFull) -> Unit)? = null,
|
||||
var onGradesEditorClick: ((subjectId: Long, semesterNumber: Int) -> Unit)? = null
|
||||
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
|
||||
companion object {
|
||||
private const val TAG = "GradesAdapter"
|
||||
private const val ITEM_TYPE_SUBJECT = 0
|
||||
private const val ITEM_TYPE_SEMESTER = 1
|
||||
private const val ITEM_TYPE_EMPTY = 2
|
||||
private const val ITEM_TYPE_GRADE = 3
|
||||
private const val ITEM_TYPE_STATS = 4
|
||||
const val STATE_CLOSED = 0
|
||||
const val STATE_OPENED = 1
|
||||
}
|
||||
|
||||
var items = mutableListOf<Any>()
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
|
||||
val inflater = LayoutInflater.from(parent.context)
|
||||
return when (viewType) {
|
||||
ITEM_TYPE_SUBJECT -> SubjectViewHolder(inflater, parent)
|
||||
ITEM_TYPE_SEMESTER -> SemesterViewHolder(inflater, parent)
|
||||
ITEM_TYPE_EMPTY -> EmptyViewHolder(inflater, parent)
|
||||
ITEM_TYPE_GRADE -> GradeViewHolder(inflater, parent)
|
||||
ITEM_TYPE_STATS -> StatsViewHolder(inflater, parent)
|
||||
else -> throw IllegalArgumentException("Incorrect viewType")
|
||||
}
|
||||
}
|
||||
|
||||
override fun getItemViewType(position: Int): Int {
|
||||
return when (items[position]) {
|
||||
is GradesSubject -> ITEM_TYPE_SUBJECT
|
||||
is GradesSemester -> ITEM_TYPE_SEMESTER
|
||||
is GradesEmpty -> ITEM_TYPE_EMPTY
|
||||
is Grade -> ITEM_TYPE_GRADE
|
||||
is GradesStats -> ITEM_TYPE_STATS
|
||||
else -> throw IllegalArgumentException("Incorrect viewType")
|
||||
}
|
||||
}
|
||||
|
||||
private val onClickListener = View.OnClickListener { view ->
|
||||
val model = view.getTag(R.string.tag_key_model)
|
||||
if (model is GradeFull) {
|
||||
onGradeClick?.invoke(model)
|
||||
return@OnClickListener
|
||||
}
|
||||
if (model !is ExpandableItemModel<*>)
|
||||
return@OnClickListener
|
||||
val position = items.indexOf(model)
|
||||
if (position == -1)
|
||||
return@OnClickListener
|
||||
//val position = it.getTag(R.string.tag_key_position) as? Int ?: return@OnClickListener
|
||||
|
||||
if (model is GradesSubject || model is GradesSemester) {
|
||||
view.findViewById<View>(R.id.dropdownIcon)?.let { dropdownIcon ->
|
||||
ObjectAnimator.ofFloat(
|
||||
dropdownIcon,
|
||||
View.ROTATION,
|
||||
if (model.state == STATE_CLOSED) 0f else 180f,
|
||||
if (model.state == STATE_CLOSED) 180f else 0f
|
||||
).setDuration(200).start();
|
||||
}
|
||||
}
|
||||
if (model is GradesSubject) {
|
||||
val preview = view.findViewById<View>(R.id.previewContainer)
|
||||
val summary = view.findViewById<View>(R.id.yearSummary)
|
||||
preview?.visibility = if (model.state == STATE_CLOSED) View.INVISIBLE else View.VISIBLE
|
||||
summary?.visibility = if (model.state == STATE_CLOSED) View.VISIBLE else View.INVISIBLE
|
||||
}
|
||||
|
||||
if (model.state == STATE_CLOSED) {
|
||||
|
||||
val subItems = if (model is GradesSemester && model.grades.isEmpty())
|
||||
listOf(GradesEmpty())
|
||||
else
|
||||
model.items
|
||||
|
||||
model.state = STATE_OPENED
|
||||
items.addAll(position + 1, subItems.filterNotNull())
|
||||
notifyItemRangeInserted(position + 1, subItems.size)
|
||||
/*notifyItemRangeChanged(
|
||||
position + subItems.size,
|
||||
items.size - (position + subItems.size)
|
||||
)*/
|
||||
//notifyItemRangeChanged(position, items.size - position)
|
||||
|
||||
if (model is GradesSubject) {
|
||||
// auto expand first semester
|
||||
if (model.semesters.isNotEmpty()) {
|
||||
val semester = model.semesters.firstOrNull { it.grades.isNotEmpty() } ?: model.semesters.first()
|
||||
val semesterIndex = model.semesters.indexOf(semester)
|
||||
val grades = if (semester.grades.isEmpty())
|
||||
listOf(GradesEmpty())
|
||||
else
|
||||
semester.grades
|
||||
semester.state = STATE_OPENED
|
||||
items.addAll(position + 2 + semesterIndex, grades)
|
||||
notifyItemRangeInserted(position + 2 + semesterIndex, grades.size)
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
val start = position + 1
|
||||
var end: Int = items.size
|
||||
for (i in start until items.size) {
|
||||
val model1 = items[i]
|
||||
val level = if (model1 is GradesStats) 0 else (model1 as? ExpandableItemModel<*>)?.level ?: 3
|
||||
if (level <= model.level) {
|
||||
end = i
|
||||
break
|
||||
} else {
|
||||
if (model1 is ExpandableItemModel<*> && model1.state == STATE_OPENED) {
|
||||
model1.state = STATE_CLOSED
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (end != -1) {
|
||||
items.subList(start, end).clear()
|
||||
notifyItemRangeRemoved(start, end - start)
|
||||
//notifyItemRangeChanged(start, end - start)
|
||||
//notifyItemRangeChanged(position, items.size - position)
|
||||
}
|
||||
|
||||
model.state = STATE_CLOSED
|
||||
}
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
|
||||
val item = items[position]
|
||||
if (holder !is BindableViewHolder<*>)
|
||||
return
|
||||
|
||||
val app = activity.applicationContext as App
|
||||
|
||||
val viewType = when (holder) {
|
||||
is SubjectViewHolder -> ITEM_TYPE_SUBJECT
|
||||
is SemesterViewHolder -> ITEM_TYPE_SEMESTER
|
||||
is EmptyViewHolder -> ITEM_TYPE_EMPTY
|
||||
is GradeViewHolder -> ITEM_TYPE_GRADE
|
||||
is StatsViewHolder -> ITEM_TYPE_STATS
|
||||
else -> throw IllegalArgumentException("Incorrect viewType")
|
||||
}
|
||||
holder.itemView.setTag(R.string.tag_key_view_type, viewType)
|
||||
holder.itemView.setTag(R.string.tag_key_position, position)
|
||||
holder.itemView.setTag(R.string.tag_key_model, item)
|
||||
|
||||
when {
|
||||
holder is SubjectViewHolder && item is GradesSubject -> holder.onBind(activity, app, item, position)
|
||||
holder is SemesterViewHolder && item is GradesSemester -> holder.onBind(activity, app, item, position)
|
||||
holder is EmptyViewHolder && item is GradesEmpty -> holder.onBind(activity, app, item, position)
|
||||
holder is GradeViewHolder && item is GradeFull -> holder.onBind(activity, app, item, position)
|
||||
holder is StatsViewHolder && item is GradesStats -> holder.onBind(activity, app, item, position)
|
||||
}
|
||||
|
||||
if (holder is SemesterViewHolder && item is GradesSemester) {
|
||||
holder.b.editButton.onClick {
|
||||
onGradesEditorClick?.invoke(item.subjectId, item.number)
|
||||
}
|
||||
}
|
||||
|
||||
holder.itemView.setOnClickListener(onClickListener)
|
||||
}
|
||||
|
||||
override fun getItemCount() = items.size
|
||||
}
|
@ -1,513 +0,0 @@
|
||||
package pl.szczodrzynski.edziennik.ui.modules.grades;
|
||||
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ListView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.databinding.DataBindingUtil;
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
||||
import com.afollestad.materialdialogs.MaterialDialog;
|
||||
import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import pl.szczodrzynski.edziennik.App;
|
||||
import pl.szczodrzynski.edziennik.MainActivity;
|
||||
import pl.szczodrzynski.edziennik.R;
|
||||
import pl.szczodrzynski.edziennik.config.ProfileConfigGrades;
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade;
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Subject;
|
||||
import pl.szczodrzynski.edziennik.data.db.full.GradeFull;
|
||||
import pl.szczodrzynski.edziennik.databinding.FragmentGradesBinding;
|
||||
import pl.szczodrzynski.edziennik.ui.dialogs.settings.GradesConfigDialog;
|
||||
import pl.szczodrzynski.edziennik.utils.Themes;
|
||||
import pl.szczodrzynski.edziennik.utils.models.ItemGradesSubjectModel;
|
||||
import pl.szczodrzynski.navlib.bottomsheet.items.BottomSheetPrimaryItem;
|
||||
import pl.szczodrzynski.navlib.bottomsheet.items.BottomSheetSeparatorItem;
|
||||
|
||||
import static pl.szczodrzynski.edziennik.config.ConfigGrades.ORDER_BY_DATE_ASC;
|
||||
import static pl.szczodrzynski.edziennik.config.ConfigGrades.ORDER_BY_DATE_DESC;
|
||||
import static pl.szczodrzynski.edziennik.config.ConfigGrades.ORDER_BY_SUBJECT_ASC;
|
||||
import static pl.szczodrzynski.edziennik.data.db.entity.Metadata.TYPE_GRADE;
|
||||
import static pl.szczodrzynski.edziennik.data.db.entity.Profile.YEAR_1_AVG_2_AVG;
|
||||
import static pl.szczodrzynski.edziennik.data.db.entity.Profile.YEAR_1_AVG_2_SEM;
|
||||
import static pl.szczodrzynski.edziennik.data.db.entity.Profile.YEAR_1_SEM_2_AVG;
|
||||
import static pl.szczodrzynski.edziennik.data.db.entity.Profile.YEAR_1_SEM_2_SEM;
|
||||
import static pl.szczodrzynski.edziennik.data.db.entity.Profile.YEAR_ALL_GRADES;
|
||||
|
||||
public class GradesFragment extends Fragment {
|
||||
|
||||
private App app = null;
|
||||
private MainActivity activity = null;
|
||||
private FragmentGradesBinding b = null;
|
||||
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
activity = (MainActivity) getActivity();
|
||||
if (getActivity() == null || getContext() == null)
|
||||
return null;
|
||||
app = (App) activity.getApplication();
|
||||
getContext().getTheme().applyStyle(Themes.INSTANCE.getAppTheme(), true);
|
||||
// activity, context and profile is valid
|
||||
b = DataBindingUtil.inflate(inflater, R.layout.fragment_grades, container, false);
|
||||
b.refreshLayout.setParent(activity.getSwipeRefreshLayout());
|
||||
b.refreshLayout.setNestedScrollingEnabled(true);
|
||||
return b.getRoot();
|
||||
}
|
||||
|
||||
ListView listView;
|
||||
List<ItemGradesSubjectModel> subjectList;
|
||||
|
||||
private String getRegisterCardAverageModeSubText() {
|
||||
switch (App.Companion.getConfig().forProfile().getGrades().getYearAverageMode()) {
|
||||
default:
|
||||
case YEAR_1_AVG_2_AVG:
|
||||
return getString(R.string.settings_register_avg_mode_0_short);
|
||||
case YEAR_1_SEM_2_AVG:
|
||||
return getString(R.string.settings_register_avg_mode_1_short);
|
||||
case YEAR_1_AVG_2_SEM:
|
||||
return getString(R.string.settings_register_avg_mode_2_short);
|
||||
case YEAR_1_SEM_2_SEM:
|
||||
return getString(R.string.settings_register_avg_mode_3_short);
|
||||
case YEAR_ALL_GRADES:
|
||||
return getString(R.string.settings_register_avg_mode_4_short);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||
if (app == null || activity == null || b == null || !isAdded())
|
||||
return;
|
||||
|
||||
/*activity.getBottomSheet().setToggleGroupEnabled(true);
|
||||
activity.getBottomSheet().toggleGroupRemoveItems();
|
||||
activity.getBottomSheet().setToggleGroupSelectionMode(NavBottomSheet.TOGGLE_GROUP_SORTING_ORDER);
|
||||
activity.getBottomSheet().toggleGroupAddItem(0, getString(R.string.sort_by_date), (Drawable)null, SORT_MODE_DESCENDING);
|
||||
activity.getBottomSheet().toggleGroupAddItem(1, getString(R.string.sort_by_subject), (Drawable)null, SORT_MODE_ASCENDING);
|
||||
activity.getBottomSheet().setToggleGroupSortingOrderListener((id, sortMode) -> {
|
||||
sortModeChanged = true;
|
||||
if (id == 0 && sortMode == SORT_MODE_ASCENDING) {
|
||||
app.appConfig.gradesOrderBy = ORDER_BY_DATE_ASC;
|
||||
}
|
||||
else if (id == 1 && sortMode == SORT_MODE_ASCENDING) {
|
||||
app.appConfig.gradesOrderBy = ORDER_BY_SUBJECT_ASC;
|
||||
}
|
||||
else if (id == 0 && sortMode == SORT_MODE_DESCENDING) {
|
||||
app.appConfig.gradesOrderBy = ORDER_BY_DATE_DESC;
|
||||
}
|
||||
else if (id == 1 && sortMode == SORT_MODE_DESCENDING) {
|
||||
app.appConfig.gradesOrderBy = ORDER_BY_SUBJECT_DESC;
|
||||
}
|
||||
return null;
|
||||
});
|
||||
activity.getBottomSheet().setToggleGroupTitle("Sortowanie");
|
||||
activity.getBottomSheet().toggleGroupCheck(0);
|
||||
activity.getBottomSheet().setOnCloseListener(() -> {
|
||||
if (sortModeChanged) {
|
||||
sortModeChanged = false;
|
||||
activity.reloadTarget();
|
||||
}
|
||||
return null;
|
||||
});*/
|
||||
|
||||
activity.getBottomSheet().prependItems(
|
||||
new BottomSheetPrimaryItem(true)
|
||||
.withTitle(R.string.menu_grades_averages)
|
||||
.withDescription(R.string.menu_grades_averages_desc)
|
||||
.withIcon(CommunityMaterial.Icon.cmd_chart_line)
|
||||
.withOnClickListener(v3 -> {
|
||||
activity.getBottomSheet().close();
|
||||
showAverages();
|
||||
}),
|
||||
new BottomSheetPrimaryItem(true)
|
||||
.withTitle(R.string.menu_grades_config)
|
||||
.withIcon(CommunityMaterial.Icon2.cmd_settings_outline)
|
||||
.withOnClickListener(v3 -> {
|
||||
activity.getBottomSheet().close();
|
||||
new GradesConfigDialog(activity, true, null, null);
|
||||
}),
|
||||
new BottomSheetSeparatorItem(true),
|
||||
new BottomSheetPrimaryItem(true)
|
||||
.withTitle(R.string.menu_mark_as_read)
|
||||
.withIcon(CommunityMaterial.Icon.cmd_eye_check_outline)
|
||||
.withOnClickListener(v3 -> {
|
||||
activity.getBottomSheet().close();
|
||||
AsyncTask.execute(() -> App.db.metadataDao().setAllSeen(App.Companion.getProfileId(), TYPE_GRADE, true));
|
||||
Toast.makeText(activity, R.string.main_menu_mark_as_read_success, Toast.LENGTH_SHORT).show();
|
||||
})
|
||||
);
|
||||
activity.gainAttention();
|
||||
|
||||
/*b.refreshLayout.setOnRefreshListener(() -> {
|
||||
activity.syncCurrentFeature(MainActivity.DRAWER_ITEM_GRADES, b.refreshLayout);
|
||||
});*/
|
||||
|
||||
listView = b.gradesRecyclerView;
|
||||
//listView.setHasFixedSize(true);
|
||||
//listView.setLayoutManager(new LinearLayoutManager(getContext()));
|
||||
|
||||
long expandSubjectId = -1;
|
||||
if (getArguments() != null) {
|
||||
expandSubjectId = getArguments().getLong("gradesSubjectId", -1);
|
||||
}
|
||||
|
||||
/*b.gradesSwipeLayout.setOnRefreshListener(() -> {
|
||||
Toast.makeText(activity, "Works!", Toast.LENGTH_LONG).show();
|
||||
// To keep animation for 4 seconds
|
||||
new Handler().postDelayed(() -> {
|
||||
// Stop animation (This will be after 3 seconds)
|
||||
b.gradesSwipeLayout.setRefreshing(false);
|
||||
}, 3000);
|
||||
});*/
|
||||
|
||||
long finalExpandSubjectId = expandSubjectId;
|
||||
String orderBy;
|
||||
if (app.getConfig().getGrades().getOrderBy() == ORDER_BY_SUBJECT_ASC) {
|
||||
orderBy = "subjectLongName ASC, addedDate DESC";
|
||||
}
|
||||
else if (app.getConfig().getGrades().getOrderBy() == ORDER_BY_DATE_DESC) {
|
||||
orderBy = "addedDate DESC";
|
||||
}
|
||||
else if (app.getConfig().getGrades().getOrderBy() == ORDER_BY_DATE_ASC) {
|
||||
orderBy = "addedDate ASC";
|
||||
}
|
||||
else {
|
||||
orderBy = "subjectLongName DESC, addedDate DESC";
|
||||
}
|
||||
|
||||
App.db.gradeDao().getAllOrderBy(App.Companion.getProfileId(), orderBy).observe(this, grades -> {
|
||||
if (app == null || activity == null || b == null || !isAdded())
|
||||
return;
|
||||
|
||||
subjectList = new ArrayList<>();
|
||||
|
||||
ProfileConfigGrades config = app.getConfig().getFor(App.Companion.getProfileId()).getGrades();
|
||||
|
||||
// now we have all grades from the newest to the oldest
|
||||
for (GradeFull grade: grades) {
|
||||
ItemGradesSubjectModel model = ItemGradesSubjectModel.searchModelBySubjectId(subjectList, grade.subjectId);
|
||||
if (model == null) {
|
||||
model = new ItemGradesSubjectModel(app.getProfile(),
|
||||
new Subject(App.Companion.getProfileId(), grade.subjectId, grade.subjectLongName, grade.subjectShortName),
|
||||
new ArrayList<>(),
|
||||
new ArrayList<>());
|
||||
subjectList.add(model);
|
||||
if (model.subject != null && model.subject.id == finalExpandSubjectId) {
|
||||
model.expandView = true;
|
||||
}
|
||||
model.colorMode = App.Companion.getConfig().forProfile().getGrades().getColorMode();
|
||||
model.yearAverageMode = App.Companion.getConfig().forProfile().getGrades().getYearAverageMode();
|
||||
}
|
||||
if (!grade.seen && grade.semester == 1) {
|
||||
model.semester1Unread++;
|
||||
}
|
||||
if (!grade.seen && grade.semester == 2) {
|
||||
model.semester2Unread++;
|
||||
}
|
||||
// COUNT POINT GRADES
|
||||
if (grade.type == Grade.TYPE_POINT_AVG) {
|
||||
model.isPointSubject = true;
|
||||
if (grade.semester == 1) {
|
||||
model.gradeSumOverall += grade.value;
|
||||
model.gradeCountOverall += grade.valueMax;
|
||||
model.gradeSumSemester1 += grade.value;
|
||||
model.gradeCountSemester1 += grade.valueMax;
|
||||
model.semester1Average = model.gradeSumSemester1 / model.gradeCountSemester1 * 100;
|
||||
model.grades1.add(grade);
|
||||
}
|
||||
if (grade.semester == 2) {
|
||||
model.gradeSumOverall += grade.value;
|
||||
model.gradeCountOverall += grade.valueMax;
|
||||
model.gradeSumSemester2 += grade.value;
|
||||
model.gradeCountSemester2 += grade.valueMax;
|
||||
model.semester2Average = model.gradeSumSemester2 / model.gradeCountSemester2 * 100;
|
||||
model.grades2.add(grade);
|
||||
}
|
||||
}
|
||||
else if (grade.type == Grade.TYPE_POINT_SUM) {
|
||||
model.isBehaviourSubject = true;
|
||||
if (grade.semester == 1) {
|
||||
model.semester1Average += grade.value;
|
||||
model.yearAverage += grade.value;
|
||||
model.grades1.add(grade);
|
||||
}
|
||||
if (grade.semester == 2) {
|
||||
model.semester2Average += grade.value;
|
||||
model.yearAverage += grade.value;
|
||||
model.grades2.add(grade);
|
||||
}
|
||||
}
|
||||
else if (grade.type == Grade.TYPE_NORMAL) {
|
||||
model.isNormalSubject = true;
|
||||
float weight = grade.weight;
|
||||
if (weight < 0) {
|
||||
// do not show *normal* grades with negative weight - these are historical grades - Iuczniowie
|
||||
continue;
|
||||
}
|
||||
if (!config.getCountZeroToAvg() && grade.name.equals("0")) {
|
||||
weight = 0;
|
||||
}
|
||||
float valueWeighted = grade.value * weight;
|
||||
if (grade.semester == 1) {
|
||||
model.gradeSumOverall += valueWeighted;
|
||||
model.gradeCountOverall += weight;
|
||||
model.gradeSumSemester1 += valueWeighted;
|
||||
model.gradeCountSemester1 += weight;
|
||||
model.semester1Average = model.gradeSumSemester1 / model.gradeCountSemester1;
|
||||
if (grade.parentId == -1) {
|
||||
// show only "current" grades - these which are not historical
|
||||
model.grades1.add(grade);
|
||||
}
|
||||
}
|
||||
if (grade.semester == 2) {
|
||||
model.gradeSumOverall += valueWeighted;
|
||||
model.gradeCountOverall += weight;
|
||||
model.gradeSumSemester2 += valueWeighted;
|
||||
model.gradeCountSemester2 += weight;
|
||||
model.semester2Average = model.gradeSumSemester2 / model.gradeCountSemester2;
|
||||
if (grade.parentId == -1) {
|
||||
// show only "current" grades - these which are not historical
|
||||
model.grades2.add(grade);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (grade.type == Grade.TYPE_SEMESTER1_PROPOSED) {
|
||||
model.semester1Proposed = grade;
|
||||
}
|
||||
else if (grade.type == Grade.TYPE_SEMESTER1_FINAL) {
|
||||
model.semester1Final = grade;
|
||||
}
|
||||
else if (grade.type == Grade.TYPE_SEMESTER2_PROPOSED) {
|
||||
model.semester2Proposed = grade;
|
||||
}
|
||||
else if (grade.type == Grade.TYPE_SEMESTER2_FINAL) {
|
||||
model.semester2Final = grade;
|
||||
}
|
||||
else if (grade.type == Grade.TYPE_YEAR_PROPOSED) {
|
||||
model.yearProposed = grade;
|
||||
}
|
||||
else if (grade.type == Grade.TYPE_YEAR_FINAL) {
|
||||
model.yearFinal = grade;
|
||||
}
|
||||
else {
|
||||
// descriptive grades, text grades
|
||||
model.isDescriptiveSubject = true;
|
||||
if (grade.semester == 1) {
|
||||
model.grades1.add(grade);
|
||||
}
|
||||
if (grade.semester == 2) {
|
||||
model.grades2.add(grade);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (ItemGradesSubjectModel model: subjectList) {
|
||||
if (model.isPointSubject) {
|
||||
model.yearAverage = model.gradeSumOverall / model.gradeCountOverall * 100.0f; // map the point grade "average" % value from 0.0f-1.0f to 0%-100%
|
||||
}
|
||||
/*else if (model.isDescriptiveSubject && !model.isNormalSubject) {
|
||||
// applies for only descriptive grades - do nothing. average is hidden
|
||||
//model.isDescriptiveSubject = false;
|
||||
//model.semester1Average = -1;
|
||||
//model.semester2Average = -1;
|
||||
//model.yearAverage = -1;
|
||||
}*/
|
||||
else if (!model.isBehaviourSubject && model.isNormalSubject) {
|
||||
// applies for normal grades & normal+descriptive grades
|
||||
// calculate the normal grade average based on the user's setting
|
||||
switch (App.Companion.getConfig().forProfile().getGrades().getYearAverageMode()) {
|
||||
case YEAR_1_AVG_2_AVG:
|
||||
model.yearAverage = (model.semester1Average + model.semester2Average) / 2;
|
||||
break;
|
||||
case YEAR_1_SEM_2_AVG:
|
||||
model.yearAverage = model.semester1Final != null ? (model.semester1Final.value + model.semester2Average) / 2 : 0.0f;
|
||||
break;
|
||||
case YEAR_1_AVG_2_SEM:
|
||||
model.yearAverage = model.semester2Final != null ? (model.semester1Average + model.semester2Final.value) / 2 : 0.0f;
|
||||
break;
|
||||
case YEAR_1_SEM_2_SEM:
|
||||
model.yearAverage = model.semester1Final != null && model.semester2Final != null ? (model.semester1Final.value + model.semester2Final.value) / 2 : 0.0f;
|
||||
break;
|
||||
default:
|
||||
case YEAR_ALL_GRADES:
|
||||
model.yearAverage = model.gradeSumOverall / model.gradeCountOverall;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (subjectList.size() > 0) {
|
||||
GradesSubjectAdapter adapter;
|
||||
if ((adapter = (GradesSubjectAdapter) listView.getAdapter()) != null) {
|
||||
adapter.subjectList = subjectList;
|
||||
adapter.notifyDataSetChanged();
|
||||
return;
|
||||
}
|
||||
adapter = new GradesSubjectAdapter(subjectList, activity);
|
||||
listView.setAdapter(adapter);
|
||||
listView.setVisibility(View.VISIBLE);
|
||||
b.gradesNoData.setVisibility(View.GONE);
|
||||
if (finalExpandSubjectId != -1) {
|
||||
int subjectIndex = subjectList.indexOf(ItemGradesSubjectModel.searchModelBySubjectId(subjectList, finalExpandSubjectId));
|
||||
listView.setSelection(subjectIndex > 0 ? subjectIndex - 1 : subjectIndex);
|
||||
}
|
||||
}
|
||||
else {
|
||||
listView.setVisibility(View.GONE);
|
||||
b.gradesNoData.setVisibility(View.VISIBLE);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private int gradeFromAverage(float value) {
|
||||
int grade = (int)Math.floor(value);
|
||||
if (value % 1.0f >= 0.75f)
|
||||
grade++;
|
||||
return grade;
|
||||
}
|
||||
|
||||
public void showAverages() {
|
||||
if (app == null || activity == null || b == null || !isAdded() || subjectList == null)
|
||||
return;
|
||||
|
||||
float semester1Sum = 0;
|
||||
float semester1Count = 0;
|
||||
float semester1ProposedSum = 0;
|
||||
float semester1ProposedCount = 0;
|
||||
float semester1FinalSum = 0;
|
||||
float semester1FinalCount = 0;
|
||||
|
||||
float semester2Sum = 0;
|
||||
float semester2Count = 0;
|
||||
float semester2ProposedSum = 0;
|
||||
float semester2ProposedCount = 0;
|
||||
float semester2FinalSum = 0;
|
||||
float semester2FinalCount = 0;
|
||||
|
||||
float yearSum = 0;
|
||||
float yearCount = 0;
|
||||
float yearProposedSum = 0;
|
||||
float yearProposedCount = 0;
|
||||
float yearFinalSum = 0;
|
||||
float yearFinalCount = 0;
|
||||
|
||||
for (ItemGradesSubjectModel subject: subjectList) {
|
||||
// we cannot skip non-normal subjects because a point subject may also have a final grade
|
||||
if (subject.isBehaviourSubject)
|
||||
continue;
|
||||
|
||||
// SEMESTER 1 GRADES & AVERAGES
|
||||
if (subject.semester1Final != null && subject.semester1Final.value > 0) { // if final available, add to final grades & expected grades
|
||||
semester1FinalSum += subject.semester1Final.value;
|
||||
semester1FinalCount++;
|
||||
semester1Sum += subject.semester1Final.value;
|
||||
semester1Count++;
|
||||
}
|
||||
else if (subject.semester1Proposed != null && subject.semester1Proposed.value > 0) { // if final not available, add proposed to expected grades
|
||||
semester1Sum += subject.semester1Proposed.value;
|
||||
semester1Count++;
|
||||
}
|
||||
else if (!Float.isNaN(subject.semester1Average)
|
||||
&& subject.semester1Average > 0
|
||||
&& !subject.isPointSubject) { // if final&proposed unavailable, calculate from avg
|
||||
semester1Sum += gradeFromAverage(subject.semester1Average);
|
||||
semester1Count++;
|
||||
}
|
||||
if (subject.semester1Proposed != null && subject.semester1Proposed.value > 0) { // add proposed to proposed grades even if final is available
|
||||
semester1ProposedSum += subject.semester1Proposed.value;
|
||||
semester1ProposedCount++;
|
||||
}
|
||||
|
||||
// SEMESTER 2 GRADES & AVERAGES
|
||||
if (subject.semester2Final != null && subject.semester2Final.value > 0) { // if final available, add to final grades & expected grades
|
||||
semester2FinalSum += subject.semester2Final.value;
|
||||
semester2FinalCount++;
|
||||
semester2Sum += subject.semester2Final.value;
|
||||
semester2Count++;
|
||||
}
|
||||
else if (subject.semester2Proposed != null && subject.semester2Proposed.value > 0) { // if final not available, add proposed to expected grades
|
||||
semester2Sum += subject.semester2Proposed.value;
|
||||
semester2Count++;
|
||||
}
|
||||
else if (!Float.isNaN(subject.semester2Average)
|
||||
&& subject.semester2Average > 0
|
||||
&& !subject.isPointSubject) { // if final&proposed unavailable, calculate from avg
|
||||
semester2Sum += gradeFromAverage(subject.semester2Average);
|
||||
semester2Count++;
|
||||
}
|
||||
if (subject.semester2Proposed != null && subject.semester2Proposed.value > 0) { // add proposed to proposed grades even if final is available
|
||||
semester2ProposedSum += subject.semester2Proposed.value;
|
||||
semester2ProposedCount++;
|
||||
}
|
||||
|
||||
// YEAR GRADES & AVERAGES
|
||||
if (subject.yearFinal != null && subject.yearFinal.value > 0) { // if final available, add to final grades & expected grades
|
||||
yearFinalSum += subject.yearFinal.value;
|
||||
yearFinalCount++;
|
||||
yearSum += subject.yearFinal.value;
|
||||
yearCount++;
|
||||
}
|
||||
else if (subject.yearProposed != null && subject.yearProposed.value > 0) { // if final not available, add proposed to expected grades
|
||||
yearSum += subject.yearProposed.value;
|
||||
yearCount++;
|
||||
}
|
||||
else if (!Float.isNaN(subject.yearAverage)
|
||||
&& subject.yearAverage > 0
|
||||
&& !subject.isPointSubject) { // if final&proposed unavailable, calculate from avg
|
||||
yearSum += gradeFromAverage(subject.yearAverage);
|
||||
yearCount++;
|
||||
}
|
||||
if (subject.yearProposed != null && subject.yearProposed.value > 0) { // add proposed to proposed grades even if final is available
|
||||
yearProposedSum += subject.yearProposed.value;
|
||||
yearProposedCount++;
|
||||
}
|
||||
}
|
||||
|
||||
String semester1ExpectedAverageStr = semester1Count > semester1ProposedCount || semester1Count > semester1FinalCount ? getString(R.string.dialog_averages_expected_format, 1, semester1Sum / semester1Count) : "";
|
||||
String semester1ProposedAverageStr = semester1ProposedCount > 0 ? getString(R.string.dialog_averages_proposed_format, 1, semester1ProposedSum / semester1ProposedCount) : "";
|
||||
String semester1FinalAverageStr = semester1FinalCount > 0 ? getString(R.string.dialog_averages_final_format, 1, semester1FinalSum / semester1FinalCount) : "";
|
||||
|
||||
String semester2ExpectedAverageStr = semester2Count > semester2ProposedCount || semester2Count > semester2FinalCount ? getString(R.string.dialog_averages_expected_format, 2, semester2Sum / semester2Count) : "";
|
||||
String semester2ProposedAverageStr = semester2ProposedCount > 0 ? getString(R.string.dialog_averages_proposed_format, 2, semester2ProposedSum / semester2ProposedCount) : "";
|
||||
String semester2FinalAverageStr = semester2FinalCount > 0 ? getString(R.string.dialog_averages_final_format, 2, semester2FinalSum / semester2FinalCount) : "";
|
||||
|
||||
String yearExpectedAverageStr = yearCount > yearProposedCount || yearCount > yearFinalCount ? getString(R.string.dialog_averages_expected_yearly_format, yearSum / yearCount) : "";
|
||||
String yearProposedAverageStr = yearProposedCount > 0 ? getString(R.string.dialog_averages_proposed_yearly_format, yearProposedSum / yearProposedCount) : "";
|
||||
String yearFinalAverageStr = yearFinalCount > 0 ? getString(R.string.dialog_averages_final_yearly_format, yearFinalSum / yearFinalCount) : "";
|
||||
|
||||
if (semester1ExpectedAverageStr.isEmpty() && semester1ProposedAverageStr.isEmpty() && semester1FinalAverageStr.isEmpty()) {
|
||||
semester1ExpectedAverageStr = getString(R.string.dialog_averages_unavailable_format, 1);
|
||||
}
|
||||
if (semester2ExpectedAverageStr.isEmpty() && semester2ProposedAverageStr.isEmpty() && semester2FinalAverageStr.isEmpty()) {
|
||||
semester2ExpectedAverageStr = getString(R.string.dialog_averages_unavailable_format, 2);
|
||||
}
|
||||
if (yearExpectedAverageStr.isEmpty() && yearProposedAverageStr.isEmpty() && yearFinalAverageStr.isEmpty()) {
|
||||
yearExpectedAverageStr = getString(R.string.dialog_averages_unavailable_yearly);
|
||||
}
|
||||
|
||||
new MaterialDialog.Builder(activity)
|
||||
.title(R.string.dialog_averages_title)
|
||||
.content(getString(
|
||||
R.string.dialog_averages_format,
|
||||
semester1ExpectedAverageStr,
|
||||
semester1ProposedAverageStr,
|
||||
semester1FinalAverageStr,
|
||||
semester2ExpectedAverageStr,
|
||||
semester2ProposedAverageStr,
|
||||
semester2FinalAverageStr,
|
||||
yearExpectedAverageStr,
|
||||
yearProposedAverageStr,
|
||||
yearFinalAverageStr))
|
||||
.positiveText(R.string.ok)
|
||||
.show();
|
||||
}
|
||||
}
|
@ -0,0 +1,245 @@
|
||||
/*
|
||||
* Copyright (c) Kuba Szczodrzyński 2020-3-4.
|
||||
*/
|
||||
|
||||
package pl.szczodrzynski.edziennik.ui.modules.grades
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.Fragment
|
||||
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.averageOrNull
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade
|
||||
import pl.szczodrzynski.edziennik.data.db.full.GradeFull
|
||||
import pl.szczodrzynski.edziennik.databinding.GradesFragmentBinding
|
||||
import pl.szczodrzynski.edziennik.ui.dialogs.grade.GradeDetailsDialog
|
||||
import pl.szczodrzynski.edziennik.ui.modules.grades.models.GradesAverages
|
||||
import pl.szczodrzynski.edziennik.ui.modules.grades.models.GradesSemester
|
||||
import pl.szczodrzynski.edziennik.ui.modules.grades.models.GradesStats
|
||||
import pl.szczodrzynski.edziennik.ui.modules.grades.models.GradesSubject
|
||||
import pl.szczodrzynski.edziennik.utils.managers.GradesManager
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
import kotlin.math.max
|
||||
|
||||
class GradesFragment : Fragment(), CoroutineScope {
|
||||
companion object {
|
||||
private const val TAG = "GradesFragment"
|
||||
}
|
||||
|
||||
private lateinit var app: App
|
||||
private lateinit var activity: MainActivity
|
||||
private lateinit var b: GradesFragmentBinding
|
||||
|
||||
private val job: Job = Job()
|
||||
override val coroutineContext: CoroutineContext
|
||||
get() = job + Dispatchers.Main
|
||||
|
||||
// local/private variables go here
|
||||
private val adapter by lazy {
|
||||
GradesAdapter(activity)
|
||||
}
|
||||
private val manager by lazy { app.gradesManager }
|
||||
private val dontCountGrades by lazy { manager.dontCountGrades }
|
||||
|
||||
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 = GradesFragmentBinding.inflate(inflater)
|
||||
b.refreshLayout.setParent(activity.swipeRefreshLayout)
|
||||
return b.root
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
if (!isAdded)
|
||||
return
|
||||
|
||||
app.db.gradeDao()
|
||||
.getAllOrderBy(App.profileId, app.gradesManager.getOrderByString())
|
||||
.observe(this, Observer { grades ->
|
||||
if (b.gradesRecyclerView.adapter == null) {
|
||||
b.gradesRecyclerView.adapter = adapter
|
||||
b.gradesRecyclerView.apply {
|
||||
setHasFixedSize(true)
|
||||
layoutManager = LinearLayoutManager(context)
|
||||
//addItemDecoration(SimpleDividerItemDecoration(context))
|
||||
}
|
||||
}
|
||||
|
||||
launch(Dispatchers.Default) {
|
||||
processGrades(grades)
|
||||
}
|
||||
|
||||
if (grades != null && grades.isNotEmpty()) {
|
||||
b.gradesRecyclerView.visibility = View.VISIBLE
|
||||
b.gradesNoData.visibility = View.GONE
|
||||
} else {
|
||||
b.gradesRecyclerView.visibility = View.GONE
|
||||
b.gradesNoData.visibility = View.VISIBLE
|
||||
}
|
||||
})
|
||||
|
||||
adapter.onGradeClick = {
|
||||
GradeDetailsDialog(activity, it)
|
||||
}
|
||||
|
||||
adapter.onGradesEditorClick = { subjectId, semesterNumber ->
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun processGrades(grades: List<GradeFull>) {
|
||||
val items = mutableListOf<GradesSubject>()
|
||||
|
||||
var subjectId = -1L
|
||||
var semesterNumber = 0
|
||||
var subject = GradesSubject(subjectId, "")
|
||||
var semester = GradesSemester(0, 1)
|
||||
|
||||
// grades returned by the query are ordered
|
||||
// by the subject ID, so it's easier and probably
|
||||
// a bit faster to build all the models
|
||||
for (grade in grades) {
|
||||
/*if (grade.parentId != null && grade.parentId != -1L)
|
||||
continue // the grade is hidden as a new, improved one is available*/
|
||||
if (grade.subjectId != subjectId) {
|
||||
subjectId = grade.subjectId
|
||||
semesterNumber = 0
|
||||
|
||||
subject = items.firstOrNull { it.subjectId == subjectId }
|
||||
?: GradesSubject(grade.subjectId, grade.subjectLongName ?: "").also {
|
||||
items += it
|
||||
it.semester = 2
|
||||
}
|
||||
}
|
||||
if (grade.semester != semesterNumber) {
|
||||
semesterNumber = grade.semester
|
||||
|
||||
semester = subject.semesters.firstOrNull { it.number == semesterNumber }
|
||||
?: GradesSemester(subject.subjectId, grade.semester).also { subject.semesters += it }
|
||||
}
|
||||
|
||||
when (grade.type) {
|
||||
Grade.TYPE_SEMESTER1_PROPOSED,
|
||||
Grade.TYPE_SEMESTER2_PROPOSED -> semester.proposedGrade = grade
|
||||
Grade.TYPE_SEMESTER1_FINAL,
|
||||
Grade.TYPE_SEMESTER2_FINAL -> semester.finalGrade = grade
|
||||
Grade.TYPE_YEAR_PROPOSED -> subject.proposedGrade = grade
|
||||
Grade.TYPE_YEAR_FINAL -> subject.finalGrade = grade
|
||||
else -> {
|
||||
semester.grades += grade
|
||||
countGrade(grade, subject.averages)
|
||||
countGrade(grade, semester.averages)
|
||||
}
|
||||
}
|
||||
|
||||
subject.lastAddedDate = max(subject.lastAddedDate, grade.addedDate)
|
||||
}
|
||||
|
||||
val stats = GradesStats()
|
||||
|
||||
val sem1Expected = mutableListOf<Float>()
|
||||
val sem2Expected = mutableListOf<Float>()
|
||||
val yearlyExpected = mutableListOf<Float>()
|
||||
val sem1Proposed = mutableListOf<Float>()
|
||||
val sem2Proposed = mutableListOf<Float>()
|
||||
val yearlyProposed = mutableListOf<Float>()
|
||||
val sem1Final = mutableListOf<Float>()
|
||||
val sem2Final = mutableListOf<Float>()
|
||||
val yearlyFinal = mutableListOf<Float>()
|
||||
|
||||
val sem1Point = mutableListOf<Float>()
|
||||
val sem2Point = mutableListOf<Float>()
|
||||
val yearlyPoint = mutableListOf<Float>()
|
||||
|
||||
for (item in items) {
|
||||
item.semesters.forEach { sem ->
|
||||
manager.calculateAverages(sem.averages)
|
||||
if (sem.number == 1) {
|
||||
sem.proposedGrade?.value?.let { sem1Proposed += it }
|
||||
sem.finalGrade?.value?.let {
|
||||
sem1Final += it
|
||||
sem1Expected += it
|
||||
} ?: run {
|
||||
sem.averages.normalAvg?.let { sem1Expected += manager.getRoundedGrade(it).toFloat() }
|
||||
}
|
||||
sem.averages.pointAvgPercent?.let { sem1Point += it }
|
||||
}
|
||||
if (sem.number == 2) {
|
||||
sem.proposedGrade?.value?.let { sem2Proposed += it }
|
||||
sem.finalGrade?.value?.let {
|
||||
sem2Final += it
|
||||
sem2Expected += it
|
||||
} ?: run {
|
||||
sem.averages.normalAvg?.let { sem2Expected += manager.getRoundedGrade(it).toFloat() }
|
||||
}
|
||||
sem.averages.pointAvgPercent?.let { sem2Point += it }
|
||||
}
|
||||
}
|
||||
manager.calculateAverages(item.averages, item.semesters)
|
||||
item.proposedGrade?.value?.let { yearlyProposed += it }
|
||||
item.finalGrade?.value?.let {
|
||||
yearlyFinal += it
|
||||
yearlyExpected += it
|
||||
} ?: run {
|
||||
item.averages.normalAvg?.let { yearlyExpected += manager.getRoundedGrade(it).toFloat() }
|
||||
}
|
||||
item.averages.pointAvgPercent?.let { yearlyPoint += it }
|
||||
}
|
||||
|
||||
stats.normalSem1 = sem1Expected.averageOrNull()?.toFloat() ?: 0f
|
||||
stats.normalSem1Proposed = sem1Proposed.averageOrNull()?.toFloat() ?: 0f
|
||||
stats.normalSem1Final = sem1Final.averageOrNull()?.toFloat() ?: 0f
|
||||
stats.sem1NotAllFinal = sem1Final.size < sem1Expected.size
|
||||
stats.normalSem2 = sem2Expected.averageOrNull()?.toFloat() ?: 0f
|
||||
stats.normalSem2Proposed = sem2Proposed.averageOrNull()?.toFloat() ?: 0f
|
||||
stats.normalSem2Final = sem2Final.averageOrNull()?.toFloat() ?: 0f
|
||||
stats.sem2NotAllFinal = sem2Final.size < sem2Expected.size
|
||||
stats.normalYearly = yearlyExpected.averageOrNull()?.toFloat() ?: 0f
|
||||
stats.normalYearlyProposed = yearlyProposed.averageOrNull()?.toFloat() ?: 0f
|
||||
stats.normalYearlyFinal = yearlyFinal.averageOrNull()?.toFloat() ?: 0f
|
||||
stats.yearlyNotAllFinal = yearlyFinal.size < yearlyExpected.size
|
||||
|
||||
stats.pointSem1 = sem1Point.averageOrNull()?.toFloat() ?: 0f
|
||||
stats.pointSem2 = sem2Point.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 }
|
||||
}
|
||||
|
||||
adapter.items = items.toMutableList()
|
||||
adapter.items.add(stats)
|
||||
|
||||
withContext(Dispatchers.Main) {
|
||||
adapter.notifyDataSetChanged()
|
||||
}
|
||||
}
|
||||
|
||||
private fun countGrade(grade: Grade, averages: GradesAverages) {
|
||||
val value = manager.getGradeValue(grade)
|
||||
val weight = manager.getGradeWeight(dontCountGrades, grade)
|
||||
when (grade.type) {
|
||||
Grade.TYPE_NORMAL -> {
|
||||
averages.normalSum += value
|
||||
averages.normalCount ++
|
||||
averages.normalWeightedSum += value * weight
|
||||
averages.normalWeightedCount += weight
|
||||
}
|
||||
Grade.TYPE_POINT_AVG -> {
|
||||
averages.pointAvgSum += grade.value
|
||||
averages.pointAvgMax += grade.valueMax ?: value
|
||||
}
|
||||
Grade.TYPE_POINT_SUM -> {
|
||||
averages.pointSum += grade.value
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,143 +0,0 @@
|
||||
package pl.szczodrzynski.edziennik.ui.modules.grades;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.PorterDuffColorFilter;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.core.graphics.ColorUtils;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.List;
|
||||
|
||||
import pl.szczodrzynski.edziennik.App;
|
||||
import pl.szczodrzynski.edziennik.R;
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade;
|
||||
import pl.szczodrzynski.edziennik.data.db.full.GradeFull;
|
||||
import pl.szczodrzynski.edziennik.ui.dialogs.grade.GradeDetailsDialog;
|
||||
import pl.szczodrzynski.edziennik.utils.Colors;
|
||||
import pl.szczodrzynski.edziennik.utils.models.Date;
|
||||
|
||||
import static pl.szczodrzynski.edziennik.data.db.entity.Profile.COLOR_MODE_DEFAULT;
|
||||
|
||||
public class GradesListAdapter extends RecyclerView.Adapter<GradesListAdapter.ViewHolder> {
|
||||
private Context mContext;
|
||||
private List<GradeFull> gradeList;
|
||||
|
||||
//getting the context and product list with constructor
|
||||
public GradesListAdapter(Context mCtx, List<GradeFull> gradeList) {
|
||||
this.mContext = mCtx;
|
||||
this.gradeList = gradeList;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public GradesListAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
//inflating and returning our view holder
|
||||
LayoutInflater inflater = LayoutInflater.from(mContext);
|
||||
View view = inflater.inflate(R.layout.row_grades_list_item, parent, false);
|
||||
return new GradesListAdapter.ViewHolder(view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull GradesListAdapter.ViewHolder holder, int position) {
|
||||
App app = (App) mContext.getApplicationContext();
|
||||
|
||||
GradeFull grade = gradeList.get(position);
|
||||
|
||||
holder.root.setOnClickListener((v -> {
|
||||
new GradeDetailsDialog(v.getContext(), App.Companion.getProfileId()).show(app, grade);
|
||||
}));
|
||||
|
||||
int gradeColor;
|
||||
if (App.Companion.getConfig().forProfile().getGrades().getColorMode() == COLOR_MODE_DEFAULT) {
|
||||
gradeColor = grade.color;
|
||||
}
|
||||
else {
|
||||
gradeColor = Colors.gradeToColor(grade);
|
||||
}
|
||||
|
||||
holder.gradesListName.setText(grade.name);
|
||||
holder.gradesListName.setSelected(true);
|
||||
//holder.gradesListName.setTypeface(null, Typeface.BOLD);
|
||||
holder.gradesListName.setTextColor(ColorUtils.calculateLuminance(gradeColor) > 0.3 ? 0xff000000 : 0xffffffff);
|
||||
holder.gradesListName.getBackground().setColorFilter(new PorterDuffColorFilter(gradeColor, PorterDuff.Mode.MULTIPLY));
|
||||
|
||||
if (grade.description.trim().isEmpty()) {
|
||||
holder.gradesListDescription.setText(grade.category);
|
||||
holder.gradesListCategory.setText(grade.isImprovement ? app.getString(R.string.grades_improvement_category_format, "") : "");
|
||||
}
|
||||
else {
|
||||
holder.gradesListDescription.setText(grade.description);
|
||||
holder.gradesListCategory.setText(grade.isImprovement ? app.getString(R.string.grades_improvement_category_format, grade.category) : grade.category);
|
||||
}
|
||||
|
||||
DecimalFormat format = new DecimalFormat("#.##");
|
||||
DecimalFormat formatWithZeroes = new DecimalFormat("#.00");
|
||||
|
||||
if (grade.weight < 0) {
|
||||
grade.weight *= -1;
|
||||
}
|
||||
if (grade.type == Grade.TYPE_DESCRIPTIVE || grade.type == Grade.TYPE_DESCRIPTIVE_TEXT || grade.type == Grade.TYPE_TEXT || grade.type == Grade.TYPE_POINT_SUM) {
|
||||
holder.gradesListWeight.setVisibility(View.GONE);
|
||||
grade.weight = 0;
|
||||
}
|
||||
else {
|
||||
holder.gradesListWeight.setVisibility(View.VISIBLE);
|
||||
if (grade.type == Grade.TYPE_POINT_AVG) {
|
||||
holder.gradesListWeight.setText(app.getString(R.string.grades_max_points_format, format.format(grade.valueMax)));
|
||||
}
|
||||
else if (grade.weight == 0) {
|
||||
holder.gradesListWeight.setText(app.getString(R.string.grades_weight_not_counted));
|
||||
}
|
||||
else {
|
||||
holder.gradesListWeight.setText(app.getString(R.string.grades_weight_format, format.format(grade.weight) + (grade.classAverage != -1 ? ", " + formatWithZeroes.format(grade.classAverage) : "")));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
holder.gradesListTeacher.setText(grade.teacherFullName);
|
||||
holder.gradesListAddedDate.setText(Date.fromMillis(grade.addedDate).getFormattedStringShort());
|
||||
|
||||
if (!grade.seen) {
|
||||
holder.gradesListDescription.setBackground(mContext.getResources().getDrawable(R.drawable.bg_rounded_4dp));
|
||||
holder.gradesListDescription.getBackground().setColorFilter(new PorterDuffColorFilter(0x692196f3, PorterDuff.Mode.MULTIPLY));
|
||||
}
|
||||
else {
|
||||
holder.gradesListDescription.setBackground(null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return gradeList.size();
|
||||
}
|
||||
|
||||
class ViewHolder extends RecyclerView.ViewHolder {
|
||||
|
||||
View root;
|
||||
TextView gradesListName;
|
||||
TextView gradesListDescription;
|
||||
TextView gradesListCategory;
|
||||
TextView gradesListWeight;
|
||||
TextView gradesListTeacher;
|
||||
TextView gradesListAddedDate;
|
||||
|
||||
ViewHolder(View itemView) {
|
||||
super(itemView);
|
||||
root = itemView.getRootView();
|
||||
gradesListName = itemView.findViewById(R.id.gradesListName);
|
||||
gradesListDescription = itemView.findViewById(R.id.gradesListCategoryColumn);
|
||||
gradesListCategory = itemView.findViewById(R.id.gradesListCategoryDescription);
|
||||
gradesListWeight = itemView.findViewById(R.id.gradesListWeight);
|
||||
gradesListTeacher = itemView.findViewById(R.id.gradesListTeacher);
|
||||
gradesListAddedDate = itemView.findViewById(R.id.gradesListAddedDate);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,787 +0,0 @@
|
||||
package pl.szczodrzynski.edziennik.ui.modules.grades;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.PorterDuffColorFilter;
|
||||
import android.graphics.Typeface;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.animation.Animation;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.constraintlayout.widget.ConstraintLayout;
|
||||
import androidx.core.graphics.ColorUtils;
|
||||
import androidx.core.widget.NestedScrollView;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.mikepenz.iconics.view.IconicsImageView;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.List;
|
||||
|
||||
import pl.szczodrzynski.edziennik.App;
|
||||
import pl.szczodrzynski.edziennik.MainActivity;
|
||||
import pl.szczodrzynski.edziennik.R;
|
||||
import pl.szczodrzynski.edziennik.data.db.AppDb;
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Subject;
|
||||
import pl.szczodrzynski.edziennik.data.db.full.GradeFull;
|
||||
import pl.szczodrzynski.edziennik.utils.Anim;
|
||||
import pl.szczodrzynski.edziennik.utils.Colors;
|
||||
import pl.szczodrzynski.edziennik.utils.Utils;
|
||||
import pl.szczodrzynski.edziennik.utils.models.ItemGradesSubjectModel;
|
||||
|
||||
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
|
||||
import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
|
||||
import static pl.szczodrzynski.edziennik.MainActivity.TARGET_GRADES_EDITOR;
|
||||
import static pl.szczodrzynski.edziennik.data.db.entity.Profile.COLOR_MODE_DEFAULT;
|
||||
import static pl.szczodrzynski.edziennik.data.db.entity.Profile.YEAR_1_AVG_2_SEM;
|
||||
import static pl.szczodrzynski.edziennik.data.db.entity.Profile.YEAR_1_SEM_2_AVG;
|
||||
import static pl.szczodrzynski.edziennik.data.db.entity.Profile.YEAR_1_SEM_2_SEM;
|
||||
|
||||
public class GradesSubjectAdapter extends ArrayAdapter<ItemGradesSubjectModel> implements View.OnClickListener {
|
||||
private static final String TAG = "GradesSubjectAdapter";
|
||||
private MainActivity activity;
|
||||
public List<ItemGradesSubjectModel> subjectList;
|
||||
|
||||
private void updateBadges(Context context, ItemGradesSubjectModel model) {
|
||||
// do not need this since we have an Observer for unread counters..
|
||||
//((App)getContext().getApplicationContext()).saveRegister(); // I don't like this.
|
||||
}
|
||||
|
||||
private boolean invalidAvg(float avg) {
|
||||
return avg == 0.0f || Float.isNaN(avg);
|
||||
}
|
||||
|
||||
private void updateSubjectSemesterBadges(ViewHolder holder, ItemGradesSubjectModel model) {
|
||||
if (model.semester1Unread > 0 || model.semester2Unread > 0) {
|
||||
holder.gradesSubjectTitle.setBackground(getContext().getResources().getDrawable(R.drawable.bg_rounded_4dp));
|
||||
holder.gradesSubjectTitle.getBackground().setColorFilter(new PorterDuffColorFilter(0x692196f3, PorterDuff.Mode.MULTIPLY));
|
||||
}
|
||||
else {
|
||||
holder.gradesSubjectTitle.setBackground(null);
|
||||
}
|
||||
if (model.semester1Unread > 0) {
|
||||
holder.gradesSubjectSemester1Title.setBackground(getContext().getResources().getDrawable(R.drawable.bg_rounded_4dp));
|
||||
holder.gradesSubjectSemester1Title.getBackground().setColorFilter(new PorterDuffColorFilter(0x692196f3, PorterDuff.Mode.MULTIPLY));
|
||||
}
|
||||
else {
|
||||
holder.gradesSubjectSemester1Title.setBackground(null);
|
||||
}
|
||||
if (model.semester2Unread > 0) {
|
||||
holder.gradesSubjectSemester2Title.setBackground(getContext().getResources().getDrawable(R.drawable.bg_rounded_4dp));
|
||||
holder.gradesSubjectSemester2Title.getBackground().setColorFilter(new PorterDuffColorFilter(0x692196f3, PorterDuff.Mode.MULTIPLY));
|
||||
}
|
||||
else {
|
||||
holder.gradesSubjectSemester2Title.setBackground(null);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean gradesSetAsRead(ViewHolder holder, ItemGradesSubjectModel model, int semester) {
|
||||
boolean somethingChanged = false;
|
||||
AppDb db = App.Companion.getDb();
|
||||
if (semester == 1) {
|
||||
model.semester1Unread = 0;
|
||||
for (GradeFull grade : model.grades1) {
|
||||
if (!grade.seen) {
|
||||
db.metadataDao().setSeen(App.Companion.getProfileId(), grade, somethingChanged = true);
|
||||
}
|
||||
}
|
||||
if (model.semester1Proposed != null && !model.semester1Proposed.seen)
|
||||
db.metadataDao().setSeen(App.Companion.getProfileId(), model.semester1Proposed, somethingChanged = true);
|
||||
if (model.semester1Final != null && !model.semester1Final.seen)
|
||||
db.metadataDao().setSeen(App.Companion.getProfileId(), model.semester1Final, somethingChanged = true);
|
||||
}
|
||||
else if (semester == 2) {
|
||||
model.semester2Unread = 0;
|
||||
for (GradeFull grade : model.grades2) {
|
||||
if (!grade.seen) {
|
||||
db.metadataDao().setSeen(App.Companion.getProfileId(), grade, somethingChanged = true);
|
||||
}
|
||||
}
|
||||
if (model.semester2Proposed != null && !model.semester2Proposed.seen)
|
||||
db.metadataDao().setSeen(App.Companion.getProfileId(), model.semester2Proposed, somethingChanged = true);
|
||||
if (model.semester2Final != null && !model.semester2Final.seen)
|
||||
db.metadataDao().setSeen(App.Companion.getProfileId(), model.semester2Final, somethingChanged = true);
|
||||
if (model.yearProposed != null && !model.yearProposed.seen)
|
||||
db.metadataDao().setSeen(App.Companion.getProfileId(), model.yearProposed, somethingChanged = true);
|
||||
if (model.yearFinal != null && !model.yearFinal.seen)
|
||||
db.metadataDao().setSeen(App.Companion.getProfileId(), model.yearFinal, somethingChanged = true);
|
||||
}
|
||||
if (somethingChanged) updateSubjectSemesterBadges(holder, model);
|
||||
return somethingChanged;
|
||||
}
|
||||
|
||||
private void expandSubject(ViewHolder holder, ItemGradesSubjectModel model) {
|
||||
Anim.fadeOut(holder.gradesSubjectPreviewContainer, 200, new Animation.AnimationListener() {
|
||||
@Override public void onAnimationStart(Animation animation) { }
|
||||
@Override public void onAnimationRepeat(Animation animation) { }
|
||||
@Override
|
||||
public void onAnimationEnd(Animation animation) {
|
||||
boolean somethingChanged = false;
|
||||
if (holder.gradesSubjectSemester1Container.getVisibility() != View.GONE) {
|
||||
somethingChanged = gradesSetAsRead(holder, model, 1);
|
||||
}
|
||||
if (holder.gradesSubjectSemester2Container.getVisibility() != View.GONE) {
|
||||
somethingChanged = gradesSetAsRead(holder, model, 2);
|
||||
}
|
||||
if (somethingChanged) updateBadges(getContext(), model);
|
||||
//holder.gradesSubjectPreviewContent.setVisibility(View.INVISIBLE);
|
||||
Anim.expand(holder.gradesSubjectContent, 500, null);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void collapseSubject(ViewHolder holder, ItemGradesSubjectModel model) {
|
||||
Anim.collapse(holder.gradesSubjectContent, 500, new Animation.AnimationListener() {
|
||||
@Override public void onAnimationStart(Animation animation) { }
|
||||
@Override public void onAnimationRepeat(Animation animation) { }
|
||||
@Override
|
||||
public void onAnimationEnd(Animation animation) {
|
||||
//holder.gradesSubjectPreviewContent.setVisibility(View.VISIBLE);
|
||||
Anim.fadeIn(holder.gradesSubjectPreviewContainer, 200, null);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
class BuildGradeViews extends AsyncTask<Void, Void, Void> {
|
||||
boolean findViews;
|
||||
ItemGradesSubjectModel model;
|
||||
//ViewGroup parent;
|
||||
//int position;
|
||||
ViewHolder holder;
|
||||
|
||||
BuildGradeViews(ItemGradesSubjectModel model, ViewHolder holder, ViewGroup parent, int position, boolean findViews) {
|
||||
this.model = model;
|
||||
this.holder = holder;
|
||||
this.findViews = findViews;
|
||||
//this.parent = parent;
|
||||
//this.position = position;
|
||||
}
|
||||
|
||||
protected Void doInBackground(Void... params) {
|
||||
if (this.findViews) {
|
||||
findViews(holder, holder.gradesSubjectRoot);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected void onPostExecute(Void aVoid) {
|
||||
DecimalFormat df = new DecimalFormat("#.00");
|
||||
if (this.findViews) {
|
||||
// TODO NIE WIEM CO TO ROBI XD
|
||||
//this.viewHolder.semestrTitle1.setText(C0193R.string.semestr1);
|
||||
//this.viewHolder.semestrTitle2.setText(C0193R.string.semestr2);
|
||||
/*if (GradesSubjectAdapter.this.columns == 0) {
|
||||
DisplayMetrics metrics = GradeListAdapterBySubject.this.context.getResources().getDisplayMetrics();
|
||||
if (GradeListAdapterBySubject.this.context.getResources().getBoolean(C0193R.bool.tablet)) {
|
||||
GradeListAdapterBySubject.this.columns = ((int) ((((float) (this.parent.getWidth() / 2)) / metrics.density) - 30.0f)) / 58;
|
||||
} else {
|
||||
GradeListAdapterBySubject.this.columns = ((int) ((((float) this.parent.getWidth()) / metrics.density) - 30.0f)) / 58;
|
||||
}
|
||||
}
|
||||
this.viewHolder.semestrGridView1.setColumnCount(GradeListAdapterBySubject.this.columns);
|
||||
this.viewHolder.semestrGridView2.setColumnCount(GradeListAdapterBySubject.this.columns);*/
|
||||
}
|
||||
if (model != null && model.subject != null && model.subject.id != holder.lastSubject) {
|
||||
holder.gradesSubjectRoot.setBackground(Colors.getAdaptiveBackgroundDrawable(model.subject.color, model.subject.color));
|
||||
updateSubjectSemesterBadges(holder, model);
|
||||
holder.gradesSubjectTitle.setText(model.subject.longName);
|
||||
holder.gradesSubjectPreviewContent.removeAllViews();
|
||||
|
||||
if (model.expandView) {
|
||||
// commented is without animations, do not use now (with unread badges)
|
||||
//holder.gradesSubjectContent.setVisibility(View.VISIBLE);
|
||||
//holder.gradesSubjectPreviewContent.setVisibility(View.INVISIBLE);
|
||||
expandSubject(holder, model);
|
||||
model.expandView = false;
|
||||
}
|
||||
int showSemester = model.profile.getCurrentSemester();
|
||||
|
||||
List<GradeFull> gradeList = (showSemester == 1 ? model.grades1 : model.grades2);
|
||||
if (gradeList.size() == 0) {
|
||||
showSemester = (showSemester == 1 ? 2 : 1);
|
||||
gradeList = (showSemester == 1 ? model.grades1 : model.grades2);
|
||||
}
|
||||
|
||||
App app = (App) getContext().getApplicationContext();
|
||||
|
||||
float scale = getContext().getResources().getDisplayMetrics().density;
|
||||
int _5dp = (int) (5 * scale + 0.5f);
|
||||
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT);
|
||||
layoutParams.setMargins(0, 0, _5dp, 0);
|
||||
|
||||
DisplayMetrics displayMetrics = getContext().getResources().getDisplayMetrics();
|
||||
int maxWidthPx = displayMetrics.widthPixels - Utils.dpToPx((app.getConfig().getUi().getMiniMenuVisible() ? 72 : 0)/*miniDrawer size*/ + 8 + 8/*left and right offsets*/ + 24/*ellipsize width*/);
|
||||
int totalWidthPx = 0;
|
||||
boolean ellipsized = false;
|
||||
|
||||
if (showSemester != model.profile.getCurrentSemester()) {
|
||||
// showing different semester, because of no grades in the selected one
|
||||
holder.gradesSubjectPreviewSemester.setVisibility(View.VISIBLE);
|
||||
holder.gradesSubjectPreviewSemester.setText(getContext().getString(R.string.grades_semester_header_format, showSemester));
|
||||
// decrease the max preview width. DONE below
|
||||
/*holder.gradesSubjectPreviewSemester.measure(WRAP_CONTENT, WRAP_CONTENT);
|
||||
maxWidthPx -= holder.gradesSubjectPreviewSemester.getMeasuredWidth();
|
||||
maxWidthPx -= _5dp;*/
|
||||
}
|
||||
else {
|
||||
holder.gradesSubjectPreviewSemester.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
|
||||
if (model.grades1.size() > 0) {
|
||||
holder.gradesSubjectSemester1Nest.setNestedScrollingEnabled(false);
|
||||
holder.gradesSubjectSemester1Content.setHasFixedSize(false);
|
||||
holder.gradesSubjectSemester1Content.setNestedScrollingEnabled(false);
|
||||
holder.gradesSubjectSemester1Content.setLayoutManager(new LinearLayoutManager(activity));
|
||||
holder.gradesSubjectSemester1Content.setAdapter(new GradesListAdapter(activity, model.grades1));
|
||||
holder.gradesSubjectSemester1Header.setVisibility(View.VISIBLE);
|
||||
if (showSemester == 1) {
|
||||
holder.gradesSubjectSemester1Container.setVisibility(View.VISIBLE);
|
||||
}
|
||||
else {
|
||||
holder.gradesSubjectSemester1Container.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
if (model.isDescriptiveSubject && !model.isNormalSubject && !model.isPointSubject && !model.isBehaviourSubject) {
|
||||
holder.gradesSubjectPreviewAverage.setVisibility(View.GONE);
|
||||
holder.gradesSubjectSemester1Average.setVisibility(View.GONE);
|
||||
}
|
||||
else {
|
||||
holder.gradesSubjectPreviewAverage.setVisibility(View.VISIBLE);
|
||||
holder.gradesSubjectSemester1Average.setVisibility(View.VISIBLE);
|
||||
int formatSingle = (model.isPointSubject ? R.string.grades_average_single_percent_format : model.isBehaviourSubject ? R.string.grades_average_single_point_format : R.string.grades_average_single_format);
|
||||
int format = (model.isPointSubject ? R.string.grades_semester_average_percent_format : model.isBehaviourSubject ? R.string.grades_semester_average_point_format : R.string.grades_semester_average_format);
|
||||
// PREVIEW AVERAGE
|
||||
if (showSemester == 1) {
|
||||
holder.gradesSubjectPreviewAverage.setText(
|
||||
getContext().getString(
|
||||
formatSingle,
|
||||
invalidAvg(model.semester1Average) ? "-" : df.format(model.semester1Average)
|
||||
)
|
||||
);
|
||||
}
|
||||
// AVERAGE value
|
||||
holder.gradesSubjectSemester1Average.setText(
|
||||
getContext().getString(
|
||||
format,
|
||||
1,
|
||||
invalidAvg(model.semester1Average) ? "-" : df.format(model.semester1Average)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// PROPOSED grade
|
||||
if (model.semester1Proposed != null) {
|
||||
holder.gradesSubjectSemester1Proposed.setVisibility(View.VISIBLE);
|
||||
holder.gradesSubjectSemester1Proposed.setText(model.semester1Proposed.name);
|
||||
holder.gradesSubjectSemester1Proposed.getBackground().setColorFilter(new PorterDuffColorFilter(Colors.gradeNameToColor(model.semester1Proposed.name), PorterDuff.Mode.MULTIPLY));
|
||||
holder.gradesSubjectSemester1Proposed.setTextColor(Colors.gradeNameToColor(model.semester1Proposed.name));
|
||||
if (showSemester == 1) {
|
||||
holder.gradesSubjectPreviewProposed.setVisibility(View.VISIBLE);
|
||||
holder.gradesSubjectPreviewProposed.setText(model.semester1Proposed.name);
|
||||
holder.gradesSubjectPreviewProposed.getBackground().setColorFilter(new PorterDuffColorFilter(Colors.gradeNameToColor(model.semester1Proposed.name), PorterDuff.Mode.MULTIPLY));
|
||||
holder.gradesSubjectPreviewProposed.setTextColor(Colors.gradeNameToColor(model.semester1Proposed.name));
|
||||
}
|
||||
}
|
||||
else {
|
||||
holder.gradesSubjectSemester1Proposed.setVisibility(View.GONE);
|
||||
if (showSemester == 1) {
|
||||
holder.gradesSubjectPreviewProposed.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
// FINAL grade
|
||||
if (model.semester1Final != null) {
|
||||
holder.gradesSubjectSemester1Final.setVisibility(View.VISIBLE);
|
||||
holder.gradesSubjectSemester1Final.setText(model.semester1Final.name);
|
||||
holder.gradesSubjectSemester1Final.getBackground().setColorFilter(new PorterDuffColorFilter(Colors.gradeNameToColor(model.semester1Final.name), PorterDuff.Mode.MULTIPLY));
|
||||
if (showSemester == 1) {
|
||||
holder.gradesSubjectPreviewFinal.setVisibility(View.VISIBLE);
|
||||
holder.gradesSubjectPreviewFinal.setText(model.semester1Final.name);
|
||||
holder.gradesSubjectPreviewFinal.getBackground().setColorFilter(new PorterDuffColorFilter(Colors.gradeNameToColor(model.semester1Final.name), PorterDuff.Mode.MULTIPLY));
|
||||
}
|
||||
}
|
||||
else {
|
||||
holder.gradesSubjectSemester1Final.setVisibility(View.GONE);
|
||||
if (showSemester == 1) {
|
||||
holder.gradesSubjectPreviewFinal.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
holder.gradesSubjectSemester1Header.setVisibility(View.GONE);
|
||||
holder.gradesSubjectSemester1Container.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
if (model.grades2.size() > 0) {
|
||||
holder.gradesSubjectSemester2Nest.setNestedScrollingEnabled(false);
|
||||
holder.gradesSubjectSemester2Content.setHasFixedSize(false);
|
||||
holder.gradesSubjectSemester2Content.setNestedScrollingEnabled(false);
|
||||
holder.gradesSubjectSemester2Content.setLayoutManager(new LinearLayoutManager(activity));
|
||||
holder.gradesSubjectSemester2Content.setAdapter(new GradesListAdapter(activity, model.grades2));
|
||||
holder.gradesSubjectSemester2Header.setVisibility(View.VISIBLE);
|
||||
if (showSemester == 2) {
|
||||
holder.gradesSubjectSemester2Container.setVisibility(View.VISIBLE);
|
||||
}
|
||||
else {
|
||||
holder.gradesSubjectSemester2Container.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
if (model.isDescriptiveSubject && !model.isNormalSubject && !model.isPointSubject && !model.isBehaviourSubject) {
|
||||
holder.gradesSubjectPreviewAverage.setVisibility(View.GONE);
|
||||
holder.gradesSubjectSemester2Average.setVisibility(View.GONE);
|
||||
}
|
||||
else {
|
||||
holder.gradesSubjectPreviewAverage.setVisibility(View.VISIBLE);
|
||||
holder.gradesSubjectSemester2Average.setVisibility(View.VISIBLE);
|
||||
// PREVIEW AVERAGE
|
||||
int formatDouble = (model.isPointSubject ? R.string.grades_average_double_percent_format : model.isBehaviourSubject ? R.string.grades_average_double_point_format : R.string.grades_average_double_format);
|
||||
int format = (model.isPointSubject ? R.string.grades_semester_average_percent_format : model.isBehaviourSubject ? R.string.grades_semester_average_point_format : R.string.grades_semester_average_format);
|
||||
if (showSemester == 2) {
|
||||
if (model.semester2Proposed != null || model.semester2Final != null) {
|
||||
holder.gradesSubjectPreviewAverage.setText(invalidAvg(model.semester2Average) ? "-" : df.format(model.semester2Average));
|
||||
holder.gradesSubjectPreviewYearAverage.setText(invalidAvg(model.yearAverage) ? "-" : df.format(model.yearAverage));
|
||||
holder.gradesSubjectPreviewYearAverage.setVisibility(View.VISIBLE);
|
||||
}
|
||||
else {
|
||||
holder.gradesSubjectPreviewAverage.setText(
|
||||
getContext().getString(
|
||||
formatDouble,
|
||||
invalidAvg(model.semester2Average) ? "-" : df.format(model.semester2Average),
|
||||
invalidAvg(model.yearAverage) ? "-" : df.format(model.yearAverage)
|
||||
)
|
||||
);
|
||||
holder.gradesSubjectPreviewYearAverage.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
// AVERAGE value
|
||||
holder.gradesSubjectSemester2Average.setText(
|
||||
getContext().getString(
|
||||
format,
|
||||
2,
|
||||
invalidAvg(model.semester2Average) ? "-" : df.format(model.semester2Average)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// PROPOSED grade
|
||||
if (model.semester2Proposed != null) {
|
||||
holder.gradesSubjectSemester2Proposed.setVisibility(View.VISIBLE);
|
||||
holder.gradesSubjectSemester2Proposed.setText(model.semester2Proposed.name);
|
||||
holder.gradesSubjectSemester2Proposed.getBackground().setColorFilter(new PorterDuffColorFilter(Colors.gradeNameToColor(model.semester2Proposed.name), PorterDuff.Mode.MULTIPLY));
|
||||
holder.gradesSubjectSemester2Proposed.setTextColor(Colors.gradeNameToColor(model.semester2Proposed.name));
|
||||
if (showSemester == 2) {
|
||||
holder.gradesSubjectPreviewProposed.setVisibility(View.VISIBLE);
|
||||
holder.gradesSubjectPreviewProposed.setText(model.semester2Proposed.name);
|
||||
holder.gradesSubjectPreviewProposed.getBackground().setColorFilter(new PorterDuffColorFilter(Colors.gradeNameToColor(model.semester2Proposed.name), PorterDuff.Mode.MULTIPLY));
|
||||
holder.gradesSubjectPreviewProposed.setTextColor(Colors.gradeNameToColor(model.semester2Proposed.name));
|
||||
}
|
||||
}
|
||||
else {
|
||||
holder.gradesSubjectSemester2Proposed.setVisibility(View.GONE);
|
||||
if (showSemester == 2) {
|
||||
holder.gradesSubjectPreviewProposed.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
// FINAL grade
|
||||
if (model.semester2Final != null) {
|
||||
holder.gradesSubjectSemester2Final.setVisibility(View.VISIBLE);
|
||||
holder.gradesSubjectSemester2Final.setText(model.semester2Final.name);
|
||||
holder.gradesSubjectSemester2Final.getBackground().setColorFilter(new PorterDuffColorFilter(Colors.gradeNameToColor(model.semester2Final.name), PorterDuff.Mode.MULTIPLY));
|
||||
if (showSemester == 2) {
|
||||
holder.gradesSubjectPreviewFinal.setVisibility(View.VISIBLE);
|
||||
holder.gradesSubjectPreviewFinal.setText(model.semester2Final.name);
|
||||
holder.gradesSubjectPreviewFinal.getBackground().setColorFilter(new PorterDuffColorFilter(Colors.gradeNameToColor(model.semester2Final.name), PorterDuff.Mode.MULTIPLY));
|
||||
}
|
||||
}
|
||||
else {
|
||||
holder.gradesSubjectSemester2Final.setVisibility(View.GONE);
|
||||
if (showSemester == 2) {
|
||||
holder.gradesSubjectPreviewFinal.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
if (model.isDescriptiveSubject && !model.isNormalSubject && !model.isPointSubject && !model.isBehaviourSubject) {
|
||||
holder.gradesSubjectYearAverage.setVisibility(View.GONE);
|
||||
}
|
||||
else {
|
||||
holder.gradesSubjectYearAverage.setVisibility(View.VISIBLE);
|
||||
// AVERAGE value
|
||||
int format = (model.isPointSubject ? R.string.grades_year_average_percent_format : model.isBehaviourSubject ? R.string.grades_year_average_point_format : R.string.grades_year_average_format);
|
||||
holder.gradesSubjectYearAverage.setText(
|
||||
getContext().getString(
|
||||
format,
|
||||
invalidAvg(model.yearAverage) ? "-" : df.format(model.yearAverage)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// PROPOSED grade
|
||||
if (model.yearProposed != null) {
|
||||
holder.gradesSubjectYearProposed.setVisibility(View.VISIBLE);
|
||||
holder.gradesSubjectYearProposed.setText(model.yearProposed.name);
|
||||
holder.gradesSubjectYearProposed.getBackground().setColorFilter(new PorterDuffColorFilter(Colors.gradeNameToColor(model.yearProposed.name), PorterDuff.Mode.MULTIPLY));
|
||||
holder.gradesSubjectYearProposed.setTextColor(Colors.gradeNameToColor(model.yearProposed.name));
|
||||
if (showSemester == 2) {
|
||||
holder.gradesSubjectPreviewYearProposed.setVisibility(View.VISIBLE);
|
||||
holder.gradesSubjectPreviewYearProposed.setText(model.yearProposed.name);
|
||||
holder.gradesSubjectPreviewYearProposed.getBackground().setColorFilter(new PorterDuffColorFilter(Colors.gradeNameToColor(model.yearProposed.name), PorterDuff.Mode.MULTIPLY));
|
||||
holder.gradesSubjectPreviewYearProposed.setTextColor(Colors.gradeNameToColor(model.yearProposed.name));
|
||||
}
|
||||
}
|
||||
else {
|
||||
holder.gradesSubjectYearProposed.setVisibility(View.GONE);
|
||||
if (showSemester == 2) {
|
||||
holder.gradesSubjectPreviewYearProposed.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
// FINAL grade
|
||||
if (model.yearFinal != null) {
|
||||
holder.gradesSubjectYearFinal.setVisibility(View.VISIBLE);
|
||||
holder.gradesSubjectYearFinal.setText(model.yearFinal.name);
|
||||
holder.gradesSubjectYearFinal.getBackground().setColorFilter(new PorterDuffColorFilter(Colors.gradeNameToColor(model.yearFinal.name), PorterDuff.Mode.MULTIPLY));
|
||||
if (showSemester == 2) {
|
||||
holder.gradesSubjectPreviewYearFinal.setVisibility(View.VISIBLE);
|
||||
holder.gradesSubjectPreviewYearFinal.setText(model.yearFinal.name);
|
||||
holder.gradesSubjectPreviewYearFinal.getBackground().setColorFilter(new PorterDuffColorFilter(Colors.gradeNameToColor(model.yearFinal.name), PorterDuff.Mode.MULTIPLY));
|
||||
}
|
||||
}
|
||||
else {
|
||||
holder.gradesSubjectYearFinal.setVisibility(View.GONE);
|
||||
if (showSemester == 2) {
|
||||
holder.gradesSubjectPreviewYearFinal.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
holder.gradesSubjectSemester2Header.setVisibility(View.GONE);
|
||||
holder.gradesSubjectSemester2Container.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
// decrease the width by average, proposed, final and semester TextViews
|
||||
holder.gradesSubjectPreviewContainer.measure(WRAP_CONTENT, MATCH_PARENT);
|
||||
//Log.d(TAG, "gradesSubjectPreviewContainer "+holder.gradesSubjectPreviewContainer.getMeasuredWidth());
|
||||
|
||||
/*holder.gradesSubjectPreviewAverage.measure(WRAP_CONTENT, WRAP_CONTENT);
|
||||
maxWidthPx -= holder.gradesSubjectPreviewAverage.getMeasuredWidth();
|
||||
maxWidthPx -= 2*_5dp;
|
||||
if (holder.gradesSubjectPreviewProposed.getVisibility() == View.VISIBLE) {
|
||||
holder.gradesSubjectPreviewProposed.measure(WRAP_CONTENT, WRAP_CONTENT);
|
||||
maxWidthPx -= holder.gradesSubjectPreviewProposed.getMeasuredWidth();
|
||||
maxWidthPx -= _5dp;
|
||||
}
|
||||
if (holder.gradesSubjectPreviewFinal.getVisibility() == View.VISIBLE) {
|
||||
holder.gradesSubjectPreviewFinal.measure(WRAP_CONTENT, WRAP_CONTENT);
|
||||
maxWidthPx -= holder.gradesSubjectPreviewFinal.getMeasuredWidth();
|
||||
maxWidthPx -= _5dp;
|
||||
}*/
|
||||
maxWidthPx -= holder.gradesSubjectPreviewContainer.getMeasuredWidth();
|
||||
maxWidthPx -= _5dp;
|
||||
|
||||
for (GradeFull grade: gradeList) {
|
||||
if (grade.semester != showSemester)
|
||||
continue;
|
||||
|
||||
int gradeColor;
|
||||
if (model.colorMode == COLOR_MODE_DEFAULT) {
|
||||
gradeColor = grade.color;
|
||||
} else {
|
||||
gradeColor = Colors.gradeToColor(grade);
|
||||
}
|
||||
|
||||
TextView gradeName = new TextView(activity);
|
||||
gradeName.setText(grade.name);
|
||||
gradeName.setTextColor(ColorUtils.calculateLuminance(gradeColor) > 0.25 ? 0xff000000 : 0xffffffff);
|
||||
gradeName.setPadding(_5dp, 0, _5dp, 0);
|
||||
gradeName.setBackgroundResource(R.drawable.bg_rounded_4dp);
|
||||
gradeName.getBackground().setColorFilter(new PorterDuffColorFilter(gradeColor, PorterDuff.Mode.MULTIPLY));
|
||||
gradeName.setTypeface(null, Typeface.BOLD);
|
||||
|
||||
gradeName.measure(WRAP_CONTENT, WRAP_CONTENT);
|
||||
totalWidthPx += gradeName.getMeasuredWidth() + _5dp;
|
||||
//Log.d(TAG, "totalWidthPx " + totalWidthPx);
|
||||
if (totalWidthPx >= maxWidthPx) {
|
||||
if (ellipsized)
|
||||
continue;
|
||||
ellipsized = true;
|
||||
TextView ellipsisText = new TextView(activity);
|
||||
ellipsisText.setText(R.string.ellipsis);
|
||||
ellipsisText.setTextAppearance(activity, R.style.NavView_TextView);
|
||||
ellipsisText.setTypeface(null, Typeface.BOLD);
|
||||
ellipsisText.setPadding(0, 0, 0, 0);
|
||||
holder.gradesSubjectPreviewContent.addView(ellipsisText, layoutParams);
|
||||
}
|
||||
else {
|
||||
holder.gradesSubjectPreviewContent.addView(gradeName, layoutParams);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (findViews) {
|
||||
//Log.d("GradesSubjectAdapter", "runOnUiThread");
|
||||
//this.viewHolder.gradesSubjectContent.setTag(View.VISIBLE);
|
||||
//this.viewHolder.gradesSubjectPreviewContainer.setTag(View.VISIBLE);
|
||||
activity.runOnUiThread(() -> {
|
||||
|
||||
holder.gradesSubjectRoot.setOnClickListener(v -> {
|
||||
if (holder.gradesSubjectContent.getVisibility() == View.GONE) {
|
||||
expandSubject(holder, model);
|
||||
}
|
||||
else {
|
||||
collapseSubject(holder, model);
|
||||
}
|
||||
});
|
||||
|
||||
holder.gradesSubjectSemester1Header.setOnClickListener(v -> {
|
||||
if (holder.gradesSubjectSemester1Container.getVisibility() == View.GONE) {
|
||||
if (gradesSetAsRead(holder, model, 1)) updateBadges(getContext(), model);
|
||||
|
||||
Anim.expand(holder.gradesSubjectSemester1Container, 500, null);
|
||||
if (holder.gradesSubjectSemester2Container.getVisibility() != View.GONE) {
|
||||
Anim.collapse(holder.gradesSubjectSemester2Container, 500, null);
|
||||
}
|
||||
}
|
||||
else {
|
||||
Anim.collapse(holder.gradesSubjectSemester1Container, 500, null);
|
||||
}
|
||||
});
|
||||
holder.gradesSubjectSemester2Header.setOnClickListener(v -> {
|
||||
if (holder.gradesSubjectSemester2Container.getVisibility() == View.GONE) {
|
||||
if (gradesSetAsRead(holder, model, 2)) updateBadges(getContext(), model);
|
||||
|
||||
Anim.expand(holder.gradesSubjectSemester2Container, 500, null);
|
||||
if (holder.gradesSubjectSemester1Container.getVisibility() != View.GONE) {
|
||||
Anim.collapse(holder.gradesSubjectSemester1Container, 500, null);
|
||||
}
|
||||
}
|
||||
else {
|
||||
Anim.collapse(holder.gradesSubjectSemester2Container, 500, null);
|
||||
}
|
||||
});
|
||||
|
||||
// hide the grade simulator when there are point, behaviour or descriptive grades
|
||||
if (model.isPointSubject || model.isBehaviourSubject || (model.isDescriptiveSubject && !model.isNormalSubject)) {
|
||||
holder.gradesSubjectSemester1EditButton.setVisibility(View.GONE);
|
||||
holder.gradesSubjectSemester2EditButton.setVisibility(View.GONE);
|
||||
}
|
||||
else {
|
||||
holder.gradesSubjectSemester1EditButton.setVisibility(View.VISIBLE);
|
||||
holder.gradesSubjectSemester1EditButton.setOnClickListener(v -> {
|
||||
Bundle arguments = new Bundle();
|
||||
|
||||
if (model.subject != null) {
|
||||
arguments.putLong("subjectId", model.subject.id);
|
||||
}
|
||||
arguments.putInt("semester", 1);
|
||||
//d(TAG, "Model is " + model);
|
||||
switch (model.yearAverageMode) {
|
||||
case YEAR_1_SEM_2_AVG:
|
||||
case YEAR_1_SEM_2_SEM:
|
||||
arguments.putInt("averageMode", -1);
|
||||
break;
|
||||
default:
|
||||
arguments.putInt("averageMode", model.semester2Final == null && model.yearAverageMode == YEAR_1_AVG_2_SEM ? -1 : model.yearAverageMode);
|
||||
arguments.putFloat("yearAverageBefore", model.yearAverage);
|
||||
arguments.putFloat("gradeSumOtherSemester", model.gradeSumSemester2);
|
||||
arguments.putFloat("gradeCountOtherSemester", model.gradeCountSemester2);
|
||||
arguments.putFloat("averageOtherSemester", model.semester2Average);
|
||||
arguments.putFloat("finalOtherSemester", model.semester2Final == null ? -1 : model.semester2Final.value);
|
||||
break;
|
||||
}
|
||||
|
||||
activity.loadTarget(TARGET_GRADES_EDITOR, arguments);
|
||||
});
|
||||
holder.gradesSubjectSemester2EditButton.setVisibility(View.VISIBLE);
|
||||
holder.gradesSubjectSemester2EditButton.setOnClickListener(v -> {
|
||||
Bundle arguments = new Bundle();
|
||||
|
||||
if (model.subject != null) {
|
||||
arguments.putLong("subjectId", model.subject.id);
|
||||
}
|
||||
arguments.putInt("semester", 2);
|
||||
//d(TAG, "Model is " + model);
|
||||
switch (model.yearAverageMode) {
|
||||
case YEAR_1_AVG_2_SEM:
|
||||
case YEAR_1_SEM_2_SEM:
|
||||
arguments.putInt("averageMode", -1);
|
||||
break;
|
||||
default:
|
||||
arguments.putInt("averageMode", model.semester1Final == null && model.yearAverageMode == YEAR_1_SEM_2_AVG ? -1 : model.yearAverageMode);
|
||||
arguments.putFloat("yearAverageBefore", model.yearAverage);
|
||||
arguments.putFloat("gradeSumOtherSemester", model.gradeSumSemester1);
|
||||
arguments.putFloat("gradeCountOtherSemester", model.gradeCountSemester1);
|
||||
arguments.putFloat("averageOtherSemester", model.semester1Average);
|
||||
arguments.putFloat("finalOtherSemester", model.semester1Final == null ? -1 : model.semester1Final.value);
|
||||
break;
|
||||
}
|
||||
|
||||
activity.loadTarget(TARGET_GRADES_EDITOR, arguments);
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
if (model != null && model.subject != null) {
|
||||
holder.lastSubject = model.subject.id;
|
||||
}
|
||||
super.onPostExecute(aVoid);
|
||||
}
|
||||
}
|
||||
|
||||
//getting the context and product list with constructor
|
||||
public GradesSubjectAdapter(List<ItemGradesSubjectModel> data, MainActivity context) {
|
||||
super(context, R.layout.row_grades_subject_item, data);
|
||||
this.activity = context;
|
||||
this.subjectList = data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
int position = (Integer) v.getTag();
|
||||
Object object = getItem(position);
|
||||
ItemGradesSubjectModel dataModel = (ItemGradesSubjectModel)object;
|
||||
|
||||
}
|
||||
|
||||
private void findViews(ViewHolder holder, View root) {
|
||||
//holder.gradesSubjectRoot = root.findViewById(R.id.gradesSubjectRoot);
|
||||
holder.gradesSubjectTitle = root.findViewById(R.id.gradesSubjectTitle);
|
||||
holder.gradesSubjectExpandIndicator = root.findViewById(R.id.gradesSubjectExpandIndicator);
|
||||
|
||||
holder.gradesSubjectPreviewContainer = root.findViewById(R.id.gradesSubjectPreviewContainer);
|
||||
holder.gradesSubjectPreviewSemester = root.findViewById(R.id.gradesSubjectPreviewSemester);
|
||||
holder.gradesSubjectPreviewContent = root.findViewById(R.id.gradesSubjectPreviewContent);
|
||||
holder.gradesSubjectPreviewAverage = root.findViewById(R.id.gradesSubjectPreviewAverage);
|
||||
holder.gradesSubjectPreviewProposed = root.findViewById(R.id.gradesSubjectPreviewProposed);
|
||||
holder.gradesSubjectPreviewFinal = root.findViewById(R.id.gradesSubjectPreviewFinal);
|
||||
holder.gradesSubjectPreviewYearAverage = root.findViewById(R.id.gradesSubjectPreviewYearAverage);
|
||||
holder.gradesSubjectPreviewYearProposed = root.findViewById(R.id.gradesSubjectPreviewYearProposed);
|
||||
holder.gradesSubjectPreviewYearFinal = root.findViewById(R.id.gradesSubjectPreviewYearFinal);
|
||||
|
||||
holder.gradesSubjectContent = root.findViewById(R.id.gradesSubjectContent);
|
||||
|
||||
holder.gradesSubjectSemester1Header = root.findViewById(R.id.gradesSubjectSemester1Header);
|
||||
holder.gradesSubjectSemester1Title = root.findViewById(R.id.gradesSubjectSemester1Title);
|
||||
holder.gradesSubjectSemester1ExpandIndicator = root.findViewById(R.id.gradesSubjectSemester1ExpandIndicator);
|
||||
holder.gradesSubjectSemester1Average = root.findViewById(R.id.gradesSubjectSemester1Average);
|
||||
holder.gradesSubjectSemester1Proposed = root.findViewById(R.id.gradesSubjectSemester1Proposed);
|
||||
holder.gradesSubjectSemester1Final = root.findViewById(R.id.gradesSubjectSemester1Final);
|
||||
holder.gradesSubjectSemester1EditButton = root.findViewById(R.id.gradesSubjectSemester1EditButton);
|
||||
holder.gradesSubjectSemester1Container = root.findViewById(R.id.gradesSubjectSemester1Container);
|
||||
holder.gradesSubjectSemester1Nest = root.findViewById(R.id.gradesSubjectSemester1Nest);
|
||||
holder.gradesSubjectSemester1Content = root.findViewById(R.id.gradesSubjectSemester1Content);
|
||||
|
||||
holder.gradesSubjectSemester2Header = root.findViewById(R.id.gradesSubjectSemester2Header);
|
||||
holder.gradesSubjectSemester2Title = root.findViewById(R.id.gradesSubjectSemester2Title);
|
||||
holder.gradesSubjectSemester2ExpandIndicator = root.findViewById(R.id.gradesSubjectSemester2ExpandIndicator);
|
||||
holder.gradesSubjectSemester2Average = root.findViewById(R.id.gradesSubjectSemester2Average);
|
||||
holder.gradesSubjectSemester2Proposed = root.findViewById(R.id.gradesSubjectSemester2Proposed);
|
||||
holder.gradesSubjectSemester2Final = root.findViewById(R.id.gradesSubjectSemester2Final);
|
||||
holder.gradesSubjectSemester2EditButton = root.findViewById(R.id.gradesSubjectSemester2EditButton);
|
||||
holder.gradesSubjectSemester2Container = root.findViewById(R.id.gradesSubjectSemester2Container);
|
||||
holder.gradesSubjectSemester2Nest = root.findViewById(R.id.gradesSubjectSemester2Nest);
|
||||
holder.gradesSubjectSemester2Content = root.findViewById(R.id.gradesSubjectSemester2Content);
|
||||
|
||||
holder.gradesSubjectYearAverage = root.findViewById(R.id.gradesSubjectYearAverage);
|
||||
holder.gradesSubjectYearProposed = root.findViewById(R.id.gradesSubjectYearProposed);
|
||||
holder.gradesSubjectYearFinal = root.findViewById(R.id.gradesSubjectYearFinal);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public View getView(int position, View convertView, @NonNull ViewGroup parent) {
|
||||
if (position >= subjectList.size()) {
|
||||
return convertView;
|
||||
}
|
||||
ItemGradesSubjectModel model = subjectList.get(position);
|
||||
if (model == null) {
|
||||
//Toast.makeText(activity, "return convertView;", Toast.LENGTH_SHORT).show();
|
||||
return convertView;
|
||||
}
|
||||
ViewHolder holder;
|
||||
if (convertView == null) {
|
||||
try {
|
||||
convertView = LayoutInflater.from(activity).inflate(R.layout.row_grades_subject_item, parent, false);
|
||||
holder = new ViewHolder();
|
||||
holder.gradesSubjectRoot = convertView.findViewById(R.id.gradesSubjectRoot);
|
||||
convertView.setTag(holder);
|
||||
new BuildGradeViews(model, holder, parent, position, true).execute();
|
||||
return convertView;
|
||||
} catch (Exception e) {
|
||||
return new View(getContext());
|
||||
}
|
||||
}
|
||||
holder = (ViewHolder) convertView.getTag();
|
||||
Subject subject = model.subject;
|
||||
holder.gradesSubjectTitle.setText(subject != null ? subject.longName : "");
|
||||
/*if (model.getNotSeen() > 0) {
|
||||
viewHolder.notseen.setVisibility(0);
|
||||
viewHolder.notseen.setText(model.getNotSeen() + "");
|
||||
} else {
|
||||
viewHolder.notseen.setVisibility(8);
|
||||
}*/
|
||||
new BuildGradeViews(model, holder, parent, position, false).execute();
|
||||
return convertView;
|
||||
}
|
||||
|
||||
public int getViewTypeCount() {
|
||||
return getCount();
|
||||
}
|
||||
|
||||
public int getItemViewType(int position) {
|
||||
return position;
|
||||
}
|
||||
|
||||
class ViewHolder {
|
||||
long lastSubject;
|
||||
|
||||
TextView gradesSubjectTitle;
|
||||
ConstraintLayout gradesSubjectRoot;
|
||||
IconicsImageView gradesSubjectExpandIndicator;
|
||||
|
||||
LinearLayout gradesSubjectPreviewContainer;
|
||||
TextView gradesSubjectPreviewSemester;
|
||||
LinearLayout gradesSubjectPreviewContent;
|
||||
TextView gradesSubjectPreviewAverage;
|
||||
TextView gradesSubjectPreviewProposed;
|
||||
TextView gradesSubjectPreviewFinal;
|
||||
TextView gradesSubjectPreviewYearAverage;
|
||||
TextView gradesSubjectPreviewYearProposed;
|
||||
TextView gradesSubjectPreviewYearFinal;
|
||||
|
||||
LinearLayout gradesSubjectContent;
|
||||
|
||||
LinearLayout gradesSubjectSemester1Header;
|
||||
TextView gradesSubjectSemester1Title;
|
||||
IconicsImageView gradesSubjectSemester1ExpandIndicator;
|
||||
TextView gradesSubjectSemester1Average;
|
||||
TextView gradesSubjectSemester1Proposed;
|
||||
TextView gradesSubjectSemester1Final;
|
||||
IconicsImageView gradesSubjectSemester1EditButton;
|
||||
LinearLayout gradesSubjectSemester1Container;
|
||||
NestedScrollView gradesSubjectSemester1Nest;
|
||||
RecyclerView gradesSubjectSemester1Content;
|
||||
|
||||
LinearLayout gradesSubjectSemester2Header;
|
||||
TextView gradesSubjectSemester2Title;
|
||||
IconicsImageView gradesSubjectSemester2ExpandIndicator;
|
||||
TextView gradesSubjectSemester2Average;
|
||||
TextView gradesSubjectSemester2Proposed;
|
||||
TextView gradesSubjectSemester2Final;
|
||||
IconicsImageView gradesSubjectSemester2EditButton;
|
||||
LinearLayout gradesSubjectSemester2Container;
|
||||
NestedScrollView gradesSubjectSemester2Nest;
|
||||
RecyclerView gradesSubjectSemester2Content;
|
||||
|
||||
TextView gradesSubjectYearAverage;
|
||||
TextView gradesSubjectYearProposed;
|
||||
TextView gradesSubjectYearFinal;
|
||||
}
|
||||
}
|
@ -14,13 +14,13 @@ import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import com.afollestad.materialdialogs.MaterialDialog
|
||||
import pl.szczodrzynski.edziennik.*
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Profile.Companion.YEAR_1_AVG_2_AVG
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Profile.Companion.YEAR_1_AVG_2_SEM
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Profile.Companion.YEAR_1_SEM_2_AVG
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Profile.Companion.YEAR_ALL_GRADES
|
||||
import pl.szczodrzynski.edziennik.databinding.FragmentGradesEditorBinding
|
||||
import pl.szczodrzynski.edziennik.utils.Colors
|
||||
import pl.szczodrzynski.edziennik.utils.Themes
|
||||
import pl.szczodrzynski.edziennik.utils.managers.GradesManager.Companion.YEAR_1_AVG_2_AVG
|
||||
import pl.szczodrzynski.edziennik.utils.managers.GradesManager.Companion.YEAR_1_AVG_2_SEM
|
||||
import pl.szczodrzynski.edziennik.utils.managers.GradesManager.Companion.YEAR_1_SEM_2_AVG
|
||||
import pl.szczodrzynski.edziennik.utils.managers.GradesManager.Companion.YEAR_ALL_GRADES
|
||||
import java.text.DecimalFormat
|
||||
import java.util.*
|
||||
import kotlin.math.floor
|
||||
|
@ -0,0 +1,12 @@
|
||||
/*
|
||||
* Copyright (c) Kuba Szczodrzyński 2020-2-29.
|
||||
*/
|
||||
|
||||
package pl.szczodrzynski.edziennik.ui.modules.grades.models
|
||||
|
||||
import pl.szczodrzynski.edziennik.ui.modules.grades.GradesAdapter.Companion.STATE_CLOSED
|
||||
|
||||
abstract class ExpandableItemModel<T>(val items: MutableList<T>) {
|
||||
open var level: Int = 3
|
||||
var state: Int = STATE_CLOSED
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright (c) Kuba Szczodrzyński 2020-3-1.
|
||||
*/
|
||||
|
||||
package pl.szczodrzynski.edziennik.ui.modules.grades.models
|
||||
|
||||
class GradesAverages {
|
||||
var normalSum = 0f
|
||||
var normalCount = 0
|
||||
var normalWeightedSum = 0f
|
||||
var normalWeightedCount = 0f
|
||||
|
||||
var pointSum = 0f
|
||||
|
||||
var pointAvgSum = 0f
|
||||
var pointAvgMax = 0f
|
||||
|
||||
var normalAvg: Float? = null
|
||||
var pointAvgPercent: Float? = null
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
/*
|
||||
* Copyright (c) Kuba Szczodrzyński 2020-3-1.
|
||||
*/
|
||||
|
||||
package pl.szczodrzynski.edziennik.ui.modules.grades.models
|
||||
|
||||
class GradesEmpty
|
@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright (c) Kuba Szczodrzyński 2020-2-29.
|
||||
*/
|
||||
|
||||
package pl.szczodrzynski.edziennik.ui.modules.grades.models
|
||||
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade
|
||||
import pl.szczodrzynski.edziennik.data.db.full.GradeFull
|
||||
|
||||
data class GradesSemester(
|
||||
val subjectId: Long,
|
||||
val number: Int,
|
||||
val grades: MutableList<Grade> = mutableListOf()
|
||||
) : ExpandableItemModel<Grade>(grades) {
|
||||
override var level = 2
|
||||
|
||||
val averages = GradesAverages()
|
||||
var proposedGrade: GradeFull? = null
|
||||
var finalGrade: GradeFull? = null
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright (c) Kuba Szczodrzyński 2020-3-3.
|
||||
*/
|
||||
|
||||
package pl.szczodrzynski.edziennik.ui.modules.grades.models
|
||||
|
||||
class GradesStats {
|
||||
var normalSem1 = 0f
|
||||
var normalSem1Proposed = 0f
|
||||
var normalSem1Final = 0f
|
||||
var normalSem2 = 0f
|
||||
var normalSem2Proposed = 0f
|
||||
var normalSem2Final = 0f
|
||||
var normalYearly = 0f
|
||||
var normalYearlyProposed = 0f
|
||||
var normalYearlyFinal = 0f
|
||||
|
||||
var sem1NotAllFinal = false
|
||||
var sem2NotAllFinal = false
|
||||
var yearlyNotAllFinal = false
|
||||
|
||||
var pointSem1 = 0f
|
||||
var pointSem2 = 0f
|
||||
var pointYearly = 0f
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Copyright (c) Kuba Szczodrzyński 2020-2-29.
|
||||
*/
|
||||
|
||||
package pl.szczodrzynski.edziennik.ui.modules.grades.models
|
||||
|
||||
import pl.szczodrzynski.edziennik.data.db.full.GradeFull
|
||||
|
||||
data class GradesSubject(
|
||||
val subjectId: Long,
|
||||
val subjectName: String,
|
||||
val semesters: MutableList<GradesSemester> = mutableListOf()
|
||||
) : ExpandableItemModel<GradesSemester>(semesters) {
|
||||
override var level = 1
|
||||
|
||||
var lastAddedDate = 0L
|
||||
var semester: Int = 1
|
||||
|
||||
val averages = GradesAverages()
|
||||
var proposedGrade: GradeFull? = null
|
||||
var finalGrade: GradeFull? = null
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
/*
|
||||
* Copyright (c) Kuba Szczodrzyński 2020-2-29.
|
||||
*/
|
||||
|
||||
package pl.szczodrzynski.edziennik.ui.modules.grades.viewholder
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import pl.szczodrzynski.edziennik.App
|
||||
|
||||
interface BindableViewHolder<T> {
|
||||
fun onBind(activity: AppCompatActivity, app: App, item: T, position: Int)
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright (c) Kuba Szczodrzyński 2020-3-1.
|
||||
*/
|
||||
|
||||
package pl.szczodrzynski.edziennik.ui.modules.grades.viewholder
|
||||
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import pl.szczodrzynski.edziennik.App
|
||||
import pl.szczodrzynski.edziennik.databinding.GradesItemEmptyBinding
|
||||
import pl.szczodrzynski.edziennik.ui.modules.grades.models.GradesEmpty
|
||||
|
||||
class EmptyViewHolder(
|
||||
inflater: LayoutInflater,
|
||||
parent: ViewGroup,
|
||||
val b: GradesItemEmptyBinding = GradesItemEmptyBinding.inflate(inflater, parent, false)
|
||||
) : RecyclerView.ViewHolder(b.root), BindableViewHolder<GradesEmpty> {
|
||||
companion object {
|
||||
private const val TAG = "EmptyViewHolder"
|
||||
}
|
||||
|
||||
override fun onBind(activity: AppCompatActivity, app: App, item: GradesEmpty, position: Int) {
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (c) Kuba Szczodrzyński 2020-2-29.
|
||||
*/
|
||||
|
||||
package pl.szczodrzynski.edziennik.ui.modules.grades.viewholder
|
||||
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import pl.szczodrzynski.edziennik.App
|
||||
import pl.szczodrzynski.edziennik.R
|
||||
import pl.szczodrzynski.edziennik.data.db.full.GradeFull
|
||||
import pl.szczodrzynski.edziennik.databinding.GradesItemGradeBinding
|
||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||
|
||||
class GradeViewHolder(
|
||||
inflater: LayoutInflater,
|
||||
parent: ViewGroup,
|
||||
val b: GradesItemGradeBinding = GradesItemGradeBinding.inflate(inflater, parent, false)
|
||||
) : RecyclerView.ViewHolder(b.root), BindableViewHolder<GradeFull> {
|
||||
companion object {
|
||||
private const val TAG = "GradeViewHolder"
|
||||
}
|
||||
|
||||
@Suppress("PARAMETER_NAME_CHANGED_ON_OVERRIDE")
|
||||
override fun onBind(activity: AppCompatActivity, app: App, grade: GradeFull, position: Int) {
|
||||
val manager = app.gradesManager
|
||||
|
||||
b.gradeName.setGrade(grade, manager, bigView = true)
|
||||
|
||||
if (grade.description.isNullOrBlank()) {
|
||||
b.gradeDescription.text = grade.category
|
||||
b.gradeCategory.text =
|
||||
if (grade.isImprovement)
|
||||
app.getString(R.string.grades_improvement_category_format, "")
|
||||
else
|
||||
""
|
||||
} else {
|
||||
b.gradeDescription.text = grade.description
|
||||
b.gradeCategory.text =
|
||||
if (grade.isImprovement)
|
||||
app.getString(R.string.grades_improvement_category_format, grade.category)
|
||||
else
|
||||
grade.category
|
||||
}
|
||||
|
||||
b.gradeWeight.text = manager.getWeightString(activity, grade, showClassAverage = true)
|
||||
|
||||
b.gradeTeacherName.text = grade.teacherFullName
|
||||
b.gradeAddedDate.text = Date.fromMillis(grade.addedDate).let {
|
||||
it.getRelativeString(app, 5) ?: it.formattedStringShort
|
||||
}
|
||||
|
||||
/*if (!grade.seen) {
|
||||
b.gradeDescription.setBackground(mContext.getResources().getDrawable(R.drawable.bg_rounded_4dp))
|
||||
b.gradeDescription.getBackground()
|
||||
.setColorFilter(PorterDuffColorFilter(0x692196f3, PorterDuff.Mode.MULTIPLY))
|
||||
} else {
|
||||
b.gradeDescription.setBackground(null)
|
||||
}*/
|
||||
}
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (c) Kuba Szczodrzyński 2020-2-29.
|
||||
*/
|
||||
|
||||
package pl.szczodrzynski.edziennik.ui.modules.grades.viewholder
|
||||
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import pl.szczodrzynski.edziennik.App
|
||||
import pl.szczodrzynski.edziennik.R
|
||||
import pl.szczodrzynski.edziennik.databinding.GradesItemSemesterBinding
|
||||
import pl.szczodrzynski.edziennik.setText
|
||||
import pl.szczodrzynski.edziennik.ui.modules.grades.GradesAdapter
|
||||
import pl.szczodrzynski.edziennik.ui.modules.grades.models.GradesSemester
|
||||
|
||||
class SemesterViewHolder(
|
||||
inflater: LayoutInflater,
|
||||
parent: ViewGroup,
|
||||
val b: GradesItemSemesterBinding = GradesItemSemesterBinding.inflate(inflater, parent, false)
|
||||
) : RecyclerView.ViewHolder(b.root), BindableViewHolder<GradesSemester> {
|
||||
companion object {
|
||||
private const val TAG = "SemesterViewHolder"
|
||||
}
|
||||
|
||||
override fun onBind(activity: AppCompatActivity, app: App, item: GradesSemester, position: Int) {
|
||||
val manager = app.gradesManager
|
||||
b.semesterName.setText(R.string.grades_semester_format, item.number)
|
||||
b.dropdownIcon.rotation = when (item.state) {
|
||||
GradesAdapter.STATE_CLOSED -> 0f
|
||||
else -> 180f
|
||||
}
|
||||
|
||||
b.average.text = manager.getAverageString(app, item.averages)
|
||||
b.proposedGrade.setGrade(item.proposedGrade, manager)
|
||||
b.finalGrade.setGrade(item.finalGrade, manager)
|
||||
}
|
||||
}
|
@ -0,0 +1,142 @@
|
||||
/*
|
||||
* Copyright (c) Kuba Szczodrzyński 2020-3-3.
|
||||
*/
|
||||
|
||||
package pl.szczodrzynski.edziennik.ui.modules.grades.viewholder
|
||||
|
||||
import android.content.Context
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import pl.szczodrzynski.edziennik.App
|
||||
import pl.szczodrzynski.edziennik.R
|
||||
import pl.szczodrzynski.edziennik.databinding.GradesItemStatsBinding
|
||||
import pl.szczodrzynski.edziennik.onClick
|
||||
import pl.szczodrzynski.edziennik.ui.dialogs.settings.GradesConfigDialog
|
||||
import pl.szczodrzynski.edziennik.ui.modules.grades.models.GradesStats
|
||||
import java.text.DecimalFormat
|
||||
|
||||
class StatsViewHolder(
|
||||
inflater: LayoutInflater,
|
||||
parent: ViewGroup,
|
||||
val b: GradesItemStatsBinding = GradesItemStatsBinding.inflate(inflater, parent, false)
|
||||
) : RecyclerView.ViewHolder(b.root), BindableViewHolder<GradesStats> {
|
||||
companion object {
|
||||
private const val TAG = "StatsViewHolder"
|
||||
}
|
||||
|
||||
override fun onBind(activity: AppCompatActivity, app: App, item: GradesStats, position: Int) {
|
||||
val manager = app.gradesManager
|
||||
val showAverages = mutableListOf<Int>()
|
||||
val showPoint = mutableListOf<Int>()
|
||||
|
||||
getSemesterString(app, item.normalSem1, item.normalSem1Proposed, item.normalSem1Final, item.sem1NotAllFinal).let { (average, notice) ->
|
||||
b.normalSemester1Layout.isVisible = average != null
|
||||
b.normalSemester1Notice.isVisible = notice != null
|
||||
b.normalSemester1.text = average
|
||||
b.normalSemester1Notice.text = notice
|
||||
if (average != null)
|
||||
showAverages += 1
|
||||
}
|
||||
getSemesterString(app, item.normalSem2, item.normalSem2Proposed, item.normalSem2Final, item.sem2NotAllFinal).let { (average, notice) ->
|
||||
b.normalSemester2Layout.isVisible = average != null
|
||||
b.normalSemester2Notice.isVisible = notice != null
|
||||
b.normalSemester2.text = average
|
||||
b.normalSemester2Notice.text = notice
|
||||
if (average != null)
|
||||
showAverages += 2
|
||||
}
|
||||
getSemesterString(app, item.normalYearly, item.normalYearlyProposed, item.normalYearlyFinal, item.yearlyNotAllFinal).let { (average, notice) ->
|
||||
b.normalYearlyLayout.isVisible = average != null
|
||||
b.normalYearlyNotice.isVisible = notice != null
|
||||
b.normalYearly.text = average
|
||||
b.normalYearlyNotice.text = notice
|
||||
if (average != null)
|
||||
showAverages += 3
|
||||
}
|
||||
|
||||
b.normalTitle.isVisible = showAverages.size > 0
|
||||
b.normalLayout.isVisible = showAverages.size > 0
|
||||
b.normalDivider.isVisible = showAverages.size > 0
|
||||
b.helpButton.isVisible = showAverages.size > 0
|
||||
b.normalDiv1.isVisible = showAverages.contains(1) && showAverages.contains(2) || showAverages.contains(1) && showAverages.contains(3)
|
||||
b.normalDiv2.isVisible = showAverages.contains(2) && showAverages.contains(3)
|
||||
|
||||
getSemesterString(app, 0f, 0f, item.pointSem1, false).let { (average, _) ->
|
||||
b.pointSemester1Layout.isVisible = average != null
|
||||
b.pointSemester1.text = average
|
||||
if (average != null)
|
||||
showPoint += 1
|
||||
}
|
||||
getSemesterString(app, 0f, 0f, item.pointSem2, false).let { (average, _) ->
|
||||
b.pointSemester2Layout.isVisible = average != null
|
||||
b.pointSemester2.text = average
|
||||
if (average != null)
|
||||
showPoint += 2
|
||||
}
|
||||
getSemesterString(app, 0f, 0f, item.pointYearly, false).let { (average, _) ->
|
||||
b.pointYearlyLayout.isVisible = average != null
|
||||
b.pointYearly.text = average
|
||||
if (average != null)
|
||||
showPoint += 3
|
||||
}
|
||||
|
||||
b.pointTitle.isVisible = showPoint.size > 0
|
||||
b.pointLayout.isVisible = showPoint.size > 0
|
||||
b.pointDivider.isVisible = showPoint.size > 0
|
||||
b.pointDiv1.isVisible = showPoint.contains(1) && showPoint.contains(2)
|
||||
b.pointDiv2.isVisible = showPoint.contains(2) && showPoint.contains(3)
|
||||
|
||||
b.noData.isVisible = showAverages.isEmpty() && showPoint.isEmpty()
|
||||
b.disclaimer.isVisible = !b.noData.isVisible
|
||||
|
||||
b.helpButton.onClick {
|
||||
MaterialAlertDialogBuilder(activity)
|
||||
.setTitle(R.string.grades_stats_help_title)
|
||||
.setMessage(R.string.grades_stats_help_text)
|
||||
.setPositiveButton(R.string.ok, null)
|
||||
.show()
|
||||
}
|
||||
|
||||
b.customValueDivider.isVisible = manager.plusValue != null || manager.minusValue != null
|
||||
b.customValueLayout.isVisible = b.customValueDivider.isVisible
|
||||
b.customValueButton.onClick {
|
||||
GradesConfigDialog(activity, reloadOnDismiss = true)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getSemesterString(context: Context, expected: Float, proposed: Float, final: Float, notAllFinal: Boolean) : Pair<String?, String?> {
|
||||
val format = DecimalFormat("#.##")
|
||||
|
||||
val average = when {
|
||||
final != 0f -> final
|
||||
proposed != 0f -> proposed
|
||||
expected != 0f -> expected
|
||||
else -> null
|
||||
}?.let {
|
||||
format.format(it)
|
||||
}
|
||||
|
||||
val notice = when {
|
||||
final != 0f -> when {
|
||||
notAllFinal -> if (expected != 0f)
|
||||
context.getString(R.string.grades_stats_from_final, format.format(expected))
|
||||
else
|
||||
context.getString(R.string.grades_stats_from_final_no_expected)
|
||||
proposed != 0f -> context.getString(R.string.grades_stats_proposed_avg, format.format(proposed))
|
||||
else -> null
|
||||
}
|
||||
proposed != 0f -> if (expected != 0f)
|
||||
context.getString(R.string.grades_stats_from_proposed, format.format(expected))
|
||||
else
|
||||
context.getString(R.string.grades_stats_from_proposed_no_expected)
|
||||
expected != 0f -> context.getString(R.string.grades_stats_expected)
|
||||
else -> null
|
||||
}
|
||||
|
||||
return average to notice
|
||||
}
|
||||
}
|
@ -0,0 +1,134 @@
|
||||
/*
|
||||
* Copyright (c) Kuba Szczodrzyński 2020-2-29.
|
||||
*/
|
||||
|
||||
package pl.szczodrzynski.edziennik.ui.modules.grades.viewholder
|
||||
|
||||
import android.text.TextUtils
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.TextView
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.appcompat.view.ContextThemeWrapper
|
||||
import androidx.core.view.get
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import pl.szczodrzynski.edziennik.App
|
||||
import pl.szczodrzynski.edziennik.R
|
||||
import pl.szczodrzynski.edziennik.databinding.GradesItemSubjectBinding
|
||||
import pl.szczodrzynski.edziennik.dp
|
||||
import pl.szczodrzynski.edziennik.setText
|
||||
import pl.szczodrzynski.edziennik.ui.modules.grades.GradeView
|
||||
import pl.szczodrzynski.edziennik.ui.modules.grades.GradesAdapter.Companion.STATE_CLOSED
|
||||
import pl.szczodrzynski.edziennik.ui.modules.grades.models.GradesSubject
|
||||
import pl.szczodrzynski.edziennik.utils.Themes
|
||||
|
||||
class SubjectViewHolder(
|
||||
inflater: LayoutInflater,
|
||||
parent: ViewGroup,
|
||||
val b: GradesItemSubjectBinding = GradesItemSubjectBinding.inflate(inflater, parent, false)
|
||||
) : RecyclerView.ViewHolder(b.root), BindableViewHolder<GradesSubject> {
|
||||
companion object {
|
||||
private const val TAG = "SubjectViewHolder"
|
||||
}
|
||||
|
||||
override fun onBind(activity: AppCompatActivity, app: App, item: GradesSubject, position: Int) {
|
||||
val manager = app.gradesManager
|
||||
val contextWrapper = ContextThemeWrapper(activity, Themes.themeInt)
|
||||
|
||||
b.subjectName.text = item.subjectName
|
||||
b.dropdownIcon.rotation = when (item.state) {
|
||||
STATE_CLOSED -> 0f
|
||||
else -> 180f
|
||||
}
|
||||
|
||||
b.previewContainer.visibility = if (item.state == STATE_CLOSED) View.VISIBLE else View.INVISIBLE
|
||||
b.yearSummary.visibility = if (item.state == STATE_CLOSED) View.INVISIBLE else View.VISIBLE
|
||||
|
||||
val gradesContainer = b.previewContainer[0]
|
||||
b.previewContainer.removeAllViews()
|
||||
b.gradesContainer.removeAllViews()
|
||||
b.previewContainer.addView(gradesContainer)
|
||||
|
||||
val firstSemester = item.semesters.firstOrNull() ?: return
|
||||
|
||||
b.yearSummary.text = manager.getYearSummaryString(app, item.semesters.map { it.grades.size }.sum(), item.averages)
|
||||
|
||||
if (firstSemester.number != item.semester) {
|
||||
b.gradesContainer.addView(TextView(contextWrapper).apply {
|
||||
setText(R.string.grades_preview_other_semester, firstSemester.number)
|
||||
setPadding(0, 0, 5.dp, 0)
|
||||
maxLines = 1
|
||||
ellipsize = TextUtils.TruncateAt.END
|
||||
})
|
||||
}
|
||||
|
||||
/*if (firstSemester.grades.isEmpty()) {
|
||||
b.previewContainer.addView(TextView(app).apply {
|
||||
setText(R.string.grades_no_grades_in_semester, firstSemester.number)
|
||||
})
|
||||
}*/
|
||||
|
||||
for (grade in firstSemester.grades) {
|
||||
b.gradesContainer.addView(GradeView(
|
||||
contextWrapper,
|
||||
grade,
|
||||
manager,
|
||||
periodGradesTextual = false
|
||||
))
|
||||
}
|
||||
|
||||
b.previewContainer.addView(TextView(contextWrapper).apply {
|
||||
text = manager.getAverageString(app, firstSemester.averages, nameSemester = true, showSemester = firstSemester.number)
|
||||
//gravity = Gravity.END
|
||||
layoutParams = LinearLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT).apply {
|
||||
setMargins(0, 0, 8.dp, 0)
|
||||
}
|
||||
maxLines = 1
|
||||
ellipsize = TextUtils.TruncateAt.END
|
||||
})
|
||||
|
||||
firstSemester.proposedGrade?.let {
|
||||
b.previewContainer.addView(GradeView(
|
||||
contextWrapper,
|
||||
it,
|
||||
manager
|
||||
))
|
||||
}
|
||||
firstSemester.finalGrade?.let {
|
||||
b.previewContainer.addView(GradeView(
|
||||
contextWrapper,
|
||||
it,
|
||||
manager
|
||||
))
|
||||
}
|
||||
|
||||
if (firstSemester.number == item.semester) {
|
||||
b.previewContainer.addView(TextView(contextWrapper).apply {
|
||||
text = manager.getAverageString(app, item.averages, nameSemester = true)
|
||||
layoutParams = LinearLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT).apply {
|
||||
setMargins(0, 0, 8.dp, 0)
|
||||
}
|
||||
maxLines = 1
|
||||
ellipsize = TextUtils.TruncateAt.END
|
||||
})
|
||||
|
||||
item.proposedGrade?.let {
|
||||
b.previewContainer.addView(GradeView(
|
||||
contextWrapper,
|
||||
it,
|
||||
manager
|
||||
))
|
||||
}
|
||||
item.finalGrade?.let {
|
||||
b.previewContainer.addView(GradeView(
|
||||
contextWrapper,
|
||||
it,
|
||||
manager
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -28,7 +28,12 @@ import kotlinx.coroutines.Job
|
||||
import pl.szczodrzynski.edziennik.App
|
||||
import pl.szczodrzynski.edziennik.MainActivity
|
||||
import pl.szczodrzynski.edziennik.R
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade.*
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_SEMESTER1_FINAL
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_SEMESTER1_PROPOSED
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_SEMESTER2_FINAL
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_SEMESTER2_PROPOSED
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_YEAR_FINAL
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_YEAR_PROPOSED
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Subject
|
||||
import pl.szczodrzynski.edziennik.data.db.full.GradeFull
|
||||
@ -39,6 +44,7 @@ import pl.szczodrzynski.edziennik.ui.modules.home.HomeCardAdapter
|
||||
import pl.szczodrzynski.edziennik.ui.modules.home.HomeFragment
|
||||
import pl.szczodrzynski.edziennik.utils.Colors
|
||||
import pl.szczodrzynski.edziennik.utils.Utils
|
||||
import pl.szczodrzynski.edziennik.utils.managers.GradesManager.Companion.COLOR_MODE_DEFAULT
|
||||
import pl.szczodrzynski.edziennik.utils.models.ItemGradesSubjectModel
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
|
||||
@ -122,7 +128,7 @@ class HomeGradesCard(
|
||||
|
||||
subject.grades1.onEach { grade ->
|
||||
val gradeColor = when (App.config.forProfile().grades.colorMode) {
|
||||
Profile.COLOR_MODE_DEFAULT -> grade.color
|
||||
COLOR_MODE_DEFAULT -> grade.color
|
||||
else -> Colors.gradeToColor(grade)
|
||||
}
|
||||
|
||||
|
@ -64,14 +64,14 @@ import static android.app.Activity.RESULT_OK;
|
||||
import static pl.szczodrzynski.edziennik.ExtensionsKt.initDefaultLocale;
|
||||
import static pl.szczodrzynski.edziennik.data.db.entity.Profile.REGISTRATION_DISABLED;
|
||||
import static pl.szczodrzynski.edziennik.data.db.entity.Profile.REGISTRATION_ENABLED;
|
||||
import static pl.szczodrzynski.edziennik.data.db.entity.Profile.YEAR_1_AVG_2_AVG;
|
||||
import static pl.szczodrzynski.edziennik.data.db.entity.Profile.YEAR_1_AVG_2_SEM;
|
||||
import static pl.szczodrzynski.edziennik.data.db.entity.Profile.YEAR_1_SEM_2_AVG;
|
||||
import static pl.szczodrzynski.edziennik.data.db.entity.Profile.YEAR_1_SEM_2_SEM;
|
||||
import static pl.szczodrzynski.edziennik.data.db.entity.Profile.YEAR_ALL_GRADES;
|
||||
import static pl.szczodrzynski.edziennik.utils.Utils.d;
|
||||
import static pl.szczodrzynski.edziennik.utils.Utils.getRealPathFromURI;
|
||||
import static pl.szczodrzynski.edziennik.utils.Utils.getResizedBitmap;
|
||||
import static pl.szczodrzynski.edziennik.utils.managers.GradesManager.YEAR_1_AVG_2_AVG;
|
||||
import static pl.szczodrzynski.edziennik.utils.managers.GradesManager.YEAR_1_AVG_2_SEM;
|
||||
import static pl.szczodrzynski.edziennik.utils.managers.GradesManager.YEAR_1_SEM_2_AVG;
|
||||
import static pl.szczodrzynski.edziennik.utils.managers.GradesManager.YEAR_1_SEM_2_SEM;
|
||||
import static pl.szczodrzynski.edziennik.utils.managers.GradesManager.YEAR_ALL_GRADES;
|
||||
|
||||
public class SettingsNewFragment extends MaterialAboutFragment {
|
||||
|
||||
|
@ -117,17 +117,17 @@ public class Colors {
|
||||
|
||||
public static int gradeToColor(Grade grade)
|
||||
{
|
||||
if (grade.type == Grade.TYPE_POINT_SUM) {
|
||||
return grade.value < 0 ? 0xfff44336 : grade.value > 0 ? 0xff4caf50 : 0xffbdbdbd;
|
||||
if (grade.getType() == Grade.TYPE_POINT_SUM) {
|
||||
return grade.getValue() < 0 ? 0xfff44336 : grade.getValue() > 0 ? 0xff4caf50 : 0xffbdbdbd;
|
||||
}
|
||||
else if (grade.type == Grade.TYPE_POINT_AVG) {
|
||||
return Color.parseColor("#"+gradeValueToColorStr(grade.value/grade.valueMax*100));
|
||||
else if (grade.getType() == Grade.TYPE_POINT_AVG) {
|
||||
return Color.parseColor("#"+gradeValueToColorStr(grade.getValue()/grade.getValueMax()*100));
|
||||
}
|
||||
else if (grade.type == Grade.TYPE_DESCRIPTIVE || grade.type == Grade.TYPE_DESCRIPTIVE_TEXT || grade.type == Grade.TYPE_TEXT) {
|
||||
return grade.color;
|
||||
else if (grade.getType() == Grade.TYPE_DESCRIPTIVE || grade.getType() == Grade.TYPE_DESCRIPTIVE_TEXT || grade.getType() == Grade.TYPE_TEXT) {
|
||||
return grade.getColor();
|
||||
}
|
||||
else {
|
||||
return Color.parseColor("#"+gradeNameToColorStr(grade.name));
|
||||
return Color.parseColor("#"+gradeNameToColorStr(grade.getName()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,227 @@
|
||||
/*
|
||||
* Copyright (c) Kuba Szczodrzyński 2020-3-1.
|
||||
*/
|
||||
|
||||
package pl.szczodrzynski.edziennik.utils.managers
|
||||
|
||||
import android.content.Context
|
||||
import pl.szczodrzynski.edziennik.*
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_NORMAL
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_POINT_AVG
|
||||
import pl.szczodrzynski.edziennik.ui.modules.grades.models.GradesAverages
|
||||
import pl.szczodrzynski.edziennik.ui.modules.grades.models.GradesSemester
|
||||
import pl.szczodrzynski.edziennik.utils.Colors
|
||||
import java.text.DecimalFormat
|
||||
import kotlin.math.floor
|
||||
|
||||
class GradesManager(val app: App) {
|
||||
companion object {
|
||||
const val ORDER_BY_DATE_DESC = 0
|
||||
const val ORDER_BY_SUBJECT_ASC = 1
|
||||
const val ORDER_BY_DATE_ASC = 2
|
||||
const val ORDER_BY_SUBJECT_DESC = 3
|
||||
const val YEAR_1_AVG_2_AVG = 0
|
||||
const val YEAR_1_SEM_2_AVG = 1
|
||||
const val YEAR_1_AVG_2_SEM = 2
|
||||
const val YEAR_1_SEM_2_SEM = 3
|
||||
const val YEAR_ALL_GRADES = 4
|
||||
const val COLOR_MODE_DEFAULT = 0
|
||||
const val COLOR_MODE_WEIGHTED = 1
|
||||
}
|
||||
|
||||
private val gradeRegex by lazy { """([0-6])([+-])?""".toRegex() }
|
||||
private val format = DecimalFormat("#.##")
|
||||
|
||||
val orderBy
|
||||
get() = app.config.grades.orderBy
|
||||
val yearAverageMode
|
||||
get() = app.config.forProfile().grades.yearAverageMode
|
||||
val colorMode
|
||||
get() = app.config.forProfile().grades.colorMode
|
||||
val plusValue
|
||||
get() = app.config.forProfile().grades.plusValue
|
||||
val minusValue
|
||||
get() = app.config.forProfile().grades.minusValue
|
||||
val dontCountGrades
|
||||
get() = app.config.forProfile().grades.dontCountGrades
|
||||
|
||||
|
||||
fun getOrderByString() = when (orderBy) {
|
||||
ORDER_BY_SUBJECT_ASC -> "subjectLongName ASC, gradeSemester DESC, addedDate DESC"
|
||||
ORDER_BY_DATE_ASC -> "subjectId ASC, gradeSemester DESC, addedDate ASC"
|
||||
ORDER_BY_SUBJECT_DESC -> "subjectLongName DESC, gradeSemester DESC, addedDate DESC"
|
||||
else -> "subjectId ASC, gradeSemester DESC, addedDate DESC"
|
||||
}
|
||||
|
||||
fun getWeightString(context: Context, grade: Grade, showClassAverage: Boolean = false) = when (grade.type) {
|
||||
TYPE_NORMAL -> if (grade.weight == 0f)
|
||||
context.getString(R.string.grades_weight_not_counted)
|
||||
else
|
||||
if (showClassAverage && (grade.classAverage ?: 0f) != 0f)
|
||||
context.getString(R.string.grades_weight_format, format.format(grade.weight)+", "+format.format(grade.classAverage))
|
||||
else
|
||||
context.getString(R.string.grades_weight_format, format.format(grade.weight))
|
||||
TYPE_POINT_AVG -> context.getString(R.string.grades_max_points_format, format.format(grade.valueMax))
|
||||
else -> null
|
||||
}
|
||||
|
||||
private fun gradeNameToColorStr(grade: String): String? {
|
||||
when (grade.toLowerCase()) {
|
||||
"+", "++", "+++" ->
|
||||
return "4caf50"
|
||||
"-", "-,", "-,-,", "np", "np.", "npnp", "np,", "np,np,", "bs", "nk" ->
|
||||
return "ff7043"
|
||||
"1-", "1", "f" ->
|
||||
return "ff0000"
|
||||
"1+", "ef" ->
|
||||
return "ff3d00"
|
||||
"2-", "2", "e" ->
|
||||
return "ff9100"
|
||||
"2+", "de" ->
|
||||
return "ffab00"
|
||||
"3-", "3", "d" ->
|
||||
return "ffff00"
|
||||
"3+", "cd" ->
|
||||
return "c6ff00"
|
||||
"4-", "4", "c" ->
|
||||
return "76ff03"
|
||||
"4+", "bc" ->
|
||||
return "64dd17"
|
||||
"5-", "5", "b" ->
|
||||
return "00c853"
|
||||
"5+", "ab" ->
|
||||
return "00bfa5"
|
||||
"6-", "6", "a" ->
|
||||
return "2196f3"
|
||||
"6+", "a+" ->
|
||||
return "0091ea"
|
||||
}
|
||||
return "bdbdbd"
|
||||
}
|
||||
|
||||
fun getRoundedGrade(value: Float): Int {
|
||||
return floor(value.toDouble()).toInt() + if (value % 1.0f >= 0.75) 1 else 0
|
||||
}
|
||||
|
||||
fun getGradeValue(grade: Grade): Float {
|
||||
gradeRegex.find(grade.name)?.let {
|
||||
var value = it[1].toFloatOrNull() ?: return grade.value
|
||||
if (it[2] == "+")
|
||||
value += plusValue ?: return grade.value
|
||||
if (it[2] == "-")
|
||||
value -= minusValue ?: return grade.value
|
||||
return value
|
||||
}
|
||||
return grade.value
|
||||
}
|
||||
|
||||
fun getGradeWeight(dontCountGrades: List<String>, grade: Grade): Float {
|
||||
if (grade.name.toLowerCase() in dontCountGrades)
|
||||
return 0f
|
||||
return grade.weight
|
||||
}
|
||||
|
||||
fun getColor(grade: Grade): Int {
|
||||
return Colors.gradeToColor(grade)
|
||||
}
|
||||
|
||||
fun calculateAverages(averages: GradesAverages, semesters: List<GradesSemester>? = null) {
|
||||
if (averages.pointAvgMax != 0f)
|
||||
averages.pointAvgPercent = averages.pointAvgSum / averages.pointAvgMax * 100f
|
||||
|
||||
if (averages.normalCount <= 0f) {
|
||||
// no grades to count
|
||||
return
|
||||
}
|
||||
|
||||
if (semesters == null || yearAverageMode == YEAR_ALL_GRADES) {
|
||||
// counting average for one semester
|
||||
// or yearly, but just averaging every grade
|
||||
averages.normalAvg = when {
|
||||
averages.normalWeightedCount > 0f -> {
|
||||
averages.normalWeightedSum / averages.normalWeightedCount
|
||||
}
|
||||
averages.normalSum > 0f && averages.normalCount > 0f -> {
|
||||
averages.normalSum / averages.normalCount
|
||||
}
|
||||
else -> null
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
val yearAverageMode = yearAverageMode
|
||||
averages.normalAvg = when (yearAverageMode) {
|
||||
YEAR_1_AVG_2_AVG -> {
|
||||
semesters.mapNotNull { it.averages.normalAvg }.average().toFloat()
|
||||
}
|
||||
else -> {
|
||||
if (semesters.size >= 2) {
|
||||
val sem1 = semesters.firstOrNull { it.number == 1 }
|
||||
val sem2 = semesters.firstOrNull { it.number == 2 }
|
||||
when (yearAverageMode) {
|
||||
YEAR_1_SEM_2_AVG -> {
|
||||
ifNotNull(sem1?.finalGrade?.value, sem2?.averages?.normalAvg) { s1, s2 ->
|
||||
(s1 + s2) / 2f
|
||||
}
|
||||
}
|
||||
YEAR_1_AVG_2_SEM -> {
|
||||
ifNotNull(sem1?.averages?.normalAvg, sem2?.finalGrade?.value) { s1, s2 ->
|
||||
(s1 + s2) / 2f
|
||||
}
|
||||
}
|
||||
YEAR_1_SEM_2_SEM -> {
|
||||
ifNotNull(sem1?.finalGrade?.value, sem2?.finalGrade?.value) { s1, s2 ->
|
||||
(s1 + s2) / 2f
|
||||
}
|
||||
}
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
else null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun getAverageString(context: Context, averages: GradesAverages, nameSemester: Boolean = false, showSemester: Int? = null, noAverageRes: Int? = null): CharSequence? {
|
||||
val averageString = when {
|
||||
averages.normalAvg != null -> String.format("%.2f", averages.normalAvg)
|
||||
averages.pointSum != 0f -> context.getString(R.string.grades_average_value_sum_format, format.format(averages.pointSum))
|
||||
averages.pointAvgPercent != null -> context.getString(
|
||||
R.string.grades_average_value_point_format,
|
||||
format.format(averages.pointAvgSum),
|
||||
format.format(averages.pointAvgMax),
|
||||
format.format(averages.pointAvgPercent)
|
||||
)
|
||||
else -> return noAverageRes?.let { context.getString(it) }
|
||||
}.asColoredSpannable(android.R.attr.textColorSecondary.resolveAttr(context))
|
||||
|
||||
return if (nameSemester) {
|
||||
context.getString(
|
||||
if (showSemester == null)
|
||||
R.string.grades_average_year_format
|
||||
else
|
||||
R.string.grades_average_semester_format,
|
||||
showSemester ?: 0,
|
||||
averageString
|
||||
)
|
||||
}
|
||||
else {
|
||||
when {
|
||||
averages.normalAvg != null -> context.getString(R.string.grades_average_normal_format, averageString)
|
||||
averages.pointSum != 0f -> context.getString(R.string.grades_average_sum_format, averageString)
|
||||
averages.pointAvgPercent != null -> context.getString(R.string.grades_average_point_format, averageString)
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun getYearSummaryString(context: Context, gradeCount: Int, averages: GradesAverages): CharSequence {
|
||||
val gradeCountString = context.plural(R.plurals.grades_format, gradeCount)
|
||||
return context.getString(
|
||||
R.string.grades_year_summary_format,
|
||||
gradeCountString,
|
||||
getAverageString(context, averages, noAverageRes = R.string.grades_average_no)
|
||||
)
|
||||
}
|
||||
}
|
@ -313,7 +313,7 @@ public class Date implements Comparable<Date> {
|
||||
@Nullable
|
||||
public String getRelativeString(Context context, int maxDiff) {
|
||||
int diffDays = Date.diffDays(this, Date.getToday());
|
||||
if (maxDiff != 0 && diffDays > maxDiff) {
|
||||
if (maxDiff != 0 && Math.abs(diffDays) > maxDiff) {
|
||||
return null;
|
||||
}
|
||||
return dayDiffString(context, diffDays);
|
||||
|
@ -3,7 +3,7 @@
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
|
||||
<solid android:color="#00000000" />
|
||||
<corners android:radius="4dp" />
|
||||
<!--<solid android:color="?attr/windowBackground" />-->
|
||||
<stroke android:color="#ffffff" android:width="2dp" />
|
||||
</shape>
|
||||
</shape>
|
||||
|
@ -5,4 +5,4 @@
|
||||
|
||||
<corners android:radius="8dp" />
|
||||
<solid android:color="#ffffff" />
|
||||
</shape>
|
||||
</shape>
|
||||
|
16
app/src/main/res/drawable/ic_no_grades.xml
Normal file
16
app/src/main/res/drawable/ic_no_grades.xml
Normal file
@ -0,0 +1,16 @@
|
||||
<!--
|
||||
~ Copyright (c) Kuba Szczodrzyński 2020-3-4.
|
||||
-->
|
||||
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="128dp"
|
||||
android:height="128dp"
|
||||
android:viewportWidth="128"
|
||||
android:viewportHeight="128">
|
||||
<path
|
||||
android:pathData="m114,62c0,27.6 -22.4,50 -50,50s-50,-22.4 -50,-50 22.4,-50 50,-50 50,22.4 50,50z"
|
||||
android:fillColor="#795bfa"/>
|
||||
<path
|
||||
android:pathData="m67.9,36.8 l4.46,12.6c0.57,1.61 2.07,2.71 3.77,2.76l11.9,0.375c3.94,0.121 5.49,5.18 2.31,7.51l-9.39,6.88c-1.45,1.06 -2.05,2.93 -1.5,4.64l4.39,11c1.2,3.71 -2.9,6.89 -6.17,4.77l-11.4,-6.81c-1.36,-0.883 -3.11,-0.883 -4.48,0l-11.4,6.81c-3.27,2.11 -7.37,-1.06 -6.17,-4.77l4.39,-11c0.551,-1.71 -0.055,-3.58 -1.5,-4.64l-9.39,-6.88c-3.18,-2.33 -1.63,-7.39 2.31,-7.51l11.9,-0.375c1.7,-0.051 3.2,-1.15 3.77,-2.76l4.46,-12.6c1.3,-3.69 6.49,-3.69 7.8,0z"
|
||||
android:fillColor="#fff"/>
|
||||
</vector>
|
@ -3,7 +3,8 @@
|
||||
~ Copyright (c) Kacper Ziubryniewicz 2020-1-20
|
||||
-->
|
||||
|
||||
<layout xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
<ScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
@ -14,10 +15,62 @@
|
||||
android:orientation="vertical"
|
||||
android:padding="24dp">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/customPlusCheckBox"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:minHeight="0dp"
|
||||
android:text="Własna wartość plusa" />
|
||||
|
||||
<it.sephiroth.android.library.numberpicker.NumberPicker
|
||||
android:id="@+id/customPlusValue"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="32dp"
|
||||
app:picker_min="0.0"
|
||||
app:picker_max="1.0"
|
||||
app:picker_stepSize="0.01"
|
||||
app:picker_disableGestures="true"
|
||||
app:picker_orientation="horizontal" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/customMinusCheckBox"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:minHeight="0dp"
|
||||
android:text="Własna wartość minusa" />
|
||||
|
||||
<it.sephiroth.android.library.numberpicker.NumberPicker
|
||||
android:id="@+id/customMinusValue"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="32dp"
|
||||
app:picker_min="0.0"
|
||||
app:picker_max="1.0"
|
||||
app:picker_stepSize="0.01"
|
||||
app:picker_disableGestures="true"
|
||||
app:picker_orientation="horizontal" />
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:layout_marginBottom="4dp"
|
||||
style="@style/TextAppearance.AppCompat.Small"
|
||||
android:text="@string/menu_grades_sort_mode"/>
|
||||
|
||||
@ -29,20 +82,22 @@
|
||||
android:id="@+id/sortGradesByDateRadio"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/dialog_grades_config_sort_by_date"/>
|
||||
android:minHeight="0dp"
|
||||
android:text="@string/dialog_grades_config_sort_by_date" />
|
||||
|
||||
<RadioButton
|
||||
android:id="@+id/sortGradesBySubjectRadio"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:minHeight="0dp"
|
||||
android:text="@string/dialog_grades_config_sort_by_subject"/>
|
||||
</RadioGroup>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginBottom="4dp"
|
||||
style="@style/TextAppearance.AppCompat.Small"
|
||||
android:text="@string/menu_grades_color_mode"/>
|
||||
|
||||
@ -54,20 +109,22 @@
|
||||
android:id="@+id/gradeColorFromERegister"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:minHeight="0dp"
|
||||
android:text="@string/dialog_grades_config_color_from_eregister"/>
|
||||
|
||||
<RadioButton
|
||||
android:id="@+id/gradeColorByValue"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:minHeight="0dp"
|
||||
android:text="@string/dialog_grades_config_color_by_value"/>
|
||||
</RadioGroup>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginBottom="4dp"
|
||||
style="@style/TextAppearance.AppCompat.Small"
|
||||
android:text="@string/menu_grades_average_mode"/>
|
||||
|
||||
@ -79,30 +136,35 @@
|
||||
android:id="@+id/gradeAverageMode4"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:minHeight="0dp"
|
||||
android:text="@string/settings_register_avg_mode_4"/>
|
||||
|
||||
<RadioButton
|
||||
android:id="@+id/gradeAverageMode0"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:minHeight="0dp"
|
||||
android:text="@string/settings_register_avg_mode_0"/>
|
||||
|
||||
<RadioButton
|
||||
android:id="@+id/gradeAverageMode1"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:minHeight="0dp"
|
||||
android:text="@string/settings_register_avg_mode_1"/>
|
||||
|
||||
<RadioButton
|
||||
android:id="@+id/gradeAverageMode2"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:minHeight="0dp"
|
||||
android:text="@string/settings_register_avg_mode_2"/>
|
||||
|
||||
<RadioButton
|
||||
android:id="@+id/gradeAverageMode3"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:minHeight="0dp"
|
||||
android:text="@string/settings_register_avg_mode_3"/>
|
||||
</RadioGroup>
|
||||
|
||||
@ -118,6 +180,7 @@
|
||||
android:id="@+id/dontCountZeroToAverage"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:minHeight="0dp"
|
||||
android:text="@string/settings_register_dont_count_zero_text"/>
|
||||
</LinearLayout>
|
||||
</ScrollView>
|
||||
|
@ -28,238 +28,252 @@
|
||||
<variable
|
||||
name="devMode"
|
||||
type="boolean" />
|
||||
<variable
|
||||
name="gradeValue"
|
||||
type="float" />
|
||||
</data>
|
||||
<LinearLayout
|
||||
android:orientation="vertical"
|
||||
|
||||
<ScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/gradeName"
|
||||
android:layout_width="72dp"
|
||||
android:layout_height="72dp"
|
||||
android:background="@drawable/bg_rounded_16dp"
|
||||
android:fontFamily="serif-monospace"
|
||||
android:gravity="center"
|
||||
android:padding="8dp"
|
||||
android:text="@{grade.name}"
|
||||
android:textIsSelectable="true"
|
||||
android:textSize="36sp"
|
||||
android:textStyle="bold"
|
||||
app:autoSizeMaxTextSize="56sp"
|
||||
app:autoSizeTextType="uniform"
|
||||
tools:background="#ff4caf50"
|
||||
tools:text="1-" />
|
||||
android:orientation="vertical"
|
||||
android:paddingLeft="24dp"
|
||||
android:paddingTop="24dp"
|
||||
android:paddingRight="24dp">
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="vertical"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_weight="1">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
<TextView
|
||||
android:id="@+id/gradeSemester"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:textAppearance="@style/NavView.TextView.Helper"
|
||||
android:textIsSelectable="true"
|
||||
android:text="@{@string/dialog_grade_details_semester_format(grade.semester)}"
|
||||
tools:text="semestr 1"/>
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/gradeSubjectName"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@{grade.subjectLongName}"
|
||||
android:textIsSelectable="true"
|
||||
android:textAppearance="@style/NavView.TextView.Title"
|
||||
tools:text="pracownia urządzeń techniki komputerowej" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/gradeWeight"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@{weightText}"
|
||||
android:textIsSelectable="true"
|
||||
android:textAppearance="@style/NavView.TextView.Subtitle"
|
||||
android:visibility="@{weightText != null ? View.VISIBLE : View.GONE}"
|
||||
tools:text="waga 3"
|
||||
tools:visibility="visible" />
|
||||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:textAppearance="@style/NavView.TextView.Helper"
|
||||
android:text="@string/dialog_grade_details_teacher" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="0dp"
|
||||
android:text="@{grade.teacherFullName}"
|
||||
android:textIsSelectable="true"
|
||||
tools:text="Janósz Kowalski" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:textAppearance="@style/NavView.TextView.Helper"
|
||||
android:text="@string/dialog_grade_details_category" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="0dp"
|
||||
android:text="@{Utils.ns(@string/dialog_grade_details_no_category, grade.category)}"
|
||||
android:textIsSelectable="true"
|
||||
tools:text="@string/dialog_grade_details_no_category" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:textAppearance="@style/NavView.TextView.Helper"
|
||||
android:text="@string/dialog_grade_details_description" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="0dp"
|
||||
android:text="@{Utils.ns(@string/dialog_grade_details_no_description, grade.description)}"
|
||||
android:textIsSelectable="true"
|
||||
tools:text="@string/dialog_grade_details_no_description" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:textAppearance="@style/NavView.TextView.Helper"
|
||||
android:visibility="@{grade.classAverage > -1 ? View.VISIBLE : View.GONE}"
|
||||
android:text="@string/dialog_grade_details_class_average" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="0dp"
|
||||
android:text="@{@string/dialog_grade_details_class_average_format(grade.classAverage)}"
|
||||
android:textIsSelectable="true"
|
||||
android:visibility="@{grade.classAverage > -1 ? View.VISIBLE : View.GONE}"
|
||||
tools:text="1.72" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:textAppearance="@style/NavView.TextView.Helper"
|
||||
android:visibility="@{commentVisible ? View.VISIBLE : View.GONE}"
|
||||
android:text="@string/dialog_grade_details_comment" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="0dp"
|
||||
tools:text="Uczeń jest idiotą i nie umie robić nic w excelu. Niestety nie zdał tej klasy więc ta ocena i tak mu nic nie da, więc a cotam, dam mu jedynkę kolejną.. XDD"
|
||||
android:textIsSelectable="true"
|
||||
android:visibility="@{commentVisible ? View.VISIBLE : View.GONE}" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:textAppearance="@style/NavView.TextView.Helper"
|
||||
android:text="@string/dialog_grade_details_value"
|
||||
android:visibility="@{grade.value > -1 ? View.VISIBLE : View.GONE}" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="0dp"
|
||||
android:text="@{@string/dialog_grade_details_class_average_format(grade.value)}"
|
||||
android:textIsSelectable="true"
|
||||
android:visibility="@{grade.value > -1 ? View.VISIBLE : View.GONE}"
|
||||
tools:text="4.75" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:textAppearance="@style/NavView.TextView.Helper"
|
||||
android:text="@string/dialog_grade_details_added_date" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="0dp"
|
||||
android:text="@{@string/dialog_grade_details_date_format(Date.fromMillis(grade.addedDate).getFormattedString(), Time.fromMillis(grade.addedDate).getStringHM())}"
|
||||
android:textIsSelectable="true"
|
||||
tools:text="May 10, 12:03" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:textAppearance="@style/NavView.TextView.Helper"
|
||||
android:visibility="@{devMode ? View.VISIBLE : View.GONE}"
|
||||
android:text="@string/dialog_grade_details_id" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="0dp"
|
||||
android:text="@{Long.toString(grade.id)}"
|
||||
android:textIsSelectable="true"
|
||||
android:visibility="@{devMode ? View.VISIBLE : View.GONE}"
|
||||
tools:text="12345" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:textAppearance="@style/NavView.TextView.Small"
|
||||
android:visibility="@{grade.parentId != -1 ? View.VISIBLE : View.GONE}"
|
||||
android:text="@string/dialog_grade_details_improved" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:textAppearance="@style/NavView.TextView.Helper"
|
||||
android:visibility="@{historyVisible ? View.VISIBLE : View.GONE}"
|
||||
android:text="@string/dialog_grade_details_history" />
|
||||
|
||||
<androidx.core.widget.NestedScrollView
|
||||
android:id="@+id/gradeHistoryNest"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="@{historyVisible ? View.VISIBLE : View.GONE}">
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/gradeHistoryList"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
tools:listitem="@layout/row_grades_list_item" />
|
||||
android:orientation="horizontal">
|
||||
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
<TextView
|
||||
android:id="@+id/gradeName"
|
||||
android:layout_width="72dp"
|
||||
android:layout_height="72dp"
|
||||
android:background="@drawable/bg_rounded_16dp"
|
||||
android:fontFamily="serif-monospace"
|
||||
android:gravity="center"
|
||||
android:padding="8dp"
|
||||
android:text="@{grade.name}"
|
||||
android:textIsSelectable="true"
|
||||
android:textSize="36sp"
|
||||
android:textStyle="bold"
|
||||
app:autoSizeMaxTextSize="56sp"
|
||||
app:autoSizeTextType="uniform"
|
||||
tools:background="#ff4caf50"
|
||||
tools:text="1-" />
|
||||
|
||||
</LinearLayout>
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_weight="1"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/gradeSemester"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="@{@string/dialog_grade_details_semester_format(grade.semester)}"
|
||||
android:textAppearance="@style/NavView.TextView.Helper"
|
||||
android:textIsSelectable="true"
|
||||
tools:text="semestr 1" />
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/gradeSubjectName"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@{grade.subjectLongName}"
|
||||
android:textAppearance="@style/NavView.TextView.Title"
|
||||
android:textIsSelectable="true"
|
||||
tools:text="pracownia urządzeń techniki komputerowej" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/gradeWeight"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@{weightText}"
|
||||
android:textAppearance="@style/NavView.TextView.Subtitle"
|
||||
android:textIsSelectable="true"
|
||||
android:visibility="@{weightText != null ? View.VISIBLE : View.GONE}"
|
||||
tools:text="waga 3"
|
||||
tools:visibility="visible" />
|
||||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:text="@string/dialog_grade_details_teacher"
|
||||
android:textAppearance="@style/NavView.TextView.Helper" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="0dp"
|
||||
android:text="@{grade.teacherFullName}"
|
||||
android:textIsSelectable="true"
|
||||
tools:text="Janósz Kowalski" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:text="@string/dialog_grade_details_category"
|
||||
android:textAppearance="@style/NavView.TextView.Helper" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="0dp"
|
||||
android:text="@{Utils.ns(@string/dialog_grade_details_no_category, grade.category)}"
|
||||
android:textIsSelectable="true"
|
||||
tools:text="@string/dialog_grade_details_no_category" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:text="@string/dialog_grade_details_description"
|
||||
android:textAppearance="@style/NavView.TextView.Helper" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="0dp"
|
||||
android:text="@{Utils.ns(@string/dialog_grade_details_no_description, grade.description)}"
|
||||
android:textIsSelectable="true"
|
||||
tools:text="@string/dialog_grade_details_no_description" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:text="@string/dialog_grade_details_class_average"
|
||||
android:textAppearance="@style/NavView.TextView.Helper"
|
||||
android:visibility="@{grade.classAverage != null && grade.classAverage != -1 ? View.VISIBLE : View.GONE}" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="0dp"
|
||||
android:text="@{@string/dialog_grade_details_class_average_format(grade.classAverage)}"
|
||||
android:textIsSelectable="true"
|
||||
android:visibility="@{grade.classAverage != null && grade.classAverage != -1 ? View.VISIBLE : View.GONE}"
|
||||
tools:text="1.72" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:text="@string/dialog_grade_details_comment"
|
||||
android:textAppearance="@style/NavView.TextView.Helper"
|
||||
android:visibility="@{commentVisible ? View.VISIBLE : View.GONE}" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="0dp"
|
||||
android:textIsSelectable="true"
|
||||
android:visibility="@{commentVisible ? View.VISIBLE : View.GONE}"
|
||||
tools:text="Uczeń jest idiotą i nie umie robić nic w excelu. Niestety nie zdał tej klasy więc ta ocena i tak mu nic nie da, więc a cotam, dam mu jedynkę kolejną.. XDD" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:text="@string/dialog_grade_details_value"
|
||||
android:textAppearance="@style/NavView.TextView.Helper"
|
||||
android:visibility="@{gradeValue != -1 ? View.VISIBLE : View.GONE}" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="0dp"
|
||||
android:text="@{@string/dialog_grade_details_class_average_format(gradeValue)}"
|
||||
android:textIsSelectable="true"
|
||||
android:visibility="@{gradeValue != -1 ? View.VISIBLE : View.GONE}"
|
||||
tools:text="4.75" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:text="@string/dialog_grade_details_added_date"
|
||||
android:textAppearance="@style/NavView.TextView.Helper" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="0dp"
|
||||
android:text="@{@string/dialog_grade_details_date_format(Date.fromMillis(grade.addedDate).getFormattedString(), Time.fromMillis(grade.addedDate).getStringHM())}"
|
||||
android:textIsSelectable="true"
|
||||
tools:text="May 10, 12:03" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:text="@string/dialog_grade_details_id"
|
||||
android:textAppearance="@style/NavView.TextView.Helper"
|
||||
android:visibility="@{devMode ? View.VISIBLE : View.GONE}" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="0dp"
|
||||
android:text="@{Long.toString(grade.id)}"
|
||||
android:textIsSelectable="true"
|
||||
android:visibility="@{devMode ? View.VISIBLE : View.GONE}"
|
||||
tools:text="12345" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:text="@string/dialog_grade_details_improved"
|
||||
android:textAppearance="@style/NavView.TextView.Small"
|
||||
android:visibility="@{grade.parentId instanceof Long ? View.VISIBLE : View.GONE}" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:text="@string/dialog_grade_details_history"
|
||||
android:textAppearance="@style/NavView.TextView.Helper"
|
||||
android:visibility="@{historyVisible ? View.VISIBLE : View.GONE}" />
|
||||
|
||||
<androidx.core.widget.NestedScrollView
|
||||
android:id="@+id/gradeHistoryNest"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="-8dp"
|
||||
android:layout_marginRight="-8dp"
|
||||
android:visibility="@{historyVisible ? View.VISIBLE : View.GONE}">
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/gradeHistoryList"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
tools:listitem="@layout/row_grades_list_item" />
|
||||
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
|
||||
</LinearLayout>
|
||||
</ScrollView>
|
||||
</layout>
|
||||
|
37
app/src/main/res/layout/grades_fragment.xml
Normal file
37
app/src/main/res/layout/grades_fragment.xml
Normal file
@ -0,0 +1,37 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (c) Kuba Szczodrzyński 2020-3-4.
|
||||
-->
|
||||
|
||||
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<pl.szczodrzynski.edziennik.utils.SwipeRefreshLayoutNoIndicator
|
||||
android:id="@+id/refreshLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/gradesNoData"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:drawablePadding="16dp"
|
||||
android:fontFamily="sans-serif-light"
|
||||
android:text="@string/grades_no_data"
|
||||
android:textSize="24sp"
|
||||
app:drawableTopCompat="@drawable/ic_no_grades" />
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/gradesRecyclerView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:listitem="@layout/grades_item_subject" />
|
||||
</FrameLayout>
|
||||
</pl.szczodrzynski.edziennik.utils.SwipeRefreshLayoutNoIndicator>
|
||||
</layout>
|
21
app/src/main/res/layout/grades_item_empty.xml
Normal file
21
app/src/main/res/layout/grades_item_empty.xml
Normal file
@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (c) Kuba Szczodrzyński 2020-3-1.
|
||||
-->
|
||||
|
||||
<layout xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="8dp"
|
||||
android:gravity="center"
|
||||
android:textSize="18sp"
|
||||
android:textColor="?android:textColorSecondary"
|
||||
android:textStyle="italic"
|
||||
android:text="Nie ma ocen w tym semestrze."/>
|
||||
</LinearLayout>
|
||||
</layout>
|
101
app/src/main/res/layout/grades_item_grade.xml
Normal file
101
app/src/main/res/layout/grades_item_grade.xml
Normal file
@ -0,0 +1,101 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (c) Kuba Szczodrzyński 2020-2-29.
|
||||
-->
|
||||
|
||||
<layout xmlns:tools="http://schemas.android.com/tools"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?selectableItemBackground"
|
||||
android:orientation="horizontal"
|
||||
android:paddingTop="8dp"
|
||||
android:paddingBottom="8dp">
|
||||
|
||||
<pl.szczodrzynski.edziennik.ui.modules.grades.GradeView
|
||||
android:id="@+id/gradeName"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginLeft="8dp"
|
||||
tools:text="5+" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/gradeDescription"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginLeft="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_marginRight="8dp"
|
||||
android:layout_weight="1"
|
||||
android:ellipsize="end"
|
||||
android:singleLine="true"
|
||||
tools:text="kraje hehe no jak zwykle jedynka z geografii. to jest baaardzo długi tekst ale szkoda że się nie scrolluje." />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/gradeAddedDate"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_marginRight="8dp"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Small"
|
||||
tools:text="14.10.2015" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/gradeWeight"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginLeft="8dp"
|
||||
android:textStyle="bold"
|
||||
tools:text="waga 30"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/gradeCategory"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginLeft="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_marginRight="8dp"
|
||||
android:ellipsize="end"
|
||||
android:maxWidth="200dp"
|
||||
android:maxLines="1"
|
||||
tools:text="Kartkówki - K1 123456789 12345678" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/gradeTeacherName"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_marginRight="8dp"
|
||||
android:layout_weight="1"
|
||||
android:ellipsize="end"
|
||||
android:gravity="end"
|
||||
android:maxLines="1"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Small"
|
||||
tools:text="Anna Jakaśtam-Cośtam" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</layout>
|
80
app/src/main/res/layout/grades_item_semester.xml
Normal file
80
app/src/main/res/layout/grades_item_semester.xml
Normal file
@ -0,0 +1,80 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (c) Kuba Szczodrzyński 2020-2-29.
|
||||
-->
|
||||
|
||||
<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:background="?selectableItemBackground"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<com.mikepenz.iconics.view.IconicsImageView
|
||||
android:id="@+id/dropdownIcon"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginLeft="8dp"
|
||||
android:scaleType="centerInside"
|
||||
app:iiv_color="?android:textColorSecondary"
|
||||
app:iiv_icon="cmd-chevron-down"
|
||||
app:iiv_size="16dp"
|
||||
tools:src="@android:drawable/ic_menu_more" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/semesterName"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="8dp"
|
||||
android:layout_weight="1"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
android:textSize="18sp"
|
||||
tools:text="Semestr 1" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/average"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="5dp"
|
||||
android:layout_marginRight="5dp"
|
||||
android:gravity="end"
|
||||
android:textSize="14sp"
|
||||
tools:text="punkty: 18.75/20\n(95,67%)"
|
||||
tools:text1="suma: 175 pkt"
|
||||
tools:text2="średnia: 4,78" />
|
||||
|
||||
<pl.szczodrzynski.edziennik.ui.modules.grades.GradeView
|
||||
android:id="@+id/proposedGrade"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="gone"
|
||||
tools:layout_marginRight="5dp"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<pl.szczodrzynski.edziennik.ui.modules.grades.GradeView
|
||||
android:id="@+id/finalGrade"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="gone"
|
||||
tools:layout_marginRight="5dp"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<com.mikepenz.iconics.view.IconicsImageView
|
||||
android:id="@+id/editButton"
|
||||
android:layout_width="32dp"
|
||||
android:layout_height="32dp"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:background="?selectableItemBackgroundBorderless"
|
||||
android:scaleType="centerInside"
|
||||
app:iiv_color="?android:textColorSecondary"
|
||||
app:iiv_icon="cmd-playlist-edit"
|
||||
app:iiv_size="16dp"
|
||||
tools:src="@android:drawable/ic_menu_edit" />
|
||||
</LinearLayout>
|
||||
</layout>
|
334
app/src/main/res/layout/grades_item_stats.xml
Normal file
334
app/src/main/res/layout/grades_item_stats.xml
Normal file
@ -0,0 +1,334 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (c) Kuba Szczodrzyński 2020-3-3.
|
||||
-->
|
||||
|
||||
<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">
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:layout_marginBottom="32dp"
|
||||
android:background="@drawable/divider" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="8dp"
|
||||
android:text="@string/grades_stats_title"
|
||||
android:textAppearance="@style/NavView.TextView.Title" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/noData"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_margin="8dp"
|
||||
android:fontFamily="sans-serif-light"
|
||||
android:text="@string/grades_stats_no_data"
|
||||
android:textSize="16sp"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/normalTitle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:text="@string/grades_stats_normal"
|
||||
android:textAppearance="@style/NavView.TextView.Subtitle" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/normalLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:paddingStart="8dp"
|
||||
android:paddingEnd="8dp">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/normalSemester1Layout"
|
||||
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_semester_1" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/normalSemester1"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:fontFamily="sans-serif-light"
|
||||
android:textSize="24sp"
|
||||
tools:text="4,56" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/normalSemester1Notice"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_horizontal"
|
||||
android:textAppearance="@style/NavView.TextView.Helper"
|
||||
tools:text="*z ocen proponowanych" />
|
||||
</LinearLayout>
|
||||
|
||||
<View
|
||||
android:id="@+id/normalDiv1"
|
||||
android:layout_width="1dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginTop="8dp"
|
||||
android:background="@drawable/divider" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/normalSemester2Layout"
|
||||
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_semester_2" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/normalSemester2"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:fontFamily="sans-serif-light"
|
||||
android:textSize="24sp"
|
||||
tools:text="4,67" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/normalSemester2Notice"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_horizontal"
|
||||
android:textAppearance="@style/NavView.TextView.Helper"
|
||||
tools:text="*przewidywana średnia" />
|
||||
</LinearLayout>
|
||||
|
||||
<View
|
||||
android:id="@+id/normalDiv2"
|
||||
android:layout_width="1dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginTop="8dp"
|
||||
android:background="@drawable/divider" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/normalYearlyLayout"
|
||||
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_yearly" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/normalYearly"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:fontFamily="sans-serif-light"
|
||||
android:textSize="24sp"
|
||||
tools:text="3,75" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/normalYearlyNotice"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_horizontal"
|
||||
android:textAppearance="@style/NavView.TextView.Helper"
|
||||
tools:text="*przewidywana średnia" />
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<com.mikepenz.iconics.view.IconicsImageView
|
||||
android:id="@+id/helpButton"
|
||||
android:layout_width="32dp"
|
||||
android:layout_height="32dp"
|
||||
android:layout_gravity="end"
|
||||
android:background="?selectableItemBackgroundBorderless"
|
||||
android:scaleType="centerInside"
|
||||
app:iiv_color="?android:textColorSecondary"
|
||||
app:iiv_icon="cmd-help-circle-outline"
|
||||
app:iiv_size="16dp"
|
||||
tools:src="@android:drawable/ic_menu_help" />
|
||||
|
||||
<View
|
||||
android:id="@+id/normalDivider"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:background="@drawable/divider" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/pointTitle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:text="@string/grades_stats_point"
|
||||
android:textAppearance="@style/NavView.TextView.Subtitle" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/pointLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:paddingStart="8dp"
|
||||
android:paddingEnd="8dp">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/pointSemester1Layout"
|
||||
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_semester_1" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/pointSemester1"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:fontFamily="sans-serif-light"
|
||||
android:textSize="24sp"
|
||||
tools:text="95%" />
|
||||
</LinearLayout>
|
||||
|
||||
<View
|
||||
android:id="@+id/pointDiv1"
|
||||
android:layout_width="1dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginTop="8dp"
|
||||
android:background="@drawable/divider" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/pointSemester2Layout"
|
||||
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_semester_2" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/pointSemester2"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:fontFamily="sans-serif-light"
|
||||
android:textSize="24sp"
|
||||
tools:text="93,27%" />
|
||||
</LinearLayout>
|
||||
|
||||
<View
|
||||
android:id="@+id/pointDiv2"
|
||||
android:layout_width="1dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginTop="8dp"
|
||||
android:background="@drawable/divider" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/pointYearlyLayout"
|
||||
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_yearly" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/pointYearly"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:fontFamily="sans-serif-light"
|
||||
android:textSize="24sp"
|
||||
tools:text="94,50%" />
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<View
|
||||
android:id="@+id/pointDivider"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:background="@drawable/divider" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/disclaimer"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="8dp"
|
||||
android:text="@string/grades_stats_disclaimer"
|
||||
android:textAppearance="@style/NavView.TextView.Helper"
|
||||
android:textSize="12sp"
|
||||
android:textStyle="italic" />
|
||||
|
||||
<View
|
||||
android:id="@+id/customValueDivider"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:background="@drawable/divider" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/customValueLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="8dp"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/grades_stats_custom_value_notice"
|
||||
android:textAppearance="@style/NavView.TextView.Helper"
|
||||
android:textSize="12sp"
|
||||
android:textStyle="italic" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/customValueButton"
|
||||
style="@style/Widget.MaterialComponents.Button.OutlinedButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_marginRight="8dp"
|
||||
android:minHeight="0dp"
|
||||
android:text="@string/configure" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</layout>
|
91
app/src/main/res/layout/grades_item_subject.xml
Normal file
91
app/src/main/res/layout/grades_item_subject.xml
Normal file
@ -0,0 +1,91 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (c) Kuba Szczodrzyński 2020-2-29.
|
||||
-->
|
||||
|
||||
<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">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/subjectName"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="8dp"
|
||||
android:layout_weight="1"
|
||||
android:ellipsize="end"
|
||||
android:fontFamily="sans-serif-medium"
|
||||
android:maxLines="2"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
android:textSize="20sp"
|
||||
tools:text="systemy operacyjne\n1234" />
|
||||
|
||||
<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:src="@android:drawable/ic_menu_more" />
|
||||
</LinearLayout>
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:layout_marginLeft="8dp">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/previewContainer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
tools:visibility="visible"
|
||||
android:baselineAligned="false">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/gradesContainer"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:layout_marginRight="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:orientation="horizontal" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/yearSummary"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:textSize="14sp"
|
||||
android:visibility="gone"
|
||||
tools:text1="Cały rok: 3 oceny • suma: 320 pkt"
|
||||
tools:text2="Cały rok: 15 ocen • średnia: 2,62"
|
||||
tools:text="Cały rok: 6 ocen • punkty: 34.20/40 (87.5%)"
|
||||
tools:visibility="gone"/>
|
||||
</FrameLayout>
|
||||
</LinearLayout>
|
||||
</layout>
|
@ -175,7 +175,7 @@
|
||||
<string name="dialog_grade_details_description">Description</string>
|
||||
<string name="dialog_grade_details_history">Grade history</string>
|
||||
<string name="dialog_grade_details_id">Grade ID</string>
|
||||
<string name="dialog_grade_details_improved">Grade is hidden - it was improved</string>
|
||||
<string name="dialog_grade_details_improved">The grade is improved by another one</string>
|
||||
<string name="dialog_grade_details_no_category">(no category)</string>
|
||||
<string name="dialog_grade_details_no_description">(no description)</string>
|
||||
<string name="dialog_grade_details_semester_format">semester %d</string>
|
||||
@ -273,7 +273,7 @@
|
||||
<string name="grades_editor_weight_other">other weight</string>
|
||||
<string name="grades_improvement_category_format">(resit) %s</string>
|
||||
<string name="grades_max_points_format">max %s pts</string>
|
||||
<string name="grades_no_data">No subjects to show</string>
|
||||
<string name="grades_no_data">No grades.</string>
|
||||
<string name="grades_semester1_header">Semester 1</string>
|
||||
<string name="grades_semester2_header">Semester 2</string>
|
||||
<string name="grades_semester_average_format">semester %d: %s</string>
|
||||
|
@ -153,4 +153,10 @@
|
||||
<item quantity="few">%d inne powiadomienia</item> <!-- 2, 3, 4, 32, 33, 34 -->
|
||||
<item quantity="other">%d innych powiadomień</item> <!-- 5, 10, 12, 13, 21, 25 -->
|
||||
</plurals>
|
||||
</resources>
|
||||
|
||||
<plurals name="grades_format">
|
||||
<item quantity="one">%d ocena</item> <!-- 1 -->
|
||||
<item quantity="few">%d oceny</item> <!-- 2, 3, 4, 32, 33, 34 -->
|
||||
<item quantity="other">%d ocen</item> <!-- 5, 10, 12, 13, 21, 25 -->
|
||||
</plurals>
|
||||
</resources>
|
||||
|
@ -208,7 +208,7 @@
|
||||
<string name="dialog_grade_details_description">Opis</string>
|
||||
<string name="dialog_grade_details_history">Historia oceny</string>
|
||||
<string name="dialog_grade_details_id">ID oceny</string>
|
||||
<string name="dialog_grade_details_improved">Ocena jest ukryta - została poprawiona</string>
|
||||
<string name="dialog_grade_details_improved">Ocena została poprawiona</string>
|
||||
<string name="dialog_grade_details_no_category">(brak kategorii)</string>
|
||||
<string name="dialog_grade_details_no_description">(brak opisu)</string>
|
||||
<string name="dialog_grade_details_semester_format">semestr %d</string>
|
||||
@ -311,7 +311,7 @@
|
||||
<string name="grades_editor_weight_other">inna waga</string>
|
||||
<string name="grades_improvement_category_format">(poprawa) %s</string>
|
||||
<string name="grades_max_points_format">max %s pkt</string>
|
||||
<string name="grades_no_data">Brak przedmiotów do wyświetlenia</string>
|
||||
<string name="grades_no_data">Brak ocen w dzienniku.</string>
|
||||
<string name="grades_semester1_header">Semestr 1</string>
|
||||
<string name="grades_semester2_header">Semestr 2</string>
|
||||
<string name="grades_semester_average_format">semestr %d: %s</string>
|
||||
@ -1195,4 +1195,42 @@
|
||||
<string name="hint_save_in_calendar">Zapisz do kalendarza</string>
|
||||
<string name="hint_edit_event">Edytuj wydarzenie</string>
|
||||
<string name="hint_go_to_timetable">Idź do planu lekcji</string>
|
||||
<string name="today">dzisiaj</string>
|
||||
<string name="tomorrow">jutro</string>
|
||||
<string name="tag_key_model">model</string>
|
||||
<string name="tag_key_view_type">viewType</string>
|
||||
<string name="tag_key_position">position</string>
|
||||
<string name="grades_semester_format">Semestr %d</string>
|
||||
<string name="grades_preview_other_semester">Semestr %d</string>
|
||||
|
||||
<!--<string name="grades_average_value_point_format">%s/%s (%s%%)</string>-->
|
||||
<string name="grades_average_value_point_format">%3$s%%</string>
|
||||
<string name="grades_average_value_sum_format">%s pkt</string>
|
||||
|
||||
<string name="grades_average_normal_format">średnia: %s</string>
|
||||
<string name="grades_average_sum_format">suma: %s</string>
|
||||
<string name="grades_average_point_format">punkty: %s</string>
|
||||
|
||||
<string name="grades_average_semester_format">sem. %1$d: %2$s</string>
|
||||
<string name="grades_average_year_format">roczna: %2$s</string>
|
||||
<string name="grades_year_summary_format">Cały rok: %s • %s</string>
|
||||
<string name="grades_average_no">brak średniej</string>
|
||||
<string name="grades_stats_semester_1">semestr 1</string>
|
||||
<string name="grades_stats_semester_2">semestr 2</string>
|
||||
<string name="grades_stats_yearly">całoroczna</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_title">Statystyka ocen</string>
|
||||
<string name="grades_stats_normal">Średnia zwykłych ocen</string>
|
||||
<string name="grades_stats_point">Średnia przedmiotów punktowych</string>
|
||||
<string name="grades_stats_no_data">Zbyt mało danych do wyliczenia średniej.</string>
|
||||
<string name="grades_stats_expected">*przewidywana średnia</string>
|
||||
<string name="grades_stats_from_proposed">*z ocen proponowanych\nPrzewidywana: %s</string>
|
||||
<string name="grades_stats_from_proposed_no_expected">*z ocen proponowanych</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_proposed_avg">Śr. ocen proponowanych:\n%s</string>
|
||||
<string name="grades_stats_help_title">Obliczanie średniej wszystkich przedmiotów</string>
|
||||
<string name="grades_stats_help_text">Ocena przewidywana z danego przedmiotu jest obliczana na podstawie aktualnej średniej ważonej.\n\nOcena jest liczbą całkowitą, jaką wystawił by nauczyciel bazując na średniej. Liczba zaokrąglona jest w górę jeśli część po przecinku przekroczy ,75.\nPrzykładowo: średnie 3,75 jak również 4,74 dają w wyniku ocenę dobrą (4).\n\nŚrednia przewidywana ze wszystkich przedmiotów obejmuje obliczone w ten sposób oceny końcowe.</string>
|
||||
<string name="grades_stats_custom_value_notice">Została ustawiona własna wartość plusa/minusa. Jeśli uważasz, że średnia się nie zgadza, kliknij Konfiguruj.</string>
|
||||
<string name="configure">Konfiguruj</string>
|
||||
</resources>
|
||||
|
Loading…
x
Reference in New Issue
Block a user