From 64229397cbf37b16e30977c22ca52886604b9b86 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 5 Feb 2024 12:45:48 +0100 Subject: [PATCH] Take into account the setting `isSendTypingNotificationsEnabled` to not send typing notification when it's been disabled by the user. --- .../MessageComposerPresenter.kt | 15 ++++++++++--- .../messages/impl/MessagesPresenterTest.kt | 1 + .../MessageComposerPresenterTest.kt | 22 +++++++++++++++++++ 3 files changed, 35 insertions(+), 3 deletions(-) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenter.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenter.kt index 4fea2ee046..b98f5fcb39 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenter.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenter.kt @@ -23,6 +23,7 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.DisposableEffect import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.MutableState +import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateListOf import androidx.compose.runtime.mutableStateOf @@ -37,6 +38,7 @@ import io.element.android.features.messages.impl.attachments.Attachment import io.element.android.features.messages.impl.attachments.preview.error.sendAttachmentError import io.element.android.features.messages.impl.mentions.MentionSuggestion import io.element.android.features.messages.impl.mentions.MentionSuggestionsProcessor +import io.element.android.features.preferences.api.store.SessionPreferencesStore import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.designsystem.utils.snackbar.SnackbarDispatcher import io.element.android.libraries.designsystem.utils.snackbar.SnackbarMessage @@ -86,6 +88,7 @@ class MessageComposerPresenter @Inject constructor( private val room: MatrixRoom, private val mediaPickerProvider: PickerProvider, private val featureFlagService: FeatureFlagService, + private val sessionPreferencesStore: SessionPreferencesStore, private val localMediaFactory: LocalMediaFactory, private val mediaSender: MediaSender, private val snackbarDispatcher: SnackbarDispatcher, @@ -147,6 +150,8 @@ class MessageComposerPresenter @Inject constructor( var showAttachmentSourcePicker: Boolean by remember { mutableStateOf(false) } var showTextFormatting: Boolean by remember { mutableStateOf(false) } + val sendTypingNotifications by sessionPreferencesStore.isSendTypingNotificationsEnabled().collectAsState(initial = true) + LaunchedEffect(messageComposerContext.composerMode) { when (val modeValue = messageComposerContext.composerMode) { is MessageComposerMode.Edit -> @@ -212,7 +217,9 @@ class MessageComposerPresenter @Inject constructor( // Declare that the user is not typing anymore when the composer is disposed onDispose { appCoroutineScope.launch { - room.typingNotice(false) + if (sendTypingNotifications) { + room.typingNotice(false) + } } } } @@ -310,8 +317,10 @@ class MessageComposerPresenter @Inject constructor( analyticsService.trackError(event.error) } is MessageComposerEvents.TypingNotice -> { - localCoroutineScope.launch { - room.typingNotice(event.isTyping) + if (sendTypingNotifications) { + localCoroutineScope.launch { + room.typingNotice(event.isTyping) + } } } is MessageComposerEvents.SuggestionReceived -> { diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/MessagesPresenterTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/MessagesPresenterTest.kt index 1c10cb97e8..9dd9ff5d88 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/MessagesPresenterTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/MessagesPresenterTest.kt @@ -675,6 +675,7 @@ class MessagesPresenterTest { room = matrixRoom, mediaPickerProvider = FakePickerProvider(), featureFlagService = FakeFeatureFlagService(mapOf(FeatureFlags.NotificationSettings.key to true)), + sessionPreferencesStore = InMemorySessionPreferencesStore(), localMediaFactory = FakeLocalMediaFactory(mockMediaUrl), mediaSender = mediaSender, snackbarDispatcher = SnackbarDispatcher(), diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/textcomposer/MessageComposerPresenterTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/textcomposer/MessageComposerPresenterTest.kt index d4b3c33cb1..c189e28c13 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/textcomposer/MessageComposerPresenterTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/textcomposer/MessageComposerPresenterTest.kt @@ -32,11 +32,13 @@ import io.element.android.features.messages.impl.messagecomposer.MessageComposer import io.element.android.features.messages.impl.messagecomposer.MessageComposerEvents import io.element.android.features.messages.impl.messagecomposer.MessageComposerPresenter import io.element.android.features.messages.impl.messagecomposer.MessageComposerState +import io.element.android.features.preferences.api.store.SessionPreferencesStore import io.element.android.libraries.core.mimetype.MimeTypes import io.element.android.libraries.designsystem.utils.snackbar.SnackbarDispatcher import io.element.android.libraries.featureflag.api.FeatureFlagService import io.element.android.libraries.featureflag.api.FeatureFlags import io.element.android.libraries.featureflag.test.FakeFeatureFlagService +import io.element.android.libraries.featureflag.test.InMemorySessionPreferencesStore import io.element.android.libraries.matrix.api.core.EventId import io.element.android.libraries.matrix.api.core.TransactionId import io.element.android.libraries.matrix.api.media.ImageInfo @@ -888,6 +890,24 @@ class MessageComposerPresenterTest { } } + @Test + fun `present - handle typing notice event when sending typing notice is disabled`() = runTest { + val room = FakeMatrixRoom() + val store = InMemorySessionPreferencesStore( + isSendTypingNotificationsEnabled = false + ) + val presenter = createPresenter(room = room, sessionPreferencesStore = store, coroutineScope = this) + moleculeFlow(RecompositionMode.Immediate) { + presenter.present() + }.test { + val initialState = awaitFirstItem() + assertThat(room.typingRecord).isEmpty() + initialState.eventSink.invoke(MessageComposerEvents.TypingNotice(true)) + initialState.eventSink.invoke(MessageComposerEvents.TypingNotice(false)) + assertThat(room.typingRecord).isEmpty() + } + } + private suspend fun ReceiveTurbine.backToNormalMode(state: MessageComposerState, skipCount: Int = 0): MessageComposerState { state.eventSink.invoke(MessageComposerEvents.CloseSpecialMode) skipItems(skipCount) @@ -901,6 +921,7 @@ class MessageComposerPresenterTest { room: MatrixRoom = FakeMatrixRoom(), pickerProvider: PickerProvider = this.pickerProvider, featureFlagService: FeatureFlagService = this.featureFlagService, + sessionPreferencesStore: SessionPreferencesStore = InMemorySessionPreferencesStore(), mediaPreProcessor: MediaPreProcessor = this.mediaPreProcessor, snackbarDispatcher: SnackbarDispatcher = this.snackbarDispatcher, permissionPresenter: PermissionsPresenter = FakePermissionsPresenter(), @@ -909,6 +930,7 @@ class MessageComposerPresenterTest { room, pickerProvider, featureFlagService, + sessionPreferencesStore, localMediaFactory, MediaSender(mediaPreProcessor, room), snackbarDispatcher,