Unverified Commit 8aa843bc authored by Lucio Maciel's avatar Lucio Maciel Committed by GitHub

Merge branch 'beta' into fix/cas

parents 8127853f a9009bac
......@@ -291,6 +291,9 @@ class ChatRoomAdapter(
R.id.action_menu_msg_react -> {
actionSelectListener?.showReactions(id)
}
R.id.action_message_permalink -> {
actionSelectListener?.copyPermalink(id)
}
else -> {
TODO("Not implemented")
}
......@@ -310,5 +313,6 @@ class ChatRoomAdapter(
fun showReactions(id: String)
fun openDirectMessage(roomName: String, message: String)
fun sendMessage(chatRoomId: String, text: String)
fun copyPermalink(id: String)
}
}
\ No newline at end of file
}
......@@ -541,7 +541,7 @@ class ChatRoomPresenter @Inject constructor(
val messages =
retryIO(description = "history($chatRoomId, $roomType, $instant)") {
client.history(
chatRoomId, roomType, count = 50,
chatRoomId, roomType, count = 50,
oldest = instant
)
}
......@@ -658,6 +658,7 @@ class ChatRoomPresenter @Inject constructor(
try {
messagesRepository.getById(messageId)?.let { m ->
view.copyToClipboard(m.message)
view.showMessage(R.string.msg_message_copied)
}
} catch (e: RocketChatException) {
Timber.e(e)
......@@ -895,6 +896,42 @@ class ChatRoomPresenter @Inject constructor(
}
}
// TODO: move this to new interactor or FetchChatRoomsInteractor?
private suspend fun getChatRoomAsync(roomId: String): ChatRoom? = withContext(CommonPool) {
return@withContext dbManager.chatRoomDao().get(roomId)?.let {
with(it.chatRoom) {
ChatRoom(
id = id,
subscriptionId = subscriptionId,
type = roomTypeOf(type),
unread = unread,
broadcast = broadcast ?: false,
alert = alert,
fullName = fullname,
name = name,
favorite = favorite ?: false,
default = isDefault ?: false,
readonly = readonly,
open = open,
lastMessage = null,
archived = false,
status = null,
user = null,
userMentions = userMentions,
client = client,
announcement = null,
description = null,
groupMentions = groupMentions,
roles = null,
topic = null,
lastSeen = this.lastSeen,
timestamp = timestamp,
updatedAt = updatedAt
)
}
}
}
// TODO: move this to new interactor or FetchChatRoomsInteractor?
private suspend fun getChatRoomsAsync(name: String? = null): List<ChatRoom> = withContext(CommonPool) {
return@withContext dbManager.chatRoomDao().getAllSync().filter {
......@@ -977,6 +1014,24 @@ class ChatRoomPresenter @Inject constructor(
}
}
fun copyPermalink(messageId: String) {
launchUI(strategy) {
try {
messagesRepository.getById(messageId)?.let { message ->
getChatRoomAsync(message.roomId)?.let { chatRoom ->
val models = mapper.map(message)
models.firstOrNull()?.permalink?.let {
view.copyToClipboard(it)
view.showMessage(R.string.msg_permalink_copied)
}
}
}
} catch (ex: Exception) {
Timber.e(ex)
}
}
}
/**
* Send an emoji reaction to a message.
*/
......
......@@ -621,7 +621,6 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
ui {
val clipboard = it.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
clipboard.primaryClip = ClipData.newPlainText("", message)
showToast(R.string.msg_message_copied)
}
}
......@@ -1059,6 +1058,10 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
}
}
override fun copyPermalink(id: String) {
presenter.copyPermalink(id)
}
override fun showReactions(id: String) {
presenter.showReactions(id)
}
......
......@@ -73,4 +73,4 @@ class MessageActionsBottomSheet : BottomSheetDialogFragment() {
}
}
}
}
\ No newline at end of file
}
......@@ -20,7 +20,8 @@ data class ActionsAttachmentUiModel(
override var unread: Boolean? = null,
override var menuItemsToHide: MutableList<Int> = mutableListOf(),
override var currentDayMarkerText: String,
override var showDayMarker: Boolean
override var showDayMarker: Boolean,
override var permalink: String
) : BaseAttachmentUiModel<ActionsAttachment> {
override val viewType: Int
get() = BaseUiModel.ViewType.ACTIONS_ATTACHMENT.viewType
......
......@@ -5,20 +5,21 @@ import chat.rocket.core.model.Message
import chat.rocket.core.model.attachment.AudioAttachment
data class AudioAttachmentUiModel(
override val message: Message,
override val rawData: AudioAttachment,
override val messageId: String,
override val attachmentUrl: String,
override val attachmentTitle: CharSequence,
override val id: Long,
override var reactions: List<ReactionUiModel>,
override var nextDownStreamMessage: BaseUiModel<*>? = null,
override var preview: Message? = null,
override var isTemporary: Boolean = false,
override var unread: Boolean? = null,
override var menuItemsToHide: MutableList<Int> = mutableListOf(),
override var currentDayMarkerText: String,
override var showDayMarker: Boolean
override val message: Message,
override val rawData: AudioAttachment,
override val messageId: String,
override val attachmentUrl: String,
override val attachmentTitle: CharSequence,
override val id: Long,
override var reactions: List<ReactionUiModel>,
override var nextDownStreamMessage: BaseUiModel<*>? = null,
override var preview: Message? = null,
override var isTemporary: Boolean = false,
override var unread: Boolean? = null,
override var menuItemsToHide: MutableList<Int> = mutableListOf(),
override var currentDayMarkerText: String,
override var showDayMarker: Boolean,
override var permalink: String
) : BaseFileAttachmentUiModel<AudioAttachment> {
override val viewType: Int
get() = BaseUiModel.ViewType.AUDIO_ATTACHMENT.viewType
......
......@@ -20,7 +20,7 @@ data class AuthorAttachmentUiModel(
override var unread: Boolean? = null,
override var menuItemsToHide: MutableList<Int> = mutableListOf(),
override var currentDayMarkerText: String,
override var showDayMarker: Boolean
override var showDayMarker: Boolean, override var permalink: String
) : BaseAttachmentUiModel<AuthorAttachment> {
override val viewType: Int
get() = BaseUiModel.ViewType.AUTHOR_ATTACHMENT.viewType
......
......@@ -17,6 +17,7 @@ interface BaseUiModel<out T> {
var currentDayMarkerText: String
var showDayMarker: Boolean
var menuItemsToHide: MutableList<Int>
var permalink: String
enum class ViewType(val viewType: Int) {
MESSAGE(0),
......
......@@ -20,7 +20,8 @@ data class ColorAttachmentUiModel(
override var unread: Boolean?,
override var menuItemsToHide: MutableList<Int> = mutableListOf(),
override var currentDayMarkerText: String,
override var showDayMarker: Boolean
override var showDayMarker: Boolean,
override var permalink: String
) : BaseAttachmentUiModel<ColorAttachment> {
override val viewType: Int
get() = BaseUiModel.ViewType.COLOR_ATTACHMENT.viewType
......
......@@ -18,7 +18,8 @@ data class GenericFileAttachmentUiModel(
override var unread: Boolean? = null,
override var menuItemsToHide: MutableList<Int> = mutableListOf(),
override var currentDayMarkerText: String,
override var showDayMarker: Boolean
override var showDayMarker: Boolean,
override var permalink: String
) : BaseFileAttachmentUiModel<GenericFileAttachment> {
override val viewType: Int
get() = BaseUiModel.ViewType.GENERIC_FILE_ATTACHMENT.viewType
......
......@@ -20,7 +20,8 @@ data class ImageAttachmentUiModel(
override var unread: Boolean? = null,
override var menuItemsToHide: MutableList<Int> = mutableListOf(),
override var currentDayMarkerText: String,
override var showDayMarker: Boolean
override var showDayMarker: Boolean,
override var permalink: String
) : BaseFileAttachmentUiModel<ImageAttachment> {
override val viewType: Int
get() = BaseUiModel.ViewType.IMAGE_ATTACHMENT.viewType
......
......@@ -19,7 +19,8 @@ data class MessageAttachmentUiModel(
override var unread: Boolean? = null,
override var menuItemsToHide: MutableList<Int> = mutableListOf(),
override var currentDayMarkerText: String,
override var showDayMarker: Boolean
override var showDayMarker: Boolean,
override var permalink: String
) : BaseUiModel<Message> {
override val viewType: Int
get() = BaseUiModel.ViewType.MESSAGE_ATTACHMENT.viewType
......
......@@ -15,7 +15,8 @@ data class MessageReplyUiModel(
override var unread: Boolean? = null,
override var menuItemsToHide: MutableList<Int> = mutableListOf(),
override var currentDayMarkerText: String,
override var showDayMarker: Boolean
override var showDayMarker: Boolean,
override var permalink: String
) : BaseUiModel<MessageReply> {
override val viewType: Int
get() = BaseUiModel.ViewType.MESSAGE_REPLY.viewType
......
......@@ -20,7 +20,8 @@ data class MessageUiModel(
override var unread: Boolean? = null,
var isFirstUnread: Boolean,
override var isTemporary: Boolean = false,
override var menuItemsToHide: MutableList<Int> = mutableListOf()
override var menuItemsToHide: MutableList<Int> = mutableListOf(),
override var permalink: String
) : BaseMessageUiModel<Message> {
override val viewType: Int
get() = BaseUiModel.ViewType.MESSAGE.viewType
......
......@@ -19,7 +19,8 @@ data class UrlPreviewUiModel(
override var unread: Boolean? = null,
override var menuItemsToHide: MutableList<Int> = mutableListOf(),
override var currentDayMarkerText: String,
override var showDayMarker: Boolean
override var showDayMarker: Boolean,
override var permalink: String
) : BaseUiModel<Url> {
override val viewType: Int
get() = BaseUiModel.ViewType.URL_PREVIEW.viewType
......
......@@ -5,20 +5,21 @@ import chat.rocket.core.model.Message
import chat.rocket.core.model.attachment.VideoAttachment
data class VideoAttachmentUiModel(
override val message: Message,
override val rawData: VideoAttachment,
override val messageId: String,
override val attachmentUrl: String,
override val attachmentTitle: CharSequence,
override val id: Long,
override var reactions: List<ReactionUiModel>,
override var nextDownStreamMessage: BaseUiModel<*>? = null,
override var preview: Message? = null,
override var isTemporary: Boolean = false,
override var unread: Boolean? = null,
override var menuItemsToHide: MutableList<Int> = mutableListOf(),
override var currentDayMarkerText: String,
override var showDayMarker: Boolean
override val message: Message,
override val rawData: VideoAttachment,
override val messageId: String,
override val attachmentUrl: String,
override val attachmentTitle: CharSequence,
override val id: Long,
override var reactions: List<ReactionUiModel>,
override var nextDownStreamMessage: BaseUiModel<*>? = null,
override var preview: Message? = null,
override var isTemporary: Boolean = false,
override var unread: Boolean? = null,
override var menuItemsToHide: MutableList<Int> = mutableListOf(),
override var currentDayMarkerText: String,
override var showDayMarker: Boolean,
override var permalink: String
) : BaseFileAttachmentUiModel<VideoAttachment> {
override val viewType: Int
get() = BaseUiModel.ViewType.VIDEO_ATTACHMENT.viewType
......
......@@ -2,7 +2,9 @@ package chat.rocket.android.chatroom.uimodel.suggestion
import chat.rocket.android.suggestions.model.SuggestionModel
class ChatRoomSuggestionUiModel(text: String,
val fullName: String,
val name: String,
searchList: List<String>) : SuggestionModel(text, searchList, false)
\ No newline at end of file
class ChatRoomSuggestionUiModel(
text: String,
val fullName: String,
val name: String,
searchList: List<String>
) : SuggestionModel(text, searchList, false)
......@@ -2,6 +2,8 @@ package chat.rocket.android.chatroom.uimodel.suggestion
import chat.rocket.android.suggestions.model.SuggestionModel
class CommandSuggestionUiModel(text: String,
val description: String,
searchList: List<String>) : SuggestionModel(text, searchList)
\ No newline at end of file
class CommandSuggestionUiModel(
text: String,
val description: String,
searchList: List<String>
) : SuggestionModel(text, searchList)
\ No newline at end of file
......@@ -3,13 +3,15 @@ package chat.rocket.android.chatroom.uimodel.suggestion
import chat.rocket.android.suggestions.model.SuggestionModel
import chat.rocket.common.model.UserStatus
class PeopleSuggestionUiModel(val imageUri: String?,
text: String,
val username: String,
val name: String,
val status: UserStatus?,
pinned: Boolean = false,
searchList: List<String>) : SuggestionModel(text, searchList, pinned) {
class PeopleSuggestionUiModel(
val imageUri: String?,
text: String,
val username: String,
val name: String,
val status: UserStatus?,
pinned: Boolean = false,
searchList: List<String>
) : SuggestionModel(text, searchList, pinned) {
override fun toString(): String {
return "PeopleSuggestionUiModel(imageUri='$imageUri', username='$username', name='$name', status=$status, pinned=$pinned)"
......
......@@ -17,7 +17,7 @@ class MessageHelper @Inject constructor(
private val currentServer = serverInteractor.get()!!
private val settings: PublicSettings = getSettingsInteractor.get(currentServer)
fun createPermalink(message: Message, chatRoom: ChatRoom): String {
fun createPermalink(message: Message, chatRoom: ChatRoom, markdownSyntax: Boolean = true): String {
val type = when (chatRoom.type) {
is RoomType.PrivateGroup -> "group"
is RoomType.Channel -> "channel"
......@@ -30,7 +30,8 @@ class MessageHelper @Inject constructor(
} else {
chatRoom.name
}
return "[ ]($currentServer/$type/$name?msg=${message.id}) "
val permalink = "$currentServer/$type/$name?msg=${message.id}"
return if (markdownSyntax) "[ ]($permalink) " else permalink
}
fun messageIdFromPermalink(permalink: String): String? {
......
......@@ -14,6 +14,7 @@ import android.view.View
import androidx.core.content.res.ResourcesCompat
import androidx.core.util.PatternsCompat
import chat.rocket.android.R
import androidx.core.util.PatternsCompat
import chat.rocket.android.chatroom.ui.StrikethroughDelimiterProcessor
import chat.rocket.android.emoji.EmojiParser
import chat.rocket.android.emoji.EmojiRepository
......
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="20"
android:viewportHeight="20">
<path
android:fillColor="@color/actionMenuColor"
android:pathData="M9.548,14.23l-2.651,2.652a2.676,2.676 0,0 1,-3.78 0,2.676 2.676,0 0,1 0,-3.78L6.91,9.311a2.677,2.677 0,0 1,3.781 0,0.669 0.669,0 0,0 0.945,-0.946 4.015,4.015 0,0 0,-5.67 0l-3.792,3.792a4.014,4.014 0,0 0,0 5.67,4.014 4.014,0 0,0 5.67,0l2.65,-2.65a0.669,0.669 0,0 0,-0.945 -0.947zM17.828,2.173a4.014,4.014 0,0 0,-5.67 0L9.506,4.824a0.668,0.668 0,1 0,0.946 0.945l2.651,-2.651a2.676,2.676 0,0 1,3.78 0,2.676 2.676,0 0,1 0,3.78L13.09,10.69a2.678,2.678 0,0 1,-3.781 0,0.668 0.668,0 1,0 -0.945,0.945 4.015,4.015 0,0 0,5.67 0l3.793,-3.792a4.014,4.014 0,0 0,0 -5.67z" />
</vector>
......@@ -12,6 +12,11 @@
android:icon="@drawable/ic_action_message_reply_24dp"
android:title="@string/action_msg_reply" />
<item
android:id="@+id/action_message_permalink"
android:icon="@drawable/ic_action_message_link_24dp"
android:title="@string/action_msg_copy_permalink" />
<item
android:id="@+id/action_message_quote"
android:icon="@drawable/ic_action_message_quote_24dp"
......
......@@ -163,6 +163,8 @@
<string name="msg_view_more">view more</string>
<!-- TODO - Add proper translation -->
<string name="msg_view_less">view less</string>
<!-- TODO - Add proper translation -->
<string name="msg_permalink_copied">Permalink copied</string>
<!-- Preferences messages -->
<string name="msg_analytics_tracking">Analytics tracking</string> <!-- TODO Add translation -->
......@@ -199,6 +201,8 @@
<string name="action_msg_share">Teilen</string>
<string name="action_title_editing">Nachricht bearbeiten</string>
<string name="action_msg_add_reaction">Reaktion hinzufügen</string>
<!-- TODO - Add proper translation -->
<string name="action_msg_copy_permalink">Copy permalink</string>
<!-- Permission messages -->
<string name="permission_editing_not_allowed">Bearbeiten nicht erlaubt</string>
......
......@@ -159,6 +159,8 @@
<string name="msg_view_more">view more</string>
<!-- TODO - Add proper translation -->
<string name="msg_view_less">view less</string>
<!-- TODO - Add proper translation -->
<string name="msg_permalink_copied">Permalink copied</string>
<!-- Preferences messages -->
<string name="msg_analytics_tracking">Analytics tracking</string> <!-- TODO Add translation -->
......@@ -195,6 +197,7 @@
<string name="action_msg_share">Compartir</string>
<string name="action_title_editing">Edición de mensaje</string>
<string name="action_msg_add_reaction">Añadir una reacción</string>
<string name="action_msg_copy_permalink">Copiar permalink</string>
<!-- Permission messages -->
<string name="permission_editing_not_allowed">La edición no és permitida</string>
......
......@@ -154,6 +154,8 @@
<string name="msg_view_more">view more</string>
<!-- TODO - Add proper translation -->
<string name="msg_view_less">view less</string>
<!-- TODO - Add proper translation -->
<string name="msg_permalink_copied">Permalink copied</string>
<!-- Create channel messages -->
<string name="msg_private_channel">Privé</string>
......@@ -203,6 +205,8 @@
<string name="action_msg_share">Partager</string>
<string name="action_title_editing">Modification du message</string>
<string name="action_msg_add_reaction">Ajouter une réaction</string>
<!-- TODO - Add proper translation -->
<string name="action_msg_copy_permalink">Copy permalink</string>
<!-- Permission messages -->
<string name="permission_editing_not_allowed">L\'édition n\'est pas autorisée</string>
......
......@@ -165,6 +165,8 @@
<string name="msg_channel_created_successfully">चैनल सफलतापूर्वक बनाया गया</string>
<string name="msg_view_more">और देखें</string>
<string name="msg_view_less">कम देखें</string>
<!-- TODO - Add proper translation -->
<string name="msg_permalink_copied">Permalink copied</string>
<!-- Preferences messages -->
<string name="msg_analytics_tracking">एनालिटिक्स ट्रैकिंग</string>
......@@ -187,7 +189,6 @@
<string name="message_role_removed">%1$s अब %3$s द्वारा %2$s नहीं है</string>
<string name="message_credentials_saved_successfully">प्रमाण पत्र सफलतापूर्वक सहेजे गए</string>
<!-- Message actions -->
<string name="action_msg_reply">जवाब दें</string>
<string name="action_msg_info">संदेश जानकारी</string>
......@@ -202,6 +203,8 @@
<string name="action_msg_share">शेयर करें</string>
<string name="action_title_editing">संपादन संदेश</string>
<string name="action_msg_add_reaction">प्रतिक्रिया जोड़ें</string>
<!-- TODO - Add proper translation -->
<string name="action_msg_copy_permalink">Copy permalink</string>
<!-- Permission messages -->
<string name="permission_editing_not_allowed">संपादन की अनुमति नहीं है</string>
......
......@@ -169,6 +169,8 @@
<string name="msg_message_copied">メッセージをコピー</string>
<string name="msg_delete_message">メッセージを削除</string>
<string name="msg_delete_description">このメッセージを削除してもよろしいですか?</string>
<!-- TODO - Add proper translation -->
<string name="msg_permalink_copied">Permalink copied</string>
<!-- Preferences messages -->
<string name="msg_analytics_tracking">Analytics tracking</string> <!-- TODO Add translation -->
......@@ -205,6 +207,8 @@
<string name="action_msg_share">Share</string>
<string name="action_title_editing">メッセージの編集</string>
<string name="action_msg_add_reaction">リアクションする</string>
<!-- TODO - Add proper translation -->
<string name="action_msg_copy_permalink">Copy permalink</string>
<!-- Permission messages -->
<string name="permission_editing_not_allowed">編集は許可されていません</string>
......
......@@ -152,6 +152,8 @@
<string name="msg__your_2fa_code">What’s your 2FA code?</string> <!-- TODO Add translation -->
<string name="msg_view_more">visualizar mais</string>
<string name="msg_view_less">visualizar menos</string>
<!-- TODO - Add proper translation -->
<string name="msg_permalink_copied">Permalink copiado</string>
<!-- Create channel messages -->
<string name="msg_private_channel">Privado</string>
......@@ -201,6 +203,7 @@
<string name="action_msg_share">Compartilhar</string>
<string name="action_title_editing">Editando mensagem</string>
<string name="action_msg_add_reaction">Adicionar reação</string>
<string name="action_msg_copy_permalink">Copiar permalink</string>
<!-- Permission messages -->
<string name="permission_editing_not_allowed">Edição não permitida</string>
......
......@@ -150,6 +150,8 @@
<string name="msg__your_2fa_code">Ваш код 2FA?</string>
<string name="msg_view_more">больше</string>
<string name="msg_view_less">меньше</string>
<!-- TODO - Add proper translation -->
<string name="msg_permalink_copied">Permalink copied</string>
<!-- Create channel messages -->
<string name="msg_private_channel">Приватный</string>
......@@ -198,6 +200,8 @@
<string name="action_msg_share">Поделиться</string>
<string name="action_title_editing">Редактирование сообщения</string>
<string name="action_msg_add_reaction">Отреагировать</string>
<!-- TODO - Add proper translation -->
<string name="action_msg_copy_permalink">Copy permalink</string>
<!-- Permission messages -->
<string name="permission_editing_not_allowed">Редактирование запрещено</string>
......
......@@ -166,6 +166,8 @@
<string name="msg_delete_description">Bu mesajı silmek istediğinizden emin misiniz</string>
<string name="msg_view_more">Daha fazla göster</string>
<string name="msg_view_less">Daha az göster</string>
<!-- TODO - Add proper translation -->
<string name="msg_permalink_copied">Permalink copied</string>
<!-- Preferences messages -->
<string name="msg_analytics_tracking">İstatistik takibi</string>
......@@ -202,6 +204,8 @@
<string name="action_msg_share">Paylaş</string>
<string name="action_title_editing">Mesaj Düzenleniyor</string>
<string name="action_msg_add_reaction">Tepki Ekle</string>
<!-- TODO - Add proper translation -->
<string name="action_msg_copy_permalink">Copy permalink</string>
<!-- Permission messages -->
<string name="permission_editing_not_allowed">Düzenlemeye izin verilmiyor</string>
......
......@@ -151,6 +151,8 @@
<string name="msg_view_more">view more</string>
<!-- TODO - Add proper translation -->
<string name="msg_view_less">view less</string>
<!-- TODO - Add proper translation -->
<string name="msg_permalink_copied">Permalink copied</string>
<!-- Create channel messages -->
<string name="msg_private_channel">Приватний</string>
......@@ -199,6 +201,8 @@
<string name="action_msg_share">Поділитися</string>
<string name="action_title_editing">Редагування повідомлення</string>
<string name="action_msg_add_reaction">Відреагувати</string>
<!-- TODO - Add proper translation -->
<string name="action_msg_copy_permalink">Copy permalink</string>
<!-- Permission messages -->
<string name="permission_editing_not_allowed">Редагування заборонено</string>
......
......@@ -161,6 +161,7 @@ https://github.com/RocketChat/java-code-styles/blob/master/CODING_STYLE.md#strin
<string name="msg_continue_with_wordpress">Continue with <b>WordPress</b></string>
<string name="msg_two_factor_authentication">Two-factor Authentication</string>
<string name="msg__your_2fa_code">What’s your 2FA code?</string>
<string name="msg_permalink_copied">Permalink copied</string>
<!-- Create channel messages -->
<string name="msg_private_channel">Private</string>
......@@ -214,6 +215,7 @@ https://github.com/RocketChat/java-code-styles/blob/master/CODING_STYLE.md#strin
<string name="action_msg_share">Share</string>
<string name="action_title_editing">Editing Message</string>
<string name="action_msg_add_reaction">Add reaction</string>
<string name="action_msg_copy_permalink">Copy permalink</string>
<!-- Permission messages -->
<string name="permission_editing_not_allowed">Editing is not allowed</string>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment