From 649d4f619a32821c117b909ff6575ffc8d0f2a72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kuba=20Szczodrzy=C5=84ski?= Date: Thu, 20 Oct 2022 21:59:01 +0200 Subject: [PATCH] [UI] Hide unavailable settings depending on LoginType. --- .../szczodrzynski/edziennik/MainActivity.kt | 8 +- .../edziennik/data/db/enums/FeatureType.kt | 5 +- .../edziennik/data/db/enums/LoginType.kt | 37 ++--- .../data/db/enums/LoginTypeFeatures.kt | 145 ++++++++++++++++++ .../edziennik/ext/DataExtensions.kt | 7 +- .../dialogs/settings/TimetableConfigDialog.kt | 6 +- .../ui/dialogs/sync/SyncViewListDialog.kt | 3 +- .../edziennik/ui/home/HomeFragment.kt | 13 +- .../ui/settings/cards/SettingsRegisterCard.kt | 14 +- .../edziennik/utils/BetterLink.kt | 8 +- .../res/layout/timetable_config_dialog.xml | 7 + 11 files changed, 201 insertions(+), 52 deletions(-) create mode 100644 app/src/main/java/pl/szczodrzynski/edziennik/data/db/enums/LoginTypeFeatures.kt diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/MainActivity.kt b/app/src/main/java/pl/szczodrzynski/edziennik/MainActivity.kt index 072e8550..e0e6cd3e 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/MainActivity.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/MainActivity.kt @@ -33,7 +33,6 @@ import org.greenrobot.eventbus.EventBus import org.greenrobot.eventbus.Subscribe import org.greenrobot.eventbus.ThreadMode import pl.droidsonroids.gif.GifDrawable -import pl.szczodrzynski.edziennik.data.api.ERROR_REQUIRES_USER_ACTION import pl.szczodrzynski.edziennik.data.api.ERROR_VULCAN_API_DEPRECATED import pl.szczodrzynski.edziennik.data.api.edziennik.EdziennikTask import pl.szczodrzynski.edziennik.data.api.events.* @@ -918,6 +917,11 @@ class MainActivity : AppCompatActivity(), CoroutineScope { ) { d(TAG, "navigateImpl(profileId = ${profile.id}, target = ${navTarget.name}, args = $args)") + if (navTarget.featureType != null && !profile.hasUIFeature(navTarget.featureType)) { + navigateImpl(profile, NavTarget.HOME, args, profileChanged) + return + } + if (profileChanged) { App.profile = profile MessagesFragment.pageSelection = -1 @@ -1162,7 +1166,7 @@ class MainActivity : AppCompatActivity(), CoroutineScope { for (target in NavTarget.values()) { if (target.devModeOnly && !App.devMode) continue - if (target.featureType != null && target.featureType !in app.profile.loginStoreType.features) + if (target.featureType != null && !app.profile.hasUIFeature(target.featureType)) continue when (target.location) { diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/db/enums/FeatureType.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/enums/FeatureType.kt index 98837920..90209435 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/data/db/enums/FeatureType.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/enums/FeatureType.kt @@ -10,11 +10,12 @@ enum class FeatureType( val id: Int, val isAlwaysNeeded: Boolean, val nameRes: Int? = null, + val isUIAlwaysAvailable: Boolean = false, ) { TIMETABLE(id = 1, isAlwaysNeeded = false, nameRes = R.string.menu_timetable), - AGENDA(id = 2, isAlwaysNeeded = false, nameRes = R.string.menu_agenda), + AGENDA(id = 2, isAlwaysNeeded = false, nameRes = R.string.menu_agenda, isUIAlwaysAvailable = true), GRADES(id = 3, isAlwaysNeeded = false, nameRes = R.string.menu_grades), - HOMEWORK(id = 4, isAlwaysNeeded = false, nameRes = R.string.menu_homework), + HOMEWORK(id = 4, isAlwaysNeeded = false, nameRes = R.string.menu_homework, isUIAlwaysAvailable = true), BEHAVIOUR(id = 5, isAlwaysNeeded = false, nameRes = R.string.menu_notices), ATTENDANCE(id = 6, isAlwaysNeeded = false, nameRes = R.string.menu_attendance), MESSAGES_INBOX(id = 7, isAlwaysNeeded = false, nameRes = R.string.title_messages_inbox_single), diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/db/enums/LoginType.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/enums/LoginType.kt index ea77dd7c..9bc066d9 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/data/db/enums/LoginType.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/enums/LoginType.kt @@ -4,36 +4,19 @@ package pl.szczodrzynski.edziennik.data.db.enums -import pl.szczodrzynski.edziennik.data.db.enums.FeatureType.* - -private val FEATURES_BASE = listOf( - TIMETABLE, - AGENDA, - GRADES, - HOMEWORK, -) -private val FEATURES_EXTENDED = listOf( - BEHAVIOUR, - ATTENDANCE, -) -private val FEATURES_MESSAGES = listOf( - MESSAGES_INBOX, - MESSAGES_SENT, -) - enum class LoginType( val id: Int, - val features: List, + val features: Set, ) { - MOBIDZIENNIK(id = 1, features = FEATURES_BASE + FEATURES_EXTENDED + FEATURES_MESSAGES), - LIBRUS(id = 2, features = MOBIDZIENNIK.features + ANNOUNCEMENTS), - VULCAN(id = 4, features = MOBIDZIENNIK.features), - PODLASIE(id = 6, features = FEATURES_BASE), - USOS(id = 7, features = FEATURES_BASE - GRADES), - DEMO(id = 20, features = listOf()), - TEMPLATE(id = 21, features = listOf()), + MOBIDZIENNIK(id = 1, features = FEATURES_MOBIDZIENNIK), + LIBRUS(id = 2, features = FEATURES_LIBRUS), + VULCAN(id = 4, features = FEATURES_VULCAN), + PODLASIE(id = 6, features = FEATURES_PODLASIE), + USOS(id = 7, features = FEATURES_USOS), + DEMO(id = 20, features = setOf()), + TEMPLATE(id = 21, features = setOf()), // the graveyard - EDUDZIENNIK(id = 5, features = FEATURES_BASE + FEATURES_EXTENDED), - IDZIENNIK(id = 3, features = LIBRUS.features), + EDUDZIENNIK(id = 5, features = FEATURES_EDUDZIENNIK), + IDZIENNIK(id = 3, features = FEATURES_IDZIENNIK), } diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/db/enums/LoginTypeFeatures.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/enums/LoginTypeFeatures.kt new file mode 100644 index 00000000..b0d16002 --- /dev/null +++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/enums/LoginTypeFeatures.kt @@ -0,0 +1,145 @@ +/* + * Copyright (c) Kuba SzczodrzyƄski 2022-10-20. + */ + +package pl.szczodrzynski.edziennik.data.db.enums + +import pl.szczodrzynski.edziennik.data.db.enums.FeatureType.* + +internal val FEATURES_MOBIDZIENNIK = setOf( + TIMETABLE, + AGENDA, + GRADES, + HOMEWORK, + BEHAVIOUR, + ATTENDANCE, + MESSAGES_INBOX, + MESSAGES_SENT, + + STUDENT_INFO, + STUDENT_NUMBER, + SCHOOL_INFO, + CLASS_INFO, + TEAM_INFO, + LUCKY_NUMBER, + TEACHERS, + SUBJECTS, + CLASSROOMS, + PUSH_CONFIG, +) + +internal val FEATURES_LIBRUS = setOf( + TIMETABLE, + AGENDA, + GRADES, + HOMEWORK, + BEHAVIOUR, + ATTENDANCE, + MESSAGES_INBOX, + MESSAGES_SENT, + ANNOUNCEMENTS, + + STUDENT_INFO, + STUDENT_NUMBER, + SCHOOL_INFO, + CLASS_INFO, + TEAM_INFO, + LUCKY_NUMBER, + TEACHERS, + SUBJECTS, + CLASSROOMS, + PUSH_CONFIG, +) + +internal val FEATURES_VULCAN = setOf( + TIMETABLE, + AGENDA, + GRADES, + HOMEWORK, + BEHAVIOUR, + ATTENDANCE, + MESSAGES_INBOX, + MESSAGES_SENT, + + STUDENT_INFO, + STUDENT_NUMBER, + SCHOOL_INFO, + CLASS_INFO, + TEAM_INFO, + LUCKY_NUMBER, + TEACHERS, + SUBJECTS, + CLASSROOMS, + PUSH_CONFIG, +) + +internal val FEATURES_PODLASIE = setOf( + TIMETABLE, + AGENDA, + GRADES, + HOMEWORK, + + STUDENT_INFO, + STUDENT_NUMBER, + SCHOOL_INFO, + CLASS_INFO, + TEAM_INFO, + LUCKY_NUMBER, + TEACHERS, + SUBJECTS, + CLASSROOMS, +) + +internal val FEATURES_USOS = setOf( + TIMETABLE, + AGENDA, + + STUDENT_INFO, + STUDENT_NUMBER, + CLASS_INFO, + TEAM_INFO, + TEACHERS, + SUBJECTS, + CLASSROOMS, +) + +internal val FEATURES_EDUDZIENNIK = setOf( + TIMETABLE, + AGENDA, + GRADES, + HOMEWORK, + BEHAVIOUR, + ATTENDANCE, + + STUDENT_INFO, + STUDENT_NUMBER, + SCHOOL_INFO, + CLASS_INFO, + TEAM_INFO, + LUCKY_NUMBER, + TEACHERS, + SUBJECTS, + CLASSROOMS, +) + +internal val FEATURES_IDZIENNIK = setOf( + TIMETABLE, + AGENDA, + GRADES, + HOMEWORK, + BEHAVIOUR, + ATTENDANCE, + MESSAGES_INBOX, + MESSAGES_SENT, + ANNOUNCEMENTS, + + STUDENT_INFO, + STUDENT_NUMBER, + SCHOOL_INFO, + CLASS_INFO, + TEAM_INFO, + LUCKY_NUMBER, + TEACHERS, + SUBJECTS, + CLASSROOMS, +) diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ext/DataExtensions.kt b/app/src/main/java/pl/szczodrzynski/edziennik/ext/DataExtensions.kt index 5f41af98..fc0c3fd0 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/ext/DataExtensions.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/ext/DataExtensions.kt @@ -4,16 +4,14 @@ package pl.szczodrzynski.edziennik.ext -import android.content.Context import android.util.LongSparseArray import androidx.core.util.forEach import com.google.android.material.datepicker.CalendarConstraints import com.google.gson.JsonElement -import pl.szczodrzynski.edziennik.R -import pl.szczodrzynski.edziennik.data.db.entity.Notification import pl.szczodrzynski.edziennik.data.db.entity.Profile import pl.szczodrzynski.edziennik.data.db.entity.Teacher import pl.szczodrzynski.edziennik.data.db.entity.Team +import pl.szczodrzynski.edziennik.data.db.enums.FeatureType fun List.byId(id: Long) = firstOrNull { it.id == id } fun List.byNameFirstLast(nameFirstLast: String) = firstOrNull { it.name + " " + it.surname == nameFirstLast } @@ -47,3 +45,6 @@ fun Profile.getSchoolYearConstrains(): CalendarConstraints { .setEnd(dateYearEnd.inMillisUtc) .build() } + +fun Profile.hasFeature(featureType: FeatureType) = featureType in this.loginStoreType.features +fun Profile.hasUIFeature(featureType: FeatureType) = featureType.isUIAlwaysAvailable || hasFeature(featureType) diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/dialogs/settings/TimetableConfigDialog.kt b/app/src/main/java/pl/szczodrzynski/edziennik/ui/dialogs/settings/TimetableConfigDialog.kt index b784165b..6f3cef7c 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/ui/dialogs/settings/TimetableConfigDialog.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/dialogs/settings/TimetableConfigDialog.kt @@ -6,11 +6,9 @@ package pl.szczodrzynski.edziennik.ui.dialogs.settings import android.view.LayoutInflater import androidx.appcompat.app.AppCompatActivity -import pl.szczodrzynski.edziennik.MainActivity import pl.szczodrzynski.edziennik.R import pl.szczodrzynski.edziennik.databinding.TimetableConfigDialogBinding import pl.szczodrzynski.edziennik.ext.Intent -import pl.szczodrzynski.edziennik.ext.onClick import pl.szczodrzynski.edziennik.ui.dialogs.base.ConfigDialog import pl.szczodrzynski.edziennik.ui.timetable.TimetableFragment @@ -34,6 +32,10 @@ class TimetableConfigDialog( 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 } diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/dialogs/sync/SyncViewListDialog.kt b/app/src/main/java/pl/szczodrzynski/edziennik/ui/dialogs/sync/SyncViewListDialog.kt index 55e185b7..50f918d7 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/ui/dialogs/sync/SyncViewListDialog.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/dialogs/sync/SyncViewListDialog.kt @@ -10,6 +10,7 @@ import pl.szczodrzynski.edziennik.R import pl.szczodrzynski.edziennik.data.api.edziennik.EdziennikTask import pl.szczodrzynski.edziennik.data.db.entity.Message import pl.szczodrzynski.edziennik.data.db.enums.FeatureType +import pl.szczodrzynski.edziennik.ext.hasFeature import pl.szczodrzynski.edziennik.ext.resolveString import pl.szczodrzynski.edziennik.ui.base.enums.NavTarget import pl.szczodrzynski.edziennik.ui.dialogs.base.BaseDialog @@ -31,7 +32,7 @@ class SyncViewListDialog( @Suppress("USELESS_CAST") override fun getMultiChoiceItems() = FeatureType.values() - .filter { it.nameRes != null } + .filter { it.nameRes != null && app.profile.hasFeature(it) } .associateBy { it.nameRes!!.resolveString(activity) as CharSequence } override fun getDefaultSelectedItems() = when (currentNavTarget) { diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/home/HomeFragment.kt b/app/src/main/java/pl/szczodrzynski/edziennik/ui/home/HomeFragment.kt index 5a95c114..50240713 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/ui/home/HomeFragment.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/home/HomeFragment.kt @@ -25,9 +25,10 @@ import pl.szczodrzynski.edziennik.App import pl.szczodrzynski.edziennik.BuildConfig import pl.szczodrzynski.edziennik.MainActivity import pl.szczodrzynski.edziennik.R -import pl.szczodrzynski.edziennik.data.db.entity.LoginStore +import pl.szczodrzynski.edziennik.data.db.enums.FeatureType import pl.szczodrzynski.edziennik.data.db.enums.LoginType import pl.szczodrzynski.edziennik.databinding.FragmentHomeBinding +import pl.szczodrzynski.edziennik.ext.hasUIFeature import pl.szczodrzynski.edziennik.ext.onClick import pl.szczodrzynski.edziennik.ui.dialogs.settings.StudentNumberDialog import pl.szczodrzynski.edziennik.ui.home.cards.* @@ -146,11 +147,11 @@ class HomeFragment : Fragment(), CoroutineScope { val cards = app.config.forProfile().ui.homeCards.filter { it.profileId == app.profile.id }.toMutableList() if (cards.isEmpty()) { - cards += listOf( - HomeCardModel(app.profile.id, HomeCard.CARD_LUCKY_NUMBER), - HomeCardModel(app.profile.id, HomeCard.CARD_TIMETABLE), - HomeCardModel(app.profile.id, HomeCard.CARD_EVENTS), - HomeCardModel(app.profile.id, HomeCard.CARD_GRADES), + cards += listOfNotNull( + HomeCardModel(app.profile.id, HomeCard.CARD_LUCKY_NUMBER).takeIf { app.profile.hasUIFeature(FeatureType.LUCKY_NUMBER) }, + HomeCardModel(app.profile.id, HomeCard.CARD_TIMETABLE).takeIf { app.profile.hasUIFeature(FeatureType.TIMETABLE) }, + HomeCardModel(app.profile.id, HomeCard.CARD_EVENTS).takeIf { app.profile.hasUIFeature(FeatureType.AGENDA) }, + 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) } diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/settings/cards/SettingsRegisterCard.kt b/app/src/main/java/pl/szczodrzynski/edziennik/ui/settings/cards/SettingsRegisterCard.kt index fc369b6a..ad405263 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/ui/settings/cards/SettingsRegisterCard.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/settings/cards/SettingsRegisterCard.kt @@ -9,8 +9,10 @@ import com.mikepenz.iconics.typeface.library.community.material.CommunityMateria import eu.szkolny.font.SzkolnyFont import pl.szczodrzynski.edziennik.App import pl.szczodrzynski.edziennik.R +import pl.szczodrzynski.edziennik.data.db.enums.FeatureType import pl.szczodrzynski.edziennik.data.db.enums.LoginType import pl.szczodrzynski.edziennik.ext.after +import pl.szczodrzynski.edziennik.ext.hasUIFeature import pl.szczodrzynski.edziennik.ui.dialogs.settings.* import pl.szczodrzynski.edziennik.ui.settings.SettingsCard import pl.szczodrzynski.edziennik.ui.settings.SettingsUtil @@ -59,27 +61,29 @@ class SettingsRegisterCard(util: SettingsUtil) : SettingsCard(util) { icon = CommunityMaterial.Icon3.cmd_timetable ) { TimetableConfigDialog(activity, reloadOnDismiss = false).show() - }, + }.takeIf { app.profile.hasUIFeature(FeatureType.TIMETABLE) }, util.createActionItem( text = R.string.menu_agenda_config, icon = CommunityMaterial.Icon.cmd_calendar_outline ) { AgendaConfigDialog(activity, reloadOnDismiss = false).show() - }, + }.takeIf { app.profile.hasUIFeature(FeatureType.AGENDA) }, util.createActionItem( text = R.string.menu_grades_config, icon = CommunityMaterial.Icon3.cmd_numeric_5_box_outline ) { GradesConfigDialog(activity, reloadOnDismiss = false).show() - }, + }.takeIf { app.profile.hasUIFeature(FeatureType.GRADES) }, util.createActionItem( text = R.string.menu_messages_config, icon = CommunityMaterial.Icon.cmd_email_outline ) { MessagesConfigDialog(activity, reloadOnDismiss = false).show() + }.takeIf { + app.profile.hasUIFeature(FeatureType.MESSAGES_INBOX) || app.profile.hasUIFeature(FeatureType.MESSAGES_SENT) }, util.createActionItem( @@ -87,7 +91,7 @@ class SettingsRegisterCard(util: SettingsUtil) : SettingsCard(util) { icon = CommunityMaterial.Icon.cmd_calendar_remove_outline ) { AttendanceConfigDialog(activity, reloadOnDismiss = false).show() - }, + }.takeIf { app.profile.hasUIFeature(FeatureType.ATTENDANCE) }, if (app.profile.archived) null @@ -169,7 +173,7 @@ class SettingsRegisterCard(util: SettingsUtil) : SettingsCard(util) { value = configProfile.grades.hideSticksFromOld ) { _, it -> configProfile.grades.hideSticksFromOld = it - } + }.takeIf { app.profile.hasUIFeature(FeatureType.GRADES) } else null ) diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/utils/BetterLink.kt b/app/src/main/java/pl/szczodrzynski/edziennik/utils/BetterLink.kt index f0cc9c13..ee6a3f65 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/utils/BetterLink.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/utils/BetterLink.kt @@ -24,10 +24,8 @@ import androidx.appcompat.view.menu.MenuPopupHelper import androidx.core.widget.addTextChangedListener import pl.szczodrzynski.edziennik.* import pl.szczodrzynski.edziennik.data.api.Regexes -import pl.szczodrzynski.edziennik.ext.Intent -import pl.szczodrzynski.edziennik.ext.copyToClipboard -import pl.szczodrzynski.edziennik.ext.get -import pl.szczodrzynski.edziennik.ext.getTextPosition +import pl.szczodrzynski.edziennik.data.db.enums.FeatureType +import pl.szczodrzynski.edziennik.ext.* import pl.szczodrzynski.edziennik.ui.base.enums.NavTarget import pl.szczodrzynski.edziennik.utils.models.Date @@ -108,6 +106,8 @@ object BetterLink { } private fun createTeacherItems(menu: MenuBuilder, context: Context, teacherId: Long, fullName: String) { + if (!(context.applicationContext as App).profile.hasFeature(FeatureType.MESSAGES_INBOX)) + return menu.setTitle(fullName) menu.add( 1, diff --git a/app/src/main/res/layout/timetable_config_dialog.xml b/app/src/main/res/layout/timetable_config_dialog.xml index 19e165cf..8b724858 100644 --- a/app/src/main/res/layout/timetable_config_dialog.xml +++ b/app/src/main/res/layout/timetable_config_dialog.xml @@ -7,9 +7,15 @@ + + + +