Merge pull request #3904 from element-hq/feature/bma/editedCaption
Render edited caption.
This commit is contained in:
@@ -87,6 +87,7 @@ class TimelineItemContentMessageFactory @Inject constructor(
|
||||
filename = messageType.filename,
|
||||
caption = messageType.caption?.trimEnd(),
|
||||
formattedCaption = parseHtml(messageType.formattedCaption) ?: messageType.caption?.withLinks(),
|
||||
isEdited = content.isEdited,
|
||||
mediaSource = messageType.source,
|
||||
thumbnailSource = messageType.info?.thumbnailSource,
|
||||
mimeType = messageType.info?.mimetype ?: MimeTypes.OctetStream,
|
||||
@@ -106,6 +107,7 @@ class TimelineItemContentMessageFactory @Inject constructor(
|
||||
filename = messageType.filename,
|
||||
caption = messageType.caption?.trimEnd(),
|
||||
formattedCaption = parseHtml(messageType.formattedCaption) ?: messageType.caption?.withLinks(),
|
||||
isEdited = content.isEdited,
|
||||
mediaSource = messageType.source,
|
||||
thumbnailSource = messageType.info?.thumbnailSource,
|
||||
mimeType = messageType.info?.mimetype ?: MimeTypes.OctetStream,
|
||||
@@ -143,6 +145,7 @@ class TimelineItemContentMessageFactory @Inject constructor(
|
||||
filename = messageType.filename,
|
||||
caption = messageType.caption?.trimEnd(),
|
||||
formattedCaption = parseHtml(messageType.formattedCaption) ?: messageType.caption?.withLinks(),
|
||||
isEdited = content.isEdited,
|
||||
thumbnailSource = messageType.info?.thumbnailSource,
|
||||
videoSource = messageType.source,
|
||||
mimeType = messageType.info?.mimetype ?: MimeTypes.OctetStream,
|
||||
@@ -162,6 +165,7 @@ class TimelineItemContentMessageFactory @Inject constructor(
|
||||
filename = messageType.filename,
|
||||
caption = messageType.caption?.trimEnd(),
|
||||
formattedCaption = parseHtml(messageType.formattedCaption) ?: messageType.caption?.withLinks(),
|
||||
isEdited = content.isEdited,
|
||||
mediaSource = messageType.source,
|
||||
duration = messageType.info?.duration ?: Duration.ZERO,
|
||||
mimeType = messageType.info?.mimetype ?: MimeTypes.OctetStream,
|
||||
@@ -177,6 +181,7 @@ class TimelineItemContentMessageFactory @Inject constructor(
|
||||
filename = messageType.filename,
|
||||
caption = messageType.caption?.trimEnd(),
|
||||
formattedCaption = parseHtml(messageType.formattedCaption) ?: messageType.caption?.withLinks(),
|
||||
isEdited = content.isEdited,
|
||||
mediaSource = messageType.source,
|
||||
duration = messageType.info?.duration ?: Duration.ZERO,
|
||||
mimeType = messageType.info?.mimetype ?: MimeTypes.OctetStream,
|
||||
@@ -188,6 +193,7 @@ class TimelineItemContentMessageFactory @Inject constructor(
|
||||
filename = messageType.filename,
|
||||
caption = messageType.caption?.trimEnd(),
|
||||
formattedCaption = parseHtml(messageType.formattedCaption) ?: messageType.caption?.withLinks(),
|
||||
isEdited = content.isEdited,
|
||||
mediaSource = messageType.source,
|
||||
duration = messageType.info?.duration ?: Duration.ZERO,
|
||||
mimeType = messageType.info?.mimetype ?: MimeTypes.OctetStream,
|
||||
@@ -203,6 +209,7 @@ class TimelineItemContentMessageFactory @Inject constructor(
|
||||
filename = messageType.filename,
|
||||
caption = messageType.caption?.trimEnd(),
|
||||
formattedCaption = parseHtml(messageType.formattedCaption) ?: messageType.caption?.withLinks(),
|
||||
isEdited = content.isEdited,
|
||||
thumbnailSource = messageType.info?.thumbnailSource,
|
||||
fileSource = messageType.source,
|
||||
mimeType = messageType.info?.mimetype ?: MimeTypes.fromFileExtension(fileExtension),
|
||||
|
||||
@@ -36,6 +36,7 @@ class TimelineItemContentStickerFactory @Inject constructor(
|
||||
filename = content.filename,
|
||||
caption = content.body,
|
||||
formattedCaption = null,
|
||||
isEdited = false,
|
||||
mediaSource = content.source,
|
||||
thumbnailSource = content.info.thumbnailSource,
|
||||
mimeType = content.info.mimetype ?: MimeTypes.OctetStream,
|
||||
|
||||
@@ -15,6 +15,7 @@ data class TimelineItemAudioContent(
|
||||
override val filename: String,
|
||||
override val caption: String?,
|
||||
override val formattedCaption: CharSequence?,
|
||||
override val isEdited: Boolean,
|
||||
val duration: Duration,
|
||||
val mediaSource: MediaSource,
|
||||
val mimeType: String,
|
||||
|
||||
@@ -25,6 +25,7 @@ fun aTimelineItemAudioContent(fileName: String = "A sound.mp3") = TimelineItemAu
|
||||
filename = fileName,
|
||||
caption = null,
|
||||
formattedCaption = null,
|
||||
isEdited = false,
|
||||
mimeType = MimeTypes.Mp3,
|
||||
formattedFileSize = "100kB",
|
||||
fileExtension = "mp3",
|
||||
|
||||
@@ -14,8 +14,15 @@ sealed interface TimelineItemEventContent {
|
||||
val type: String
|
||||
}
|
||||
|
||||
interface TimelineItemEventMutableContent {
|
||||
/** Whether the event has been edited. */
|
||||
val isEdited: Boolean
|
||||
}
|
||||
|
||||
@Immutable
|
||||
sealed interface TimelineItemEventContentWithAttachment : TimelineItemEventContent {
|
||||
sealed interface TimelineItemEventContentWithAttachment :
|
||||
TimelineItemEventContent,
|
||||
TimelineItemEventMutableContent {
|
||||
val filename: String
|
||||
val caption: String?
|
||||
val formattedCaption: CharSequence?
|
||||
@@ -74,9 +81,7 @@ fun TimelineItemEventContent.canReact(): Boolean =
|
||||
/**
|
||||
* Whether the event content has been edited.
|
||||
*/
|
||||
fun TimelineItemEventContent.isEdited(): Boolean =
|
||||
when (this) {
|
||||
is TimelineItemTextBasedContent -> isEdited
|
||||
is TimelineItemPollContent -> isEdited
|
||||
else -> false
|
||||
}
|
||||
fun TimelineItemEventContent.isEdited(): Boolean = when (this) {
|
||||
is TimelineItemEventMutableContent -> isEdited
|
||||
else -> false
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ data class TimelineItemFileContent(
|
||||
override val filename: String,
|
||||
override val caption: String?,
|
||||
override val formattedCaption: CharSequence?,
|
||||
override val isEdited: Boolean,
|
||||
val fileSource: MediaSource,
|
||||
val thumbnailSource: MediaSource?,
|
||||
val formattedFileSize: String,
|
||||
|
||||
@@ -26,6 +26,7 @@ fun aTimelineItemFileContent(
|
||||
filename = fileName,
|
||||
caption = null,
|
||||
formattedCaption = null,
|
||||
isEdited = false,
|
||||
thumbnailSource = null,
|
||||
fileSource = MediaSource(url = ""),
|
||||
mimeType = MimeTypes.Pdf,
|
||||
|
||||
@@ -17,6 +17,7 @@ data class TimelineItemImageContent(
|
||||
override val filename: String,
|
||||
override val caption: String?,
|
||||
override val formattedCaption: CharSequence?,
|
||||
override val isEdited: Boolean,
|
||||
val mediaSource: MediaSource,
|
||||
val thumbnailSource: MediaSource?,
|
||||
val formattedFileSize: String,
|
||||
|
||||
@@ -31,6 +31,7 @@ fun aTimelineItemImageContent(
|
||||
filename = filename,
|
||||
caption = caption,
|
||||
formattedCaption = null,
|
||||
isEdited = false,
|
||||
mediaSource = MediaSource(""),
|
||||
thumbnailSource = null,
|
||||
mimeType = MimeTypes.IMAGE_JPEG,
|
||||
|
||||
@@ -19,7 +19,8 @@ data class TimelineItemPollContent(
|
||||
val answerItems: List<PollAnswerItem>,
|
||||
val pollKind: PollKind,
|
||||
val isEnded: Boolean,
|
||||
val isEdited: Boolean
|
||||
) : TimelineItemEventContent {
|
||||
override val isEdited: Boolean,
|
||||
) : TimelineItemEventContent,
|
||||
TimelineItemEventMutableContent {
|
||||
override val type: String = "TimelineItemPollContent"
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ data class TimelineItemStickerContent(
|
||||
override val filename: String,
|
||||
override val caption: String?,
|
||||
override val formattedCaption: CharSequence?,
|
||||
override val isEdited: Boolean,
|
||||
val mediaSource: MediaSource,
|
||||
val thumbnailSource: MediaSource?,
|
||||
val formattedFileSize: String,
|
||||
|
||||
@@ -29,6 +29,7 @@ fun aTimelineItemStickerContent(
|
||||
filename = "a sticker.gif",
|
||||
caption = "a body",
|
||||
formattedCaption = null,
|
||||
isEdited = false,
|
||||
mediaSource = MediaSource(""),
|
||||
thumbnailSource = null,
|
||||
mimeType = MimeTypes.IMAGE_JPEG,
|
||||
|
||||
@@ -14,7 +14,9 @@ import org.jsoup.nodes.Document
|
||||
* Represents a text based content of a timeline item event (a message, a notice, an emote event...).
|
||||
*/
|
||||
@Immutable
|
||||
sealed interface TimelineItemTextBasedContent : TimelineItemEventContent {
|
||||
sealed interface TimelineItemTextBasedContent :
|
||||
TimelineItemEventContent,
|
||||
TimelineItemEventMutableContent {
|
||||
/** The raw body of the event, in Markdown format. */
|
||||
val body: String
|
||||
|
||||
@@ -30,9 +32,6 @@ sealed interface TimelineItemTextBasedContent : TimelineItemEventContent {
|
||||
/** The plain text version of the event body. This is the Markdown version without actual Markdown formatting. */
|
||||
val plainText: String
|
||||
|
||||
/** Whether the event has been edited. */
|
||||
val isEdited: Boolean
|
||||
|
||||
/** The raw HTML body of the event. */
|
||||
val htmlBody: String?
|
||||
get() = htmlDocument?.body()?.html()
|
||||
|
||||
@@ -14,6 +14,7 @@ data class TimelineItemVideoContent(
|
||||
override val filename: String,
|
||||
override val caption: String?,
|
||||
override val formattedCaption: CharSequence?,
|
||||
override val isEdited: Boolean,
|
||||
val duration: Duration,
|
||||
val videoSource: MediaSource,
|
||||
val thumbnailSource: MediaSource?,
|
||||
|
||||
@@ -30,6 +30,7 @@ fun aTimelineItemVideoContent(
|
||||
filename = "Video.mp4",
|
||||
caption = null,
|
||||
formattedCaption = null,
|
||||
isEdited = false,
|
||||
thumbnailSource = null,
|
||||
blurHash = blurhash,
|
||||
aspectRatio = aspectRatio,
|
||||
|
||||
@@ -17,6 +17,7 @@ data class TimelineItemVoiceContent(
|
||||
override val filename: String,
|
||||
override val caption: String?,
|
||||
override val formattedCaption: CharSequence?,
|
||||
override val isEdited: Boolean,
|
||||
val duration: Duration,
|
||||
val mediaSource: MediaSource,
|
||||
val mimeType: String,
|
||||
|
||||
@@ -48,6 +48,7 @@ fun aTimelineItemVoiceContent(
|
||||
filename = filename,
|
||||
caption = caption,
|
||||
formattedCaption = null,
|
||||
isEdited = false,
|
||||
duration = duration,
|
||||
mediaSource = mediaSource,
|
||||
mimeType = mimeType,
|
||||
|
||||
@@ -318,6 +318,7 @@ class MessagesPresenterTest {
|
||||
filename = "image.jpg",
|
||||
caption = null,
|
||||
formattedCaption = null,
|
||||
isEdited = false,
|
||||
mediaSource = MediaSource(AN_AVATAR_URL),
|
||||
thumbnailSource = null,
|
||||
mimeType = MimeTypes.Jpeg,
|
||||
@@ -359,6 +360,7 @@ class MessagesPresenterTest {
|
||||
filename = "video.mp4",
|
||||
caption = null,
|
||||
formattedCaption = null,
|
||||
isEdited = false,
|
||||
duration = 10.milliseconds,
|
||||
videoSource = MediaSource(AN_AVATAR_URL),
|
||||
thumbnailSource = MediaSource(AN_AVATAR_URL),
|
||||
@@ -400,6 +402,7 @@ class MessagesPresenterTest {
|
||||
content = TimelineItemFileContent(
|
||||
filename = "file.pdf",
|
||||
caption = null,
|
||||
isEdited = false,
|
||||
formattedCaption = null,
|
||||
fileSource = MediaSource(AN_AVATAR_URL),
|
||||
thumbnailSource = MediaSource(AN_AVATAR_URL),
|
||||
|
||||
@@ -237,6 +237,7 @@ class TimelineItemContentMessageFactoryTest {
|
||||
filename = "filename",
|
||||
caption = null,
|
||||
formattedCaption = null,
|
||||
isEdited = false,
|
||||
duration = Duration.ZERO,
|
||||
videoSource = MediaSource(url = "url", json = null),
|
||||
thumbnailSource = null,
|
||||
@@ -278,7 +279,8 @@ class TimelineItemContentMessageFactoryTest {
|
||||
thumbnailSource = MediaSource("url_thumbnail"),
|
||||
blurhash = A_BLUR_HASH,
|
||||
),
|
||||
)
|
||||
),
|
||||
isEdited = true,
|
||||
),
|
||||
senderDisambiguatedDisplayName = "Bob",
|
||||
eventId = AN_EVENT_ID,
|
||||
@@ -287,6 +289,7 @@ class TimelineItemContentMessageFactoryTest {
|
||||
filename = "body.mp4",
|
||||
caption = "body.mp4 caption",
|
||||
formattedCaption = SpannedString("formatted"),
|
||||
isEdited = true,
|
||||
duration = 1.minutes,
|
||||
videoSource = MediaSource(url = "url", json = null),
|
||||
thumbnailSource = MediaSource("url_thumbnail"),
|
||||
@@ -315,6 +318,7 @@ class TimelineItemContentMessageFactoryTest {
|
||||
filename = "filename",
|
||||
caption = null,
|
||||
formattedCaption = null,
|
||||
isEdited = false,
|
||||
duration = Duration.ZERO,
|
||||
mediaSource = MediaSource(url = "url", json = null),
|
||||
mimeType = MimeTypes.OctetStream,
|
||||
@@ -339,7 +343,8 @@ class TimelineItemContentMessageFactoryTest {
|
||||
size = 123L,
|
||||
mimetype = MimeTypes.Mp3,
|
||||
)
|
||||
)
|
||||
),
|
||||
isEdited = true,
|
||||
),
|
||||
senderDisambiguatedDisplayName = "Bob",
|
||||
eventId = AN_EVENT_ID,
|
||||
@@ -348,6 +353,7 @@ class TimelineItemContentMessageFactoryTest {
|
||||
filename = "body.mp3",
|
||||
caption = null,
|
||||
formattedCaption = null,
|
||||
isEdited = true,
|
||||
duration = 1.minutes,
|
||||
mediaSource = MediaSource(url = "url", json = null),
|
||||
mimeType = MimeTypes.Mp3,
|
||||
@@ -370,6 +376,7 @@ class TimelineItemContentMessageFactoryTest {
|
||||
eventId = AN_EVENT_ID,
|
||||
caption = null,
|
||||
formattedCaption = null,
|
||||
isEdited = false,
|
||||
duration = Duration.ZERO,
|
||||
mediaSource = MediaSource(url = "url", json = null),
|
||||
mimeType = MimeTypes.OctetStream,
|
||||
@@ -397,7 +404,8 @@ class TimelineItemContentMessageFactoryTest {
|
||||
duration = 1.minutes,
|
||||
waveform = persistentListOf(1f, 2f),
|
||||
),
|
||||
)
|
||||
),
|
||||
isEdited = true,
|
||||
),
|
||||
senderDisambiguatedDisplayName = "Bob",
|
||||
eventId = AN_EVENT_ID,
|
||||
@@ -407,6 +415,7 @@ class TimelineItemContentMessageFactoryTest {
|
||||
filename = "body.ogg",
|
||||
caption = null,
|
||||
formattedCaption = null,
|
||||
isEdited = true,
|
||||
duration = 1.minutes,
|
||||
mediaSource = MediaSource(url = "url", json = null),
|
||||
mimeType = MimeTypes.Ogg,
|
||||
@@ -433,6 +442,7 @@ class TimelineItemContentMessageFactoryTest {
|
||||
filename = "filename",
|
||||
caption = null,
|
||||
formattedCaption = null,
|
||||
isEdited = false,
|
||||
duration = Duration.ZERO,
|
||||
mediaSource = MediaSource(url = "url", json = null),
|
||||
mimeType = MimeTypes.OctetStream,
|
||||
@@ -454,6 +464,7 @@ class TimelineItemContentMessageFactoryTest {
|
||||
filename = "filename",
|
||||
caption = "body",
|
||||
formattedCaption = null,
|
||||
isEdited = false,
|
||||
mediaSource = MediaSource(url = "url", json = null),
|
||||
thumbnailSource = null,
|
||||
formattedFileSize = "0 Bytes",
|
||||
@@ -483,6 +494,7 @@ class TimelineItemContentMessageFactoryTest {
|
||||
filename = "filename",
|
||||
caption = null,
|
||||
formattedCaption = null,
|
||||
isEdited = false,
|
||||
mediaSource = MediaSource(url = "url", json = null),
|
||||
thumbnailSource = MediaSource(url = "thumbnail://url", json = null),
|
||||
formattedFileSize = "8192 Bytes",
|
||||
@@ -520,15 +532,17 @@ class TimelineItemContentMessageFactoryTest {
|
||||
thumbnailSource = MediaSource("url_thumbnail"),
|
||||
blurhash = A_BLUR_HASH,
|
||||
)
|
||||
)
|
||||
),
|
||||
isEdited = true,
|
||||
),
|
||||
senderDisambiguatedDisplayName = "Bob",
|
||||
eventId = AN_EVENT_ID,
|
||||
)
|
||||
val expected = TimelineItemImageContent(
|
||||
filename = "body.jpg",
|
||||
formattedCaption = SpannedString("formatted"),
|
||||
caption = "body.jpg caption",
|
||||
formattedCaption = SpannedString("formatted"),
|
||||
isEdited = true,
|
||||
mediaSource = MediaSource(url = "url", json = null),
|
||||
thumbnailSource = MediaSource("url_thumbnail"),
|
||||
formattedFileSize = "888 Bytes",
|
||||
@@ -556,6 +570,7 @@ class TimelineItemContentMessageFactoryTest {
|
||||
filename = "filename",
|
||||
caption = null,
|
||||
formattedCaption = null,
|
||||
isEdited = false,
|
||||
fileSource = MediaSource(url = "url", json = null),
|
||||
thumbnailSource = null,
|
||||
formattedFileSize = "0 Bytes",
|
||||
@@ -586,7 +601,8 @@ class TimelineItemContentMessageFactoryTest {
|
||||
),
|
||||
thumbnailSource = MediaSource("url_thumbnail"),
|
||||
)
|
||||
)
|
||||
),
|
||||
isEdited = true,
|
||||
),
|
||||
senderDisambiguatedDisplayName = "Bob",
|
||||
eventId = AN_EVENT_ID,
|
||||
@@ -595,6 +611,7 @@ class TimelineItemContentMessageFactoryTest {
|
||||
filename = "body.pdf",
|
||||
caption = null,
|
||||
formattedCaption = null,
|
||||
isEdited = true,
|
||||
fileSource = MediaSource(url = "url", json = null),
|
||||
thumbnailSource = MediaSource("url_thumbnail"),
|
||||
formattedFileSize = "123 Bytes",
|
||||
|
||||
Reference in New Issue
Block a user