exposing option to enable/disable sending read receipts

Disabled by default
This commit is contained in:
Adam Brown 2022-10-08 11:35:14 +01:00
parent 0e4f6d6ac2
commit 990cb08347
21 changed files with 109 additions and 22 deletions

View File

@ -191,6 +191,7 @@ internal class FeatureModules internal constructor(
context, context,
base64, base64,
imageContentReader, imageContentReader,
storeModule.value.messageStore(),
) )
} }
val homeModule by unsafeLazy { HomeModule(storeModule.value, matrixModules.profile, matrixModules.sync, buildMeta) } val homeModule by unsafeLazy { HomeModule(storeModule.value, matrixModules.profile, matrixModules.sync, buildMeta) }
@ -206,6 +207,7 @@ internal class FeatureModules internal constructor(
coroutineDispatchers, coroutineDispatchers,
coreAndroidModule.themeStore(), coreAndroidModule.themeStore(),
storeModule.value.loggingStore(), storeModule.value.loggingStore(),
storeModule.value.messageStore(),
) )
} }
val profileModule by unsafeLazy { ProfileModule(matrixModules.profile, matrixModules.sync, matrixModules.room, trackingModule.errorTracker) } val profileModule by unsafeLazy { ProfileModule(matrixModules.profile, matrixModules.sync, matrixModules.room, trackingModule.errorTracker) }

View File

@ -25,4 +25,5 @@ dependencies {
implementation "com.squareup.sqldelight:coroutines-extensions:1.5.3" implementation "com.squareup.sqldelight:coroutines-extensions:1.5.3"
kotlinFixtures(it) kotlinFixtures(it)
} testImplementation(testFixtures(project(":core")))
testFixturesImplementation(testFixtures(project(":core")))}

View File

@ -5,8 +5,9 @@ import app.dapk.st.core.CoroutineDispatchers
import app.dapk.st.core.Preferences import app.dapk.st.core.Preferences
import app.dapk.st.core.extensions.ErrorTracker import app.dapk.st.core.extensions.ErrorTracker
import app.dapk.st.core.extensions.unsafeLazy import app.dapk.st.core.extensions.unsafeLazy
import app.dapk.st.domain.eventlog.EventLogPersistence import app.dapk.st.domain.application.eventlog.EventLogPersistence
import app.dapk.st.domain.eventlog.LoggingStore import app.dapk.st.domain.application.eventlog.LoggingStore
import app.dapk.st.domain.application.message.MessageOptionsStore
import app.dapk.st.domain.localecho.LocalEchoPersistence import app.dapk.st.domain.localecho.LocalEchoPersistence
import app.dapk.st.domain.preference.CachingPreferences import app.dapk.st.domain.preference.CachingPreferences
import app.dapk.st.domain.preference.PropertyCache import app.dapk.st.domain.preference.PropertyCache
@ -65,6 +66,8 @@ class StoreModule(
fun loggingStore(): LoggingStore = LoggingStore(cachingPreferences) fun loggingStore(): LoggingStore = LoggingStore(cachingPreferences)
fun messageStore(): MessageOptionsStore = MessageOptionsStore(cachingPreferences)
fun memberStore(): MemberStore { fun memberStore(): MemberStore {
return MemberPersistence(database, coroutineDispatchers) return MemberPersistence(database, coroutineDispatchers)
} }

View File

@ -1,4 +1,4 @@
package app.dapk.st.domain.eventlog package app.dapk.st.domain.application.eventlog
import app.dapk.db.DapkDb import app.dapk.db.DapkDb
import app.dapk.st.core.CoroutineDispatchers import app.dapk.st.core.CoroutineDispatchers

View File

@ -1,4 +1,4 @@
package app.dapk.st.domain.eventlog package app.dapk.st.domain.application.eventlog
import app.dapk.st.core.CachedPreferences import app.dapk.st.core.CachedPreferences
import app.dapk.st.core.readBoolean import app.dapk.st.core.readBoolean

View File

@ -0,0 +1,17 @@
package app.dapk.st.domain.application.message
import app.dapk.st.core.CachedPreferences
import app.dapk.st.core.readBoolean
import app.dapk.st.core.store
private const val KEY_READ_RECEIPTS_DISABLED = "key_read_receipts_disabled"
class MessageOptionsStore(private val cachedPreferences: CachedPreferences) {
suspend fun isReadReceiptsDisabled() = cachedPreferences.readBoolean(KEY_READ_RECEIPTS_DISABLED, defaultValue = true)
suspend fun setReadReceiptsDisabled(isDisabled: Boolean) {
cachedPreferences.store(KEY_READ_RECEIPTS_DISABLED, isDisabled)
}
}

View File

@ -1,6 +1,6 @@
package app.dapk.st.settings package fake
import app.dapk.st.domain.eventlog.LoggingStore import app.dapk.st.domain.application.eventlog.LoggingStore
import io.mockk.coEvery import io.mockk.coEvery
import io.mockk.mockk import io.mockk.mockk
import test.delegateReturn import test.delegateReturn

View File

@ -0,0 +1,12 @@
package fake
import app.dapk.st.domain.application.message.MessageOptionsStore
import io.mockk.coEvery
import io.mockk.mockk
import test.delegateReturn
class FakeMessageOptionsStore {
val instance = mockk<MessageOptionsStore>()
fun givenReadReceiptsDisabled() = coEvery { instance.isReadReceiptsDisabled() }.delegateReturn()
}

View File

@ -1,4 +1,4 @@
package fixture package fake
import app.dapk.st.domain.StoreCleaner import app.dapk.st.domain.StoreCleaner
import io.mockk.mockk import io.mockk.mockk

View File

@ -8,6 +8,7 @@ dependencies {
implementation project(":matrix:services:room") implementation project(":matrix:services:room")
implementation project(":domains:android:compose-core") implementation project(":domains:android:compose-core")
implementation project(":domains:android:viewmodel") implementation project(":domains:android:viewmodel")
implementation project(":domains:store")
implementation project(":core") implementation project(":core")
implementation project(":features:navigator") implementation project(":features:navigator")
implementation project(":design-library") implementation project(":design-library")

View File

@ -3,6 +3,7 @@ package app.dapk.st.messenger
import android.content.Context import android.content.Context
import app.dapk.st.core.Base64 import app.dapk.st.core.Base64
import app.dapk.st.core.ProvidableModule import app.dapk.st.core.ProvidableModule
import app.dapk.st.domain.application.message.MessageOptionsStore
import app.dapk.st.matrix.common.CredentialsStore import app.dapk.st.matrix.common.CredentialsStore
import app.dapk.st.matrix.common.RoomId import app.dapk.st.matrix.common.RoomId
import app.dapk.st.matrix.message.MessageService import app.dapk.st.matrix.message.MessageService
@ -22,10 +23,21 @@ class MessengerModule(
private val context: Context, private val context: Context,
private val base64: Base64, private val base64: Base64,
private val imageMetaReader: ImageContentReader, private val imageMetaReader: ImageContentReader,
private val messageOptionsStore: MessageOptionsStore,
) : ProvidableModule { ) : ProvidableModule {
internal fun messengerViewModel(): MessengerViewModel { internal fun messengerViewModel(): MessengerViewModel {
return MessengerViewModel(messageService, roomService, roomStore, credentialsStore, timelineUseCase(), LocalIdFactory(), imageMetaReader, clock) return MessengerViewModel(
messageService,
roomService,
roomStore,
credentialsStore,
timelineUseCase(),
LocalIdFactory(),
imageMetaReader,
messageOptionsStore,
clock
)
} }
private fun timelineUseCase(): TimelineUseCaseImpl { private fun timelineUseCase(): TimelineUseCaseImpl {

View File

@ -3,6 +3,7 @@ package app.dapk.st.messenger
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import app.dapk.st.core.Lce import app.dapk.st.core.Lce
import app.dapk.st.core.extensions.takeIfContent import app.dapk.st.core.extensions.takeIfContent
import app.dapk.st.domain.application.message.MessageOptionsStore
import app.dapk.st.matrix.common.CredentialsStore import app.dapk.st.matrix.common.CredentialsStore
import app.dapk.st.matrix.common.EventId import app.dapk.st.matrix.common.EventId
import app.dapk.st.matrix.common.RoomId import app.dapk.st.matrix.common.RoomId
@ -30,6 +31,7 @@ internal class MessengerViewModel(
private val observeTimeline: ObserveTimelineUseCase, private val observeTimeline: ObserveTimelineUseCase,
private val localIdFactory: LocalIdFactory, private val localIdFactory: LocalIdFactory,
private val imageContentReader: ImageContentReader, private val imageContentReader: ImageContentReader,
private val messageOptionsStore: MessageOptionsStore,
private val clock: Clock, private val clock: Clock,
factory: MutableStateFactory<MessengerScreenState> = defaultStateFactory(), factory: MutableStateFactory<MessengerScreenState> = defaultStateFactory(),
) : DapkViewModel<MessengerScreenState, MessengerEvent>( ) : DapkViewModel<MessengerScreenState, MessengerEvent>(
@ -101,7 +103,7 @@ internal class MessengerViewModel(
private fun CoroutineScope.updateRoomReadStateAsync(latestReadEvent: EventId, state: MessengerState): Deferred<Unit> { private fun CoroutineScope.updateRoomReadStateAsync(latestReadEvent: EventId, state: MessengerState): Deferred<Unit> {
return async { return async {
runCatching { runCatching {
roomService.markFullyRead(state.roomState.roomOverview.roomId, latestReadEvent, isPrivate = true) roomService.markFullyRead(state.roomState.roomOverview.roomId, latestReadEvent, isPrivate = messageOptionsStore.isReadReceiptsDisabled())
roomStore.markRead(state.roomState.roomOverview.roomId) roomStore.markRead(state.roomState.roomOverview.roomId)
} }
} }

View File

@ -11,6 +11,7 @@ import app.dapk.st.matrix.room.RoomService
import app.dapk.st.matrix.sync.RoomState import app.dapk.st.matrix.sync.RoomState
import app.dapk.st.matrix.sync.SyncService import app.dapk.st.matrix.sync.SyncService
import fake.FakeCredentialsStore import fake.FakeCredentialsStore
import fake.FakeMessageOptionsStore
import fake.FakeRoomStore import fake.FakeRoomStore
import fixture.* import fixture.*
import internalfake.FakeLocalIdFactory import internalfake.FakeLocalIdFactory
@ -25,6 +26,7 @@ import java.time.Instant
import java.time.ZoneOffset import java.time.ZoneOffset
private const val A_CURRENT_TIMESTAMP = 10000L private const val A_CURRENT_TIMESTAMP = 10000L
private const val READ_RECEIPTS_ARE_DISABLED = true
private val A_ROOM_ID = aRoomId("messenger state room id") private val A_ROOM_ID = aRoomId("messenger state room id")
private const val A_MESSAGE_CONTENT = "message content" private const val A_MESSAGE_CONTENT = "message content"
private const val A_LOCAL_ID = "local.1111-2222-3333" private const val A_LOCAL_ID = "local.1111-2222-3333"
@ -40,6 +42,7 @@ class MessengerViewModelTest {
private val fakeRoomStore = FakeRoomStore() private val fakeRoomStore = FakeRoomStore()
private val fakeCredentialsStore = FakeCredentialsStore().also { it.givenCredentials().returns(aUserCredentials(userId = A_SELF_ID)) } private val fakeCredentialsStore = FakeCredentialsStore().also { it.givenCredentials().returns(aUserCredentials(userId = A_SELF_ID)) }
private val fakeObserveTimelineUseCase = FakeObserveTimelineUseCase() private val fakeObserveTimelineUseCase = FakeObserveTimelineUseCase()
private val fakeMessageOptionsStore = FakeMessageOptionsStore()
private val viewModel = MessengerViewModel( private val viewModel = MessengerViewModel(
fakeMessageService, fakeMessageService,
@ -49,6 +52,7 @@ class MessengerViewModelTest {
fakeObserveTimelineUseCase, fakeObserveTimelineUseCase,
localIdFactory = FakeLocalIdFactory().also { it.givenCreate().returns(A_LOCAL_ID) }.instance, localIdFactory = FakeLocalIdFactory().also { it.givenCreate().returns(A_LOCAL_ID) }.instance,
imageContentReader = FakeImageContentReader(), imageContentReader = FakeImageContentReader(),
messageOptionsStore = fakeMessageOptionsStore.instance,
clock = fixedClock(A_CURRENT_TIMESTAMP), clock = fixedClock(A_CURRENT_TIMESTAMP),
factory = runViewModelTest.testMutableStateFactory(), factory = runViewModelTest.testMutableStateFactory(),
) )
@ -68,8 +72,9 @@ class MessengerViewModelTest {
@Test @Test
fun `given timeline emits state, when starting, then updates state and marks room and events as read`() = runViewModelTest { fun `given timeline emits state, when starting, then updates state and marks room and events as read`() = runViewModelTest {
fakeMessageOptionsStore.givenReadReceiptsDisabled().returns(READ_RECEIPTS_ARE_DISABLED)
fakeRoomStore.expectUnit(times = 2) { it.markRead(A_ROOM_ID) } fakeRoomStore.expectUnit(times = 2) { it.markRead(A_ROOM_ID) }
fakeRoomService.expectUnit { it.markFullyRead(A_ROOM_ID, AN_EVENT_ID, isPrivate = true) } fakeRoomService.expectUnit { it.markFullyRead(A_ROOM_ID, AN_EVENT_ID, isPrivate = READ_RECEIPTS_ARE_DISABLED) }
val state = aMessengerStateWithEvent(AN_EVENT_ID, A_SELF_ID) val state = aMessengerStateWithEvent(AN_EVENT_ID, A_SELF_ID)
fakeObserveTimelineUseCase.given(A_ROOM_ID, A_SELF_ID).returns(flowOf(state)) fakeObserveTimelineUseCase.given(A_ROOM_ID, A_SELF_ID).returns(flowOf(state))

View File

@ -4,7 +4,8 @@ import app.dapk.st.core.BuildMeta
import app.dapk.st.core.DeviceMeta import app.dapk.st.core.DeviceMeta
import app.dapk.st.core.ThemeStore import app.dapk.st.core.ThemeStore
import app.dapk.st.core.isAtLeastS import app.dapk.st.core.isAtLeastS
import app.dapk.st.domain.eventlog.LoggingStore import app.dapk.st.domain.application.eventlog.LoggingStore
import app.dapk.st.domain.application.message.MessageOptionsStore
import app.dapk.st.push.PushTokenRegistrars import app.dapk.st.push.PushTokenRegistrars
internal class SettingsItemFactory( internal class SettingsItemFactory(
@ -13,6 +14,7 @@ internal class SettingsItemFactory(
private val pushTokenRegistrars: PushTokenRegistrars, private val pushTokenRegistrars: PushTokenRegistrars,
private val themeStore: ThemeStore, private val themeStore: ThemeStore,
private val loggingStore: LoggingStore, private val loggingStore: LoggingStore,
private val messageOptionsStore: MessageOptionsStore,
) { ) {
suspend fun root() = general() + theme() + data() + account() + advanced() + about() suspend fun root() = general() + theme() + data() + account() + advanced() + about()
@ -44,6 +46,12 @@ internal class SettingsItemFactory(
val loggingIsEnabled = loggingStore.isEnabled() val loggingIsEnabled = loggingStore.isEnabled()
return listOf( return listOf(
SettingItem.Header("Advanced"), SettingItem.Header("Advanced"),
SettingItem.Toggle(
SettingItem.Id.ToggleSendReadReceipts,
"Don't send message read receipts",
subtitle = "Requires the Homeserver to be running Synapse 1.65+",
state = messageOptionsStore.isReadReceiptsDisabled()
),
SettingItem.Toggle(SettingItem.Id.ToggleEnableLogs, "Enable local logging", state = loggingIsEnabled), SettingItem.Toggle(SettingItem.Id.ToggleEnableLogs, "Enable local logging", state = loggingIsEnabled),
SettingItem.Text(SettingItem.Id.EventLog, "Event log", enabled = loggingIsEnabled), SettingItem.Text(SettingItem.Id.EventLog, "Event log", enabled = loggingIsEnabled),
) )

View File

@ -3,7 +3,8 @@ package app.dapk.st.settings
import android.content.ContentResolver import android.content.ContentResolver
import app.dapk.st.core.* import app.dapk.st.core.*
import app.dapk.st.domain.StoreModule import app.dapk.st.domain.StoreModule
import app.dapk.st.domain.eventlog.LoggingStore import app.dapk.st.domain.application.eventlog.LoggingStore
import app.dapk.st.domain.application.message.MessageOptionsStore
import app.dapk.st.matrix.crypto.CryptoService import app.dapk.st.matrix.crypto.CryptoService
import app.dapk.st.matrix.sync.SyncService import app.dapk.st.matrix.sync.SyncService
import app.dapk.st.push.PushModule import app.dapk.st.push.PushModule
@ -20,6 +21,7 @@ class SettingsModule(
private val coroutineDispatchers: CoroutineDispatchers, private val coroutineDispatchers: CoroutineDispatchers,
private val themeStore: ThemeStore, private val themeStore: ThemeStore,
private val loggingStore: LoggingStore, private val loggingStore: LoggingStore,
private val messageOptionsStore: MessageOptionsStore,
) : ProvidableModule { ) : ProvidableModule {
internal fun settingsViewModel(): SettingsViewModel { internal fun settingsViewModel(): SettingsViewModel {
@ -29,10 +31,11 @@ class SettingsModule(
cryptoService, cryptoService,
syncService, syncService,
UriFilenameResolver(contentResolver, coroutineDispatchers), UriFilenameResolver(contentResolver, coroutineDispatchers),
SettingsItemFactory(buildMeta, deviceMeta, pushModule.pushTokenRegistrars(), themeStore, loggingStore), SettingsItemFactory(buildMeta, deviceMeta, pushModule.pushTokenRegistrars(), themeStore, loggingStore, messageOptionsStore),
pushModule.pushTokenRegistrars(), pushModule.pushTokenRegistrars(),
themeStore, themeStore,
loggingStore, loggingStore,
messageOptionsStore,
) )
} }

View File

@ -44,7 +44,7 @@ internal sealed interface SettingItem {
data class Header(val label: String, override val id: Id = Id.Ignored) : SettingItem data class Header(val label: String, override val id: Id = Id.Ignored) : SettingItem
data class Text(override val id: Id, val content: String, val subtitle: String? = null, val enabled: Boolean = true) : SettingItem data class Text(override val id: Id, val content: String, val subtitle: String? = null, val enabled: Boolean = true) : SettingItem
data class Toggle(override val id: Id, val content: String, val state: Boolean) : SettingItem data class Toggle(override val id: Id, val content: String, val subtitle: String? = null, val state: Boolean) : SettingItem
data class AccessToken(override val id: Id, val content: String, val accessToken: String) : SettingItem data class AccessToken(override val id: Id, val content: String, val accessToken: String) : SettingItem
enum class Id { enum class Id {
@ -58,6 +58,7 @@ internal sealed interface SettingItem {
Ignored, Ignored,
ToggleDynamicTheme, ToggleDynamicTheme,
ToggleEnableLogs, ToggleEnableLogs,
ToggleSendReadReceipts,
} }
} }

View File

@ -7,7 +7,8 @@ import app.dapk.st.core.Lce
import app.dapk.st.core.ThemeStore import app.dapk.st.core.ThemeStore
import app.dapk.st.design.components.SpiderPage import app.dapk.st.design.components.SpiderPage
import app.dapk.st.domain.StoreCleaner import app.dapk.st.domain.StoreCleaner
import app.dapk.st.domain.eventlog.LoggingStore import app.dapk.st.domain.application.eventlog.LoggingStore
import app.dapk.st.domain.application.message.MessageOptionsStore
import app.dapk.st.matrix.crypto.CryptoService import app.dapk.st.matrix.crypto.CryptoService
import app.dapk.st.matrix.crypto.ImportResult import app.dapk.st.matrix.crypto.ImportResult
import app.dapk.st.matrix.sync.SyncService import app.dapk.st.matrix.sync.SyncService
@ -34,6 +35,7 @@ internal class SettingsViewModel(
private val pushTokenRegistrars: PushTokenRegistrars, private val pushTokenRegistrars: PushTokenRegistrars,
private val themeStore: ThemeStore, private val themeStore: ThemeStore,
private val loggingStore: LoggingStore, private val loggingStore: LoggingStore,
private val messageOptionsStore: MessageOptionsStore,
factory: MutableStateFactory<SettingsScreenState> = defaultStateFactory(), factory: MutableStateFactory<SettingsScreenState> = defaultStateFactory(),
) : DapkViewModel<SettingsScreenState, SettingsEvent>( ) : DapkViewModel<SettingsScreenState, SettingsEvent>(
initialState = SettingsScreenState(SpiderPage(Page.Routes.root, "Settings", null, Page.Root(Lce.Loading()))), initialState = SettingsScreenState(SpiderPage(Page.Routes.root, "Settings", null, Page.Root(Lce.Loading()))),
@ -104,6 +106,10 @@ internal class SettingsViewModel(
loggingStore.setEnabled(!loggingStore.isEnabled()) loggingStore.setEnabled(!loggingStore.isEnabled())
refreshRoot() refreshRoot()
} }
ToggleSendReadReceipts -> viewModelScope.launch {
messageOptionsStore.setReadReceiptsDisabled(!messageOptionsStore.isReadReceiptsDisabled())
}
} }
} }

View File

@ -1,7 +1,7 @@
package app.dapk.st.settings.eventlogger package app.dapk.st.settings.eventlogger
import app.dapk.st.core.Lce import app.dapk.st.core.Lce
import app.dapk.st.domain.eventlog.LogLine import app.dapk.st.domain.application.eventlog.LogLine
data class EventLoggerState( data class EventLoggerState(
val logs: Lce<List<String>>, val logs: Lce<List<String>>,

View File

@ -2,7 +2,7 @@ package app.dapk.st.settings.eventlogger
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import app.dapk.st.core.Lce import app.dapk.st.core.Lce
import app.dapk.st.domain.eventlog.EventLogPersistence import app.dapk.st.domain.application.eventlog.EventLogPersistence
import app.dapk.st.viewmodel.DapkViewModel import app.dapk.st.viewmodel.DapkViewModel
import kotlinx.coroutines.Job import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.collect import kotlinx.coroutines.flow.collect

View File

@ -4,6 +4,8 @@ import app.dapk.st.core.BuildMeta
import app.dapk.st.core.DeviceMeta import app.dapk.st.core.DeviceMeta
import app.dapk.st.push.PushTokenRegistrars import app.dapk.st.push.PushTokenRegistrars
import app.dapk.st.push.Registrar import app.dapk.st.push.Registrar
import fake.FakeLoggingStore
import fake.FakeMessageOptionsStore
import internalfixture.aSettingHeaderItem import internalfixture.aSettingHeaderItem
import internalfixture.aSettingTextItem import internalfixture.aSettingTextItem
import io.mockk.coEvery import io.mockk.coEvery
@ -16,6 +18,7 @@ import test.delegateReturn
private val A_SELECTION = Registrar("A_SELECTION") private val A_SELECTION = Registrar("A_SELECTION")
private const val ENABLED_MATERIAL_YOU = true private const val ENABLED_MATERIAL_YOU = true
private const val DISABLED_LOGGING = false private const val DISABLED_LOGGING = false
private const val DISABLED_READ_RECEIPTS = true
class SettingsItemFactoryTest { class SettingsItemFactoryTest {
@ -24,13 +27,15 @@ class SettingsItemFactoryTest {
private val fakePushTokenRegistrars = FakePushRegistrars() private val fakePushTokenRegistrars = FakePushRegistrars()
private val fakeThemeStore = FakeThemeStore() private val fakeThemeStore = FakeThemeStore()
private val fakeLoggingStore = FakeLoggingStore() private val fakeLoggingStore = FakeLoggingStore()
private val fakeMessageOptionsStore = FakeMessageOptionsStore()
private val settingsItemFactory = SettingsItemFactory( private val settingsItemFactory = SettingsItemFactory(
buildMeta, buildMeta,
deviceMeta, deviceMeta,
fakePushTokenRegistrars.instance, fakePushTokenRegistrars.instance,
fakeThemeStore.instance, fakeThemeStore.instance,
fakeLoggingStore.instance fakeLoggingStore.instance,
fakeMessageOptionsStore.instance,
) )
@Test @Test
@ -38,6 +43,7 @@ class SettingsItemFactoryTest {
fakePushTokenRegistrars.givenCurrentSelection().returns(A_SELECTION) fakePushTokenRegistrars.givenCurrentSelection().returns(A_SELECTION)
fakeThemeStore.givenMaterialYouIsEnabled().returns(ENABLED_MATERIAL_YOU) fakeThemeStore.givenMaterialYouIsEnabled().returns(ENABLED_MATERIAL_YOU)
fakeLoggingStore.givenLoggingIsEnabled().returns(DISABLED_LOGGING) fakeLoggingStore.givenLoggingIsEnabled().returns(DISABLED_LOGGING)
fakeMessageOptionsStore.givenReadReceiptsDisabled().returns(DISABLED_READ_RECEIPTS)
val result = settingsItemFactory.root() val result = settingsItemFactory.root()
@ -52,6 +58,12 @@ class SettingsItemFactoryTest {
aSettingHeaderItem("Account"), aSettingHeaderItem("Account"),
aSettingTextItem(SettingItem.Id.SignOut, "Sign out"), aSettingTextItem(SettingItem.Id.SignOut, "Sign out"),
aSettingHeaderItem("Advanced"), aSettingHeaderItem("Advanced"),
SettingItem.Toggle(
SettingItem.Id.ToggleSendReadReceipts,
"Don't send message read receipts",
subtitle = "Requires the Homeserver to be running Synapse 1.65+",
state = DISABLED_READ_RECEIPTS
),
SettingItem.Toggle(SettingItem.Id.ToggleEnableLogs, "Enable local logging", state = DISABLED_LOGGING), SettingItem.Toggle(SettingItem.Id.ToggleEnableLogs, "Enable local logging", state = DISABLED_LOGGING),
aSettingTextItem(SettingItem.Id.EventLog, "Event log", enabled = DISABLED_LOGGING), aSettingTextItem(SettingItem.Id.EventLog, "Event log", enabled = DISABLED_LOGGING),
aSettingHeaderItem("About"), aSettingHeaderItem("About"),

View File

@ -5,7 +5,7 @@ import app.dapk.st.core.Lce
import app.dapk.st.design.components.SpiderPage import app.dapk.st.design.components.SpiderPage
import app.dapk.st.matrix.crypto.ImportResult import app.dapk.st.matrix.crypto.ImportResult
import fake.* import fake.*
import fixture.FakeStoreCleaner import fake.FakeStoreCleaner
import fixture.aRoomId import fixture.aRoomId
import internalfake.FakeSettingsItemFactory import internalfake.FakeSettingsItemFactory
import internalfake.FakeUriFilenameResolver import internalfake.FakeUriFilenameResolver
@ -42,6 +42,7 @@ internal class SettingsViewModelTest {
private val fakeSettingsItemFactory = FakeSettingsItemFactory() private val fakeSettingsItemFactory = FakeSettingsItemFactory()
private val fakeThemeStore = FakeThemeStore() private val fakeThemeStore = FakeThemeStore()
private val fakeLoggingStore = FakeLoggingStore() private val fakeLoggingStore = FakeLoggingStore()
private val fakeMessageOptionsStore = FakeMessageOptionsStore()
private val viewModel = SettingsViewModel( private val viewModel = SettingsViewModel(
fakeStoreCleaner, fakeStoreCleaner,
@ -53,6 +54,7 @@ internal class SettingsViewModelTest {
fakePushTokenRegistrars.instance, fakePushTokenRegistrars.instance,
fakeThemeStore.instance, fakeThemeStore.instance,
fakeLoggingStore.instance, fakeLoggingStore.instance,
fakeMessageOptionsStore.instance,
runViewModelTest.testMutableStateFactory(), runViewModelTest.testMutableStateFactory(),
) )