Pinned events : introduce banner formatter
This commit is contained in:
parent
0bcfffdddf
commit
039744c4be
4 changed files with 182 additions and 14 deletions
|
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* Copyright (c) 2024 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
|
||||
*
|
||||
* https://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 io.element.android.libraries.eventformatter.api
|
||||
|
||||
import io.element.android.libraries.matrix.api.timeline.item.event.EventTimelineItem
|
||||
|
||||
interface PinnedMessagesBannerFormatter {
|
||||
fun format(event: EventTimelineItem): CharSequence
|
||||
}
|
||||
|
|
@ -0,0 +1,123 @@
|
|||
/*
|
||||
* Copyright (c) 2024 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
|
||||
*
|
||||
* https://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 io.element.android.libraries.eventformatter.impl
|
||||
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.compose.ui.text.AnnotatedString
|
||||
import com.squareup.anvil.annotations.ContributesBinding
|
||||
import io.element.android.libraries.di.SessionScope
|
||||
import io.element.android.libraries.eventformatter.api.PinnedMessagesBannerFormatter
|
||||
import io.element.android.libraries.matrix.api.permalink.PermalinkParser
|
||||
import io.element.android.libraries.matrix.api.timeline.item.event.AudioMessageType
|
||||
import io.element.android.libraries.matrix.api.timeline.item.event.EmoteMessageType
|
||||
import io.element.android.libraries.matrix.api.timeline.item.event.EventTimelineItem
|
||||
import io.element.android.libraries.matrix.api.timeline.item.event.FileMessageType
|
||||
import io.element.android.libraries.matrix.api.timeline.item.event.ImageMessageType
|
||||
import io.element.android.libraries.matrix.api.timeline.item.event.LocationMessageType
|
||||
import io.element.android.libraries.matrix.api.timeline.item.event.MessageContent
|
||||
import io.element.android.libraries.matrix.api.timeline.item.event.MessageType
|
||||
import io.element.android.libraries.matrix.api.timeline.item.event.NoticeMessageType
|
||||
import io.element.android.libraries.matrix.api.timeline.item.event.OtherMessageType
|
||||
import io.element.android.libraries.matrix.api.timeline.item.event.PollContent
|
||||
import io.element.android.libraries.matrix.api.timeline.item.event.RedactedContent
|
||||
import io.element.android.libraries.matrix.api.timeline.item.event.StickerContent
|
||||
import io.element.android.libraries.matrix.api.timeline.item.event.StickerMessageType
|
||||
import io.element.android.libraries.matrix.api.timeline.item.event.TextMessageType
|
||||
import io.element.android.libraries.matrix.api.timeline.item.event.UnableToDecryptContent
|
||||
import io.element.android.libraries.matrix.api.timeline.item.event.VideoMessageType
|
||||
import io.element.android.libraries.matrix.api.timeline.item.event.VoiceMessageType
|
||||
import io.element.android.libraries.matrix.api.timeline.item.event.getDisambiguatedDisplayName
|
||||
import io.element.android.libraries.matrix.ui.messages.toPlainText
|
||||
import io.element.android.libraries.ui.strings.CommonStrings
|
||||
import io.element.android.services.toolbox.api.strings.StringProvider
|
||||
import javax.inject.Inject
|
||||
|
||||
@ContributesBinding(SessionScope::class)
|
||||
class DefaultPinnedMessagesBannerFormatter @Inject constructor(
|
||||
private val sp: StringProvider,
|
||||
private val permalinkParser: PermalinkParser,
|
||||
) : PinnedMessagesBannerFormatter {
|
||||
|
||||
override fun format(event: EventTimelineItem): CharSequence {
|
||||
return when (val content = event.content) {
|
||||
is MessageContent -> processMessageContents(event, content)
|
||||
is StickerContent -> {
|
||||
content.body.prefixWith(CommonStrings.common_sticker)
|
||||
}
|
||||
is UnableToDecryptContent -> {
|
||||
sp.getString(CommonStrings.common_waiting_for_decryption_key)
|
||||
}
|
||||
is PollContent -> {
|
||||
content.question.prefixWith(CommonStrings.a11y_poll)
|
||||
}
|
||||
RedactedContent -> {
|
||||
sp.getString(CommonStrings.common_message_removed)
|
||||
}
|
||||
else -> {
|
||||
sp.getString(CommonStrings.common_unsupported_event)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun processMessageContents(
|
||||
event: EventTimelineItem,
|
||||
messageContent: MessageContent,
|
||||
): CharSequence {
|
||||
|
||||
return when (val messageType: MessageType = messageContent.type) {
|
||||
is EmoteMessageType -> {
|
||||
val senderDisambiguatedDisplayName = event.senderProfile.getDisambiguatedDisplayName(event.sender)
|
||||
"* $senderDisambiguatedDisplayName ${messageType.body}"
|
||||
}
|
||||
is TextMessageType -> {
|
||||
messageType.toPlainText(permalinkParser)
|
||||
}
|
||||
is VideoMessageType -> {
|
||||
messageType.body.prefixWith(CommonStrings.common_video)
|
||||
}
|
||||
is ImageMessageType -> {
|
||||
messageType.body.prefixWith(CommonStrings.common_image)
|
||||
}
|
||||
is StickerMessageType -> {
|
||||
messageType.body.prefixWith(CommonStrings.common_sticker)
|
||||
}
|
||||
is LocationMessageType -> {
|
||||
messageType.body.prefixWith(CommonStrings.common_shared_location)
|
||||
}
|
||||
is FileMessageType -> {
|
||||
messageType.body.prefixWith(CommonStrings.common_file)
|
||||
}
|
||||
is AudioMessageType -> {
|
||||
messageType.body.prefixWith(CommonStrings.common_audio)
|
||||
}
|
||||
is VoiceMessageType -> {
|
||||
messageType.body.prefixWith(CommonStrings.common_voice_message)
|
||||
}
|
||||
is OtherMessageType -> {
|
||||
messageType.body
|
||||
}
|
||||
is NoticeMessageType -> {
|
||||
messageType.body
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun CharSequence.prefixWith(@StringRes res: Int): AnnotatedString {
|
||||
val prefix = sp.getString(res)
|
||||
return prefixWith(prefix)
|
||||
}
|
||||
}
|
||||
|
|
@ -79,7 +79,7 @@ class DefaultRoomLastMessageFormatter @Inject constructor(
|
|||
RedactedContent -> {
|
||||
val message = sp.getString(CommonStrings.common_message_removed)
|
||||
if (!isDmRoom) {
|
||||
prefix(message, senderDisambiguatedDisplayName)
|
||||
message.prefixWith(senderDisambiguatedDisplayName)
|
||||
} else {
|
||||
message
|
||||
}
|
||||
|
|
@ -90,7 +90,7 @@ class DefaultRoomLastMessageFormatter @Inject constructor(
|
|||
is UnableToDecryptContent -> {
|
||||
val message = sp.getString(CommonStrings.common_waiting_for_decryption_key)
|
||||
if (!isDmRoom) {
|
||||
prefix(message, senderDisambiguatedDisplayName)
|
||||
message.prefixWith(senderDisambiguatedDisplayName)
|
||||
} else {
|
||||
message
|
||||
}
|
||||
|
|
@ -113,7 +113,6 @@ class DefaultRoomLastMessageFormatter @Inject constructor(
|
|||
}
|
||||
is LegacyCallInviteContent -> sp.getString(CommonStrings.common_call_invite)
|
||||
is CallNotifyContent -> sp.getString(CommonStrings.common_call_started)
|
||||
else -> null
|
||||
}?.take(MAX_SAFE_LENGTH)
|
||||
}
|
||||
|
||||
|
|
@ -168,16 +167,6 @@ class DefaultRoomLastMessageFormatter @Inject constructor(
|
|||
): CharSequence = if (isDmRoom) {
|
||||
message
|
||||
} else {
|
||||
prefix(message, senderDisambiguatedDisplayName)
|
||||
}
|
||||
|
||||
private fun prefix(message: String, senderDisambiguatedDisplayName: String): AnnotatedString {
|
||||
return buildAnnotatedString {
|
||||
withStyle(SpanStyle(fontWeight = FontWeight.Bold)) {
|
||||
append(senderDisambiguatedDisplayName)
|
||||
}
|
||||
append(": ")
|
||||
append(message)
|
||||
}
|
||||
message.prefixWith(senderDisambiguatedDisplayName)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* Copyright (c) 2024 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
|
||||
*
|
||||
* https://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 io.element.android.libraries.eventformatter.impl
|
||||
|
||||
import androidx.compose.ui.text.AnnotatedString
|
||||
import androidx.compose.ui.text.SpanStyle
|
||||
import androidx.compose.ui.text.buildAnnotatedString
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.withStyle
|
||||
|
||||
internal fun CharSequence.prefixWith(prefix: String): AnnotatedString {
|
||||
return buildAnnotatedString {
|
||||
withStyle(SpanStyle(fontWeight = FontWeight.Bold)) {
|
||||
append(prefix)
|
||||
}
|
||||
append(": ")
|
||||
append(this@prefixWith)
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue