data: add CalendarPrefs (hidden calendar ids in DataStore)
This commit is contained in:
@@ -0,0 +1,44 @@
|
|||||||
|
package de.jeanlucmakiola.calendula.data.prefs
|
||||||
|
|
||||||
|
import androidx.datastore.core.DataStore
|
||||||
|
import androidx.datastore.preferences.core.Preferences
|
||||||
|
import androidx.datastore.preferences.core.edit
|
||||||
|
import androidx.datastore.preferences.core.stringPreferencesKey
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
import kotlinx.coroutines.flow.map
|
||||||
|
import javax.inject.Inject
|
||||||
|
import javax.inject.Singleton
|
||||||
|
|
||||||
|
/**
|
||||||
|
* App-side preference for "calendars the user has hidden in this app",
|
||||||
|
* separate from the system's per-calendar VISIBLE flag.
|
||||||
|
*
|
||||||
|
* Persisted as a comma-separated string of Long ids; non-numeric tokens are
|
||||||
|
* silently dropped (defensive — see CalendarPrefsTest).
|
||||||
|
*/
|
||||||
|
@Singleton
|
||||||
|
class CalendarPrefs @Inject constructor(
|
||||||
|
private val store: DataStore<Preferences>,
|
||||||
|
) {
|
||||||
|
|
||||||
|
val hiddenCalendarIds: Flow<Set<Long>> = store.data.map { prefs ->
|
||||||
|
prefs[HIDDEN_IDS_KEY].orEmpty()
|
||||||
|
.split(',')
|
||||||
|
.mapNotNull { it.trim().toLongOrNull() }
|
||||||
|
.toSet()
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun setHiddenCalendarIds(ids: Set<Long>) {
|
||||||
|
store.edit { prefs ->
|
||||||
|
if (ids.isEmpty()) {
|
||||||
|
prefs.remove(HIDDEN_IDS_KEY)
|
||||||
|
} else {
|
||||||
|
prefs[HIDDEN_IDS_KEY] = ids.sorted().joinToString(",")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
internal val HIDDEN_IDS_KEY = stringPreferencesKey("hidden_calendar_ids")
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
package de.jeanlucmakiola.calendula.data.prefs
|
||||||
|
|
||||||
|
import androidx.datastore.core.DataStore
|
||||||
|
import androidx.datastore.preferences.core.PreferenceDataStoreFactory
|
||||||
|
import androidx.datastore.preferences.core.Preferences
|
||||||
|
import com.google.common.truth.Truth.assertThat
|
||||||
|
import kotlinx.coroutines.flow.first
|
||||||
|
import kotlinx.coroutines.test.runTest
|
||||||
|
import org.junit.jupiter.api.Test
|
||||||
|
import org.junit.jupiter.api.io.TempDir
|
||||||
|
import java.nio.file.Path
|
||||||
|
|
||||||
|
class CalendarPrefsTest {
|
||||||
|
|
||||||
|
private fun newDataStore(tempDir: Path): DataStore<Preferences> =
|
||||||
|
PreferenceDataStoreFactory.create(
|
||||||
|
produceFile = { tempDir.resolve("test_prefs.preferences_pb").toFile() },
|
||||||
|
)
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `hiddenCalendarIds defaults to empty when unset`(@TempDir tempDir: Path) = runTest {
|
||||||
|
val prefs = CalendarPrefs(newDataStore(tempDir))
|
||||||
|
assertThat(prefs.hiddenCalendarIds.first()).isEmpty()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `setHiddenCalendarIds round-trips through DataStore`(@TempDir tempDir: Path) = runTest {
|
||||||
|
val store = newDataStore(tempDir)
|
||||||
|
val prefs = CalendarPrefs(store)
|
||||||
|
prefs.setHiddenCalendarIds(setOf(1L, 42L, 7L))
|
||||||
|
assertThat(prefs.hiddenCalendarIds.first()).isEqualTo(setOf(1L, 42L, 7L))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `setting empty set clears storage`(@TempDir tempDir: Path) = runTest {
|
||||||
|
val prefs = CalendarPrefs(newDataStore(tempDir))
|
||||||
|
prefs.setHiddenCalendarIds(setOf(1L))
|
||||||
|
prefs.setHiddenCalendarIds(emptySet())
|
||||||
|
assertThat(prefs.hiddenCalendarIds.first()).isEmpty()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `garbage stored string is parsed defensively`(@TempDir tempDir: Path) = runTest {
|
||||||
|
val store = newDataStore(tempDir)
|
||||||
|
val prefs = CalendarPrefs(store)
|
||||||
|
store.updateData { p ->
|
||||||
|
val mutable = p.toMutablePreferences()
|
||||||
|
mutable[CalendarPrefs.HIDDEN_IDS_KEY] = "1,abc,3"
|
||||||
|
mutable
|
||||||
|
}
|
||||||
|
assertThat(prefs.hiddenCalendarIds.first()).isEqualTo(setOf(1L, 3L))
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user