Show correct UI when replying to a voice message (#1658)
Shows voice messages in the room summary. Shows voice messages in the reply context menu and composer. Show replies to voice messages in the timeline. (before this PR voice messages were shown the same as audio messages) Story: https://github.com/vector-im/element-meta/issues/2106
This commit is contained in:
parent
bf905dd79b
commit
b2a61f2ed3
18 changed files with 110 additions and 23 deletions
|
|
@ -331,11 +331,14 @@ class MessagesPresenter @AssistedInject constructor(
|
|||
textContent = targetEvent.content.body,
|
||||
type = AttachmentThumbnailType.Audio,
|
||||
)
|
||||
is TimelineItemVoiceContent -> AttachmentThumbnailInfo(
|
||||
textContent = targetEvent.content.body,
|
||||
type = AttachmentThumbnailType.Voice,
|
||||
)
|
||||
is TimelineItemLocationContent -> AttachmentThumbnailInfo(
|
||||
type = AttachmentThumbnailType.Location,
|
||||
)
|
||||
is TimelineItemPollContent, // TODO Polls: handle reply to
|
||||
is TimelineItemVoiceContent, // TODO Voice messages: handle reply to
|
||||
is TimelineItemTextBasedContent,
|
||||
is TimelineItemRedactedContent,
|
||||
is TimelineItemStateContent,
|
||||
|
|
|
|||
|
|
@ -20,11 +20,13 @@ import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
|||
import io.element.android.features.messages.impl.actionlist.model.TimelineItemAction
|
||||
import io.element.android.features.messages.impl.timeline.aTimelineItemEvent
|
||||
import io.element.android.features.messages.impl.timeline.aTimelineItemReactions
|
||||
import io.element.android.features.messages.impl.timeline.model.event.aTimelineItemAudioContent
|
||||
import io.element.android.features.messages.impl.timeline.model.event.aTimelineItemFileContent
|
||||
import io.element.android.features.messages.impl.timeline.model.event.aTimelineItemImageContent
|
||||
import io.element.android.features.messages.impl.timeline.model.event.aTimelineItemLocationContent
|
||||
import io.element.android.features.messages.impl.timeline.model.event.aTimelineItemPollContent
|
||||
import io.element.android.features.messages.impl.timeline.model.event.aTimelineItemVideoContent
|
||||
import io.element.android.features.messages.impl.timeline.model.event.aTimelineItemVoiceContent
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
|
||||
|
|
@ -67,6 +69,22 @@ open class ActionListStateProvider : PreviewParameterProvider<ActionListState> {
|
|||
actions = aTimelineItemActionList(),
|
||||
)
|
||||
),
|
||||
anActionListState().copy(
|
||||
target = ActionListState.Target.Success(
|
||||
event = aTimelineItemEvent(content = aTimelineItemAudioContent()).copy(
|
||||
reactionsState = reactionsState
|
||||
),
|
||||
actions = aTimelineItemActionList(),
|
||||
)
|
||||
),
|
||||
anActionListState().copy(
|
||||
target = ActionListState.Target.Success(
|
||||
event = aTimelineItemEvent(content = aTimelineItemVoiceContent()).copy(
|
||||
reactionsState = reactionsState
|
||||
),
|
||||
actions = aTimelineItemActionList(),
|
||||
)
|
||||
),
|
||||
anActionListState().copy(
|
||||
target = ActionListState.Target.Success(
|
||||
event = aTimelineItemEvent(content = aTimelineItemLocationContent()).copy(
|
||||
|
|
|
|||
|
|
@ -238,7 +238,6 @@ private fun MessageSummary(event: TimelineItem.Event, modifier: Modifier = Modif
|
|||
|
||||
when (event.content) {
|
||||
is TimelineItemPollContent, // TODO Polls: handle summary
|
||||
is TimelineItemVoiceContent, // TODO Voice messages: handle reply summary
|
||||
is TimelineItemTextBasedContent,
|
||||
is TimelineItemStateContent,
|
||||
is TimelineItemEncryptedContent,
|
||||
|
|
@ -309,6 +308,18 @@ private fun MessageSummary(event: TimelineItem.Event, modifier: Modifier = Modif
|
|||
}
|
||||
content = { ContentForBody(event.content.body) }
|
||||
}
|
||||
is TimelineItemVoiceContent -> {
|
||||
icon = {
|
||||
AttachmentThumbnail(
|
||||
modifier = imageModifier,
|
||||
info = AttachmentThumbnailInfo(
|
||||
textContent = textContent,
|
||||
type = AttachmentThumbnailType.Voice,
|
||||
)
|
||||
)
|
||||
}
|
||||
content = { ContentForBody(event.content.body) }
|
||||
}
|
||||
}
|
||||
Row(modifier = modifier) {
|
||||
icon()
|
||||
|
|
|
|||
|
|
@ -612,10 +612,18 @@ private fun attachmentThumbnailInfoForInReplyTo(inReplyTo: InReplyTo.Ready): Att
|
|||
textContent = messageContent.body,
|
||||
type = AttachmentThumbnailType.Location,
|
||||
)
|
||||
is AudioMessageType -> AttachmentThumbnailInfo(
|
||||
textContent = messageContent.body,
|
||||
type = AttachmentThumbnailType.Audio,
|
||||
)
|
||||
is AudioMessageType -> {
|
||||
when (type.isVoiceMessage) {
|
||||
true -> AttachmentThumbnailInfo(
|
||||
textContent = messageContent.body,
|
||||
type = AttachmentThumbnailType.Voice,
|
||||
)
|
||||
false -> AttachmentThumbnailInfo(
|
||||
textContent = messageContent.body,
|
||||
type = AttachmentThumbnailType.Audio,
|
||||
)
|
||||
}
|
||||
}
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:pathData="M12.029,14.15C11.176,14.15 10.446,13.846 9.837,13.238C9.229,12.629 8.925,11.9 8.925,11.05V5.075C8.925,4.221 9.229,3.495 9.837,2.897C10.446,2.299 11.176,2 12.029,2C12.882,2 13.607,2.299 14.204,2.897C14.801,3.495 15.1,4.221 15.1,5.075V11.05C15.1,11.9 14.801,12.629 14.204,13.238C13.607,13.846 12.882,14.15 12.029,14.15ZM12.025,21C11.742,21 11.496,20.896 11.288,20.688C11.079,20.479 10.975,20.233 10.975,19.95V18.005C9.442,17.802 8.142,17.163 7.075,16.087C6.008,15.012 5.35,13.725 5.1,12.225C5.05,11.915 5.131,11.642 5.344,11.405C5.557,11.168 5.842,11.05 6.2,11.05C6.433,11.05 6.642,11.133 6.825,11.3C7.008,11.467 7.125,11.683 7.175,11.95C7.388,13.095 7.946,14.052 8.849,14.821C9.752,15.59 10.81,15.975 12.025,15.975C13.233,15.975 14.286,15.59 15.184,14.821C16.083,14.052 16.638,13.095 16.85,11.95C16.9,11.683 17.017,11.467 17.2,11.3C17.383,11.133 17.6,11.05 17.851,11.05C18.191,11.05 18.468,11.168 18.681,11.405C18.893,11.642 18.975,11.915 18.925,12.225C18.695,13.728 18.046,15.016 16.977,16.09C15.909,17.163 14.608,17.802 13.075,18.005V19.95C13.075,20.233 12.971,20.479 12.762,20.688C12.554,20.896 12.308,21 12.025,21Z"
|
||||
android:fillColor="#1B1D22"/>
|
||||
</vector>
|
||||
|
|
@ -128,7 +128,11 @@ class DefaultRoomLastMessageFormatter @Inject constructor(
|
|||
sp.getString(CommonStrings.common_file)
|
||||
}
|
||||
is AudioMessageType -> {
|
||||
sp.getString(CommonStrings.common_audio)
|
||||
if (messageType.isVoiceMessage) {
|
||||
sp.getString(CommonStrings.common_voice_message)
|
||||
} else {
|
||||
sp.getString(CommonStrings.common_audio)
|
||||
}
|
||||
}
|
||||
is OtherMessageType -> {
|
||||
messageType.body
|
||||
|
|
|
|||
|
|
@ -163,6 +163,7 @@ class DefaultRoomLastMessageFormatterTest {
|
|||
TextMessageType(body, null),
|
||||
VideoMessageType(body, MediaSource("url"), null),
|
||||
AudioMessageType(body, MediaSource("url"), null, null, false),
|
||||
AudioMessageType(body, MediaSource("url"), null, null, true),
|
||||
ImageMessageType(body, MediaSource("url"), null),
|
||||
FileMessageType(body, MediaSource("url"), null),
|
||||
LocationMessageType(body, "geo:1,2", null),
|
||||
|
|
@ -198,7 +199,12 @@ class DefaultRoomLastMessageFormatterTest {
|
|||
for ((type, result) in resultsInDm) {
|
||||
val expectedResult = when (type) {
|
||||
is VideoMessageType -> "Video"
|
||||
is AudioMessageType -> "Audio"
|
||||
is AudioMessageType -> {
|
||||
when (type.isVoiceMessage) {
|
||||
true -> "Voice message"
|
||||
false -> "Audio"
|
||||
}
|
||||
}
|
||||
is ImageMessageType -> "Image"
|
||||
is FileMessageType -> "File"
|
||||
is LocationMessageType -> "Shared location"
|
||||
|
|
@ -216,7 +222,12 @@ class DefaultRoomLastMessageFormatterTest {
|
|||
val string = result.toString()
|
||||
val expectedResult = when (type) {
|
||||
is VideoMessageType -> "$senderName: Video"
|
||||
is AudioMessageType -> "$senderName: Audio"
|
||||
is AudioMessageType -> {
|
||||
when (type.isVoiceMessage) {
|
||||
true -> "$senderName: Voice message"
|
||||
false -> "$senderName: Audio"
|
||||
}
|
||||
}
|
||||
is ImageMessageType -> "$senderName: Image"
|
||||
is FileMessageType -> "$senderName: File"
|
||||
is LocationMessageType -> "$senderName: Shared location"
|
||||
|
|
@ -228,7 +239,12 @@ class DefaultRoomLastMessageFormatterTest {
|
|||
}
|
||||
val shouldCreateAnnotatedString = when (type) {
|
||||
is VideoMessageType -> true
|
||||
is AudioMessageType -> true
|
||||
is AudioMessageType -> {
|
||||
when (type.isVoiceMessage) {
|
||||
true -> true
|
||||
false -> true
|
||||
}
|
||||
}
|
||||
is ImageMessageType -> true
|
||||
is FileMessageType -> true
|
||||
is LocationMessageType -> false
|
||||
|
|
|
|||
|
|
@ -75,6 +75,12 @@ fun AttachmentThumbnail(
|
|||
contentDescription = info.textContent,
|
||||
)
|
||||
}
|
||||
AttachmentThumbnailType.Voice -> {
|
||||
Icon(
|
||||
resourceId = CommonDrawables.ic_voice_attachment,
|
||||
contentDescription = info.textContent,
|
||||
)
|
||||
}
|
||||
AttachmentThumbnailType.File -> {
|
||||
Icon(
|
||||
resourceId = CommonDrawables.ic_september_attachment,
|
||||
|
|
@ -95,7 +101,7 @@ fun AttachmentThumbnail(
|
|||
|
||||
@Parcelize
|
||||
enum class AttachmentThumbnailType : Parcelable {
|
||||
Image, Video, File, Audio, Location
|
||||
Image, Video, File, Audio, Location, Voice
|
||||
}
|
||||
|
||||
@Parcelize
|
||||
|
|
|
|||
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:85692ea3847fe5a79f955bb71153ccb6e5b24cf451292c7b9d56f26e2eff95b7
|
||||
size 28840
|
||||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:979138753000ada021a67f4bc14a89b912430c4331ac69aa702b2e50c050d7cb
|
||||
size 41200
|
||||
oid sha256:d32becec465a3f01e35aac9ebbeb8f48507cc2146f35b8e6c6393bbd410cca3e
|
||||
size 39370
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:e06e1a32d8c9d06a307a5116a396a03308d5e5486f911d34002139485e7d9ffe
|
||||
size 28176
|
||||
oid sha256:a1f8750e66aa2a60198fe68d2e3185bcf5a8708df81502f33c394d72f7b20a30
|
||||
size 42765
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:85692ea3847fe5a79f955bb71153ccb6e5b24cf451292c7b9d56f26e2eff95b7
|
||||
size 28840
|
||||
oid sha256:979138753000ada021a67f4bc14a89b912430c4331ac69aa702b2e50c050d7cb
|
||||
size 41200
|
||||
|
|
|
|||
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:e06e1a32d8c9d06a307a5116a396a03308d5e5486f911d34002139485e7d9ffe
|
||||
size 28176
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:5df2d3b6e4698867277712214fa526e08a9bf790140cd000cfe2bf94c70e77f4
|
||||
size 27525
|
||||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:752abe37a810cc8e4b36ae5f4c4aa38c9f22757b6458f272ba991050c69aee53
|
||||
size 39409
|
||||
oid sha256:a99566280864e66ec327d2d6d8016c74b12f1c62ff27fd0d2d4ba0109ae9756a
|
||||
size 37747
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:0c53fdbe427ddb7088d9bd8f9b46a1281d145fd6f9ccc3a7de339750e3079075
|
||||
size 26498
|
||||
oid sha256:fbb1233cf288e6ffc1aaa7136b56c412699897d7edd20bef82784562e302bf40
|
||||
size 41215
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:5df2d3b6e4698867277712214fa526e08a9bf790140cd000cfe2bf94c70e77f4
|
||||
size 27525
|
||||
oid sha256:752abe37a810cc8e4b36ae5f4c4aa38c9f22757b6458f272ba991050c69aee53
|
||||
size 39409
|
||||
|
|
|
|||
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:0c53fdbe427ddb7088d9bd8f9b46a1281d145fd6f9ccc3a7de339750e3079075
|
||||
size 26498
|
||||
Loading…
Add table
Add a link
Reference in a new issue