From 79b970256fee5e4f212e3ea6ac3d539531f6eab1 Mon Sep 17 00:00:00 2001 From: Michael <5672750+mibac138@users.noreply.github.com> Date: Sat, 11 Dec 2021 17:14:46 +0100 Subject: [PATCH] More strongly typed data in preferences (#1697) --- .../github/wulkanowy/data/enums/AppTheme.kt | 12 +++ .../wulkanowy/data/enums/TimetableMode.kt | 11 +++ .../repositories/PreferencesRepository.kt | 16 ++-- .../github/wulkanowy/ui/base/ThemeManager.kt | 12 +-- .../ui/modules/timetable/TimetableAdapter.kt | 7 +- .../ui/modules/timetable/TimetableFragment.kt | 3 +- .../modules/timetable/TimetablePresenter.kt | 3 +- .../ui/modules/timetable/TimetableView.kt | 8 +- .../timetablewidget/TimetableWidgetFactory.kt | 83 +++++++++++++------ 9 files changed, 113 insertions(+), 42 deletions(-) create mode 100644 app/src/main/java/io/github/wulkanowy/data/enums/AppTheme.kt create mode 100644 app/src/main/java/io/github/wulkanowy/data/enums/TimetableMode.kt diff --git a/app/src/main/java/io/github/wulkanowy/data/enums/AppTheme.kt b/app/src/main/java/io/github/wulkanowy/data/enums/AppTheme.kt new file mode 100644 index 00000000..438f0732 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/data/enums/AppTheme.kt @@ -0,0 +1,12 @@ +package io.github.wulkanowy.data.enums + +enum class AppTheme(val value: String) { + SYSTEM("system"), + LIGHT("light"), + DARK("dark"), + BLACK("black"); + + companion object { + fun getByValue(value: String) = values().find { it.value == value } ?: LIGHT + } +} \ No newline at end of file diff --git a/app/src/main/java/io/github/wulkanowy/data/enums/TimetableMode.kt b/app/src/main/java/io/github/wulkanowy/data/enums/TimetableMode.kt new file mode 100644 index 00000000..9e294ad7 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/data/enums/TimetableMode.kt @@ -0,0 +1,11 @@ +package io.github.wulkanowy.data.enums + +enum class TimetableMode(val value: String) { + WHOLE_PLAN("yes"), + ONLY_CURRENT_GROUP("no"), + SMALL_OTHER_GROUP("small"); + + companion object { + fun getByValue(value: String) = values().find { it.value == value } ?: ONLY_CURRENT_GROUP + } +} \ No newline at end of file diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/PreferencesRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/PreferencesRepository.kt index f4fb77d8..48eac48a 100644 --- a/app/src/main/java/io/github/wulkanowy/data/repositories/PreferencesRepository.kt +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/PreferencesRepository.kt @@ -7,9 +7,11 @@ import com.fredporciuncula.flow.preferences.FlowSharedPreferences import com.fredporciuncula.flow.preferences.Preference import dagger.hilt.android.qualifiers.ApplicationContext import io.github.wulkanowy.R +import io.github.wulkanowy.data.enums.AppTheme import io.github.wulkanowy.data.enums.GradeColorTheme import io.github.wulkanowy.data.enums.GradeExpandMode import io.github.wulkanowy.data.enums.GradeSortingMode +import io.github.wulkanowy.data.enums.TimetableMode import io.github.wulkanowy.sdk.toLocalDate import io.github.wulkanowy.ui.modules.dashboard.DashboardItem import io.github.wulkanowy.ui.modules.grade.GradeAverageMode @@ -73,8 +75,8 @@ class PreferencesRepository @Inject constructor( ) val appThemeKey = context.getString(R.string.pref_key_app_theme) - val appTheme: String - get() = getString(appThemeKey, R.string.pref_default_app_theme) + val appTheme: AppTheme + get() = AppTheme.getByValue(getString(appThemeKey, R.string.pref_default_app_theme)) val gradeColorTheme: GradeColorTheme get() = GradeColorTheme.getByValue( @@ -159,10 +161,12 @@ class PreferencesRepository @Inject constructor( R.bool.pref_default_timetable_show_groups ) - val showWholeClassPlan: String - get() = getString( - R.string.pref_key_timetable_show_whole_class, - R.string.pref_default_timetable_show_whole_class + val showWholeClassPlan: TimetableMode + get() = TimetableMode.getByValue( + getString( + R.string.pref_key_timetable_show_whole_class, + R.string.pref_default_timetable_show_whole_class + ) ) val gradeSortingMode: GradeSortingMode diff --git a/app/src/main/java/io/github/wulkanowy/ui/base/ThemeManager.kt b/app/src/main/java/io/github/wulkanowy/ui/base/ThemeManager.kt index e934a182..2d83bbbf 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/base/ThemeManager.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/base/ThemeManager.kt @@ -7,6 +7,7 @@ import androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM import androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_NO import androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_YES import io.github.wulkanowy.R +import io.github.wulkanowy.data.enums.AppTheme import io.github.wulkanowy.data.repositories.PreferencesRepository import io.github.wulkanowy.ui.modules.login.LoginActivity import io.github.wulkanowy.ui.modules.main.MainActivity @@ -20,7 +21,7 @@ class ThemeManager @Inject constructor(private val preferencesRepository: Prefer fun applyActivityTheme(activity: AppCompatActivity) { if (isThemeApplicable(activity)) { applyDefaultTheme() - if (preferencesRepository.appTheme == "black") { + if (preferencesRepository.appTheme == AppTheme.BLACK) { when (activity) { is MainActivity -> activity.setTheme(R.style.WulkanowyTheme_Black) is LoginActivity -> activity.setTheme(R.style.WulkanowyTheme_Login_Black) @@ -32,11 +33,10 @@ class ThemeManager @Inject constructor(private val preferencesRepository: Prefer fun applyDefaultTheme() { AppCompatDelegate.setDefaultNightMode( - when (val theme = preferencesRepository.appTheme) { - "light" -> MODE_NIGHT_NO - "dark", "black" -> MODE_NIGHT_YES - "system" -> MODE_NIGHT_FOLLOW_SYSTEM - else -> throw IllegalArgumentException("Wrong theme: $theme") + when (preferencesRepository.appTheme) { + AppTheme.LIGHT -> MODE_NIGHT_NO + AppTheme.DARK, AppTheme.BLACK -> MODE_NIGHT_YES + AppTheme.SYSTEM -> MODE_NIGHT_FOLLOW_SYSTEM } ) } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetableAdapter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetableAdapter.kt index 2228aaf4..0f3e0029 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetableAdapter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetableAdapter.kt @@ -12,6 +12,7 @@ import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.RecyclerView import io.github.wulkanowy.R import io.github.wulkanowy.data.db.entities.Timetable +import io.github.wulkanowy.data.enums.TimetableMode import io.github.wulkanowy.databinding.ItemTimetableBinding import io.github.wulkanowy.databinding.ItemTimetableSmallBinding import io.github.wulkanowy.utils.getThemeAttrColor @@ -35,7 +36,7 @@ class TimetableAdapter @Inject constructor() : RecyclerView.Adapter Unit = {} - private var showWholeClassPlan: String = "no" + private lateinit var showWholeClassPlan: TimetableMode private var showGroupsInPlan: Boolean = false @@ -47,7 +48,7 @@ class TimetableAdapter @Inject constructor() : RecyclerView.Adapter, - showWholeClassPlan: String = this.showWholeClassPlan, + showWholeClassPlan: TimetableMode = this.showWholeClassPlan, showGroupsInPlan: Boolean = this.showGroupsInPlan, showTimers: Boolean = this.showTimers ) { @@ -87,7 +88,7 @@ class TimetableAdapter @Inject constructor() : RecyclerView.Adapter ViewType.ITEM_SMALL.ordinal + !items[position].isStudentPlan && showWholeClassPlan == TimetableMode.SMALL_OTHER_GROUP -> ViewType.ITEM_SMALL.ordinal else -> ViewType.ITEM_NORMAL.ordinal } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetableFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetableFragment.kt index 07a9f6c7..b49d11c1 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetableFragment.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetableFragment.kt @@ -14,6 +14,7 @@ import com.google.android.material.datepicker.MaterialDatePicker import dagger.hilt.android.AndroidEntryPoint import io.github.wulkanowy.R import io.github.wulkanowy.data.db.entities.Timetable +import io.github.wulkanowy.data.enums.TimetableMode import io.github.wulkanowy.databinding.FragmentTimetableBinding import io.github.wulkanowy.ui.base.BaseFragment import io.github.wulkanowy.ui.modules.main.MainActivity @@ -115,7 +116,7 @@ class TimetableFragment : BaseFragment(R.layout.fragme override fun updateData( data: List, - showWholeClassPlanType: String, + showWholeClassPlanType: TimetableMode, showGroupsInPlanType: Boolean, showTimetableTimers: Boolean ) { diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetablePresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetablePresenter.kt index 86e99398..87f5cac3 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetablePresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetablePresenter.kt @@ -3,6 +3,7 @@ package io.github.wulkanowy.ui.modules.timetable import android.annotation.SuppressLint import io.github.wulkanowy.data.Status import io.github.wulkanowy.data.db.entities.Timetable +import io.github.wulkanowy.data.enums.TimetableMode import io.github.wulkanowy.data.repositories.PreferencesRepository import io.github.wulkanowy.data.repositories.SemesterRepository import io.github.wulkanowy.data.repositories.StudentRepository @@ -197,7 +198,7 @@ class TimetablePresenter @Inject constructor( } private fun createItems(items: List) = items.filter { item -> - if (prefRepository.showWholeClassPlan == "no") item.isStudentPlan else true + if (prefRepository.showWholeClassPlan == TimetableMode.ONLY_CURRENT_GROUP) item.isStudentPlan else true }.sortedWith(compareBy({ item -> item.number }, { item -> !item.isStudentPlan })) private fun showErrorViewOnError(message: String, error: Throwable) { diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetableView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetableView.kt index 4afb0b05..eaf75cb0 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetableView.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetableView.kt @@ -1,6 +1,7 @@ package io.github.wulkanowy.ui.modules.timetable import io.github.wulkanowy.data.db.entities.Timetable +import io.github.wulkanowy.data.enums.TimetableMode import io.github.wulkanowy.ui.base.BaseView import java.time.LocalDate @@ -12,7 +13,12 @@ interface TimetableView : BaseView { fun initView() - fun updateData(data: List, showWholeClassPlanType: String, showGroupsInPlanType: Boolean, showTimetableTimers: Boolean) + fun updateData( + data: List, + showWholeClassPlanType: TimetableMode, + showGroupsInPlanType: Boolean, + showTimetableTimers: Boolean + ) fun updateNavigationDay(date: String) diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/timetablewidget/TimetableWidgetFactory.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/timetablewidget/TimetableWidgetFactory.kt index c8dda23c..f3d760f0 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/timetablewidget/TimetableWidgetFactory.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/timetablewidget/TimetableWidgetFactory.kt @@ -14,6 +14,7 @@ import android.widget.RemoteViewsService import io.github.wulkanowy.R import io.github.wulkanowy.data.db.SharedPrefProvider import io.github.wulkanowy.data.db.entities.Timetable +import io.github.wulkanowy.data.enums.TimetableMode import io.github.wulkanowy.data.repositories.PreferencesRepository import io.github.wulkanowy.data.repositories.SemesterRepository import io.github.wulkanowy.data.repositories.StudentRepository @@ -88,7 +89,7 @@ class TimetableWidgetFactory( private fun getItemLayout(lesson: Timetable): Int { return when { - prefRepository.showWholeClassPlan == "small" && !lesson.isStudentPlan -> { + prefRepository.showWholeClassPlan == TimetableMode.SMALL_OTHER_GROUP && !lesson.isStudentPlan -> { if (savedCurrentTheme == 0L) R.layout.item_widget_timetable_small else R.layout.item_widget_timetable_small_dark } @@ -109,7 +110,11 @@ class TimetableWidgetFactory( timetableRepository.getTimetable(student, semester, date, date, false) .toFirstResult().data?.lessons.orEmpty() .sortedWith(compareBy({ it.number }, { !it.isStudentPlan })) - .filter { if (prefRepository.showWholeClassPlan == "no") it.isStudentPlan else true } + .filter { + if (prefRepository.showWholeClassPlan == TimetableMode.ONLY_CURRENT_GROUP) { + it.isStudentPlan + } else true + } } } catch (e: Exception) { Timber.e(e, "An error has occurred in timetable widget factory") @@ -124,8 +129,14 @@ class TimetableWidgetFactory( return RemoteViews(context.packageName, getItemLayout(lesson)).apply { setTextViewText(R.id.timetableWidgetItemSubject, lesson.subject) setTextViewText(R.id.timetableWidgetItemNumber, lesson.number.toString()) - setTextViewText(R.id.timetableWidgetItemTimeStart, lesson.start.toFormattedString("HH:mm")) - setTextViewText(R.id.timetableWidgetItemTimeFinish, lesson.end.toFormattedString("HH:mm")) + setTextViewText( + R.id.timetableWidgetItemTimeStart, + lesson.start.toFormattedString("HH:mm") + ) + setTextViewText( + R.id.timetableWidgetItemTimeFinish, + lesson.end.toFormattedString("HH:mm") + ) updateDescription(this, lesson) @@ -156,11 +167,16 @@ class TimetableWidgetFactory( private fun updateStylesCanceled(remoteViews: RemoteViews) { with(remoteViews) { - setInt(R.id.timetableWidgetItemSubject, "setPaintFlags", - STRIKE_THRU_TEXT_FLAG or ANTI_ALIAS_FLAG) + setInt( + R.id.timetableWidgetItemSubject, "setPaintFlags", + STRIKE_THRU_TEXT_FLAG or ANTI_ALIAS_FLAG + ) setTextColor(R.id.timetableWidgetItemNumber, context.getCompatColor(primaryColor!!)) setTextColor(R.id.timetableWidgetItemSubject, context.getCompatColor(primaryColor!!)) - setTextColor(R.id.timetableWidgetItemDescription, context.getCompatColor(primaryColor!!)) + setTextColor( + R.id.timetableWidgetItemDescription, + context.getCompatColor(primaryColor!!) + ) } } @@ -168,7 +184,10 @@ class TimetableWidgetFactory( with(remoteViews) { setInt(R.id.timetableWidgetItemSubject, "setPaintFlags", ANTI_ALIAS_FLAG) setTextColor(R.id.timetableWidgetItemSubject, context.getCompatColor(textColor!!)) - setTextColor(R.id.timetableWidgetItemDescription, context.getCompatColor(timetableChangeColor!!)) + setTextColor( + R.id.timetableWidgetItemDescription, + context.getCompatColor(timetableChangeColor!!) + ) updateNotCanceledLessonNumberColor(this, lesson) updateNotCanceledSubjectColor(this, lesson) @@ -180,37 +199,53 @@ class TimetableWidgetFactory( } private fun updateNotCanceledLessonNumberColor(remoteViews: RemoteViews, lesson: Timetable) { - remoteViews.setTextColor(R.id.timetableWidgetItemNumber, context.getCompatColor( - if (lesson.changes || (lesson.info.isNotBlank() && !lesson.canceled)) timetableChangeColor!! - else textColor!! - )) + remoteViews.setTextColor( + R.id.timetableWidgetItemNumber, context.getCompatColor( + if (lesson.changes || (lesson.info.isNotBlank() && !lesson.canceled)) timetableChangeColor!! + else textColor!! + ) + ) } private fun updateNotCanceledSubjectColor(remoteViews: RemoteViews, lesson: Timetable) { - remoteViews.setTextColor(R.id.timetableWidgetItemSubject, context.getCompatColor( - if (lesson.subjectOld.isNotBlank() && lesson.subject != lesson.subjectOld) timetableChangeColor!! - else textColor!! - )) + remoteViews.setTextColor( + R.id.timetableWidgetItemSubject, context.getCompatColor( + if (lesson.subjectOld.isNotBlank() && lesson.subject != lesson.subjectOld) timetableChangeColor!! + else textColor!! + ) + ) } - private fun updateNotCanceledRoom(remoteViews: RemoteViews, lesson: Timetable, teacherChange: Boolean) { + private fun updateNotCanceledRoom( + remoteViews: RemoteViews, + lesson: Timetable, + teacherChange: Boolean + ) { with(remoteViews) { if (lesson.room.isNotBlank()) { - setTextViewText(R.id.timetableWidgetItemRoom, + setTextViewText( + R.id.timetableWidgetItemRoom, if (teacherChange) lesson.room else "${context.getString(R.string.timetable_room)} ${lesson.room}" ) - setTextColor(R.id.timetableWidgetItemRoom, context.getCompatColor( - if (lesson.roomOld.isNotBlank() && lesson.room != lesson.roomOld) timetableChangeColor!! - else textColor!! - )) + setTextColor( + R.id.timetableWidgetItemRoom, context.getCompatColor( + if (lesson.roomOld.isNotBlank() && lesson.room != lesson.roomOld) timetableChangeColor!! + else textColor!! + ) + ) } else setTextViewText(R.id.timetableWidgetItemRoom, "") } } - private fun updateNotCanceledTeacher(remoteViews: RemoteViews, lesson: Timetable, teacherChange: Boolean) { - remoteViews.setTextViewText(R.id.timetableWidgetItemTeacher, + private fun updateNotCanceledTeacher( + remoteViews: RemoteViews, + lesson: Timetable, + teacherChange: Boolean + ) { + remoteViews.setTextViewText( + R.id.timetableWidgetItemTeacher, if (teacherChange) lesson.teacher else "" )