Skip to content

Instantly share code, notes, and snippets.

@samuel22gj
Created October 18, 2019 10:54
Show Gist options
  • Save samuel22gj/164b23feeecdd476f1988cf66913ba2c to your computer and use it in GitHub Desktop.
Save samuel22gj/164b23feeecdd476f1988cf66913ba2c to your computer and use it in GitHub Desktop.
sealed class SharedPreferenceDelegates<in R, T> : ReadWriteProperty<R, T> {
class BooleanType(
private val sharedPreferences: SharedPreferences,
private val key: String,
private val defaultValue: Boolean = false
) : SharedPreferenceDelegates<Any?, Boolean>() {
override fun getValue(thisRef: Any?, property: KProperty<*>): Boolean {
return sharedPreferences.getBoolean(key, defaultValue)
}
override fun setValue(thisRef: Any?, property: KProperty<*>, value: Boolean) {
sharedPreferences.edit()
.putBoolean(key, value)
.apply()
}
}
class NullableBooleanType(
private val sharedPreferences: SharedPreferences,
private val key: String
) : SharedPreferenceDelegates<Any?, Boolean?>() {
override fun getValue(thisRef: Any?, property: KProperty<*>): Boolean? {
return if (sharedPreferences.contains(key)) {
sharedPreferences.getBoolean(key, false)
} else {
null
}
}
override fun setValue(thisRef: Any?, property: KProperty<*>, value: Boolean?) {
if (value != null) {
sharedPreferences.edit()
.putBoolean(key, value)
.apply()
} else {
sharedPreferences.edit()
.remove(key)
.apply()
}
}
}
class FloatType(
private val sharedPreferences: SharedPreferences,
private val key: String,
private val defaultValue: Float = 0.0f
) : SharedPreferenceDelegates<Any?, Float>() {
override fun getValue(thisRef: Any?, property: KProperty<*>): Float {
return sharedPreferences.getFloat(key, defaultValue)
}
override fun setValue(thisRef: Any?, property: KProperty<*>, value: Float) {
sharedPreferences.edit()
.putFloat(key, value)
.apply()
}
}
class NullableFloatType(
private val sharedPreferences: SharedPreferences,
private val key: String
) : SharedPreferenceDelegates<Any?, Float?>() {
override fun getValue(thisRef: Any?, property: KProperty<*>): Float? {
return if (sharedPreferences.contains(key)) {
sharedPreferences.getFloat(key, 0.0f)
} else {
null
}
}
override fun setValue(thisRef: Any?, property: KProperty<*>, value: Float?) {
if (value != null) {
sharedPreferences.edit()
.putFloat(key, value)
.apply()
} else {
sharedPreferences.edit()
.remove(key)
.apply()
}
}
}
class IntType(
private val sharedPreferences: SharedPreferences,
private val key: String,
private val defaultValue: Int = 0
) : SharedPreferenceDelegates<Any?, Int>() {
override fun getValue(thisRef: Any?, property: KProperty<*>): Int {
return sharedPreferences.getInt(key, defaultValue)
}
override fun setValue(thisRef: Any?, property: KProperty<*>, value: Int) {
sharedPreferences.edit()
.putInt(key, value)
.apply()
}
}
class NullableIntType(
private val sharedPreferences: SharedPreferences,
private val key: String
) : SharedPreferenceDelegates<Any?, Int?>() {
override fun getValue(thisRef: Any?, property: KProperty<*>): Int? {
return if (sharedPreferences.contains(key)) {
sharedPreferences.getInt(key, 0)
} else {
null
}
}
override fun setValue(thisRef: Any?, property: KProperty<*>, value: Int?) {
if (value != null) {
sharedPreferences.edit()
.putInt(key, value)
.apply()
} else {
sharedPreferences.edit()
.remove(key)
.apply()
}
}
}
class LongType(
private val sharedPreferences: SharedPreferences,
private val key: String,
private val defaultValue: Long = 0L
) : SharedPreferenceDelegates<Any?, Long>() {
override fun getValue(thisRef: Any?, property: KProperty<*>): Long {
return sharedPreferences.getLong(key, defaultValue)
}
override fun setValue(thisRef: Any?, property: KProperty<*>, value: Long) {
sharedPreferences.edit()
.putLong(key, value)
.apply()
}
}
class NullableLongType(
private val sharedPreferences: SharedPreferences,
private val key: String
) : SharedPreferenceDelegates<Any?, Long?>() {
override fun getValue(thisRef: Any?, property: KProperty<*>): Long? {
return if (sharedPreferences.contains(key)) {
sharedPreferences.getLong(key, 0L)
} else {
null
}
}
override fun setValue(thisRef: Any?, property: KProperty<*>, value: Long?) {
if (value != null) {
sharedPreferences.edit()
.putLong(key, value)
.apply()
} else {
sharedPreferences.edit()
.remove(key)
.apply()
}
}
}
class StringType(
private val sharedPreferences: SharedPreferences,
private val key: String,
private val defaultValue: String? = null
) : SharedPreferenceDelegates<Any?, String?>() {
override fun getValue(thisRef: Any?, property: KProperty<*>): String? {
return sharedPreferences.getString(key, defaultValue)
}
override fun setValue(thisRef: Any?, property: KProperty<*>, value: String?) {
sharedPreferences.edit()
.putString(key, value)
.apply()
}
}
class StringSetType(
private val sharedPreferences: SharedPreferences,
private val key: String,
private val defaultValue: Set<String>? = null
) : SharedPreferenceDelegates<Any?, Set<String>?>() {
override fun getValue(thisRef: Any?, property: KProperty<*>): Set<String>? {
return sharedPreferences.getStringSet(key, defaultValue)
}
override fun setValue(thisRef: Any?, property: KProperty<*>, value: Set<String>?) {
sharedPreferences.edit()
.putStringSet(key, value)
.apply()
}
}
sealed class ListType<T>(
private val sharedPreferences: SharedPreferences,
private val key: String,
private val defaultValue: List<T>? = null,
private val separator: String = ",",
private val stringToObject: (String) -> T,
private val objectToString: (T) -> String
) : SharedPreferenceDelegates<Any?, List<T>?>() {
override fun getValue(thisRef: Any?, property: KProperty<*>): List<T>? {
val value = sharedPreferences.getString(key, null)
?.split(separator)
?.map(stringToObject)
return value ?: defaultValue
}
override fun setValue(thisRef: Any?, property: KProperty<*>, value: List<T>?) {
sharedPreferences.edit()
.putString(key, value?.map(objectToString)?.join(separator))
.apply()
}
class IntType(
sharedPreferences: SharedPreferences,
key: String,
defaultValue: List<Int>? = null,
separator: String = ","
) : ListType<Int>(
sharedPreferences,
key,
defaultValue,
separator,
{ it.toInt() },
{ it.toString() }
)
class StringType(
sharedPreferences: SharedPreferences,
key: String,
defaultValue: List<String>? = null,
separator: String = ","
) : ListType<String>(
sharedPreferences,
key,
defaultValue,
separator,
{ it },
{ it }
)
}
sealed class Cacheable<T>(
private val sharedPreferences: SharedPreferences,
private val key: String,
private val defaultValue: T,
private val expirePeriod: Long // millisecond
) : SharedPreferenceDelegates<Any?, T>() {
private var cacheTimestamp by LongType(
sharedPreferences,
key + "_timestamp",
0L
)
override fun getValue(thisRef: Any?, property: KProperty<*>): T {
return if (isExpired(cacheTimestamp, expirePeriod)) {
defaultValue
} else {
getValueInternal(sharedPreferences, key, defaultValue)
}
}
override fun setValue(thisRef: Any?, property: KProperty<*>, value: T) {
cacheTimestamp = Calendar.getInstance().timeInMillis
setValueInternal(sharedPreferences, key, value)
}
private fun isExpired(lastTime: Long, expirePeriod: Long): Boolean {
val now = Calendar.getInstance().timeInMillis
return lastTime == 0L || now - lastTime > expirePeriod
}
abstract fun getValueInternal(sharedPreferences: SharedPreferences, key: String, defaultValue: T): T
abstract fun setValueInternal(sharedPreferences: SharedPreferences, key: String, newValue: T)
class StringType(
sharedPreferences: SharedPreferences,
key: String,
defaultValue: String? = null,
expirePeriod: Long
) : Cacheable<String?>(
sharedPreferences,
key,
defaultValue,
expirePeriod
) {
override fun getValueInternal(
sharedPreferences: SharedPreferences,
key: String,
defaultValue: String?
): String? {
return sharedPreferences.getString(key, defaultValue)
}
override fun setValueInternal(
sharedPreferences: SharedPreferences,
key: String,
newValue: String?
) {
sharedPreferences.edit().putString(key, newValue).apply()
}
}
}
sealed class OtherType<T>(
private val sharedPreferences: SharedPreferences,
private val key: String,
private val defaultValue: T? = null,
private val stringToObject: (String) -> T,
private val objectToString: (T) -> String
) : SharedPreferenceDelegates<Any?, T?>() {
override fun getValue(thisRef: Any?, property: KProperty<*>): T? {
val value = sharedPreferences.getString(key, null)?.run(stringToObject)
return value ?: defaultValue
}
override fun setValue(thisRef: Any?, property: KProperty<*>, value: T?) {
sharedPreferences.edit()
.putString(key, value?.run(objectToString))
.apply()
}
class SnapupSellingReminderSubscriptionType(
sharedPreferences: SharedPreferences,
key: String,
defaultValue: SnapupSellingReminderSubscription? = null
) : OtherType<SnapupSellingReminderSubscription>(
sharedPreferences,
key,
defaultValue,
{ SnapupSellingReminderSubscription.parse(it) },
{ it.toString() }
)
}
}
sealed class SharedPreferenceDynamicKey(
private val sharedPreferences: SharedPreferences,
private val keyPrefix: String
) {
fun removeAll(keySuffix: String) {
sharedPreferences.edit()
.remove(keyPrefix + keySuffix)
.apply()
}
fun clear() {
sharedPreferences.edit()?.let {
for ((key, _) in sharedPreferences.all) {
if (key.startsWith(keyPrefix)) {
it.remove(key)
}
it.apply()
}
}
}
class BooleanType(
private val sharedPreferences: SharedPreferences,
private val keyPrefix: String,
private val defaultValue: Boolean = false
) : SharedPreferenceDynamicKey(
sharedPreferences,
keyPrefix
) {
fun get(keySuffix: String, defaultValue: Boolean = this.defaultValue): Boolean {
return sharedPreferences.getBoolean(keyPrefix + keySuffix, defaultValue)
}
fun set(keySuffix: String, value: Boolean) {
sharedPreferences.edit()
.putBoolean(keyPrefix + keySuffix, value)
.apply()
}
}
class NullableBooleanType(
private val sharedPreferences: SharedPreferences,
private val keyPrefix: String
) : SharedPreferenceDynamicKey(
sharedPreferences,
keyPrefix
) {
fun get(keySuffix: String): Boolean? {
return if (sharedPreferences.contains(keyPrefix + keySuffix)) {
sharedPreferences.getBoolean(keyPrefix + keySuffix, false)
} else {
null
}
}
fun set(keySuffix: String, value: Boolean?) {
if (value != null) {
sharedPreferences.edit()
.putBoolean(keyPrefix + keySuffix, value)
.apply()
} else {
sharedPreferences.edit()
.remove(keyPrefix + keySuffix)
.apply()
}
}
}
class FloatType(
private val sharedPreferences: SharedPreferences,
private val keyPrefix: String,
private val defaultValue: Float = 0.0f
) : SharedPreferenceDynamicKey(
sharedPreferences,
keyPrefix
) {
fun get(keySuffix: String, defaultValue: Float = this.defaultValue): Float {
return sharedPreferences.getFloat(keyPrefix + keySuffix, defaultValue)
}
fun set(keySuffix: String, value: Float) {
sharedPreferences.edit()
.putFloat(keyPrefix + keySuffix, value)
.apply()
}
}
class NullableFloatType(
private val sharedPreferences: SharedPreferences,
private val keyPrefix: String
) : SharedPreferenceDynamicKey(
sharedPreferences,
keyPrefix
) {
fun get(keySuffix: String): Float? {
return if (sharedPreferences.contains(keyPrefix + keySuffix)) {
sharedPreferences.getFloat(keyPrefix + keySuffix, 0.0f)
} else {
null
}
}
fun set(keySuffix: String, value: Float?) {
if (value != null) {
sharedPreferences.edit()
.putFloat(keyPrefix + keySuffix, value)
.apply()
} else {
sharedPreferences.edit()
.remove(keyPrefix + keySuffix)
.apply()
}
}
}
class IntType(
private val sharedPreferences: SharedPreferences,
private val keyPrefix: String,
private val defaultValue: Int = 0
) : SharedPreferenceDynamicKey(
sharedPreferences,
keyPrefix
) {
fun get(keySuffix: String, defaultValue: Int = this.defaultValue): Int {
return sharedPreferences.getInt(keyPrefix + keySuffix, defaultValue)
}
fun set(keySuffix: String, value: Int) {
sharedPreferences.edit()
.putInt(keyPrefix + keySuffix, value)
.apply()
}
}
class NullableIntType(
private val sharedPreferences: SharedPreferences,
private val keyPrefix: String
) : SharedPreferenceDynamicKey(
sharedPreferences,
keyPrefix
) {
fun get(keySuffix: String): Int? {
return if (sharedPreferences.contains(keyPrefix + keySuffix)) {
sharedPreferences.getInt(keyPrefix + keySuffix, 0)
} else {
null
}
}
fun set(keySuffix: String, value: Int?) {
if (value != null) {
sharedPreferences.edit()
.putInt(keyPrefix + keySuffix, value)
.apply()
} else {
sharedPreferences.edit()
.remove(keyPrefix + keySuffix)
.apply()
}
}
}
class LongType(
private val sharedPreferences: SharedPreferences,
private val keyPrefix: String,
private val defaultValue: Long = 0L
) : SharedPreferenceDynamicKey(
sharedPreferences,
keyPrefix
) {
fun get(keySuffix: String, defaultValue: Long = this.defaultValue): Long {
return sharedPreferences.getLong(keyPrefix + keySuffix, defaultValue)
}
fun set(keySuffix: String, value: Long) {
sharedPreferences.edit()
.putLong(keyPrefix + keySuffix, value)
.apply()
}
}
class NullableLongType(
private val sharedPreferences: SharedPreferences,
private val keyPrefix: String
) : SharedPreferenceDynamicKey(
sharedPreferences,
keyPrefix
) {
fun get(keySuffix: String): Long? {
return if (sharedPreferences.contains(keyPrefix + keySuffix)) {
sharedPreferences.getLong(keyPrefix + keySuffix, 0L)
} else {
null
}
}
fun set(keySuffix: String, value: Long?) {
if (value != null) {
sharedPreferences.edit()
.putLong(keyPrefix + keySuffix, value)
.apply()
} else {
sharedPreferences.edit()
.remove(keyPrefix + keySuffix)
.apply()
}
}
}
class StringType(
private val sharedPreferences: SharedPreferences,
private val keyPrefix: String,
private val defaultValue: String? = null
) : SharedPreferenceDynamicKey(
sharedPreferences,
keyPrefix
) {
fun get(keySuffix: String, defaultValue: String? = this.defaultValue): String? {
return sharedPreferences.getString(keyPrefix + keySuffix, defaultValue)
}
fun set(keySuffix: String, value: String?) {
sharedPreferences.edit()
.putString(keyPrefix + keySuffix, value)
.apply()
}
}
class StringSetType(
private val sharedPreferences: SharedPreferences,
private val keyPrefix: String,
private val defaultValue: Set<String>? = null
) : SharedPreferenceDynamicKey(
sharedPreferences,
keyPrefix
) {
fun get(keySuffix: String, defaultValue: Set<String>? = this.defaultValue): Set<String>? {
return sharedPreferences.getStringSet(keyPrefix + keySuffix, defaultValue)
}
fun set(keySuffix: String, value: Set<String>?) {
sharedPreferences.edit()
.putStringSet(keyPrefix + keySuffix, value)
.apply()
}
}
sealed class ListType<T>(
private val sharedPreferences: SharedPreferences,
private val keyPrefix: String,
private val defaultValue: List<T>? = null,
private val separator: String = ",",
private val maxCount: Int = Int.MAX_VALUE,
private val stringToObject: (String) -> T,
private val objectToString: (T) -> String
) : SharedPreferenceDynamicKey(
sharedPreferences,
keyPrefix
) {
private fun getListOrNull(keySuffix: String): List<T>? {
return sharedPreferences.getString(keyPrefix + keySuffix, null)
?.split(separator)
?.map(stringToObject)
}
fun get(keySuffix: String, defaultValue: List<T>? = this.defaultValue): List<T>? {
return getListOrNull(keySuffix) ?: defaultValue
}
fun add(keySuffix: String, value: T) {
val list = getListOrNull(keySuffix)?.toMutableList() ?: mutableListOf()
list.apply {
remove(value)
add(0, value)
set(keySuffix, take(maxCount))
}
}
fun remove(keySuffix: String, value: T) {
val list = getListOrNull(keySuffix)?.toMutableList() ?: mutableListOf()
list.apply {
if (contains(value)) {
remove(value)
set(keySuffix, this)
}
}
}
fun set(keySuffix: String, valueList: List<T>) {
sharedPreferences.edit()
.putString(keyPrefix + keySuffix, valueList.map(objectToString).join(separator))
.apply()
}
class IntType(
sharedPreferences: SharedPreferences,
keyPrefix: String,
defaultValue: List<Int>? = null,
separator: String = ",",
maxCount: Int = Int.MAX_VALUE
) : ListType<Int>(
sharedPreferences,
keyPrefix,
defaultValue,
separator,
maxCount,
{ it.toInt() },
{ it.toString() }
)
class StringType(
sharedPreferences: SharedPreferences,
keyPrefix: String,
defaultValue: List<String>? = null,
separator: String = ",",
maxCount: Int = Int.MAX_VALUE
) : ListType<String>(
sharedPreferences,
keyPrefix,
defaultValue,
separator,
maxCount,
{ it },
{ it }
)
}
sealed class OtherType<T>(
private val sharedPreferences: SharedPreferences,
private val keyPrefix: String,
private val defaultValue: T? = null,
private val stringToObject: (String) -> T,
private val objectToString: (T) -> String
) : SharedPreferenceDynamicKey(
sharedPreferences,
keyPrefix
) {
fun get(keySuffix: String): T? {
val value = sharedPreferences.getString(keyPrefix + keySuffix, null)?.run(stringToObject)
return value ?: defaultValue
}
fun set(keySuffix: String, value: T?) {
sharedPreferences.edit()
.putString(keyPrefix + keySuffix, value?.run(objectToString))
.apply()
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment