forked from github/wulkanowy-mirror
Add points to class grades statistics (#512)
This commit is contained in:

committed by
Rafał Borcz

parent
d411d86355
commit
f9474af39e
@ -85,6 +85,10 @@ internal class RepositoryModule {
|
||||
@Provides
|
||||
fun provideGradeStatisticsDao(database: AppDatabase) = database.gradeStatistics
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
fun provideGradePointsStatisticsDao(database: AppDatabase) = database.gradePointsStatistics
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
fun provideMessagesDao(database: AppDatabase) = database.messagesDao
|
||||
|
@ -11,6 +11,7 @@ import io.github.wulkanowy.data.db.dao.AttendanceSummaryDao
|
||||
import io.github.wulkanowy.data.db.dao.CompletedLessonsDao
|
||||
import io.github.wulkanowy.data.db.dao.ExamDao
|
||||
import io.github.wulkanowy.data.db.dao.GradeDao
|
||||
import io.github.wulkanowy.data.db.dao.GradePointsStatisticsDao
|
||||
import io.github.wulkanowy.data.db.dao.GradeStatisticsDao
|
||||
import io.github.wulkanowy.data.db.dao.GradeSummaryDao
|
||||
import io.github.wulkanowy.data.db.dao.HomeworkDao
|
||||
@ -30,6 +31,7 @@ import io.github.wulkanowy.data.db.entities.AttendanceSummary
|
||||
import io.github.wulkanowy.data.db.entities.CompletedLesson
|
||||
import io.github.wulkanowy.data.db.entities.Exam
|
||||
import io.github.wulkanowy.data.db.entities.Grade
|
||||
import io.github.wulkanowy.data.db.entities.GradePointsStatistics
|
||||
import io.github.wulkanowy.data.db.entities.GradeStatistics
|
||||
import io.github.wulkanowy.data.db.entities.GradeSummary
|
||||
import io.github.wulkanowy.data.db.entities.Homework
|
||||
@ -51,6 +53,7 @@ import io.github.wulkanowy.data.db.migrations.Migration13
|
||||
import io.github.wulkanowy.data.db.migrations.Migration14
|
||||
import io.github.wulkanowy.data.db.migrations.Migration15
|
||||
import io.github.wulkanowy.data.db.migrations.Migration16
|
||||
import io.github.wulkanowy.data.db.migrations.Migration17
|
||||
import io.github.wulkanowy.data.db.migrations.Migration2
|
||||
import io.github.wulkanowy.data.db.migrations.Migration3
|
||||
import io.github.wulkanowy.data.db.migrations.Migration4
|
||||
@ -73,6 +76,7 @@ import javax.inject.Singleton
|
||||
Grade::class,
|
||||
GradeSummary::class,
|
||||
GradeStatistics::class,
|
||||
GradePointsStatistics::class,
|
||||
Message::class,
|
||||
Note::class,
|
||||
Homework::class,
|
||||
@ -91,7 +95,7 @@ import javax.inject.Singleton
|
||||
abstract class AppDatabase : RoomDatabase() {
|
||||
|
||||
companion object {
|
||||
const val VERSION_SCHEMA = 16
|
||||
const val VERSION_SCHEMA = 17
|
||||
|
||||
fun newInstance(context: Context): AppDatabase {
|
||||
return Room.databaseBuilder(context, AppDatabase::class.java, "wulkanowy_database")
|
||||
@ -113,7 +117,8 @@ abstract class AppDatabase : RoomDatabase() {
|
||||
Migration13(),
|
||||
Migration14(),
|
||||
Migration15(),
|
||||
Migration16()
|
||||
Migration16(),
|
||||
Migration17()
|
||||
)
|
||||
.build()
|
||||
}
|
||||
@ -137,6 +142,8 @@ abstract class AppDatabase : RoomDatabase() {
|
||||
|
||||
abstract val gradeStatistics: GradeStatisticsDao
|
||||
|
||||
abstract val gradePointsStatistics: GradePointsStatisticsDao
|
||||
|
||||
abstract val messagesDao: MessagesDao
|
||||
|
||||
abstract val noteDao: NoteDao
|
||||
|
@ -0,0 +1,26 @@
|
||||
package io.github.wulkanowy.data.db.dao
|
||||
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Delete
|
||||
import androidx.room.Insert
|
||||
import androidx.room.Query
|
||||
import io.github.wulkanowy.data.db.entities.GradePointsStatistics
|
||||
import io.reactivex.Maybe
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Singleton
|
||||
@Dao
|
||||
interface GradePointsStatisticsDao {
|
||||
|
||||
@Insert
|
||||
fun insertAll(gradesStatistics: List<GradePointsStatistics>)
|
||||
|
||||
@Delete
|
||||
fun deleteAll(gradesStatistics: List<GradePointsStatistics>)
|
||||
|
||||
@Query("SELECT * FROM GradesPointsStatistics WHERE student_id = :studentId AND semester_id = :semesterId AND subject = :subjectName")
|
||||
fun loadSubject(semesterId: Int, studentId: Int, subjectName: String): Maybe<GradePointsStatistics>
|
||||
|
||||
@Query("SELECT * FROM GradesPointsStatistics WHERE student_id = :studentId AND semester_id = :semesterId")
|
||||
fun loadAll(semesterId: Int, studentId: Int): Maybe<List<GradePointsStatistics>>
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
package io.github.wulkanowy.data.db.entities
|
||||
|
||||
import androidx.room.ColumnInfo
|
||||
import androidx.room.Entity
|
||||
import androidx.room.PrimaryKey
|
||||
|
||||
@Entity(tableName = "GradesPointsStatistics")
|
||||
data class GradePointsStatistics(
|
||||
|
||||
@ColumnInfo(name = "student_id")
|
||||
val studentId: Int,
|
||||
|
||||
@ColumnInfo(name = "semester_id")
|
||||
val semesterId: Int,
|
||||
|
||||
val subject: String,
|
||||
|
||||
val others: Double,
|
||||
|
||||
val student: Double
|
||||
) {
|
||||
@PrimaryKey(autoGenerate = true)
|
||||
var id: Long = 0
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
package io.github.wulkanowy.data.db.migrations
|
||||
|
||||
import androidx.room.migration.Migration
|
||||
import androidx.sqlite.db.SupportSQLiteDatabase
|
||||
|
||||
class Migration17 : Migration(16, 17) {
|
||||
|
||||
override fun migrate(database: SupportSQLiteDatabase) {
|
||||
database.execSQL("""
|
||||
CREATE TABLE IF NOT EXISTS GradesPointsStatistics(
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
|
||||
student_id INTEGER NOT NULL,
|
||||
semester_id INTEGER NOT NULL,
|
||||
subject TEXT NOT NULL,
|
||||
others REAL NOT NULL,
|
||||
student REAL NOT NULL
|
||||
)
|
||||
""")
|
||||
}
|
||||
}
|
@ -1,6 +1,8 @@
|
||||
package io.github.wulkanowy.data.repositories.gradestatistics
|
||||
|
||||
import io.github.wulkanowy.data.db.dao.GradePointsStatisticsDao
|
||||
import io.github.wulkanowy.data.db.dao.GradeStatisticsDao
|
||||
import io.github.wulkanowy.data.db.entities.GradePointsStatistics
|
||||
import io.github.wulkanowy.data.db.entities.GradeStatistics
|
||||
import io.github.wulkanowy.data.db.entities.Semester
|
||||
import io.reactivex.Maybe
|
||||
@ -8,27 +10,57 @@ import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Singleton
|
||||
class GradeStatisticsLocal @Inject constructor(private val gradeStatisticsDb: GradeStatisticsDao) {
|
||||
class GradeStatisticsLocal @Inject constructor(
|
||||
private val gradeStatisticsDb: GradeStatisticsDao,
|
||||
private val gradePointsStatisticsDb: GradePointsStatisticsDao
|
||||
) {
|
||||
|
||||
fun getGradesStatistics(semester: Semester, isSemester: Boolean): Maybe<List<GradeStatistics>> {
|
||||
return gradeStatisticsDb.loadAll(semester.semesterId, semester.studentId, isSemester)
|
||||
.filter { !it.isEmpty() }
|
||||
return gradeStatisticsDb.loadAll(semester.semesterId, semester.studentId, isSemester).filter { it.isNotEmpty() }
|
||||
}
|
||||
|
||||
fun getGradesPointsStatistics(semester: Semester): Maybe<List<GradePointsStatistics>> {
|
||||
return gradePointsStatisticsDb.loadAll(semester.semesterId, semester.studentId).filter { it.isNotEmpty() }
|
||||
}
|
||||
|
||||
fun getGradesStatistics(semester: Semester, isSemester: Boolean, subjectName: String): Maybe<List<GradeStatistics>> {
|
||||
return (if ("Wszystkie" == subjectName) gradeStatisticsDb.loadAll(semester.semesterId, semester.studentId, isSemester).map { list ->
|
||||
list.groupBy { it.grade }.map {
|
||||
GradeStatistics(semester.studentId, semester.semesterId, subjectName, it.key, it.value.fold(0) { acc, e -> acc + e.amount }, false)
|
||||
return when (subjectName) {
|
||||
"Wszystkie" -> gradeStatisticsDb.loadAll(semester.semesterId, semester.studentId, isSemester).map { list ->
|
||||
list.groupBy { it.grade }.map {
|
||||
GradeStatistics(semester.studentId, semester.semesterId, subjectName, it.key,
|
||||
it.value.fold(0) { acc, e -> acc + e.amount }, false)
|
||||
}
|
||||
}
|
||||
else -> gradeStatisticsDb.loadSubject(semester.semesterId, semester.studentId, subjectName, isSemester)
|
||||
}.filter { it.isNotEmpty() }
|
||||
}
|
||||
|
||||
fun getGradesPointsStatistics(semester: Semester, subjectName: String): Maybe<GradePointsStatistics> {
|
||||
return when (subjectName) {
|
||||
"Wszystkie" -> gradePointsStatisticsDb.loadAll(semester.semesterId, semester.studentId).flatMap { list ->
|
||||
if (list.isEmpty()) return@flatMap Maybe.empty<GradePointsStatistics>()
|
||||
Maybe.just(GradePointsStatistics(semester.studentId, semester.semesterId, subjectName,
|
||||
list.fold(.0) { acc, e -> acc + e.others },
|
||||
list.fold(.0) { acc, e -> acc + e.student })
|
||||
)
|
||||
}
|
||||
else -> gradePointsStatisticsDb.loadSubject(semester.semesterId, semester.studentId, subjectName)
|
||||
}
|
||||
else gradeStatisticsDb.loadSubject(semester.semesterId, semester.studentId, subjectName, isSemester)).filter { !it.isEmpty() }
|
||||
}
|
||||
|
||||
fun saveGradesStatistics(gradesStatistics: List<GradeStatistics>) {
|
||||
gradeStatisticsDb.insertAll(gradesStatistics)
|
||||
}
|
||||
|
||||
fun saveGradesPointsStatistics(gradePointsStatistics: List<GradePointsStatistics>) {
|
||||
gradePointsStatisticsDb.insertAll(gradePointsStatistics)
|
||||
}
|
||||
|
||||
fun deleteGradesStatistics(gradesStatistics: List<GradeStatistics>) {
|
||||
gradeStatisticsDb.deleteAll(gradesStatistics)
|
||||
}
|
||||
|
||||
fun deleteGradesPointsStatistics(gradesPointsStatistics: List<GradePointsStatistics>) {
|
||||
gradePointsStatisticsDb.deleteAll(gradesPointsStatistics)
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package io.github.wulkanowy.data.repositories.gradestatistics
|
||||
|
||||
import io.github.wulkanowy.api.Api
|
||||
import io.github.wulkanowy.data.db.entities.GradePointsStatistics
|
||||
import io.github.wulkanowy.data.db.entities.GradeStatistics
|
||||
import io.github.wulkanowy.data.db.entities.Semester
|
||||
import io.reactivex.Single
|
||||
@ -12,7 +13,10 @@ class GradeStatisticsRemote @Inject constructor(private val api: Api) {
|
||||
|
||||
fun getGradeStatistics(semester: Semester, isSemester: Boolean): Single<List<GradeStatistics>> {
|
||||
return Single.just(api.apply { diaryId = semester.diaryId })
|
||||
.flatMap { it.getGradesStatistics(semester.semesterId, isSemester) }
|
||||
.flatMap {
|
||||
if (isSemester) it.getGradesAnnualStatistics(semester.semesterId)
|
||||
else it.getGradesPartialStatistics(semester.semesterId)
|
||||
}
|
||||
.map { gradeStatistics ->
|
||||
gradeStatistics.map {
|
||||
GradeStatistics(
|
||||
@ -26,4 +30,20 @@ class GradeStatisticsRemote @Inject constructor(private val api: Api) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun getGradePointsStatistics(semester: Semester): Single<List<GradePointsStatistics>> {
|
||||
return Single.just(api.apply { diaryId = semester.diaryId })
|
||||
.flatMap { it.getGradesPointsStatistics(semester.semesterId) }
|
||||
.map { gradePointsStatistics ->
|
||||
gradePointsStatistics.map {
|
||||
GradePointsStatistics(
|
||||
semesterId = semester.semesterId,
|
||||
studentId = semester.studentId,
|
||||
subject = it.subject,
|
||||
others = it.others,
|
||||
student = it.student
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,9 +2,11 @@ package io.github.wulkanowy.data.repositories.gradestatistics
|
||||
|
||||
import com.github.pwittchen.reactivenetwork.library.rx2.ReactiveNetwork
|
||||
import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.InternetObservingSettings
|
||||
import io.github.wulkanowy.data.db.entities.GradePointsStatistics
|
||||
import io.github.wulkanowy.data.db.entities.GradeStatistics
|
||||
import io.github.wulkanowy.data.db.entities.Semester
|
||||
import io.github.wulkanowy.utils.uniqueSubtract
|
||||
import io.reactivex.Maybe
|
||||
import io.reactivex.Single
|
||||
import java.net.UnknownHostException
|
||||
import javax.inject.Inject
|
||||
@ -31,4 +33,19 @@ class GradeStatisticsRepository @Inject constructor(
|
||||
}
|
||||
}.flatMap { local.getGradesStatistics(semester, isSemester, subjectName).toSingle(emptyList()) })
|
||||
}
|
||||
|
||||
fun getGradesPointsStatistics(semester: Semester, subjectName: String, forceRefresh: Boolean): Maybe<GradePointsStatistics> {
|
||||
return local.getGradesPointsStatistics(semester, subjectName).filter { !forceRefresh }
|
||||
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
|
||||
.flatMapMaybe {
|
||||
if (it) remote.getGradePointsStatistics(semester).toMaybe()
|
||||
else Maybe.error(UnknownHostException())
|
||||
}.flatMap { new ->
|
||||
local.getGradesPointsStatistics(semester).defaultIfEmpty(emptyList())
|
||||
.doOnSuccess { old ->
|
||||
local.deleteGradesPointsStatistics(old.uniqueSubtract(new))
|
||||
local.saveGradesPointsStatistics(new.uniqueSubtract(old))
|
||||
}
|
||||
}.flatMap { local.getGradesPointsStatistics(semester, subjectName) })
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
package io.github.wulkanowy.ui.modules.grade.statistics
|
||||
|
||||
import android.graphics.Color
|
||||
import android.graphics.Color.WHITE
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
@ -10,11 +11,15 @@ import android.widget.TextView
|
||||
import androidx.core.content.ContextCompat
|
||||
import com.github.mikephil.charting.components.Legend
|
||||
import com.github.mikephil.charting.components.LegendEntry
|
||||
import com.github.mikephil.charting.data.BarData
|
||||
import com.github.mikephil.charting.data.BarDataSet
|
||||
import com.github.mikephil.charting.data.BarEntry
|
||||
import com.github.mikephil.charting.data.PieData
|
||||
import com.github.mikephil.charting.data.PieDataSet
|
||||
import com.github.mikephil.charting.data.PieEntry
|
||||
import com.github.mikephil.charting.formatter.ValueFormatter
|
||||
import io.github.wulkanowy.R
|
||||
import io.github.wulkanowy.data.db.entities.GradePointsStatistics
|
||||
import io.github.wulkanowy.data.db.entities.GradeStatistics
|
||||
import io.github.wulkanowy.ui.base.BaseFragment
|
||||
import io.github.wulkanowy.ui.modules.grade.GradeFragment
|
||||
@ -38,7 +43,9 @@ class GradeStatisticsFragment : BaseFragment(), GradeStatisticsView, GradeView.G
|
||||
fun newInstance() = GradeStatisticsFragment()
|
||||
}
|
||||
|
||||
override val isViewEmpty get() = gradeStatisticsChart.isEmpty
|
||||
override val isPieViewEmpty get() = gradeStatisticsChart.isEmpty
|
||||
|
||||
override val isBarViewEmpty get() = gradeStatisticsChartPoints.isEmpty
|
||||
|
||||
private lateinit var gradeColors: List<Pair<Int, Int>>
|
||||
|
||||
@ -60,6 +67,11 @@ class GradeStatisticsFragment : BaseFragment(), GradeStatisticsView, GradeView.G
|
||||
1 to R.color.grade_material_one
|
||||
)
|
||||
|
||||
private val gradePointsColors = listOf(
|
||||
Color.parseColor("#37c69c"),
|
||||
Color.parseColor("#d8b12a")
|
||||
)
|
||||
|
||||
private val gradeLabels = listOf(
|
||||
"6, 6-", "5, 5-, 5+", "4, 4-, 4+", "3, 3-, 3+", "2, 2-, 2+", "1, 1+"
|
||||
)
|
||||
@ -70,8 +82,8 @@ class GradeStatisticsFragment : BaseFragment(), GradeStatisticsView, GradeView.G
|
||||
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
super.onActivityCreated(savedInstanceState)
|
||||
messageContainer = gradeStatisticsChart
|
||||
presenter.onAttachView(this, savedInstanceState?.getBoolean(SAVED_CHART_TYPE))
|
||||
messageContainer = gradeStatisticsSwipe
|
||||
presenter.onAttachView(this, savedInstanceState?.getSerializable(SAVED_CHART_TYPE) as? ViewType)
|
||||
}
|
||||
|
||||
override fun initView() {
|
||||
@ -84,6 +96,13 @@ class GradeStatisticsFragment : BaseFragment(), GradeStatisticsView, GradeView.G
|
||||
legend.textColor = context.getThemeAttrColor(android.R.attr.textColorPrimary)
|
||||
}
|
||||
|
||||
with(gradeStatisticsChartPoints) {
|
||||
description.isEnabled = false
|
||||
|
||||
animateXY(1000, 1000)
|
||||
legend.textColor = context.getThemeAttrColor(android.R.attr.textColorPrimary)
|
||||
}
|
||||
|
||||
subjectsAdapter = ArrayAdapter(requireContext(), android.R.layout.simple_spinner_item, mutableListOf())
|
||||
subjectsAdapter.setDropDownViewResource(R.layout.item_attendance_summary_subject)
|
||||
|
||||
@ -105,23 +124,25 @@ class GradeStatisticsFragment : BaseFragment(), GradeStatisticsView, GradeView.G
|
||||
}
|
||||
}
|
||||
|
||||
override fun updateData(items: List<GradeStatistics>, theme: String) {
|
||||
override fun updatePieData(items: List<GradeStatistics>, theme: String) {
|
||||
gradeColors = when (theme) {
|
||||
"vulcan" -> vulcanGradeColors
|
||||
else -> materialGradeColors
|
||||
}
|
||||
|
||||
gradeStatisticsChart.run {
|
||||
data = PieData(PieDataSet(items.map {
|
||||
PieEntry(it.amount.toFloat(), it.grade.toString())
|
||||
}, "Legenda").apply {
|
||||
valueTextSize = 12f
|
||||
sliceSpace = 1f
|
||||
valueTextColor = WHITE
|
||||
setColors(items.map {
|
||||
gradeColors.single { color -> color.first == it.grade }.second
|
||||
}.toIntArray(), context)
|
||||
}).apply {
|
||||
val dataset = PieDataSet(items.map {
|
||||
PieEntry(it.amount.toFloat(), it.grade.toString())
|
||||
}, "Legenda").apply {
|
||||
valueTextSize = 12f
|
||||
sliceSpace = 1f
|
||||
valueTextColor = WHITE
|
||||
setColors(items.map {
|
||||
gradeColors.single { color -> color.first == it.grade }.second
|
||||
}.toIntArray(), context)
|
||||
}
|
||||
|
||||
with(gradeStatisticsChart) {
|
||||
data = PieData(dataset).apply {
|
||||
setTouchEnabled(false)
|
||||
setValueFormatter(object : ValueFormatter() {
|
||||
override fun getPieLabel(value: Float, pieEntry: PieEntry): String {
|
||||
@ -144,6 +165,47 @@ class GradeStatisticsFragment : BaseFragment(), GradeStatisticsView, GradeView.G
|
||||
}
|
||||
}
|
||||
|
||||
override fun updateBarData(item: GradePointsStatistics) {
|
||||
val dataset = BarDataSet(listOf(
|
||||
BarEntry(1f, item.others.toFloat()),
|
||||
BarEntry(2f, item.student.toFloat())
|
||||
), "Legenda").apply {
|
||||
valueTextSize = 12f
|
||||
valueTextColor = requireContext().getThemeAttrColor(android.R.attr.textColorPrimary)
|
||||
valueFormatter = object : ValueFormatter() {
|
||||
override fun getBarLabel(barEntry: BarEntry) = "${barEntry.y}%"
|
||||
}
|
||||
colors = gradePointsColors
|
||||
}
|
||||
|
||||
with(gradeStatisticsChartPoints) {
|
||||
data = BarData(dataset).apply {
|
||||
barWidth = 0.5f
|
||||
setFitBars(true)
|
||||
}
|
||||
setTouchEnabled(false)
|
||||
xAxis.setDrawLabels(false)
|
||||
xAxis.setDrawGridLines(false)
|
||||
requireContext().getThemeAttrColor(android.R.attr.textColorPrimary).let {
|
||||
axisLeft.textColor = it
|
||||
axisRight.textColor = it
|
||||
}
|
||||
legend.setCustom(listOf(
|
||||
LegendEntry().apply {
|
||||
label = "Średnia klasy"
|
||||
formColor = gradePointsColors[0]
|
||||
form = Legend.LegendForm.SQUARE
|
||||
},
|
||||
LegendEntry().apply {
|
||||
label = "Uczeń"
|
||||
formColor = gradePointsColors[1]
|
||||
form = Legend.LegendForm.SQUARE
|
||||
}
|
||||
))
|
||||
invalidate()
|
||||
}
|
||||
}
|
||||
|
||||
override fun showSubjects(show: Boolean) {
|
||||
gradeStatisticsSubjectsContainer.visibility = if (show) View.VISIBLE else View.INVISIBLE
|
||||
gradeStatisticsTypeSwitch.visibility = if (show) View.VISIBLE else View.INVISIBLE
|
||||
@ -151,12 +213,17 @@ class GradeStatisticsFragment : BaseFragment(), GradeStatisticsView, GradeView.G
|
||||
|
||||
override fun clearView() {
|
||||
gradeStatisticsChart.clear()
|
||||
gradeStatisticsChartPoints.clear()
|
||||
}
|
||||
|
||||
override fun showContent(show: Boolean) {
|
||||
override fun showPieContent(show: Boolean) {
|
||||
gradeStatisticsChart.visibility = if (show) View.VISIBLE else View.GONE
|
||||
}
|
||||
|
||||
override fun showBarContent(show: Boolean) {
|
||||
gradeStatisticsChartPoints.visibility = if (show) View.VISIBLE else View.GONE
|
||||
}
|
||||
|
||||
override fun showEmpty(show: Boolean) {
|
||||
gradeStatisticsEmpty.visibility = if (show) View.VISIBLE else View.INVISIBLE
|
||||
}
|
||||
@ -196,13 +263,17 @@ class GradeStatisticsFragment : BaseFragment(), GradeStatisticsView, GradeView.G
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
gradeStatisticsTypeSwitch.setOnCheckedChangeListener { _, checkedId ->
|
||||
presenter.onTypeChange(checkedId == R.id.gradeStatisticsTypeSemester)
|
||||
presenter.onTypeChange(when (checkedId) {
|
||||
R.id.gradeStatisticsTypeSemester -> ViewType.SEMESTER
|
||||
R.id.gradeStatisticsTypePartial -> ViewType.PARTIAL
|
||||
else -> ViewType.POINTS
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
super.onSaveInstanceState(outState)
|
||||
outState.putBoolean(SAVED_CHART_TYPE, presenter.currentIsSemester)
|
||||
outState.putSerializable(SAVED_CHART_TYPE, presenter.currentType)
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
|
@ -30,19 +30,19 @@ class GradeStatisticsPresenter @Inject constructor(
|
||||
|
||||
private var currentSubjectName: String = "Wszystkie"
|
||||
|
||||
var currentIsSemester = false
|
||||
var currentType: ViewType = ViewType.PARTIAL
|
||||
private set
|
||||
|
||||
fun onAttachView(view: GradeStatisticsView, isSemester: Boolean?) {
|
||||
fun onAttachView(view: GradeStatisticsView, type: ViewType?) {
|
||||
super.onAttachView(view)
|
||||
currentIsSemester = isSemester ?: false
|
||||
currentType = type ?: ViewType.PARTIAL
|
||||
view.initView()
|
||||
}
|
||||
|
||||
fun onParentViewLoadData(semesterId: Int, forceRefresh: Boolean) {
|
||||
currentSemesterId = semesterId
|
||||
loadSubjects()
|
||||
loadData(semesterId, currentSubjectName, currentIsSemester, forceRefresh)
|
||||
loadDataByType(semesterId, currentSubjectName, currentType, forceRefresh)
|
||||
}
|
||||
|
||||
fun onParentViewChangeSemester() {
|
||||
@ -50,7 +50,7 @@ class GradeStatisticsPresenter @Inject constructor(
|
||||
showProgress(true)
|
||||
enableSwipe(false)
|
||||
showRefresh(false)
|
||||
showContent(false)
|
||||
showBarContent(false)
|
||||
showEmpty(false)
|
||||
clearView()
|
||||
}
|
||||
@ -65,28 +65,30 @@ class GradeStatisticsPresenter @Inject constructor(
|
||||
fun onSubjectSelected(name: String?) {
|
||||
Timber.i("Select grade stats subject $name")
|
||||
view?.run {
|
||||
showContent(false)
|
||||
showBarContent(false)
|
||||
showPieContent(false)
|
||||
showProgress(true)
|
||||
enableSwipe(false)
|
||||
showEmpty(false)
|
||||
clearView()
|
||||
}
|
||||
(subjects.singleOrNull { it.name == name }?.name)?.let {
|
||||
if (it != currentSubjectName) loadData(currentSemesterId, it, currentIsSemester)
|
||||
if (it != currentSubjectName) loadDataByType(currentSemesterId, it, currentType)
|
||||
}
|
||||
}
|
||||
|
||||
fun onTypeChange(isSemester: Boolean) {
|
||||
Timber.i("Select grade stats semester: $isSemester")
|
||||
fun onTypeChange(type: ViewType) {
|
||||
Timber.i("Select grade stats semester: $type")
|
||||
disposable.clear()
|
||||
view?.run {
|
||||
showContent(false)
|
||||
showBarContent(false)
|
||||
showPieContent(false)
|
||||
showProgress(true)
|
||||
enableSwipe(false)
|
||||
showEmpty(false)
|
||||
clearView()
|
||||
}
|
||||
loadData(currentSemesterId, currentSubjectName, isSemester)
|
||||
loadDataByType(currentSemesterId, currentSubjectName, type)
|
||||
}
|
||||
|
||||
private fun loadSubjects() {
|
||||
@ -111,10 +113,18 @@ class GradeStatisticsPresenter @Inject constructor(
|
||||
)
|
||||
}
|
||||
|
||||
private fun loadDataByType(semesterId: Int, subjectName: String, type: ViewType, forceRefresh: Boolean = false) {
|
||||
currentSubjectName = subjectName
|
||||
currentType = type
|
||||
when (type) {
|
||||
ViewType.SEMESTER -> loadData(semesterId, subjectName, true, forceRefresh)
|
||||
ViewType.PARTIAL -> loadData(semesterId, subjectName, false, forceRefresh)
|
||||
ViewType.POINTS -> loadPointsData(semesterId, subjectName, forceRefresh)
|
||||
}
|
||||
}
|
||||
|
||||
private fun loadData(semesterId: Int, subjectName: String, isSemester: Boolean, forceRefresh: Boolean = false) {
|
||||
Timber.i("Loading grade stats data started")
|
||||
currentSubjectName = subjectName
|
||||
currentIsSemester = isSemester
|
||||
disposable.add(studentRepository.getCurrentStudent()
|
||||
.flatMap { semesterRepository.getSemesters(it) }
|
||||
.flatMap { gradeStatisticsRepository.getGradesStatistics(it.first { item -> item.semesterId == semesterId }, subjectName, isSemester, forceRefresh) }
|
||||
@ -134,14 +144,53 @@ class GradeStatisticsPresenter @Inject constructor(
|
||||
Timber.i("Loading grade stats result: Success")
|
||||
view?.run {
|
||||
showEmpty(it.isEmpty())
|
||||
showContent(it.isNotEmpty())
|
||||
updateData(it, preferencesRepository.gradeColorTheme)
|
||||
showBarContent(false)
|
||||
showPieContent(it.isNotEmpty())
|
||||
updatePieData(it, preferencesRepository.gradeColorTheme)
|
||||
}
|
||||
analytics.logEvent("load_grade_statistics", "items" to it.size, "force_refresh" to forceRefresh)
|
||||
}) {
|
||||
Timber.e("Loading grade stats result: An exception occurred")
|
||||
view?.run { showEmpty(isViewEmpty) }
|
||||
view?.run { showEmpty(isPieViewEmpty) }
|
||||
errorHandler.dispatch(it)
|
||||
})
|
||||
}
|
||||
|
||||
private fun loadPointsData(semesterId: Int, subjectName: String, forceRefresh: Boolean = false) {
|
||||
Timber.i("Loading grade points stats data started")
|
||||
disposable.add(studentRepository.getCurrentStudent()
|
||||
.flatMap { semesterRepository.getSemesters(it) }
|
||||
.flatMapMaybe { gradeStatisticsRepository.getGradesPointsStatistics(it.first { item -> item.semesterId == semesterId }, subjectName, forceRefresh) }
|
||||
.subscribeOn(schedulers.backgroundThread)
|
||||
.observeOn(schedulers.mainThread)
|
||||
.doFinally {
|
||||
view?.run {
|
||||
showRefresh(false)
|
||||
showProgress(false)
|
||||
enableSwipe(true)
|
||||
notifyParentDataLoaded(semesterId)
|
||||
}
|
||||
}
|
||||
.subscribe({
|
||||
Timber.i("Loading grade points stats result: Success")
|
||||
view?.run {
|
||||
showEmpty(false)
|
||||
showPieContent(false)
|
||||
showBarContent(true)
|
||||
updateBarData(it)
|
||||
}
|
||||
analytics.logEvent("load_grade_points_statistics", "force_refresh" to forceRefresh)
|
||||
}, {
|
||||
Timber.e("Loading grade points stats result: An exception occurred")
|
||||
view?.run { showEmpty(isBarViewEmpty) }
|
||||
errorHandler.dispatch(it)
|
||||
}, {
|
||||
Timber.d("Loading grade points stats result: No point stats found")
|
||||
view?.run {
|
||||
showBarContent(false)
|
||||
showEmpty(true)
|
||||
}
|
||||
})
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -1,17 +1,22 @@
|
||||
package io.github.wulkanowy.ui.modules.grade.statistics
|
||||
|
||||
import io.github.wulkanowy.data.db.entities.GradePointsStatistics
|
||||
import io.github.wulkanowy.data.db.entities.GradeStatistics
|
||||
import io.github.wulkanowy.ui.base.BaseView
|
||||
|
||||
interface GradeStatisticsView : BaseView {
|
||||
|
||||
val isViewEmpty: Boolean
|
||||
val isPieViewEmpty: Boolean
|
||||
|
||||
val isBarViewEmpty: Boolean
|
||||
|
||||
fun initView()
|
||||
|
||||
fun updateSubjects(data: ArrayList<String>)
|
||||
|
||||
fun updateData(items: List<GradeStatistics>, theme: String)
|
||||
fun updatePieData(items: List<GradeStatistics>, theme: String)
|
||||
|
||||
fun updateBarData(item: GradePointsStatistics)
|
||||
|
||||
fun showSubjects(show: Boolean)
|
||||
|
||||
@ -21,7 +26,9 @@ interface GradeStatisticsView : BaseView {
|
||||
|
||||
fun clearView()
|
||||
|
||||
fun showContent(show: Boolean)
|
||||
fun showPieContent(show: Boolean)
|
||||
|
||||
fun showBarContent(show: Boolean)
|
||||
|
||||
fun showEmpty(show: Boolean)
|
||||
|
||||
|
@ -0,0 +1,7 @@
|
||||
package io.github.wulkanowy.ui.modules.grade.statistics
|
||||
|
||||
enum class ViewType {
|
||||
SEMESTER,
|
||||
PARTIAL,
|
||||
POINTS
|
||||
}
|
Reference in New Issue
Block a user