11package de.binarynoise.captiveportalautologin.preferences
22
3+ import kotlin.properties.ReadWriteProperty
34import kotlin.reflect.KProperty
45import androidx.core.content.edit
56import androidx.preference.Preference
67import androidx.preference.PreferenceManager
78import de.binarynoise.captiveportalautologin.util.applicationContext
89import de.binarynoise.liberator.PortalDetection
10+ import de.binarynoise.liberator.PortalTestURL
911
1012object SharedPreferences {
11- val liberator_automatically_liberate by PreferenceProperty (true )
12- val liberator_captive_test_url by PreferenceProperty (PortalDetection .defaultBackend)
13- val liberator_user_agent by PreferenceProperty (PortalDetection .defaultUserAgent)
14- val liberator_send_stats by PreferenceProperty (true )
15- val api_base by PreferenceProperty (" " )
13+ val liberator_automatically_liberate: PreferencePropertyDelegate <Boolean > by PreferenceProperty (true )
14+ val liberator_captive_test_url: DynamicPreferencePropertyDelegate <String , PortalTestURL > by DynamicPreferenceProperty (
15+ { key -> PortalDetection .backends.getValue(key) },
16+ { value -> PortalDetection .backends.entries.single { it.value == value }.key },
17+ PortalDetection .defaultBackendKey,
18+ )
19+ val liberator_user_agent: PreferencePropertyDelegate <String > by PreferenceProperty (PortalDetection .defaultUserAgent)
20+ val liberator_send_stats: PreferencePropertyDelegate <Boolean > by PreferenceProperty (true )
21+ val api_base: PreferencePropertyDelegate <String > by PreferenceProperty (" " )
1622
1723 val stats_last_retry_time by PreferenceProperty (0L )
1824
19- private class PreferenceProperty <T >(private val defaultValue : T ) {
25+ private class PreferenceProperty <T : Any >(private val defaultValue : T ) {
2026 operator fun getValue (parent : Any , property : KProperty <* >): PreferencePropertyDelegate <T > {
2127 return PreferencePropertyDelegate (property, defaultValue)
2228 }
2329 }
30+
31+ private class DynamicPreferenceProperty <K : Any , V >(
32+ private val getValue : (K ) -> V ,
33+ private val getKey : (V ) -> K ,
34+ private val defaultKey : K ,
35+ ) {
36+ operator fun getValue (parent : Any , property : KProperty <* >): DynamicPreferencePropertyDelegate <K , V > {
37+ return DynamicPreferencePropertyDelegate (property, getValue, getKey, defaultKey)
38+ }
39+ }
2440}
2541
2642
27- class PreferencePropertyDelegate <T >(val parent : KProperty <* >, val defaultValue : T ) : (Preference ) -> Unit {
43+ open class PreferencePropertyDelegate <T : Any >(val parent : KProperty <* >, val defaultValue : T ) :
44+ ReadWriteProperty <Any ?, T ?>, (Preference ) -> Unit {
2845 val key = parent.name
2946
47+ init {
48+ require(defaultValue is Int || defaultValue is String || defaultValue is Boolean || defaultValue is Float || defaultValue is Long ) {
49+ " Unsupported type: ${defaultValue::class } "
50+ }
51+ }
52+
3053 override fun invoke (preference : Preference ) {
3154 preference.setDefaultValue(defaultValue)
3255 preference.key = key
3356 }
3457
3558 @Suppress(" UNCHECKED_CAST" )
36- operator fun getValue (parent : Any? , property : KProperty <* >? ): T {
59+ @JvmName(" getValueNullable" )
60+ operator fun getValue (thisRef : Any? , property : KProperty <* >? ): T {
3761 with (PreferenceManager .getDefaultSharedPreferences(applicationContext)) {
3862 return if (contains(key)) all[key] as T
3963 else defaultValue
4064 }
4165 }
4266
43- operator fun setValue (parent : Any? , property : KProperty <* >? , newValue : T ) {
67+ override operator fun getValue (thisRef : Any? , property : KProperty <* >): T {
68+ return getValue(thisRef, null )
69+ }
70+
71+ @JvmName(" setValueNullable" )
72+ operator fun setValue (thisRef : Any? , property : KProperty <* >? , newValue : T ? ) {
4473 PreferenceManager .getDefaultSharedPreferences(applicationContext).edit {
4574 when (newValue) {
4675 null -> remove(key)
@@ -54,7 +83,59 @@ class PreferencePropertyDelegate<T>(val parent: KProperty<*>, val defaultValue:
5483 }
5584 }
5685
86+ override operator fun setValue (thisRef : Any? , property : KProperty <* >, value : T ? ) {
87+ setValue(thisRef, null , value)
88+ }
89+
5790 fun get (): T = getValue(null , null )
5891
59- fun set (newValue : T ) = setValue(null , null , newValue)
92+ fun set (newValue : T ? ) = setValue(null , null , newValue)
93+ }
94+
95+ class DynamicPreferencePropertyDelegate <K : Any , V >(
96+ val parent : KProperty <* >,
97+ private val getValue : (K ) -> V ,
98+ private val getKey : (V ) -> K ,
99+ val defaultKey : K ,
100+ ) : ReadWriteProperty<Any?, V>, (Preference ) -> Unit {
101+ val wrapped = PreferencePropertyDelegate (parent, defaultKey)
102+
103+ val key: String by wrapped::key
104+
105+
106+ override fun invoke (preference : Preference ) {
107+ preference.setDefaultValue(getValue(defaultKey))
108+ preference.key = key
109+ }
110+
111+ @JvmName(" getValueNullable" )
112+ operator fun getValue (thisRef : Any? , property : KProperty <* >? ): V {
113+ return getValue(wrapped.get())
114+ }
115+
116+ override operator fun getValue (thisRef : Any? , property : KProperty <* >): V {
117+ return getValue(thisRef, null )
118+ }
119+
120+ @JvmName(" setKeyNullable" )
121+ operator fun setValue (thisRef : Any? , property : KProperty <* >? , newKey : K ) {
122+ wrapped.set(newKey)
123+ }
124+
125+ override operator fun setValue (thisRef : Any? , property : KProperty <* >, value : V ) {
126+ setValue(thisRef, null , value)
127+ }
128+
129+ @JvmName(" setValueNullable" )
130+ operator fun setValue (thisRef : Any? , property : KProperty <* >? , newValue : V ) {
131+ setValue(thisRef, property, getKey(newValue))
132+ }
133+
134+ fun get (): V = getValue(null , null )
135+
136+ @JvmName(" setKey" )
137+ fun set (newKey : K ) = setValue(null , null , newKey)
138+
139+ @JvmName(" setValue" )
140+ fun set (newValue : V ) = setValue(null , null , getKey(newValue))
60141}
0 commit comments