Commit 677a5eec authored by Filipe de Lima Brito's avatar Filipe de Lima Brito

Merge branch 'develop-2.x' of https://github.com/RocketChat/Rocket.Chat.Android into fix/logout

parents 95ba6ac3 61cb7b9e
...@@ -8,14 +8,15 @@ import chat.rocket.android.chatroom.presentation.ChatRoomPresenter ...@@ -8,14 +8,15 @@ import chat.rocket.android.chatroom.presentation.ChatRoomPresenter
import chat.rocket.android.chatroom.viewmodel.* import chat.rocket.android.chatroom.viewmodel.*
import chat.rocket.android.util.extensions.inflate import chat.rocket.android.util.extensions.inflate
import chat.rocket.core.model.Message import chat.rocket.core.model.Message
import chat.rocket.core.model.isSystemMessage
import timber.log.Timber import timber.log.Timber
import java.security.InvalidParameterException import java.security.InvalidParameterException
class ChatRoomAdapter( class ChatRoomAdapter(
private val roomType: String, private val roomType: String,
private val roomName: String, private val roomName: String,
private val presenter: ChatRoomPresenter?, private val presenter: ChatRoomPresenter?,
private val enableActions: Boolean = true private val enableActions: Boolean = true
) : RecyclerView.Adapter<BaseViewHolder<*>>() { ) : RecyclerView.Adapter<BaseViewHolder<*>>() {
private val dataSet = ArrayList<BaseViewModel<*>>() private val dataSet = ArrayList<BaseViewModel<*>>()
...@@ -25,7 +26,7 @@ class ChatRoomAdapter( ...@@ -25,7 +26,7 @@ class ChatRoomAdapter(
} }
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseViewHolder<*> { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseViewHolder<*> {
return when(viewType.toViewType()) { return when (viewType.toViewType()) {
BaseViewModel.ViewType.MESSAGE -> { BaseViewModel.ViewType.MESSAGE -> {
val view = parent.inflate(R.layout.item_message) val view = parent.inflate(R.layout.item_message)
MessageViewHolder(view, actionsListener) MessageViewHolder(view, actionsListener)
...@@ -86,16 +87,27 @@ class ChatRoomAdapter( ...@@ -86,16 +87,27 @@ class ChatRoomAdapter(
} }
fun prependData(dataSet: List<BaseViewModel<*>>) { fun prependData(dataSet: List<BaseViewModel<*>>) {
this.dataSet.addAll(0, dataSet) val item = dataSet.firstOrNull { newItem ->
notifyItemRangeInserted(0, dataSet.size) this.dataSet.indexOfFirst { it.messageId == newItem.messageId && it.viewType == newItem.viewType } > -1
}
if (item == null) {
this.dataSet.addAll(0, dataSet)
notifyItemRangeInserted(0, dataSet.size)
}
} }
fun updateItem(message: BaseViewModel<*>) { fun updateItem(message: BaseViewModel<*>) {
val index = dataSet.indexOfLast { it.messageId == message.messageId } val index = dataSet.indexOfLast { it.messageId == message.messageId }
val indexOfFirst = dataSet.indexOfFirst { it.messageId == message.messageId }
Timber.d("index: $index") Timber.d("index: $index")
if (index > -1) { if (index > -1) {
dataSet[index] = message dataSet[index] = message
notifyItemChanged(index) notifyItemChanged(index)
// Delete message only if current is a system message update, i.e.: Message Removed
if (message.message.isSystemMessage() && indexOfFirst > -1 && indexOfFirst != index) {
dataSet.removeAt(indexOfFirst)
notifyItemRemoved(indexOfFirst)
}
} }
} }
......
...@@ -20,6 +20,9 @@ class MessageViewHolder( ...@@ -20,6 +20,9 @@ class MessageViewHolder(
override fun bindViews(data: MessageViewModel) { override fun bindViews(data: MessageViewModel) {
with(itemView) { with(itemView) {
if (data.isFirstUnread) new_messages_notif.visibility = View.VISIBLE
else new_messages_notif.visibility = View.GONE
text_message_time.text = data.time text_message_time.text = data.time
text_sender.text = data.senderName text_sender.text = data.senderName
text_content.text = data.content text_content.text = data.content
......
...@@ -20,14 +20,16 @@ import dagger.android.DispatchingAndroidInjector ...@@ -20,14 +20,16 @@ import dagger.android.DispatchingAndroidInjector
import dagger.android.support.HasSupportFragmentInjector import dagger.android.support.HasSupportFragmentInjector
import kotlinx.android.synthetic.main.app_bar_chat_room.* import kotlinx.android.synthetic.main.app_bar_chat_room.*
import javax.inject.Inject import javax.inject.Inject
import timber.log.Timber
fun Context.chatRoomIntent(chatRoomId: String, chatRoomName: String, chatRoomType: String, isChatRoomReadOnly: Boolean): Intent { fun Context.chatRoomIntent(chatRoomId: String, chatRoomName: String, chatRoomType: String, isChatRoomReadOnly: Boolean, chatRoomLastSeen: Long): Intent {
return Intent(this, ChatRoomActivity::class.java).apply { return Intent(this, ChatRoomActivity::class.java).apply {
putExtra(INTENT_CHAT_ROOM_ID, chatRoomId) putExtra(INTENT_CHAT_ROOM_ID, chatRoomId)
putExtra(INTENT_CHAT_ROOM_NAME, chatRoomName) putExtra(INTENT_CHAT_ROOM_NAME, chatRoomName)
putExtra(INTENT_CHAT_ROOM_TYPE, chatRoomType) putExtra(INTENT_CHAT_ROOM_TYPE, chatRoomType)
putExtra(INTENT_IS_CHAT_ROOM_READ_ONLY, isChatRoomReadOnly) putExtra(INTENT_IS_CHAT_ROOM_READ_ONLY, isChatRoomReadOnly)
putExtra(INTENT_CHAT_ROOM_LAST_SEEN, chatRoomLastSeen)
} }
} }
...@@ -35,6 +37,7 @@ private const val INTENT_CHAT_ROOM_ID = "chat_room_id" ...@@ -35,6 +37,7 @@ private const val INTENT_CHAT_ROOM_ID = "chat_room_id"
private const val INTENT_CHAT_ROOM_NAME = "chat_room_name" private const val INTENT_CHAT_ROOM_NAME = "chat_room_name"
private const val INTENT_CHAT_ROOM_TYPE = "chat_room_type" private const val INTENT_CHAT_ROOM_TYPE = "chat_room_type"
private const val INTENT_IS_CHAT_ROOM_READ_ONLY = "is_chat_room_read_only" private const val INTENT_IS_CHAT_ROOM_READ_ONLY = "is_chat_room_read_only"
private const val INTENT_CHAT_ROOM_LAST_SEEN = "chat_room_last_seen"
class ChatRoomActivity : AppCompatActivity(), HasSupportFragmentInjector { class ChatRoomActivity : AppCompatActivity(), HasSupportFragmentInjector {
@Inject lateinit var fragmentDispatchingAndroidInjector: DispatchingAndroidInjector<Fragment> @Inject lateinit var fragmentDispatchingAndroidInjector: DispatchingAndroidInjector<Fragment>
...@@ -47,6 +50,7 @@ class ChatRoomActivity : AppCompatActivity(), HasSupportFragmentInjector { ...@@ -47,6 +50,7 @@ class ChatRoomActivity : AppCompatActivity(), HasSupportFragmentInjector {
private lateinit var chatRoomName: String private lateinit var chatRoomName: String
private lateinit var chatRoomType: String private lateinit var chatRoomType: String
private var isChatRoomReadOnly: Boolean = false private var isChatRoomReadOnly: Boolean = false
private var chatRoomLastSeen: Long = -1L
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
AndroidInjection.inject(this) AndroidInjection.inject(this)
...@@ -70,8 +74,10 @@ class ChatRoomActivity : AppCompatActivity(), HasSupportFragmentInjector { ...@@ -70,8 +74,10 @@ class ChatRoomActivity : AppCompatActivity(), HasSupportFragmentInjector {
setupToolbar() setupToolbar()
chatRoomLastSeen = intent.getLongExtra(INTENT_CHAT_ROOM_LAST_SEEN, -1)
addFragment("ChatRoomFragment", R.id.fragment_container) { addFragment("ChatRoomFragment", R.id.fragment_container) {
newInstance(chatRoomId, chatRoomName, chatRoomType, isChatRoomReadOnly) newInstance(chatRoomId, chatRoomName, chatRoomType, isChatRoomReadOnly, chatRoomLastSeen)
} }
} }
......
...@@ -19,6 +19,7 @@ import chat.rocket.android.chatroom.adapter.ChatRoomAdapter ...@@ -19,6 +19,7 @@ import chat.rocket.android.chatroom.adapter.ChatRoomAdapter
import chat.rocket.android.chatroom.presentation.ChatRoomPresenter import chat.rocket.android.chatroom.presentation.ChatRoomPresenter
import chat.rocket.android.chatroom.presentation.ChatRoomView import chat.rocket.android.chatroom.presentation.ChatRoomView
import chat.rocket.android.chatroom.viewmodel.BaseViewModel import chat.rocket.android.chatroom.viewmodel.BaseViewModel
import chat.rocket.android.chatroom.viewmodel.MessageViewModel
import chat.rocket.android.helper.EndlessRecyclerViewScrollListener import chat.rocket.android.helper.EndlessRecyclerViewScrollListener
import chat.rocket.android.helper.KeyboardHelper import chat.rocket.android.helper.KeyboardHelper
import chat.rocket.android.helper.MessageParser import chat.rocket.android.helper.MessageParser
...@@ -28,22 +29,25 @@ import chat.rocket.android.widget.emoji.Emoji ...@@ -28,22 +29,25 @@ import chat.rocket.android.widget.emoji.Emoji
import chat.rocket.android.widget.emoji.EmojiKeyboardPopup import chat.rocket.android.widget.emoji.EmojiKeyboardPopup
import chat.rocket.android.widget.emoji.EmojiParser import chat.rocket.android.widget.emoji.EmojiParser
import chat.rocket.core.internal.realtime.State import chat.rocket.core.internal.realtime.State
import chat.rocket.core.model.Message
import dagger.android.support.AndroidSupportInjection import dagger.android.support.AndroidSupportInjection
import io.reactivex.disposables.CompositeDisposable import io.reactivex.disposables.CompositeDisposable
import kotlinx.android.synthetic.main.fragment_chat_room.* import kotlinx.android.synthetic.main.fragment_chat_room.*
import kotlinx.android.synthetic.main.message_attachment_options.* import kotlinx.android.synthetic.main.message_attachment_options.*
import kotlinx.android.synthetic.main.item_chat.*
import kotlinx.android.synthetic.main.message_composer.* import kotlinx.android.synthetic.main.message_composer.*
import kotlinx.android.synthetic.main.message_list.* import kotlinx.android.synthetic.main.message_list.*
import timber.log.Timber import timber.log.Timber
import javax.inject.Inject import javax.inject.Inject
fun newInstance(chatRoomId: String, chatRoomName: String, chatRoomType: String, isChatRoomReadOnly: Boolean): Fragment { fun newInstance(chatRoomId: String, chatRoomName: String, chatRoomType: String, isChatRoomReadOnly: Boolean, chatRoomLastSeen: Long): Fragment {
return ChatRoomFragment().apply { return ChatRoomFragment().apply {
arguments = Bundle(1).apply { arguments = Bundle(1).apply {
putString(BUNDLE_CHAT_ROOM_ID, chatRoomId) putString(BUNDLE_CHAT_ROOM_ID, chatRoomId)
putString(BUNDLE_CHAT_ROOM_NAME, chatRoomName) putString(BUNDLE_CHAT_ROOM_NAME, chatRoomName)
putString(BUNDLE_CHAT_ROOM_TYPE, chatRoomType) putString(BUNDLE_CHAT_ROOM_TYPE, chatRoomType)
putBoolean(BUNDLE_IS_CHAT_ROOM_READ_ONLY, isChatRoomReadOnly) putBoolean(BUNDLE_IS_CHAT_ROOM_READ_ONLY, isChatRoomReadOnly)
putLong(BUNDLE_CHAT_ROOM_LAST_SEEN, chatRoomLastSeen)
} }
} }
} }
...@@ -53,18 +57,18 @@ private const val BUNDLE_CHAT_ROOM_NAME = "chat_room_name" ...@@ -53,18 +57,18 @@ private const val BUNDLE_CHAT_ROOM_NAME = "chat_room_name"
private const val BUNDLE_CHAT_ROOM_TYPE = "chat_room_type" private const val BUNDLE_CHAT_ROOM_TYPE = "chat_room_type"
private const val BUNDLE_IS_CHAT_ROOM_READ_ONLY = "is_chat_room_read_only" private const val BUNDLE_IS_CHAT_ROOM_READ_ONLY = "is_chat_room_read_only"
private const val REQUEST_CODE_FOR_PERFORM_SAF = 42 private const val REQUEST_CODE_FOR_PERFORM_SAF = 42
private const val BUNDLE_CHAT_ROOM_LAST_SEEN = "chat_room_last_seen"
class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardPopup.Listener { class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardPopup.Listener {
@Inject lateinit var presenter: ChatRoomPresenter @Inject lateinit var presenter: ChatRoomPresenter
@Inject lateinit var parser: MessageParser @Inject lateinit var parser: MessageParser
private lateinit var adapter: ChatRoomAdapter private lateinit var adapter: ChatRoomAdapter
private lateinit var chatRoomId: String private lateinit var chatRoomId: String
private lateinit var chatRoomName: String private lateinit var chatRoomName: String
private lateinit var chatRoomType: String private lateinit var chatRoomType: String
private lateinit var emojiKeyboardPopup: EmojiKeyboardPopup private lateinit var emojiKeyboardPopup: EmojiKeyboardPopup
private var isChatRoomReadOnly: Boolean = false private var isChatRoomReadOnly: Boolean = false
private var chatRoomLastSeen: Long = -1
private lateinit var actionSnackbar: ActionSnackbar private lateinit var actionSnackbar: ActionSnackbar
private var citation: String? = null private var citation: String? = null
private var editingMessageId: String? = null private var editingMessageId: String? = null
...@@ -89,6 +93,7 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardPopup.Listener { ...@@ -89,6 +93,7 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardPopup.Listener {
chatRoomName = bundle.getString(BUNDLE_CHAT_ROOM_NAME) chatRoomName = bundle.getString(BUNDLE_CHAT_ROOM_NAME)
chatRoomType = bundle.getString(BUNDLE_CHAT_ROOM_TYPE) chatRoomType = bundle.getString(BUNDLE_CHAT_ROOM_TYPE)
isChatRoomReadOnly = bundle.getBoolean(BUNDLE_IS_CHAT_ROOM_READ_ONLY) isChatRoomReadOnly = bundle.getBoolean(BUNDLE_IS_CHAT_ROOM_READ_ONLY)
chatRoomLastSeen = bundle.getLong(BUNDLE_CHAT_ROOM_LAST_SEEN)
} else { } else {
requireNotNull(bundle) { "no arguments supplied when the fragment was instantiated" } requireNotNull(bundle) { "no arguments supplied when the fragment was instantiated" }
} }
...@@ -152,6 +157,27 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardPopup.Listener { ...@@ -152,6 +157,27 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardPopup.Listener {
} }
override fun showMessages(dataSet: List<BaseViewModel<*>>) { override fun showMessages(dataSet: List<BaseViewModel<*>>) {
// track the message sent immediately after the current message
var prevMessageViewModel : MessageViewModel? = null
// Loop over received messages to determine first unread
for (i in dataSet.indices) {
val msgModel = dataSet[i]
if (msgModel is MessageViewModel){
val msg = msgModel.rawData
if (msg.timestamp < chatRoomLastSeen) {
// This message was sent before the last seen of the room. Hence, it was seen.
// if there is a message after (below) this, mark it firstUnread.
if (prevMessageViewModel != null) {
prevMessageViewModel.isFirstUnread = true
}
break
}
prevMessageViewModel = msgModel
}
}
activity?.apply { activity?.apply {
if (recycler_view.adapter == null) { if (recycler_view.adapter == null) {
adapter = ChatRoomAdapter(chatRoomType, chatRoomName, presenter) adapter = ChatRoomAdapter(chatRoomType, chatRoomName, presenter)
...@@ -214,6 +240,10 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardPopup.Listener { ...@@ -214,6 +240,10 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardPopup.Listener {
override fun dispatchUpdateMessage(index: Int, message: List<BaseViewModel<*>>) { override fun dispatchUpdateMessage(index: Int, message: List<BaseViewModel<*>>) {
adapter.updateItem(message.last()) adapter.updateItem(message.last())
if (message.size > 1) {
adapter.updateItem(message.last())
adapter.prependData(listOf(message.first()))
}
} }
override fun dispatchDeleteMessage(msgId: String) { override fun dispatchDeleteMessage(msgId: String) {
......
...@@ -11,7 +11,8 @@ data class MessageViewModel( ...@@ -11,7 +11,8 @@ data class MessageViewModel(
override val time: CharSequence, override val time: CharSequence,
override val senderName: CharSequence, override val senderName: CharSequence,
override val content: CharSequence, override val content: CharSequence,
override val isPinned: Boolean override val isPinned: Boolean,
var isFirstUnread: Boolean
) : BaseMessageViewModel<Message> { ) : BaseMessageViewModel<Message> {
override val viewType: Int override val viewType: Int
get() = BaseViewModel.ViewType.MESSAGE.viewType get() = BaseViewModel.ViewType.MESSAGE.viewType
......
...@@ -138,16 +138,25 @@ class ViewModelMapper @Inject constructor(private val context: Context, ...@@ -138,16 +138,25 @@ class ViewModelMapper @Inject constructor(private val context: Context,
val quoteUrl = HttpUrl.parse(url.url) val quoteUrl = HttpUrl.parse(url.url)
val serverUrl = HttpUrl.parse(baseUrl) val serverUrl = HttpUrl.parse(baseUrl)
if (quoteUrl != null && serverUrl != null) { if (quoteUrl != null && serverUrl != null) {
quote = makeQuote(quoteUrl, serverUrl) quote = makeQuote(quoteUrl, serverUrl)?.let {
getMessageWithoutQuoteMarkdown(it)
}
} }
} }
} }
} }
val content = getContent(context, message, quote) val content = getContent(context, getMessageWithoutQuoteMarkdown(message), quote)
MessageViewModel(message = message, rawData = message, messageId = message.id, MessageViewModel(message = getMessageWithoutQuoteMarkdown(message), rawData = message,
avatar = avatar!!, time = time, senderName = sender, messageId = message.id, avatar = avatar!!, time = time, senderName = sender,
content = content, isPinned = message.pinned) content = content, isPinned = message.pinned, isFirstUnread = false)
}
private fun getMessageWithoutQuoteMarkdown(message: Message): Message {
val baseUrl = settings.baseUrl()
return message.copy(
message = message.message.replace("\\[\\s\\]\\($baseUrl.*\\)".toRegex(), "").trim()
)
} }
private fun getSenderName(message: Message): CharSequence { private fun getSenderName(message: Message): CharSequence {
...@@ -194,7 +203,7 @@ class ViewModelMapper @Inject constructor(private val context: Context, ...@@ -194,7 +203,7 @@ class ViewModelMapper @Inject constructor(private val context: Context,
var quoteViewModel: MessageViewModel? = null var quoteViewModel: MessageViewModel? = null
if (quote != null) { if (quote != null) {
val quoteMessage: Message = quote val quoteMessage: Message = quote
quoteViewModel = map(quoteMessage).first { it is MessageViewModel } as MessageViewModel quoteViewModel = mapMessage(quoteMessage)
} }
return parser.renderMarkdown(message.message, quoteViewModel, currentUsername) return parser.renderMarkdown(message.message, quoteViewModel, currentUsername)
} }
......
...@@ -69,7 +69,7 @@ class ChatRoomsPresenter @Inject constructor(private val view: ChatRoomsView, ...@@ -69,7 +69,7 @@ class ChatRoomsPresenter @Inject constructor(private val view: ChatRoomsView,
} }
navigator.toChatRoom(chatRoom.id, roomName, navigator.toChatRoom(chatRoom.id, roomName,
chatRoom.type.toString(), chatRoom.readonly ?: false) chatRoom.type.toString(), chatRoom.readonly ?: false, chatRoom.lastSeen ?: -1)
} }
/** /**
......
...@@ -59,6 +59,7 @@ class MessageParser @Inject constructor(val context: Application, private val co ...@@ -59,6 +59,7 @@ class MessageParser @Inject constructor(val context: Application, private val co
parentNode.appendChild(quoteNode) parentNode.appendChild(quoteNode)
quoteNode.accept(QuoteMessageSenderVisitor(context, configuration, builder, senderName.length)) quoteNode.accept(QuoteMessageSenderVisitor(context, configuration, builder, senderName.length))
quoteNode = parser.parse("> ${toLenientMarkdown(quote.rawData.message)}") quoteNode = parser.parse("> ${toLenientMarkdown(quote.rawData.message)}")
quoteNode.accept(EmojiVisitor(builder))
quoteNode.accept(QuoteMessageBodyVisitor(context, configuration, builder)) quoteNode.accept(QuoteMessageBodyVisitor(context, configuration, builder))
} }
parentNode.accept(LinkVisitor(builder)) parentNode.accept(LinkVisitor(builder))
......
...@@ -29,8 +29,8 @@ class MainNavigator(internal val activity: MainActivity, internal val context: C ...@@ -29,8 +29,8 @@ class MainNavigator(internal val activity: MainActivity, internal val context: C
} }
} }
fun toChatRoom(chatRoomId: String, chatRoomName: String, chatRoomType: String, isChatRoomReadOnly: Boolean) { fun toChatRoom(chatRoomId: String, chatRoomName: String, chatRoomType: String, isChatRoomReadOnly: Boolean, chatRoomLastSeen: Long) {
activity.startActivity(context.chatRoomIntent(chatRoomId, chatRoomName, chatRoomType, isChatRoomReadOnly)) activity.startActivity(context.chatRoomIntent(chatRoomId, chatRoomName, chatRoomType, isChatRoomReadOnly, chatRoomLastSeen))
activity.overridePendingTransition(R.anim.open_enter, R.anim.open_exit) activity.overridePendingTransition(R.anim.open_enter, R.anim.open_exit)
} }
} }
\ No newline at end of file
...@@ -4,10 +4,11 @@ ...@@ -4,10 +4,11 @@
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="12dp" android:background="?android:attr/selectableItemBackground"
android:layout_marginEnd="@dimen/screen_edge_left_and_right_margins" android:paddingStart="@dimen/screen_edge_left_and_right_padding"
android:layout_marginStart="@dimen/screen_edge_left_and_right_margins" android:paddingEnd="@dimen/screen_edge_left_and_right_padding"
android:layout_marginTop="12dp"> android:paddingTop="@dimen/chat_item_top_and_bottom_padding"
android:paddingBottom="@dimen/chat_item_top_and_bottom_padding">
<include <include
android:id="@+id/layout_avatar" android:id="@+id/layout_avatar"
......
...@@ -4,10 +4,11 @@ ...@@ -4,10 +4,11 @@
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="6dp" android:background="?android:attr/selectableItemBackground"
android:layout_marginEnd="@dimen/screen_edge_left_and_right_margins" android:paddingBottom="@dimen/member_item_top_and_bottom_padding"
android:layout_marginStart="@dimen/screen_edge_left_and_right_margins" android:paddingEnd="@dimen/screen_edge_left_and_right_padding"
android:layout_marginTop="6dp"> android:paddingStart="@dimen/screen_edge_left_and_right_padding"
android:paddingTop="@dimen/member_item_top_and_bottom_padding">
<include <include
android:id="@+id/layout_avatar" android:id="@+id/layout_avatar"
......
...@@ -4,10 +4,13 @@ ...@@ -4,10 +4,13 @@
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="6dp" android:background="?android:attr/selectableItemBackground"
android:layout_marginEnd="@dimen/screen_edge_left_and_right_margins" android:clickable="true"
android:layout_marginStart="@dimen/screen_edge_left_and_right_margins" android:paddingStart="@dimen/screen_edge_left_and_right_padding"
android:layout_marginTop="6dp"> 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:focusable="true">
<include <include
android:id="@+id/layout_avatar" android:id="@+id/layout_avatar"
...@@ -16,7 +19,30 @@ ...@@ -16,7 +19,30 @@
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_toTopOf="parent" /> app:layout_constraintTop_toBottomOf="@id/new_messages_notif" />
<LinearLayout
android:id="@+id/new_messages_notif"
tools:visibility="visible"
android:visibility="gone"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent">
<View
android:layout_gravity="center"
android:layout_height="1dp"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_marginRight="4dp"
android:background="@color/red"/>
<TextView
android:layout_width="wrap_content"
android:text="@string/msg_unread_messages"
android:layout_height="wrap_content"
android:textColor="@color/red" />
</LinearLayout>
<LinearLayout <LinearLayout
android:id="@+id/top_container" android:id="@+id/top_container"
...@@ -24,6 +50,7 @@ ...@@ -24,6 +50,7 @@
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">
<TextView <TextView
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
android:id="@+id/attachment_container" android:id="@+id/attachment_container"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="?android:attr/selectableItemBackground"
android:paddingStart="72dp" android:paddingStart="72dp"
android:paddingEnd="@dimen/screen_edge_left_and_right_margins" android:paddingEnd="@dimen/screen_edge_left_and_right_margins"
android:orientation="vertical"> android:orientation="vertical">
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
android:id="@+id/url_preview_layout" android:id="@+id/url_preview_layout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="?android:attr/selectableItemBackground"
android:paddingStart="72dp" android:paddingStart="72dp"
android:paddingEnd="24dp"> android:paddingEnd="24dp">
......
...@@ -66,6 +66,7 @@ ...@@ -66,6 +66,7 @@
<string name="msg_utc_offset">Deslocamento de UTC</string> <string name="msg_utc_offset">Deslocamento de UTC</string>
<string name="msg_new_password">Informe a nova senha</string> <string name="msg_new_password">Informe a nova senha</string>
<string name="msg_confirm_password">Confirme a nova senha</string> <string name="msg_confirm_password">Confirme a nova senha</string>
<string name="msg_unread_messages">Mensagens não lidas</string>
<!-- System messages --> <!-- System messages -->
<string name="message_room_name_changed">Nome da sala alterado para: %1$s por %2$s</string> <string name="message_room_name_changed">Nome da sala alterado para: %1$s por %2$s</string>
......
...@@ -4,6 +4,11 @@ ...@@ -4,6 +4,11 @@
<!-- Default screen margins, per the Android Design guidelines. --> <!-- Default screen margins, per the Android Design guidelines. -->
<dimen name="screen_edge_left_and_right_margins">16dp</dimen> <dimen name="screen_edge_left_and_right_margins">16dp</dimen>
<dimen name="screen_edge_left_and_right_padding">16dp</dimen>
<dimen name="chat_item_top_and_bottom_padding">12dp</dimen>
<dimen name="message_item_top_and_bottom_padding">6dp</dimen>
<dimen name="member_item_top_and_bottom_padding">6dp</dimen>
<dimen name="edit_text_margin">10dp</dimen> <dimen name="edit_text_margin">10dp</dimen>
<dimen name="edit_text_drawable_padding">16dp</dimen> <dimen name="edit_text_drawable_padding">16dp</dimen>
......
...@@ -68,6 +68,7 @@ ...@@ -68,6 +68,7 @@
<string name="msg_utc_offset">UTC offset</string> <string name="msg_utc_offset">UTC offset</string>
<string name="msg_new_password">Enter New Password</string> <string name="msg_new_password">Enter New Password</string>
<string name="msg_confirm_password">Confirm New Password</string> <string name="msg_confirm_password">Confirm New Password</string>
<string name="msg_unread_messages">Unread messages</string>
<!-- System messages --> <!-- System messages -->
<string name="message_room_name_changed">Room name changed to: %1$s by %2$s</string> <string name="message_room_name_changed">Room name changed to: %1$s by %2$s</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