From 0a2f252405dc6973642e5d71cbf45c82b15c7f62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kuba=20Szczodrzy=C5=84ski?= Date: Mon, 2 Dec 2019 18:12:52 +0100 Subject: [PATCH] [UI/Home] Implement home card swapping and saving. --- app/proguard/app.pro | 1 + .../java/pl/szczodrzynski/edziennik/App.java | 5 +++ .../edziennik/config/ConfigSync.kt | 7 +-- .../edziennik/config/ConfigUI.kt | 6 +++ .../config/utils/ConfigExtensions.kt | 5 ++- .../edziennik/config/utils/ConfigGsonUtils.kt | 44 +++++++++++++++++++ .../edziennik/ui/modules/home/HomeCard.kt | 23 ++++++++++ .../ui/modules/home/HomeCardModel.kt | 12 +++++ .../ui/modules/home/HomeDummyCard.kt | 2 +- .../ui/modules/home/HomeFragmentV2.kt | 33 +++++++++++--- .../ui/modules/home/cards/HomeGradesCard.kt | 2 +- .../modules/home/cards/HomeLuckyNumberCard.kt | 2 +- .../modules/home/cards/HomeTimetableCard.kt | 2 +- 13 files changed, 130 insertions(+), 14 deletions(-) create mode 100644 app/src/main/java/pl/szczodrzynski/edziennik/config/utils/ConfigGsonUtils.kt create mode 100644 app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/home/HomeCardModel.kt diff --git a/app/proguard/app.pro b/app/proguard/app.pro index aeecf18d..cd39e808 100644 --- a/app/proguard/app.pro +++ b/app/proguard/app.pro @@ -24,6 +24,7 @@ -keep class pl.szczodrzynski.edziennik.utils.models.** { *; } -keep class pl.szczodrzynski.edziennik.data.db.modules.events.Event { *; } -keep class pl.szczodrzynski.edziennik.data.db.modules.events.EventFull { *; } +-keep class pl.szczodrzynski.edziennik.ui.modules.home.HomeCardModel { *; } -keepclassmembers class pl.szczodrzynski.edziennik.widgets.WidgetConfig { public *; } -keepnames class pl.szczodrzynski.edziennik.WidgetTimetable -keepnames class pl.szczodrzynski.edziennik.notifications.WidgetNotifications diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/App.java b/app/src/main/java/pl/szczodrzynski/edziennik/App.java index db821d8c..0b62324b 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/App.java +++ b/app/src/main/java/pl/szczodrzynski/edziennik/App.java @@ -143,6 +143,10 @@ public class App extends androidx.multidex.MultiDexApplication implements Config public ProfileFull profile; public Config config; + private static Config mConfig; + public static Config getConfig() { + return mConfig; + } // other stuff public Gson gson; @@ -194,6 +198,7 @@ public class App extends androidx.multidex.MultiDexApplication implements Config config = new Config(db); config.migrate(this); + mConfig = config; Iconics.init(getApplicationContext()); Iconics.registerFont(SzkolnyFont.INSTANCE); diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/config/ConfigSync.kt b/app/src/main/java/pl/szczodrzynski/edziennik/config/ConfigSync.kt index 68168dd6..01810824 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/config/ConfigSync.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/config/ConfigSync.kt @@ -5,6 +5,7 @@ package pl.szczodrzynski.edziennik.config import pl.szczodrzynski.edziennik.config.utils.get +import pl.szczodrzynski.edziennik.config.utils.getIntList import pl.szczodrzynski.edziennik.config.utils.set class ConfigSync(private val config: Config) { @@ -74,14 +75,14 @@ class ConfigSync(private val config: Config) { private var mTokenMobidziennikList: List? = null var tokenMobidziennikList: List - get() { mTokenMobidziennikList = mTokenMobidziennikList ?: config.values.get("tokenMobidziennikList", listOf()); return mTokenMobidziennikList ?: listOf() } + get() { mTokenMobidziennikList = mTokenMobidziennikList ?: config.values.getIntList("tokenMobidziennikList", listOf()); return mTokenMobidziennikList ?: listOf() } set(value) { config.set("tokenMobidziennikList", value); mTokenMobidziennikList = value } private var mTokenLibrusList: List? = null var tokenLibrusList: List - get() { mTokenLibrusList = mTokenLibrusList ?: config.values.get("tokenLibrusList", listOf()); return mTokenLibrusList ?: listOf() } + get() { mTokenLibrusList = mTokenLibrusList ?: config.values.getIntList("tokenLibrusList", listOf()); return mTokenLibrusList ?: listOf() } set(value) { config.set("tokenLibrusList", value); mTokenLibrusList = value } private var mTokenVulcanList: List? = null var tokenVulcanList: List - get() { mTokenVulcanList = mTokenVulcanList ?: config.values.get("tokenVulcanList", listOf()); return mTokenVulcanList ?: listOf() } + get() { mTokenVulcanList = mTokenVulcanList ?: config.values.getIntList("tokenVulcanList", listOf()); return mTokenVulcanList ?: listOf() } set(value) { config.set("tokenVulcanList", value); mTokenVulcanList = value } } \ No newline at end of file diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/config/ConfigUI.kt b/app/src/main/java/pl/szczodrzynski/edziennik/config/ConfigUI.kt index 007f238e..a661148d 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/config/ConfigUI.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/config/ConfigUI.kt @@ -7,6 +7,7 @@ package pl.szczodrzynski.edziennik.config import pl.szczodrzynski.edziennik.config.utils.get import pl.szczodrzynski.edziennik.config.utils.getIntList import pl.szczodrzynski.edziennik.config.utils.set +import pl.szczodrzynski.edziennik.ui.modules.home.HomeCardModel class ConfigUI(private val config: Config) { private var mTheme: Int? = null @@ -43,4 +44,9 @@ class ConfigUI(private val config: Config) { var agendaViewType: Int get() { mAgendaViewType = mAgendaViewType ?: config.values.get("agendaViewType", 0); return mAgendaViewType ?: 0 } set(value) { config.set("agendaViewType", value); mAgendaViewType = value } + + private var mHomeCards: List? = null + var homeCards: List + get() { mHomeCards = mHomeCards ?: config.values.get("homeCards", listOf(), HomeCardModel::class.java); return mHomeCards ?: listOf() } + set(value) { config.set("homeCards", value); mHomeCards = value } } \ No newline at end of file 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 77597503..aec5ebee 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 @@ -74,8 +74,9 @@ fun HashMap.get(key: String, default: JsonObject?): JsonObject? fun HashMap.get(key: String, default: JsonArray?): JsonArray? { return this[key]?.let { JsonParser().parse(it)?.asJsonArray } ?: default } -fun HashMap.get(key: String, default: List?): List? { - return this[key]?.let { gson.fromJson>(it, object: TypeToken>(){}.type) } ?: default +/* !!! cannot use mutable list here - modifying it will not update the DB */ +fun HashMap.get(key: String, default: List?, classOfT: Class): List? { + return this[key]?.let { ConfigGsonUtils().deserializeList(gson, it, classOfT) } ?: default } fun HashMap.getStringList(key: String, default: List?): List? { return this[key]?.let { gson.fromJson>(it, object: TypeToken>(){}.type) } ?: default diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/config/utils/ConfigGsonUtils.kt b/app/src/main/java/pl/szczodrzynski/edziennik/config/utils/ConfigGsonUtils.kt new file mode 100644 index 00000000..eb04578d --- /dev/null +++ b/app/src/main/java/pl/szczodrzynski/edziennik/config/utils/ConfigGsonUtils.kt @@ -0,0 +1,44 @@ +/* + * Copyright (c) Kuba SzczodrzyƄski 2019-12-2. + */ +package pl.szczodrzynski.edziennik.config.utils + +import com.google.gson.Gson +import com.google.gson.JsonParser +import pl.szczodrzynski.edziennik.getInt +import pl.szczodrzynski.edziennik.ui.modules.home.HomeCardModel +import pl.szczodrzynski.edziennik.utils.models.Time + +class ConfigGsonUtils { + fun deserializeList(gson: Gson, str: String?, classOfT: Class): List { + val json = JsonParser().parse(str) + val list: MutableList = mutableListOf() + if (!json.isJsonArray) + return list + + json.asJsonArray.forEach { e -> + when (classOfT) { + String::class.java -> { + list += e.asString as T + } + HomeCardModel::class.java -> { + val o = e.asJsonObject + list += HomeCardModel( + o.getInt("profileId", 0), + o.getInt("cardId", 0) + ) as T + } + Time::class.java -> { + val o = e.asJsonObject + list += Time( + o.getInt("hour", 0), + o.getInt("minute", 0), + o.getInt("second", 0) + ) as T + } + } + } + + return list + } +} \ No newline at end of file diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/home/HomeCard.kt b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/home/HomeCard.kt index e6f28c68..2c7894ce 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/home/HomeCard.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/home/HomeCard.kt @@ -5,6 +5,29 @@ package pl.szczodrzynski.edziennik.ui.modules.home interface HomeCard { + companion object { + /** + * A card is visible on every profile. + * On a unified home fragment, shows + * summary data from every profile. + * Not every card may work like this. + */ + const val PROFILE_UNIFIED = -1 + /** + * A card is visible on every profile, but does + * not show every profile, just the currently + * loaded one. + */ + const val PROFILE_ALL = 0 + + const val CARD_LUCKY_NUMBER = 1 + const val CARD_TIMETABLE = 2 + const val CARD_GRADES = 3 + const val CARD_EVENTS = 4 + } + + val id: Int + fun bind(position: Int, holder: HomeCardAdapter.ViewHolder) fun unbind(position: Int, holder: HomeCardAdapter.ViewHolder) } \ No newline at end of file diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/home/HomeCardModel.kt b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/home/HomeCardModel.kt new file mode 100644 index 00000000..bc577713 --- /dev/null +++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/home/HomeCardModel.kt @@ -0,0 +1,12 @@ +/* + * Copyright (c) Kuba SzczodrzyƄski 2019-12-2. + */ + +package pl.szczodrzynski.edziennik.ui.modules.home + +import java.io.Serializable + +data class HomeCardModel( + val profileId: Int, + val cardId: Int +) : Serializable \ No newline at end of file diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/home/HomeDummyCard.kt b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/home/HomeDummyCard.kt index 88564bad..ac271b9c 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/home/HomeDummyCard.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/home/HomeDummyCard.kt @@ -15,7 +15,7 @@ import pl.szczodrzynski.edziennik.MainActivity import pl.szczodrzynski.edziennik.startCoroutineTimer import kotlin.coroutines.CoroutineContext -class HomeDummyCard(val id: Int) : HomeCard, CoroutineScope { +class HomeDummyCard(override val id: Int) : HomeCard, CoroutineScope { companion object { private const val TAG = "HomeDummyCard" } diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/home/HomeFragmentV2.kt b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/home/HomeFragmentV2.kt index 33ae7652..00d52259 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/home/HomeFragmentV2.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/home/HomeFragmentV2.kt @@ -41,6 +41,12 @@ class HomeFragmentV2 : Fragment(), CoroutineScope { private const val TAG = "HomeFragment" fun swapCards(fromPosition: Int, toPosition: Int, cardAdapter: HomeCardAdapter) { + val homeCards = App.getConfig().ui.homeCards.toMutableList() + val fromPair = homeCards[fromPosition] + homeCards[fromPosition] = homeCards[toPosition] + homeCards[toPosition] = fromPair + App.getConfig().ui.homeCards = homeCards + val fromCard = cardAdapter.items[fromPosition] cardAdapter.items[fromPosition] = cardAdapter.items[toPosition] cardAdapter.items[toPosition] = fromCard @@ -93,11 +99,28 @@ class HomeFragmentV2 : Fragment(), CoroutineScope { }) ) - val items = mutableListOf( - HomeLuckyNumberCard(0, app, activity, this, app.profile), - HomeTimetableCard(1, app, activity, this, app.profile), - HomeGradesCard(2, app, activity, this, app.profile) - ) + val showUnified = false + + val cards = app.config.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) + ) + app.config.ui.homeCards = app.config.ui.homeCards.toMutableList().also { it.addAll(cards) } + } + + val items = mutableListOf() + cards.mapNotNullTo(items) { + when (it.cardId) { + HomeCard.CARD_LUCKY_NUMBER -> HomeLuckyNumberCard(it.cardId, app, activity, this, app.profile) + HomeCard.CARD_TIMETABLE -> HomeTimetableCard(it.cardId, app, activity, this, app.profile) + HomeCard.CARD_GRADES -> HomeGradesCard(it.cardId, app, activity, this, app.profile) + else -> null + } + } val adapter = HomeCardAdapter(items) val itemTouchHelper = ItemTouchHelper(CardItemTouchHelperCallback(adapter, b.refreshLayout)) diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/home/cards/HomeGradesCard.kt b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/home/cards/HomeGradesCard.kt index 21d720bf..4dd55615 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/home/cards/HomeGradesCard.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/home/cards/HomeGradesCard.kt @@ -43,7 +43,7 @@ import pl.szczodrzynski.edziennik.utils.models.ItemGradesSubjectModel import kotlin.coroutines.CoroutineContext class HomeGradesCard( - val id: Int, + override val id: Int, val app: App, val activity: MainActivity, val fragment: HomeFragmentV2, diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/home/cards/HomeLuckyNumberCard.kt b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/home/cards/HomeLuckyNumberCard.kt index fee05477..652db015 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/home/cards/HomeLuckyNumberCard.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/home/cards/HomeLuckyNumberCard.kt @@ -26,7 +26,7 @@ import pl.szczodrzynski.edziennik.utils.models.Date import kotlin.coroutines.CoroutineContext class HomeLuckyNumberCard( - val id: Int, + override val id: Int, val app: App, val activity: MainActivity, val fragment: HomeFragmentV2, diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/home/cards/HomeTimetableCard.kt b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/home/cards/HomeTimetableCard.kt index 759d3c65..e3a2feeb 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/home/cards/HomeTimetableCard.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/home/cards/HomeTimetableCard.kt @@ -32,7 +32,7 @@ import pl.szczodrzynski.navlib.colorAttr import kotlin.coroutines.CoroutineContext class HomeTimetableCard( - val id: Int, + override val id: Int, val app: App, val activity: MainActivity, val fragment: HomeFragmentV2,