From 0d366adddb0d0aed8672bbc0118aca44348b96a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kuba=20Szczodrzy=C5=84ski?= Date: Tue, 25 Aug 2020 16:01:11 +0200 Subject: [PATCH] [UI] Implement showing archived profiles in drawer. --- .../java/pl/szczodrzynski/edziennik/App.kt | 3 + .../szczodrzynski/edziennik/MainActivity.kt | 76 ++++++++++++++++--- .../edziennik/data/db/dao/ProfileDao.kt | 6 ++ .../edziennik/data/db/entity/Profile.kt | 20 +++-- .../ui/modules/debug/LabPageFragment.kt | 10 +++ .../main/res/drawable/profile_archived.xml | 6 ++ app/src/main/res/layout/lab_fragment.xml | 6 ++ 7 files changed, 112 insertions(+), 15 deletions(-) create mode 100644 app/src/main/res/drawable/profile_archived.xml diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/App.kt b/app/src/main/java/pl/szczodrzynski/edziennik/App.kt index bea90a98..65836b5e 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/App.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/App.kt @@ -364,6 +364,9 @@ class App : MultiDexApplication(), Configuration.Provider, CoroutineScope { if (!success) { EventBus.getDefault().post(ProfileListEmptyEvent()) } + else { + onSuccess(profile) + } } } fun profileSave() = profileSave(profile) diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/MainActivity.kt b/app/src/main/java/pl/szczodrzynski/edziennik/MainActivity.kt index 0efa539e..272d8c0d 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/MainActivity.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/MainActivity.kt @@ -43,6 +43,7 @@ import pl.szczodrzynski.edziennik.data.api.events.* import pl.szczodrzynski.edziennik.data.api.models.ApiError import pl.szczodrzynski.edziennik.data.db.entity.LoginStore import pl.szczodrzynski.edziennik.data.db.entity.Metadata.* +import pl.szczodrzynski.edziennik.data.db.entity.Profile import pl.szczodrzynski.edziennik.databinding.ActivitySzkolnyBinding import pl.szczodrzynski.edziennik.sync.AppManagerDetectedEvent import pl.szczodrzynski.edziennik.sync.SyncWorker @@ -409,6 +410,18 @@ class MainActivity : AppCompatActivity(), CoroutineScope { app.db.profileDao().all.observe(this, Observer { profiles -> drawer.setProfileList(profiles.filter { it.id >= 0 && !it.archived }.toMutableList()) + //prepend the archived profile if loaded + if (app.profile.archived) { + drawer.prependProfile(Profile( + id = app.profile.id, + loginStoreId = app.profile.loginStoreId, + loginStoreType = app.profile.loginStoreType, + name = app.profile.name, + subname = "Archiwum - ${app.profile.subname}" + ).also { + it.archived = true + }) + } drawer.currentProfile = App.profileId }) @@ -434,6 +447,23 @@ class MainActivity : AppCompatActivity(), CoroutineScope { SyncWorker.scheduleNext(app) UpdateWorker.scheduleNext(app) + // if loaded profile is archived, switch to the up-to-date version of it + if (app.profile.archived) { + launch { + if (app.profile.archiveId != null) { + val profile = withContext(Dispatchers.IO) { + app.db.profileDao().getNotArchivedOf(app.profile.archiveId!!) + } + if (profile != null) + loadProfile(profile) + else + loadProfile(0) + } else { + loadProfile(0) + } + } + } + // APP BACKGROUND if (app.config.ui.appBackground != null) { try { @@ -894,23 +924,51 @@ class MainActivity : AppCompatActivity(), CoroutineScope { fun loadProfile(id: Int) = loadProfile(id, navTargetId) fun loadProfile(id: Int, arguments: Bundle?) = loadProfile(id, navTargetId, arguments) - fun loadProfile(id: Int, drawerSelection: Int, arguments: Bundle? = null) { + fun loadProfile(profile: Profile) = loadProfile( + profile, + navTargetId, + null, + if (app.profile.archived) app.profile.id else null + ) + private fun loadProfile(id: Int, drawerSelection: Int, arguments: Bundle? = null) { if (App.profileId == id) { drawer.currentProfile = app.profile.id loadTarget(drawerSelection, arguments) return } + val previousArchivedId = if (app.profile.archived) app.profile.id else null app.profileLoad(id) { - MessagesFragment.pageSelection = -1 - - setDrawerItems() - // the drawer profile is updated automatically when the drawer item is clicked - // update it manually when switching profiles from other source - //if (drawer.currentProfile != app.profile.id) - drawer.currentProfile = app.profileId - loadTarget(drawerSelection, arguments) + loadProfile(it, drawerSelection, arguments, previousArchivedId) } } + private fun loadProfile(profile: Profile, drawerSelection: Int, arguments: Bundle?, previousArchivedId: Int?) { + App.profile = profile + MessagesFragment.pageSelection = -1 + + setDrawerItems() + + if (previousArchivedId != null) { + // prevents accidentally removing the first item if the archived profile is not shown + drawer.removeProfileById(previousArchivedId) + } + if (profile.archived) { + drawer.prependProfile(Profile( + id = profile.id, + loginStoreId = profile.loginStoreId, + loginStoreType = profile.loginStoreType, + name = profile.name, + subname = "Archiwum - ${profile.subname}" + ).also { + it.archived = true + }) + } + + // the drawer profile is updated automatically when the drawer item is clicked + // update it manually when switching profiles from other source + //if (drawer.currentProfile != app.profile.id) + drawer.currentProfile = app.profileId + loadTarget(drawerSelection, arguments) + } fun loadTarget(id: Int, arguments: Bundle? = null) { var loadId = id if (loadId == -1) { diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/db/dao/ProfileDao.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/dao/ProfileDao.kt index 3225141e..6d1e799d 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/data/db/dao/ProfileDao.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/dao/ProfileDao.kt @@ -60,4 +60,10 @@ interface ProfileDao { @Query("UPDATE profiles SET empty = 0") fun setAllNotEmpty() + + @Query("SELECT * FROM profiles WHERE archiveId = :archiveId AND archived = 1") + fun getArchivesOf(archiveId: Int): List + + @Query("SELECT * FROM profiles WHERE archiveId = :archiveId AND archived = 0 ORDER BY profileId DESC LIMIT 1") + fun getNotArchivedOf(archiveId: Int): Profile? } 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 e9d931a5..f919f7c0 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 @@ -112,14 +112,18 @@ open class Profile( get() = accountName != null override fun getImageDrawable(context: Context): Drawable { + if (archived) { + return context.getDrawableFromRes(pl.szczodrzynski.edziennik.R.drawable.profile_archived).also { + it.colorFilter = PorterDuffColorFilter(colorFromName(name), PorterDuff.Mode.DST_OVER) + } + } if (!image.isNullOrEmpty()) { try { - if (image?.endsWith(".gif", true) == true) { - return GifDrawable(image ?: "") - } - else { - return RoundedBitmapDrawableFactory.create(context.resources, image ?: "") + return if (image?.endsWith(".gif", true) == true) { + GifDrawable(image ?: "") + } else { + RoundedBitmapDrawableFactory.create(context.resources, image ?: "") //return Drawable.createFromPath(image ?: "") ?: throw Exception() } } @@ -131,9 +135,13 @@ open class Profile( return context.getDrawableFromRes(R.drawable.profile).also { it.colorFilter = PorterDuffColorFilter(colorFromName(name), PorterDuff.Mode.DST_OVER) } - } + override fun getImageHolder(context: Context): ImageHolder { + if (archived) { + return ImageHolder(pl.szczodrzynski.edziennik.R.drawable.profile_archived, colorFromName(name)) + } + return if (!image.isNullOrEmpty()) { try { ProfileImageHolder(image ?: "") 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 304a7df7..72b9f9f5 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 @@ -17,6 +17,7 @@ import pl.szczodrzynski.edziennik.* import pl.szczodrzynski.edziennik.data.db.entity.Event import pl.szczodrzynski.edziennik.databinding.LabFragmentBinding import pl.szczodrzynski.edziennik.ui.modules.base.lazypager.LazyFragment +import pl.szczodrzynski.edziennik.utils.TextInputDropDown import pl.szczodrzynski.fslogin.decode import kotlin.coroutines.CoroutineContext @@ -68,6 +69,15 @@ class LabPageFragment : LazyFragment(), CoroutineScope { app.profileSave() } + 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) } + b.profile.select(app.profileId.toLong()) + b.profile.setOnChangeListener { + activity.loadProfile(it.id.toInt()) + return@setOnChangeListener true + } + val colorSecondary = android.R.attr.textColorSecondary.resolveAttr(activity) startCoroutineTimer(500L, 300L) { val text = app.cookieJar.sessionCookies diff --git a/app/src/main/res/drawable/profile_archived.xml b/app/src/main/res/drawable/profile_archived.xml new file mode 100644 index 00000000..c816dcc8 --- /dev/null +++ b/app/src/main/res/drawable/profile_archived.xml @@ -0,0 +1,6 @@ + + + + diff --git a/app/src/main/res/layout/lab_fragment.xml b/app/src/main/res/layout/lab_fragment.xml index acc924a7..b023e11c 100644 --- a/app/src/main/res/layout/lab_fragment.xml +++ b/app/src/main/res/layout/lab_fragment.xml @@ -68,6 +68,12 @@ android:layout_height="wrap_content" android:text="Unarchive this profile" android:textAllCaps="false" /> + +