mirror of
https://github.com/d4rken-org/capod.git
synced 2026-09-14 18:26:11 -04:00
refactor: Move nudge persistence into GeneralSettings
Consolidate the nudge availability DataStoreValue with the rest of the persisted settings instead of carrying it in a separate Hilt module + DataStore file. Matches the existing convention where compat-style flags (offloaded filtering, indirect callbacks, etc.) live alongside theme/notification settings. NudgeCapabilityStore keeps the verdict-mapping behavior; only the source of the persisted value changes.
This commit is contained in:
committed by
Matthias Urhahn
parent
0e6848d886
commit
83ef111599
@@ -1,35 +0,0 @@
|
||||
package eu.darken.capod.common.bluetooth
|
||||
|
||||
import android.content.Context
|
||||
import androidx.datastore.core.DataStore
|
||||
import androidx.datastore.preferences.core.Preferences
|
||||
import androidx.datastore.preferences.preferencesDataStore
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.hilt.InstallIn
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import dagger.hilt.components.SingletonComponent
|
||||
import eu.darken.capod.common.datastore.DataStoreValue
|
||||
import eu.darken.capod.common.datastore.createValue
|
||||
import eu.darken.capod.common.serialization.SerializationCapod
|
||||
import kotlinx.serialization.json.Json
|
||||
import javax.inject.Singleton
|
||||
|
||||
private val Context.bluetoothDataStore: DataStore<Preferences> by preferencesDataStore(name = "bluetooth_state")
|
||||
|
||||
@InstallIn(SingletonComponent::class)
|
||||
@Module
|
||||
object BluetoothPersistenceModule {
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideNudgeAvailability(
|
||||
@ApplicationContext context: Context,
|
||||
@SerializationCapod json: Json,
|
||||
): DataStoreValue<NudgeAvailability> = context.bluetoothDataStore.createValue(
|
||||
key = "core.bluetooth.nudge.availability",
|
||||
defaultValue = NudgeAvailability.UNKNOWN,
|
||||
json = json,
|
||||
onErrorFallbackToDefault = true,
|
||||
)
|
||||
}
|
||||
@@ -2,12 +2,12 @@ package eu.darken.capod.common.bluetooth
|
||||
|
||||
import eu.darken.capod.common.coroutine.AppScope
|
||||
import eu.darken.capod.common.coroutine.DispatcherProvider
|
||||
import eu.darken.capod.common.datastore.DataStoreValue
|
||||
import eu.darken.capod.common.datastore.value
|
||||
import eu.darken.capod.common.datastore.valueBlocking
|
||||
import eu.darken.capod.common.debug.logging.Logging.Priority.INFO
|
||||
import eu.darken.capod.common.debug.logging.log
|
||||
import eu.darken.capod.common.debug.logging.logTag
|
||||
import eu.darken.capod.main.core.GeneralSettings
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.flow.SharingStarted
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
@@ -19,11 +19,13 @@ import javax.inject.Singleton
|
||||
|
||||
@Singleton
|
||||
class NudgeCapabilityStore @Inject constructor(
|
||||
private val persistedValue: DataStoreValue<NudgeAvailability>,
|
||||
generalSettings: GeneralSettings,
|
||||
@AppScope private val appScope: CoroutineScope,
|
||||
private val dispatcherProvider: DispatcherProvider,
|
||||
) {
|
||||
|
||||
private val persistedValue = generalSettings.nudgeAvailability
|
||||
|
||||
// Resolve the persisted value synchronously at construction so consumers that read
|
||||
// `availability.value` (resolver, AutoConnect precondition, UI state) never see the
|
||||
// synthetic UNKNOWN seed before the first DataStore emission arrives. On a known-broken
|
||||
|
||||
@@ -9,6 +9,7 @@ import androidx.datastore.preferences.preferencesDataStore
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import eu.darken.capod.common.BuildConfigWrap
|
||||
import eu.darken.capod.common.bluetooth.BluetoothAddress
|
||||
import eu.darken.capod.common.bluetooth.NudgeAvailability
|
||||
import eu.darken.capod.common.datastore.createValue
|
||||
import eu.darken.capod.common.serialization.ByteArrayBase64Serializer
|
||||
import eu.darken.capod.common.serialization.SerializationCapod
|
||||
@@ -72,6 +73,12 @@ class GeneralSettings @Inject constructor(
|
||||
val isOffloadedBatchingDisabled = dataStore.createValue("core.compat.offloaded.batching.disabled", false)
|
||||
val useIndirectScanResultCallback = dataStore.createValue("core.compat.indirectcallback.enabled", false)
|
||||
|
||||
/** Runtime-detected verdict for whether `BluetoothHeadset.connect()` reflection works on this device. */
|
||||
val nudgeAvailability = dataStore.createValue(
|
||||
"core.bluetooth.nudge.availability", NudgeAvailability.UNKNOWN, json,
|
||||
onErrorFallbackToDefault = true,
|
||||
)
|
||||
|
||||
val isOnboardingDone = dataStore.createValue("core.onboarding.done", false)
|
||||
|
||||
val reactionsHintDismissed = dataStore.createValue("ui.hint.reactions_per_device.dismissed", false)
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
package eu.darken.capod.common.bluetooth
|
||||
|
||||
import eu.darken.capod.main.core.GeneralSettings
|
||||
import io.kotest.matchers.shouldBe
|
||||
import io.mockk.every
|
||||
import io.mockk.mockk
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.test.UnconfinedTestDispatcher
|
||||
import kotlinx.coroutines.test.resetMain
|
||||
@@ -18,11 +21,15 @@ class NudgeCapabilityStoreTest : BaseTest() {
|
||||
private val testDispatcher = UnconfinedTestDispatcher()
|
||||
|
||||
private lateinit var fakePersisted: FakeDataStoreValue<NudgeAvailability>
|
||||
private lateinit var generalSettings: GeneralSettings
|
||||
|
||||
@BeforeEach
|
||||
fun setup() {
|
||||
Dispatchers.setMain(testDispatcher)
|
||||
fakePersisted = FakeDataStoreValue(NudgeAvailability.UNKNOWN)
|
||||
generalSettings = mockk<GeneralSettings>().also {
|
||||
every { it.nudgeAvailability } returns fakePersisted.mock
|
||||
}
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
@@ -31,7 +38,7 @@ class NudgeCapabilityStoreTest : BaseTest() {
|
||||
}
|
||||
|
||||
private fun createStore() = NudgeCapabilityStore(
|
||||
persistedValue = fakePersisted.mock,
|
||||
generalSettings = generalSettings,
|
||||
appScope = kotlinx.coroutines.CoroutineScope(testDispatcher),
|
||||
dispatcherProvider = TestDispatcherProvider(testDispatcher),
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user