Migrate remaining prefs usages to repo (#2777)

This commit is contained in:
Phil Oliver 2025-08-19 07:17:22 -04:00 committed by GitHub
parent 5f10e9590e
commit c913bb0472
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
15 changed files with 194 additions and 199 deletions

View file

@ -18,8 +18,6 @@
package com.geeksville.mesh
import android.app.Application
import android.content.Context
import android.content.SharedPreferences
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.ProcessLifecycleOwner
@ -32,9 +30,6 @@ import dagger.hilt.components.SingletonComponent
@InstallIn(SingletonComponent::class)
@Module
object ApplicationModule {
@Provides
fun provideSharedPreferences(application: Application): SharedPreferences =
application.getSharedPreferences("ui-prefs", Context.MODE_PRIVATE)
@Provides fun provideProcessLifecycleOwner(): LifecycleOwner = ProcessLifecycleOwner.get()

View file

@ -1,127 +0,0 @@
/*
* Copyright (c) 2025 Meshtastic LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.geeksville.mesh.android
import android.content.Context
import android.content.SharedPreferences
import java.util.UUID
import kotlin.reflect.KProperty
/**
* Created by kevinh on 1/4/15.
*/
/**
* A delegate for "foo by FloatPref"
*/
class FloatPref {
fun get(thisRef: AppPrefs, prop: KProperty<Float>): Float = thisRef.getPrefs().getFloat(thisRef.makeName(prop.name), java.lang.Float.MIN_VALUE)
fun set(thisRef: AppPrefs, prop: KProperty<Float>, value: Float) {
thisRef.setPrefs { e -> e.putFloat(thisRef.makeName(prop.name), value)}
}
}
/**
* A delegate for "foo by StringPref"
*/
class StringPref(val default: String) {
fun get(thisRef: AppPrefs, prop: KProperty<String>): String = thisRef.getPrefs().getString(thisRef.makeName(prop.name), default)!!
fun set(thisRef: AppPrefs, prop: KProperty<String>, value: String) {
thisRef.setPrefs { e ->
e.putString(thisRef.makeName(prop.name), value)
}
}
}
/**
* A mixin for accessing android prefs for the app
*/
public open class AppPrefs(val context: Context) {
companion object {
private val baseName = "appPrefs_"
}
fun makeName(s: String) = baseName + s
fun getPrefs() = context.getSharedPreferences("prefs", Context.MODE_PRIVATE)
fun setPrefs(body: (SharedPreferences.Editor) -> Unit) {
val e = getPrefs().edit()
body(e)
e.commit()
}
fun incPref(name: String) {
setPrefs { e ->
e.putInt(name, 1 + getPrefs().getInt(name, 0))
}
}
fun removePref(name: String) {
setPrefs { e ->
e.remove(name)
}
}
fun putPref(name: String, b: Boolean) {
setPrefs { e ->
e.putBoolean(name, b)
}
}
fun putPref(name: String, b: Float) {
setPrefs { e ->
e.putFloat(name, b)
}
}
fun putPref(name: String, b: Int) {
setPrefs { e ->
e.putInt(name, b)
}
}
fun putPref(name: String, b: Set<String>) {
setPrefs { e ->
e.putStringSet(name, b)
}
}
fun putPref(name: String, b: String) {
setPrefs { e ->
e.putString(name, b)
}
}
/**
* Return a persistent installation ID
*/
fun getInstallId(): String {
var r = getPrefs().getString(makeName("installId"), "")!!
if(r == "") {
r = UUID.randomUUID().toString()
putPref(makeName("installId"), r)
}
return r
}
}

View file

@ -18,11 +18,19 @@
package com.geeksville.mesh.android.prefs
import android.content.SharedPreferences
import java.util.UUID
interface AnalyticsPrefs {
var analyticsAllowed: Boolean
val installId: String
}
class AnalyticsPrefsImpl(prefs: SharedPreferences) : AnalyticsPrefs {
override var analyticsAllowed: Boolean by PrefDelegate(prefs, "allowed", true)
// Having an additional app prefs store is maintaining the existing behavior.
class AnalyticsPrefsImpl(analyticsPrefs: SharedPreferences, appPrefs: SharedPreferences) : AnalyticsPrefs {
override var analyticsAllowed: Boolean by PrefDelegate(analyticsPrefs, "allowed", true)
private var _installId: String? by NullableStringPrefDelegate(appPrefs, "appPrefs_install_id", null)
override val installId: String
get() = _installId ?: UUID.randomUUID().toString().also { _installId = it }
}

View file

@ -0,0 +1,35 @@
/*
* Copyright (c) 2025 Meshtastic LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.geeksville.mesh.android.prefs
import android.content.SharedPreferences
/** Interface for general map prefs. For Google-specific prefs, see GoogleMapsPrefs. */
interface MapPrefs {
var mapStyle: Int
var showOnlyFavorites: Boolean
var showWaypointsOnMap: Boolean
var showPrecisionCircleOnMap: Boolean
}
class MapPrefsImpl(prefs: SharedPreferences) : MapPrefs {
override var mapStyle: Int by PrefDelegate(prefs, "map_style_id", 0)
override var showOnlyFavorites: Boolean by PrefDelegate(prefs, "show_only_favorites", false)
override var showWaypointsOnMap: Boolean by PrefDelegate(prefs, "show_waypoints", true)
override var showPrecisionCircleOnMap: Boolean by PrefDelegate(prefs, "show_precision_circle", true)
}

View file

@ -34,10 +34,18 @@ import javax.inject.Singleton
@Retention(AnnotationRetention.BINARY)
private annotation class AnalyticsSharedPreferences
@Qualifier
@Retention(AnnotationRetention.BINARY)
private annotation class AppSharedPreferences
@Qualifier
@Retention(AnnotationRetention.BINARY)
private annotation class CustomEmojiSharedPreferences
@Qualifier
@Retention(AnnotationRetention.BINARY)
private annotation class MapSharedPreferences
@Qualifier
@Retention(AnnotationRetention.BINARY)
private annotation class MapConsentSharedPreferences
@ -69,12 +77,24 @@ object PrefsModule {
fun provideAnalyticsSharedPreferences(@ApplicationContext context: Context): SharedPreferences =
context.getSharedPreferences("analytics-prefs", Context.MODE_PRIVATE)
@Provides
@Singleton
@AppSharedPreferences
fun provideAppSharedPreferences(@ApplicationContext context: Context): SharedPreferences =
context.getSharedPreferences("prefs", Context.MODE_PRIVATE)
@Provides
@Singleton
@CustomEmojiSharedPreferences
fun provideCustomEmojiSharedPreferences(@ApplicationContext context: Context): SharedPreferences =
context.getSharedPreferences("org.geeksville.emoji.prefs", Context.MODE_PRIVATE)
@Provides
@Singleton
@MapSharedPreferences
fun provideMapSharedPreferences(@ApplicationContext context: Context): SharedPreferences =
context.getSharedPreferences("map_prefs", Context.MODE_PRIVATE)
@Provides
@Singleton
@MapConsentSharedPreferences
@ -107,14 +127,21 @@ object PrefsModule {
@Provides
@Singleton
fun provideAnalyticsPrefs(@AnalyticsSharedPreferences sharedPreferences: SharedPreferences): AnalyticsPrefs =
AnalyticsPrefsImpl(sharedPreferences)
fun provideAnalyticsPrefs(
@AnalyticsSharedPreferences analyticsPreferences: SharedPreferences,
@AppSharedPreferences appPreferences: SharedPreferences,
): AnalyticsPrefs = AnalyticsPrefsImpl(analyticsPreferences, appPreferences)
@Provides
@Singleton
fun provideCustomEmojiPrefs(@CustomEmojiSharedPreferences sharedPreferences: SharedPreferences): CustomEmojiPrefs =
CustomEmojiPrefsImpl(sharedPreferences)
@Provides
@Singleton
fun provideMapPrefs(@MapSharedPreferences sharedPreferences: SharedPreferences): MapPrefs =
MapPrefsImpl(sharedPreferences)
@Provides
@Singleton
fun provideMapConsentPrefs(@MapConsentSharedPreferences sharedPreferences: SharedPreferences): MapConsentPrefs =

View file

@ -36,15 +36,6 @@ interface UiPrefs {
var showIgnored: Boolean
var showQuickChat: Boolean
// region Map prefs
var showOnlyFavorites: Boolean
var showWaypointsOnMap: Boolean
var showPrecisionCircleOnMap: Boolean
var mapStyle: Int
// endregion
fun shouldProvideNodeLocation(nodeNum: Int?): Boolean
fun setShouldProvideNodeLocation(nodeNum: Int?, value: Boolean)
@ -62,10 +53,6 @@ class UiPrefsImpl(private val prefs: SharedPreferences) : UiPrefs {
override var onlyDirect: Boolean by PrefDelegate(prefs, "only-direct", false)
override var showIgnored: Boolean by PrefDelegate(prefs, "show-ignored", false)
override var showQuickChat: Boolean by PrefDelegate(prefs, "show-quick-chat", false)
override var showOnlyFavorites: Boolean by PrefDelegate(prefs, "only-favorites", false)
override var showWaypointsOnMap: Boolean by PrefDelegate(prefs, "show-waypoints-on-map", true)
override var showPrecisionCircleOnMap: Boolean by PrefDelegate(prefs, "show-precision-circle-on-map", true)
override var mapStyle: Int by PrefDelegate(prefs, "map_style_id", 0)
override fun shouldProvideNodeLocation(nodeNum: Int?): Boolean =
prefs.getBoolean(provideLocationKey(nodeNum), false)

View file

@ -37,7 +37,7 @@ import com.geeksville.mesh.Portnums.PortNum
import com.geeksville.mesh.R
import com.geeksville.mesh.TelemetryProtos.Telemetry
import com.geeksville.mesh.android.Logging
import com.geeksville.mesh.android.prefs.UiPrefs
import com.geeksville.mesh.android.prefs.MapPrefs
import com.geeksville.mesh.database.MeshLogRepository
import com.geeksville.mesh.database.entity.FirmwareRelease
import com.geeksville.mesh.database.entity.MeshLog
@ -203,7 +203,7 @@ constructor(
private val radioConfigRepository: RadioConfigRepository,
private val deviceHardwareRepository: DeviceHardwareRepository,
private val firmwareReleaseRepository: FirmwareReleaseRepository,
private val uiPrefs: UiPrefs,
private val mapPrefs: MapPrefs,
) : ViewModel(),
Logging {
private val destNum = savedStateHandle.toRoute<NodesRoutes.NodeDetailGraph>().destNum
@ -233,7 +233,7 @@ constructor(
fun getUser(nodeNum: Int) = radioConfigRepository.getUser(nodeNum)
val tileSource
get() = CustomTileSource.getTileSource(uiPrefs.mapStyle)
get() = CustomTileSource.getTileSource(mapPrefs.mapStyle)
fun deleteLog(uuid: String) = viewModelScope.launch(dispatchers.io) { meshLogRepository.deleteLog(uuid) }

View file

@ -19,7 +19,7 @@ package com.geeksville.mesh.ui.map
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.geeksville.mesh.android.prefs.UiPrefs
import com.geeksville.mesh.android.prefs.MapPrefs
import com.geeksville.mesh.database.NodeRepository
import com.geeksville.mesh.database.PacketRepository
import com.geeksville.mesh.database.entity.Packet
@ -34,7 +34,7 @@ import kotlinx.coroutines.flow.stateIn
@Suppress("TooManyFunctions")
abstract class BaseMapViewModel(
protected val uiPrefs: UiPrefs,
protected val mapPrefs: MapPrefs,
nodeRepository: NodeRepository,
packetRepository: PacketRepository,
) : ViewModel() {
@ -61,27 +61,27 @@ abstract class BaseMapViewModel(
}
.stateIn(scope = viewModelScope, started = SharingStarted.WhileSubscribed(5_000), initialValue = emptyMap())
private val showOnlyFavorites = MutableStateFlow(uiPrefs.showOnlyFavorites)
private val showOnlyFavorites = MutableStateFlow(mapPrefs.showOnlyFavorites)
private val showWaypointsOnMap = MutableStateFlow(uiPrefs.showWaypointsOnMap)
private val showWaypointsOnMap = MutableStateFlow(mapPrefs.showWaypointsOnMap)
private val showPrecisionCircleOnMap = MutableStateFlow(uiPrefs.showPrecisionCircleOnMap)
private val showPrecisionCircleOnMap = MutableStateFlow(mapPrefs.showPrecisionCircleOnMap)
fun toggleOnlyFavorites() {
val current = showOnlyFavorites.value
uiPrefs.showOnlyFavorites = !current
mapPrefs.showOnlyFavorites = !current
showOnlyFavorites.value = !current
}
fun toggleShowWaypointsOnMap() {
val current = showWaypointsOnMap.value
uiPrefs.showWaypointsOnMap = !current
mapPrefs.showWaypointsOnMap = !current
showWaypointsOnMap.value = !current
}
fun toggleShowPrecisionCircleOnMap() {
val current = showPrecisionCircleOnMap.value
uiPrefs.showPrecisionCircleOnMap = !current
mapPrefs.showPrecisionCircleOnMap = !current
showPrecisionCircleOnMap.value = !current
}