import/export settings
This commit is contained in:
parent
b559a13bab
commit
49e90a27b8
97 changed files with 1721 additions and 1441 deletions
362
app/src/main/java/ani/dantotsu/settings/saving/PrefManager.kt
Normal file
362
app/src/main/java/ani/dantotsu/settings/saving/PrefManager.kt
Normal file
|
@ -0,0 +1,362 @@
|
|||
package ani.dantotsu.settings.saving
|
||||
|
||||
import android.content.Context
|
||||
import android.content.SharedPreferences
|
||||
import android.util.Base64
|
||||
import ani.dantotsu.settings.saving.internal.Compat
|
||||
import ani.dantotsu.settings.saving.internal.Location
|
||||
import ani.dantotsu.snackString
|
||||
import java.io.ByteArrayInputStream
|
||||
import java.io.ByteArrayOutputStream
|
||||
import java.io.ObjectInputStream
|
||||
import java.io.ObjectOutputStream
|
||||
|
||||
object PrefManager {
|
||||
|
||||
private var generalPreferences: SharedPreferences? = null
|
||||
private var animePreferences: SharedPreferences? = null
|
||||
private var mangaPreferences: SharedPreferences? = null
|
||||
private var playerPreferences: SharedPreferences? = null
|
||||
private var readerPreferences: SharedPreferences? = null
|
||||
private var irrelevantPreferences: SharedPreferences? = null
|
||||
private var animeDownloadsPreferences: SharedPreferences? = null
|
||||
private var protectedPreferences: SharedPreferences? = null
|
||||
|
||||
fun init(context: Context) { //must be called in Application class or will crash
|
||||
generalPreferences = context.getSharedPreferences(Location.General.location, Context.MODE_PRIVATE)
|
||||
animePreferences = context.getSharedPreferences(Location.Anime.location, Context.MODE_PRIVATE)
|
||||
mangaPreferences = context.getSharedPreferences(Location.Manga.location, Context.MODE_PRIVATE)
|
||||
playerPreferences = context.getSharedPreferences(Location.Player.location, Context.MODE_PRIVATE)
|
||||
readerPreferences = context.getSharedPreferences(Location.Reader.location, Context.MODE_PRIVATE)
|
||||
irrelevantPreferences = context.getSharedPreferences(Location.Irrelevant.location, Context.MODE_PRIVATE)
|
||||
animeDownloadsPreferences = context.getSharedPreferences(Location.AnimeDownloads.location, Context.MODE_PRIVATE)
|
||||
protectedPreferences = context.getSharedPreferences(Location.Protected.location, Context.MODE_PRIVATE)
|
||||
Compat.importOldPrefs(context)
|
||||
}
|
||||
|
||||
fun <T> setVal(prefName: PrefName, value: T?) {
|
||||
val pref = getPrefLocation(prefName.data.prefLocation)
|
||||
with(pref.edit()) {
|
||||
when (value) {
|
||||
is Boolean -> putBoolean(prefName.name, value)
|
||||
is Int -> putInt(prefName.name, value)
|
||||
is Float -> putFloat(prefName.name, value)
|
||||
is Long -> putLong(prefName.name, value)
|
||||
is String -> putString(prefName.name, value)
|
||||
is Set<*> -> convertAndPutStringSet(prefName.name, value)
|
||||
null -> remove(prefName.name)
|
||||
else -> serialzeClass(prefName.name, value)
|
||||
}
|
||||
apply()
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
fun <T> getVal(prefName: PrefName, default: T) : T {
|
||||
return try {
|
||||
val pref = getPrefLocation(prefName.data.prefLocation)
|
||||
when (prefName.data.type) {
|
||||
Boolean::class -> pref.getBoolean(prefName.name, default as Boolean) as T
|
||||
Int::class -> pref.getInt(prefName.name, default as Int) as T
|
||||
Float::class -> pref.getFloat(prefName.name, default as Float) as T
|
||||
Long::class -> pref.getLong(prefName.name, default as Long) as T
|
||||
String::class -> pref.getString(prefName.name, default as String?) as T
|
||||
Set::class -> convertFromStringSet(pref.getStringSet(prefName.name, null), default) as T
|
||||
List::class -> deserialzeClass(prefName.name, default) as T
|
||||
else -> throw IllegalArgumentException("Type not supported")
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
default
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
fun <T> getVal(prefName: PrefName) : T {
|
||||
return try {
|
||||
val pref = getPrefLocation(prefName.data.prefLocation)
|
||||
when (prefName.data.type) {
|
||||
Boolean::class -> pref.getBoolean(prefName.name, prefName.data.default as Boolean) as T
|
||||
Int::class -> pref.getInt(prefName.name, prefName.data.default as Int) as T
|
||||
Float::class -> pref.getFloat(prefName.name, prefName.data.default as Float) as T
|
||||
Long::class -> pref.getLong(prefName.name, prefName.data.default as Long) as T
|
||||
String::class -> pref.getString(prefName.name, prefName.data.default as String?) as T
|
||||
Set::class -> convertFromStringSet(pref.getStringSet(prefName.name, null), prefName.data.default) as T
|
||||
List::class -> deserialzeClass(prefName.name, prefName.data.default) as T
|
||||
else -> throw IllegalArgumentException("Type not supported")
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
prefName.data.default as T
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
fun <T> getNullableVal(prefName: PrefName, default: T?) : T? {
|
||||
return try {
|
||||
val pref = getPrefLocation(prefName.data.prefLocation)
|
||||
when (prefName.data.type) {
|
||||
Boolean::class -> pref.getBoolean(prefName.name, prefName.data.default as Boolean) as T?
|
||||
Int::class -> pref.getInt(prefName.name, prefName.data.default as Int) as T?
|
||||
Float::class -> pref.getFloat(prefName.name, prefName.data.default as Float) as T?
|
||||
Long::class -> pref.getLong(prefName.name, prefName.data.default as Long) as T?
|
||||
String::class -> pref.getString(prefName.name, prefName.data.default as String?) as T?
|
||||
Set::class -> convertFromStringSet(pref.getStringSet(prefName.name, null), prefName.data.default) as T?
|
||||
else -> deserialzeClass(prefName.name, default)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
default
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
fun <T> getCustomVal(key: String, default: T): T {
|
||||
return try {
|
||||
when (default) {
|
||||
is Boolean -> irrelevantPreferences!!.getBoolean(key, default) as T
|
||||
is Int -> irrelevantPreferences!!.getInt(key, default) as T
|
||||
is Float -> irrelevantPreferences!!.getFloat(key, default) as T
|
||||
is Long -> irrelevantPreferences!!.getLong(key, default) as T
|
||||
is String -> irrelevantPreferences!!.getString(key, default) as T
|
||||
is Set<*> -> convertFromStringSet(irrelevantPreferences!!.getStringSet(key, null), default) as T
|
||||
else -> throw IllegalArgumentException("Type not supported")
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
default
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
fun <T> getNullableCustomVal(key: String, default: T): T? {
|
||||
return try {
|
||||
when (default) {
|
||||
is Boolean -> irrelevantPreferences!!.getBoolean(key, default) as T?
|
||||
is Int -> irrelevantPreferences!!.getInt(key, default) as T?
|
||||
is Float -> irrelevantPreferences!!.getFloat(key, default) as T?
|
||||
is Long -> irrelevantPreferences!!.getLong(key, default) as T?
|
||||
is String -> irrelevantPreferences!!.getString(key, default) as T?
|
||||
is Set<*> -> convertFromStringSet(irrelevantPreferences!!.getStringSet(key, null), default) as T?
|
||||
else -> deserialzeClass(key, default)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
default
|
||||
}
|
||||
}
|
||||
|
||||
fun removeVal(prefName: PrefName) {
|
||||
val pref = getPrefLocation(prefName.data.prefLocation)
|
||||
with(pref.edit()) {
|
||||
remove(prefName.name)
|
||||
apply()
|
||||
}
|
||||
}
|
||||
|
||||
fun <T> setCustomVal(key: String, value: T?) {
|
||||
//for custom force irrelevant
|
||||
with(irrelevantPreferences!!.edit()) {
|
||||
when (value) {
|
||||
is Boolean -> putBoolean(key, value as Boolean)
|
||||
is Int -> putInt(key, value as Int)
|
||||
is Float -> putFloat(key, value as Float)
|
||||
is Long -> putLong(key, value as Long)
|
||||
is String -> putString(key, value as String)
|
||||
is Set<*> -> convertAndPutStringSet(key, value)
|
||||
null -> remove(key)
|
||||
else -> serialzeClass(key, value)
|
||||
}
|
||||
apply()
|
||||
}
|
||||
}
|
||||
|
||||
fun removeCustomVal(key: String) {
|
||||
//for custom force irrelevant
|
||||
with(irrelevantPreferences!!.edit()) {
|
||||
remove(key)
|
||||
apply()
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
fun <T> getLiveVal(prefName: PrefName, default: T) : SharedPreferenceLiveData<T> {
|
||||
val pref = getPrefLocation(prefName.data.prefLocation)
|
||||
return when (prefName.data.type) {
|
||||
Boolean::class -> SharedPreferenceBooleanLiveData(
|
||||
pref,
|
||||
prefName.name,
|
||||
default as Boolean
|
||||
) as SharedPreferenceLiveData<T>
|
||||
Int::class -> SharedPreferenceIntLiveData(
|
||||
pref,
|
||||
prefName.name,
|
||||
default as Int
|
||||
) as SharedPreferenceLiveData<T>
|
||||
Float::class -> SharedPreferenceFloatLiveData(
|
||||
pref,
|
||||
prefName.name,
|
||||
default as Float
|
||||
) as SharedPreferenceLiveData<T>
|
||||
Long::class -> SharedPreferenceLongLiveData(
|
||||
pref,
|
||||
prefName.name,
|
||||
default as Long
|
||||
) as SharedPreferenceLiveData<T>
|
||||
String::class -> SharedPreferenceStringLiveData(
|
||||
pref,
|
||||
prefName.name,
|
||||
default as String
|
||||
) as SharedPreferenceLiveData<T>
|
||||
Set::class -> SharedPreferenceStringSetLiveData(
|
||||
pref,
|
||||
prefName.name,
|
||||
default as Set<String>
|
||||
) as SharedPreferenceLiveData<T>
|
||||
else -> throw IllegalArgumentException("Type not supported")
|
||||
}
|
||||
}
|
||||
|
||||
fun SharedPreferenceLiveData<*>.asLiveBool(): SharedPreferenceBooleanLiveData =
|
||||
this as? SharedPreferenceBooleanLiveData
|
||||
?: throw ClassCastException("Cannot cast to SharedPreferenceLiveData<Boolean>")
|
||||
|
||||
fun SharedPreferenceLiveData<*>.asLiveInt(): SharedPreferenceIntLiveData =
|
||||
this as? SharedPreferenceIntLiveData
|
||||
?: throw ClassCastException("Cannot cast to SharedPreferenceLiveData<Int>")
|
||||
|
||||
fun SharedPreferenceLiveData<*>.asLiveFloat(): SharedPreferenceFloatLiveData =
|
||||
this as? SharedPreferenceFloatLiveData
|
||||
?: throw ClassCastException("Cannot cast to SharedPreferenceLiveData<Float>")
|
||||
|
||||
fun SharedPreferenceLiveData<*>.asLiveLong(): SharedPreferenceLongLiveData =
|
||||
this as? SharedPreferenceLongLiveData
|
||||
?: throw ClassCastException("Cannot cast to SharedPreferenceLiveData<Long>")
|
||||
|
||||
fun SharedPreferenceLiveData<*>.asLiveString(): SharedPreferenceStringLiveData =
|
||||
this as? SharedPreferenceStringLiveData
|
||||
?: throw ClassCastException("Cannot cast to SharedPreferenceLiveData<String>")
|
||||
|
||||
fun SharedPreferenceLiveData<*>.asLiveStringSet(): SharedPreferenceStringSetLiveData =
|
||||
this as? SharedPreferenceStringSetLiveData
|
||||
?: throw ClassCastException("Cannot cast to SharedPreferenceLiveData<Set<String>>")
|
||||
|
||||
fun getAnimeDownloadPreferences(): SharedPreferences = animeDownloadsPreferences!! //needs to be used externally
|
||||
|
||||
fun exportAllPrefs(prefLocation: Location): Map<String, *>{
|
||||
val pref = getPrefLocation(prefLocation)
|
||||
val typedMap = mutableMapOf<String, Any>()
|
||||
pref.all.forEach { (key, value) ->
|
||||
val typeValueMap = mapOf(
|
||||
"type" to value?.javaClass?.kotlin?.qualifiedName,
|
||||
"value" to value
|
||||
)
|
||||
typedMap[key] = typeValueMap
|
||||
}
|
||||
|
||||
return typedMap
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
fun importAllPrefs(prefs: Map<String, *>, prefLocation: Location) {
|
||||
val pref = getPrefLocation(prefLocation)
|
||||
with(pref.edit()) {
|
||||
prefs.forEach { (key, value) ->
|
||||
when (value) {
|
||||
is Boolean -> putBoolean(key, value)
|
||||
is Int -> putInt(key, value)
|
||||
is Float -> putFloat(key, value)
|
||||
is Long -> putLong(key, value)
|
||||
is String -> putString(key, value)
|
||||
is HashSet<*> -> putStringSet(key, value as Set<String>)
|
||||
is ArrayList<*> -> putStringSet(key, arrayListToSet(value))
|
||||
is Set<*> -> putStringSet(key, value as Set<String>)
|
||||
else -> snackString("Error importing preference: Type not supported")
|
||||
}
|
||||
}
|
||||
apply()
|
||||
}
|
||||
}
|
||||
|
||||
private fun arrayListToSet(arrayList: ArrayList<*>): Set<String> {
|
||||
return arrayList.map { it.toString() }.toSet()
|
||||
}
|
||||
|
||||
private fun getPrefLocation(prefLoc: Location): SharedPreferences {
|
||||
return when (prefLoc) {
|
||||
Location.General -> generalPreferences
|
||||
Location.UI -> generalPreferences
|
||||
Location.Anime -> animePreferences
|
||||
Location.Manga -> mangaPreferences
|
||||
Location.Player -> playerPreferences
|
||||
Location.Reader -> readerPreferences
|
||||
Location.NovelReader -> readerPreferences
|
||||
Location.Irrelevant -> irrelevantPreferences
|
||||
Location.AnimeDownloads -> animeDownloadsPreferences
|
||||
Location.Protected -> protectedPreferences
|
||||
}!!
|
||||
}
|
||||
|
||||
private fun <T> convertFromStringSet(stringSet: Set<String>?, default: T): Set<*> {
|
||||
if (stringSet.isNullOrEmpty()) return default as Set<*>
|
||||
|
||||
return try {
|
||||
val typeIdentifier = stringSet.first()
|
||||
val convertedSet = stringSet.drop(1) // Remove the type identifier
|
||||
when (typeIdentifier) {
|
||||
"Int" -> convertedSet.mapNotNull { it.toIntOrNull() }.toSet()
|
||||
"Boolean" -> convertedSet.mapNotNull { it.toBooleanStrictOrNull() }.toSet()
|
||||
"Float" -> convertedSet.mapNotNull { it.toFloatOrNull() }.toSet()
|
||||
"Long" -> convertedSet.mapNotNull { it.toLongOrNull() }.toSet()
|
||||
"String" -> convertedSet.toSet()
|
||||
else -> stringSet
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
snackString("Error converting preference: ${e.message}")
|
||||
default as Set<*>
|
||||
}
|
||||
}
|
||||
|
||||
private fun SharedPreferences.Editor.convertAndPutStringSet(key: String, value: Set<*>) {
|
||||
val typeIdentifier = when (value.firstOrNull()) {
|
||||
is Int -> "Int"
|
||||
is Boolean -> "Boolean"
|
||||
is Float -> "Float"
|
||||
is Long -> "Long"
|
||||
is String -> "String"
|
||||
null -> return
|
||||
else -> throw IllegalArgumentException("Type not supported")
|
||||
}
|
||||
val stringSet = setOf(typeIdentifier) + value.map { it.toString() }
|
||||
putStringSet(key, stringSet)
|
||||
}
|
||||
|
||||
|
||||
private fun <T> serialzeClass(key: String, value: T){
|
||||
try {
|
||||
val bos = ByteArrayOutputStream()
|
||||
ObjectOutputStream(bos).use { oos ->
|
||||
oos.writeObject(value)
|
||||
}
|
||||
|
||||
val serialized = Base64.encodeToString(bos.toByteArray(), Base64.DEFAULT)
|
||||
irrelevantPreferences!!.edit().putString(key, serialized).apply()
|
||||
} catch (e: Exception) {
|
||||
snackString("Error serializing preference: ${e.message}")
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
private fun <T> deserialzeClass(key: String, default: T?): T? {
|
||||
return try {
|
||||
val serialized = irrelevantPreferences!!.getString(key, null)
|
||||
if (serialized != null) {
|
||||
val data = Base64.decode(serialized, Base64.DEFAULT)
|
||||
val bis = ByteArrayInputStream(data)
|
||||
val ois = ObjectInputStream(bis)
|
||||
val obj = ois.readObject() as T?
|
||||
obj
|
||||
} else {
|
||||
default
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
snackString("Error deserializing preference: ${e.message}")
|
||||
default
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,196 +0,0 @@
|
|||
package ani.dantotsu.settings.saving
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.content.SharedPreferences
|
||||
import ani.dantotsu.settings.saving.internal.Compat
|
||||
import ani.dantotsu.settings.saving.internal.Location
|
||||
import ani.dantotsu.snackString
|
||||
|
||||
object PrefWrapper {
|
||||
|
||||
private var generalPreferences: SharedPreferences? = null
|
||||
private var animePreferences: SharedPreferences? = null
|
||||
private var mangaPreferences: SharedPreferences? = null
|
||||
private var playerPreferences: SharedPreferences? = null
|
||||
private var readerPreferences: SharedPreferences? = null
|
||||
private var irrelevantPreferences: SharedPreferences? = null
|
||||
private var animeDownloadsPreferences: SharedPreferences? = null
|
||||
private var protectedPreferences: SharedPreferences? = null
|
||||
|
||||
fun init(context: Context) { //must be called in Application class or will crash
|
||||
generalPreferences = context.getSharedPreferences(Location.General.location, Context.MODE_PRIVATE)
|
||||
animePreferences = context.getSharedPreferences(Location.Anime.location, Context.MODE_PRIVATE)
|
||||
mangaPreferences = context.getSharedPreferences(Location.Manga.location, Context.MODE_PRIVATE)
|
||||
playerPreferences = context.getSharedPreferences(Location.Player.location, Context.MODE_PRIVATE)
|
||||
readerPreferences = context.getSharedPreferences(Location.Reader.location, Context.MODE_PRIVATE)
|
||||
irrelevantPreferences = context.getSharedPreferences(Location.Irrelevant.location, Context.MODE_PRIVATE)
|
||||
animeDownloadsPreferences = context.getSharedPreferences(Location.AnimeDownloads.location, Context.MODE_PRIVATE)
|
||||
protectedPreferences = context.getSharedPreferences(Location.Protected.location, Context.MODE_PRIVATE)
|
||||
Compat.importOldPrefs(context)
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
fun <T> setVal(prefName: PrefName, value: T) {
|
||||
val pref = getPrefLocation(prefName)
|
||||
with(pref.edit()) {
|
||||
when (prefName.data.type) {
|
||||
Boolean::class -> putBoolean(prefName.name, value as Boolean)
|
||||
Int::class -> putInt(prefName.name, value as Int)
|
||||
Float::class -> putFloat(prefName.name, value as Float)
|
||||
Long::class -> putLong(prefName.name, value as Long)
|
||||
String::class -> putString(prefName.name, value as String?)
|
||||
Set::class -> putStringSet(prefName.name, value as Set<String>)
|
||||
else -> throw IllegalArgumentException("Type not supported")
|
||||
}
|
||||
apply()
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
fun <T> getVal(prefName: PrefName, default: T) : T {
|
||||
return try {
|
||||
val pref = getPrefLocation(prefName)
|
||||
when (prefName.data.type) {
|
||||
Boolean::class -> pref.getBoolean(prefName.name, default as Boolean) as T
|
||||
Int::class -> pref.getInt(prefName.name, default as Int) as T
|
||||
Float::class -> pref.getFloat(prefName.name, default as Float) as T
|
||||
Long::class -> pref.getLong(prefName.name, default as Long) as T
|
||||
String::class -> pref.getString(prefName.name, default as String?) as T
|
||||
Set::class -> pref.getStringSet(prefName.name, default as Set<String>) as T
|
||||
else -> throw IllegalArgumentException("Type not supported")
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
snackString("Error getting preference: ${e.message}")
|
||||
default
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
fun <T> getLiveVal(prefName: PrefName, default: T) : SharedPreferenceLiveData<T> {
|
||||
val pref = getPrefLocation(prefName)
|
||||
return when (prefName.data.type) {
|
||||
Boolean::class -> SharedPreferenceBooleanLiveData(
|
||||
pref,
|
||||
prefName.name,
|
||||
default as Boolean
|
||||
) as SharedPreferenceLiveData<T>
|
||||
Int::class -> SharedPreferenceIntLiveData(
|
||||
pref,
|
||||
prefName.name,
|
||||
default as Int
|
||||
) as SharedPreferenceLiveData<T>
|
||||
Float::class -> SharedPreferenceFloatLiveData(
|
||||
pref,
|
||||
prefName.name,
|
||||
default as Float
|
||||
) as SharedPreferenceLiveData<T>
|
||||
Long::class -> SharedPreferenceLongLiveData(
|
||||
pref,
|
||||
prefName.name,
|
||||
default as Long
|
||||
) as SharedPreferenceLiveData<T>
|
||||
String::class -> SharedPreferenceStringLiveData(
|
||||
pref,
|
||||
prefName.name,
|
||||
default as String
|
||||
) as SharedPreferenceLiveData<T>
|
||||
Set::class -> SharedPreferenceStringSetLiveData(
|
||||
pref,
|
||||
prefName.name,
|
||||
default as Set<String>
|
||||
) as SharedPreferenceLiveData<T>
|
||||
else -> throw IllegalArgumentException("Type not supported")
|
||||
}
|
||||
}
|
||||
|
||||
fun removeVal(prefName: PrefName) {
|
||||
val pref = getPrefLocation(prefName)
|
||||
with(pref.edit()) {
|
||||
remove(prefName.name)
|
||||
apply()
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
fun <T> setCustomVal(key: String, value: T) {
|
||||
//for custom force irrelevant
|
||||
with(irrelevantPreferences!!.edit()) {
|
||||
when (value) {
|
||||
is Boolean -> putBoolean(key, value as Boolean)
|
||||
is Int -> putInt(key, value as Int)
|
||||
is Float -> putFloat(key, value as Float)
|
||||
is Long -> putLong(key, value as Long)
|
||||
is String -> putString(key, value as String)
|
||||
is Set<*> -> putStringSet(key, value as Set<String>)
|
||||
else -> throw IllegalArgumentException("Type not supported")
|
||||
}
|
||||
apply()
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
fun <T> getCustomVal(key: String, default: T): T {
|
||||
//for custom force irrelevant
|
||||
return try {
|
||||
when (default) {
|
||||
is Boolean -> irrelevantPreferences!!.getBoolean(key, default) as T
|
||||
is Int -> irrelevantPreferences!!.getInt(key, default) as T
|
||||
is Float -> irrelevantPreferences!!.getFloat(key, default) as T
|
||||
is Long -> irrelevantPreferences!!.getLong(key, default) as T
|
||||
is String -> irrelevantPreferences!!.getString(key, default) as T
|
||||
is Set<*> -> irrelevantPreferences!!.getStringSet(key, default as Set<String>) as T
|
||||
else -> throw IllegalArgumentException("Type not supported")
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
default
|
||||
}
|
||||
}
|
||||
|
||||
fun removeCustomVal(key: String) {
|
||||
//for custom force irrelevant
|
||||
with(irrelevantPreferences!!.edit()) {
|
||||
remove(key)
|
||||
apply()
|
||||
}
|
||||
}
|
||||
|
||||
fun SharedPreferenceLiveData<*>.asLiveBool(): SharedPreferenceBooleanLiveData =
|
||||
this as? SharedPreferenceBooleanLiveData
|
||||
?: throw ClassCastException("Cannot cast to SharedPreferenceLiveData<Boolean>")
|
||||
|
||||
fun SharedPreferenceLiveData<*>.asLiveInt(): SharedPreferenceIntLiveData =
|
||||
this as? SharedPreferenceIntLiveData
|
||||
?: throw ClassCastException("Cannot cast to SharedPreferenceLiveData<Int>")
|
||||
|
||||
fun SharedPreferenceLiveData<*>.asLiveFloat(): SharedPreferenceFloatLiveData =
|
||||
this as? SharedPreferenceFloatLiveData
|
||||
?: throw ClassCastException("Cannot cast to SharedPreferenceLiveData<Float>")
|
||||
|
||||
fun SharedPreferenceLiveData<*>.asLiveLong(): SharedPreferenceLongLiveData =
|
||||
this as? SharedPreferenceLongLiveData
|
||||
?: throw ClassCastException("Cannot cast to SharedPreferenceLiveData<Long>")
|
||||
|
||||
fun SharedPreferenceLiveData<*>.asLiveString(): SharedPreferenceStringLiveData =
|
||||
this as? SharedPreferenceStringLiveData
|
||||
?: throw ClassCastException("Cannot cast to SharedPreferenceLiveData<String>")
|
||||
|
||||
fun SharedPreferenceLiveData<*>.asLiveStringSet(): SharedPreferenceStringSetLiveData =
|
||||
this as? SharedPreferenceStringSetLiveData
|
||||
?: throw ClassCastException("Cannot cast to SharedPreferenceLiveData<Set<String>>")
|
||||
|
||||
fun getAnimeDownloadPreferences(): SharedPreferences = animeDownloadsPreferences!! //needs to be used externally
|
||||
|
||||
private fun getPrefLocation(prefName: PrefName): SharedPreferences {
|
||||
return when (prefName.data.prefLocation) {
|
||||
Location.General -> generalPreferences
|
||||
Location.Anime -> animePreferences
|
||||
Location.Manga -> mangaPreferences
|
||||
Location.Player -> playerPreferences
|
||||
Location.Reader -> readerPreferences
|
||||
Location.Irrelevant -> irrelevantPreferences
|
||||
Location.AnimeDownloads -> animeDownloadsPreferences
|
||||
Location.Protected -> protectedPreferences
|
||||
}!!
|
||||
}
|
||||
}
|
|
@ -1,56 +1,153 @@
|
|||
package ani.dantotsu.settings.saving
|
||||
|
||||
import android.graphics.Color
|
||||
import ani.dantotsu.connections.mal.MAL
|
||||
import ani.dantotsu.settings.saving.internal.Pref
|
||||
import ani.dantotsu.settings.saving.internal.Location
|
||||
|
||||
enum class PrefName(val data: Pref) {
|
||||
enum class PrefName(val data: Pref) { //TODO: Split this into multiple files
|
||||
//General
|
||||
SharedUserID(Pref(Location.General, Boolean::class)),
|
||||
OfflineView(Pref(Location.General, Int::class)),
|
||||
UseOLED(Pref(Location.General, Boolean::class)),
|
||||
UseCustomTheme(Pref(Location.General, Boolean::class)),
|
||||
CustomThemeInt(Pref(Location.General, Int::class)),
|
||||
UseSourceTheme(Pref(Location.General, Boolean::class)),
|
||||
UseMaterialYou(Pref(Location.General, Boolean::class)),
|
||||
Theme(Pref(Location.General, String::class)),
|
||||
DownloadManager(Pref(Location.General, Int::class)),
|
||||
NSFWExtension(Pref(Location.General, Boolean::class)),
|
||||
SkipExtensionIcons(Pref(Location.General, Boolean::class)),
|
||||
SdDl(Pref(Location.General, Boolean::class)),
|
||||
ContinueMedia(Pref(Location.General, Boolean::class)),
|
||||
RecentlyListOnly(Pref(Location.General, Boolean::class)),
|
||||
SettingsPreferDub(Pref(Location.General, Boolean::class)),
|
||||
SubscriptionsTimeS(Pref(Location.General, Int::class)),
|
||||
SubscriptionCheckingNotifications(Pref(Location.General, Boolean::class)),
|
||||
CheckUpdate(Pref(Location.General, Boolean::class)),
|
||||
SharedUserID(Pref(Location.General, Boolean::class, true)),
|
||||
OfflineView(Pref(Location.General, Int::class, 0)),
|
||||
DownloadManager(Pref(Location.General, Int::class, 0)),
|
||||
NSFWExtension(Pref(Location.General, Boolean::class, false)),
|
||||
SdDl(Pref(Location.General, Boolean::class, false)),
|
||||
ContinueMedia(Pref(Location.General, Boolean::class, true)),
|
||||
RecentlyListOnly(Pref(Location.General, Boolean::class, false)),
|
||||
SettingsPreferDub(Pref(Location.General, Boolean::class, false)),
|
||||
SubscriptionsTimeS(Pref(Location.General, Int::class, 0)),
|
||||
SubscriptionCheckingNotifications(Pref(Location.General, Boolean::class, true)),
|
||||
CheckUpdate(Pref(Location.General, Boolean::class, true)),
|
||||
VerboseLogging(Pref(Location.General, Boolean::class, false)),
|
||||
DohProvider(Pref(Location.General, Int::class, 0)),
|
||||
DefaultUserAgent(Pref(Location.General, String::class, "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:110.0) Gecko/20100101 Firefox/110.0")),
|
||||
|
||||
//User Interface
|
||||
UseOLED(Pref(Location.UI, Boolean::class, false)),
|
||||
UseCustomTheme(Pref(Location.UI, Boolean::class, false)),
|
||||
CustomThemeInt(Pref(Location.UI, Int::class, Color.parseColor("#6200EE"))),
|
||||
UseSourceTheme(Pref(Location.UI, Boolean::class, false)),
|
||||
UseMaterialYou(Pref(Location.UI, Boolean::class, false)),
|
||||
Theme(Pref(Location.UI, String::class, "PURPLE")),
|
||||
SkipExtensionIcons(Pref(Location.UI, Boolean::class, false)),
|
||||
DarkMode(Pref(Location.UI, Boolean::class, true)),
|
||||
ShowYtButton(Pref(Location.UI, Boolean::class, true)),
|
||||
AnimeDefaultView(Pref(Location.UI, Int::class, 0)),
|
||||
MangaDefaultView(Pref(Location.UI, Int::class, 0)),
|
||||
ImmersiveMode(Pref(Location.UI, Boolean::class, false)),
|
||||
SmallView(Pref(Location.UI, Boolean::class, true)),
|
||||
DefaultStartUpTab(Pref(Location.UI, Int::class, 1)),
|
||||
HomeLayoutShow(Pref(Location.UI, List::class, listOf(true, false, false, true, false, false, true))),
|
||||
BannerAnimations(Pref(Location.UI, Boolean::class, true)),
|
||||
LayoutAnimations(Pref(Location.UI, Boolean::class, true)),
|
||||
AnimationSpeed(Pref(Location.UI, Float::class, 1f)),
|
||||
ListGrid(Pref(Location.UI, Boolean::class, true)),
|
||||
|
||||
//Anime
|
||||
AnimeListSortOrder(Pref(Location.Anime, String::class)),
|
||||
PinnedAnimeSources(Pref(Location.Anime, Set::class)),
|
||||
PopularAnimeList(Pref(Location.Anime, Boolean::class)),
|
||||
AnimeSearchHistory(Pref(Location.Anime, Set::class)),
|
||||
AnimeListSortOrder(Pref(Location.Anime, String::class, "score")),
|
||||
PinnedAnimeSources(Pref(Location.Anime, Set::class, setOf<String>())),
|
||||
PopularAnimeList(Pref(Location.Anime, Boolean::class, true)),
|
||||
AnimeSearchHistory(Pref(Location.Anime, Set::class, setOf<String>())),
|
||||
|
||||
//Manga
|
||||
MangaListSortOrder(Pref(Location.Manga, String::class)),
|
||||
PinnedMangaSources(Pref(Location.Manga, Set::class)),
|
||||
PopularMangaList(Pref(Location.Manga, Boolean::class)),
|
||||
MangaSearchHistory(Pref(Location.Manga, Set::class)),
|
||||
MangaListSortOrder(Pref(Location.Manga, String::class, "score")),
|
||||
PinnedMangaSources(Pref(Location.Manga, Set::class, setOf<String>())),
|
||||
PopularMangaList(Pref(Location.Manga, Boolean::class, true)),
|
||||
MangaSearchHistory(Pref(Location.Manga, Set::class, setOf<String>())),
|
||||
|
||||
//Player
|
||||
DefaultSpeed(Pref(Location.Player, Int::class, 5)),
|
||||
CursedSpeeds(Pref(Location.Player, Boolean::class, false)),
|
||||
Resize(Pref(Location.Player, Int::class, 0)),
|
||||
Subtitles(Pref(Location.Player, Boolean::class, true)),
|
||||
PrimaryColor(Pref(Location.Player, Int::class, 4)),
|
||||
SecondaryColor(Pref(Location.Player, Int::class, 0)),
|
||||
Outline(Pref(Location.Player, Int::class, 0)),
|
||||
SubBackground(Pref(Location.Player, Int::class, 0)),
|
||||
SubWindow(Pref(Location.Player, Int::class, 0)),
|
||||
Font(Pref(Location.Player, Int::class, 0)),
|
||||
FontSize(Pref(Location.Player, Int::class, 20)),
|
||||
Locale(Pref(Location.Player, Int::class, 2)),
|
||||
TimeStampsEnabled(Pref(Location.Player, Boolean::class, true)),
|
||||
UseProxyForTimeStamps(Pref(Location.Player, Boolean::class, false)),
|
||||
ShowTimeStampButton(Pref(Location.Player, Boolean::class, true)),
|
||||
AutoSkipOPED(Pref(Location.Player, Boolean::class, false)),
|
||||
AutoPlay(Pref(Location.Player, Boolean::class, true)),
|
||||
AutoSkipFiller(Pref(Location.Player, Boolean::class, false)),
|
||||
AskIndividualPlayer(Pref(Location.Player, Boolean::class, true)),
|
||||
UpdateForHPlayer(Pref(Location.Player, Boolean::class, false)),
|
||||
WatchPercentage(Pref(Location.Player, Float::class, 0.8f)),
|
||||
AlwaysContinue(Pref(Location.Player, Boolean::class, true)),
|
||||
FocusPause(Pref(Location.Player, Boolean::class, true)),
|
||||
Gestures(Pref(Location.Player, Boolean::class, true)),
|
||||
DoubleTap(Pref(Location.Player, Boolean::class, true)),
|
||||
FastForward(Pref(Location.Player, Boolean::class, true)),
|
||||
SeekTime(Pref(Location.Player, Int::class, 10)),
|
||||
SkipTime(Pref(Location.Player, Int::class, 85)),
|
||||
Cast(Pref(Location.Player, Boolean::class, true)),
|
||||
Pip(Pref(Location.Player, Boolean::class, true)),
|
||||
ContinueAnime(Pref(Location.Player, Set::class, setOf<Int>())),
|
||||
|
||||
//Reader
|
||||
ShowSource(Pref(Location.Reader, Boolean::class, true)),
|
||||
ShowSystemBars(Pref(Location.Reader, Boolean::class, false)),
|
||||
AutoDetectWebtoon(Pref(Location.Reader, Boolean::class, true)),
|
||||
AskIndividualReader(Pref(Location.Reader, Boolean::class, true)),
|
||||
UpdateForHReader(Pref(Location.Reader, Boolean::class, false)),
|
||||
Direction(Pref(Location.Reader, Int::class, 0)),
|
||||
LayoutReader(Pref(Location.Reader, Int::class, 2)),
|
||||
DualPageModeReader(Pref(Location.Reader, Int::class, 1)),
|
||||
OverScrollMode(Pref(Location.Reader, Boolean::class, true)),
|
||||
TrueColors(Pref(Location.Reader, Boolean::class, false)),
|
||||
Rotation(Pref(Location.Reader, Boolean::class, true)),
|
||||
Padding(Pref(Location.Reader, Boolean::class, true)),
|
||||
HidePageNumbers(Pref(Location.Reader, Boolean::class, false)),
|
||||
HorizontalScrollBar(Pref(Location.Reader, Boolean::class, true)),
|
||||
KeepScreenOn(Pref(Location.Reader, Boolean::class, false)),
|
||||
VolumeButtonsReader(Pref(Location.Reader, Boolean::class, false)),
|
||||
WrapImages(Pref(Location.Reader, Boolean::class, false)),
|
||||
LongClickImage(Pref(Location.Reader, Boolean::class, true)),
|
||||
CropBorders(Pref(Location.Reader, Boolean::class, false)),
|
||||
CropBorderThreshold(Pref(Location.Reader, Int::class, 10)),
|
||||
|
||||
//Novel Reader
|
||||
CurrentThemeName(Pref(Location.NovelReader, String::class, "Default")),
|
||||
LayoutNovel(Pref(Location.NovelReader, Int::class, 0)),
|
||||
DualPageModeNovel(Pref(Location.NovelReader, Int::class, 1)),
|
||||
LineHeight(Pref(Location.NovelReader, Float::class, 1.4f)),
|
||||
Margin(Pref(Location.NovelReader, Float::class, 0.06f)),
|
||||
Justify(Pref(Location.NovelReader, Boolean::class, true)),
|
||||
Hyphenation(Pref(Location.NovelReader, Boolean::class, true)),
|
||||
UseDarkThemeNovel(Pref(Location.NovelReader, Boolean::class, false)),
|
||||
UseOledThemeNovel(Pref(Location.NovelReader, Boolean::class, false)),
|
||||
Invert(Pref(Location.NovelReader, Boolean::class, false)),
|
||||
MaxInlineSize(Pref(Location.NovelReader, Int::class, 720)),
|
||||
MaxBlockSize(Pref(Location.NovelReader, Int::class, 1440)),
|
||||
HorizontalScrollBarNovel(Pref(Location.NovelReader, Boolean::class, true)),
|
||||
KeepScreenOnNovel(Pref(Location.NovelReader, Boolean::class, false)),
|
||||
VolumeButtonsNovel(Pref(Location.NovelReader, Boolean::class, false)),
|
||||
|
||||
//Irrelevant
|
||||
Incognito(Pref(Location.Irrelevant, Boolean::class)),
|
||||
OfflineMode(Pref(Location.Irrelevant, Boolean::class)),
|
||||
DownloadsKeys(Pref(Location.Irrelevant, String::class)),
|
||||
NovelLastExtCheck(Pref(Location.Irrelevant, Long::class)),
|
||||
SomethingSpecial(Pref(Location.Irrelevant, Boolean::class)),
|
||||
AllowOpeningLinks(Pref(Location.Irrelevant, Boolean::class)),
|
||||
SearchStyle(Pref(Location.Irrelevant, Int::class)),
|
||||
HasUpdatedPrefs(Pref(Location.Irrelevant, Boolean::class)),
|
||||
LangSort(Pref(Location.Irrelevant, String::class)),
|
||||
Incognito(Pref(Location.Irrelevant, Boolean::class, false)),
|
||||
OfflineMode(Pref(Location.Irrelevant, Boolean::class, false)),
|
||||
DownloadsKeys(Pref(Location.Irrelevant, String::class, "")),
|
||||
NovelLastExtCheck(Pref(Location.Irrelevant, Long::class, 0L)),
|
||||
SomethingSpecial(Pref(Location.Irrelevant, Boolean::class, false)),
|
||||
AllowOpeningLinks(Pref(Location.Irrelevant, Boolean::class, false)),
|
||||
SearchStyle(Pref(Location.Irrelevant, Int::class, 0)),
|
||||
HasUpdatedPrefs(Pref(Location.Irrelevant, Boolean::class, false)),
|
||||
LangSort(Pref(Location.Irrelevant, String::class, "all")),
|
||||
GenresList(Pref(Location.Irrelevant, Set::class, setOf<String>())),
|
||||
TagsListIsAdult(Pref(Location.Irrelevant, Set::class, setOf<String>())),
|
||||
TagsListNonAdult(Pref(Location.Irrelevant, Set::class, setOf<String>())),
|
||||
MakeDefault(Pref(Location.Irrelevant, Boolean::class, true)),
|
||||
|
||||
//Protected
|
||||
DiscordToken(Pref(Location.Protected, String::class)),
|
||||
DiscordId(Pref(Location.Protected, String::class)),
|
||||
DiscordUserName(Pref(Location.Protected, String::class)),
|
||||
DiscordAvatar(Pref(Location.Protected, String::class)),
|
||||
AnilistUserName(Pref(Location.Protected, String::class)),
|
||||
DiscordToken(Pref(Location.Protected, String::class, "")),
|
||||
DiscordId(Pref(Location.Protected, String::class, "")),
|
||||
DiscordUserName(Pref(Location.Protected, String::class, "")),
|
||||
DiscordAvatar(Pref(Location.Protected, String::class, "")),
|
||||
AnilistUserName(Pref(Location.Protected, String::class, "")),
|
||||
MALCodeChallenge(Pref(Location.Protected, String::class, "")),
|
||||
MALToken(Pref(Location.Protected, MAL.ResponseToken::class, "")),
|
||||
}
|
|
@ -2,17 +2,17 @@ package ani.dantotsu.settings.saving.internal
|
|||
|
||||
import android.content.Context
|
||||
import ani.dantotsu.settings.saving.PrefName
|
||||
import ani.dantotsu.settings.saving.PrefWrapper
|
||||
import ani.dantotsu.settings.saving.PrefManager
|
||||
|
||||
class Compat {
|
||||
companion object {
|
||||
fun importOldPrefs(context: Context) {
|
||||
if (PrefWrapper.getVal(PrefName.HasUpdatedPrefs, false)) return
|
||||
if (PrefManager.getVal(PrefName.HasUpdatedPrefs)) return
|
||||
val oldPrefs = context.getSharedPreferences("downloads_pref", Context.MODE_PRIVATE)
|
||||
val jsonString = oldPrefs.getString("downloads_key", null)
|
||||
PrefWrapper.setVal(PrefName.DownloadsKeys, jsonString)
|
||||
PrefManager.setVal(PrefName.DownloadsKeys, jsonString)
|
||||
oldPrefs.edit().clear().apply()
|
||||
PrefWrapper.setVal(PrefName.HasUpdatedPrefs, true)
|
||||
PrefManager.setVal(PrefName.HasUpdatedPrefs, true)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -5,14 +5,17 @@ import kotlin.reflect.KClass
|
|||
|
||||
data class Pref(
|
||||
val prefLocation: Location,
|
||||
val type: KClass<*>
|
||||
val type: KClass<*>,
|
||||
val default: Any
|
||||
)
|
||||
enum class Location(val location: String) {
|
||||
General("ani.dantotsu.general"),
|
||||
UI("ani.dantotsu.ui"),
|
||||
Anime("ani.dantotsu.anime"),
|
||||
Manga("ani.dantotsu.manga"),
|
||||
Player("ani.dantotsu.player"),
|
||||
Reader("ani.dantotsu.reader"),
|
||||
NovelReader("ani.dantotsu.novelReader"),
|
||||
Irrelevant("ani.dantotsu.irrelevant"),
|
||||
AnimeDownloads("animeDownloads"), //different for legacy reasons
|
||||
Protected("ani.dantotsu.protected")
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue