From b98e5331230c35eb462d74421ff0f9df81ae90bc Mon Sep 17 00:00:00 2001
From: Phil Oliver <3497406+poliver@users.noreply.github.com>
Date: Tue, 23 Sep 2025 05:51:03 -0400
Subject: [PATCH] Modularize prefs classes (#3171)
---
.../geeksville/mesh/MeshUtilApplication.kt | 2 +-
.../mesh/android/GeeksvilleApplication.kt | 2 +-
.../geeksville/mesh/ui/map/MapViewModel.kt | 2 +-
.../geeksville/mesh/MeshUtilApplication.kt | 2 +-
.../mesh/android/GeeksvilleApplication.kt | 2 +-
...PreferencesCustomTileProviderRepository.kt | 2 +-
.../geeksville/mesh/ui/map/MapViewModel.kt | 4 +-
.../java/com/geeksville/mesh/MainActivity.kt | 2 +-
.../mesh/android/prefs/PrefsModule.kt | 170 ------------------
.../geeksville/mesh/model/MetricsViewModel.kt | 2 +-
.../java/com/geeksville/mesh/model/UIState.kt | 2 +-
.../repository/radio/RadioInterfaceService.kt | 6 +-
.../geeksville/mesh/service/MeshService.kt | 4 +-
.../mesh/ui/common/EmojiPickerViewModel.kt | 2 +-
.../ui/connections/ConnectionsViewModel.kt | 2 +-
.../mesh/ui/map/BaseMapViewModel.kt | 2 +-
.../mesh/ui/settings/SettingsViewModel.kt | 2 +-
.../ui/settings/radio/RadioConfigViewModel.kt | 4 +-
core/prefs/build.gradle.kts | 7 +-
.../core/prefs/di}/GoogleMapsModule.kt | 29 +--
.../core/prefs/map}/GoogleMapsPrefs.kt | 10 +-
.../core}/prefs/NullableStringPrefDelegate.kt | 4 +-
.../meshtastic/core}/prefs/PrefDelegate.kt | 9 +-
.../core}/prefs/StringSetPrefDelegate.kt | 4 +-
.../core/prefs/analytics}/AnalyticsPrefs.kt | 16 +-
.../meshtastic/core/prefs/di/PrefsModule.kt | 163 +++++++++++++++++
.../core/prefs/emoji}/CustomEmojiPrefs.kt | 10 +-
.../core/prefs/map}/MapConsentPrefs.kt | 9 +-
.../meshtastic/core/prefs/map}/MapPrefs.kt | 9 +-
.../core/prefs/map}/MapTileProviderPrefs.kt | 10 +-
.../meshtastic/core/prefs/mesh}/MeshPrefs.kt | 9 +-
.../core/prefs/radio}/RadioPrefs.kt | 9 +-
.../org/meshtastic/core/prefs/ui}/UiPrefs.kt | 12 +-
33 files changed, 290 insertions(+), 234 deletions(-)
delete mode 100644 app/src/main/java/com/geeksville/mesh/android/prefs/PrefsModule.kt
rename {app/src/google/java/com/geeksville/mesh/android/prefs => core/prefs/src/google/kotlin/org/meshtastic/core/prefs/di}/GoogleMapsModule.kt (61%)
rename {app/src/google/java/com/geeksville/mesh/android/prefs => core/prefs/src/google/kotlin/org/meshtastic/core/prefs/map}/GoogleMapsPrefs.kt (77%)
rename {app/src/main/java/com/geeksville/mesh/android => core/prefs/src/main/kotlin/org/meshtastic/core}/prefs/NullableStringPrefDelegate.kt (95%)
rename {app/src/main/java/com/geeksville/mesh/android => core/prefs/src/main/kotlin/org/meshtastic/core}/prefs/PrefDelegate.kt (91%)
rename {app/src/main/java/com/geeksville/mesh/android => core/prefs/src/main/kotlin/org/meshtastic/core}/prefs/StringSetPrefDelegate.kt (94%)
rename {app/src/main/java/com/geeksville/mesh/android/prefs => core/prefs/src/main/kotlin/org/meshtastic/core/prefs/analytics}/AnalyticsPrefs.kt (70%)
create mode 100644 core/prefs/src/main/kotlin/org/meshtastic/core/prefs/di/PrefsModule.kt
rename {app/src/main/java/com/geeksville/mesh/android/prefs => core/prefs/src/main/kotlin/org/meshtastic/core/prefs/emoji}/CustomEmojiPrefs.kt (72%)
rename {app/src/main/java/com/geeksville/mesh/android/prefs => core/prefs/src/main/kotlin/org/meshtastic/core/prefs/map}/MapConsentPrefs.kt (79%)
rename {app/src/main/java/com/geeksville/mesh/android/prefs => core/prefs/src/main/kotlin/org/meshtastic/core/prefs/map}/MapPrefs.kt (81%)
rename {app/src/main/java/com/geeksville/mesh/android/prefs => core/prefs/src/main/kotlin/org/meshtastic/core/prefs/map}/MapTileProviderPrefs.kt (71%)
rename {app/src/main/java/com/geeksville/mesh/android/prefs => core/prefs/src/main/kotlin/org/meshtastic/core/prefs/mesh}/MeshPrefs.kt (80%)
rename {app/src/main/java/com/geeksville/mesh/android/prefs => core/prefs/src/main/kotlin/org/meshtastic/core/prefs/radio}/RadioPrefs.kt (72%)
rename {app/src/main/java/com/geeksville/mesh/android/prefs => core/prefs/src/main/kotlin/org/meshtastic/core/prefs/ui}/UiPrefs.kt (92%)
diff --git a/app/src/fdroid/java/com/geeksville/mesh/MeshUtilApplication.kt b/app/src/fdroid/java/com/geeksville/mesh/MeshUtilApplication.kt
index 52925a6cd..5782d5ce0 100644
--- a/app/src/fdroid/java/com/geeksville/mesh/MeshUtilApplication.kt
+++ b/app/src/fdroid/java/com/geeksville/mesh/MeshUtilApplication.kt
@@ -18,8 +18,8 @@
package com.geeksville.mesh
import com.geeksville.mesh.android.GeeksvilleApplication
-import com.geeksville.mesh.android.prefs.AnalyticsPrefs
import dagger.hilt.android.HiltAndroidApp
+import org.meshtastic.core.prefs.analytics.AnalyticsPrefs
import javax.inject.Inject
@HiltAndroidApp
diff --git a/app/src/fdroid/java/com/geeksville/mesh/android/GeeksvilleApplication.kt b/app/src/fdroid/java/com/geeksville/mesh/android/GeeksvilleApplication.kt
index 8117c46c0..32ed72d5f 100644
--- a/app/src/fdroid/java/com/geeksville/mesh/android/GeeksvilleApplication.kt
+++ b/app/src/fdroid/java/com/geeksville/mesh/android/GeeksvilleApplication.kt
@@ -28,8 +28,8 @@ import com.geeksville.mesh.analytics.AnalyticsProvider
import com.geeksville.mesh.analytics.NopAnalytics
import com.geeksville.mesh.android.BuildUtils.debug
import com.geeksville.mesh.android.BuildUtils.info
-import com.geeksville.mesh.android.prefs.AnalyticsPrefs
import org.meshtastic.core.model.DeviceHardware
+import org.meshtastic.core.prefs.analytics.AnalyticsPrefs
import timber.log.Timber
abstract class GeeksvilleApplication :
diff --git a/app/src/fdroid/java/com/geeksville/mesh/ui/map/MapViewModel.kt b/app/src/fdroid/java/com/geeksville/mesh/ui/map/MapViewModel.kt
index b51c9b7d9..79060fbc5 100644
--- a/app/src/fdroid/java/com/geeksville/mesh/ui/map/MapViewModel.kt
+++ b/app/src/fdroid/java/com/geeksville/mesh/ui/map/MapViewModel.kt
@@ -17,11 +17,11 @@
package com.geeksville.mesh.ui.map
-import com.geeksville.mesh.android.prefs.MapPrefs
import com.geeksville.mesh.database.NodeRepository
import com.geeksville.mesh.database.PacketRepository
import com.geeksville.mesh.repository.datastore.RadioConfigRepository
import dagger.hilt.android.lifecycle.HiltViewModel
+import org.meshtastic.core.prefs.map.MapPrefs
import javax.inject.Inject
@HiltViewModel
diff --git a/app/src/google/java/com/geeksville/mesh/MeshUtilApplication.kt b/app/src/google/java/com/geeksville/mesh/MeshUtilApplication.kt
index 997df57a0..30e8ff1d6 100644
--- a/app/src/google/java/com/geeksville/mesh/MeshUtilApplication.kt
+++ b/app/src/google/java/com/geeksville/mesh/MeshUtilApplication.kt
@@ -18,8 +18,8 @@
package com.geeksville.mesh
import com.geeksville.mesh.android.GeeksvilleApplication
-import com.geeksville.mesh.android.prefs.AnalyticsPrefs
import dagger.hilt.android.HiltAndroidApp
+import org.meshtastic.core.prefs.analytics.AnalyticsPrefs
import javax.inject.Inject
@HiltAndroidApp
diff --git a/app/src/google/java/com/geeksville/mesh/android/GeeksvilleApplication.kt b/app/src/google/java/com/geeksville/mesh/android/GeeksvilleApplication.kt
index 110be10b6..d89f97be2 100644
--- a/app/src/google/java/com/geeksville/mesh/android/GeeksvilleApplication.kt
+++ b/app/src/google/java/com/geeksville/mesh/android/GeeksvilleApplication.kt
@@ -48,7 +48,6 @@ import com.datadog.android.trace.opentelemetry.DatadogOpenTelemetry
import com.geeksville.mesh.BuildConfig
import com.geeksville.mesh.analytics.AnalyticsProvider
import com.geeksville.mesh.analytics.FirebaseAnalytics
-import com.geeksville.mesh.android.prefs.AnalyticsPrefs
import com.geeksville.mesh.util.exceptionReporter
import com.google.android.gms.common.ConnectionResult
import com.google.android.gms.common.GoogleApiAvailabilityLight
@@ -60,6 +59,7 @@ import com.google.firebase.initialize
import com.suddenh4x.ratingdialog.AppRating
import io.opentelemetry.api.GlobalOpenTelemetry
import org.meshtastic.core.model.DeviceHardware
+import org.meshtastic.core.prefs.analytics.AnalyticsPrefs
import timber.log.Timber
abstract class GeeksvilleApplication :
diff --git a/app/src/google/java/com/geeksville/mesh/repository/map/SharedPreferencesCustomTileProviderRepository.kt b/app/src/google/java/com/geeksville/mesh/repository/map/SharedPreferencesCustomTileProviderRepository.kt
index 92d5c43c7..d48034a37 100644
--- a/app/src/google/java/com/geeksville/mesh/repository/map/SharedPreferencesCustomTileProviderRepository.kt
+++ b/app/src/google/java/com/geeksville/mesh/repository/map/SharedPreferencesCustomTileProviderRepository.kt
@@ -17,7 +17,6 @@
package com.geeksville.mesh.repository.map
-import com.geeksville.mesh.android.prefs.MapTileProviderPrefs
import com.geeksville.mesh.di.IoDispatcher
import com.geeksville.mesh.ui.map.CustomTileProviderConfig
import kotlinx.coroutines.CoroutineDispatcher
@@ -27,6 +26,7 @@ import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.withContext
import kotlinx.serialization.SerializationException
import kotlinx.serialization.json.Json
+import org.meshtastic.core.prefs.map.MapTileProviderPrefs
import timber.log.Timber
import javax.inject.Inject
import javax.inject.Singleton
diff --git a/app/src/google/java/com/geeksville/mesh/ui/map/MapViewModel.kt b/app/src/google/java/com/geeksville/mesh/ui/map/MapViewModel.kt
index dd7905380..3d7cb4bb3 100644
--- a/app/src/google/java/com/geeksville/mesh/ui/map/MapViewModel.kt
+++ b/app/src/google/java/com/geeksville/mesh/ui/map/MapViewModel.kt
@@ -23,8 +23,6 @@ import androidx.core.net.toFile
import androidx.lifecycle.viewModelScope
import com.geeksville.mesh.ConfigProtos
import com.geeksville.mesh.android.BuildUtils.debug
-import com.geeksville.mesh.android.prefs.GoogleMapsPrefs
-import com.geeksville.mesh.android.prefs.MapPrefs
import com.geeksville.mesh.database.NodeRepository
import com.geeksville.mesh.database.PacketRepository
import com.geeksville.mesh.repository.datastore.RadioConfigRepository
@@ -52,6 +50,8 @@ import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import kotlinx.serialization.Serializable
import org.json.JSONObject
+import org.meshtastic.core.prefs.map.GoogleMapsPrefs
+import org.meshtastic.core.prefs.map.MapPrefs
import timber.log.Timber
import java.io.File
import java.io.FileOutputStream
diff --git a/app/src/main/java/com/geeksville/mesh/MainActivity.kt b/app/src/main/java/com/geeksville/mesh/MainActivity.kt
index 73f8a0a41..74e7c76b7 100644
--- a/app/src/main/java/com/geeksville/mesh/MainActivity.kt
+++ b/app/src/main/java/com/geeksville/mesh/MainActivity.kt
@@ -41,7 +41,6 @@ import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.geeksville.mesh.android.GeeksvilleApplication
import com.geeksville.mesh.android.Logging
-import com.geeksville.mesh.android.prefs.UiPrefs
import com.geeksville.mesh.model.UIViewModel
import com.geeksville.mesh.ui.MainScreen
import com.geeksville.mesh.ui.common.theme.AppTheme
@@ -50,6 +49,7 @@ import com.geeksville.mesh.ui.intro.AppIntroductionScreen
import com.geeksville.mesh.ui.sharing.toSharedContact
import dagger.hilt.android.AndroidEntryPoint
import org.meshtastic.core.navigation.DEEP_LINK_BASE_URI
+import org.meshtastic.core.prefs.ui.UiPrefs
import javax.inject.Inject
@AndroidEntryPoint
diff --git a/app/src/main/java/com/geeksville/mesh/android/prefs/PrefsModule.kt b/app/src/main/java/com/geeksville/mesh/android/prefs/PrefsModule.kt
deleted file mode 100644
index e4eff087d..000000000
--- a/app/src/main/java/com/geeksville/mesh/android/prefs/PrefsModule.kt
+++ /dev/null
@@ -1,170 +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 .
- */
-
-package com.geeksville.mesh.android.prefs
-
-import android.content.Context
-import android.content.SharedPreferences
-import dagger.Module
-import dagger.Provides
-import dagger.hilt.InstallIn
-import dagger.hilt.android.qualifiers.ApplicationContext
-import dagger.hilt.components.SingletonComponent
-import javax.inject.Qualifier
-import javax.inject.Singleton
-
-// These pref store qualifiers are private to prevent prefs stores from being injected directly.
-// Consuming code should always inject one of the prefs repositories.
-
-@Qualifier
-@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
-
-@Qualifier
-@Retention(AnnotationRetention.BINARY)
-private annotation class MapTileProviderSharedPreferences
-
-@Qualifier
-@Retention(AnnotationRetention.BINARY)
-private annotation class MeshSharedPreferences
-
-@Qualifier
-@Retention(AnnotationRetention.BINARY)
-private annotation class RadioSharedPreferences
-
-@Qualifier
-@Retention(AnnotationRetention.BINARY)
-private annotation class UiSharedPreferences
-
-@Suppress("TooManyFunctions")
-@InstallIn(SingletonComponent::class)
-@Module
-object PrefsModule {
-
- @Provides
- @Singleton
- @AnalyticsSharedPreferences
- 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
- fun provideMapConsentSharedPreferences(@ApplicationContext context: Context): SharedPreferences =
- context.getSharedPreferences("map_consent_preferences", Context.MODE_PRIVATE)
-
- @Provides
- @Singleton
- @MapTileProviderSharedPreferences
- fun provideMapTileProviderSharedPreferences(@ApplicationContext context: Context): SharedPreferences =
- context.getSharedPreferences("map_tile_provider_prefs", Context.MODE_PRIVATE)
-
- @Provides
- @Singleton
- @MeshSharedPreferences
- fun provideMeshSharedPreferences(@ApplicationContext context: Context): SharedPreferences =
- context.getSharedPreferences("mesh-prefs", Context.MODE_PRIVATE)
-
- @Provides
- @Singleton
- @RadioSharedPreferences
- fun provideRadioSharedPreferences(@ApplicationContext context: Context): SharedPreferences =
- context.getSharedPreferences("radio-prefs", Context.MODE_PRIVATE)
-
- @Provides
- @Singleton
- @UiSharedPreferences
- fun provideUiSharedPreferences(@ApplicationContext context: Context): SharedPreferences =
- context.getSharedPreferences("ui-prefs", Context.MODE_PRIVATE)
-
- @Provides
- @Singleton
- 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 =
- MapConsentPrefsImpl(sharedPreferences)
-
- @Provides
- @Singleton
- fun provideMapTileProviderPrefs(
- @MapTileProviderSharedPreferences sharedPreferences: SharedPreferences,
- ): MapTileProviderPrefs = MapTileProviderPrefsImpl(sharedPreferences)
-
- @Provides
- @Singleton
- fun provideMeshPrefs(@MeshSharedPreferences sharedPreferences: SharedPreferences): MeshPrefs =
- MeshPrefsImpl(sharedPreferences)
-
- @Provides
- @Singleton
- fun provideRadioPrefs(@RadioSharedPreferences sharedPreferences: SharedPreferences): RadioPrefs =
- RadioPrefsImpl(sharedPreferences)
-
- @Provides
- @Singleton
- fun provideUiPrefs(@UiSharedPreferences sharedPreferences: SharedPreferences): UiPrefs =
- UiPrefsImpl(sharedPreferences)
-}
diff --git a/app/src/main/java/com/geeksville/mesh/model/MetricsViewModel.kt b/app/src/main/java/com/geeksville/mesh/model/MetricsViewModel.kt
index ff325a593..f72f90cd5 100644
--- a/app/src/main/java/com/geeksville/mesh/model/MetricsViewModel.kt
+++ b/app/src/main/java/com/geeksville/mesh/model/MetricsViewModel.kt
@@ -36,7 +36,6 @@ import com.geeksville.mesh.Portnums
import com.geeksville.mesh.Portnums.PortNum
import com.geeksville.mesh.TelemetryProtos.Telemetry
import com.geeksville.mesh.android.Logging
-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
@@ -62,6 +61,7 @@ import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.meshtastic.core.model.DeviceHardware
import org.meshtastic.core.navigation.NodesRoutes
+import org.meshtastic.core.prefs.map.MapPrefs
import org.meshtastic.core.strings.R
import org.meshtastic.feature.map.model.CustomTileSource
import java.io.BufferedWriter
diff --git a/app/src/main/java/com/geeksville/mesh/model/UIState.kt b/app/src/main/java/com/geeksville/mesh/model/UIState.kt
index 1f4a53907..ee6f228a5 100644
--- a/app/src/main/java/com/geeksville/mesh/model/UIState.kt
+++ b/app/src/main/java/com/geeksville/mesh/model/UIState.kt
@@ -39,7 +39,6 @@ import com.geeksville.mesh.LocalOnlyProtos.LocalModuleConfig
import com.geeksville.mesh.MeshProtos
import com.geeksville.mesh.Position
import com.geeksville.mesh.android.Logging
-import com.geeksville.mesh.android.prefs.UiPrefs
import com.geeksville.mesh.channel
import com.geeksville.mesh.channelSet
import com.geeksville.mesh.channelSettings
@@ -83,6 +82,7 @@ import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import org.meshtastic.core.model.DeviceHardware
+import org.meshtastic.core.prefs.ui.UiPrefs
import org.meshtastic.core.strings.R
import javax.inject.Inject
diff --git a/app/src/main/java/com/geeksville/mesh/repository/radio/RadioInterfaceService.kt b/app/src/main/java/com/geeksville/mesh/repository/radio/RadioInterfaceService.kt
index fe12885a5..e448b421f 100644
--- a/app/src/main/java/com/geeksville/mesh/repository/radio/RadioInterfaceService.kt
+++ b/app/src/main/java/com/geeksville/mesh/repository/radio/RadioInterfaceService.kt
@@ -27,7 +27,6 @@ import com.geeksville.mesh.android.BinaryLogFile
import com.geeksville.mesh.android.BuildUtils
import com.geeksville.mesh.android.GeeksvilleApplication
import com.geeksville.mesh.android.Logging
-import com.geeksville.mesh.android.prefs.RadioPrefs
import com.geeksville.mesh.concurrent.handledLaunch
import com.geeksville.mesh.repository.bluetooth.BluetoothRepository
import com.geeksville.mesh.repository.network.NetworkRepository
@@ -49,6 +48,7 @@ import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch
+import org.meshtastic.core.prefs.radio.RadioPrefs
import javax.inject.Inject
import javax.inject.Singleton
@@ -195,9 +195,7 @@ constructor(
private fun broadcastConnectionChanged(newState: ConnectionState) {
debug("Broadcasting connection state change to $newState")
- processLifecycle.coroutineScope.launch(dispatchers.default) {
- _connectionState.emit(newState)
- }
+ processLifecycle.coroutineScope.launch(dispatchers.default) { _connectionState.emit(newState) }
}
// Send a packet/command out the radio link, this routine can block if it needs to
diff --git a/app/src/main/java/com/geeksville/mesh/service/MeshService.kt b/app/src/main/java/com/geeksville/mesh/service/MeshService.kt
index b0bc11933..6d9876769 100644
--- a/app/src/main/java/com/geeksville/mesh/service/MeshService.kt
+++ b/app/src/main/java/com/geeksville/mesh/service/MeshService.kt
@@ -58,8 +58,6 @@ import com.geeksville.mesh.analytics.DataPair
import com.geeksville.mesh.android.GeeksvilleApplication
import com.geeksville.mesh.android.Logging
import com.geeksville.mesh.android.hasLocationPermission
-import com.geeksville.mesh.android.prefs.MeshPrefs
-import com.geeksville.mesh.android.prefs.UiPrefs
import com.geeksville.mesh.concurrent.handledLaunch
import com.geeksville.mesh.copy
import com.geeksville.mesh.database.MeshLogRepository
@@ -103,6 +101,8 @@ import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import org.meshtastic.core.model.getFullTracerouteResponse
+import org.meshtastic.core.prefs.mesh.MeshPrefs
+import org.meshtastic.core.prefs.ui.UiPrefs
import org.meshtastic.core.strings.R
import java.util.Random
import java.util.UUID
diff --git a/app/src/main/java/com/geeksville/mesh/ui/common/EmojiPickerViewModel.kt b/app/src/main/java/com/geeksville/mesh/ui/common/EmojiPickerViewModel.kt
index b97cb8961..9eabbfc7b 100644
--- a/app/src/main/java/com/geeksville/mesh/ui/common/EmojiPickerViewModel.kt
+++ b/app/src/main/java/com/geeksville/mesh/ui/common/EmojiPickerViewModel.kt
@@ -18,8 +18,8 @@
package com.geeksville.mesh.ui.common
import androidx.lifecycle.ViewModel
-import com.geeksville.mesh.android.prefs.CustomEmojiPrefs
import dagger.hilt.android.lifecycle.HiltViewModel
+import org.meshtastic.core.prefs.emoji.CustomEmojiPrefs
import javax.inject.Inject
@HiltViewModel
diff --git a/app/src/main/java/com/geeksville/mesh/ui/connections/ConnectionsViewModel.kt b/app/src/main/java/com/geeksville/mesh/ui/connections/ConnectionsViewModel.kt
index 491aee075..67d21df88 100644
--- a/app/src/main/java/com/geeksville/mesh/ui/connections/ConnectionsViewModel.kt
+++ b/app/src/main/java/com/geeksville/mesh/ui/connections/ConnectionsViewModel.kt
@@ -20,7 +20,6 @@ package com.geeksville.mesh.ui.connections
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.geeksville.mesh.LocalOnlyProtos.LocalConfig
-import com.geeksville.mesh.android.prefs.UiPrefs
import com.geeksville.mesh.database.NodeRepository
import com.geeksville.mesh.database.entity.MyNodeEntity
import com.geeksville.mesh.model.Node
@@ -32,6 +31,7 @@ import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.stateIn
+import org.meshtastic.core.prefs.ui.UiPrefs
import javax.inject.Inject
@HiltViewModel
diff --git a/app/src/main/java/com/geeksville/mesh/ui/map/BaseMapViewModel.kt b/app/src/main/java/com/geeksville/mesh/ui/map/BaseMapViewModel.kt
index aafb5f67d..29e1c92c4 100644
--- a/app/src/main/java/com/geeksville/mesh/ui/map/BaseMapViewModel.kt
+++ b/app/src/main/java/com/geeksville/mesh/ui/map/BaseMapViewModel.kt
@@ -19,7 +19,6 @@ package com.geeksville.mesh.ui.map
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
-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
@@ -32,6 +31,7 @@ import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.mapLatest
import kotlinx.coroutines.flow.stateIn
+import org.meshtastic.core.prefs.map.MapPrefs
@Suppress("TooManyFunctions")
abstract class BaseMapViewModel(
diff --git a/app/src/main/java/com/geeksville/mesh/ui/settings/SettingsViewModel.kt b/app/src/main/java/com/geeksville/mesh/ui/settings/SettingsViewModel.kt
index 8d64499ba..a73c5a599 100644
--- a/app/src/main/java/com/geeksville/mesh/ui/settings/SettingsViewModel.kt
+++ b/app/src/main/java/com/geeksville/mesh/ui/settings/SettingsViewModel.kt
@@ -27,7 +27,6 @@ import com.geeksville.mesh.MeshProtos
import com.geeksville.mesh.Portnums
import com.geeksville.mesh.Position
import com.geeksville.mesh.android.Logging
-import com.geeksville.mesh.android.prefs.UiPrefs
import com.geeksville.mesh.database.MeshLogRepository
import com.geeksville.mesh.database.NodeRepository
import com.geeksville.mesh.database.entity.MyNodeEntity
@@ -48,6 +47,7 @@ import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
+import org.meshtastic.core.prefs.ui.UiPrefs
import java.io.BufferedWriter
import java.io.FileNotFoundException
import java.io.FileWriter
diff --git a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/RadioConfigViewModel.kt b/app/src/main/java/com/geeksville/mesh/ui/settings/radio/RadioConfigViewModel.kt
index 92a0cf8c0..44569533a 100644
--- a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/RadioConfigViewModel.kt
+++ b/app/src/main/java/com/geeksville/mesh/ui/settings/radio/RadioConfigViewModel.kt
@@ -45,8 +45,6 @@ import com.geeksville.mesh.Position
import com.geeksville.mesh.android.GeeksvilleApplication
import com.geeksville.mesh.android.Logging
import com.geeksville.mesh.android.isAnalyticsAvailable
-import com.geeksville.mesh.android.prefs.AnalyticsPrefs
-import com.geeksville.mesh.android.prefs.MapConsentPrefs
import com.geeksville.mesh.config
import com.geeksville.mesh.database.entity.MyNodeEntity
import com.geeksville.mesh.deviceProfile
@@ -77,6 +75,8 @@ import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.json.JSONObject
import org.meshtastic.core.navigation.SettingsRoutes
+import org.meshtastic.core.prefs.analytics.AnalyticsPrefs
+import org.meshtastic.core.prefs.map.MapConsentPrefs
import org.meshtastic.core.strings.R
import java.io.FileOutputStream
import javax.inject.Inject
diff --git a/core/prefs/build.gradle.kts b/core/prefs/build.gradle.kts
index 5f811dbf2..58b95ea1d 100644
--- a/core/prefs/build.gradle.kts
+++ b/core/prefs/build.gradle.kts
@@ -17,9 +17,14 @@
plugins {
alias(libs.plugins.meshtastic.android.library)
+ alias(libs.plugins.meshtastic.hilt)
alias(libs.plugins.kover)
}
android { namespace = "org.meshtastic.core.prefs" }
-dependencies {}
+dependencies {
+ implementation(libs.bundles.coroutines)
+ implementation(libs.appcompat)
+ googleImplementation(libs.maps.compose)
+}
diff --git a/app/src/google/java/com/geeksville/mesh/android/prefs/GoogleMapsModule.kt b/core/prefs/src/google/kotlin/org/meshtastic/core/prefs/di/GoogleMapsModule.kt
similarity index 61%
rename from app/src/google/java/com/geeksville/mesh/android/prefs/GoogleMapsModule.kt
rename to core/prefs/src/google/kotlin/org/meshtastic/core/prefs/di/GoogleMapsModule.kt
index 56328c08a..79d0eb3ff 100644
--- a/app/src/google/java/com/geeksville/mesh/android/prefs/GoogleMapsModule.kt
+++ b/core/prefs/src/google/kotlin/org/meshtastic/core/prefs/di/GoogleMapsModule.kt
@@ -15,37 +15,40 @@
* along with this program. If not, see .
*/
-package com.geeksville.mesh.android.prefs
+package org.meshtastic.core.prefs.di
import android.content.Context
import android.content.SharedPreferences
+import dagger.Binds
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.components.SingletonComponent
+import org.meshtastic.core.prefs.map.GoogleMapsPrefs
+import org.meshtastic.core.prefs.map.GoogleMapsPrefsImpl
import javax.inject.Qualifier
import javax.inject.Singleton
-// Pref store qualifiers are private to prevent prefs stores from being injected directly.
+// Pref store qualifiers are internal to prevent prefs stores from being injected directly.
// Consuming code should always inject one of the prefs repositories.
@Qualifier
@Retention(AnnotationRetention.BINARY)
-private annotation class GoogleMapsSharedPreferences
+internal annotation class GoogleMapsSharedPreferences
@InstallIn(SingletonComponent::class)
@Module
-object GoogleMapsModule {
+interface GoogleMapsModule {
- @Provides
- @Singleton
- @GoogleMapsSharedPreferences
- fun provideGoogleMapsSharedPreferences(@ApplicationContext context: Context): SharedPreferences =
- context.getSharedPreferences("google_maps_prefs", Context.MODE_PRIVATE)
+ @Binds fun bindGoogleMapsPrefs(googleMapsPrefsImpl: GoogleMapsPrefsImpl): GoogleMapsPrefs
- @Provides
- @Singleton
- fun provideGoogleMapsPrefs(@GoogleMapsSharedPreferences sharedPreferences: SharedPreferences): GoogleMapsPrefs =
- GoogleMapsPrefsImpl(sharedPreferences)
+ companion object {
+
+ @Provides
+ @Singleton
+ @GoogleMapsSharedPreferences
+ fun provideGoogleMapsSharedPreferences(@ApplicationContext context: Context): SharedPreferences =
+ context.getSharedPreferences("google_maps_prefs", Context.MODE_PRIVATE)
+ }
}
diff --git a/app/src/google/java/com/geeksville/mesh/android/prefs/GoogleMapsPrefs.kt b/core/prefs/src/google/kotlin/org/meshtastic/core/prefs/map/GoogleMapsPrefs.kt
similarity index 77%
rename from app/src/google/java/com/geeksville/mesh/android/prefs/GoogleMapsPrefs.kt
rename to core/prefs/src/google/kotlin/org/meshtastic/core/prefs/map/GoogleMapsPrefs.kt
index bf39bc344..725f2b59f 100644
--- a/app/src/google/java/com/geeksville/mesh/android/prefs/GoogleMapsPrefs.kt
+++ b/core/prefs/src/google/kotlin/org/meshtastic/core/prefs/map/GoogleMapsPrefs.kt
@@ -15,10 +15,15 @@
* along with this program. If not, see .
*/
-package com.geeksville.mesh.android.prefs
+package org.meshtastic.core.prefs.map
import android.content.SharedPreferences
import com.google.maps.android.compose.MapType
+import org.meshtastic.core.prefs.NullableStringPrefDelegate
+import org.meshtastic.core.prefs.StringSetPrefDelegate
+import org.meshtastic.core.prefs.di.GoogleMapsSharedPreferences
+import javax.inject.Inject
+import javax.inject.Singleton
/** Interface for prefs specific to Google Maps. For general map prefs, see MapPrefs. */
interface GoogleMapsPrefs {
@@ -27,7 +32,8 @@ interface GoogleMapsPrefs {
var hiddenLayerUrls: Set
}
-class GoogleMapsPrefsImpl(prefs: SharedPreferences) : GoogleMapsPrefs {
+@Singleton
+class GoogleMapsPrefsImpl @Inject constructor(@GoogleMapsSharedPreferences prefs: SharedPreferences) : GoogleMapsPrefs {
override var selectedGoogleMapType: String? by
NullableStringPrefDelegate(prefs, "selected_google_map_type", MapType.NORMAL.name)
override var selectedCustomTileUrl: String? by NullableStringPrefDelegate(prefs, "selected_custom_tile_url", null)
diff --git a/app/src/main/java/com/geeksville/mesh/android/prefs/NullableStringPrefDelegate.kt b/core/prefs/src/main/kotlin/org/meshtastic/core/prefs/NullableStringPrefDelegate.kt
similarity index 95%
rename from app/src/main/java/com/geeksville/mesh/android/prefs/NullableStringPrefDelegate.kt
rename to core/prefs/src/main/kotlin/org/meshtastic/core/prefs/NullableStringPrefDelegate.kt
index 9d1755b0b..f8fbd059f 100644
--- a/app/src/main/java/com/geeksville/mesh/android/prefs/NullableStringPrefDelegate.kt
+++ b/core/prefs/src/main/kotlin/org/meshtastic/core/prefs/NullableStringPrefDelegate.kt
@@ -15,7 +15,7 @@
* along with this program. If not, see .
*/
-package com.geeksville.mesh.android.prefs
+package org.meshtastic.core.prefs
import android.content.SharedPreferences
import androidx.core.content.edit
@@ -29,7 +29,7 @@ import kotlin.reflect.KProperty
* @param key The key used to store and retrieve the value.
* @param defaultValue The default value to return if no value is found.
*/
-class NullableStringPrefDelegate(
+internal class NullableStringPrefDelegate(
private val prefs: SharedPreferences,
private val key: String,
private val defaultValue: String?,
diff --git a/app/src/main/java/com/geeksville/mesh/android/prefs/PrefDelegate.kt b/core/prefs/src/main/kotlin/org/meshtastic/core/prefs/PrefDelegate.kt
similarity index 91%
rename from app/src/main/java/com/geeksville/mesh/android/prefs/PrefDelegate.kt
rename to core/prefs/src/main/kotlin/org/meshtastic/core/prefs/PrefDelegate.kt
index 22948a914..28ce21b65 100644
--- a/app/src/main/java/com/geeksville/mesh/android/prefs/PrefDelegate.kt
+++ b/core/prefs/src/main/kotlin/org/meshtastic/core/prefs/PrefDelegate.kt
@@ -15,7 +15,7 @@
* along with this program. If not, see .
*/
-package com.geeksville.mesh.android.prefs
+package org.meshtastic.core.prefs
import android.content.SharedPreferences
import androidx.core.content.edit
@@ -30,8 +30,11 @@ import kotlin.reflect.KProperty
* @param defaultValue The default value to return if no value is found.
* @throws IllegalArgumentException if the type is not supported.
*/
-class PrefDelegate(private val prefs: SharedPreferences, private val key: String, private val defaultValue: T) :
- ReadWriteProperty {
+internal class PrefDelegate(
+ private val prefs: SharedPreferences,
+ private val key: String,
+ private val defaultValue: T,
+) : ReadWriteProperty {
@Suppress("UNCHECKED_CAST")
override fun getValue(thisRef: Any?, property: KProperty<*>): T = when (defaultValue) {
diff --git a/app/src/main/java/com/geeksville/mesh/android/prefs/StringSetPrefDelegate.kt b/core/prefs/src/main/kotlin/org/meshtastic/core/prefs/StringSetPrefDelegate.kt
similarity index 94%
rename from app/src/main/java/com/geeksville/mesh/android/prefs/StringSetPrefDelegate.kt
rename to core/prefs/src/main/kotlin/org/meshtastic/core/prefs/StringSetPrefDelegate.kt
index 714b4936b..4cae1b099 100644
--- a/app/src/main/java/com/geeksville/mesh/android/prefs/StringSetPrefDelegate.kt
+++ b/core/prefs/src/main/kotlin/org/meshtastic/core/prefs/StringSetPrefDelegate.kt
@@ -15,14 +15,14 @@
* along with this program. If not, see .
*/
-package com.geeksville.mesh.android.prefs
+package org.meshtastic.core.prefs
import android.content.SharedPreferences
import androidx.core.content.edit
import kotlin.properties.ReadWriteProperty
import kotlin.reflect.KProperty
-class StringSetPrefDelegate(
+internal class StringSetPrefDelegate(
private val prefs: SharedPreferences,
private val key: String,
private val defaultValue: Set,
diff --git a/app/src/main/java/com/geeksville/mesh/android/prefs/AnalyticsPrefs.kt b/core/prefs/src/main/kotlin/org/meshtastic/core/prefs/analytics/AnalyticsPrefs.kt
similarity index 70%
rename from app/src/main/java/com/geeksville/mesh/android/prefs/AnalyticsPrefs.kt
rename to core/prefs/src/main/kotlin/org/meshtastic/core/prefs/analytics/AnalyticsPrefs.kt
index 445c66cfc..89ab8b721 100644
--- a/app/src/main/java/com/geeksville/mesh/android/prefs/AnalyticsPrefs.kt
+++ b/core/prefs/src/main/kotlin/org/meshtastic/core/prefs/analytics/AnalyticsPrefs.kt
@@ -15,10 +15,16 @@
* along with this program. If not, see .
*/
-package com.geeksville.mesh.android.prefs
+package org.meshtastic.core.prefs.analytics
import android.content.SharedPreferences
+import org.meshtastic.core.prefs.NullableStringPrefDelegate
+import org.meshtastic.core.prefs.PrefDelegate
+import org.meshtastic.core.prefs.di.AnalyticsSharedPreferences
+import org.meshtastic.core.prefs.di.AppSharedPreferences
import java.util.UUID
+import javax.inject.Inject
+import javax.inject.Singleton
interface AnalyticsPrefs {
var analyticsAllowed: Boolean
@@ -26,7 +32,13 @@ interface AnalyticsPrefs {
}
// Having an additional app prefs store is maintaining the existing behavior.
-class AnalyticsPrefsImpl(analyticsPrefs: SharedPreferences, appPrefs: SharedPreferences) : AnalyticsPrefs {
+@Singleton
+class AnalyticsPrefsImpl
+@Inject
+constructor(
+ @AnalyticsSharedPreferences analyticsPrefs: SharedPreferences,
+ @AppSharedPreferences appPrefs: SharedPreferences,
+) : AnalyticsPrefs {
override var analyticsAllowed: Boolean by PrefDelegate(analyticsPrefs, "allowed", true)
private var _installId: String? by NullableStringPrefDelegate(appPrefs, "appPrefs_install_id", null)
diff --git a/core/prefs/src/main/kotlin/org/meshtastic/core/prefs/di/PrefsModule.kt b/core/prefs/src/main/kotlin/org/meshtastic/core/prefs/di/PrefsModule.kt
new file mode 100644
index 000000000..6aadabaea
--- /dev/null
+++ b/core/prefs/src/main/kotlin/org/meshtastic/core/prefs/di/PrefsModule.kt
@@ -0,0 +1,163 @@
+/*
+ * 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 .
+ */
+
+package org.meshtastic.core.prefs.di
+
+import android.content.Context
+import android.content.SharedPreferences
+import dagger.Binds
+import dagger.Module
+import dagger.Provides
+import dagger.hilt.InstallIn
+import dagger.hilt.android.qualifiers.ApplicationContext
+import dagger.hilt.components.SingletonComponent
+import org.meshtastic.core.prefs.analytics.AnalyticsPrefs
+import org.meshtastic.core.prefs.analytics.AnalyticsPrefsImpl
+import org.meshtastic.core.prefs.emoji.CustomEmojiPrefs
+import org.meshtastic.core.prefs.emoji.CustomEmojiPrefsImpl
+import org.meshtastic.core.prefs.map.MapConsentPrefs
+import org.meshtastic.core.prefs.map.MapConsentPrefsImpl
+import org.meshtastic.core.prefs.map.MapPrefs
+import org.meshtastic.core.prefs.map.MapPrefsImpl
+import org.meshtastic.core.prefs.map.MapTileProviderPrefs
+import org.meshtastic.core.prefs.map.MapTileProviderPrefsImpl
+import org.meshtastic.core.prefs.mesh.MeshPrefs
+import org.meshtastic.core.prefs.mesh.MeshPrefsImpl
+import org.meshtastic.core.prefs.radio.RadioPrefs
+import org.meshtastic.core.prefs.radio.RadioPrefsImpl
+import org.meshtastic.core.prefs.ui.UiPrefs
+import org.meshtastic.core.prefs.ui.UiPrefsImpl
+import javax.inject.Qualifier
+import javax.inject.Singleton
+
+// These pref store qualifiers are internal to prevent prefs stores from being injected directly.
+// Consuming code should always inject one of the prefs repositories.
+
+@Qualifier
+@Retention(AnnotationRetention.BINARY)
+internal annotation class AnalyticsSharedPreferences
+
+@Qualifier
+@Retention(AnnotationRetention.BINARY)
+internal annotation class AppSharedPreferences
+
+@Qualifier
+@Retention(AnnotationRetention.BINARY)
+internal annotation class CustomEmojiSharedPreferences
+
+@Qualifier
+@Retention(AnnotationRetention.BINARY)
+internal annotation class MapSharedPreferences
+
+@Qualifier
+@Retention(AnnotationRetention.BINARY)
+internal annotation class MapConsentSharedPreferences
+
+@Qualifier
+@Retention(AnnotationRetention.BINARY)
+internal annotation class MapTileProviderSharedPreferences
+
+@Qualifier
+@Retention(AnnotationRetention.BINARY)
+internal annotation class MeshSharedPreferences
+
+@Qualifier
+@Retention(AnnotationRetention.BINARY)
+internal annotation class RadioSharedPreferences
+
+@Qualifier
+@Retention(AnnotationRetention.BINARY)
+internal annotation class UiSharedPreferences
+
+@Suppress("TooManyFunctions")
+@InstallIn(SingletonComponent::class)
+@Module
+interface PrefsModule {
+
+ @Binds fun bindAnalyticsPrefs(analyticsPrefsImpl: AnalyticsPrefsImpl): AnalyticsPrefs
+
+ @Binds fun bindCustomEmojiPrefs(customEmojiPrefsImpl: CustomEmojiPrefsImpl): CustomEmojiPrefs
+
+ @Binds fun bindMapConsentPrefs(mapConsentPrefsImpl: MapConsentPrefsImpl): MapConsentPrefs
+
+ @Binds fun bindMapPrefs(mapPrefsImpl: MapPrefsImpl): MapPrefs
+
+ @Binds fun bindMapTileProviderPrefs(mapTileProviderPrefsImpl: MapTileProviderPrefsImpl): MapTileProviderPrefs
+
+ @Binds fun bindMeshPrefs(meshPrefsImpl: MeshPrefsImpl): MeshPrefs
+
+ @Binds fun bindRadioPrefs(radioPrefsImpl: RadioPrefsImpl): RadioPrefs
+
+ @Binds fun bindUiPrefs(uiPrefsImpl: UiPrefsImpl): UiPrefs
+
+ companion object {
+
+ @Provides
+ @Singleton
+ @AnalyticsSharedPreferences
+ 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
+ fun provideMapConsentSharedPreferences(@ApplicationContext context: Context): SharedPreferences =
+ context.getSharedPreferences("map_consent_preferences", Context.MODE_PRIVATE)
+
+ @Provides
+ @Singleton
+ @MapTileProviderSharedPreferences
+ fun provideMapTileProviderSharedPreferences(@ApplicationContext context: Context): SharedPreferences =
+ context.getSharedPreferences("map_tile_provider_prefs", Context.MODE_PRIVATE)
+
+ @Provides
+ @Singleton
+ @MeshSharedPreferences
+ fun provideMeshSharedPreferences(@ApplicationContext context: Context): SharedPreferences =
+ context.getSharedPreferences("mesh-prefs", Context.MODE_PRIVATE)
+
+ @Provides
+ @Singleton
+ @RadioSharedPreferences
+ fun provideRadioSharedPreferences(@ApplicationContext context: Context): SharedPreferences =
+ context.getSharedPreferences("radio-prefs", Context.MODE_PRIVATE)
+
+ @Provides
+ @Singleton
+ @UiSharedPreferences
+ fun provideUiSharedPreferences(@ApplicationContext context: Context): SharedPreferences =
+ context.getSharedPreferences("ui-prefs", Context.MODE_PRIVATE)
+ }
+}
diff --git a/app/src/main/java/com/geeksville/mesh/android/prefs/CustomEmojiPrefs.kt b/core/prefs/src/main/kotlin/org/meshtastic/core/prefs/emoji/CustomEmojiPrefs.kt
similarity index 72%
rename from app/src/main/java/com/geeksville/mesh/android/prefs/CustomEmojiPrefs.kt
rename to core/prefs/src/main/kotlin/org/meshtastic/core/prefs/emoji/CustomEmojiPrefs.kt
index eb9f51eab..986265590 100644
--- a/app/src/main/java/com/geeksville/mesh/android/prefs/CustomEmojiPrefs.kt
+++ b/core/prefs/src/main/kotlin/org/meshtastic/core/prefs/emoji/CustomEmojiPrefs.kt
@@ -15,14 +15,20 @@
* along with this program. If not, see .
*/
-package com.geeksville.mesh.android.prefs
+package org.meshtastic.core.prefs.emoji
import android.content.SharedPreferences
+import org.meshtastic.core.prefs.NullableStringPrefDelegate
+import org.meshtastic.core.prefs.di.CustomEmojiSharedPreferences
+import javax.inject.Inject
+import javax.inject.Singleton
interface CustomEmojiPrefs {
var customEmojiFrequency: String?
}
-class CustomEmojiPrefsImpl(prefs: SharedPreferences) : CustomEmojiPrefs {
+@Singleton
+class CustomEmojiPrefsImpl @Inject constructor(@CustomEmojiSharedPreferences prefs: SharedPreferences) :
+ CustomEmojiPrefs {
override var customEmojiFrequency: String? by NullableStringPrefDelegate(prefs, "pref_key_custom_emoji_freq", null)
}
diff --git a/app/src/main/java/com/geeksville/mesh/android/prefs/MapConsentPrefs.kt b/core/prefs/src/main/kotlin/org/meshtastic/core/prefs/map/MapConsentPrefs.kt
similarity index 79%
rename from app/src/main/java/com/geeksville/mesh/android/prefs/MapConsentPrefs.kt
rename to core/prefs/src/main/kotlin/org/meshtastic/core/prefs/map/MapConsentPrefs.kt
index b265f8ff9..ae1a76890 100644
--- a/app/src/main/java/com/geeksville/mesh/android/prefs/MapConsentPrefs.kt
+++ b/core/prefs/src/main/kotlin/org/meshtastic/core/prefs/map/MapConsentPrefs.kt
@@ -15,10 +15,13 @@
* along with this program. If not, see .
*/
-package com.geeksville.mesh.android.prefs
+package org.meshtastic.core.prefs.map
import android.content.SharedPreferences
import androidx.core.content.edit
+import org.meshtastic.core.prefs.di.MapConsentSharedPreferences
+import javax.inject.Inject
+import javax.inject.Singleton
interface MapConsentPrefs {
fun shouldReportLocation(nodeNum: Int?): Boolean
@@ -26,7 +29,9 @@ interface MapConsentPrefs {
fun setShouldReportLocation(nodeNum: Int?, value: Boolean)
}
-class MapConsentPrefsImpl(private val prefs: SharedPreferences) : MapConsentPrefs {
+@Singleton
+class MapConsentPrefsImpl @Inject constructor(@MapConsentSharedPreferences private val prefs: SharedPreferences) :
+ MapConsentPrefs {
override fun shouldReportLocation(nodeNum: Int?) = prefs.getBoolean(nodeNum.toString(), false)
override fun setShouldReportLocation(nodeNum: Int?, value: Boolean) {
diff --git a/app/src/main/java/com/geeksville/mesh/android/prefs/MapPrefs.kt b/core/prefs/src/main/kotlin/org/meshtastic/core/prefs/map/MapPrefs.kt
similarity index 81%
rename from app/src/main/java/com/geeksville/mesh/android/prefs/MapPrefs.kt
rename to core/prefs/src/main/kotlin/org/meshtastic/core/prefs/map/MapPrefs.kt
index f095639bd..ac2f1d7ce 100644
--- a/app/src/main/java/com/geeksville/mesh/android/prefs/MapPrefs.kt
+++ b/core/prefs/src/main/kotlin/org/meshtastic/core/prefs/map/MapPrefs.kt
@@ -15,9 +15,13 @@
* along with this program. If not, see .
*/
-package com.geeksville.mesh.android.prefs
+package org.meshtastic.core.prefs.map
import android.content.SharedPreferences
+import org.meshtastic.core.prefs.PrefDelegate
+import org.meshtastic.core.prefs.di.MapSharedPreferences
+import javax.inject.Inject
+import javax.inject.Singleton
/** Interface for general map prefs. For Google-specific prefs, see GoogleMapsPrefs. */
interface MapPrefs {
@@ -27,7 +31,8 @@ interface MapPrefs {
var showPrecisionCircleOnMap: Boolean
}
-class MapPrefsImpl(prefs: SharedPreferences) : MapPrefs {
+@Singleton
+class MapPrefsImpl @Inject constructor(@MapSharedPreferences 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)
diff --git a/app/src/main/java/com/geeksville/mesh/android/prefs/MapTileProviderPrefs.kt b/core/prefs/src/main/kotlin/org/meshtastic/core/prefs/map/MapTileProviderPrefs.kt
similarity index 71%
rename from app/src/main/java/com/geeksville/mesh/android/prefs/MapTileProviderPrefs.kt
rename to core/prefs/src/main/kotlin/org/meshtastic/core/prefs/map/MapTileProviderPrefs.kt
index a97f5a1f6..9c86a4b13 100644
--- a/app/src/main/java/com/geeksville/mesh/android/prefs/MapTileProviderPrefs.kt
+++ b/core/prefs/src/main/kotlin/org/meshtastic/core/prefs/map/MapTileProviderPrefs.kt
@@ -15,14 +15,20 @@
* along with this program. If not, see .
*/
-package com.geeksville.mesh.android.prefs
+package org.meshtastic.core.prefs.map
import android.content.SharedPreferences
+import org.meshtastic.core.prefs.NullableStringPrefDelegate
+import org.meshtastic.core.prefs.di.MapTileProviderSharedPreferences
+import javax.inject.Inject
+import javax.inject.Singleton
interface MapTileProviderPrefs {
var customTileProviders: String?
}
-class MapTileProviderPrefsImpl(prefs: SharedPreferences) : MapTileProviderPrefs {
+@Singleton
+class MapTileProviderPrefsImpl @Inject constructor(@MapTileProviderSharedPreferences prefs: SharedPreferences) :
+ MapTileProviderPrefs {
override var customTileProviders: String? by NullableStringPrefDelegate(prefs, "custom_tile_providers", null)
}
diff --git a/app/src/main/java/com/geeksville/mesh/android/prefs/MeshPrefs.kt b/core/prefs/src/main/kotlin/org/meshtastic/core/prefs/mesh/MeshPrefs.kt
similarity index 80%
rename from app/src/main/java/com/geeksville/mesh/android/prefs/MeshPrefs.kt
rename to core/prefs/src/main/kotlin/org/meshtastic/core/prefs/mesh/MeshPrefs.kt
index 335000f1a..a268bd6bd 100644
--- a/app/src/main/java/com/geeksville/mesh/android/prefs/MeshPrefs.kt
+++ b/core/prefs/src/main/kotlin/org/meshtastic/core/prefs/mesh/MeshPrefs.kt
@@ -15,10 +15,14 @@
* along with this program. If not, see .
*/
-package com.geeksville.mesh.android.prefs
+package org.meshtastic.core.prefs.mesh
import android.content.SharedPreferences
import androidx.core.content.edit
+import org.meshtastic.core.prefs.NullableStringPrefDelegate
+import org.meshtastic.core.prefs.di.MeshSharedPreferences
+import javax.inject.Inject
+import javax.inject.Singleton
interface MeshPrefs {
var deviceAddress: String?
@@ -28,7 +32,8 @@ interface MeshPrefs {
fun setShouldProvideNodeLocation(nodeNum: Int?, value: Boolean)
}
-class MeshPrefsImpl(private val prefs: SharedPreferences) : MeshPrefs {
+@Singleton
+class MeshPrefsImpl @Inject constructor(@MeshSharedPreferences private val prefs: SharedPreferences) : MeshPrefs {
override var deviceAddress: String? by NullableStringPrefDelegate(prefs, "device_address", null)
override fun shouldProvideNodeLocation(nodeNum: Int?): Boolean =
diff --git a/app/src/main/java/com/geeksville/mesh/android/prefs/RadioPrefs.kt b/core/prefs/src/main/kotlin/org/meshtastic/core/prefs/radio/RadioPrefs.kt
similarity index 72%
rename from app/src/main/java/com/geeksville/mesh/android/prefs/RadioPrefs.kt
rename to core/prefs/src/main/kotlin/org/meshtastic/core/prefs/radio/RadioPrefs.kt
index f53beb804..45d986c3c 100644
--- a/app/src/main/java/com/geeksville/mesh/android/prefs/RadioPrefs.kt
+++ b/core/prefs/src/main/kotlin/org/meshtastic/core/prefs/radio/RadioPrefs.kt
@@ -15,14 +15,19 @@
* along with this program. If not, see .
*/
-package com.geeksville.mesh.android.prefs
+package org.meshtastic.core.prefs.radio
import android.content.SharedPreferences
+import org.meshtastic.core.prefs.NullableStringPrefDelegate
+import org.meshtastic.core.prefs.di.RadioSharedPreferences
+import javax.inject.Inject
+import javax.inject.Singleton
interface RadioPrefs {
var devAddr: String?
}
-class RadioPrefsImpl(prefs: SharedPreferences) : RadioPrefs {
+@Singleton
+class RadioPrefsImpl @Inject constructor(@RadioSharedPreferences prefs: SharedPreferences) : RadioPrefs {
override var devAddr: String? by NullableStringPrefDelegate(prefs, "devAddr2", null)
}
diff --git a/app/src/main/java/com/geeksville/mesh/android/prefs/UiPrefs.kt b/core/prefs/src/main/kotlin/org/meshtastic/core/prefs/ui/UiPrefs.kt
similarity index 92%
rename from app/src/main/java/com/geeksville/mesh/android/prefs/UiPrefs.kt
rename to core/prefs/src/main/kotlin/org/meshtastic/core/prefs/ui/UiPrefs.kt
index a79941c29..5a2ac697a 100644
--- a/app/src/main/java/com/geeksville/mesh/android/prefs/UiPrefs.kt
+++ b/core/prefs/src/main/kotlin/org/meshtastic/core/prefs/ui/UiPrefs.kt
@@ -15,17 +15,20 @@
* along with this program. If not, see .
*/
-package com.geeksville.mesh.android.prefs
+package org.meshtastic.core.prefs.ui
import android.content.SharedPreferences
import androidx.appcompat.app.AppCompatDelegate
import androidx.core.content.edit
-import com.geeksville.mesh.model.NodeSortOption
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.update
+import org.meshtastic.core.prefs.PrefDelegate
+import org.meshtastic.core.prefs.di.UiSharedPreferences
import java.util.concurrent.ConcurrentHashMap
+import javax.inject.Inject
+import javax.inject.Singleton
interface UiPrefs {
var theme: Int
@@ -49,7 +52,8 @@ interface UiPrefs {
const val KEY_THEME = "theme"
const val KEY_APP_INTRO_COMPLETED = "app_intro_completed"
-class UiPrefsImpl(private val prefs: SharedPreferences) : UiPrefs {
+@Singleton
+class UiPrefsImpl @Inject constructor(@UiSharedPreferences private val prefs: SharedPreferences) : UiPrefs {
override var theme: Int by PrefDelegate(prefs, KEY_THEME, AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM)
private var _themeFlow = MutableStateFlow(theme)
@@ -83,7 +87,7 @@ class UiPrefsImpl(private val prefs: SharedPreferences) : UiPrefs {
}
override var hasShownNotPairedWarning: Boolean by PrefDelegate(prefs, "has_shown_not_paired_warning", false)
- override var nodeSortOption: Int by PrefDelegate(prefs, "node-sort-option", NodeSortOption.VIA_FAVORITE.ordinal)
+ override var nodeSortOption: Int by PrefDelegate(prefs, "node-sort-option", -1)
override var includeUnknown: Boolean by PrefDelegate(prefs, "include-unknown", false)
override var showDetails: Boolean by PrefDelegate(prefs, "show-details", false)
override var onlyOnline: Boolean by PrefDelegate(prefs, "only-online", false)