mirror of
https://github.com/Novaloop-AG/element-x-android.git
synced 2026-11-02 12:07:28 +00:00
Add persistent account provider history to app preferences
This commit is contained in:
+27
@@ -8,6 +8,7 @@
|
||||
|
||||
package io.element.android.libraries.preferences.impl.store
|
||||
|
||||
import androidx.datastore.preferences.core.Preferences
|
||||
import androidx.datastore.preferences.core.booleanPreferencesKey
|
||||
import androidx.datastore.preferences.core.edit
|
||||
import androidx.datastore.preferences.core.intPreferencesKey
|
||||
@@ -36,6 +37,7 @@ private val timelineMediaPreviewValueKey = stringPreferencesKey("timelineMediaPr
|
||||
private val liveLocationMinimumDistanceUpdateKey = intPreferencesKey("liveLocationMinimumDistanceUpdate")
|
||||
private val logLevelKey = stringPreferencesKey("logLevel")
|
||||
private val traceLogPacksKey = stringPreferencesKey("traceLogPacks")
|
||||
private val homeserverHistoryKey = stringPreferencesKey("homeserverHistory")
|
||||
private val messageSoundUriKey = stringPreferencesKey("notificationMessageSoundUri")
|
||||
private val messageSoundChannelVersionKey = intPreferencesKey("notificationMessageSoundChannelVersion")
|
||||
private val messageSoundDisplayNameKey = stringPreferencesKey("notificationMessageSoundDisplayName")
|
||||
@@ -43,6 +45,10 @@ private val callRingtoneUriKey = stringPreferencesKey("notificationCallRingtoneU
|
||||
private val callRingtoneChannelVersionKey = intPreferencesKey("notificationCallRingtoneChannelVersion")
|
||||
private val callRingtoneDisplayNameKey = stringPreferencesKey("notificationCallRingtoneDisplayName")
|
||||
|
||||
// URLs never contain a newline, so it is a safe delimiter to persist an ordered list in a single String.
|
||||
private const val HOMESERVER_HISTORY_DELIMITER = "\n"
|
||||
private const val MAX_HOMESERVER_HISTORY_SIZE = 10
|
||||
|
||||
@ContributesBinding(AppScope::class)
|
||||
class DefaultAppPreferencesStore(
|
||||
private val buildMeta: BuildMeta,
|
||||
@@ -168,6 +174,20 @@ class DefaultAppPreferencesStore(
|
||||
}
|
||||
}
|
||||
|
||||
override fun getHomeserverHistoryFlow(): Flow<List<String>> {
|
||||
return store.data.map { prefs -> prefs.readHomeserverHistory() }
|
||||
}
|
||||
|
||||
override suspend fun addHomeserverToHistory(url: String) {
|
||||
val normalized = url.trim().lowercase()
|
||||
if (normalized.isEmpty()) return
|
||||
store.edit { prefs ->
|
||||
val updated = (listOf(normalized) + prefs.readHomeserverHistory().filter { it != normalized })
|
||||
.take(MAX_HOMESERVER_HISTORY_SIZE)
|
||||
prefs[homeserverHistoryKey] = updated.joinToString(HOMESERVER_HISTORY_DELIMITER)
|
||||
}
|
||||
}
|
||||
|
||||
override fun getMessageSoundFlow(): Flow<NotificationSound> {
|
||||
return store.data.map { prefs -> NotificationSound.fromStored(prefs[messageSoundUriKey]) }
|
||||
}
|
||||
@@ -242,6 +262,13 @@ class DefaultAppPreferencesStore(
|
||||
}
|
||||
}
|
||||
|
||||
private fun Preferences.readHomeserverHistory(): List<String> {
|
||||
return this[homeserverHistoryKey]
|
||||
?.split(HOMESERVER_HISTORY_DELIMITER)
|
||||
?.filter { it.isNotEmpty() }
|
||||
?: emptyList()
|
||||
}
|
||||
|
||||
private fun BuildMeta.defaultLogLevel(): LogLevel {
|
||||
return when (buildType) {
|
||||
BuildType.DEBUG -> LogLevel.TRACE
|
||||
|
||||
+70
@@ -54,4 +54,74 @@ class DefaultAppPreferencesStoreTest {
|
||||
|
||||
assertThat(store.getLiveLocationMinimumDistanceInMetersUpdateFlow().first()).isEqualTo(25)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `homeserver history is empty by default`() = runTest {
|
||||
val store = createStore()
|
||||
assertThat(store.getHomeserverHistoryFlow().first()).isEmpty()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `adding homeservers keeps the most recent first`() = runTest {
|
||||
val store = createStore()
|
||||
|
||||
store.addHomeserverToHistory("https://matrix.org")
|
||||
store.addHomeserverToHistory("https://example.com")
|
||||
|
||||
assertThat(store.getHomeserverHistoryFlow().first())
|
||||
.containsExactly("https://example.com", "https://matrix.org")
|
||||
.inOrder()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `adding an existing homeserver moves it to the front without duplicating`() = runTest {
|
||||
val store = createStore()
|
||||
|
||||
store.addHomeserverToHistory("https://matrix.org")
|
||||
store.addHomeserverToHistory("https://example.com")
|
||||
store.addHomeserverToHistory("https://matrix.org")
|
||||
|
||||
assertThat(store.getHomeserverHistoryFlow().first())
|
||||
.containsExactly("https://matrix.org", "https://example.com")
|
||||
.inOrder()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `homeservers are normalised and deduplicated case-insensitively`() = runTest {
|
||||
val store = createStore()
|
||||
|
||||
store.addHomeserverToHistory(" HTTPS://Matrix.ORG ")
|
||||
store.addHomeserverToHistory("https://matrix.org")
|
||||
|
||||
assertThat(store.getHomeserverHistoryFlow().first())
|
||||
.containsExactly("https://matrix.org")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `blank homeservers are ignored`() = runTest {
|
||||
val store = createStore()
|
||||
|
||||
store.addHomeserverToHistory(" ")
|
||||
|
||||
assertThat(store.getHomeserverHistoryFlow().first()).isEmpty()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `homeserver history is capped to the most recent entries`() = runTest {
|
||||
val store = createStore()
|
||||
|
||||
repeat(15) { index ->
|
||||
store.addHomeserverToHistory("https://server$index.org")
|
||||
}
|
||||
|
||||
val history = store.getHomeserverHistoryFlow().first()
|
||||
assertThat(history).hasSize(10)
|
||||
assertThat(history.first()).isEqualTo("https://server14.org")
|
||||
assertThat(history.last()).isEqualTo("https://server5.org")
|
||||
}
|
||||
|
||||
private fun createStore() = DefaultAppPreferencesStore(
|
||||
buildMeta = buildMeta,
|
||||
preferenceDataStoreFactory = FakePreferenceDataStoreFactory(),
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user