mirror of
https://github.com/wulkanowy/wulkanowy.git
synced 2025-02-21 19:34:44 +01:00
Allow expanding multiple subject' grades at once (#1584)
This commit is contained in:
parent
94fd303f8e
commit
0f800b61f6
@ -193,7 +193,7 @@ abstract class AppDatabase : RoomDatabase() {
|
|||||||
Migration38(),
|
Migration38(),
|
||||||
Migration39(),
|
Migration39(),
|
||||||
Migration40(),
|
Migration40(),
|
||||||
Migration41(),
|
Migration41(sharedPrefProvider),
|
||||||
Migration42()
|
Migration42()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -2,10 +2,20 @@ package io.github.wulkanowy.data.db.migrations
|
|||||||
|
|
||||||
import androidx.room.migration.Migration
|
import androidx.room.migration.Migration
|
||||||
import androidx.sqlite.db.SupportSQLiteDatabase
|
import androidx.sqlite.db.SupportSQLiteDatabase
|
||||||
|
import io.github.wulkanowy.data.db.SharedPrefProvider
|
||||||
|
import io.github.wulkanowy.ui.modules.grade.GradeExpandMode
|
||||||
|
|
||||||
class Migration41 : Migration(40, 41) {
|
class Migration41(private val sharedPrefProvider: SharedPrefProvider) : Migration(40, 41) {
|
||||||
|
|
||||||
override fun migrate(database: SupportSQLiteDatabase) {
|
override fun migrate(database: SupportSQLiteDatabase) {
|
||||||
|
migrateSharedPreferences()
|
||||||
database.execSQL("ALTER TABLE Homework ADD COLUMN is_added_by_user INTEGER NOT NULL DEFAULT 0")
|
database.execSQL("ALTER TABLE Homework ADD COLUMN is_added_by_user INTEGER NOT NULL DEFAULT 0")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun migrateSharedPreferences() {
|
||||||
|
if (sharedPrefProvider.getBoolean("pref_key_expand_grade", false)) {
|
||||||
|
sharedPrefProvider.putString("pref_key_expand_grade_mode", GradeExpandMode.ALWAYS_EXPANDED.value)
|
||||||
|
}
|
||||||
|
sharedPrefProvider.delete("pref_key_expand_grade")
|
||||||
|
}
|
||||||
}
|
}
|
@ -10,6 +10,7 @@ import io.github.wulkanowy.R
|
|||||||
import io.github.wulkanowy.sdk.toLocalDate
|
import io.github.wulkanowy.sdk.toLocalDate
|
||||||
import io.github.wulkanowy.ui.modules.dashboard.DashboardItem
|
import io.github.wulkanowy.ui.modules.dashboard.DashboardItem
|
||||||
import io.github.wulkanowy.ui.modules.grade.GradeAverageMode
|
import io.github.wulkanowy.ui.modules.grade.GradeAverageMode
|
||||||
|
import io.github.wulkanowy.ui.modules.grade.GradeExpandMode
|
||||||
import io.github.wulkanowy.ui.modules.grade.GradeSortingMode
|
import io.github.wulkanowy.ui.modules.grade.GradeSortingMode
|
||||||
import io.github.wulkanowy.utils.toLocalDateTime
|
import io.github.wulkanowy.utils.toLocalDateTime
|
||||||
import io.github.wulkanowy.utils.toTimestamp
|
import io.github.wulkanowy.utils.toTimestamp
|
||||||
@ -19,6 +20,8 @@ import kotlinx.coroutines.flow.map
|
|||||||
import kotlinx.serialization.decodeFromString
|
import kotlinx.serialization.decodeFromString
|
||||||
import kotlinx.serialization.encodeToString
|
import kotlinx.serialization.encodeToString
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
|
import java.lang.ClassCastException
|
||||||
|
import java.lang.IllegalStateException
|
||||||
import java.time.LocalDate
|
import java.time.LocalDate
|
||||||
import java.time.LocalDateTime
|
import java.time.LocalDateTime
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
@ -56,8 +59,13 @@ class PreferencesRepository @Inject constructor(
|
|||||||
R.bool.pref_default_grade_average_force_calc
|
R.bool.pref_default_grade_average_force_calc
|
||||||
)
|
)
|
||||||
|
|
||||||
val isGradeExpandable: Boolean
|
val gradeExpandMode: GradeExpandMode
|
||||||
get() = !getBoolean(R.string.pref_key_expand_grade, R.bool.pref_default_expand_grade)
|
get() = GradeExpandMode.getByValue(
|
||||||
|
getString(
|
||||||
|
R.string.pref_key_expand_grade_mode,
|
||||||
|
R.string.pref_default_expand_grade_mode
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
val showAllSubjectsOnStatisticsList: Boolean
|
val showAllSubjectsOnStatisticsList: Boolean
|
||||||
get() = getBoolean(
|
get() = getBoolean(
|
||||||
@ -265,6 +273,9 @@ class PreferencesRepository @Inject constructor(
|
|||||||
private fun getBoolean(id: String, default: Int) =
|
private fun getBoolean(id: String, default: Int) =
|
||||||
sharedPref.getBoolean(id, context.resources.getBoolean(default))
|
sharedPref.getBoolean(id, context.resources.getBoolean(default))
|
||||||
|
|
||||||
|
private fun getBoolean(id: Int, default: Boolean) =
|
||||||
|
sharedPref.getBoolean(context.getString(id), default)
|
||||||
|
|
||||||
private companion object {
|
private companion object {
|
||||||
|
|
||||||
private const val PREF_KEY_DASHBOARD_ITEMS_POSITION = "dashboard_items_position"
|
private const val PREF_KEY_DASHBOARD_ITEMS_POSITION = "dashboard_items_position"
|
||||||
|
@ -0,0 +1,9 @@
|
|||||||
|
package io.github.wulkanowy.ui.modules.grade
|
||||||
|
|
||||||
|
enum class GradeExpandMode(val value: String) {
|
||||||
|
ONE("one"), UNLIMITED("any"), ALWAYS_EXPANDED("always");
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun getByValue(value: String) = values().firstOrNull { it.value == value } ?: ONE
|
||||||
|
}
|
||||||
|
}
|
@ -5,6 +5,7 @@ import android.content.res.Resources
|
|||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
|
import androidx.core.view.isVisible
|
||||||
import androidx.recyclerview.widget.DiffUtil
|
import androidx.recyclerview.widget.DiffUtil
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import androidx.recyclerview.widget.RecyclerView.NO_POSITION
|
import androidx.recyclerview.widget.RecyclerView.NO_POSITION
|
||||||
@ -13,9 +14,11 @@ import io.github.wulkanowy.data.db.entities.Grade
|
|||||||
import io.github.wulkanowy.databinding.HeaderGradeDetailsBinding
|
import io.github.wulkanowy.databinding.HeaderGradeDetailsBinding
|
||||||
import io.github.wulkanowy.databinding.ItemGradeDetailsBinding
|
import io.github.wulkanowy.databinding.ItemGradeDetailsBinding
|
||||||
import io.github.wulkanowy.ui.base.BaseExpandableAdapter
|
import io.github.wulkanowy.ui.base.BaseExpandableAdapter
|
||||||
|
import io.github.wulkanowy.ui.modules.grade.GradeExpandMode
|
||||||
import io.github.wulkanowy.utils.getBackgroundColor
|
import io.github.wulkanowy.utils.getBackgroundColor
|
||||||
import io.github.wulkanowy.utils.toFormattedString
|
import io.github.wulkanowy.utils.toFormattedString
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
import java.util.BitSet
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class GradeDetailsAdapter @Inject constructor() : BaseExpandableAdapter<RecyclerView.ViewHolder>() {
|
class GradeDetailsAdapter @Inject constructor() : BaseExpandableAdapter<RecyclerView.ViewHolder>() {
|
||||||
@ -24,19 +27,20 @@ class GradeDetailsAdapter @Inject constructor() : BaseExpandableAdapter<Recycler
|
|||||||
|
|
||||||
private var items = mutableListOf<GradeDetailsItem>()
|
private var items = mutableListOf<GradeDetailsItem>()
|
||||||
|
|
||||||
private var expandedPosition = NO_POSITION
|
private val expandedPositions = BitSet(items.size)
|
||||||
|
|
||||||
private var isExpandable = false
|
private var expandMode = GradeExpandMode.ONE
|
||||||
|
|
||||||
var onClickListener: (Grade, position: Int) -> Unit = { _, _ -> }
|
var onClickListener: (Grade, position: Int) -> Unit = { _, _ -> }
|
||||||
|
|
||||||
var colorTheme = ""
|
var colorTheme = ""
|
||||||
|
|
||||||
fun setDataItems(data: List<GradeDetailsItem>, isExpanded: Boolean = isExpandable) {
|
fun setDataItems(data: List<GradeDetailsItem>, expandMode: GradeExpandMode = this.expandMode) {
|
||||||
headers = data.filter { it.viewType == ViewType.HEADER }.toMutableList()
|
headers = data.filter { it.viewType == ViewType.HEADER }.toMutableList()
|
||||||
items = if (isExpanded) headers else data.toMutableList()
|
items =
|
||||||
isExpandable = isExpanded
|
(if (expandMode != GradeExpandMode.ALWAYS_EXPANDED) headers else data).toMutableList()
|
||||||
expandedPosition = NO_POSITION
|
this.expandMode = expandMode
|
||||||
|
expandedPositions.clear()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun updateDetailsItem(position: Int, grade: Grade) {
|
fun updateDetailsItem(position: Int, grade: Grade) {
|
||||||
@ -48,7 +52,7 @@ class GradeDetailsAdapter @Inject constructor() : BaseExpandableAdapter<Recycler
|
|||||||
val candidates = headers.filter { (it.value as GradeDetailsHeader).subject == subject }
|
val candidates = headers.filter { (it.value as GradeDetailsHeader).subject == subject }
|
||||||
|
|
||||||
if (candidates.size > 1) {
|
if (candidates.size > 1) {
|
||||||
Timber.e("Header with subject $subject found ${candidates.size} times! Expanded: $expandedPosition. Items: $candidates")
|
Timber.e("Header with subject $subject found ${candidates.size} times! Expanded: $expandedPositions. Items: $candidates")
|
||||||
}
|
}
|
||||||
|
|
||||||
return candidates.first()
|
return candidates.first()
|
||||||
@ -64,9 +68,9 @@ class GradeDetailsAdapter @Inject constructor() : BaseExpandableAdapter<Recycler
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun collapseAll() {
|
fun collapseAll() {
|
||||||
if (expandedPosition != -1) {
|
if (!expandedPositions.isEmpty) {
|
||||||
refreshList(headers)
|
refreshList(headers.toMutableList())
|
||||||
expandedPosition = NO_POSITION
|
expandedPositions.clear()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,8 +90,12 @@ class GradeDetailsAdapter @Inject constructor() : BaseExpandableAdapter<Recycler
|
|||||||
val inflater = LayoutInflater.from(parent.context)
|
val inflater = LayoutInflater.from(parent.context)
|
||||||
|
|
||||||
return when (viewType) {
|
return when (viewType) {
|
||||||
ViewType.HEADER.id -> HeaderViewHolder(HeaderGradeDetailsBinding.inflate(inflater, parent, false))
|
ViewType.HEADER.id -> HeaderViewHolder(
|
||||||
ViewType.ITEM.id -> ItemViewHolder(ItemGradeDetailsBinding.inflate(inflater, parent, false))
|
HeaderGradeDetailsBinding.inflate(inflater, parent, false)
|
||||||
|
)
|
||||||
|
ViewType.ITEM.id -> ItemViewHolder(
|
||||||
|
ItemGradeDetailsBinding.inflate(inflater, parent, false)
|
||||||
|
)
|
||||||
else -> throw IllegalStateException()
|
else -> throw IllegalStateException()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -106,46 +114,91 @@ class GradeDetailsAdapter @Inject constructor() : BaseExpandableAdapter<Recycler
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun bindHeaderViewHolder(holder: HeaderViewHolder, header: GradeDetailsHeader, position: Int) {
|
private fun bindHeaderViewHolder(
|
||||||
val headerPosition = headers.indexOf(items[position])
|
holder: HeaderViewHolder,
|
||||||
val adapterPosition = holder.bindingAdapterPosition
|
header: GradeDetailsHeader,
|
||||||
|
position: Int
|
||||||
|
) {
|
||||||
|
val context = holder.binding.root.context
|
||||||
|
val item = items[position]
|
||||||
|
val headerPosition = headers.indexOf(item)
|
||||||
|
|
||||||
with(holder.binding) {
|
with(holder.binding) {
|
||||||
gradeHeaderDivider.visibility = if (adapterPosition == 0) View.GONE else View.VISIBLE
|
gradeHeaderDivider.isVisible = holder.bindingAdapterPosition != 0
|
||||||
with(gradeHeaderSubject) {
|
with(gradeHeaderSubject) {
|
||||||
text = header.subject
|
text = header.subject
|
||||||
maxLines = if (headerPosition == expandedPosition) 2 else 1
|
maxLines = if (expandedPositions[headerPosition]) 2 else 1
|
||||||
}
|
}
|
||||||
gradeHeaderAverage.text = formatAverage(header.average, root.context.resources)
|
gradeHeaderAverage.text = formatAverage(header.average, root.context.resources)
|
||||||
gradeHeaderPointsSum.text = root.context.getString(R.string.grade_points_sum, header.pointsSum)
|
gradeHeaderPointsSum.text =
|
||||||
gradeHeaderPointsSum.visibility = if (!header.pointsSum.isNullOrEmpty()) View.VISIBLE else View.GONE
|
context.getString(R.string.grade_points_sum, header.pointsSum)
|
||||||
gradeHeaderNumber.text = root.context.resources.getQuantityString(R.plurals.grade_number_item, header.grades.size, header.grades.size)
|
gradeHeaderPointsSum.isVisible = !header.pointsSum.isNullOrEmpty()
|
||||||
gradeHeaderNote.visibility = if (header.newGrades > 0) View.VISIBLE else View.GONE
|
gradeHeaderNumber.text = context.resources.getQuantityString(
|
||||||
if (header.newGrades > 0) gradeHeaderNote.text = header.newGrades.toString(10)
|
R.plurals.grade_number_item,
|
||||||
|
header.grades.size,
|
||||||
|
header.grades.size
|
||||||
|
)
|
||||||
|
gradeHeaderNote.isVisible = header.newGrades > 0
|
||||||
|
|
||||||
gradeHeaderContainer.isEnabled = isExpandable
|
if (header.newGrades > 0) {
|
||||||
|
gradeHeaderNote.text = header.newGrades.toString()
|
||||||
|
}
|
||||||
|
|
||||||
|
gradeHeaderContainer.isEnabled = expandMode != GradeExpandMode.ALWAYS_EXPANDED
|
||||||
gradeHeaderContainer.setOnClickListener {
|
gradeHeaderContainer.setOnClickListener {
|
||||||
expandedPosition = if (expandedPosition == adapterPosition) -1 else adapterPosition
|
expandGradeHeader(headerPosition, header, holder)
|
||||||
|
|
||||||
if (expandedPosition != NO_POSITION) {
|
|
||||||
refreshList(headers.toMutableList().apply {
|
|
||||||
addAll(headerPosition + 1, header.grades)
|
|
||||||
})
|
|
||||||
scrollToHeaderWithSubItems(headerPosition, header.grades.size)
|
|
||||||
} else {
|
|
||||||
refreshList(headers)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun formatAverage(average: Double?, resources: Resources): String {
|
private fun expandGradeHeader(
|
||||||
return if (average == null || average == .0) resources.getString(R.string.grade_no_average)
|
headerPosition: Int,
|
||||||
else resources.getString(R.string.grade_average, average)
|
header: GradeDetailsHeader,
|
||||||
|
holder: HeaderViewHolder
|
||||||
|
) {
|
||||||
|
if (expandMode == GradeExpandMode.ONE) {
|
||||||
|
val isHeaderExpanded = expandedPositions[headerPosition]
|
||||||
|
|
||||||
|
expandedPositions.clear()
|
||||||
|
|
||||||
|
if (!isHeaderExpanded) {
|
||||||
|
val updatedItemList = headers.toMutableList()
|
||||||
|
.apply { addAll(headerPosition + 1, header.grades) }
|
||||||
|
|
||||||
|
expandedPositions.set(headerPosition)
|
||||||
|
refreshList(updatedItemList)
|
||||||
|
scrollToHeaderWithSubItems(headerPosition, header.grades.size)
|
||||||
|
} else {
|
||||||
|
refreshList(headers.toMutableList())
|
||||||
|
}
|
||||||
|
} else if (expandMode == GradeExpandMode.UNLIMITED) {
|
||||||
|
val headerAdapterPosition = holder.bindingAdapterPosition
|
||||||
|
val isHeaderExpanded = expandedPositions[headerPosition]
|
||||||
|
|
||||||
|
expandedPositions.flip(headerPosition)
|
||||||
|
|
||||||
|
if (!isHeaderExpanded) {
|
||||||
|
val updatedList = items.toMutableList()
|
||||||
|
.apply { addAll(headerAdapterPosition + 1, header.grades) }
|
||||||
|
|
||||||
|
refreshList(updatedList)
|
||||||
|
scrollToHeaderWithSubItems(headerAdapterPosition, header.grades.size)
|
||||||
|
} else {
|
||||||
|
val startPosition = headerAdapterPosition + 1
|
||||||
|
val updatedList = items.toMutableList()
|
||||||
|
.apply {
|
||||||
|
subList(startPosition, startPosition + header.grades.size).clear()
|
||||||
|
}
|
||||||
|
|
||||||
|
refreshList(updatedList)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("SetTextI18n")
|
@SuppressLint("SetTextI18n")
|
||||||
private fun bindItemViewHolder(holder: ItemViewHolder, grade: Grade) {
|
private fun bindItemViewHolder(holder: ItemViewHolder, grade: Grade) {
|
||||||
|
val context = holder.binding.root.context
|
||||||
|
|
||||||
with(holder.binding) {
|
with(holder.binding) {
|
||||||
gradeItemValue.run {
|
gradeItemValue.run {
|
||||||
text = grade.entry
|
text = grade.entry
|
||||||
@ -154,26 +207,37 @@ class GradeDetailsAdapter @Inject constructor() : BaseExpandableAdapter<Recycler
|
|||||||
gradeItemDescription.text = when {
|
gradeItemDescription.text = when {
|
||||||
grade.description.isNotBlank() -> grade.description
|
grade.description.isNotBlank() -> grade.description
|
||||||
grade.gradeSymbol.isNotBlank() -> grade.gradeSymbol
|
grade.gradeSymbol.isNotBlank() -> grade.gradeSymbol
|
||||||
else -> root.context.getString(R.string.all_no_description)
|
else -> context.getString(R.string.all_no_description)
|
||||||
}
|
}
|
||||||
gradeItemDate.text = grade.date.toFormattedString()
|
gradeItemDate.text = grade.date.toFormattedString()
|
||||||
gradeItemWeight.text = "${root.context.getString(R.string.grade_weight)}: ${grade.weight}"
|
gradeItemWeight.text = "${context.getString(R.string.grade_weight)}: ${grade.weight}"
|
||||||
gradeItemNote.visibility = if (!grade.isRead) View.VISIBLE else View.GONE
|
gradeItemNote.visibility = if (!grade.isRead) View.VISIBLE else View.GONE
|
||||||
|
|
||||||
root.setOnClickListener {
|
root.setOnClickListener {
|
||||||
holder.bindingAdapterPosition.let { if (it != NO_POSITION) onClickListener(grade, it) }
|
holder.bindingAdapterPosition.let {
|
||||||
|
if (it != NO_POSITION) onClickListener(grade, it)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun formatAverage(average: Double?, resources: Resources) =
|
||||||
|
if (average == null || average == .0) {
|
||||||
|
resources.getString(R.string.grade_no_average)
|
||||||
|
} else {
|
||||||
|
resources.getString(R.string.grade_average, average)
|
||||||
|
}
|
||||||
|
|
||||||
private class HeaderViewHolder(val binding: HeaderGradeDetailsBinding) :
|
private class HeaderViewHolder(val binding: HeaderGradeDetailsBinding) :
|
||||||
RecyclerView.ViewHolder(binding.root)
|
RecyclerView.ViewHolder(binding.root)
|
||||||
|
|
||||||
private class ItemViewHolder(val binding: ItemGradeDetailsBinding) :
|
private class ItemViewHolder(val binding: ItemGradeDetailsBinding) :
|
||||||
RecyclerView.ViewHolder(binding.root)
|
RecyclerView.ViewHolder(binding.root)
|
||||||
|
|
||||||
class GradeDetailsDiffUtil(private val old: List<GradeDetailsItem>, private val new: List<GradeDetailsItem>) :
|
private class GradeDetailsDiffUtil(
|
||||||
DiffUtil.Callback() {
|
private val old: List<GradeDetailsItem>,
|
||||||
|
private val new: List<GradeDetailsItem>
|
||||||
|
) : DiffUtil.Callback() {
|
||||||
|
|
||||||
override fun getOldListSize() = old.size
|
override fun getOldListSize() = old.size
|
||||||
|
|
||||||
|
@ -12,6 +12,7 @@ import androidx.recyclerview.widget.LinearLayoutManager
|
|||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
import io.github.wulkanowy.R
|
import io.github.wulkanowy.R
|
||||||
import io.github.wulkanowy.data.db.entities.Grade
|
import io.github.wulkanowy.data.db.entities.Grade
|
||||||
|
import io.github.wulkanowy.ui.modules.grade.GradeExpandMode
|
||||||
import io.github.wulkanowy.databinding.FragmentGradeDetailsBinding
|
import io.github.wulkanowy.databinding.FragmentGradeDetailsBinding
|
||||||
import io.github.wulkanowy.ui.base.BaseFragment
|
import io.github.wulkanowy.ui.base.BaseFragment
|
||||||
import io.github.wulkanowy.ui.modules.grade.GradeFragment
|
import io.github.wulkanowy.ui.modules.grade.GradeFragment
|
||||||
@ -79,10 +80,10 @@ class GradeDetailsFragment :
|
|||||||
else false
|
else false
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun updateData(data: List<GradeDetailsItem>, isGradeExpandable: Boolean, gradeColorTheme: String) {
|
override fun updateData(data: List<GradeDetailsItem>, expandMode: GradeExpandMode, gradeColorTheme: String) {
|
||||||
with(gradeDetailsAdapter) {
|
with(gradeDetailsAdapter) {
|
||||||
colorTheme = gradeColorTheme
|
colorTheme = gradeColorTheme
|
||||||
setDataItems(data, isGradeExpandable)
|
setDataItems(data, expandMode)
|
||||||
notifyDataSetChanged()
|
notifyDataSetChanged()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,7 @@ import io.github.wulkanowy.data.repositories.StudentRepository
|
|||||||
import io.github.wulkanowy.ui.base.BasePresenter
|
import io.github.wulkanowy.ui.base.BasePresenter
|
||||||
import io.github.wulkanowy.ui.base.ErrorHandler
|
import io.github.wulkanowy.ui.base.ErrorHandler
|
||||||
import io.github.wulkanowy.ui.modules.grade.GradeAverageProvider
|
import io.github.wulkanowy.ui.modules.grade.GradeAverageProvider
|
||||||
|
import io.github.wulkanowy.ui.modules.grade.GradeExpandMode
|
||||||
import io.github.wulkanowy.ui.modules.grade.GradeSortingMode.ALPHABETIC
|
import io.github.wulkanowy.ui.modules.grade.GradeSortingMode.ALPHABETIC
|
||||||
import io.github.wulkanowy.ui.modules.grade.GradeSortingMode.DATE
|
import io.github.wulkanowy.ui.modules.grade.GradeSortingMode.DATE
|
||||||
import io.github.wulkanowy.ui.modules.grade.GradeSubject
|
import io.github.wulkanowy.ui.modules.grade.GradeSubject
|
||||||
@ -113,7 +114,7 @@ class GradeDetailsPresenter @Inject constructor(
|
|||||||
fun onParentViewReselected() {
|
fun onParentViewReselected() {
|
||||||
view?.run {
|
view?.run {
|
||||||
if (!isViewEmpty) {
|
if (!isViewEmpty) {
|
||||||
if (preferencesRepository.isGradeExpandable) collapseAllItems()
|
if (preferencesRepository.gradeExpandMode != GradeExpandMode.ALWAYS_EXPANDED) collapseAllItems()
|
||||||
scrollToStart()
|
scrollToStart()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -157,7 +158,7 @@ class GradeDetailsPresenter @Inject constructor(
|
|||||||
showContent(true)
|
showContent(true)
|
||||||
updateData(
|
updateData(
|
||||||
data = items,
|
data = items,
|
||||||
isGradeExpandable = preferencesRepository.isGradeExpandable,
|
expandMode = preferencesRepository.gradeExpandMode,
|
||||||
gradeColorTheme = preferencesRepository.gradeColorTheme
|
gradeColorTheme = preferencesRepository.gradeColorTheme
|
||||||
)
|
)
|
||||||
notifyParentDataLoaded(semesterId)
|
notifyParentDataLoaded(semesterId)
|
||||||
@ -175,7 +176,7 @@ class GradeDetailsPresenter @Inject constructor(
|
|||||||
showContent(items.isNotEmpty())
|
showContent(items.isNotEmpty())
|
||||||
updateData(
|
updateData(
|
||||||
data = items,
|
data = items,
|
||||||
isGradeExpandable = preferencesRepository.isGradeExpandable,
|
expandMode = preferencesRepository.gradeExpandMode,
|
||||||
gradeColorTheme = preferencesRepository.gradeColorTheme
|
gradeColorTheme = preferencesRepository.gradeColorTheme
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -235,14 +236,24 @@ class GradeDetailsPresenter @Inject constructor(
|
|||||||
.sortedByDescending { it.date }
|
.sortedByDescending { it.date }
|
||||||
.map { GradeDetailsItem(it, ViewType.ITEM) }
|
.map { GradeDetailsItem(it, ViewType.ITEM) }
|
||||||
|
|
||||||
listOf(GradeDetailsItem(GradeDetailsHeader(
|
val gradeDetailsItems = listOf(
|
||||||
subject = subject,
|
GradeDetailsItem(
|
||||||
average = average,
|
GradeDetailsHeader(
|
||||||
pointsSum = points,
|
subject = subject,
|
||||||
grades = subItems
|
average = average,
|
||||||
).apply {
|
pointsSum = points,
|
||||||
newGrades = grades.filter { grade -> !grade.isRead }.size
|
grades = subItems
|
||||||
}, ViewType.HEADER)) + if (preferencesRepository.isGradeExpandable) emptyList() else subItems
|
).apply {
|
||||||
|
newGrades = grades.filter { grade -> !grade.isRead }.size
|
||||||
|
}, ViewType.HEADER
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
if (preferencesRepository.gradeExpandMode == GradeExpandMode.ALWAYS_EXPANDED) {
|
||||||
|
gradeDetailsItems + subItems
|
||||||
|
} else {
|
||||||
|
gradeDetailsItems
|
||||||
|
}
|
||||||
}.flatten()
|
}.flatten()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package io.github.wulkanowy.ui.modules.grade.details
|
package io.github.wulkanowy.ui.modules.grade.details
|
||||||
|
|
||||||
import io.github.wulkanowy.data.db.entities.Grade
|
import io.github.wulkanowy.data.db.entities.Grade
|
||||||
|
import io.github.wulkanowy.ui.modules.grade.GradeExpandMode
|
||||||
import io.github.wulkanowy.ui.base.BaseView
|
import io.github.wulkanowy.ui.base.BaseView
|
||||||
|
|
||||||
interface GradeDetailsView : BaseView {
|
interface GradeDetailsView : BaseView {
|
||||||
@ -9,7 +10,7 @@ interface GradeDetailsView : BaseView {
|
|||||||
|
|
||||||
fun initView()
|
fun initView()
|
||||||
|
|
||||||
fun updateData(data: List<GradeDetailsItem>, isGradeExpandable: Boolean, gradeColorTheme: String)
|
fun updateData(data: List<GradeDetailsItem>, expandMode: GradeExpandMode, gradeColorTheme: String)
|
||||||
|
|
||||||
fun updateItem(item: Grade, position: Int)
|
fun updateItem(item: Grade, position: Int)
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
<bool name="pref_default_attendance_present">true</bool>
|
<bool name="pref_default_attendance_present">true</bool>
|
||||||
<string name="pref_default_grade_average_mode">only_one_semester</string>
|
<string name="pref_default_grade_average_mode">only_one_semester</string>
|
||||||
<bool name="pref_default_grade_average_force_calc">false</bool>
|
<bool name="pref_default_grade_average_force_calc">false</bool>
|
||||||
<bool name="pref_default_expand_grade">false</bool>
|
<string name="pref_default_expand_grade_mode">one</string>
|
||||||
<bool name="pref_default_grade_statistics_list">false</bool>
|
<bool name="pref_default_grade_statistics_list">false</bool>
|
||||||
<string name="pref_default_app_theme">light</string>
|
<string name="pref_default_app_theme">light</string>
|
||||||
<string name="pref_default_grade_color_scheme">vulcan</string>
|
<string name="pref_default_grade_color_scheme">vulcan</string>
|
||||||
|
@ -5,7 +5,8 @@
|
|||||||
<string name="pref_key_app_theme">app_theme</string>
|
<string name="pref_key_app_theme">app_theme</string>
|
||||||
<string name="pref_key_dashboard_tiles">dashboard_tiles</string>
|
<string name="pref_key_dashboard_tiles">dashboard_tiles</string>
|
||||||
<string name="pref_key_grade_color_scheme">grade_color_scheme</string>
|
<string name="pref_key_grade_color_scheme">grade_color_scheme</string>
|
||||||
<string name="pref_key_expand_grade">expand_grade</string>
|
<string name="pref_key_expand_grade">expand_grade</string> <!-- replaced by expand_grade_mode -->
|
||||||
|
<string name="pref_key_expand_grade_mode">expand_grade_mode</string>
|
||||||
<string name="pref_key_grade_average_mode">grade_average_mode</string>
|
<string name="pref_key_grade_average_mode">grade_average_mode</string>
|
||||||
<string name="pref_key_grade_average_force_calc">grade_average_always_calc</string>
|
<string name="pref_key_grade_average_force_calc">grade_average_always_calc</string>
|
||||||
<string name="pref_key_grade_statistics_list">grade_statistics_list</string>
|
<string name="pref_key_grade_statistics_list">grade_statistics_list</string>
|
||||||
|
@ -99,6 +99,17 @@
|
|||||||
<item>grade_color</item>
|
<item>grade_color</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
|
|
||||||
|
<string-array name="default_expand_grade_entries">
|
||||||
|
<item>Up to 1 at once</item>
|
||||||
|
<item>Always expanded</item>
|
||||||
|
<item>Unlimited expansions</item>
|
||||||
|
</string-array>
|
||||||
|
<string-array name="default_expand_grade_values" translatable="false">
|
||||||
|
<item>one</item>
|
||||||
|
<item>always</item>
|
||||||
|
<item>any</item>
|
||||||
|
</string-array>
|
||||||
|
|
||||||
<string-array name="grade_average_mode_entries">
|
<string-array name="grade_average_mode_entries">
|
||||||
<item>Average of grades only from selected semester</item>
|
<item>Average of grades only from selected semester</item>
|
||||||
<item>Average of averages from both semesters</item>
|
<item>Average of averages from both semesters</item>
|
||||||
|
@ -50,11 +50,14 @@
|
|||||||
app:iconSpaceReserved="false"
|
app:iconSpaceReserved="false"
|
||||||
app:key="@string/pref_key_grade_color_scheme"
|
app:key="@string/pref_key_grade_color_scheme"
|
||||||
app:title="@string/pref_view_grade_color_scheme" />
|
app:title="@string/pref_view_grade_color_scheme" />
|
||||||
<SwitchPreferenceCompat
|
<ListPreference
|
||||||
app:defaultValue="@bool/pref_default_expand_grade"
|
app:defaultValue="@string/pref_default_expand_grade_mode"
|
||||||
|
app:entries="@array/default_expand_grade_entries"
|
||||||
|
app:entryValues="@array/default_expand_grade_values"
|
||||||
app:iconSpaceReserved="false"
|
app:iconSpaceReserved="false"
|
||||||
app:key="@string/pref_key_expand_grade"
|
app:key="@string/pref_key_expand_grade_mode"
|
||||||
app:title="@string/pref_view_expand_grade" />
|
app:title="@string/pref_view_expand_grade"
|
||||||
|
app:useSimpleSummaryProvider="true" />
|
||||||
<SwitchPreferenceCompat
|
<SwitchPreferenceCompat
|
||||||
app:defaultValue="@bool/pref_default_subjects_without_grades"
|
app:defaultValue="@bool/pref_default_subjects_without_grades"
|
||||||
app:iconSpaceReserved="false"
|
app:iconSpaceReserved="false"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user