Commit 10f4acf8 authored by Leonardo Aramaki's avatar Leonardo Aramaki

Merge branch 'develop' into new/broadcast

parents 320bd1a8 1ceb0a2d
...@@ -18,7 +18,6 @@ import com.google.android.flexbox.FlexboxLayoutManager ...@@ -18,7 +18,6 @@ import com.google.android.flexbox.FlexboxLayoutManager
import ru.whalemare.sheetmenu.extension.inflate import ru.whalemare.sheetmenu.extension.inflate
import ru.whalemare.sheetmenu.extension.toList import ru.whalemare.sheetmenu.extension.toList
abstract class BaseViewHolder<T : BaseViewModel<*>>( abstract class BaseViewHolder<T : BaseViewModel<*>>(
itemView: View, itemView: View,
private val listener: ActionsListener, private val listener: ActionsListener,
...@@ -78,16 +77,23 @@ abstract class BaseViewHolder<T : BaseViewModel<*>>( ...@@ -78,16 +77,23 @@ abstract class BaseViewHolder<T : BaseViewModel<*>>(
private val onClickListener = { view: View -> private val onClickListener = { view: View ->
if (data?.message?.isSystemMessage() == false) { if (data?.message?.isSystemMessage() == false) {
data?.message?.let {
val menuItems = view.context.inflate(R.menu.message_actions).toList() val menuItems = view.context.inflate(R.menu.message_actions).toList()
menuItems.find { it.itemId == R.id.action_menu_msg_pin_unpin }?.apply { menuItems.find { it.itemId == R.id.action_message_unpin }?.apply {
val isPinned = data?.message?.pinned ?: false setTitle(if (it.pinned) R.string.action_msg_unpin else R.string.action_msg_pin)
setTitle(if (isPinned) R.string.action_msg_unpin else R.string.action_msg_pin) isChecked = it.pinned
isChecked = isPinned }
menuItems.find { it.itemId == R.id.action_message_star }?.apply {
val isStarred = it.starred?.isNotEmpty() ?: false
setTitle(if (isStarred) R.string.action_msg_unstar else R.string.action_msg_star)
isChecked = isStarred
} }
val adapter = ActionListAdapter(menuItems, this@BaseViewHolder) val adapter = ActionListAdapter(menuItems, this@BaseViewHolder)
BottomSheetMenu(adapter).show(view.context) BottomSheetMenu(adapter).show(view.context)
} }
} }
}
internal fun setupActionMenu(view: View) { internal fun setupActionMenu(view: View) {
if (listener.isActionsEnabled()) { if (listener.isActionsEnabled()) {
......
...@@ -202,25 +202,39 @@ class ChatRoomAdapter( ...@@ -202,25 +202,39 @@ class ChatRoomAdapter(
} }
private val actionsListener = object : BaseViewHolder.ActionsListener { private val actionsListener = object : BaseViewHolder.ActionsListener {
override fun isActionsEnabled(): Boolean = enableActions override fun isActionsEnabled(): Boolean = enableActions
override fun onActionSelected(item: MenuItem, message: Message) { override fun onActionSelected(item: MenuItem, message: Message) {
message.apply { message.apply {
when (item.itemId) { when (item.itemId) {
R.id.action_menu_msg_delete -> presenter?.deleteMessage(roomId, id) R.id.action_message_reply -> {
R.id.action_menu_msg_quote -> presenter?.citeMessage(roomType, id, false) presenter?.citeMessage(roomType, id, true)
R.id.action_menu_msg_reply -> presenter?.citeMessage(roomType, id, true) }
R.id.action_menu_msg_copy -> presenter?.copyMessage(id) R.id.action_message_quote -> {
R.id.action_menu_msg_edit -> presenter?.editMessage(roomId, id, message.message) presenter?.citeMessage(roomType, id, false)
R.id.action_menu_msg_pin_unpin -> { }
with(item) { R.id.action_message_copy -> {
if (!isChecked) { presenter?.copyMessage(id)
}
R.id.action_message_edit -> {
presenter?.editMessage(roomId, id, message.message)
}
R.id.action_message_star -> {
if (!item.isChecked) {
presenter?.starMessage(id)
} else {
presenter?.unstarMessage(id)
}
}
R.id.action_message_unpin -> {
if (!item.isChecked) {
presenter?.pinMessage(id) presenter?.pinMessage(id)
} else { } else {
presenter?.unpinMessage(id) presenter?.unpinMessage(id)
} }
} }
} R.id.action_message_delete -> presenter?.deleteMessage(roomId, id)
R.id.action_menu_msg_react -> presenter?.showReactions(id) R.id.action_menu_msg_react -> presenter?.showReactions(id)
else -> TODO("Not implemented") else -> TODO("Not implemented")
} }
......
package chat.rocket.android.chatroom.adapter package chat.rocket.android.chatroom.adapter
import android.support.v7.widget.RecyclerView
import android.view.View import android.view.View
import chat.rocket.android.chatroom.viewmodel.MessageReplyViewModel import chat.rocket.android.chatroom.viewmodel.MessageReplyViewModel
import chat.rocket.android.util.extensions.isBroadcastReplyAvailable
import chat.rocket.android.util.extensions.setVisible
import chat.rocket.android.widget.emoji.EmojiReactionListener import chat.rocket.android.widget.emoji.EmojiReactionListener
import kotlinx.android.synthetic.main.item_message_reply.view.* import kotlinx.android.synthetic.main.item_message_reply.view.*
...@@ -23,17 +20,11 @@ class MessageReplyViewHolder( ...@@ -23,17 +20,11 @@ class MessageReplyViewHolder(
override fun bindViews(data: MessageReplyViewModel) { override fun bindViews(data: MessageReplyViewModel) {
with(itemView) { with(itemView) {
// if (data.isBroadcastReplyAvailable()) {
// setVisible(true)
button_message_reply.setOnClickListener { button_message_reply.setOnClickListener {
with(data.rawData) { with(data.rawData) {
replyCallback.invoke(roomName, permalink) replyCallback.invoke(roomName, permalink)
} }
} }
// } else {
// visibility = View.GONE
// itemView.layoutParams = RecyclerView.LayoutParams(0, 0)
// }
} }
} }
} }
\ No newline at end of file
...@@ -3,6 +3,7 @@ package chat.rocket.android.chatroom.adapter ...@@ -3,6 +3,7 @@ package chat.rocket.android.chatroom.adapter
import android.graphics.Color import android.graphics.Color
import android.text.method.LinkMovementMethod import android.text.method.LinkMovementMethod
import android.view.View import android.view.View
import androidx.core.view.isVisible
import chat.rocket.android.chatroom.viewmodel.MessageViewModel import chat.rocket.android.chatroom.viewmodel.MessageViewModel
import chat.rocket.android.util.extensions.setVisible import chat.rocket.android.util.extensions.setVisible
import chat.rocket.android.widget.emoji.EmojiReactionListener import chat.rocket.android.widget.emoji.EmojiReactionListener
...@@ -35,10 +36,9 @@ class MessageViewHolder( ...@@ -35,10 +36,9 @@ class MessageViewHolder(
text_content.setTextColor( text_content.setTextColor(
if (data.isTemporary) Color.GRAY else Color.BLACK if (data.isTemporary) Color.GRAY else Color.BLACK
) )
if (!data.message.isSystemMessage() && data.message.editedBy != null){ data.message.let {
text_edit_indicator.setVisible(true) text_edit_indicator.isVisible = it.isSystemMessage() && it.editedBy != null
}else{ image_star_indicator.isVisible = it.starred?.isNotEmpty() ?: false
text_edit_indicator.setVisible(false)
} }
} }
} }
......
...@@ -56,6 +56,9 @@ import chat.rocket.core.internal.rest.toggleReaction ...@@ -56,6 +56,9 @@ import chat.rocket.core.internal.rest.toggleReaction
import chat.rocket.core.internal.rest.unpinMessage import chat.rocket.core.internal.rest.unpinMessage
import chat.rocket.core.internal.rest.updateMessage import chat.rocket.core.internal.rest.updateMessage
import chat.rocket.core.internal.rest.uploadFile import chat.rocket.core.internal.rest.uploadFile
import chat.rocket.core.internal.realtime.subscribeTypingStatus
import chat.rocket.core.internal.realtime.unsubscribe
import chat.rocket.core.internal.rest.*
import chat.rocket.core.model.Command import chat.rocket.core.model.Command
import chat.rocket.core.model.Message import chat.rocket.core.model.Message
import chat.rocket.core.model.Myself import chat.rocket.core.model.Myself
...@@ -98,7 +101,9 @@ class ChatRoomPresenter @Inject constructor( ...@@ -98,7 +101,9 @@ class ChatRoomPresenter @Inject constructor(
private var chatRoomType: String? = null private var chatRoomType: String? = null
private var chatIsBroadcast: Boolean = false private var chatIsBroadcast: Boolean = false
private val stateChannel = Channel<State>() private val stateChannel = Channel<State>()
private var typingStatusSubscriptionId: String? = null
private var lastState = manager.state private var lastState = manager.state
private var typingStatusList = arrayListOf<String>()
fun setupChatRoom(roomId: String) { fun setupChatRoom(roomId: String) {
launchUI(strategy) { launchUI(strategy) {
...@@ -145,6 +150,7 @@ class ChatRoomPresenter @Inject constructor( ...@@ -145,6 +150,7 @@ class ChatRoomPresenter @Inject constructor(
view.hideLoading() view.hideLoading()
} }
subscribeTypingStatus()
if (offset == 0L) { if (offset == 0L) {
subscribeState() subscribeState()
} }
...@@ -182,6 +188,7 @@ class ChatRoomPresenter @Inject constructor( ...@@ -182,6 +188,7 @@ class ChatRoomPresenter @Inject constructor(
groupable = false, groupable = false,
parseUrls = false, parseUrls = false,
pinned = false, pinned = false,
starred = emptyList(),
mentions = emptyList(), mentions = emptyList(),
reactions = null, reactions = null,
senderAlias = null, senderAlias = null,
...@@ -356,14 +363,6 @@ class ChatRoomPresenter @Inject constructor( ...@@ -356,14 +363,6 @@ class ChatRoomPresenter @Inject constructor(
} }
} }
fun unsubscribeMessages(chatRoomId: String) {
manager.removeStatusChannel(stateChannel)
manager.unsubscribeRoomMessages(chatRoomId)
// All messages during the subscribed period are assumed to be read,
// and lastSeen is updated as the time when the user leaves the room
markRoomAsRead(chatRoomId)
}
/** /**
* Delete the message with the given id. * Delete the message with the given id.
* *
...@@ -461,6 +460,34 @@ class ChatRoomPresenter @Inject constructor( ...@@ -461,6 +460,34 @@ class ChatRoomPresenter @Inject constructor(
} }
} }
fun starMessage(messageId: String) {
launchUI(strategy) {
if (!permissions.allowedMessageStarring()) {
view.showMessage(R.string.permission_starring_not_allowed)
return@launchUI
}
try {
retryIO("starMessage($messageId)") { client.starMessage(messageId) }
} catch (e: RocketChatException) {
Timber.e(e)
}
}
}
fun unstarMessage(messageId: String) {
launchUI(strategy) {
if (!permissions.allowedMessageStarring()) {
view.showMessage(R.string.permission_starring_not_allowed)
return@launchUI
}
try {
retryIO("unstarMessage($messageId)") { client.unstarMessage(messageId) }
} catch (e: RocketChatException) {
Timber.e(e)
}
}
}
fun pinMessage(messageId: String) { fun pinMessage(messageId: String) {
launchUI(strategy) { launchUI(strategy) {
if (!permissions.allowedMessagePinning()) { if (!permissions.allowedMessagePinning()) {
...@@ -708,6 +735,57 @@ class ChatRoomPresenter @Inject constructor( ...@@ -708,6 +735,57 @@ class ChatRoomPresenter @Inject constructor(
} }
} }
fun disconnect() {
unsubscribeTypingStatus()
if (chatRoomId != null) {
unsubscribeMessages(chatRoomId.toString())
}
}
private suspend fun subscribeTypingStatus() {
client.subscribeTypingStatus(chatRoomId.toString()) { _, id ->
typingStatusSubscriptionId = id
}
for (typingStatus in client.typingStatusChannel) {
processTypingStatus(typingStatus)
}
}
private fun processTypingStatus(typingStatus: Pair<String, Boolean>) {
if (!typingStatusList.any { username -> username == typingStatus.first }) {
if (typingStatus.second) {
typingStatusList.add(typingStatus.first)
}
} else {
typingStatusList.find { username -> username == typingStatus.first }?.let {
typingStatusList.remove(it)
if (typingStatus.second) {
typingStatusList.add(typingStatus.first)
}
}
}
if (typingStatusList.isNotEmpty()) {
view.showTypingStatus(typingStatusList)
} else {
view.hideTypingStatusView()
}
}
private fun unsubscribeTypingStatus() {
typingStatusSubscriptionId?.let {
client.unsubscribe(it)
}
}
private fun unsubscribeMessages(chatRoomId: String) {
manager.removeStatusChannel(stateChannel)
manager.unsubscribeRoomMessages(chatRoomId)
// All messages during the subscribed period are assumed to be read,
// and lastSeen is updated as the time when the user leaves the room
markRoomAsRead(chatRoomId)
}
private fun updateMessage(streamedMessage: Message) { private fun updateMessage(streamedMessage: Message) {
launchUI(strategy) { launchUI(strategy) {
val viewModelStreamedMessage = mapper.map(streamedMessage, chatIsBroadcast) val viewModelStreamedMessage = mapper.map(streamedMessage, chatIsBroadcast)
......
...@@ -26,6 +26,18 @@ interface ChatRoomView : LoadingView, MessageView { ...@@ -26,6 +26,18 @@ interface ChatRoomView : LoadingView, MessageView {
*/ */
fun sendMessage(text: String) fun sendMessage(text: String)
/**
* Shows the username(s) of the user(s) who is/are typing in the chat room.
*
* @param usernameList The list of username to show.
*/
fun showTypingStatus(usernameList: ArrayList<String>)
/**
* Hides the typing status view.
*/
fun hideTypingStatusView()
/** /**
* Perform file selection with the mime type [filter] * Perform file selection with the mime type [filter]
*/ */
......
...@@ -20,6 +20,10 @@ import android.view.MenuInflater ...@@ -20,6 +20,10 @@ import android.view.MenuInflater
import android.view.MenuItem import android.view.MenuItem
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.text.SpannableStringBuilder
import android.view.*
import androidx.core.text.bold
import androidx.core.view.isVisible
import chat.rocket.android.R import chat.rocket.android.R
import chat.rocket.android.chatroom.adapter.ChatRoomAdapter import chat.rocket.android.chatroom.adapter.ChatRoomAdapter
import chat.rocket.android.chatroom.adapter.CommandSuggestionsAdapter import chat.rocket.android.chatroom.adapter.CommandSuggestionsAdapter
...@@ -131,8 +135,18 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR ...@@ -131,8 +135,18 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
private var playComposeMessageButtonsAnimation = true private var playComposeMessageButtonsAnimation = true
// For reveal and unreveal anim. // For reveal and unreveal anim.
private val hypotenuse by lazy { Math.hypot(root_layout.width.toDouble(), root_layout.height.toDouble()).toFloat() } private val hypotenuse by lazy {
private val max by lazy { Math.max(layout_message_attachment_options.width.toDouble(), layout_message_attachment_options.height.toDouble()).toFloat() } Math.hypot(
root_layout.width.toDouble(),
root_layout.height.toDouble()
).toFloat()
}
private val max by lazy {
Math.max(
layout_message_attachment_options.width.toDouble(),
layout_message_attachment_options.height.toDouble()
).toFloat()
}
private val centerX by lazy { recycler_view.right } private val centerX by lazy { recycler_view.right }
private val centerY by lazy { recycler_view.bottom } private val centerY by lazy { recycler_view.bottom }
private val handler = Handler() private val handler = Handler()
...@@ -192,7 +206,7 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR ...@@ -192,7 +206,7 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
recycler_view.removeOnScrollListener(onScrollListener) recycler_view.removeOnScrollListener(onScrollListener)
recycler_view.removeOnLayoutChangeListener(layoutChangeListener) recycler_view.removeOnLayoutChangeListener(layoutChangeListener)
presenter.unsubscribeMessages(chatRoomId) presenter.disconnect()
handler.removeCallbacksAndMessages(null) handler.removeCallbacksAndMessages(null)
unsubscribeComposeTextMessage() unsubscribeComposeTextMessage()
...@@ -363,6 +377,37 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR ...@@ -363,6 +377,37 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
} }
} }
override fun showTypingStatus(usernameList: ArrayList<String>) {
ui {
when (usernameList.size) {
1 -> {
text_typing_status.text =
SpannableStringBuilder()
.bold { append(usernameList[0]) }
.append(getString(R.string.msg_is_typing))
}
2 -> {
text_typing_status.text =
SpannableStringBuilder()
.bold { append(usernameList[0]) }
.append(getString(R.string.msg_and))
.bold { append(usernameList[1]) }
.append(getString(R.string.msg_are_typing))
}
else -> {
text_typing_status.text = getString(R.string.msg_several_users_are_typing)
}
}
text_typing_status.isVisible = true
}
}
override fun hideTypingStatusView() {
ui {
text_typing_status.isVisible = false
}
}
override fun uploadFile(uri: Uri) { override fun uploadFile(uri: Uri) {
// TODO Just leaving a blank message that comes with the file for now. In the future lets add the possibility to add a message with the file to be uploaded. // TODO Just leaving a blank message that comes with the file for now. In the future lets add the possibility to add a message with the file to be uploaded.
presenter.uploadFile(chatRoomId, uri, "") presenter.uploadFile(chatRoomId, uri, "")
......
...@@ -7,8 +7,10 @@ import chat.rocket.android.util.extensions.setVisible ...@@ -7,8 +7,10 @@ import chat.rocket.android.util.extensions.setVisible
/** /**
* An adapter for bottomsheet menu that lists all the actions that could be taken over a chat message. * An adapter for bottomsheet menu that lists all the actions that could be taken over a chat message.
*/ */
class ActionListAdapter(menuItems: List<MenuItem> = emptyList(), callback: MenuItem.OnMenuItemClickListener) : class ActionListAdapter(
ListBottomSheetAdapter(menuItems = menuItems, callback = callback) { menuItems: List<MenuItem> = emptyList(),
callback: MenuItem.OnMenuItemClickListener
) : ListBottomSheetAdapter(menuItems = menuItems, callback = callback) {
override fun onBindViewHolder(holder: ViewHolder, position: Int) { override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val item = menuItems[position] val item = menuItems[position]
...@@ -25,7 +27,11 @@ class ActionListAdapter(menuItems: List<MenuItem> = emptyList(), callback: MenuI ...@@ -25,7 +27,11 @@ class ActionListAdapter(menuItems: List<MenuItem> = emptyList(), callback: MenuI
callback?.onMenuItemClick(item) callback?.onMenuItemClick(item)
} }
val deleteTextColor = holder.itemView.context.resources.getColor(R.color.red) val deleteTextColor = holder.itemView.context.resources.getColor(R.color.red)
val color = if (item.itemId == R.id.action_menu_msg_delete) deleteTextColor else textColors.get(item.itemId) val color = if (item.itemId == R.id.action_message_delete) {
deleteTextColor
} else {
textColors.get(item.itemId)
}
holder.textTitle.setTextColor(color) holder.textTitle.setTextColor(color)
} }
} }
\ No newline at end of file
...@@ -14,6 +14,7 @@ import android.support.v7.widget.SearchView ...@@ -14,6 +14,7 @@ import android.support.v7.widget.SearchView
import android.view.* import android.view.*
import android.widget.CheckBox import android.widget.CheckBox
import android.widget.RadioGroup import android.widget.RadioGroup
import androidx.core.view.isVisible
import chat.rocket.android.R import chat.rocket.android.R
import chat.rocket.android.chatrooms.presentation.ChatRoomsPresenter import chat.rocket.android.chatrooms.presentation.ChatRoomsPresenter
import chat.rocket.android.chatrooms.presentation.ChatRoomsView import chat.rocket.android.chatrooms.presentation.ChatRoomsView
...@@ -164,11 +165,7 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView { ...@@ -164,11 +165,7 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView {
/*val diff = async(CommonPool) { /*val diff = async(CommonPool) {
DiffUtil.calculateDiff(RoomsDiffCallback(adapter.baseAdapter.dataSet, newDataSet)) DiffUtil.calculateDiff(RoomsDiffCallback(adapter.baseAdapter.dataSet, newDataSet))
}.await()*/ }.await()*/
if (newDataSet.isEmpty()) { text_no_search.isVisible = newDataSet.isEmpty()
text_no_search.visibility = View.VISIBLE
}else{
text_no_search.visibility = View.GONE
}
if (isActive) { if (isActive) {
adapter.baseAdapter.updateRooms(newDataSet) adapter.baseAdapter.updateRooms(newDataSet)
// TODO - fix crash to re-enable diff.dispatchUpdatesTo(adapter) // TODO - fix crash to re-enable diff.dispatchUpdatesTo(adapter)
......
...@@ -8,7 +8,7 @@ import chat.rocket.android.server.infraestructure.RocketChatClientFactory ...@@ -8,7 +8,7 @@ import chat.rocket.android.server.infraestructure.RocketChatClientFactory
import chat.rocket.android.util.extensions.launchUI import chat.rocket.android.util.extensions.launchUI
import chat.rocket.common.RocketChatException import chat.rocket.common.RocketChatException
import chat.rocket.common.util.ifNull import chat.rocket.common.util.ifNull
import chat.rocket.core.internal.rest.getRoomPinnedMessages import chat.rocket.core.internal.rest.getPinnedMessages
import chat.rocket.core.model.isSystemMessage import chat.rocket.core.model.isSystemMessage
import timber.log.Timber import timber.log.Timber
import javax.inject.Inject import javax.inject.Inject
...@@ -37,7 +37,7 @@ class PinnedMessagesPresenter @Inject constructor( ...@@ -37,7 +37,7 @@ class PinnedMessagesPresenter @Inject constructor(
chatRoom?.let { room -> chatRoom?.let { room ->
view.showLoading() view.showLoading()
val pinnedMessages = val pinnedMessages =
client.getRoomPinnedMessages(roomId, room.type, pinnedMessagesListOffset) client.getPinnedMessages(roomId, room.type, pinnedMessagesListOffset)
pinnedMessagesListOffset = pinnedMessages.offset.toInt() pinnedMessagesListOffset = pinnedMessages.offset.toInt()
val messageList = mapper.map(pinnedMessages.result.filterNot { it.isSystemMessage() }) val messageList = mapper.map(pinnedMessages.result.filterNot { it.isSystemMessage() })
view.showPinnedMessages(messageList) view.showPinnedMessages(messageList)
......
...@@ -291,7 +291,7 @@ class PushManager @Inject constructor( ...@@ -291,7 +291,7 @@ class PushManager @Inject constructor(
.setLabel(replyTextHint) .setLabel(replyTextHint)
.build() .build()
val pendingIntent = getReplyPendingIntent(pushMessage) val pendingIntent = getReplyPendingIntent(pushMessage)
val replyAction = NotificationCompat.Action.Builder(R.drawable.ic_reply_black_24px, replyTextHint, pendingIntent) val replyAction = NotificationCompat.Action.Builder(R.drawable.ic_action_message_reply_24dp, replyTextHint, pendingIntent)
.addRemoteInput(replyRemoteInput) .addRemoteInput(replyRemoteInput)
.setAllowGeneratedReplies(true) .setAllowGeneratedReplies(true)
.build() .build()
......
...@@ -32,20 +32,25 @@ class PermissionsInteractor @Inject constructor( ...@@ -32,20 +32,25 @@ class PermissionsInteractor @Inject constructor(
} }
/** /**
* Check whether user is allowed to delete a message. * Check whether the user is allowed to delete a message.
*/ */
fun allowedMessageDeleting() = publicSettings()?.allowedMessageDeleting() ?: false fun allowedMessageDeleting() = publicSettings()?.allowedMessageDeleting() ?: false
/** /**
* Checks whether user is allowed to edit a message. * Checks whether the user is allowed to edit a message.
*/ */
fun allowedMessageEditing() = publicSettings()?.allowedMessageEditing() ?: false fun allowedMessageEditing() = publicSettings()?.allowedMessageEditing() ?: false
/** /**
* Checks whether user is allowed to pin a message to a channel. * Checks whether the user is allowed to pin a message to a channel.
*/ */
fun allowedMessagePinning() = publicSettings()?.allowedMessagePinning() ?: false fun allowedMessagePinning() = publicSettings()?.allowedMessagePinning() ?: false
/**
* Checks whether the user is allowed to star a message.
*/
fun allowedMessageStarring() = publicSettings()?.allowedMessageStarring() ?: false
/** /**
* Checks whether should show deleted message status. * Checks whether should show deleted message status.
*/ */
......
...@@ -24,7 +24,7 @@ class RefreshSettingsInteractor @Inject constructor( ...@@ -24,7 +24,7 @@ class RefreshSettingsInteractor @Inject constructor(
FAVORITE_ROOMS, UPLOAD_STORAGE_TYPE, UPLOAD_MAX_FILE_SIZE, UPLOAD_WHITELIST_MIMETYPES, FAVORITE_ROOMS, UPLOAD_STORAGE_TYPE, UPLOAD_MAX_FILE_SIZE, UPLOAD_WHITELIST_MIMETYPES,
HIDE_USER_JOIN, HIDE_USER_LEAVE, HIDE_USER_JOIN, HIDE_USER_LEAVE,
HIDE_TYPE_AU, HIDE_MUTE_UNMUTE, HIDE_TYPE_RU, ALLOW_MESSAGE_DELETING, HIDE_TYPE_AU, HIDE_MUTE_UNMUTE, HIDE_TYPE_RU, ALLOW_MESSAGE_DELETING,
ALLOW_MESSAGE_EDITING, ALLOW_MESSAGE_PINNING, SHOW_DELETED_STATUS, SHOW_EDITED_STATUS, ALLOW_MESSAGE_EDITING, ALLOW_MESSAGE_PINNING, ALLOW_MESSAGE_STARRING, SHOW_DELETED_STATUS, SHOW_EDITED_STATUS,
WIDE_TILE_310, STORE_LAST_MESSAGE) WIDE_TILE_310, STORE_LAST_MESSAGE)
suspend fun refresh(server: String) { suspend fun refresh(server: String) {
......
...@@ -49,6 +49,7 @@ const val ALLOW_MESSAGE_EDITING = "Message_AllowEditing" ...@@ -49,6 +49,7 @@ const val ALLOW_MESSAGE_EDITING = "Message_AllowEditing"
const val SHOW_DELETED_STATUS = "Message_ShowDeletedStatus" const val SHOW_DELETED_STATUS = "Message_ShowDeletedStatus"
const val SHOW_EDITED_STATUS = "Message_ShowEditedStatus" const val SHOW_EDITED_STATUS = "Message_ShowEditedStatus"
const val ALLOW_MESSAGE_PINNING = "Message_AllowPinning" const val ALLOW_MESSAGE_PINNING = "Message_AllowPinning"
const val ALLOW_MESSAGE_STARRING = "Message_AllowStarring"
const val STORE_LAST_MESSAGE = "Store_Last_Message" const val STORE_LAST_MESSAGE = "Store_Last_Message"
/* /*
...@@ -83,6 +84,7 @@ fun PublicSettings.wideTile(): String? = this[WIDE_TILE_310]?.value as String? ...@@ -83,6 +84,7 @@ fun PublicSettings.wideTile(): String? = this[WIDE_TILE_310]?.value as String?
fun PublicSettings.showDeletedStatus(): Boolean = this[SHOW_DELETED_STATUS]?.value == true fun PublicSettings.showDeletedStatus(): Boolean = this[SHOW_DELETED_STATUS]?.value == true
fun PublicSettings.showEditedStatus(): Boolean = this[SHOW_EDITED_STATUS]?.value == true fun PublicSettings.showEditedStatus(): Boolean = this[SHOW_EDITED_STATUS]?.value == true
fun PublicSettings.allowedMessagePinning(): Boolean = this[ALLOW_MESSAGE_PINNING]?.value == true fun PublicSettings.allowedMessagePinning(): Boolean = this[ALLOW_MESSAGE_PINNING]?.value == true
fun PublicSettings.allowedMessageStarring(): Boolean = this[ALLOW_MESSAGE_STARRING]?.value == true
fun PublicSettings.allowedMessageEditing(): Boolean = this[ALLOW_MESSAGE_EDITING]?.value == true fun PublicSettings.allowedMessageEditing(): Boolean = this[ALLOW_MESSAGE_EDITING]?.value == true
fun PublicSettings.allowedMessageDeleting(): Boolean = this[ALLOW_MESSAGE_DELETING]?.value == true fun PublicSettings.allowedMessageDeleting(): Boolean = this[ALLOW_MESSAGE_DELETING]?.value == true
......
...@@ -110,7 +110,6 @@ class ConnectionManager(internal val client: RocketChatClient) { ...@@ -110,7 +110,6 @@ class ConnectionManager(internal val client: RocketChatClient) {
Timber.d("Received new Message for room ${message.roomId}") Timber.d("Received new Message for room ${message.roomId}")
val channel = roomMessagesChannels[message.roomId] val channel = roomMessagesChannels[message.roomId]
channel?.send(message) channel?.send(message)
} }
} }
...@@ -131,6 +130,7 @@ class ConnectionManager(internal val client: RocketChatClient) { ...@@ -131,6 +130,7 @@ class ConnectionManager(internal val client: RocketChatClient) {
} }
} }
} }
client.connect() client.connect()
// Broadcast initial state... // Broadcast initial state...
......
<vector xmlns:android="http://schemas.android.com/apk/res/android" <vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp" android:width="24dp"
android:height="24dp" android:height="24dp"
android:viewportWidth="24.0" android:viewportHeight="24.0"
android:viewportHeight="24.0"> android:viewportWidth="24.0">
<path <path
android:pathData="M16,1L4,1c-1.1,0 -2,0.9 -2,2v14h2L4,3h12L16,1zM19,5L8,5c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h11c1.1,0 2,-0.9 2,-2L21,7c0,-1.1 -0.9,-2 -2,-2zM19,21L8,21L8,7h11v14z" android:fillColor="@color/actionMenuColor"
android:fillColor="@color/actionMenuColor"/> android:pathData="M16,1L4,1c-1.1,0 -2,0.9 -2,2v14h2L4,3h12L16,1zM19,5L8,5c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h11c1.1,0 2,-0.9 2,-2L21,7c0,-1.1 -0.9,-2 -2,-2zM19,21L8,21L8,7h11v14z" />
</vector> </vector>
\ No newline at end of file
<vector xmlns:android="http://schemas.android.com/apk/res/android" <vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp" android:width="24dp"
android:height="24dp" android:height="24dp"
android:viewportWidth="24.0" android:viewportHeight="24.0"
android:viewportHeight="24.0"> android:viewportWidth="24.0">
<path <path
android:pathData="M6,19c0,1.1 0.9,2 2,2h8c1.1,0 2,-0.9 2,-2V7H6v12zM19,4h-3.5l-1,-1h-5l-1,1H5v2h14V4z" android:fillColor="#FF0000"
android:fillColor="#FF0000"/> android:pathData="M6,19c0,1.1 0.9,2 2,2h8c1.1,0 2,-0.9 2,-2V7H6v12zM19,4h-3.5l-1,-1h-5l-1,1H5v2h14V4z" />
</vector> </vector>
<vector xmlns:android="http://schemas.android.com/apk/res/android" <vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp" android:width="24dp"
android:height="24dp" android:height="24dp"
android:viewportWidth="24.0" android:viewportHeight="24.0"
android:viewportHeight="24.0"> android:viewportWidth="24.0">
<path <path
android:pathData="M3,17.25V21h3.75L17.81,9.94l-3.75,-3.75L3,17.25zM20.71,7.04c0.39,-0.39 0.39,-1.02 0,-1.41l-2.34,-2.34c-0.39,-0.39 -1.02,-0.39 -1.41,0l-1.83,1.83 3.75,3.75 1.83,-1.83z" android:fillColor="@color/actionMenuColor"
android:fillColor="@color/actionMenuColor"/> android:pathData="M3,17.25V21h3.75L17.81,9.94l-3.75,-3.75L3,17.25zM20.71,7.04c0.39,-0.39 0.39,-1.02 0,-1.41l-2.34,-2.34c-0.39,-0.39 -1.02,-0.39 -1.41,0l-1.83,1.83 3.75,3.75 1.83,-1.83z" />
</vector> </vector>
\ No newline at end of file
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="24"
android:viewportWidth="24">
<path
android:fillColor="@color/actionMenuColor"
android:pathData="M16,12V4H17V2H7V4H8V12L6,14V16H11.2V22H12.8V16H18V14L16,12Z" />
</vector>
\ No newline at end of file
<vector xmlns:android="http://schemas.android.com/apk/res/android" <vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp" android:width="24dp"
android:height="24dp" android:height="24dp"
android:viewportWidth="24.0" android:viewportHeight="24.0"
android:viewportHeight="24.0"> android:viewportWidth="24.0">
<path <path
android:pathData="M6,17h3l2,-4L11,7L5,7v6h3zM14,17h3l2,-4L19,7h-6v6h3z" android:fillColor="@color/actionMenuColor"
android:fillColor="@color/actionMenuColor"/> android:pathData="M6,17h3l2,-4L11,7L5,7v6h3zM14,17h3l2,-4L19,7h-6v6h3z" />
</vector> </vector>
\ No newline at end of file
<vector xmlns:android="http://schemas.android.com/apk/res/android" <vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp" android:width="24dp"
android:height="24dp" android:height="24dp"
android:viewportWidth="24.0" android:viewportHeight="24.0"
android:viewportHeight="24.0"> android:viewportWidth="24.0">
<path <path
android:pathData="M10,9V5l-7,7 7,7v-4.1c5,0 8.5,1.6 11,5.1 -1,-5 -4,-10 -11,-11z" android:fillColor="@color/actionMenuColor"
android:fillColor="@color/actionMenuColor"/> android:pathData="M10,9V5l-7,7 7,7v-4.1c5,0 8.5,1.6 11,5.1 -1,-5 -4,-10 -11,-11z" />
</vector> </vector>
\ No newline at end of file
<vector xmlns:android="http://schemas.android.com/apk/res/android" <vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp" android:width="24dp"
android:height="24dp" android:height="24dp"
android:viewportWidth="24.0" android:viewportHeight="24.0"
android:viewportHeight="24.0"> android:viewportWidth="24.0">
<path <path
android:pathData="M12,17.27L18.18,21l-1.64,-7.03L22,9.24l-7.19,-0.61L12,2 9.19,8.63 2,9.24l5.46,4.73L5.82,21z" android:fillColor="@color/actionMenuColor"
android:fillColor="@color/actionMenuColor"/> android:pathData="M12,17.27L18.18,21l-1.64,-7.03L22,9.24l-7.19,-0.61L12,2 9.19,8.63 2,9.24l5.46,4.73L5.82,21z" />
</vector> </vector>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:viewportWidth="197.218"
android:viewportHeight="197.218"
android:width="197.218dp"
android:height="197.218dp">
<group
android:translateX="-570.396"
android:translateY="-306.782">
<path
android:pathData="M704.445 306.782l-6.785 6.785c-6.084 6.084 -7.622 14.712 -4.309 21.871l-44.068 35.44 -3.086 -3.086c-7.889 -7.889 -19.525 -7.889 -27.414 0l-8.944 8.953 87.821 87.811 8.934 -8.933c7.899 -7.899 7.899 -19.525 0 -27.433l-3.076 -3.077 36.051 -44.68c6.824 2.466 14.367 1.036 20.037 -4.624l8.008 -5.858 -63.169 -63.169zm-66.867 116.487l-67.182 66.857 0 13.874 13.864 0 66.867 -67.182 -13.549 -13.549z"
android:fillColor="@color/actionMenuColor"
/>
</group>
</vector>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/root_layout" android:id="@+id/root_layout"
...@@ -12,23 +11,23 @@ ...@@ -12,23 +11,23 @@
android:id="@+id/view_loading" android:id="@+id/view_loading"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:visibility="gone" android:visibility="gone"
app:indicatorColor="@color/black" app:indicatorColor="@color/black"
app:indicatorName="BallPulseIndicator" app:indicatorName="BallPulseIndicator"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:visibility="visible" /> tools:visibility="visible" />
<FrameLayout <FrameLayout
android:id="@+id/message_list_container" android:id="@+id/message_list_container"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="0dp" android:layout_height="0dp"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintBottom_toTopOf="@id/text_typing_status"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toTopOf="@id/layout_message_composer"> app:layout_constraintTop_toTopOf="parent">
<include <include
android:id="@+id/layout_message_list" android:id="@+id/layout_message_list"
...@@ -44,52 +43,65 @@ ...@@ -44,52 +43,65 @@
android:layout_height="100dp" android:layout_height="100dp"
android:src="@drawable/ic_chat_black_24dp" android:src="@drawable/ic_chat_black_24dp"
android:tint="@color/icon_grey" android:tint="@color/icon_grey"
app:layout_constraintStart_toStartOf="parent" android:visibility="gone"
app:layout_constraintBottom_toTopOf="@id/text_chat_title"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="@id/text_chat_title"
app:layout_constraintVertical_chainStyle="packed" app:layout_constraintVertical_chainStyle="packed"
android:visibility="gone"
tools:visibility="visible" /> tools:visibility="visible" />
<TextView <TextView
android:id="@+id/text_chat_title" android:id="@+id/text_chat_title"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:text="@string/msg_no_chat_title" android:text="@string/msg_no_chat_title"
app:layout_constraintStart_toStartOf="parent" android:textColor="@color/colorSecondaryText"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/image_chat_icon"
app:layout_constraintBottom_toTopOf="@id/text_chat_description"
android:textSize="20sp" android:textSize="20sp"
android:layout_marginTop="24dp"
android:textStyle="bold" android:textStyle="bold"
android:textColor="@color/colorSecondaryText"
android:visibility="gone" android:visibility="gone"
tools:visibility="visible"/> app:layout_constraintBottom_toTopOf="@id/text_chat_description"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/image_chat_icon"
tools:visibility="visible" />
<TextView <TextView
android:id="@+id/text_chat_description" android:id="@+id/text_chat_description"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/msg_no_chat_description"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/text_chat_title"
app:layout_constraintBottom_toTopOf="@id/layout_message_composer"
android:layout_marginTop="16dp" android:layout_marginTop="16dp"
android:text="@string/msg_no_chat_description"
android:textAlignment="center" android:textAlignment="center"
android:textSize="16sp"
android:textColor="@color/colorSecondaryTextLight" android:textColor="@color/colorSecondaryTextLight"
android:textSize="16sp"
android:visibility="gone" android:visibility="gone"
tools:visibility="visible"/> app:layout_constraintBottom_toTopOf="@id/layout_message_composer"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/text_chat_title"
tools:visibility="visible" />
<chat.rocket.android.widget.autocompletion.ui.SuggestionsView <chat.rocket.android.widget.autocompletion.ui.SuggestionsView
android:id="@+id/suggestions_view" android:id="@+id/suggestions_view"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="@color/suggestion_background_color"
app:layout_constraintBottom_toTopOf="@id/layout_message_composer" />
<TextView
android:id="@+id/text_typing_status"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="5dp"
android:layout_marginEnd="16dp"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:maxLines="2"
android:visibility="gone"
app:layout_constraintBottom_toTopOf="@id/layout_message_composer" app:layout_constraintBottom_toTopOf="@id/layout_message_composer"
android:background="@color/suggestion_background_color" /> app:layout_constraintEnd_toStartOf="parent" />
<include <include
android:id="@+id/layout_message_composer" android:id="@+id/layout_message_composer"
...@@ -102,18 +114,18 @@ ...@@ -102,18 +114,18 @@
android:id="@+id/view_dim" android:id="@+id/view_dim"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
app:layout_constraintBottom_toTopOf="@id/layout_message_composer"
android:background="@color/colorDim" android:background="@color/colorDim"
android:visibility="gone" /> android:visibility="gone"
app:layout_constraintBottom_toTopOf="@id/layout_message_composer" />
<include <include
android:id="@+id/layout_message_attachment_options" android:id="@+id/layout_message_attachment_options"
layout="@layout/message_attachment_options" layout="@layout/message_attachment_options"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
app:layout_constraintBottom_toTopOf="@id/layout_message_composer"
android:layout_margin="5dp" android:layout_margin="5dp"
android:visibility="gone" /> android:visibility="gone"
app:layout_constraintBottom_toTopOf="@id/layout_message_composer" />
<TextView <TextView
android:id="@+id/connection_status_text" android:id="@+id/connection_status_text"
......
...@@ -36,7 +36,7 @@ ...@@ -36,7 +36,7 @@
android:id="@+id/iv_pin_icon" android:id="@+id/iv_pin_icon"
android:layout_width="100dp" android:layout_width="100dp"
android:layout_height="100dp" android:layout_height="100dp"
android:src="@drawable/ic_pin_black_24dp" android:src="@drawable/ic_action_message_pin_24dp"
android:tint="@color/icon_grey" android:tint="@color/icon_grey"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
......
...@@ -7,11 +7,11 @@ ...@@ -7,11 +7,11 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="?android:attr/selectableItemBackground" android:background="?android:attr/selectableItemBackground"
android:clickable="true" android:clickable="true"
android:paddingStart="@dimen/screen_edge_left_and_right_padding" android:focusable="true"
android:paddingEnd="@dimen/screen_edge_left_and_right_padding"
android:paddingTop="@dimen/message_item_top_and_bottom_padding"
android:paddingBottom="@dimen/message_item_top_and_bottom_padding" android:paddingBottom="@dimen/message_item_top_and_bottom_padding"
android:focusable="true"> android:paddingEnd="@dimen/screen_edge_left_and_right_padding"
android:paddingStart="@dimen/screen_edge_left_and_right_padding"
android:paddingTop="@dimen/message_item_top_and_bottom_padding">
<include <include
android:id="@+id/layout_avatar" android:id="@+id/layout_avatar"
...@@ -20,36 +20,39 @@ ...@@ -20,36 +20,39 @@
android:layout_height="40dp" android:layout_height="40dp"
android:layout_marginTop="5dp" android:layout_marginTop="5dp"
app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@id/new_messages_notif" /> app:layout_constraintTop_toBottomOf="@+id/new_messages_notif" />
<LinearLayout <LinearLayout
android:id="@+id/new_messages_notif" android:id="@+id/new_messages_notif"
tools:visibility="visible"
android:visibility="gone"
android:orientation="horizontal"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="horizontal"
android:visibility="gone"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"> app:layout_constraintTop_toTopOf="parent"
tools:visibility="visible">
<View <View
android:layout_gravity="center"
android:layout_height="1dp"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_weight="1" android:layout_height="1dp"
android:layout_gravity="center"
android:layout_marginEnd="4dp" android:layout_marginEnd="4dp"
android:background="@color/red"/> android:layout_weight="1"
android:background="@color/red" />
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:text="@string/msg_unread_messages"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/msg_unread_messages"
android:textColor="@color/red" /> android:textColor="@color/red" />
<View <View
android:layout_gravity="center"
android:layout_height="1dp"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_weight="1" android:layout_height="1dp"
android:layout_gravity="center"
android:layout_marginStart="4dp" android:layout_marginStart="4dp"
android:background="@color/red"/> android:layout_weight="1"
android:background="@color/red" />
</LinearLayout> </LinearLayout>
<LinearLayout <LinearLayout
...@@ -58,8 +61,8 @@ ...@@ -58,8 +61,8 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="16dp" android:layout_marginStart="16dp"
android:orientation="horizontal" android:orientation="horizontal"
app:layout_constraintTop_toBottomOf="@id/new_messages_notif" app:layout_constraintLeft_toRightOf="@+id/layout_avatar"
app:layout_constraintLeft_toRightOf="@+id/layout_avatar"> app:layout_constraintTop_toBottomOf="@+id/new_messages_notif">
<TextView <TextView
android:id="@+id/text_sender" android:id="@+id/text_sender"
...@@ -80,11 +83,22 @@ ...@@ -80,11 +83,22 @@
android:id="@+id/text_edit_indicator" android:id="@+id/text_edit_indicator"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/msg_edited"
android:layout_marginStart="8dp" android:layout_marginStart="8dp"
android:text="@string/msg_edited"
android:textStyle="italic" android:textStyle="italic"
android:visibility="gone" android:visibility="gone"
tools:visibility="visible" /> tools:visibility="visible" />
<ImageView
android:id="@+id/image_star_indicator"
android:layout_width="14dp"
android:layout_height="14dp"
android:layout_gravity="center_vertical"
android:layout_marginStart="8dp"
android:layout_marginTop="2dp"
android:src="@drawable/ic_action_message_star_24dp"
android:visibility="gone"
tools:visibility="visible" />
</LinearLayout> </LinearLayout>
<TextView <TextView
...@@ -94,12 +108,13 @@ ...@@ -94,12 +108,13 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="2dp" android:layout_marginBottom="2dp"
android:layout_marginTop="5dp" android:layout_marginTop="5dp"
app:layout_constraintLeft_toLeftOf="@id/top_container" app:layout_constraintLeft_toLeftOf="@+id/top_container"
app:layout_constraintRight_toRightOf="parent" app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/top_container" app:layout_constraintTop_toBottomOf="@+id/top_container"
tools:text="This is a multiline chat message from Bertie that will take more than just one line of text. I have sure that everything is amazing!" /> tools:text="This is a multiline chat message from Bertie that will take more than just one line of text. I have sure that everything is amazing!" />
<include layout="@layout/layout_reactions" <include
layout="@layout/layout_reactions"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="@+id/text_content" app:layout_constraintEnd_toEndOf="@+id/text_content"
......
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"> <menu xmlns:android="http://schemas.android.com/apk/res/android">
<group android:id="@+id/common_actions">
<item <item
android:id="@+id/action_menu_msg_reply" android:id="@+id/action_message_reply"
android:icon="@drawable/ic_reply_black_24px" android:icon="@drawable/ic_action_message_reply_24dp"
android:title="@string/action_msg_reply" /> android:title="@string/action_msg_reply" />
<item <item
android:id="@+id/action_menu_msg_quote" android:id="@+id/action_message_quote"
android:icon="@drawable/ic_quote_black_24px" android:icon="@drawable/ic_action_message_quote_24dp"
android:title="@string/action_msg_quote" /> android:title="@string/action_msg_quote" />
<item <item
android:id="@+id/action_menu_msg_edit" android:id="@+id/action_message_copy"
android:icon="@drawable/ic_edit_black_24px" android:icon="@drawable/ic_action_message_copy_24dp"
android:title="@string/action_msg_edit" />
<item
android:id="@+id/action_menu_msg_copy"
android:icon="@drawable/ic_content_copy_black_24px"
android:title="@string/action_msg_copy" /> android:title="@string/action_msg_copy" />
<item <item
...@@ -33,20 +27,22 @@ ...@@ -33,20 +27,22 @@
<!--android:title="@string/action_msg_share" />--> <!--android:title="@string/action_msg_share" />-->
<item <item
android:id="@+id/action_menu_msg_pin_unpin" android:id="@+id/action_message_star"
android:icon="@drawable/ic_pin_black_24dp" android:icon="@drawable/ic_action_message_star_24dp"
android:title="@string/action_msg_star" />
<item
android:id="@+id/action_message_unpin"
android:icon="@drawable/ic_action_message_pin_24dp"
android:title="@string/action_msg_pin" /> android:title="@string/action_msg_pin" />
<!--<item--> <item
<!--android:id="@+id/action_menu_msg_star"--> android:id="@+id/action_message_edit"
<!--andrtextIconicon="@drawable/ic_star_black_24px"--> android:icon="@drawable/ic_action_message_edit_24dp"
<!--android:title="@string/action_msg_star" />--> android:title="@string/action_msg_edit" />
</group>
<group android:id="@+id/dangerous_actions">
<item <item
android:id="@+id/action_menu_msg_delete" android:id="@+id/action_message_delete"
android:icon="@drawable/ic_delete_black_24px" android:icon="@drawable/ic_action_message_delete_24dp"
android:title="@string/action_msg_delete" /> android:title="@string/action_msg_delete" />
</group>
</menu> </menu>
\ No newline at end of file
...@@ -111,6 +111,14 @@ ...@@ -111,6 +111,14 @@
<string name="msg_no_chat_title">Sin mensajes de chat</string> <string name="msg_no_chat_title">Sin mensajes de chat</string>
<string name="msg_no_chat_description">Comience a conversar para ver\nsus mensajes aquí.</string> <string name="msg_no_chat_description">Comience a conversar para ver\nsus mensajes aquí.</string>
<string name="msg_edited">(editado)</string> <string name="msg_edited">(editado)</string>
// TODO: Add proper translation.
<string name="msg_and">\u0020and\u0020</string>
// TODO: Add proper translation.
<string name="msg_is_typing">\u0020is typing…</string>
// TODO: Add proper translation.
<string name="msg_are_typing">\u0020are typing…</string>
// TODO: Add proper translation.
<string name="msg_several_users_are_typing">Several users are typing…</string>
<string name="msg_no_search_found">No se han encontrado resultados</string> <string name="msg_no_search_found">No se han encontrado resultados</string>
<!-- System messages --> <!-- System messages -->
...@@ -136,6 +144,8 @@ ...@@ -136,6 +144,8 @@
<string name="action_msg_pin">Fijar mensaje</string> <string name="action_msg_pin">Fijar mensaje</string>
<string name="action_msg_unpin">Soltar mensaje</string> <string name="action_msg_unpin">Soltar mensaje</string>
<string name="action_msg_star">Star mensaje</string> <string name="action_msg_star">Star mensaje</string>
// TODO: Add proper translation.
<string name="action_msg_unstar">Unstar Message</string>
<string name="action_msg_share">Compartir</string> <string name="action_msg_share">Compartir</string>
<string name="action_title_editing">Edición de mensaje</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_add_reaction">Añadir una reacción</string>
...@@ -144,6 +154,8 @@ ...@@ -144,6 +154,8 @@
<string name="permission_editing_not_allowed">La edición no és permitida</string> <string name="permission_editing_not_allowed">La edición no és permitida</string>
<string name="permission_deleting_not_allowed">Eliminar no és permitido</string> <string name="permission_deleting_not_allowed">Eliminar no és permitido</string>
<string name="permission_pinning_not_allowed">Fijar no és permitido</string> <string name="permission_pinning_not_allowed">Fijar no és permitido</string>
// TODO: Add proper translation.
<string name="permission_starring_not_allowed">Starring is not allowed</string>
<!-- Members List --> <!-- Members List -->
<string name="title_members_list">Lista de miembros</string> <string name="title_members_list">Lista de miembros</string>
......
...@@ -111,6 +111,14 @@ ...@@ -111,6 +111,14 @@
<string name="msg_no_chat_title">Aucun message de discussion</string> <string name="msg_no_chat_title">Aucun message de discussion</string>
<string name="msg_no_chat_description">Commencez à converser pour voir\nvos messages ici.</string> <string name="msg_no_chat_description">Commencez à converser pour voir\nvos messages ici.</string>
<string name="msg_edited">(édité)</string> <string name="msg_edited">(édité)</string>
// TODO: Add proper translation.
<string name="msg_and">\u0020and\u0020</string>
// TODO: Add proper translation.
<string name="msg_is_typing">\u0020is typing…</string>
// TODO: Add proper translation.
<string name="msg_are_typing">\u0020are typing…</string>
// TODO: Add proper translation.
<string name="msg_several_users_are_typing">Several users are typing…</string>
<string name="msg_no_search_found">Aucun résultat trouvé</string> <string name="msg_no_search_found">Aucun résultat trouvé</string>
<!-- System messages --> <!-- System messages -->
...@@ -135,7 +143,10 @@ ...@@ -135,7 +143,10 @@
<string name="action_msg_delete">Effacer</string> <string name="action_msg_delete">Effacer</string>
<string name="action_msg_pin">Épingle message</string> <string name="action_msg_pin">Épingle message</string>
<string name="action_msg_unpin">Enlever message</string> <string name="action_msg_unpin">Enlever message</string>
// TODO: Add proper translation.
<string name="action_msg_star">Star message</string> <string name="action_msg_star">Star message</string>
// TODO: Add proper translation.
<string name="action_msg_unstar">Unstar Message</string>
<string name="action_msg_share">Partager</string> <string name="action_msg_share">Partager</string>
<string name="action_title_editing">Modification du message</string> <string name="action_title_editing">Modification du message</string>
<string name="action_msg_add_reaction">Ajouter une réaction</string> <string name="action_msg_add_reaction">Ajouter une réaction</string>
...@@ -144,6 +155,8 @@ ...@@ -144,6 +155,8 @@
<string name="permission_editing_not_allowed">L\'édition n\'est pas autorisée</string> <string name="permission_editing_not_allowed">L\'édition n\'est pas autorisée</string>
<string name="permission_deleting_not_allowed">La suppression n\'est pas autorisée</string> <string name="permission_deleting_not_allowed">La suppression n\'est pas autorisée</string>
<string name="permission_pinning_not_allowed">L\'épinglage n\'est pas autorisé</string> <string name="permission_pinning_not_allowed">L\'épinglage n\'est pas autorisé</string>
// TODO: Add proper translation.
<string name="permission_starring_not_allowed">Starring is not allowed</string>
<!-- Members List --> <!-- Members List -->
<string name="title_members_list">Liste des membres</string> <string name="title_members_list">Liste des membres</string>
......
...@@ -113,6 +113,14 @@ ...@@ -113,6 +113,14 @@
<string name="msg_no_chat_title">कोई चैट संदेश नहीं</string> <string name="msg_no_chat_title">कोई चैट संदेश नहीं</string>
<string name="msg_no_chat_description">यहां अपने संदेश देखने के लिए\nबातचीत शुरू करें।</string> <string name="msg_no_chat_description">यहां अपने संदेश देखने के लिए\nबातचीत शुरू करें।</string>
<string name="msg_edited">(संपादित)</string> <string name="msg_edited">(संपादित)</string>
// TODO: Add proper translation.
<string name="msg_and">\u0020and\u0020</string>
// TODO: Add proper translation.
<string name="msg_is_typing">\u0020is typing…</string>
// TODO: Add proper translation.
<string name="msg_are_typing">\u0020are typing…</string>
// TODO: Add proper translation.
<string name="msg_several_users_are_typing">Several users are typing…</string>
<string name="msg_no_search_found">कोई परिणाम नहीं मिला</string> <string name="msg_no_search_found">कोई परिणाम नहीं मिला</string>
<!-- System messages --> <!-- System messages -->
...@@ -138,6 +146,8 @@ ...@@ -138,6 +146,8 @@
<string name="action_msg_pin">संदेश को पिन करें</string> <string name="action_msg_pin">संदेश को पिन करें</string>
<string name="action_msg_unpin">संदेश को पिन से हटाएँ</string> <string name="action_msg_unpin">संदेश को पिन से हटाएँ</string>
<string name="action_msg_star">संदेश को स्टार करें</string> <string name="action_msg_star">संदेश को स्टार करें</string>
// TODO: Add proper translation.
<string name="action_msg_unstar">Unstar Message</string>
<string name="action_msg_share">शेयर करें</string> <string name="action_msg_share">शेयर करें</string>
<string name="action_title_editing">संपादन संदेश</string> <string name="action_title_editing">संपादन संदेश</string>
<string name="action_msg_add_reaction">प्रतिक्रिया जोड़ें</string> <string name="action_msg_add_reaction">प्रतिक्रिया जोड़ें</string>
...@@ -146,6 +156,8 @@ ...@@ -146,6 +156,8 @@
<string name="permission_editing_not_allowed">संपादन की अनुमति नहीं है</string> <string name="permission_editing_not_allowed">संपादन की अनुमति नहीं है</string>
<string name="permission_deleting_not_allowed">हटाने की अनुमति नहीं है</string> <string name="permission_deleting_not_allowed">हटाने की अनुमति नहीं है</string>
<string name="permission_pinning_not_allowed">पिनि करने की अनुमति नहीं है</string> <string name="permission_pinning_not_allowed">पिनि करने की अनुमति नहीं है</string>
// TODO: Add proper translation.
<string name="permission_starring_not_allowed">Starring is not allowed</string>
<!-- Members List --> <!-- Members List -->
<string name="title_members_list">सदस्यों की सूची</string> <string name="title_members_list">सदस्यों की सूची</string>
......
...@@ -107,6 +107,10 @@ ...@@ -107,6 +107,10 @@
<string name="msg_image_saved_successfully">Imagem salva na galeria</string> <string name="msg_image_saved_successfully">Imagem salva na galeria</string>
<string name="msg_image_saved_failed">Falha ao salvar a imagem</string> <string name="msg_image_saved_failed">Falha ao salvar a imagem</string>
<string name="msg_edited">(editado)</string> <string name="msg_edited">(editado)</string>
<string name="msg_and">\u0020e\u0020</string>
<string name="msg_is_typing">\u0020está digitando…</string>
<string name="msg_are_typing">\u0020estão digitando…</string>
<string name="msg_several_users_are_typing">Vários usuários estão digitando…</string>
<string name="msg_no_search_found">nenhum resultado encontrado</string> <string name="msg_no_search_found">nenhum resultado encontrado</string>
<!-- System messages --> <!-- System messages -->
...@@ -132,6 +136,7 @@ ...@@ -132,6 +136,7 @@
<string name="action_msg_pin">Pinar mensagem</string> <string name="action_msg_pin">Pinar mensagem</string>
<string name="action_msg_unpin">Despinar mensagem</string> <string name="action_msg_unpin">Despinar mensagem</string>
<string name="action_msg_star">Favoritar mensagem</string> <string name="action_msg_star">Favoritar mensagem</string>
<string name="action_msg_unstar">Desfavoritar messagem</string>
<string name="action_msg_share">Compartilhar</string> <string name="action_msg_share">Compartilhar</string>
<string name="action_title_editing">Editando mensagem</string> <string name="action_title_editing">Editando mensagem</string>
<string name="action_msg_add_reaction">Adicionar reação</string> <string name="action_msg_add_reaction">Adicionar reação</string>
...@@ -140,6 +145,7 @@ ...@@ -140,6 +145,7 @@
<string name="permission_editing_not_allowed">Edição não permitida</string> <string name="permission_editing_not_allowed">Edição não permitida</string>
<string name="permission_deleting_not_allowed">Remoção não permitida</string> <string name="permission_deleting_not_allowed">Remoção não permitida</string>
<string name="permission_pinning_not_allowed">Pinagem não permitida</string> <string name="permission_pinning_not_allowed">Pinagem não permitida</string>
<string name="permission_starring_not_allowed">Favoritar não permitido</string>
<!-- Members List --> <!-- Members List -->
<string name="title_members_list">Lista de Membros</string> <string name="title_members_list">Lista de Membros</string>
......
...@@ -131,6 +131,7 @@ ...@@ -131,6 +131,7 @@
<string name="action_msg_pin">Pin Message</string> <string name="action_msg_pin">Pin Message</string>
<string name="action_msg_unpin">Unpin Message</string> <string name="action_msg_unpin">Unpin Message</string>
<string name="action_msg_star">Star Message</string> <string name="action_msg_star">Star Message</string>
<string name="action_msg_unstar">Unstar Message</string>
<string name="action_msg_share">Share</string> <string name="action_msg_share">Share</string>
<string name="action_title_editing">Editing Message</string> <string name="action_title_editing">Editing Message</string>
<string name="action_msg_add_reaction">Add reaction</string> <string name="action_msg_add_reaction">Add reaction</string>
...@@ -139,6 +140,8 @@ ...@@ -139,6 +140,8 @@
<string name="permission_editing_not_allowed">Editing is not allowed</string> <string name="permission_editing_not_allowed">Editing is not allowed</string>
<string name="permission_deleting_not_allowed">Deleting is not allowed</string> <string name="permission_deleting_not_allowed">Deleting is not allowed</string>
<string name="permission_pinning_not_allowed">Pinning is not allowed</string> <string name="permission_pinning_not_allowed">Pinning is not allowed</string>
// TODO: Add proper translation.
<string name="permission_starring_not_allowed">Starring is not allowed</string>
<!-- Members List --> <!-- Members List -->
<string name="title_members_list">Members List</string> <string name="title_members_list">Members List</string>
......
...@@ -108,6 +108,10 @@ ...@@ -108,6 +108,10 @@
<string name="msg_image_saved_successfully">Image has been saved to gallery</string> <string name="msg_image_saved_successfully">Image has been saved to gallery</string>
<string name="msg_image_saved_failed">Failed to save image</string> <string name="msg_image_saved_failed">Failed to save image</string>
<string name="msg_edited">(edited)</string> <string name="msg_edited">(edited)</string>
<string name="msg_and">\u0020and\u0020</string>
<string name="msg_is_typing">\u0020is typing…</string>
<string name="msg_are_typing">\u0020are typing…</string>
<string name="msg_several_users_are_typing">Several users are typing…</string>
<string name="msg_no_search_found">No result found</string> <string name="msg_no_search_found">No result found</string>
<!-- System messages --> <!-- System messages -->
...@@ -133,6 +137,7 @@ ...@@ -133,6 +137,7 @@
<string name="action_msg_pin">Pin Message</string> <string name="action_msg_pin">Pin Message</string>
<string name="action_msg_unpin">Unpin Message</string> <string name="action_msg_unpin">Unpin Message</string>
<string name="action_msg_star">Star Message</string> <string name="action_msg_star">Star Message</string>
<string name="action_msg_unstar">Unstar Message</string>
<string name="action_msg_share">Share</string> <string name="action_msg_share">Share</string>
<string name="action_title_editing">Editing Message</string> <string name="action_title_editing">Editing Message</string>
<string name="action_msg_add_reaction">Add reaction</string> <string name="action_msg_add_reaction">Add reaction</string>
...@@ -141,6 +146,7 @@ ...@@ -141,6 +146,7 @@
<string name="permission_editing_not_allowed">Editing is not allowed</string> <string name="permission_editing_not_allowed">Editing is not allowed</string>
<string name="permission_deleting_not_allowed">Deleting is not allowed</string> <string name="permission_deleting_not_allowed">Deleting is not allowed</string>
<string name="permission_pinning_not_allowed">Pinning is not allowed</string> <string name="permission_pinning_not_allowed">Pinning is not allowed</string>
<string name="permission_starring_not_allowed">Starring is not allowed</string>
<!-- Members List --> <!-- Members List -->
<string name="title_members_list">Members List</string> <string name="title_members_list">Members List</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