mirror of
https://github.com/szkolny-eu/szkolny-android.git
synced 2025-01-18 12:56:45 -06:00
[UI/Home] Implement home card swapping and saving.
This commit is contained in:
parent
09bc658f97
commit
0a2f252405
@ -24,6 +24,7 @@
|
|||||||
-keep class pl.szczodrzynski.edziennik.utils.models.** { *; }
|
-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.Event { *; }
|
||||||
-keep class pl.szczodrzynski.edziennik.data.db.modules.events.EventFull { *; }
|
-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 *; }
|
-keepclassmembers class pl.szczodrzynski.edziennik.widgets.WidgetConfig { public *; }
|
||||||
-keepnames class pl.szczodrzynski.edziennik.WidgetTimetable
|
-keepnames class pl.szczodrzynski.edziennik.WidgetTimetable
|
||||||
-keepnames class pl.szczodrzynski.edziennik.notifications.WidgetNotifications
|
-keepnames class pl.szczodrzynski.edziennik.notifications.WidgetNotifications
|
||||||
|
@ -143,6 +143,10 @@ public class App extends androidx.multidex.MultiDexApplication implements Config
|
|||||||
|
|
||||||
public ProfileFull profile;
|
public ProfileFull profile;
|
||||||
public Config config;
|
public Config config;
|
||||||
|
private static Config mConfig;
|
||||||
|
public static Config getConfig() {
|
||||||
|
return mConfig;
|
||||||
|
}
|
||||||
|
|
||||||
// other stuff
|
// other stuff
|
||||||
public Gson gson;
|
public Gson gson;
|
||||||
@ -194,6 +198,7 @@ public class App extends androidx.multidex.MultiDexApplication implements Config
|
|||||||
|
|
||||||
config = new Config(db);
|
config = new Config(db);
|
||||||
config.migrate(this);
|
config.migrate(this);
|
||||||
|
mConfig = config;
|
||||||
|
|
||||||
Iconics.init(getApplicationContext());
|
Iconics.init(getApplicationContext());
|
||||||
Iconics.registerFont(SzkolnyFont.INSTANCE);
|
Iconics.registerFont(SzkolnyFont.INSTANCE);
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
package pl.szczodrzynski.edziennik.config
|
package pl.szczodrzynski.edziennik.config
|
||||||
|
|
||||||
import pl.szczodrzynski.edziennik.config.utils.get
|
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.config.utils.set
|
||||||
|
|
||||||
class ConfigSync(private val config: Config) {
|
class ConfigSync(private val config: Config) {
|
||||||
@ -74,14 +75,14 @@ class ConfigSync(private val config: Config) {
|
|||||||
|
|
||||||
private var mTokenMobidziennikList: List<Int>? = null
|
private var mTokenMobidziennikList: List<Int>? = null
|
||||||
var tokenMobidziennikList: List<Int>
|
var tokenMobidziennikList: List<Int>
|
||||||
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 }
|
set(value) { config.set("tokenMobidziennikList", value); mTokenMobidziennikList = value }
|
||||||
private var mTokenLibrusList: List<Int>? = null
|
private var mTokenLibrusList: List<Int>? = null
|
||||||
var tokenLibrusList: List<Int>
|
var tokenLibrusList: List<Int>
|
||||||
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 }
|
set(value) { config.set("tokenLibrusList", value); mTokenLibrusList = value }
|
||||||
private var mTokenVulcanList: List<Int>? = null
|
private var mTokenVulcanList: List<Int>? = null
|
||||||
var tokenVulcanList: List<Int>
|
var tokenVulcanList: List<Int>
|
||||||
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 }
|
set(value) { config.set("tokenVulcanList", value); mTokenVulcanList = value }
|
||||||
}
|
}
|
@ -7,6 +7,7 @@ package pl.szczodrzynski.edziennik.config
|
|||||||
import pl.szczodrzynski.edziennik.config.utils.get
|
import pl.szczodrzynski.edziennik.config.utils.get
|
||||||
import pl.szczodrzynski.edziennik.config.utils.getIntList
|
import pl.szczodrzynski.edziennik.config.utils.getIntList
|
||||||
import pl.szczodrzynski.edziennik.config.utils.set
|
import pl.szczodrzynski.edziennik.config.utils.set
|
||||||
|
import pl.szczodrzynski.edziennik.ui.modules.home.HomeCardModel
|
||||||
|
|
||||||
class ConfigUI(private val config: Config) {
|
class ConfigUI(private val config: Config) {
|
||||||
private var mTheme: Int? = null
|
private var mTheme: Int? = null
|
||||||
@ -43,4 +44,9 @@ class ConfigUI(private val config: Config) {
|
|||||||
var agendaViewType: Int
|
var agendaViewType: Int
|
||||||
get() { mAgendaViewType = mAgendaViewType ?: config.values.get("agendaViewType", 0); return mAgendaViewType ?: 0 }
|
get() { mAgendaViewType = mAgendaViewType ?: config.values.get("agendaViewType", 0); return mAgendaViewType ?: 0 }
|
||||||
set(value) { config.set("agendaViewType", value); mAgendaViewType = value }
|
set(value) { config.set("agendaViewType", value); mAgendaViewType = 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() }
|
||||||
|
set(value) { config.set("homeCards", value); mHomeCards = value }
|
||||||
}
|
}
|
@ -74,8 +74,9 @@ fun HashMap<String, String?>.get(key: String, default: JsonObject?): JsonObject?
|
|||||||
fun HashMap<String, String?>.get(key: String, default: JsonArray?): JsonArray? {
|
fun HashMap<String, String?>.get(key: String, default: JsonArray?): JsonArray? {
|
||||||
return this[key]?.let { JsonParser().parse(it)?.asJsonArray } ?: default
|
return this[key]?.let { JsonParser().parse(it)?.asJsonArray } ?: default
|
||||||
}
|
}
|
||||||
fun <T> HashMap<String, String?>.get(key: String, default: List<T>?): List<T>? {
|
/* !!! cannot use mutable list here - modifying it will not update the DB */
|
||||||
return this[key]?.let { gson.fromJson<List<T>>(it, object: TypeToken<List<T>>(){}.type) } ?: default
|
fun <T> HashMap<String, String?>.get(key: String, default: List<T>?, classOfT: Class<T>): List<T>? {
|
||||||
|
return this[key]?.let { ConfigGsonUtils().deserializeList<T>(gson, it, classOfT) } ?: default
|
||||||
}
|
}
|
||||||
fun HashMap<String, String?>.getStringList(key: String, default: List<String>?): List<String>? {
|
fun HashMap<String, String?>.getStringList(key: String, default: List<String>?): List<String>? {
|
||||||
return this[key]?.let { gson.fromJson<List<String>>(it, object: TypeToken<List<String>>(){}.type) } ?: default
|
return this[key]?.let { gson.fromJson<List<String>>(it, object: TypeToken<List<String>>(){}.type) } ?: default
|
||||||
|
@ -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 <T> deserializeList(gson: Gson, str: String?, classOfT: Class<T>): List<T> {
|
||||||
|
val json = JsonParser().parse(str)
|
||||||
|
val list: MutableList<T> = 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
|
||||||
|
}
|
||||||
|
}
|
@ -5,6 +5,29 @@
|
|||||||
package pl.szczodrzynski.edziennik.ui.modules.home
|
package pl.szczodrzynski.edziennik.ui.modules.home
|
||||||
|
|
||||||
interface HomeCard {
|
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 bind(position: Int, holder: HomeCardAdapter.ViewHolder)
|
||||||
fun unbind(position: Int, holder: HomeCardAdapter.ViewHolder)
|
fun unbind(position: Int, holder: HomeCardAdapter.ViewHolder)
|
||||||
}
|
}
|
@ -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
|
@ -15,7 +15,7 @@ import pl.szczodrzynski.edziennik.MainActivity
|
|||||||
import pl.szczodrzynski.edziennik.startCoroutineTimer
|
import pl.szczodrzynski.edziennik.startCoroutineTimer
|
||||||
import kotlin.coroutines.CoroutineContext
|
import kotlin.coroutines.CoroutineContext
|
||||||
|
|
||||||
class HomeDummyCard(val id: Int) : HomeCard, CoroutineScope {
|
class HomeDummyCard(override val id: Int) : HomeCard, CoroutineScope {
|
||||||
companion object {
|
companion object {
|
||||||
private const val TAG = "HomeDummyCard"
|
private const val TAG = "HomeDummyCard"
|
||||||
}
|
}
|
||||||
|
@ -41,6 +41,12 @@ class HomeFragmentV2 : Fragment(), CoroutineScope {
|
|||||||
private const val TAG = "HomeFragment"
|
private const val TAG = "HomeFragment"
|
||||||
|
|
||||||
fun swapCards(fromPosition: Int, toPosition: Int, cardAdapter: HomeCardAdapter) {
|
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]
|
val fromCard = cardAdapter.items[fromPosition]
|
||||||
cardAdapter.items[fromPosition] = cardAdapter.items[toPosition]
|
cardAdapter.items[fromPosition] = cardAdapter.items[toPosition]
|
||||||
cardAdapter.items[toPosition] = fromCard
|
cardAdapter.items[toPosition] = fromCard
|
||||||
@ -93,11 +99,28 @@ class HomeFragmentV2 : Fragment(), CoroutineScope {
|
|||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
|
||||||
val items = mutableListOf<HomeCard>(
|
val showUnified = false
|
||||||
HomeLuckyNumberCard(0, app, activity, this, app.profile),
|
|
||||||
HomeTimetableCard(1, app, activity, this, app.profile),
|
val cards = app.config.ui.homeCards.filter { it.profileId == app.profile.id }.toMutableList()
|
||||||
HomeGradesCard(2, app, activity, this, app.profile)
|
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<HomeCard>()
|
||||||
|
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 adapter = HomeCardAdapter(items)
|
||||||
val itemTouchHelper = ItemTouchHelper(CardItemTouchHelperCallback(adapter, b.refreshLayout))
|
val itemTouchHelper = ItemTouchHelper(CardItemTouchHelperCallback(adapter, b.refreshLayout))
|
||||||
|
@ -43,7 +43,7 @@ import pl.szczodrzynski.edziennik.utils.models.ItemGradesSubjectModel
|
|||||||
import kotlin.coroutines.CoroutineContext
|
import kotlin.coroutines.CoroutineContext
|
||||||
|
|
||||||
class HomeGradesCard(
|
class HomeGradesCard(
|
||||||
val id: Int,
|
override val id: Int,
|
||||||
val app: App,
|
val app: App,
|
||||||
val activity: MainActivity,
|
val activity: MainActivity,
|
||||||
val fragment: HomeFragmentV2,
|
val fragment: HomeFragmentV2,
|
||||||
|
@ -26,7 +26,7 @@ import pl.szczodrzynski.edziennik.utils.models.Date
|
|||||||
import kotlin.coroutines.CoroutineContext
|
import kotlin.coroutines.CoroutineContext
|
||||||
|
|
||||||
class HomeLuckyNumberCard(
|
class HomeLuckyNumberCard(
|
||||||
val id: Int,
|
override val id: Int,
|
||||||
val app: App,
|
val app: App,
|
||||||
val activity: MainActivity,
|
val activity: MainActivity,
|
||||||
val fragment: HomeFragmentV2,
|
val fragment: HomeFragmentV2,
|
||||||
|
@ -32,7 +32,7 @@ import pl.szczodrzynski.navlib.colorAttr
|
|||||||
import kotlin.coroutines.CoroutineContext
|
import kotlin.coroutines.CoroutineContext
|
||||||
|
|
||||||
class HomeTimetableCard(
|
class HomeTimetableCard(
|
||||||
val id: Int,
|
override val id: Int,
|
||||||
val app: App,
|
val app: App,
|
||||||
val activity: MainActivity,
|
val activity: MainActivity,
|
||||||
val fragment: HomeFragmentV2,
|
val fragment: HomeFragmentV2,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user