[Agenda] Add config dialog. Add compact mode.

This commit is contained in:
Kuba Szczodrzyński 2021-04-10 20:51:29 +02:00
parent b14ef5cd78
commit 3eae8fb58b
No known key found for this signature in database
GPG Key ID: 70CB8A85BA1633CB
9 changed files with 359 additions and 36 deletions

View File

@ -15,6 +15,36 @@ class ProfileConfigUI(private val config: ProfileConfig) {
get() { mAgendaViewType = mAgendaViewType ?: config.values.get("agendaViewType", 0); return mAgendaViewType ?: AGENDA_DEFAULT }
set(value) { config.set("agendaViewType", value); mAgendaViewType = value }
private var mAgendaCompactMode: Boolean? = null
var agendaCompactMode: Boolean
get() { mAgendaCompactMode = mAgendaCompactMode ?: config.values.get("agendaCompactMode", false); return mAgendaCompactMode ?: false }
set(value) { config.set("agendaCompactMode", value); mAgendaCompactMode = value }
private var mAgendaGroupByType: Boolean? = null
var agendaGroupByType: Boolean
get() { mAgendaGroupByType = mAgendaGroupByType ?: config.values.get("agendaGroupByType", false); return mAgendaGroupByType ?: false }
set(value) { config.set("agendaGroupByType", value); mAgendaGroupByType = value }
private var mAgendaLessonChanges: Boolean? = null
var agendaLessonChanges: Boolean
get() { mAgendaLessonChanges = mAgendaLessonChanges ?: config.values.get("agendaLessonChanges", true); return mAgendaLessonChanges ?: true }
set(value) { config.set("agendaLessonChanges", value); mAgendaLessonChanges = value }
private var mAgendaTeacherAbsence: Boolean? = null
var agendaTeacherAbsence: Boolean
get() { mAgendaTeacherAbsence = mAgendaTeacherAbsence ?: config.values.get("agendaTeacherAbsence", true); return mAgendaTeacherAbsence ?: true }
set(value) { config.set("agendaTeacherAbsence", value); mAgendaTeacherAbsence = value }
private var mAgendaElearningMark: Boolean? = null
var agendaElearningMark: Boolean
get() { mAgendaElearningMark = mAgendaElearningMark ?: config.values.get("agendaElearningMark", false); return mAgendaElearningMark ?: false }
set(value) { config.set("agendaElearningMark", value); mAgendaElearningMark = value }
private var mAgendaElearningGroup: Boolean? = null
var agendaElearningGroup: Boolean
get() { mAgendaElearningGroup = mAgendaElearningGroup ?: config.values.get("agendaElearningGroup", true); return mAgendaElearningGroup ?: true }
set(value) { config.set("agendaElearningGroup", value); mAgendaElearningGroup = value }
private var mHomeCards: List<HomeCardModel>? = null
var homeCards: List<HomeCardModel>
get() { mHomeCards = mHomeCards ?: config.values.get("homeCards", listOf(), HomeCardModel::class.java); return mHomeCards ?: listOf() }

View File

@ -0,0 +1,93 @@
/*
* Copyright (c) Kuba Szczodrzyński 2021-4-10.
*/
package pl.szczodrzynski.edziennik.ui.dialogs.agenda
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import pl.szczodrzynski.edziennik.*
import pl.szczodrzynski.edziennik.data.db.entity.Profile
import pl.szczodrzynski.edziennik.data.db.entity.Profile.Companion.REGISTRATION_ENABLED
import pl.szczodrzynski.edziennik.databinding.DialogConfigAgendaBinding
import pl.szczodrzynski.edziennik.ui.dialogs.sync.RegistrationConfigDialog
import java.util.*
class AgendaConfigDialog(
private val activity: AppCompatActivity,
private val reloadOnDismiss: Boolean = true,
private val onShowListener: ((tag: String) -> Unit)? = null,
private val onDismissListener: ((tag: String) -> Unit)? = null
) {
companion object {
const val TAG = "AgendaConfigDialog"
}
private val app by lazy { activity.application as App }
private val config by lazy { app.config.ui }
private val profileConfig by lazy { app.config.forProfile().ui }
private lateinit var b: DialogConfigAgendaBinding
private lateinit var dialog: AlertDialog
init { run {
if (activity.isFinishing)
return@run
b = DialogConfigAgendaBinding.inflate(activity.layoutInflater)
onShowListener?.invoke(TAG)
dialog = MaterialAlertDialogBuilder(activity)
.setTitle(R.string.menu_agenda_config)
.setView(b.root)
.setPositiveButton(R.string.ok) { dialog, _ -> dialog.dismiss() }
.setOnDismissListener {
saveConfig()
onDismissListener?.invoke(TAG)
if (reloadOnDismiss) (activity as? MainActivity)?.reloadTarget()
}
.create()
loadConfig()
dialog.show()
}}
private fun loadConfig() {
b.config = profileConfig
b.isAgendaMode = profileConfig.agendaViewType == Profile.AGENDA_DEFAULT
b.eventSharingEnabled.isChecked = app.profile.enableSharedEvents
&& app.profile.registration == REGISTRATION_ENABLED
b.eventSharingEnabled.onChange { _, isChecked ->
if (isChecked && app.profile.registration != REGISTRATION_ENABLED) {
b.eventSharingEnabled.isChecked = false
val dialog = RegistrationConfigDialog(activity, app.profile, onChangeListener = { enabled ->
b.eventSharingEnabled.isChecked = enabled
setEventSharingEnabled(enabled)
}, onShowListener, onDismissListener)
dialog.showEnableDialog()
return@onChange
}
setEventSharingEnabled(isChecked)
}
}
private fun setEventSharingEnabled(enabled: Boolean) {
if (enabled == app.profile.enableSharedEvents)
return
app.profile.enableSharedEvents = enabled
app.profileSave()
MaterialAlertDialogBuilder(activity)
.setTitle(R.string.event_sharing)
.setMessage(
if (enabled)
R.string.settings_register_shared_events_dialog_enabled_text
else
R.string.settings_register_shared_events_dialog_disabled_text
)
.setPositiveButton(R.string.ok, null)
.show()
}
private fun saveConfig() {
}
}

View File

@ -25,6 +25,7 @@ import pl.szczodrzynski.edziennik.data.db.entity.Metadata
import pl.szczodrzynski.edziennik.data.db.entity.Profile
import pl.szczodrzynski.edziennik.databinding.FragmentAgendaCalendarBinding
import pl.szczodrzynski.edziennik.databinding.FragmentAgendaDefaultBinding
import pl.szczodrzynski.edziennik.ui.dialogs.agenda.AgendaConfigDialog
import pl.szczodrzynski.edziennik.ui.dialogs.day.DayDialog
import pl.szczodrzynski.edziennik.ui.dialogs.event.EventManualDialog
import pl.szczodrzynski.edziennik.utils.Themes
@ -78,6 +79,13 @@ class AgendaFragment : Fragment(), CoroutineScope {
defaultDate = AgendaFragmentDefault.selectedDate
)
},
BottomSheetPrimaryItem(true)
.withTitle(R.string.menu_agenda_config)
.withIcon(CommunityMaterial.Icon.cmd_cog_outline)
.withOnClickListener {
activity.bottomSheet.close()
AgendaConfigDialog(activity, true, null, null)
},
BottomSheetPrimaryItem(true)
.withTitle(R.string.menu_agenda_change_view)
.withIcon(if (type == Profile.AGENDA_DEFAULT) CommunityMaterial.Icon.cmd_calendar_outline else CommunityMaterial.Icon2.cmd_format_list_bulleted_square)
@ -135,8 +143,6 @@ class AgendaFragment : Fragment(), CoroutineScope {
agendaDefault = AgendaFragmentDefault(activity, app, b)
agendaDefault?.initView(this@AgendaFragment)
b.progressBar.visibility = View.GONE
}}}
private fun createCalendarAgendaView() { (b as? FragmentAgendaCalendarBinding)?.let { b -> launch {

View File

@ -7,6 +7,7 @@ package pl.szczodrzynski.edziennik.ui.modules.agenda
import android.util.SparseIntArray
import androidx.core.util.forEach
import androidx.core.util.set
import androidx.core.view.isVisible
import com.github.tibolte.agendacalendarview.CalendarManager
import com.github.tibolte.agendacalendarview.CalendarPickerController
import com.github.tibolte.agendacalendarview.agenda.AgendaAdapter
@ -21,6 +22,7 @@ import pl.szczodrzynski.edziennik.MainActivity
import pl.szczodrzynski.edziennik.data.db.full.EventFull
import pl.szczodrzynski.edziennik.databinding.FragmentAgendaDefaultBinding
import pl.szczodrzynski.edziennik.ui.dialogs.day.DayDialog
import pl.szczodrzynski.edziennik.ui.dialogs.event.EventDetailsDialog
import pl.szczodrzynski.edziennik.ui.dialogs.lessonchange.LessonChangeDialog
import pl.szczodrzynski.edziennik.ui.dialogs.teacherabsence.TeacherAbsenceDialog
import pl.szczodrzynski.edziennik.ui.modules.agenda.event.AgendaEvent
@ -44,18 +46,18 @@ 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 }
suspend fun initView(fragment: AgendaFragment) {
isInitialized = false
withContext(Dispatchers.Default) {
if (profileConfig.agendaLessonChanges)
addLessonChanges(events)
val showTeacherAbsences = app.profile.getStudentData("showTeacherAbsences", true)
if (showTeacherAbsences) {
if (profileConfig.agendaTeacherAbsence)
addTeacherAbsence(events)
}
}
app.db.eventDao().getAll(app.profileId).observe(fragment) {
addEvents(events, it)
@ -70,6 +72,8 @@ class AgendaFragmentDefault(
val dateStart = app.profile.dateSemester1Start.asCalendar
val dateEnd = app.profile.dateYearEnd.asCalendar
val isCompactMode = profileConfig.agendaCompactMode
b.agendaDefaultView.init(
events,
dateStart,
@ -82,13 +86,15 @@ class AgendaFragmentDefault(
val date = Date.fromCalendar(event.instanceDay)
when (event) {
is AgendaEvent -> DayDialog(activity, app.profileId, date)
is AgendaEvent -> EventDetailsDialog(activity, event.event)
is LessonChangesEvent -> LessonChangeDialog(activity, app.profileId, date)
is TeacherAbsenceEvent -> TeacherAbsenceDialog(
activity,
app.profileId,
date
)
is BaseCalendarEvent -> if (event.isPlaceHolder)
DayDialog(activity, app.profileId, date)
}
}
@ -104,12 +110,13 @@ class AgendaFragmentDefault(
}
}
},
AgendaEventRenderer(),
AgendaEventRenderer(isCompactMode),
LessonChangesEventRenderer(),
TeacherAbsenceEventRenderer()
)
isInitialized = true
b.progressBar.isVisible = false
}
private fun updateView() {

View File

@ -11,13 +11,17 @@ import pl.szczodrzynski.edziennik.R
import pl.szczodrzynski.edziennik.databinding.AgendaWrappedEventBinding
import pl.szczodrzynski.edziennik.utils.Colors
class AgendaEventRenderer : EventRenderer<AgendaEvent>() {
class AgendaEventRenderer(
private val isCompact: Boolean
) : EventRenderer<AgendaEvent>() {
@SuppressLint("SetTextI18n")
override fun render(view: View, aEvent: AgendaEvent) {
val b = AgendaWrappedEventBinding.bind(view).item
val event = aEvent.event
b.isCompact = isCompact
b.card.setCardBackgroundColor(event.eventColor)
b.eventTitle.setTextColor(Colors.legibleTextColor(event.eventColor))
b.eventSubtitle.setTextColor(Colors.legibleTextColor(event.eventColor))

View File

@ -12,6 +12,7 @@ import pl.szczodrzynski.edziennik.R
import pl.szczodrzynski.edziennik.after
import pl.szczodrzynski.edziennik.data.api.LOGIN_TYPE_LIBRUS
import pl.szczodrzynski.edziennik.data.db.entity.Profile.Companion.REGISTRATION_ENABLED
import pl.szczodrzynski.edziennik.ui.dialogs.agenda.AgendaConfigDialog
import pl.szczodrzynski.edziennik.ui.dialogs.bell.BellSyncConfigDialog
import pl.szczodrzynski.edziennik.ui.dialogs.grade.GradesConfigDialog
import pl.szczodrzynski.edziennik.ui.dialogs.settings.AttendanceConfigDialog
@ -58,6 +59,13 @@ class SettingsRegisterCard(util: SettingsUtil) : SettingsCard(util) {
}
override fun getItems() = listOfNotNull(
util.createActionItem(
text = R.string.menu_agenda_config,
icon = CommunityMaterial.Icon.cmd_calendar_outline
) {
AgendaConfigDialog(activity, reloadOnDismiss = false)
},
util.createActionItem(
text = R.string.menu_grades_config,
icon = CommunityMaterial.Icon3.cmd_numeric_5_box_outline

View File

@ -3,9 +3,20 @@
~ Copyright (c) Kuba Szczodrzyński 2021-4-8.
-->
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
xmlns:tools="http://schemas.android.com/tools">
<data>
<import type="android.view.View" />
<variable
name="isCompact"
type="boolean" />
</data>
<androidx.cardview.widget.CardView
android:id="@+id/card"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@ -23,7 +34,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:ellipsize="end"
android:maxLines="3"
android:maxLines="@{isCompact ? 2 : 3}"
android:textSize="16sp"
tools:text="sprawdzian - Język polski" />
@ -34,6 +45,8 @@
android:layout_marginTop="5dp"
android:textColor="@color/calendar_text_default"
android:textSize="12sp"
android:visibility="@{isCompact ? View.GONE : View.VISIBLE}"
tools:text="9:05, biologia, Jan Kowalski, 7a" />
</LinearLayout>
</androidx.cardview.widget.CardView>
</layout>

View File

@ -0,0 +1,148 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (c) Kuba Szczodrzyński 2021-4-10.
-->
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<data>
<import type="android.view.View" />
<variable
name="config"
type="pl.szczodrzynski.edziennik.config.ProfileConfigUI" />
<variable
name="isAgendaMode"
type="boolean" />
</data>
<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="24dp">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/agenda_config_appearance"
android:textAppearance="@style/NavView.TextView.Subtitle" />
<com.google.android.material.checkbox.MaterialCheckBox
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:checked="@={config.agendaLessonChanges}"
android:minHeight="32dp"
android:text="@string/agenda_config_lesson_changes" />
<com.google.android.material.checkbox.MaterialCheckBox
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:checked="@={config.agendaTeacherAbsence}"
android:minHeight="32dp"
android:text="@string/agenda_config_teacher_absence" />
<com.google.android.material.checkbox.MaterialCheckBox
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:checked="@={config.agendaCompactMode}"
android:enabled="@{isAgendaMode}"
android:minHeight="32dp"
android:text="@string/agenda_config_compact_mode"
tools:enabled="false" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:enabled="@{isAgendaMode}"
android:text="@string/agenda_config_compact_mode_hint"
android:textAppearance="@style/NavView.TextView.Small"
tools:enabled="false" />
<com.google.android.material.checkbox.MaterialCheckBox
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:checked="@={config.agendaGroupByType}"
android:enabled="@{isAgendaMode}"
android:minHeight="32dp"
android:text="@string/agenda_config_group_by_type"
tools:enabled="false" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/agenda_config_mode_unavailable"
android:textStyle="italic"
android:visibility="@{isAgendaMode ? View.GONE : View.VISIBLE}" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="@string/agenda_config_event_sharing"
android:textAppearance="@style/NavView.TextView.Subtitle" />
<com.google.android.material.checkbox.MaterialCheckBox
android:id="@+id/eventSharingEnabled"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:minHeight="32dp"
android:text="@string/agenda_config_event_sharing_enabled" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="@string/agenda_config_elearning"
android:textAppearance="@style/NavView.TextView.Subtitle" />
<com.google.android.material.checkbox.MaterialCheckBox
android:id="@+id/elearningEnabled"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:checked="@={config.agendaElearningMark}"
android:minHeight="32dp"
android:onClick="@{() -> elearningType.setEnabled(elearningEnabled.isChecked())}"
android:text="@string/agenda_config_elearning_mark" />
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/elearningType"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.Dense"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:enabled="@{config.agendaElearningMark}"
android:hint="@string/agenda_config_elearning_type">
<pl.szczodrzynski.edziennik.utils.TextInputDropDown
android:id="@+id/elearningTypeDropdown"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:enabled="false"
android:focusable="true"
android:focusableInTouchMode="true" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.checkbox.MaterialCheckBox
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:checked="@={config.agendaElearningGroup}"
android:minHeight="32dp"
android:text="@string/agenda_config_elearning_group" />
</LinearLayout>
</ScrollView>
</layout>

View File

@ -1425,4 +1425,18 @@
<string name="permissions_generate_timetable">Aby móc zapisać wygenerowany plan lekcji musisz przyznać uprawnienia dostępu do pamięci urządzenia.\n\nKliknij OK, aby przyznać uprawnienia.</string>
<string name="privacy_policy_dialog_html"><![CDATA[Korzystając z aplikacji potwierdzasz <a href="https://szkolny.eu/privacy-policy">przeczytanie Polityki prywatności</a> i akceptujesz jej postanowienia.<br /><br />Autorzy aplikacji nie biorą odpowiedzialności za korzystanie z aplikacji Szkolny.eu.]]></string>
<string name="login_chooser_version_format">Szkolny.eu v%s\n%s</string>
<string name="menu_agenda_config">Ustawienia terminarza</string>
<string name="agenda_config_appearance">Wygląd</string>
<string name="agenda_config_lesson_changes">Pokazuj zmiany planu lekcji</string>
<string name="agenda_config_teacher_absence">Pokazuj nieobecności nauczycieli</string>
<string name="agenda_config_compact_mode">Tryb kompaktowy</string>
<string name="agenda_config_compact_mode_hint">Mniejszy rozmiar wydarzeń na liście</string>
<string name="agenda_config_group_by_type">Grupuj wydarzenia tego samego typu</string>
<string name="agenda_config_mode_unavailable">Niedostępne w trybie kalendarza</string>
<string name="agenda_config_event_sharing">Udostępnianie wydarzeń</string>
<string name="agenda_config_event_sharing_enabled">Włącz Udostępnianie wydarzeń</string>
<string name="agenda_config_elearning">Nauczanie zdalne</string>
<string name="agenda_config_elearning_mark">Ustaw wydarzenia jako lekcje on-line</string>
<string name="agenda_config_elearning_type">Wybierz rodzaj wydarzeń</string>
<string name="agenda_config_elearning_group">Grupuj lekcje on-line na liście</string>
</resources>