feat: initial system message impl
Signed-off-by: Infi <wingit@geist.ga>
This commit is contained in:
parent
963935e037
commit
5683dd85ce
|
|
@ -95,5 +95,10 @@ data class Masquerade(
|
|||
@Serializable
|
||||
data class SystemInfo(
|
||||
val type: String? = null,
|
||||
val id: String? = null
|
||||
val id: String? = null,
|
||||
val name: String? = null,
|
||||
val by: String? = null,
|
||||
val from: String? = null,
|
||||
val to: String? = null,
|
||||
val content: String? = null,
|
||||
)
|
||||
|
|
@ -0,0 +1,245 @@
|
|||
package chat.revolt.components.chat
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Info
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.LocalContentColor
|
||||
import androidx.compose.material3.LocalTextStyle
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.CompositionLocalProvider
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.dp
|
||||
import chat.revolt.R
|
||||
import chat.revolt.api.schemas.Message
|
||||
|
||||
enum class SystemMessageType(val type: String) {
|
||||
CHANNEL_OWNERSHIP_CHANGED("channel_ownership_changed"),
|
||||
CHANNEL_ICON_CHANGED("channel_icon_changed"),
|
||||
CHANNEL_DESCRIPTION_CHANGED("channel_description_changed"),
|
||||
CHANNEL_RENAMED("channel_renamed"),
|
||||
USER_REMOVE("user_remove"),
|
||||
USER_ADDED("user_added"),
|
||||
USER_BANNED("user_banned"),
|
||||
USER_KICKED("user_kicked"),
|
||||
USER_LEFT("user_left"),
|
||||
USER_JOINED("user_joined"),
|
||||
TEXT("text"),
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun SystemMessage(
|
||||
message: Message
|
||||
) {
|
||||
if (message.system == null) return
|
||||
|
||||
val systemMessageType =
|
||||
SystemMessageType.values().firstOrNull { it.type == message.system.type }
|
||||
|
||||
if (systemMessageType == null) {
|
||||
Text(text = message.system.toString())
|
||||
return
|
||||
}
|
||||
|
||||
CompositionLocalProvider(
|
||||
LocalContentColor provides LocalContentColor.current.copy(alpha = 0.7f),
|
||||
LocalTextStyle provides LocalTextStyle.current.copy(
|
||||
fontWeight = FontWeight.Light
|
||||
)
|
||||
) {
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
modifier = Modifier.padding(horizontal = 10.dp, vertical = 4.dp)
|
||||
) {
|
||||
SystemMessageIconWithBackground(type = systemMessageType)
|
||||
|
||||
Spacer(modifier = Modifier.width(10.dp))
|
||||
|
||||
when (systemMessageType) {
|
||||
SystemMessageType.CHANNEL_OWNERSHIP_CHANGED -> {
|
||||
Text(text = "Channel ownership changed from ${message.system.from} to ${message.system.to}")
|
||||
}
|
||||
|
||||
SystemMessageType.CHANNEL_ICON_CHANGED -> {
|
||||
Text(text = "Channel icon changed by ${message.system.by}")
|
||||
}
|
||||
|
||||
SystemMessageType.CHANNEL_DESCRIPTION_CHANGED -> {
|
||||
Text(text = "Channel description changed by ${message.system.by}")
|
||||
}
|
||||
|
||||
SystemMessageType.CHANNEL_RENAMED -> {
|
||||
Text(text = "Channel renamed to ${message.system.name} by ${message.system.by}")
|
||||
}
|
||||
|
||||
SystemMessageType.USER_REMOVE -> {
|
||||
Text(text = "User ${message.system.id} removed by ${message.system.by}")
|
||||
}
|
||||
|
||||
SystemMessageType.USER_ADDED -> {
|
||||
Text(text = "User ${message.system.id} added by ${message.system.by}")
|
||||
}
|
||||
|
||||
SystemMessageType.USER_BANNED -> {
|
||||
Text(text = "User ${message.system.id} banned")
|
||||
}
|
||||
|
||||
SystemMessageType.USER_KICKED -> {
|
||||
Text(text = "User ${message.system.id} kicked")
|
||||
}
|
||||
|
||||
SystemMessageType.USER_LEFT -> {
|
||||
Text(text = "User ${message.system.id} left")
|
||||
}
|
||||
|
||||
SystemMessageType.USER_JOINED -> {
|
||||
Text(text = "User ${message.system.id} joined")
|
||||
}
|
||||
|
||||
SystemMessageType.TEXT -> {
|
||||
message.system.content?.let { Text(text = it) }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun SystemMessageIcon(
|
||||
type: SystemMessageType,
|
||||
modifier: Modifier = Modifier,
|
||||
size: Dp = 24.dp
|
||||
) {
|
||||
when (type) {
|
||||
SystemMessageType.CHANNEL_OWNERSHIP_CHANGED -> {
|
||||
Icon(
|
||||
painter = painterResource(R.drawable.ic_key_arrow_right_24dp),
|
||||
contentDescription = stringResource(R.string.system_message_ownership_changed_alt),
|
||||
tint = LocalContentColor.current,
|
||||
modifier = modifier.size(size)
|
||||
)
|
||||
}
|
||||
|
||||
SystemMessageType.CHANNEL_ICON_CHANGED -> {
|
||||
Icon(
|
||||
painter = painterResource(R.drawable.ic_image_multiple_24dp),
|
||||
contentDescription = stringResource(R.string.system_message_channel_icon_changed_alt),
|
||||
tint = LocalContentColor.current,
|
||||
modifier = modifier.size(size)
|
||||
)
|
||||
}
|
||||
|
||||
SystemMessageType.CHANNEL_DESCRIPTION_CHANGED -> {
|
||||
Icon(
|
||||
painter = painterResource(R.drawable.ic_text_box_multiple_24dp),
|
||||
contentDescription = stringResource(R.string.system_message_channel_description_changed_alt),
|
||||
tint = LocalContentColor.current,
|
||||
modifier = modifier.size(size)
|
||||
)
|
||||
}
|
||||
|
||||
SystemMessageType.CHANNEL_RENAMED -> {
|
||||
Icon(
|
||||
painter = painterResource(R.drawable.ic_cursor_text_24dp),
|
||||
contentDescription = stringResource(R.string.system_message_channel_renamed_alt),
|
||||
tint = LocalContentColor.current,
|
||||
modifier = modifier.size(size)
|
||||
)
|
||||
}
|
||||
|
||||
SystemMessageType.USER_REMOVE -> {
|
||||
Icon(
|
||||
painter = painterResource(R.drawable.ic_account_cancel_24dp),
|
||||
contentDescription = stringResource(R.string.system_message_user_removed_alt),
|
||||
tint = LocalContentColor.current,
|
||||
modifier = modifier.size(size)
|
||||
)
|
||||
}
|
||||
|
||||
SystemMessageType.USER_ADDED -> {
|
||||
Icon(
|
||||
painter = painterResource(R.drawable.ic_account_plus_24dp),
|
||||
contentDescription = stringResource(R.string.system_message_user_added_alt),
|
||||
tint = LocalContentColor.current,
|
||||
modifier = modifier.size(size)
|
||||
)
|
||||
}
|
||||
|
||||
SystemMessageType.USER_BANNED -> {
|
||||
Icon(
|
||||
painter = painterResource(R.drawable.ic_gavel_24dp),
|
||||
contentDescription = stringResource(R.string.system_message_user_banned_alt),
|
||||
tint = LocalContentColor.current,
|
||||
modifier = modifier.size(size)
|
||||
)
|
||||
}
|
||||
|
||||
SystemMessageType.USER_KICKED -> {
|
||||
Icon(
|
||||
painter = painterResource(R.drawable.ic_shield_24dp),
|
||||
contentDescription = stringResource(R.string.system_message_user_kicked_alt),
|
||||
tint = LocalContentColor.current,
|
||||
modifier = modifier.size(size)
|
||||
)
|
||||
}
|
||||
|
||||
SystemMessageType.USER_LEFT -> {
|
||||
Icon(
|
||||
painter = painterResource(R.drawable.ic_account_arrow_left_24dp),
|
||||
contentDescription = stringResource(R.string.system_message_user_left_alt),
|
||||
tint = LocalContentColor.current,
|
||||
modifier = modifier.size(size)
|
||||
)
|
||||
}
|
||||
|
||||
SystemMessageType.USER_JOINED -> {
|
||||
Icon(
|
||||
painter = painterResource(R.drawable.ic_account_arrow_right_24dp),
|
||||
contentDescription = stringResource(R.string.system_message_user_joined_alt),
|
||||
tint = LocalContentColor.current,
|
||||
modifier = modifier.size(size)
|
||||
)
|
||||
}
|
||||
|
||||
SystemMessageType.TEXT -> {
|
||||
Icon(
|
||||
imageVector = Icons.Default.Info,
|
||||
contentDescription = stringResource(R.string.system_message_text_alt),
|
||||
tint = LocalContentColor.current,
|
||||
modifier = modifier.size(size)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun SystemMessageIconWithBackground(
|
||||
type: SystemMessageType,
|
||||
modifier: Modifier = Modifier,
|
||||
size: Dp = 40.dp
|
||||
) {
|
||||
Box(
|
||||
contentAlignment = Alignment.Center,
|
||||
modifier = modifier
|
||||
.clip(CircleShape)
|
||||
.background(MaterialTheme.colorScheme.primary.copy(alpha = 0.3f))
|
||||
.size(size)
|
||||
) {
|
||||
SystemMessageIcon(type = type)
|
||||
}
|
||||
}
|
||||
|
|
@ -60,6 +60,7 @@ import chat.revolt.api.internals.ChannelUtils
|
|||
import chat.revolt.api.routes.microservices.autumn.FileArgs
|
||||
import chat.revolt.components.chat.Message
|
||||
import chat.revolt.components.chat.MessageField
|
||||
import chat.revolt.components.chat.SystemMessage
|
||||
import chat.revolt.components.screens.chat.AttachmentManager
|
||||
import chat.revolt.components.screens.chat.ChannelHeader
|
||||
import chat.revolt.components.screens.chat.ReplyManager
|
||||
|
|
@ -244,63 +245,66 @@ fun ChannelScreen(
|
|||
items = viewModel.renderableMessages,
|
||||
key = { it.id!! }
|
||||
) { message ->
|
||||
Message(
|
||||
message,
|
||||
parse = {
|
||||
val parser = MarkdownParser()
|
||||
.addRules(
|
||||
SimpleMarkdownRules.createEscapeRule(),
|
||||
UserMentionRule(),
|
||||
ChannelMentionRule(),
|
||||
CustomEmoteRule(),
|
||||
)
|
||||
.addRules(
|
||||
createCodeRule(context, codeBlockColor.toArgb()),
|
||||
createInlineCodeRule(context, codeBlockColor.toArgb()),
|
||||
)
|
||||
.addRules(
|
||||
SimpleMarkdownRules.createSimpleMarkdownRules(
|
||||
includeEscapeRule = false
|
||||
when {
|
||||
message.system != null -> SystemMessage(message)
|
||||
else -> Message(
|
||||
message,
|
||||
parse = {
|
||||
val parser = MarkdownParser()
|
||||
.addRules(
|
||||
SimpleMarkdownRules.createEscapeRule(),
|
||||
UserMentionRule(),
|
||||
ChannelMentionRule(),
|
||||
CustomEmoteRule(),
|
||||
)
|
||||
.addRules(
|
||||
createCodeRule(context, codeBlockColor.toArgb()),
|
||||
createInlineCodeRule(context, codeBlockColor.toArgb()),
|
||||
)
|
||||
.addRules(
|
||||
SimpleMarkdownRules.createSimpleMarkdownRules(
|
||||
includeEscapeRule = false
|
||||
)
|
||||
)
|
||||
|
||||
SimpleRenderer.render(
|
||||
source = it.content ?: "",
|
||||
parser = parser,
|
||||
initialState = MarkdownState(0),
|
||||
renderContext = MarkdownContext(
|
||||
memberMap = mapOf(),
|
||||
userMap = RevoltAPI.userCache.toMap(),
|
||||
channelMap = RevoltAPI.channelCache.mapValues { ch ->
|
||||
ch.value.name ?: ch.value.id ?: "#DeletedChannel"
|
||||
},
|
||||
emojiMap = RevoltAPI.emojiCache,
|
||||
serverId = channel.server ?: "",
|
||||
)
|
||||
)
|
||||
|
||||
SimpleRenderer.render(
|
||||
source = it.content ?: "",
|
||||
parser = parser,
|
||||
initialState = MarkdownState(0),
|
||||
renderContext = MarkdownContext(
|
||||
memberMap = mapOf(),
|
||||
userMap = RevoltAPI.userCache.toMap(),
|
||||
channelMap = RevoltAPI.channelCache.mapValues { ch ->
|
||||
ch.value.name ?: ch.value.id ?: "#DeletedChannel"
|
||||
},
|
||||
emojiMap = RevoltAPI.emojiCache,
|
||||
serverId = channel.server ?: "",
|
||||
)
|
||||
)
|
||||
},
|
||||
onMessageContextMenu = {
|
||||
messageContextSheetShown = true
|
||||
messageContextSheetTarget = message.id ?: ""
|
||||
},
|
||||
onAvatarClick = {
|
||||
message.author?.let { author ->
|
||||
onUserSheetOpenFor(author, channel.server)
|
||||
}
|
||||
},
|
||||
canReply = true,
|
||||
onReply = {
|
||||
if (viewModel.pendingReplies.size >= 5) {
|
||||
Toast.makeText(
|
||||
context,
|
||||
context.getString(R.string.too_many_replies, 5),
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
return@Message
|
||||
}
|
||||
viewModel.replyToMessage(message)
|
||||
},
|
||||
)
|
||||
},
|
||||
onMessageContextMenu = {
|
||||
messageContextSheetShown = true
|
||||
messageContextSheetTarget = message.id ?: ""
|
||||
},
|
||||
onAvatarClick = {
|
||||
message.author?.let { author ->
|
||||
onUserSheetOpenFor(author, channel.server)
|
||||
}
|
||||
},
|
||||
canReply = true,
|
||||
onReply = {
|
||||
if (viewModel.pendingReplies.size >= 5) {
|
||||
Toast.makeText(
|
||||
context,
|
||||
context.getString(R.string.too_many_replies, 5),
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
return@Message
|
||||
}
|
||||
viewModel.replyToMessage(message)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
item {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:height="24dp"
|
||||
android:width="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="#ffffff"
|
||||
android:pathData="M17 18H21V16H17V14L14 17L17 20V18M11 4C8.8 4 7 5.8 7 8S8.8 12 11 12 15 10.2 15 8 13.2 4 11 4M11 14C6.6 14 3 15.8 3 18V20H12.5C12.2 19.2 12 18.4 12 17.5C12 16.3 12.3 15.2 12.9 14.1C12.3 14.1 11.7 14 11 14" />
|
||||
</vector>
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:height="24dp"
|
||||
android:width="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="#ffffff"
|
||||
android:pathData="M18 16H14V18H18V20L21 17L18 14V16M11 4C8.8 4 7 5.8 7 8S8.8 12 11 12 15 10.2 15 8 13.2 4 11 4M11 14C6.6 14 3 15.8 3 18V20H12.5C12.2 19.2 12 18.4 12 17.5C12 16.3 12.3 15.2 12.9 14.1C12.3 14.1 11.7 14 11 14" />
|
||||
</vector>
|
||||
|
|
@ -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:fillColor="#ffffff"
|
||||
android:pathData="M10 4A4 4 0 0 0 6 8A4 4 0 0 0 10 12A4 4 0 0 0 14 8A4 4 0 0 0 10 4M17.5 13C15 13 13 15 13 17.5C13 20 15 22 17.5 22C20 22 22 20 22 17.5C22 15 20 13 17.5 13M10 14C5.58 14 2 15.79 2 18V20H11.5A6.5 6.5 0 0 1 11 17.5A6.5 6.5 0 0 1 11.95 14.14C11.32 14.06 10.68 14 10 14M17.5 14.5C19.16 14.5 20.5 15.84 20.5 17.5C20.5 18.06 20.35 18.58 20.08 19L16 14.92C16.42 14.65 16.94 14.5 17.5 14.5M14.92 16L19 20.08C18.58 20.35 18.06 20.5 17.5 20.5C15.84 20.5 14.5 19.16 14.5 17.5C14.5 16.94 14.65 16.42 14.92 16Z" />
|
||||
</vector>
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:height="24dp"
|
||||
android:width="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="#ffffff"
|
||||
android:pathData="M15,14C12.33,14 7,15.33 7,18V20H23V18C23,15.33 17.67,14 15,14M6,10V7H4V10H1V12H4V15H6V12H9V10M15,12A4,4 0 0,0 19,8A4,4 0 0,0 15,4A4,4 0 0,0 11,8A4,4 0 0,0 15,12Z" />
|
||||
</vector>
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:height="24dp"
|
||||
android:width="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="#ffffff"
|
||||
android:pathData="M13,19A1,1 0 0,0 14,20H16V22H13.5C12.95,22 12,21.55 12,21C12,21.55 11.05,22 10.5,22H8V20H10A1,1 0 0,0 11,19V5A1,1 0 0,0 10,4H8V2H10.5C11.05,2 12,2.45 12,3C12,2.45 12.95,2 13.5,2H16V4H14A1,1 0 0,0 13,5V19Z" />
|
||||
</vector>
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:height="24dp"
|
||||
android:width="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="#ffffff"
|
||||
android:pathData="M2.3,20.28L11.9,10.68L10.5,9.26L9.78,9.97C9.39,10.36 8.76,10.36 8.37,9.97L7.66,9.26C7.27,8.87 7.27,8.24 7.66,7.85L13.32,2.19C13.71,1.8 14.34,1.8 14.73,2.19L15.44,2.9C15.83,3.29 15.83,3.92 15.44,4.31L14.73,5L16.15,6.43C16.54,6.04 17.17,6.04 17.56,6.43C17.95,6.82 17.95,7.46 17.56,7.85L18.97,9.26L19.68,8.55C20.07,8.16 20.71,8.16 21.1,8.55L21.8,9.26C22.19,9.65 22.19,10.29 21.8,10.68L16.15,16.33C15.76,16.72 15.12,16.72 14.73,16.33L14.03,15.63C13.63,15.24 13.63,14.6 14.03,14.21L14.73,13.5L13.32,12.09L3.71,21.7C3.32,22.09 2.69,22.09 2.3,21.7C1.91,21.31 1.91,20.67 2.3,20.28M20,19A2,2 0 0,1 22,21V22H12V21A2,2 0 0,1 14,19H20Z" />
|
||||
</vector>
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:height="24dp"
|
||||
android:width="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="#ffffff"
|
||||
android:pathData="M22,16V4A2,2 0 0,0 20,2H8A2,2 0 0,0 6,4V16A2,2 0 0,0 8,18H20A2,2 0 0,0 22,16M11,12L13.03,14.71L16,11L20,16H8M2,6V20A2,2 0 0,0 4,22H18V20H4V6" />
|
||||
</vector>
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:height="24dp"
|
||||
android:width="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="#ffffff"
|
||||
android:pathData="M11.7 6C11.1 4.2 9.4 3 7.5 3C5 3 3 5 3 7.5S5 12 7.5 12C9.5 12 11.1 10.8 11.7 9H15V12H18V9H21V6H11.7M7.5 9C6.7 9 6 8.3 6 7.5S6.7 6 7.5 6 9 6.7 9 7.5 8.3 9 7.5 9M13 21V19H8V17H13V15L16 18L13 21" />
|
||||
</vector>
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:height="24dp"
|
||||
android:width="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="#ffffff"
|
||||
android:pathData="M12,1L3,5V11C3,16.55 6.84,21.74 12,23C17.16,21.74 21,16.55 21,11V5L12,1Z" />
|
||||
</vector>
|
||||
|
|
@ -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:fillColor="#ffffff"
|
||||
android:pathData="M16,15H9V13H16M19,11H9V9H19M19,7H9V5H19M21,1H7C5.89,1 5,1.89 5,3V17C5,18.11 5.9,19 7,19H21C22.11,19 23,18.11 23,17V3C23,1.89 22.1,1 21,1M3,5V21H19V23H3A2,2 0 0,1 1,21V5H3Z" />
|
||||
</vector>
|
||||
|
|
@ -134,6 +134,18 @@
|
|||
<string name="reply_message_not_cached">Unknown message, tap to jump</string>
|
||||
<string name="reply_message_empty_has_attachments">Sent attachments</string>
|
||||
|
||||
<string name="system_message_ownership_changed_alt">Ownership changed</string>
|
||||
<string name="system_message_channel_icon_changed_alt">Channel icon changed</string>
|
||||
<string name="system_message_channel_description_changed_alt">Channel description changed</string>
|
||||
<string name="system_message_channel_renamed_alt">Channel renamed</string>
|
||||
<string name="system_message_user_removed_alt">User removed</string>
|
||||
<string name="system_message_user_added_alt">User added</string>
|
||||
<string name="system_message_user_banned_alt">User banned</string>
|
||||
<string name="system_message_user_kicked_alt">User kicked</string>
|
||||
<string name="system_message_user_left_alt">User left</string>
|
||||
<string name="system_message_user_joined_alt">User joined</string>
|
||||
<string name="system_message_text_alt">System message</string>
|
||||
|
||||
<string name="today">Today</string>
|
||||
<string name="yesterday">Yesterday</string>
|
||||
<string name="x_days_ago">%1$d days ago</string>
|
||||
|
|
|
|||
Loading…
Reference in New Issue