From 80dcd9aa69badef2d6041f59d7f19a002a6c0677 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kuba=20Szczodrzy=C5=84ski?= Date: Sat, 18 Sep 2021 16:36:17 +0200 Subject: [PATCH 1/5] [API] Refactor register availability checking module. --- .../java/pl/szczodrzynski/edziennik/App.kt | 1 + .../szczodrzynski/edziennik/MainActivity.kt | 57 ++++------ .../szczodrzynski/edziennik/config/Config.kt | 5 + .../data/api/edziennik/EdziennikTask.kt | 34 ++---- .../api/events/RegisterAvailabilityEvent.kt | 6 +- .../edziennik/data/db/entity/Profile.kt | 2 +- .../data/firebase/SzkolnyAppFirebase.kt | 2 +- .../ui/dialogs/RegisterUnavailableDialog.kt | 2 - .../edziennik/ui/modules/home/HomeFragment.kt | 5 +- .../home/cards/HomeAvailabilityCard.kt | 10 +- .../ui/modules/login/LoginChooserFragment.kt | 60 +++-------- .../utils/managers/AvailabilityManager.kt | 100 ++++++++++++++++++ 12 files changed, 162 insertions(+), 122 deletions(-) create mode 100644 app/src/main/java/pl/szczodrzynski/edziennik/utils/managers/AvailabilityManager.kt diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/App.kt b/app/src/main/java/pl/szczodrzynski/edziennik/App.kt index 71e6c7e6..4db63386 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/App.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/App.kt @@ -71,6 +71,7 @@ class App : MultiDexApplication(), Configuration.Provider, CoroutineScope { val permissionManager by lazy { PermissionManager(this) } val attendanceManager by lazy { AttendanceManager(this) } val buildManager by lazy { BuildManager(this) } + val availabilityManager by lazy { AvailabilityManager(this) } val db get() = App.db diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/MainActivity.kt b/app/src/main/java/pl/szczodrzynski/edziennik/MainActivity.kt index 2cd4f7b7..b7540b44 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/MainActivity.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/MainActivity.kt @@ -85,6 +85,8 @@ import pl.szczodrzynski.edziennik.ui.modules.webpush.WebPushFragment import pl.szczodrzynski.edziennik.utils.* import pl.szczodrzynski.edziennik.utils.Utils.d import pl.szczodrzynski.edziennik.utils.Utils.dpToPx +import pl.szczodrzynski.edziennik.utils.managers.AvailabilityManager +import pl.szczodrzynski.edziennik.utils.managers.AvailabilityManager.Error.Type import pl.szczodrzynski.edziennik.utils.models.Date import pl.szczodrzynski.edziennik.utils.models.NavTarget import pl.szczodrzynski.navlib.* @@ -634,45 +636,23 @@ class MainActivity : AppCompatActivity(), CoroutineScope { return } - app.profile.registerName?.let { registerName -> - var status = app.config.sync.registerAvailability[registerName] - if (status == null || status.nextCheckAt < currentTimeUnix()) { - val api = SzkolnyApi(app) - val result = withContext(Dispatchers.IO) { - return@withContext api.runCatching({ - val availability = getRegisterAvailability() - app.config.sync.registerAvailability = availability - availability[registerName] - }, onError = { - if (it.toErrorCode() == ERROR_API_INVALID_SIGNATURE) { - return@withContext false - } - return@withContext it - }) - } - - when (result) { - false -> { - Toast.makeText(this@MainActivity, R.string.error_no_api_access, Toast.LENGTH_SHORT).show() - return@let - } - is Throwable -> { - errorSnackbar.addError(result.toApiError(TAG)).show() - return - } - is RegisterAvailabilityStatus -> { - status = result - } - } - } - - if (status?.available != true || status.minVersionCode > BuildConfig.VERSION_CODE) { + val error = withContext(Dispatchers.IO) { + app.availabilityManager.check(app.profile) + } + when (error?.type) { + Type.NOT_AVAILABLE -> { swipeRefreshLayout.isRefreshing = false loadTarget(DRAWER_ITEM_HOME) - if (status != null) - RegisterUnavailableDialog(this, status) + RegisterUnavailableDialog(this, error.status!!) return } + Type.API_ERROR -> { + errorSnackbar.addError(error.apiError!!).show() + return + } + Type.NO_API_ACCESS -> { + Toast.makeText(this, R.string.error_no_api_access, Toast.LENGTH_SHORT).show() + } } swipeRefreshLayout.isRefreshing = true @@ -699,10 +679,9 @@ class MainActivity : AppCompatActivity(), CoroutineScope { @Subscribe(threadMode = ThreadMode.MAIN, sticky = true) fun onRegisterAvailabilityEvent(event: RegisterAvailabilityEvent) { EventBus.getDefault().removeStickyEvent(event) - app.profile.registerName?.let { registerName -> - event.data[registerName]?.let { - RegisterUnavailableDialog(this, it) - } + val error = app.availabilityManager.check(app.profile, cacheOnly = true) + if (error != null) { + RegisterUnavailableDialog(this, error.status!!) } } @Subscribe(threadMode = ThreadMode.MAIN) diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/config/Config.kt b/app/src/main/java/pl/szczodrzynski/edziennik/config/Config.kt index 0274912f..8c9270f2 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/config/Config.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/config/Config.kt @@ -125,6 +125,11 @@ class Config(val db: AppDb) : CoroutineScope, AbstractConfig { get() { mApiInvalidCert = mApiInvalidCert ?: values["apiInvalidCert"]; return mApiInvalidCert } set(value) { set("apiInvalidCert", value); mApiInvalidCert = value } + private var mApiAvailabilityCheck: Boolean? = null + var apiAvailabilityCheck: Boolean + get() { mApiAvailabilityCheck = mApiAvailabilityCheck ?: values.get("apiAvailabilityCheck", true); return mApiAvailabilityCheck ?: true } + set(value) { set("apiAvailabilityCheck", value); mApiAvailabilityCheck = value } + private var rawEntries: List = db.configDao().getAllNow() private val profileConfigs: HashMap = hashMapOf() init { diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/EdziennikTask.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/EdziennikTask.kt index e3692c33..ab27dda9 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/EdziennikTask.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/EdziennikTask.kt @@ -18,7 +18,6 @@ import pl.szczodrzynski.edziennik.data.api.events.RegisterAvailabilityEvent import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikCallback import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikInterface import pl.szczodrzynski.edziennik.data.api.models.ApiError -import pl.szczodrzynski.edziennik.data.api.szkolny.SzkolnyApi import pl.szczodrzynski.edziennik.data.api.task.IApiTask import pl.szczodrzynski.edziennik.data.db.entity.LoginStore import pl.szczodrzynski.edziennik.data.db.entity.Profile @@ -27,6 +26,7 @@ import pl.szczodrzynski.edziennik.data.db.full.AnnouncementFull import pl.szczodrzynski.edziennik.data.db.full.EventFull import pl.szczodrzynski.edziennik.data.db.full.MessageFull import pl.szczodrzynski.edziennik.utils.Utils.d +import pl.szczodrzynski.edziennik.utils.managers.AvailabilityManager.Error.Type open class EdziennikTask(override val profileId: Int, val request: Any) : IApiTask(profileId) { companion object { @@ -90,35 +90,21 @@ open class EdziennikTask(override val profileId: Int, val request: Any) : IApiTa return } - profile.registerName?.also { registerName -> - var status = app.config.sync.registerAvailability[registerName] - if (status == null || status.nextCheckAt < currentTimeUnix()) { - val api = SzkolnyApi(app) - api.runCatching({ - val availability = getRegisterAvailability() - app.config.sync.registerAvailability = availability - status = availability[registerName] - }, onError = { - val apiError = it.toApiError(TAG) - if (apiError.errorCode == ERROR_API_INVALID_SIGNATURE) { - return@also - } - taskCallback.onError(apiError) - return - }) - } - - if (status?.available != true - || status?.minVersionCode ?: BuildConfig.VERSION_CODE > BuildConfig.VERSION_CODE) { + val error = app.availabilityManager.check(profile) + when (error?.type) { + Type.NOT_AVAILABLE -> { if (EventBus.getDefault().hasSubscriberForEvent(RegisterAvailabilityEvent::class.java)) { - EventBus.getDefault().postSticky( - RegisterAvailabilityEvent(app.config.sync.registerAvailability) - ) + EventBus.getDefault().postSticky(RegisterAvailabilityEvent()) } cancel() taskCallback.onCompleted() return } + Type.API_ERROR -> { + taskCallback.onError(error.apiError!!) + return + } + else -> return@let } } diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/events/RegisterAvailabilityEvent.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/events/RegisterAvailabilityEvent.kt index fe66c4b3..2a3531df 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/events/RegisterAvailabilityEvent.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/events/RegisterAvailabilityEvent.kt @@ -4,8 +4,4 @@ package pl.szczodrzynski.edziennik.data.api.events -import pl.szczodrzynski.edziennik.data.api.szkolny.response.RegisterAvailabilityStatus - -data class RegisterAvailabilityEvent( - val data: Map< String, RegisterAvailabilityStatus> -) +class RegisterAvailabilityEvent() diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/db/entity/Profile.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/entity/Profile.kt index b3586a79..9c2552a6 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/data/db/entity/Profile.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/entity/Profile.kt @@ -140,7 +140,7 @@ open class Profile( LOGIN_TYPE_MOBIDZIENNIK -> "mobidziennik" LOGIN_TYPE_PODLASIE -> "podlasie" LOGIN_TYPE_EDUDZIENNIK -> "edudziennik" - else -> null + else -> "unknown" } override fun getImageDrawable(context: Context): Drawable { diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/firebase/SzkolnyAppFirebase.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/firebase/SzkolnyAppFirebase.kt index 1d563c34..111fef4a 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/data/firebase/SzkolnyAppFirebase.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/firebase/SzkolnyAppFirebase.kt @@ -60,7 +60,7 @@ class SzkolnyAppFirebase(val app: App, val profiles: List, val message: ) ?: return@launch app.config.sync.registerAvailability = data if (EventBus.getDefault().hasSubscriberForEvent(RegisterAvailabilityEvent::class.java)) { - EventBus.getDefault().postSticky(RegisterAvailabilityEvent(data)) + EventBus.getDefault().postSticky(RegisterAvailabilityEvent()) } } } diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/dialogs/RegisterUnavailableDialog.kt b/app/src/main/java/pl/szczodrzynski/edziennik/ui/dialogs/RegisterUnavailableDialog.kt index b9e733b8..10853812 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/ui/dialogs/RegisterUnavailableDialog.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/dialogs/RegisterUnavailableDialog.kt @@ -42,8 +42,6 @@ class RegisterUnavailableDialog( init { run { if (activity.isFinishing) return@run - if (status.available && status.minVersionCode <= BuildConfig.VERSION_CODE) - return@run onShowListener?.invoke(TAG) app = activity.applicationContext as App diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/home/HomeFragment.kt b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/home/HomeFragment.kt index 944c60e8..5d5cbc45 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/home/HomeFragment.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/home/HomeFragment.kt @@ -163,10 +163,9 @@ class HomeFragment : Fragment(), CoroutineScope { if (app.profile.archived) items.add(0, HomeArchiveCard(101, app, activity, this, app.profile)) - val status = app.config.sync.registerAvailability[app.profile.registerName] + val status = app.availabilityManager.check(app.profile, cacheOnly = true)?.status val update = app.config.update - if (update != null && update.versionCode > BuildConfig.VERSION_CODE - || status != null && (!status.available || status.minVersionCode > BuildConfig.VERSION_CODE)) { + if (update != null && update.versionCode > BuildConfig.VERSION_CODE || status?.userMessage != null) { items.add(0, HomeAvailabilityCard(102, app, activity, this, app.profile)) } diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/home/cards/HomeAvailabilityCard.kt b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/home/cards/HomeAvailabilityCard.kt index fd54748e..613658f4 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/home/cards/HomeAvailabilityCard.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/home/cards/HomeAvailabilityCard.kt @@ -50,7 +50,8 @@ class HomeAvailabilityCard( } holder.root += b.root - val status = app.config.sync.registerAvailability[profile.registerName] + val error = app.availabilityManager.check(profile, cacheOnly = true) + val status = error?.status val update = app.config.update if (update == null && status == null) @@ -58,7 +59,8 @@ class HomeAvailabilityCard( var onInfoClick = { _: View -> } - if (status != null && !status.available && status.userMessage != null) { + // show "register unavailable" only when disabled + if (status?.userMessage != null) { b.homeAvailabilityTitle.text = HtmlCompat.fromHtml(status.userMessage.title, HtmlCompat.FROM_HTML_MODE_LEGACY) b.homeAvailabilityText.text = HtmlCompat.fromHtml(status.userMessage.contentShort, HtmlCompat.FROM_HTML_MODE_LEGACY) b.homeAvailabilityUpdate.isVisible = false @@ -69,6 +71,7 @@ class HomeAvailabilityCard( RegisterUnavailableDialog(activity, status) } } + // show "update available" when available OR version too old for the register else if (update != null && update.versionCode > BuildConfig.VERSION_CODE) { b.homeAvailabilityTitle.setText(R.string.home_availability_title) b.homeAvailabilityText.setText(R.string.home_availability_text, update.versionName) @@ -78,6 +81,9 @@ class HomeAvailabilityCard( UpdateAvailableDialog(activity, update) } } + else { + b.root.isVisible = false + } b.homeAvailabilityUpdate.onClick { if (update == null) diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/login/LoginChooserFragment.kt b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/login/LoginChooserFragment.kt index 858b4a01..71a5b804 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/login/LoginChooserFragment.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/login/LoginChooserFragment.kt @@ -26,13 +26,12 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder import kotlinx.coroutines.* import pl.szczodrzynski.edziennik.* import pl.szczodrzynski.edziennik.data.api.* -import pl.szczodrzynski.edziennik.data.api.szkolny.SzkolnyApi -import pl.szczodrzynski.edziennik.data.api.szkolny.response.RegisterAvailabilityStatus import pl.szczodrzynski.edziennik.databinding.LoginChooserFragmentBinding import pl.szczodrzynski.edziennik.ui.dialogs.RegisterUnavailableDialog import pl.szczodrzynski.edziennik.ui.modules.feedback.FeedbackActivity import pl.szczodrzynski.edziennik.utils.BetterLinkMovementMethod import pl.szczodrzynski.edziennik.utils.SimpleDividerItemDecoration +import pl.szczodrzynski.edziennik.utils.managers.AvailabilityManager.Error.Type import pl.szczodrzynski.edziennik.utils.models.Date import kotlin.coroutines.CoroutineContext @@ -269,52 +268,23 @@ class LoginChooserFragment : Fragment(), CoroutineScope { } private suspend fun checkAvailability(loginType: Int): Boolean { - when (loginType) { - LOGIN_TYPE_LIBRUS -> "librus" - LOGIN_TYPE_VULCAN -> "vulcan" - LOGIN_TYPE_IDZIENNIK -> "idziennik" - LOGIN_TYPE_MOBIDZIENNIK -> "mobidziennik" - LOGIN_TYPE_PODLASIE -> "podlasie" - LOGIN_TYPE_EDUDZIENNIK -> "edudziennik" - else -> null - }?.let { registerName -> - var status = app.config.sync.registerAvailability[registerName] - if (status == null || status.nextCheckAt < currentTimeUnix()) { - val api = SzkolnyApi(app) - val result = withContext(Dispatchers.IO) { - return@withContext api.runCatching({ - val availability = getRegisterAvailability() - app.config.sync.registerAvailability = availability - availability[registerName] - }, onError = { - if (it.toErrorCode() == ERROR_API_INVALID_SIGNATURE) { - return@withContext false - } - return@withContext it - }) - } + val error = withContext(Dispatchers.IO) { + app.availabilityManager.check(loginType) + } ?: return true - when (result) { - false -> { - Toast.makeText(activity, R.string.error_no_api_access, Toast.LENGTH_SHORT).show() - return@let - } - is Throwable -> { - activity.errorSnackbar.addError(result.toApiError(TAG)).show() - return false - } - is RegisterAvailabilityStatus -> { - status = result - } - } + return when (error.type) { + Type.NOT_AVAILABLE -> { + RegisterUnavailableDialog(activity, error.status!!) + false } - - if (status?.available != true || status.minVersionCode > BuildConfig.VERSION_CODE) { - if (status != null) - RegisterUnavailableDialog(activity, status) - return false + Type.API_ERROR -> { + activity.errorSnackbar.addError(error.apiError!!).show() + false + } + Type.NO_API_ACCESS -> { + Toast.makeText(activity, R.string.error_no_api_access, Toast.LENGTH_SHORT).show() + true } } - return true } } diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/utils/managers/AvailabilityManager.kt b/app/src/main/java/pl/szczodrzynski/edziennik/utils/managers/AvailabilityManager.kt new file mode 100644 index 00000000..0c93468e --- /dev/null +++ b/app/src/main/java/pl/szczodrzynski/edziennik/utils/managers/AvailabilityManager.kt @@ -0,0 +1,100 @@ +/* + * Copyright (c) Kuba Szczodrzyński 2021-9-18. + */ + +package pl.szczodrzynski.edziennik.utils.managers + +import pl.szczodrzynski.edziennik.App +import pl.szczodrzynski.edziennik.BuildConfig +import pl.szczodrzynski.edziennik.currentTimeUnix +import pl.szczodrzynski.edziennik.data.api.* +import pl.szczodrzynski.edziennik.data.api.models.ApiError +import pl.szczodrzynski.edziennik.data.api.szkolny.SzkolnyApi +import pl.szczodrzynski.edziennik.data.api.szkolny.response.RegisterAvailabilityStatus +import pl.szczodrzynski.edziennik.data.db.entity.Profile +import pl.szczodrzynski.edziennik.toApiError + +class AvailabilityManager(val app: App) { + companion object { + private const val TAG = "AvailabilityManager" + } + + private val api = SzkolnyApi(app) + + data class Error( + val type: Type, + val status: RegisterAvailabilityStatus?, + val apiError: ApiError? + ) { + companion object { + fun notAvailable(status: RegisterAvailabilityStatus) = + Error(Type.NOT_AVAILABLE, status, null) + + fun apiError(apiError: ApiError) = + Error(Type.API_ERROR, null, apiError) + + fun noApiAccess() = + Error(Type.NO_API_ACCESS, null, null) + } + + enum class Type { + NOT_AVAILABLE, + API_ERROR, + NO_API_ACCESS, + } + } + + fun check(profile: Profile, cacheOnly: Boolean = false): Error? { + return check(profile.registerName, cacheOnly) + } + + fun check(loginType: Int, cacheOnly: Boolean = false): Error? { + val registerName = when (loginType) { + LOGIN_TYPE_LIBRUS -> "librus" + LOGIN_TYPE_VULCAN -> "vulcan" + LOGIN_TYPE_IDZIENNIK -> "idziennik" + LOGIN_TYPE_MOBIDZIENNIK -> "mobidziennik" + LOGIN_TYPE_PODLASIE -> "podlasie" + LOGIN_TYPE_EDUDZIENNIK -> "edudziennik" + else -> "unknown" + } + return check(registerName, cacheOnly) + } + + fun check(registerName: String, cacheOnly: Boolean = false): Error? { + if (!app.config.apiAvailabilityCheck) + return null + val status = app.config.sync.registerAvailability[registerName] + if (status != null && status.nextCheckAt > currentTimeUnix()) { + return reportStatus(status) + } + if (cacheOnly) { + return reportStatus(status) + } + + return try { + val availability = api.getRegisterAvailability() + app.config.sync.registerAvailability = availability + reportStatus(availability[registerName]) + } catch (e: Throwable) { + reportApiError(e) + } + } + + private fun reportStatus(status: RegisterAvailabilityStatus?): Error? { + if (status == null) + return null + if (!status.available || status.minVersionCode > BuildConfig.VERSION_CODE) + return Error.notAvailable(status) + return null + } + + private fun reportApiError(throwable: Throwable): Error { + val apiError = throwable.toApiError(TAG) + if (apiError.errorCode == ERROR_API_INVALID_SIGNATURE) { + app.config.sync.registerAvailability = mapOf() + return Error.noApiAccess() + } + return Error.apiError(apiError) + } +} From 60f0628f5ea89fda120d33a9f423fbe996e9a6f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kuba=20Szczodrzy=C5=84ski?= Date: Sat, 18 Sep 2021 16:37:24 +0200 Subject: [PATCH 2/5] [Lab] Fix disabling Chucker and Dev Mode. Add new Lab options. --- .../java/pl/szczodrzynski/edziennik/App.kt | 4 +- .../szczodrzynski/edziennik/config/Config.kt | 19 ++++---- .../config/utils/ConfigExtensions.kt | 3 ++ .../edziennik/config/utils/ConfigMigration.kt | 2 +- .../edziennik/ui/modules/debug/LabFragment.kt | 1 + .../ui/modules/debug/LabPageFragment.kt | 17 ++++++-- .../ui/modules/login/LoginPrizeFragment.kt | 6 +-- app/src/main/res/layout/lab_fragment.xml | 43 +++++++++++++++---- 8 files changed, 65 insertions(+), 30 deletions(-) diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/App.kt b/app/src/main/java/pl/szczodrzynski/edziennik/App.kt index 4db63386..b3ec1cc3 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/App.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/App.kt @@ -175,8 +175,8 @@ class App : MultiDexApplication(), Configuration.Provider, CoroutineScope { App.config = Config(App.db) App.profile = Profile(0, 0, 0, "") debugMode = BuildConfig.DEBUG - devMode = config.debugMode || debugMode - enableChucker = config.enableChucker || devMode + devMode = config.devMode ?: debugMode + enableChucker = config.enableChucker ?: devMode if (!profileLoadById(config.lastProfileId)) { db.profileDao().firstId?.let { profileLoadById(it) } diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/config/Config.kt b/app/src/main/java/pl/szczodrzynski/edziennik/config/Config.kt index 8c9270f2..e29d93ad 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/config/Config.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/config/Config.kt @@ -12,10 +12,7 @@ import kotlinx.coroutines.launch import pl.szczodrzynski.edziennik.App import pl.szczodrzynski.edziennik.BuildConfig import pl.szczodrzynski.edziennik.config.db.ConfigEntry -import pl.szczodrzynski.edziennik.config.utils.ConfigMigration -import pl.szczodrzynski.edziennik.config.utils.get -import pl.szczodrzynski.edziennik.config.utils.set -import pl.szczodrzynski.edziennik.config.utils.toHashMap +import pl.szczodrzynski.edziennik.config.utils.* import pl.szczodrzynski.edziennik.data.api.szkolny.response.Update import pl.szczodrzynski.edziennik.data.db.AppDb import kotlin.coroutines.CoroutineContext @@ -75,15 +72,15 @@ class Config(val db: AppDb) : CoroutineScope, AbstractConfig { get() { mPrivacyPolicyAccepted = mPrivacyPolicyAccepted ?: values.get("privacyPolicyAccepted", false); return mPrivacyPolicyAccepted ?: false } set(value) { set("privacyPolicyAccepted", value); mPrivacyPolicyAccepted = value } - private var mDebugMode: Boolean? = null - var debugMode: Boolean - get() { mDebugMode = mDebugMode ?: values.get("debugMode", false); return mDebugMode ?: false } - set(value) { set("debugMode", value); mDebugMode = value } + private var mDevMode: Boolean? = null + var devMode: Boolean? + get() { mDevMode = mDevMode ?: values.getBooleanOrNull("debugMode"); return mDevMode } + set(value) { set("debugMode", value?.toString()); mDevMode = value } private var mEnableChucker: Boolean? = null - var enableChucker: Boolean - get() { mEnableChucker = mEnableChucker ?: values.get("enableChucker", false); return mEnableChucker ?: false } - set(value) { set("enableChucker", value); mEnableChucker = value } + var enableChucker: Boolean? + get() { mEnableChucker = mEnableChucker ?: values.getBooleanOrNull("enableChucker"); return mEnableChucker } + set(value) { set("enableChucker", value?.toString()); mEnableChucker = value } private var mDevModePassword: String? = null var devModePassword: String? diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/config/utils/ConfigExtensions.kt b/app/src/main/java/pl/szczodrzynski/edziennik/config/utils/ConfigExtensions.kt index c98cf832..94bb87e6 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/config/utils/ConfigExtensions.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/config/utils/ConfigExtensions.kt @@ -59,6 +59,9 @@ fun HashMap.get(key: String, default: String?): String? { fun HashMap.get(key: String, default: Boolean): Boolean { return this[key]?.toBoolean() ?: default } +fun HashMap.getBooleanOrNull(key: String): Boolean? { + return this[key]?.toBooleanStrictOrNull() +} fun HashMap.get(key: String, default: Int): Int { return this[key]?.toIntOrNull() ?: default } diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/config/utils/ConfigMigration.kt b/app/src/main/java/pl/szczodrzynski/edziennik/config/utils/ConfigMigration.kt index 1095f511..58dc35f7 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/config/utils/ConfigMigration.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/config/utils/ConfigMigration.kt @@ -67,7 +67,7 @@ class ConfigMigration(app: App, config: Config) { if (dataVersion < 3) { update = null privacyPolicyAccepted = false - debugMode = false + devMode = null devModePassword = null appInstalledTime = 0L appRateSnackbarTime = 0L diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/debug/LabFragment.kt b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/debug/LabFragment.kt index 60c30cf9..f7c8952d 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/debug/LabFragment.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/debug/LabFragment.kt @@ -41,6 +41,7 @@ class LabFragment : Fragment(), CoroutineScope { app = activity.application as App b = TemplateFragmentBinding.inflate(inflater) b.refreshLayout.setParent(activity.swipeRefreshLayout) + b.refreshLayout.isEnabled = false return b.root } diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/debug/LabPageFragment.kt b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/debug/LabPageFragment.kt index 4d8205bf..19ae4697 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/debug/LabPageFragment.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/debug/LabPageFragment.kt @@ -16,6 +16,7 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Job import kotlinx.coroutines.launch import pl.szczodrzynski.edziennik.* +import pl.szczodrzynski.edziennik.config.Config import pl.szczodrzynski.edziennik.data.db.entity.Event import pl.szczodrzynski.edziennik.databinding.LabFragmentBinding import pl.szczodrzynski.edziennik.ui.dialogs.profile.ProfileRemoveDialog @@ -78,10 +79,10 @@ class LabPageFragment : LazyFragment(), CoroutineScope { app.db.eventDao().getRawNow("UPDATE events SET homeworkBody = NULL WHERE profileId = ${App.profileId}") } - b.chucker.isChecked = app.config.enableChucker - + b.chucker.isChecked = App.enableChucker b.chucker.onChange { _, isChecked -> app.config.enableChucker = isChecked + App.enableChucker = isChecked MaterialAlertDialogBuilder(activity) .setTitle("Restart") .setMessage("Wymagany restart aplikacji") @@ -94,9 +95,9 @@ class LabPageFragment : LazyFragment(), CoroutineScope { .show() } - b.disableDebug.onClick { - app.config.debugMode = false + app.config.devMode = false + App.devMode = false MaterialAlertDialogBuilder(activity) .setTitle("Restart") .setMessage("Wymagany restart aplikacji") @@ -115,6 +116,14 @@ class LabPageFragment : LazyFragment(), CoroutineScope { app.profileSave() } + b.resetCert.onClick { + app.config.apiInvalidCert = null + } + + b.rebuildConfig.onClick { + App.config = Config(App.db) + } + val profiles = app.db.profileDao().allNow b.profile.clear() b.profile += profiles.map { TextInputDropDown.Item(it.id.toLong(), "${it.id} ${it.name} archived ${it.archived}", tag = it) } diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/login/LoginPrizeFragment.kt b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/login/LoginPrizeFragment.kt index 1c9634fc..f14c6d19 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/login/LoginPrizeFragment.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/login/LoginPrizeFragment.kt @@ -53,7 +53,7 @@ class LoginPrizeFragment : Fragment(), CoroutineScope { .setTitle(R.string.are_you_sure) .setMessage(R.string.dev_mode_enable_warning) .setPositiveButton(R.string.yes) { _, _ -> - app.config.debugMode = true + app.config.devMode = true App.devMode = true MaterialAlertDialogBuilder(activity) .setTitle("Restart") @@ -67,8 +67,8 @@ class LoginPrizeFragment : Fragment(), CoroutineScope { .show() } .setNegativeButton(R.string.no) { _, _ -> - app.config.debugMode = false - App.devMode = false + app.config.devMode = App.debugMode + App.devMode = App.debugMode activity.finish() } .show() diff --git a/app/src/main/res/layout/lab_fragment.xml b/app/src/main/res/layout/lab_fragment.xml index 6c4bca77..d0756d7f 100644 --- a/app/src/main/res/layout/lab_fragment.xml +++ b/app/src/main/res/layout/lab_fragment.xml @@ -1,15 +1,17 @@ - - - - + + --> - + tools:text="Cookies:\n\nsynergia.librus.pl\n DZIENNIKSID=L01~1234567890abcdef" />