[App] Refactor getting profile config.

This commit is contained in:
Kuba Szczodrzyński 2022-10-25 20:48:10 +02:00
parent 00e077d01f
commit bfd2e9883a
No known key found for this signature in database
GPG Key ID: 70CB8A85BA1633CB
30 changed files with 181 additions and 139 deletions

View File

@ -55,11 +55,9 @@ class Config(db: AppDb) : BaseConfig(db) {
ConfigMigration(app, this)
}
fun getFor(profileId: Int): ProfileConfig {
operator fun get(profileId: Int): ProfileConfig {
return profileConfigs[profileId] ?: ProfileConfig(db, profileId, entries).also {
profileConfigs[profileId] = it
}
}
fun forProfile() = getFor(App.profileId)
}

View File

@ -198,7 +198,6 @@ class SzkolnyApi(val app: App) : CoroutineScope {
val teams = app.db.teamDao().allNow
val users = profiles.mapNotNull { profile ->
val config = app.config.getFor(profile.id)
val user = ServerSyncRequest.User(
profile.userCode,
profile.studentNameLong,
@ -207,9 +206,9 @@ class SzkolnyApi(val app: App) : CoroutineScope {
teams.filter { it.profileId == profile.id }.map { it.code }
)
val hash = user.toString().md5()
if (hash == config.hash)
if (hash == profile.config.hash)
return@mapNotNull null
return@mapNotNull user to config
return@mapNotNull user to profile.config
}
val response = api.serverSync(ServerSyncRequest(

View File

@ -55,7 +55,7 @@ class SzkolnyTask(val app: App, val syncingProfiles: List<Profile>) : IApiTask(-
notificationList
.mapNotNull { it.profileId }
.distinct()
.map { app.config.getFor(it).sync.notificationFilter }
.map { app.config[it].sync.notificationFilter }
.forEach { filter ->
filter.forEach { type ->
notificationList.removeAll { it.type == type }

View File

@ -8,7 +8,9 @@ import android.content.Context
import android.widget.ImageView
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.Ignore
import com.google.gson.JsonObject
import pl.szczodrzynski.edziennik.App
import pl.szczodrzynski.edziennik.data.db.enums.LoginType
import pl.szczodrzynski.edziennik.ext.dateToSemester
import pl.szczodrzynski.edziennik.ext.getDrawable
@ -88,6 +90,9 @@ open class Profile(
val canShare
get() = registration == REGISTRATION_ENABLED && !archived
@delegate:Ignore
val config by lazy { App.config[this.id] }
override fun getImageDrawable(context: Context) = this.getDrawable(context)
override fun getImageHolder(context: Context) = this.getHolder()
override fun applyImageTo(imageView: ImageView) {

View File

@ -176,7 +176,7 @@ class SzkolnyAppFirebase(val app: App, val profiles: List<Profile>, val message:
)
val type = if (event.isHomework) NotificationType.SHARED_HOMEWORK else NotificationType.SHARED_EVENT
val notificationFilter = app.config.getFor(event.profileId).sync.notificationFilter
val notificationFilter = app.config[event.profileId].sync.notificationFilter
if (!notificationFilter.contains(type) && event.sharedBy != "self" && event.date >= Date.getToday()) {
val notification = Notification(
@ -211,7 +211,7 @@ class SzkolnyAppFirebase(val app: App, val profiles: List<Profile>, val message:
val profile = profiles.firstOrNull { it.id == team.profileId } ?: return@forEach
if (!profile.canShare)
return@forEach
val notificationFilter = app.config.getFor(team.profileId).sync.notificationFilter
val notificationFilter = app.config[team.profileId].sync.notificationFilter
if (!notificationFilter.contains(NotificationType.REMOVED_SHARED_EVENT)) {
val notification = Notification(
@ -265,7 +265,7 @@ class SzkolnyAppFirebase(val app: App, val profiles: List<Profile>, val message:
return@forEach
val type = NotificationType.SHARED_NOTE
val notificationFilter = app.config.getFor(note.profileId).sync.notificationFilter
val notificationFilter = app.config[note.profileId].sync.notificationFilter
if (!notificationFilter.contains(type) && note.sharedBy != "self") {
val notification = Notification(

View File

@ -17,7 +17,12 @@ import com.mikepenz.iconics.typeface.library.community.material.CommunityMateria
import com.mikepenz.iconics.utils.colorInt
import com.mikepenz.iconics.utils.sizeDp
import eu.szkolny.font.SzkolnyFont
import kotlinx.coroutines.*
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import pl.szczodrzynski.edziennik.App
import pl.szczodrzynski.edziennik.MainActivity
import pl.szczodrzynski.edziennik.R
@ -53,7 +58,7 @@ class AgendaFragment : Fragment(), CoroutineScope {
if (getActivity() == null || context == null) return null
activity = getActivity() as MainActivity
context?.theme?.applyStyle(Themes.appTheme, true)
type = app.config.forProfile().ui.agendaViewType
type = app.profile.config.ui.agendaViewType
b = when (type) {
Profile.AGENDA_DEFAULT -> FragmentAgendaDefaultBinding.inflate(inflater, container, false)
Profile.AGENDA_CALENDAR -> FragmentAgendaCalendarBinding.inflate(inflater, container, false)
@ -92,7 +97,7 @@ class AgendaFragment : Fragment(), CoroutineScope {
activity.bottomSheet.close()
type =
if (type == Profile.AGENDA_DEFAULT) Profile.AGENDA_CALENDAR else Profile.AGENDA_DEFAULT
app.config.forProfile().ui.agendaViewType = type
app.profile.config.ui.agendaViewType = type
activity.reloadTarget()
},
BottomSheetSeparatorItem(true),

View File

@ -16,7 +16,12 @@ import com.github.tibolte.agendacalendarview.agenda.AgendaAdapter
import com.github.tibolte.agendacalendarview.models.BaseCalendarEvent
import com.github.tibolte.agendacalendarview.models.CalendarEvent
import com.github.tibolte.agendacalendarview.models.IDayItem
import kotlinx.coroutines.*
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import pl.szczodrzynski.edziennik.App
import pl.szczodrzynski.edziennik.MainActivity
import pl.szczodrzynski.edziennik.data.db.full.EventFull
@ -49,7 +54,6 @@ class AgendaFragmentDefault(
private val unreadDates = mutableSetOf<Int>()
private val events = mutableListOf<CalendarEvent>()
private var isInitialized = false
private val profileConfig by lazy { app.config.forProfile().ui }
private val listView
get() = b.agendaDefaultView.agendaView.agendaListView
@ -107,10 +111,10 @@ class AgendaFragmentDefault(
isInitialized = false
withContext(Dispatchers.Default) {
if (profileConfig.agendaLessonChanges)
if (app.profile.config.ui.agendaLessonChanges)
addLessonChanges(events)
if (profileConfig.agendaTeacherAbsence)
if (app.profile.config.ui.agendaTeacherAbsence)
addTeacherAbsence(events)
}
@ -127,7 +131,7 @@ class AgendaFragmentDefault(
val dateStart = app.profile.dateSemester1Start.asCalendar
val dateEnd = app.profile.dateYearEnd.asCalendar
val isCompactMode = profileConfig.agendaCompactMode
val isCompactMode = app.profile.config.ui.agendaCompactMode
b.agendaDefaultView.init(
events,
@ -247,7 +251,7 @@ class AgendaFragmentDefault(
) {
events.removeAll { it is AgendaEvent || it is AgendaEventGroup }
if (!profileConfig.agendaGroupByType) {
if (!app.profile.config.ui.agendaGroupByType) {
events += eventList.map {
if (!it.seen)
unreadDates.add(it.date.value)

View File

@ -18,7 +18,6 @@ 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.Metadata
import pl.szczodrzynski.edziennik.data.db.enums.MetadataType
import pl.szczodrzynski.edziennik.databinding.AttendanceFragmentBinding
import pl.szczodrzynski.edziennik.ext.Bundle
@ -83,7 +82,7 @@ class AttendanceFragment : Fragment(), CoroutineScope {
activity.gainAttention()
if (pageSelection == 1)
pageSelection = app.config.forProfile().attendance.attendancePageSelection
pageSelection = app.profile.config.attendance.attendancePageSelection
val pagerAdapter = FragmentLazyPagerAdapter(
parentFragmentManager,
@ -114,7 +113,7 @@ class AttendanceFragment : Fragment(), CoroutineScope {
currentItem = pageSelection
addOnPageSelectedListener {
pageSelection = it
app.config.forProfile().attendance.attendancePageSelection = it
app.profile.config.attendance.attendancePageSelection = it
}
b.tabLayout.setupWithViewPager(this)
}

View File

@ -129,8 +129,8 @@ class AttendanceListFragment : LazyFragment(), CoroutineScope {
if (attendance.isEmpty())
return mutableListOf()
val groupConsecutiveDays = app.config.forProfile().attendance.groupConsecutiveDays
val showPresenceInMonth = app.config.forProfile().attendance.showPresenceInMonth
val groupConsecutiveDays = app.profile.config.attendance.groupConsecutiveDays
val showPresenceInMonth = app.profile.config.attendance.showPresenceInMonth
if (viewType == AttendanceFragment.VIEW_DAYS) {
val items = attendance

View File

@ -12,11 +12,16 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.isVisible
import androidx.recyclerview.widget.LinearLayoutManager
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.gson.*
import com.google.gson.JsonArray
import com.google.gson.JsonObject
import com.google.gson.JsonParser
import com.google.gson.JsonPrimitive
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import pl.szczodrzynski.edziennik.*
import pl.szczodrzynski.edziennik.App
import pl.szczodrzynski.edziennik.MainActivity
import pl.szczodrzynski.edziennik.R
import pl.szczodrzynski.edziennik.data.api.models.ApiError
import pl.szczodrzynski.edziennik.databinding.TemplateListPageFragmentBinding
import pl.szczodrzynski.edziennik.ext.*
@ -66,7 +71,7 @@ class LabProfileFragment : LazyFragment(), CoroutineScope {
"LoginStore" -> loginStore
"LoginStore / data" -> loginStore?.data ?: JsonObject()
"Config" -> app.config.values
"Config (profile)" -> app.config.forProfile().values
"Config (profile)" -> app.profile.config.values
else -> when (obj) {
is JsonObject -> (obj as JsonObject).get(el)
is JsonArray -> (obj as JsonArray).get(el.toInt())
@ -176,7 +181,7 @@ class LabProfileFragment : LazyFragment(), CoroutineScope {
json.add("LoginStore", app.gson.toJsonTree(loginStore))
json.add("LoginStore / data", loginStore?.data ?: JsonObject())
json.add("Config", JsonParser.parseString(app.gson.toJson(app.config.values.toSortedMap())))
json.add("Config (profile)", JsonParser.parseString(app.gson.toJson(app.config.forProfile().values.toSortedMap())))
json.add("Config (profile)", JsonParser.parseString(app.gson.toJson(app.profile.config.values.toSortedMap())))
}
adapter.items = LabJsonAdapter.expand(json, 0)
adapter.notifyDataSetChanged()

View File

@ -6,13 +6,11 @@ package pl.szczodrzynski.edziennik.ui.dialogs.settings
import android.view.LayoutInflater
import androidx.appcompat.app.AppCompatActivity
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import pl.szczodrzynski.edziennik.*
import pl.szczodrzynski.edziennik.R
import pl.szczodrzynski.edziennik.data.db.entity.Profile
import pl.szczodrzynski.edziennik.databinding.DialogConfigAgendaBinding
import pl.szczodrzynski.edziennik.ext.onChange
import pl.szczodrzynski.edziennik.ui.dialogs.base.ConfigDialog
import java.util.*
class AgendaConfigDialog(
activity: AppCompatActivity,
@ -32,11 +30,9 @@ class AgendaConfigDialog(
override fun inflate(layoutInflater: LayoutInflater) =
DialogConfigAgendaBinding.inflate(layoutInflater)
private val profileConfig by lazy { app.config.forProfile() }
override suspend fun loadConfig() {
b.config = profileConfig
b.isAgendaMode = profileConfig.ui.agendaViewType == Profile.AGENDA_DEFAULT
b.config = app.profile.config
b.isAgendaMode = app.profile.config.ui.agendaViewType == Profile.AGENDA_DEFAULT
var calledFromListener = false
b.eventSharingEnabled.isChecked = app.profile.canShare

View File

@ -29,23 +29,21 @@ class AttendanceConfigDialog(
override fun inflate(layoutInflater: LayoutInflater) =
AttendanceConfigDialogBinding.inflate(layoutInflater)
private val profileConfig by lazy { app.config.getFor(app.profileId).attendance }
override suspend fun loadConfig() {
b.useSymbols.isChecked = profileConfig.useSymbols
b.groupConsecutiveDays.isChecked = profileConfig.groupConsecutiveDays
b.showPresenceInMonth.isChecked = profileConfig.showPresenceInMonth
b.useSymbols.isChecked = app.profile.config.attendance.useSymbols
b.groupConsecutiveDays.isChecked = app.profile.config.attendance.groupConsecutiveDays
b.showPresenceInMonth.isChecked = app.profile.config.attendance.showPresenceInMonth
}
override fun initView() {
b.useSymbols.onChange { _, isChecked ->
profileConfig.useSymbols = isChecked
app.profile.config.attendance.useSymbols = isChecked
}
b.groupConsecutiveDays.onChange { _, isChecked ->
profileConfig.groupConsecutiveDays = isChecked
app.profile.config.attendance.groupConsecutiveDays = isChecked
}
b.showPresenceInMonth.onChange { _, isChecked ->
profileConfig.showPresenceInMonth = isChecked
app.profile.config.attendance.showPresenceInMonth = isChecked
}
}
}

View File

@ -45,17 +45,15 @@ class GradesConfigDialog(
override fun inflate(layoutInflater: LayoutInflater) =
DialogConfigGradesBinding.inflate(layoutInflater)
private val profileConfig by lazy { app.config.getFor(app.profileId).grades }
@SuppressLint("SetTextI18n")
override suspend fun loadConfig() {
b.customPlusCheckBox.isChecked = profileConfig.plusValue != null
b.customPlusCheckBox.isChecked = app.profile.config.grades.plusValue != null
b.customPlusValue.isVisible = b.customPlusCheckBox.isChecked
b.customMinusCheckBox.isChecked = profileConfig.minusValue != null
b.customMinusCheckBox.isChecked = app.profile.config.grades.minusValue != null
b.customMinusValue.isVisible = b.customMinusCheckBox.isChecked
b.customPlusValue.progress = profileConfig.plusValue ?: 0.5f
b.customMinusValue.progress = profileConfig.minusValue ?: 0.25f
b.customPlusValue.progress = app.profile.config.grades.plusValue ?: 0.5f
b.customMinusValue.progress = app.profile.config.grades.minusValue ?: 0.25f
when (config.orderBy) {
ORDER_BY_DATE_DESC -> b.sortGradesByDateRadio
@ -63,13 +61,13 @@ class GradesConfigDialog(
else -> null
}?.isChecked = true
when (profileConfig.colorMode) {
when (app.profile.config.grades.colorMode) {
COLOR_MODE_DEFAULT -> b.gradeColorFromERegister
COLOR_MODE_WEIGHTED -> b.gradeColorByValue
else -> null
}?.isChecked = true
when (profileConfig.yearAverageMode) {
when (app.profile.config.grades.yearAverageMode) {
YEAR_ALL_GRADES -> b.gradeAverageMode4
YEAR_1_AVG_2_AVG -> b.gradeAverageMode0
YEAR_1_SEM_2_AVG -> b.gradeAverageMode1
@ -79,21 +77,21 @@ class GradesConfigDialog(
}?.isChecked = true
b.dontCountGrades.isChecked =
profileConfig.dontCountEnabled && profileConfig.dontCountGrades.isNotEmpty()
b.hideImproved.isChecked = profileConfig.hideImproved
b.averageWithoutWeight.isChecked = profileConfig.averageWithoutWeight
app.profile.config.grades.dontCountEnabled && app.profile.config.grades.dontCountGrades.isNotEmpty()
b.hideImproved.isChecked = app.profile.config.grades.hideImproved
b.averageWithoutWeight.isChecked = app.profile.config.grades.averageWithoutWeight
if (profileConfig.dontCountGrades.isEmpty()) {
if (app.profile.config.grades.dontCountGrades.isEmpty()) {
b.dontCountGradesText.setText("nb, 0, bz, bd")
} else {
b.dontCountGradesText.setText(profileConfig.dontCountGrades.join(", "))
b.dontCountGradesText.setText(app.profile.config.grades.dontCountGrades.join(", "))
}
}
override suspend fun saveConfig() {
profileConfig.plusValue =
app.profile.config.grades.plusValue =
if (b.customPlusCheckBox.isChecked) b.customPlusValue.progress else null
profileConfig.minusValue =
app.profile.config.grades.minusValue =
if (b.customMinusCheckBox.isChecked) b.customMinusValue.progress else null
b.dontCountGradesText.setText(
@ -103,8 +101,8 @@ class GradesConfigDialog(
?.lowercase()
?.replace(", ", ",")
)
profileConfig.dontCountEnabled = b.dontCountGrades.isChecked
profileConfig.dontCountGrades = b.dontCountGradesText.text
app.profile.config.grades.dontCountEnabled = b.dontCountGrades.isChecked
app.profile.config.grades.dontCountGrades = b.dontCountGradesText.text
?.split(",")
?.map { it.trim() }
?: listOf()
@ -121,39 +119,39 @@ class GradesConfigDialog(
// who the hell named those methods
// THIS SHIT DOES NOT EVEN WORK
b.customPlusValue.doOnStopTrackingTouch {
profileConfig.plusValue = it.progress
app.profile.config.grades.plusValue = it.progress
}
b.customMinusValue.doOnStopTrackingTouch {
profileConfig.minusValue = it.progress
app.profile.config.grades.minusValue = it.progress
}
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
app.profile.config.grades.colorMode = COLOR_MODE_DEFAULT
}
b.gradeColorByValue.setOnSelectedListener { profileConfig.colorMode = COLOR_MODE_WEIGHTED }
b.gradeColorByValue.setOnSelectedListener { app.profile.config.grades.colorMode = COLOR_MODE_WEIGHTED }
b.gradeAverageMode4.setOnSelectedListener {
profileConfig.yearAverageMode = YEAR_ALL_GRADES
app.profile.config.grades.yearAverageMode = YEAR_ALL_GRADES
}
b.gradeAverageMode0.setOnSelectedListener {
profileConfig.yearAverageMode = YEAR_1_AVG_2_AVG
app.profile.config.grades.yearAverageMode = YEAR_1_AVG_2_AVG
}
b.gradeAverageMode1.setOnSelectedListener {
profileConfig.yearAverageMode = YEAR_1_SEM_2_AVG
app.profile.config.grades.yearAverageMode = YEAR_1_SEM_2_AVG
}
b.gradeAverageMode2.setOnSelectedListener {
profileConfig.yearAverageMode = YEAR_1_AVG_2_SEM
app.profile.config.grades.yearAverageMode = YEAR_1_AVG_2_SEM
}
b.gradeAverageMode3.setOnSelectedListener {
profileConfig.yearAverageMode = YEAR_1_SEM_2_SEM
app.profile.config.grades.yearAverageMode = YEAR_1_SEM_2_SEM
}
b.hideImproved.onChange { _, isChecked -> profileConfig.hideImproved = isChecked }
b.hideImproved.onChange { _, isChecked -> app.profile.config.grades.hideImproved = isChecked }
b.averageWithoutWeight.onChange { _, isChecked ->
profileConfig.averageWithoutWeight = isChecked
app.profile.config.grades.averageWithoutWeight = isChecked
}
b.averageWithoutWeightHelp.onClick {

View File

@ -28,13 +28,11 @@ class MessagesConfigDialog(
override fun inflate(layoutInflater: LayoutInflater) =
MessagesConfigDialogBinding.inflate(layoutInflater)
private val profileConfig by lazy { app.config.getFor(app.profileId).ui }
override suspend fun loadConfig() {
b.config = profileConfig
b.config = app.profile.config.ui
b.greetingText.setText(
profileConfig.messagesGreetingText
app.profile.config.ui.messagesGreetingText
?: "\n\nZ poważaniem\n${app.profile.accountOwnerName}"
)
}
@ -42,8 +40,8 @@ class MessagesConfigDialog(
override suspend fun saveConfig() {
val greetingText = b.greetingText.text?.toString()?.trim()
if (greetingText.isNullOrEmpty())
profileConfig.messagesGreetingText = null
app.profile.config.ui.messagesGreetingText = null
else
profileConfig.messagesGreetingText = "\n\n$greetingText"
app.profile.config.ui.messagesGreetingText = "\n\n$greetingText"
}
}

View File

@ -30,7 +30,7 @@ class NotificationFilterDialog(
.associateBy { it.titleRes.resolveString(activity) as CharSequence }
override fun getDefaultSelectedItems() = NotificationType.values()
.filter { it.enabledByDefault != null && it !in app.config.forProfile().sync.notificationFilter }
.filter { it.enabledByDefault != null && it !in app.profile.config.sync.notificationFilter }
.toSet()
override suspend fun onShow() = Unit
@ -47,7 +47,7 @@ class NotificationFilterDialog(
.setTitle(R.string.are_you_sure)
.setMessage(R.string.notification_filter_warning)
.setPositiveButton(R.string.ok) { _, _ ->
app.config.forProfile().sync.notificationFilter = disabledTypes
app.profile.config.sync.notificationFilter = disabledTypes
dismiss()
}
.setNegativeButton(R.string.cancel, null)
@ -55,7 +55,7 @@ class NotificationFilterDialog(
return NO_DISMISS
}
app.config.forProfile().sync.notificationFilter = disabledTypes
app.profile.config.sync.notificationFilter = disabledTypes
return DISMISS
}

View File

@ -7,7 +7,11 @@ package pl.szczodrzynski.edziennik.ui.dialogs.settings
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import kotlinx.coroutines.*
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import pl.szczodrzynski.edziennik.App
import pl.szczodrzynski.edziennik.R
import pl.szczodrzynski.edziennik.data.api.szkolny.SzkolnyApi
@ -117,7 +121,7 @@ class RegistrationConfigDialog(
profile.registration = Profile.REGISTRATION_ENABLED
// force full registration of the user
App.config.getFor(profile.id).hash = ""
profile.config.hash = ""
SzkolnyApi(app).runCatching(activity) {
AppSync(app, mutableListOf(), listOf(profile), this).run(

View File

@ -30,14 +30,12 @@ class TimetableConfigDialog(
override fun inflate(layoutInflater: LayoutInflater) =
TimetableConfigDialogBinding.inflate(layoutInflater)
private val profileConfig by lazy { app.config.getFor(app.profileId).ui }
override fun initView() {
b.features = app.profile.loginStoreType.features
}
override suspend fun loadConfig() {
b.config = profileConfig
b.config = app.profile.config.ui
}
override suspend fun saveConfig() {

View File

@ -13,23 +13,33 @@ import androidx.appcompat.app.AppCompatActivity
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.jaredrummler.android.colorpicker.ColorPickerDialog
import com.jaredrummler.android.colorpicker.ColorPickerDialogListener
import kotlinx.coroutines.*
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import pl.szczodrzynski.edziennik.*
import pl.szczodrzynski.edziennik.R
import pl.szczodrzynski.edziennik.data.api.edziennik.EdziennikTask
import pl.szczodrzynski.edziennik.data.api.events.ApiTaskAllFinishedEvent
import pl.szczodrzynski.edziennik.data.api.events.ApiTaskErrorEvent
import pl.szczodrzynski.edziennik.data.api.events.ApiTaskFinishedEvent
import pl.szczodrzynski.edziennik.data.api.szkolny.SzkolnyApi
import pl.szczodrzynski.edziennik.data.db.entity.*
import pl.szczodrzynski.edziennik.data.db.entity.Event
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
import pl.szczodrzynski.edziennik.data.db.entity.Profile
import pl.szczodrzynski.edziennik.data.db.entity.Subject
import pl.szczodrzynski.edziennik.data.db.enums.FeatureType
import pl.szczodrzynski.edziennik.data.db.enums.MetadataType
import pl.szczodrzynski.edziennik.data.db.full.EventFull
import pl.szczodrzynski.edziennik.data.db.full.LessonFull
import pl.szczodrzynski.edziennik.databinding.DialogEventManualV2Binding
import pl.szczodrzynski.edziennik.ext.*
import pl.szczodrzynski.edziennik.ext.JsonObject
import pl.szczodrzynski.edziennik.ext.getStudentData
import pl.szczodrzynski.edziennik.ext.onChange
import pl.szczodrzynski.edziennik.ext.onClick
import pl.szczodrzynski.edziennik.ext.setText
import pl.szczodrzynski.edziennik.ext.setTintColor
import pl.szczodrzynski.edziennik.ui.dialogs.base.BindingDialog
import pl.szczodrzynski.edziennik.ui.dialogs.settings.RegistrationConfigDialog
import pl.szczodrzynski.edziennik.ui.views.TimeDropdown.Companion.DISPLAY_LESSONS
@ -80,8 +90,6 @@ class EventManualDialog(
SzkolnyApi(app)
}
private val profileConfig by lazy { app.config.forProfile() }
private var enqueuedWeekDialog: AlertDialog? = null
private var enqueuedWeekStart = Date.getToday()
@ -137,7 +145,7 @@ class EventManualDialog(
loadLists()
val shareByDefault = profileConfig.shareByDefault && profile.canShare
val shareByDefault = app.profile.config.shareByDefault && profile.canShare
b.shareSwitch.isChecked = editingShared || editingEvent == null && shareByDefault
b.shareSwitch.isEnabled = !editingShared || editingOwn

View File

@ -81,7 +81,7 @@ class GradesListFragment : Fragment(), CoroutineScope {
}
val items = when {
app.config.forProfile().grades.hideSticksFromOld && App.devMode -> grades.filter { it.value != 1.0f }
app.profile.config.grades.hideSticksFromOld && App.devMode -> grades.filter { it.value != 1.0f }
else -> grades
}

View File

@ -12,7 +12,9 @@ import androidx.fragment.app.Fragment
import androidx.lifecycle.Observer
import androidx.recyclerview.widget.LinearLayoutManager
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import pl.szczodrzynski.edziennik.*
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.databinding.FragmentGradesEditorBinding
import pl.szczodrzynski.edziennik.ext.getFloat
@ -37,7 +39,7 @@ class GradesEditorFragment : Fragment() {
private val navController: NavController by lazy { Navigation.findNavController(b.root) }
*/
private val config by lazy { app.config.getFor(App.profileId).grades }
private val config by lazy { app.profile.config.grades }
private var subjectId: Long = -1
private var semester: Int = 1

View File

@ -37,18 +37,17 @@ class HomeConfigDialog(
).mapKeys { (resId, _) -> activity.getString(resId) }
override fun getDefaultSelectedItems() =
profileConfig.homeCards
app.profile.config.ui.homeCards
.filter { it.profileId == App.profileId }
.map { it.cardId }
.toSet()
override suspend fun onShow() = Unit
private val profileConfig by lazy { app.config.getFor(app.profileId).ui }
private var configChanged = false
override suspend fun onPositiveClick(): Boolean {
val homeCards = profileConfig.homeCards.toMutableList()
val homeCards = app.profile.config.ui.homeCards.toMutableList()
homeCards.removeAll { it.profileId == App.profileId }
homeCards += getMultiSelection().mapNotNull {
HomeCardModel(
@ -56,7 +55,7 @@ class HomeConfigDialog(
cardId = it as? Int ?: return@mapNotNull null
)
}
profileConfig.homeCards = homeCards
app.profile.config.ui.homeCards = homeCards
return DISMISS
}

View File

@ -50,18 +50,18 @@ class HomeFragment : Fragment(), CoroutineScope {
cardAdapter.items[toPosition] = fromCard
cardAdapter.notifyItemMoved(fromPosition, toPosition)
val homeCards = App.config.forProfile().ui.homeCards.toMutableList()
val homeCards = App.profile.config.ui.homeCards.toMutableList()
val fromIndex = homeCards.indexOfFirst { it.cardId == fromCard.id }
val toIndex = homeCards.indexOfFirst { it.cardId == toCard.id }
val fromPair = homeCards[fromIndex]
homeCards[fromIndex] = homeCards[toIndex]
homeCards[toIndex] = fromPair
App.config.forProfile().ui.homeCards = homeCards
App.profile.config.ui.homeCards = homeCards
return true
}
fun removeCard(position: Int, cardAdapter: HomeCardAdapter) {
val homeCards = App.config.forProfile().ui.homeCards.toMutableList()
val homeCards = App.profile.config.ui.homeCards.toMutableList()
if (position >= homeCards.size)
return
val card = cardAdapter.items[position]
@ -71,7 +71,7 @@ class HomeFragment : Fragment(), CoroutineScope {
return
}
homeCards.removeAll { it.cardId == card.id }
App.config.forProfile().ui.homeCards = homeCards
App.profile.config.ui.homeCards = homeCards
}
}
@ -144,7 +144,7 @@ class HomeFragment : Fragment(), CoroutineScope {
b.refreshLayout.isEnabled = scrollY == 0
}
val cards = app.config.forProfile().ui.homeCards.filter { it.profileId == app.profile.id }.toMutableList()
val cards = app.profile.config.ui.homeCards.filter { it.profileId == app.profile.id }.toMutableList()
if (cards.isEmpty()) {
cards += listOfNotNull(
HomeCardModel(app.profile.id, HomeCard.CARD_LUCKY_NUMBER).takeIf { app.profile.hasUIFeature(FeatureType.LUCKY_NUMBER) },
@ -153,7 +153,7 @@ class HomeFragment : Fragment(), CoroutineScope {
HomeCardModel(app.profile.id, HomeCard.CARD_GRADES).takeIf { app.profile.hasUIFeature(FeatureType.GRADES) },
HomeCardModel(app.profile.id, HomeCard.CARD_NOTES),
)
app.config.forProfile().ui.homeCards = app.config.forProfile().ui.homeCards.toMutableList().also { it.addAll(cards) }
app.profile.config.ui.homeCards = app.profile.config.ui.homeCards.toMutableList().also { it.addAll(cards) }
}
val items = mutableListOf<HomeCard>()

View File

@ -11,7 +11,11 @@ import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.navigation.NavController
import androidx.navigation.Navigation
import kotlinx.coroutines.*
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
@ -73,9 +77,8 @@ class LoginSyncFragment : Fragment(), CoroutineScope {
Profile.REGISTRATION_DISABLED
val data = AppData.get(it.loginStoreType)
val config = app.config.getFor(it.id)
for ((key, value) in data.configOverrides) {
config.set(key, value)
it.config.set(key, value)
}
app.db.eventTypeDao().addDefaultTypes(it)

View File

@ -67,9 +67,8 @@ class MessagesComposeFragment : Fragment(), CoroutineScope {
get() = app.messageManager
private val textStylingManager
get() = app.textStylingManager
private val profileConfig by lazy { app.config.forProfile().ui }
private val greetingText
get() = profileConfig.messagesGreetingText ?: "\n\nZ poważaniem\n${app.profile.accountOwnerName}"
get() = app.profile.config.ui.messagesGreetingText ?: "\n\nZ poważaniem\n${app.profile.accountOwnerName}"
private val teachers = mutableListOf<Teacher>()
@ -242,9 +241,9 @@ class MessagesComposeFragment : Fragment(), CoroutineScope {
subject = b.subject,
body = b.text,
teachers = teachers,
greetingOnCompose = profileConfig.messagesGreetingOnCompose,
greetingOnReply = profileConfig.messagesGreetingOnReply,
greetingOnForward = profileConfig.messagesGreetingOnForward,
greetingOnCompose = app.profile.config.ui.messagesGreetingOnCompose,
greetingOnReply = app.profile.config.ui.messagesGreetingOnReply,
greetingOnForward = app.profile.config.ui.messagesGreetingOnForward,
greetingText = greetingText,
)
stylingConfig = StylingConfig(

View File

@ -13,7 +13,6 @@ import com.mikepenz.iconics.typeface.library.community.material.CommunityMateria
import com.mikepenz.iconics.utils.colorInt
import com.mikepenz.iconics.utils.sizeDp
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import pl.szczodrzynski.edziennik.R
import pl.szczodrzynski.edziennik.data.db.entity.Note
@ -60,8 +59,6 @@ class NoteEditorDialog(
private val textStylingManager
get() = app.textStylingManager
private val profileConfig by lazy { app.config.forProfile() }
private var progressDialog: AlertDialog? = null
override suspend fun onPositiveClick(): Boolean {
@ -136,7 +133,7 @@ class NoteEditorDialog(
b.ownerType = owner?.getNoteType() ?: Note.OwnerType.NONE
b.editingNote = editingNote
b.shareByDefault = profileConfig.shareByDefault && profile?.canShare == true
b.shareByDefault = app.profile.config.shareByDefault && profile?.canShare == true
b.color.clear().append(Note.Color.values().map { color ->
TextInputDropDown.Item(

View File

@ -16,7 +16,7 @@ abstract class SettingsCard(
protected val activity: MainActivity = util.activity
protected val configGlobal by lazy { app.config }
protected val configProfile by lazy { app.config.forProfile() }
protected val configProfile by lazy { app.profile.config }
val card by lazy {
buildCard()

View File

@ -14,25 +14,48 @@ import android.widget.LinearLayout
import android.widget.TextView
import androidx.asynclayoutinflater.view.AsyncLayoutInflater
import androidx.core.graphics.ColorUtils
import androidx.core.view.*
import androidx.core.view.isVisible
import androidx.core.view.marginTop
import androidx.core.view.setPadding
import androidx.core.view.updateLayoutParams
import androidx.core.view.updateMargins
import com.linkedin.android.tachyon.DayView
import com.linkedin.android.tachyon.DayViewConfig
import com.mikepenz.iconics.IconicsDrawable
import com.mikepenz.iconics.utils.colorInt
import com.mikepenz.iconics.utils.sizeDp
import kotlinx.coroutines.*
import pl.szczodrzynski.edziennik.*
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import pl.szczodrzynski.edziennik.App
import pl.szczodrzynski.edziennik.MainActivity
import pl.szczodrzynski.edziennik.R
import pl.szczodrzynski.edziennik.data.api.edziennik.EdziennikTask
import pl.szczodrzynski.edziennik.data.db.entity.Lesson
import pl.szczodrzynski.edziennik.data.db.enums.FeatureType
import pl.szczodrzynski.edziennik.data.db.enums.LoginType
import pl.szczodrzynski.edziennik.data.db.full.AttendanceFull
import pl.szczodrzynski.edziennik.data.db.full.EventFull
import pl.szczodrzynski.edziennik.data.db.full.LessonFull
import pl.szczodrzynski.edziennik.databinding.TimetableDayFragmentBinding
import pl.szczodrzynski.edziennik.databinding.TimetableLessonBinding
import pl.szczodrzynski.edziennik.databinding.TimetableNoTimetableBinding
import pl.szczodrzynski.edziennik.ext.*
import pl.szczodrzynski.edziennik.ext.Intent
import pl.szczodrzynski.edziennik.ext.JsonObject
import pl.szczodrzynski.edziennik.ext.asColoredSpannable
import pl.szczodrzynski.edziennik.ext.asStrikethroughSpannable
import pl.szczodrzynski.edziennik.ext.concat
import pl.szczodrzynski.edziennik.ext.dp
import pl.szczodrzynski.edziennik.ext.findParentById
import pl.szczodrzynski.edziennik.ext.getStudentData
import pl.szczodrzynski.edziennik.ext.listOfNotEmpty
import pl.szczodrzynski.edziennik.ext.onClick
import pl.szczodrzynski.edziennik.ext.resolveAttr
import pl.szczodrzynski.edziennik.ext.resolveDrawable
import pl.szczodrzynski.edziennik.ext.setText
import pl.szczodrzynski.edziennik.ext.setTintColor
import pl.szczodrzynski.edziennik.ext.startCoroutineTimer
import pl.szczodrzynski.edziennik.ui.base.lazypager.LazyFragment
import pl.szczodrzynski.edziennik.ui.timetable.TimetableFragment.Companion.DEFAULT_END_HOUR
import pl.szczodrzynski.edziennik.ui.timetable.TimetableFragment.Companion.DEFAULT_START_HOUR
@ -76,7 +99,6 @@ class TimetableDayFragment : LazyFragment(), CoroutineScope {
// find SwipeRefreshLayout in the hierarchy
private val refreshLayout by lazy { view?.findParentById(R.id.refreshLayout) }
private val profileConfig by lazy { app.config.forProfile().ui }
private val dayViewDelegate = mutableLazy {
val dayView = DayView(activity, DayViewConfig(
@ -186,7 +208,7 @@ class TimetableDayFragment : LazyFragment(), CoroutineScope {
val minStartHour = lessonsActual.minOf { it.displayStartTime?.hour ?: DEFAULT_END_HOUR }
val maxEndHour = lessonsActual.maxOf { it.displayEndTime?.hour?.plus(1) ?: DEFAULT_START_HOUR }
if (profileConfig.timetableTrimHourRange) {
if (app.profile.config.ui.timetableTrimHourRange) {
dayViewDelegate.deinitialize()
// end/start defaults are swapped on purpose
startHour = minStartHour
@ -238,7 +260,7 @@ class TimetableDayFragment : LazyFragment(), CoroutineScope {
val colorSecondary = android.R.attr.textColorSecondary.resolveAttr(activity)
for (lesson in lessons) {
val attendance = if (profileConfig.timetableShowAttendance)
val attendance = if (app.profile.config.ui.timetableShowAttendance)
attendanceList.find { it.startTime == lesson.startTime }
else
null
@ -272,7 +294,7 @@ class TimetableDayFragment : LazyFragment(), CoroutineScope {
}
val eventIcons = listOf(lb.event1, lb.event2, lb.event3)
if (profileConfig.timetableShowEvents) {
if (app.profile.config.ui.timetableShowEvents) {
val eventList = events.filter { it.time != null && it.time == lesson.displayStartTime }.take(3)
for ((i, eventIcon) in eventIcons.withIndex()) {
eventList.getOrNull(i).let {
@ -323,7 +345,7 @@ class TimetableDayFragment : LazyFragment(), CoroutineScope {
val lessonText =
lesson.getNoteSubstituteText(showNotes = true) ?: lesson.displaySubjectName
val (subjectTextPrimary, subjectTextSecondary) = if (profileConfig.timetableColorSubjectName) {
val (subjectTextPrimary, subjectTextSecondary) = if (app.profile.config.ui.timetableColorSubjectName) {
val subjectColor = lesson.color ?: Colors.stringToMaterialColorCRC(lessonText?.toString() ?: "")
if (lb.annotationVisible) {
lb.subjectContainer.background = ColorDrawable(subjectColor)

View File

@ -58,7 +58,6 @@ class TimetableFragment : Fragment(), CoroutineScope {
private var fabShown = false
private val items = mutableListOf<Date>()
private val profileConfig by lazy { app.config.forProfile().ui }
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
activity = (getActivity() as MainActivity?) ?: return null

View File

@ -24,7 +24,7 @@ class AttendanceManager(val app: App) : CoroutineScope {
get() = job + Dispatchers.Default
val useSymbols
get() = app.config.forProfile().attendance.useSymbols
get() = app.profile.config.attendance.useSymbols
fun getTypeShort(baseType: Int): String {
return when (baseType) {

View File

@ -16,7 +16,13 @@ import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_POINT_AVG
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_POINT_SUM
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_YEAR_FINAL
import pl.szczodrzynski.edziennik.data.db.full.GradeFull
import pl.szczodrzynski.edziennik.ext.*
import pl.szczodrzynski.edziennik.ext.asColoredSpannable
import pl.szczodrzynski.edziennik.ext.get
import pl.szczodrzynski.edziennik.ext.ifNotNull
import pl.szczodrzynski.edziennik.ext.notEmptyOrNull
import pl.szczodrzynski.edziennik.ext.plural
import pl.szczodrzynski.edziennik.ext.resolveAttr
import pl.szczodrzynski.edziennik.ext.startCoroutineTimer
import pl.szczodrzynski.edziennik.ui.grades.models.GradesAverages
import pl.szczodrzynski.edziennik.ui.grades.models.GradesSemester
import java.text.DecimalFormat
@ -48,21 +54,21 @@ class GradesManager(val app: App) : CoroutineScope {
val orderBy
get() = app.config.grades.orderBy
val yearAverageMode
get() = app.config.forProfile().grades.yearAverageMode
get() = app.profile.config.grades.yearAverageMode
val colorMode
get() = app.config.forProfile().grades.colorMode
get() = app.profile.config.grades.colorMode
val plusValue
get() = app.config.forProfile().grades.plusValue
get() = app.profile.config.grades.plusValue
val minusValue
get() = app.config.forProfile().grades.minusValue
get() = app.profile.config.grades.minusValue
val dontCountEnabled
get() = app.config.forProfile().grades.dontCountEnabled
get() = app.profile.config.grades.dontCountEnabled
val dontCountGrades
get() = app.config.forProfile().grades.dontCountGrades
get() = app.profile.config.grades.dontCountGrades
val hideImproved
get() = app.config.forProfile().grades.hideImproved
get() = app.profile.config.grades.hideImproved
val averageWithoutWeight
get() = app.config.forProfile().grades.averageWithoutWeight
get() = app.profile.config.grades.averageWithoutWeight
fun getOrderByString() = when (orderBy) {