diff --git a/changelog.d/7845.wip b/changelog.d/7845.wip new file mode 100644 index 0000000000..8bce21499a --- /dev/null +++ b/changelog.d/7845.wip @@ -0,0 +1 @@ +[Voice Broadcast] Only display a notification on the first voice chunk diff --git a/library/ui-strings/src/main/res/values/strings.xml b/library/ui-strings/src/main/res/values/strings.xml index f1c2eb2c6d..6731248f83 100644 --- a/library/ui-strings/src/main/res/values/strings.xml +++ b/library/ui-strings/src/main/res/values/strings.xml @@ -2295,6 +2295,7 @@ Verification Conclusion Shared their location Shared their live location + Started a voice broadcast Waiting… %s canceled diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/format/DisplayableEventFormatter.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/format/DisplayableEventFormatter.kt index ef4846d822..eaa0bbb51a 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/format/DisplayableEventFormatter.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/format/DisplayableEventFormatter.kt @@ -27,6 +27,7 @@ import im.vector.app.core.resources.StringProvider import im.vector.app.features.html.EventHtmlRenderer import im.vector.app.features.voicebroadcast.VoiceBroadcastConstants import im.vector.app.features.voicebroadcast.isLive +import im.vector.app.features.voicebroadcast.isVoiceBroadcast import im.vector.app.features.voicebroadcast.model.asVoiceBroadcastEvent import me.gujun.android.span.image import me.gujun.android.span.span @@ -39,6 +40,7 @@ import org.matrix.android.sdk.api.session.room.model.message.MessageContent import org.matrix.android.sdk.api.session.room.model.message.MessagePollContent import org.matrix.android.sdk.api.session.room.model.message.MessageTextContent import org.matrix.android.sdk.api.session.room.model.message.MessageType +import org.matrix.android.sdk.api.session.room.model.message.asMessageAudioEvent import org.matrix.android.sdk.api.session.room.model.relation.ReactionContent import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent import org.matrix.android.sdk.api.session.room.timeline.getTextDisplayableContent @@ -86,10 +88,16 @@ class DisplayableEventFormatter @Inject constructor( simpleFormat(senderName, stringProvider.getString(R.string.sent_an_image), appendAuthor) } MessageType.MSGTYPE_AUDIO -> { - if ((messageContent as? MessageAudioContent)?.voiceMessageIndicator != null) { - simpleFormat(senderName, stringProvider.getString(R.string.sent_a_voice_message), appendAuthor) - } else { - simpleFormat(senderName, stringProvider.getString(R.string.sent_an_audio_file), appendAuthor) + when { + (messageContent as? MessageAudioContent)?.voiceMessageIndicator == null -> { + simpleFormat(senderName, stringProvider.getString(R.string.sent_an_audio_file), appendAuthor) + } + timelineEvent.root.asMessageAudioEvent().isVoiceBroadcast() -> { + simpleFormat(senderName, stringProvider.getString(R.string.started_a_voice_broadcast), appendAuthor) + } + else -> { + simpleFormat(senderName, stringProvider.getString(R.string.sent_a_voice_message), appendAuthor) + } } } MessageType.MSGTYPE_VIDEO -> { diff --git a/vector/src/main/java/im/vector/app/features/notifications/FilteredEventDetector.kt b/vector/src/main/java/im/vector/app/features/notifications/FilteredEventDetector.kt new file mode 100644 index 0000000000..e21462b182 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/notifications/FilteredEventDetector.kt @@ -0,0 +1,59 @@ +/* + * Copyright 2023 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package im.vector.app.features.notifications + +import im.vector.app.ActiveSessionDataSource +import im.vector.app.features.voicebroadcast.isVoiceBroadcast +import im.vector.app.features.voicebroadcast.sequence +import org.matrix.android.sdk.api.session.events.model.isVoiceMessage +import org.matrix.android.sdk.api.session.getRoom +import org.matrix.android.sdk.api.session.room.getTimelineEvent +import org.matrix.android.sdk.api.session.room.model.message.asMessageAudioEvent +import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent +import javax.inject.Inject + +class FilteredEventDetector @Inject constructor( + private val activeSessionDataSource: ActiveSessionDataSource +) { + + /** + * Returns true if the given event should be ignored. + * Used to skip notifications if a non expected message is received. + */ + fun shouldBeIgnored(notifiableEvent: NotifiableEvent): Boolean { + val session = activeSessionDataSource.currentValue?.orNull() ?: return false + + if (notifiableEvent is NotifiableMessageEvent) { + val room = session.getRoom(notifiableEvent.roomId) ?: return false + val timelineEvent = room.getTimelineEvent(notifiableEvent.eventId) ?: return false + return timelineEvent.shouldBeIgnored() + } + return false + } + + /** + * Whether the timeline event should be ignored. + */ + private fun TimelineEvent.shouldBeIgnored(): Boolean { + if (root.isVoiceMessage()) { + val audioEvent = root.asMessageAudioEvent() + // if the event is a voice message related to a voice broadcast, only show the event on the first chunk. + return audioEvent.isVoiceBroadcast() && audioEvent?.sequence != 1 + } + + return false + } +} diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotificationDrawerManager.kt b/vector/src/main/java/im/vector/app/features/notifications/NotificationDrawerManager.kt index 4f05e83bd4..2d799034d9 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/NotificationDrawerManager.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotificationDrawerManager.kt @@ -47,6 +47,7 @@ class NotificationDrawerManager @Inject constructor( private val notifiableEventProcessor: NotifiableEventProcessor, private val notificationRenderer: NotificationRenderer, private val notificationEventPersistence: NotificationEventPersistence, + private val filteredEventDetector: FilteredEventDetector, private val buildMeta: BuildMeta, ) { @@ -100,6 +101,11 @@ class NotificationDrawerManager @Inject constructor( Timber.d("onNotifiableEventReceived(): is push: ${notifiableEvent.canBeReplaced}") } + if (filteredEventDetector.shouldBeIgnored(notifiableEvent)) { + Timber.d("onNotifiableEventReceived(): ignore the event") + return + } + add(notifiableEvent) }