Add 'send private read receipts' option in advanced settings (#2290)
* Add 'send private read receipts' option in advanced settings * Create `SessionPreferencesStore` that stores the settings for the current use separate from those of the app. * Rename `PreferencesStore` to `AppPreferencesStore` to split the preferences. --------- Co-authored-by: ElementBot <benoitm+elementbot@element.io>
This commit is contained in:
parent
e22ac6a48d
commit
17f22d143b
38 changed files with 314 additions and 85 deletions
|
|
@ -63,7 +63,7 @@ import io.element.android.features.messages.impl.utils.messagesummary.MessageSum
|
|||
import io.element.android.features.messages.impl.voicemessages.composer.VoiceMessageComposerPresenter
|
||||
import io.element.android.features.networkmonitor.api.NetworkMonitor
|
||||
import io.element.android.features.networkmonitor.api.NetworkStatus
|
||||
import io.element.android.features.preferences.api.store.PreferencesStore
|
||||
import io.element.android.features.preferences.api.store.AppPreferencesStore
|
||||
import io.element.android.libraries.androidutils.clipboard.ClipboardHelper
|
||||
import io.element.android.libraries.architecture.AsyncData
|
||||
import io.element.android.libraries.architecture.Presenter
|
||||
|
|
@ -108,7 +108,7 @@ class MessagesPresenter @AssistedInject constructor(
|
|||
private val messageSummaryFormatter: MessageSummaryFormatter,
|
||||
private val dispatchers: CoroutineDispatchers,
|
||||
private val clipboardHelper: ClipboardHelper,
|
||||
private val preferencesStore: PreferencesStore,
|
||||
private val appPreferencesStore: AppPreferencesStore,
|
||||
private val featureFlagsService: FeatureFlagService,
|
||||
private val htmlConverterProvider: HtmlConverterProvider,
|
||||
@Assisted private val navigator: MessagesNavigator,
|
||||
|
|
@ -178,7 +178,7 @@ class MessagesPresenter @AssistedInject constructor(
|
|||
timelineState.eventSink(TimelineEvents.SetHighlightedEvent(composerState.mode.relatedEventId))
|
||||
}
|
||||
|
||||
val enableTextFormatting by preferencesStore.isRichTextEditorEnabledFlow().collectAsState(initial = true)
|
||||
val enableTextFormatting by appPreferencesStore.isRichTextEditorEnabledFlow().collectAsState(initial = true)
|
||||
|
||||
var enableVoiceMessages by remember { mutableStateOf(false) }
|
||||
LaunchedEffect(featureFlagsService) {
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ import io.element.android.features.messages.impl.timeline.model.event.TimelineIt
|
|||
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemVoiceContent
|
||||
import io.element.android.features.messages.impl.timeline.model.event.canBeCopied
|
||||
import io.element.android.features.messages.impl.timeline.model.event.canReact
|
||||
import io.element.android.features.preferences.api.store.PreferencesStore
|
||||
import io.element.android.features.preferences.api.store.AppPreferencesStore
|
||||
import io.element.android.libraries.architecture.Presenter
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
|
|
@ -39,7 +39,7 @@ import kotlinx.coroutines.launch
|
|||
import javax.inject.Inject
|
||||
|
||||
class ActionListPresenter @Inject constructor(
|
||||
private val preferencesStore: PreferencesStore,
|
||||
private val appPreferencesStore: AppPreferencesStore,
|
||||
) : Presenter<ActionListState> {
|
||||
@Composable
|
||||
override fun present(): ActionListState {
|
||||
|
|
@ -49,7 +49,7 @@ class ActionListPresenter @Inject constructor(
|
|||
mutableStateOf(ActionListState.Target.None)
|
||||
}
|
||||
|
||||
val isDeveloperModeEnabled by preferencesStore.isDeveloperModeEnabledFlow().collectAsState(initial = false)
|
||||
val isDeveloperModeEnabled by appPreferencesStore.isDeveloperModeEnabledFlow().collectAsState(initial = false)
|
||||
|
||||
fun handleEvents(event: ActionListEvents) {
|
||||
when (event) {
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ import io.element.android.features.messages.impl.timeline.session.SessionState
|
|||
import io.element.android.features.messages.impl.voicemessages.timeline.RedactedVoiceMessageManager
|
||||
import io.element.android.features.poll.api.actions.EndPollAction
|
||||
import io.element.android.features.poll.api.actions.SendPollResponseAction
|
||||
import io.element.android.features.preferences.api.store.SessionPreferencesStore
|
||||
import io.element.android.libraries.architecture.Presenter
|
||||
import io.element.android.libraries.core.coroutine.CoroutineDispatchers
|
||||
import io.element.android.libraries.matrix.api.core.EventId
|
||||
|
|
@ -73,6 +74,7 @@ class TimelinePresenter @AssistedInject constructor(
|
|||
private val redactedVoiceMessageManager: RedactedVoiceMessageManager,
|
||||
private val sendPollResponseAction: SendPollResponseAction,
|
||||
private val endPollAction: EndPollAction,
|
||||
private val sessionPreferencesStore: SessionPreferencesStore,
|
||||
) : Presenter<TimelineState> {
|
||||
@AssistedFactory
|
||||
interface Factory {
|
||||
|
|
@ -103,6 +105,8 @@ class TimelinePresenter @AssistedInject constructor(
|
|||
val sessionVerifiedStatus by verificationService.sessionVerifiedStatus.collectAsState()
|
||||
val keyBackupState by encryptionService.backupStateStateFlow.collectAsState()
|
||||
|
||||
val isSendPublicReadReceiptsEnabled by sessionPreferencesStore.isSendPublicReadReceiptsEnabled().collectAsState(initial = true)
|
||||
|
||||
val sessionState by remember {
|
||||
derivedStateOf {
|
||||
SessionState(
|
||||
|
|
@ -124,7 +128,8 @@ class TimelinePresenter @AssistedInject constructor(
|
|||
firstVisibleIndex = event.firstIndex,
|
||||
timelineItems = timelineItems,
|
||||
lastReadReceiptIndex = lastReadReceiptIndex,
|
||||
lastReadReceiptId = lastReadReceiptId
|
||||
lastReadReceiptId = lastReadReceiptId,
|
||||
readReceiptType = if (isSendPublicReadReceiptsEnabled) ReceiptType.READ else ReceiptType.READ_PRIVATE,
|
||||
)
|
||||
}
|
||||
is TimelineEvents.PollAnswerSelected -> appScope.launch {
|
||||
|
|
@ -223,13 +228,14 @@ class TimelinePresenter @AssistedInject constructor(
|
|||
timelineItems: ImmutableList<TimelineItem>,
|
||||
lastReadReceiptIndex: MutableState<Int>,
|
||||
lastReadReceiptId: MutableState<EventId?>,
|
||||
readReceiptType: ReceiptType,
|
||||
) = launch(dispatchers.computation) {
|
||||
// Get last valid EventId seen by the user, as the first index might refer to a Virtual item
|
||||
val eventId = getLastEventIdBeforeOrAt(firstVisibleIndex, timelineItems)
|
||||
if (eventId != null && firstVisibleIndex <= lastReadReceiptIndex.value && eventId != lastReadReceiptId.value) {
|
||||
lastReadReceiptIndex.value = firstVisibleIndex
|
||||
lastReadReceiptId.value = eventId
|
||||
timeline.sendReadReceipt(eventId = eventId, receiptType = ReceiptType.READ)
|
||||
timeline.sendReadReceipt(eventId = eventId, receiptType = readReceiptType)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue