Unverified Commit 823c6125 authored by Rafael Kellermann Streit's avatar Rafael Kellermann Streit Committed by GitHub

Merge branch 'beta' into release/3.0.1-hotfix

parents 847036a7 041a0f0d
...@@ -8,6 +8,7 @@ import android.view.View ...@@ -8,6 +8,7 @@ import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.core.view.ViewCompat import androidx.core.view.ViewCompat
import androidx.core.view.isVisible
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import chat.rocket.android.R import chat.rocket.android.R
import chat.rocket.android.analytics.AnalyticsManager import chat.rocket.android.analytics.AnalyticsManager
...@@ -16,7 +17,6 @@ import chat.rocket.android.authentication.registerusername.presentation.Register ...@@ -16,7 +17,6 @@ import chat.rocket.android.authentication.registerusername.presentation.Register
import chat.rocket.android.authentication.registerusername.presentation.RegisterUsernameView import chat.rocket.android.authentication.registerusername.presentation.RegisterUsernameView
import chat.rocket.android.util.extension.asObservable import chat.rocket.android.util.extension.asObservable
import chat.rocket.android.util.extensions.inflate import chat.rocket.android.util.extensions.inflate
import chat.rocket.android.util.extensions.setVisible
import chat.rocket.android.util.extensions.showKeyboard import chat.rocket.android.util.extensions.showKeyboard
import chat.rocket.android.util.extensions.showToast import chat.rocket.android.util.extensions.showToast
import chat.rocket.android.util.extensions.textContent import chat.rocket.android.util.extensions.textContent
...@@ -113,13 +113,13 @@ class RegisterUsernameFragment : Fragment(), RegisterUsernameView { ...@@ -113,13 +113,13 @@ class RegisterUsernameFragment : Fragment(), RegisterUsernameView {
override fun showLoading() { override fun showLoading() {
ui { ui {
disableUserInput() disableUserInput()
view_loading.setVisible(true) view_loading.isVisible = true
} }
} }
override fun hideLoading() { override fun hideLoading() {
ui { ui {
view_loading.setVisible(false) view_loading.isVisible = false
enableUserInput() enableUserInput()
} }
} }
......
...@@ -6,6 +6,7 @@ import android.view.View ...@@ -6,6 +6,7 @@ import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.core.view.ViewCompat import androidx.core.view.ViewCompat
import androidx.core.view.isVisible
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import chat.rocket.android.R import chat.rocket.android.R
import chat.rocket.android.analytics.AnalyticsManager import chat.rocket.android.analytics.AnalyticsManager
...@@ -15,7 +16,6 @@ import chat.rocket.android.authentication.resetpassword.presentation.ResetPasswo ...@@ -15,7 +16,6 @@ import chat.rocket.android.authentication.resetpassword.presentation.ResetPasswo
import chat.rocket.android.util.extension.asObservable import chat.rocket.android.util.extension.asObservable
import chat.rocket.android.util.extensions.inflate import chat.rocket.android.util.extensions.inflate
import chat.rocket.android.util.extensions.isEmail import chat.rocket.android.util.extensions.isEmail
import chat.rocket.android.util.extensions.setVisible
import chat.rocket.android.util.extensions.showKeyboard import chat.rocket.android.util.extensions.showKeyboard
import chat.rocket.android.util.extensions.showToast import chat.rocket.android.util.extensions.showToast
import chat.rocket.android.util.extensions.textContent import chat.rocket.android.util.extensions.textContent
...@@ -93,13 +93,13 @@ class ResetPasswordFragment : Fragment(), ResetPasswordView { ...@@ -93,13 +93,13 @@ class ResetPasswordFragment : Fragment(), ResetPasswordView {
override fun showLoading() { override fun showLoading() {
ui { ui {
disableUserInput() disableUserInput()
view_loading.setVisible(true) view_loading.isVisible = true
} }
} }
override fun hideLoading() { override fun hideLoading() {
ui { ui {
view_loading.setVisible(false) view_loading.isVisible = false
enableUserInput() enableUserInput()
} }
} }
......
...@@ -4,6 +4,7 @@ import android.os.Bundle ...@@ -4,6 +4,7 @@ import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.core.view.isVisible
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.DefaultItemAnimator import androidx.recyclerview.widget.DefaultItemAnimator
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
...@@ -15,7 +16,6 @@ import chat.rocket.android.chatinformation.adapter.ReadReceiptAdapter ...@@ -15,7 +16,6 @@ import chat.rocket.android.chatinformation.adapter.ReadReceiptAdapter
import chat.rocket.android.chatinformation.presentation.MessageInfoPresenter import chat.rocket.android.chatinformation.presentation.MessageInfoPresenter
import chat.rocket.android.chatinformation.presentation.MessageInfoView import chat.rocket.android.chatinformation.presentation.MessageInfoView
import chat.rocket.android.chatinformation.viewmodel.ReadReceiptViewModel import chat.rocket.android.chatinformation.viewmodel.ReadReceiptViewModel
import chat.rocket.android.util.extensions.setVisible
import chat.rocket.android.util.extensions.showToast import chat.rocket.android.util.extensions.showToast
import chat.rocket.android.util.extensions.ui import chat.rocket.android.util.extensions.ui
import dagger.android.support.AndroidSupportInjection import dagger.android.support.AndroidSupportInjection
...@@ -86,15 +86,15 @@ class MessageInfoFragment : Fragment(), MessageInfoView { ...@@ -86,15 +86,15 @@ class MessageInfoFragment : Fragment(), MessageInfoView {
override fun showLoading() { override fun showLoading() {
ui { ui {
view_loading.setVisible(true) view_loading.isVisible = true
view_loading.show() view_loading.show()
} }
} }
override fun hideLoading() { override fun hideLoading() {
ui { ui {
view_loading.isVisible = false
view_loading.hide() view_loading.hide()
view_loading.setVisible(false)
} }
} }
...@@ -103,4 +103,4 @@ class MessageInfoFragment : Fragment(), MessageInfoView { ...@@ -103,4 +103,4 @@ class MessageInfoFragment : Fragment(), MessageInfoView {
adapter.addAll(messageReceipts) adapter.addAll(messageReceipts)
} }
} }
} }
\ No newline at end of file
...@@ -7,10 +7,10 @@ import android.view.View ...@@ -7,10 +7,10 @@ import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.ImageView import android.widget.ImageView
import android.widget.TextView import android.widget.TextView
import androidx.core.view.isVisible
import chat.rocket.android.R import chat.rocket.android.R
import chat.rocket.android.chatroom.adapter.PeopleSuggestionsAdapter.PeopleSuggestionViewHolder import chat.rocket.android.chatroom.adapter.PeopleSuggestionsAdapter.PeopleSuggestionViewHolder
import chat.rocket.android.chatroom.uimodel.suggestion.PeopleSuggestionUiModel import chat.rocket.android.chatroom.uimodel.suggestion.PeopleSuggestionUiModel
import chat.rocket.android.util.extensions.setVisible
import chat.rocket.android.suggestions.model.SuggestionModel import chat.rocket.android.suggestions.model.SuggestionModel
import chat.rocket.android.suggestions.ui.BaseSuggestionViewHolder import chat.rocket.android.suggestions.ui.BaseSuggestionViewHolder
import chat.rocket.android.suggestions.ui.SuggestionsAdapter import chat.rocket.android.suggestions.ui.SuggestionsAdapter
...@@ -58,9 +58,9 @@ class PeopleSuggestionsAdapter(context: Context) : SuggestionsAdapter<PeopleSugg ...@@ -58,9 +58,9 @@ class PeopleSuggestionsAdapter(context: Context) : SuggestionsAdapter<PeopleSugg
username.text = item.username username.text = item.username
name.text = item.name name.text = item.name
if (item.imageUri?.isEmpty() != false) { if (item.imageUri?.isEmpty() != false) {
avatar.setVisible(false) avatar.isVisible = false
} else { } else {
avatar.setVisible(true) avatar.isVisible = true
avatar.setImageURI(item.imageUri) avatar.setImageURI(item.imageUri)
} }
val status = item.status val status = item.status
...@@ -68,7 +68,7 @@ class PeopleSuggestionsAdapter(context: Context) : SuggestionsAdapter<PeopleSugg ...@@ -68,7 +68,7 @@ class PeopleSuggestionsAdapter(context: Context) : SuggestionsAdapter<PeopleSugg
val statusDrawable = DrawableHelper.getUserStatusDrawable(status, itemView.context) val statusDrawable = DrawableHelper.getUserStatusDrawable(status, itemView.context)
statusView.setImageDrawable(statusDrawable) statusView.setImageDrawable(statusDrawable)
} else { } else {
statusView.setVisible(false) statusView.isVisible = false
} }
setOnClickListener { setOnClickListener {
itemClickListener?.onClick(item) itemClickListener?.onClick(item)
......
...@@ -266,16 +266,16 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR ...@@ -266,16 +266,16 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
override fun onPause() { override fun onPause() {
super.onPause() super.onPause()
setReactionButtonIcon(R.drawable.ic_reaction_24dp)
dismissEmojiKeyboard() dismissEmojiKeyboard()
activity?.invalidateOptionsMenu() activity?.invalidateOptionsMenu()
} }
private fun dismissEmojiKeyboard() { fun dismissEmojiKeyboard() {
// Check if the keyboard was ever initialized. // Check if the keyboard was ever initialized.
// It may be the case when you are looking a not joined room // It may be the case when you are looking a not joined room
if (::emojiKeyboardPopup.isInitialized) { if (::emojiKeyboardPopup.isInitialized) {
emojiKeyboardPopup.dismiss() emojiKeyboardPopup.dismiss()
setReactionButtonIcon(R.drawable.ic_reaction_24dp)
} }
} }
...@@ -784,8 +784,7 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR ...@@ -784,8 +784,7 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
context: Context context: Context
) { ) {
if (f is MessageActionsBottomSheet) { if (f is MessageActionsBottomSheet) {
setReactionButtonIcon(R.drawable.ic_reaction_24dp) dismissEmojiKeyboard()
emojiKeyboardPopup.dismiss()
} }
} }
}, },
...@@ -805,9 +804,8 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR ...@@ -805,9 +804,8 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
it.onBackPressed() it.onBackPressed()
} }
KeyboardHelper.hideSoftKeyboard(it) KeyboardHelper.hideSoftKeyboard(it)
emojiKeyboardPopup.dismiss() dismissEmojiKeyboard()
} }
setReactionButtonIcon(R.drawable.ic_reaction_24dp)
} }
} }
...@@ -917,8 +915,7 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR ...@@ -917,8 +915,7 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
setReactionButtonIcon(R.drawable.ic_keyboard_black_24dp) setReactionButtonIcon(R.drawable.ic_keyboard_black_24dp)
} else { } else {
// If popup is showing, simply dismiss it to show the underlying text keyboard // If popup is showing, simply dismiss it to show the underlying text keyboard
emojiKeyboardPopup.dismiss() dismissEmojiKeyboard()
setReactionButtonIcon(R.drawable.ic_reaction_24dp)
} }
} }
......
...@@ -7,6 +7,7 @@ import androidx.core.view.isVisible ...@@ -7,6 +7,7 @@ import androidx.core.view.isVisible
import chat.rocket.android.emoji.internal.GlideApp import chat.rocket.android.emoji.internal.GlideApp
import chat.rocket.android.util.extensions.getFileName import chat.rocket.android.util.extensions.getFileName
import chat.rocket.android.util.extensions.getMimeType import chat.rocket.android.util.extensions.getMimeType
import com.bumptech.glide.load.resource.gif.GifDrawable
import com.bumptech.glide.request.target.SimpleTarget import com.bumptech.glide.request.target.SimpleTarget
import com.bumptech.glide.request.transition.Transition import com.bumptech.glide.request.transition.Transition
...@@ -21,22 +22,32 @@ fun ChatRoomFragment.showFileAttachmentDialog(uri: Uri) { ...@@ -21,22 +22,32 @@ fun ChatRoomFragment.showFileAttachmentDialog(uri: Uri) {
description.text.clear() description.text.clear()
when { when {
mimeType.startsWith("image") -> { mimeType.startsWith("image") -> {
GlideApp if (mimeType.contains("gif")) {
.with(context) GlideApp
.asBitmap() .with(context)
.load(uri) .asGif()
.override(imagePreview.width, imagePreview.height) .load(uri)
.fitCenter() .override(imagePreview.width, imagePreview.height)
.into(object : SimpleTarget<Bitmap>() { .fitCenter()
override fun onResourceReady( .into(imagePreview)
resource: Bitmap, } else {
transition: Transition<in Bitmap>? GlideApp
) { .with(context)
bitmap = resource .asBitmap()
imagePreview.setImageBitmap(resource) .load(uri)
imagePreview.isVisible = true .override(imagePreview.width, imagePreview.height)
} .fitCenter()
}) .into(object : SimpleTarget<Bitmap>() {
override fun onResourceReady(
resource: Bitmap,
transition: Transition<in Bitmap>?
) {
bitmap = resource
imagePreview.setImageBitmap(resource)
}
})
}
imagePreview.isVisible = true
} }
mimeType.startsWith("video") -> audioVideoAttachment.isVisible = true mimeType.startsWith("video") -> audioVideoAttachment.isVisible = true
else -> { else -> {
......
...@@ -79,6 +79,17 @@ private fun ChatRoomFragment.setupSearchMessageMenuItem(menu: Menu, context: Con ...@@ -79,6 +79,17 @@ private fun ChatRoomFragment.setupSearchMessageMenuItem(menu: Menu, context: Con
.setShowAsActionFlags( .setShowAsActionFlags(
MenuItem.SHOW_AS_ACTION_IF_ROOM or MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW MenuItem.SHOW_AS_ACTION_IF_ROOM or MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW
) )
.setOnActionExpandListener(object : MenuItem.OnActionExpandListener {
override fun onMenuItemActionExpand(item: MenuItem?): Boolean {
dismissEmojiKeyboard()
return true
}
override fun onMenuItemActionCollapse(item: MenuItem?): Boolean {
dismissEmojiKeyboard()
return true
}
})
(searchItem?.actionView as? SearchView)?.let { (searchItem?.actionView as? SearchView)?.let {
// TODO: Check why we need to stylize the search text programmatically instead of by defining it in the styles.xml (ChatRoom.SearchView) // TODO: Check why we need to stylize the search text programmatically instead of by defining it in the styles.xml (ChatRoom.SearchView)
......
...@@ -42,27 +42,28 @@ class RoomUiModelMapper( ...@@ -42,27 +42,28 @@ class RoomUiModelMapper(
userInteractor.get() userInteractor.get()
} }
fun map(rooms: List<ChatRoom>, grouped: Boolean = false): List<ItemHolder<*>> { fun map(rooms: List<ChatRoom>, grouped: Boolean = false, showLastMessage: Boolean = true): List<ItemHolder<*>> {
val list = ArrayList<ItemHolder<*>>(rooms.size + 4) val list = ArrayList<ItemHolder<*>>(rooms.size + 4)
var lastType: String? = null var lastType: String? = null
rooms.forEach { room -> rooms.forEach { room ->
if (grouped && lastType != room.chatRoom.type) { if (grouped && lastType != room.chatRoom.type) {
list.add(HeaderItemHolder(roomType(room.chatRoom.type))) list.add(HeaderItemHolder(roomType(room.chatRoom.type)))
} }
list.add(RoomItemHolder(map(room))) list.add(RoomItemHolder(map(room, showLastMessage)))
lastType = room.chatRoom.type lastType = room.chatRoom.type
} }
return list return list
} }
fun map(spotlight: SpotlightResult): List<ItemHolder<*>> { fun map(spotlight: SpotlightResult, showLastMessage: Boolean = true): List<ItemHolder<*>> {
val list = ArrayList<ItemHolder<*>>(spotlight.users.size + spotlight.rooms.size) val list = ArrayList<ItemHolder<*>>(spotlight.users.size + spotlight.rooms.size)
spotlight.users.filterNot { it.username.isNullOrEmpty() }.forEach { user -> spotlight.users.filterNot { it.username.isNullOrEmpty() }.forEach { user ->
list.add(RoomItemHolder(mapUser(user))) list.add(RoomItemHolder(mapUser(user)))
} }
spotlight.rooms.filterNot { it.name.isNullOrEmpty() }.forEach { room -> spotlight.rooms.filterNot { it.name.isNullOrEmpty() }.forEach { room ->
list.add(RoomItemHolder(mapRoom(room))) list.add(RoomItemHolder(mapRoom(room, showLastMessage)))
} }
return list return list
...@@ -86,21 +87,21 @@ class RoomUiModelMapper( ...@@ -86,21 +87,21 @@ class RoomUiModelMapper(
} }
} }
private fun mapRoom(room: Room): RoomUiModel { private fun mapRoom(room: Room, showLastMessage:Boolean = true): RoomUiModel {
return with(room) { return with(room) {
RoomUiModel( RoomUiModel(
id = id, id = id,
name = name!!, name = name!!,
type = type, type = type,
avatar = serverUrl.avatarUrl(name!!, isGroupOrChannel = true), avatar = serverUrl.avatarUrl(name!!, isGroupOrChannel = true),
lastMessage = mapLastMessage(lastMessage?.sender?.id, lastMessage?.sender?.username, lastMessage = if(showLastMessage) { mapLastMessage(lastMessage?.sender?.id, lastMessage?.sender?.username,
lastMessage?.sender?.name, lastMessage?.message, lastMessage?.sender?.name, lastMessage?.message,
isDirectMessage = type is RoomType.DirectMessage) isDirectMessage = type is RoomType.DirectMessage)} else { null }
) )
} }
} }
fun map(chatRoom: ChatRoom): RoomUiModel { fun map(chatRoom: ChatRoom, showLastMessage:Boolean = true): RoomUiModel {
return with(chatRoom.chatRoom) { return with(chatRoom.chatRoom) {
val isUnread = alert || unread > 0 val isUnread = alert || unread > 0
val type = roomTypeOf(type) val type = roomTypeOf(type)
...@@ -113,9 +114,9 @@ class RoomUiModelMapper( ...@@ -113,9 +114,9 @@ class RoomUiModelMapper(
serverUrl.avatarUrl(name, isGroupOrChannel = true) serverUrl.avatarUrl(name, isGroupOrChannel = true)
} }
val unread = mapUnread(unread) val unread = mapUnread(unread)
val lastMessage = mapLastMessage(lastMessageUserId, chatRoom.lastMessageUserName, val lastMessage = if(showLastMessage) { mapLastMessage(lastMessageUserId, chatRoom.lastMessageUserName,
chatRoom.lastMessageUserFullName, lastMessageText, isUnread, chatRoom.lastMessageUserFullName, lastMessageText, isUnread,
type is RoomType.DirectMessage) type is RoomType.DirectMessage) } else { null }
val open = open val open = open
RoomUiModel( RoomUiModel(
...@@ -148,6 +149,7 @@ class RoomUiModelMapper( ...@@ -148,6 +149,7 @@ class RoomUiModelMapper(
private fun mapLastMessage(userId: String?, name: String?, fullName: String?, text: String?, private fun mapLastMessage(userId: String?, name: String?, fullName: String?, text: String?,
unread: Boolean = false, unread: Boolean = false,
isDirectMessage: Boolean = false): CharSequence? { isDirectMessage: Boolean = false): CharSequence? {
return if (!settings.showLastMessage()) { return if (!settings.showLastMessage()) {
null null
} else if (name != null && text != null) { } else if (name != null && text != null) {
......
...@@ -12,6 +12,7 @@ import android.view.View ...@@ -12,6 +12,7 @@ import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.ImageView import android.widget.ImageView
import android.widget.TextView import android.widget.TextView
import androidx.core.view.isVisible
import chat.rocket.android.R import chat.rocket.android.R
import chat.rocket.android.infrastructure.LocalRepository import chat.rocket.android.infrastructure.LocalRepository
import chat.rocket.android.infrastructure.checkIfMyself import chat.rocket.android.infrastructure.checkIfMyself
...@@ -53,13 +54,13 @@ class ChatRoomsAdapter( ...@@ -53,13 +54,13 @@ class ChatRoomsAdapter(
bindName(chatRoom, text_chat_name) bindName(chatRoom, text_chat_name)
bindIcon(chatRoom, image_chat_icon) bindIcon(chatRoom, image_chat_icon)
if (settings.showLastMessage()) { if (settings.showLastMessage()) {
text_last_message.setVisible(true) text_last_message.isVisible = true
text_last_message_date_time.setVisible(true) text_last_message_date_time.isVisible = true
bindLastMessageDateTime(chatRoom, text_last_message_date_time) bindLastMessageDateTime(chatRoom, text_last_message_date_time)
bindLastMessage(chatRoom, text_last_message) bindLastMessage(chatRoom, text_last_message)
} else { } else {
text_last_message.setVisible(false) text_last_message.isVisible = false
text_last_message_date_time.setVisible(false) text_last_message_date_time.isVisible = false
} }
bindUnreadMessages(chatRoom, text_total_unread_messages) bindUnreadMessages(chatRoom, text_total_unread_messages)
...@@ -178,13 +179,13 @@ class ChatRoomsAdapter( ...@@ -178,13 +179,13 @@ class ChatRoomsAdapter(
when { when {
totalUnreadMessage in 1..99 -> { totalUnreadMessage in 1..99 -> {
textView.textContent = totalUnreadMessage.toString() textView.textContent = totalUnreadMessage.toString()
textView.setVisible(true) textView.isVisible = true
} }
totalUnreadMessage > 99 -> { totalUnreadMessage > 99 -> {
textView.textContent = context.getString(R.string.msg_more_than_ninety_nine_unread_messages) textView.textContent = context.getString(R.string.msg_more_than_ninety_nine_unread_messages)
textView.setVisible(true) textView.isVisible = true
} }
else -> textView.setVisible(false) else -> textView.isVisible = false
} }
} }
} }
......
...@@ -178,11 +178,14 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView { ...@@ -178,11 +178,14 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView {
override fun onMenuItemActionCollapse(item: MenuItem): Boolean { override fun onMenuItemActionCollapse(item: MenuItem): Boolean {
// Simply setting sortView to visible won't work, so we invalidate the options // Simply setting sortView to visible won't work, so we invalidate the options
// to recreate the entire menu... // to recreate the entire menu...
viewModel.showLastMessage = true
activity?.invalidateOptionsMenu() activity?.invalidateOptionsMenu()
queryChatRoomsByName(null)
return true return true
} }
override fun onMenuItemActionExpand(item: MenuItem): Boolean { override fun onMenuItemActionExpand(item: MenuItem): Boolean {
viewModel.showLastMessage = false
sortView?.isVisible = false sortView?.isVisible = false
return true return true
} }
......
...@@ -30,6 +30,7 @@ import timber.log.Timber ...@@ -30,6 +30,7 @@ import timber.log.Timber
import java.security.InvalidParameterException import java.security.InvalidParameterException
import kotlin.coroutines.experimental.coroutineContext import kotlin.coroutines.experimental.coroutineContext
class ChatRoomsViewModel( class ChatRoomsViewModel(
private val connectionManager: ConnectionManager, private val connectionManager: ConnectionManager,
private val interactor: FetchChatRoomsInteractor, private val interactor: FetchChatRoomsInteractor,
...@@ -41,9 +42,11 @@ class ChatRoomsViewModel( ...@@ -41,9 +42,11 @@ class ChatRoomsViewModel(
private val runContext = newSingleThreadContext("chat-rooms-view-model") private val runContext = newSingleThreadContext("chat-rooms-view-model")
private val client = connectionManager.client private val client = connectionManager.client
private var loaded = false private var loaded = false
var showLastMessage = true
fun getChatRooms(): LiveData<RoomsModel> { fun getChatRooms(): LiveData<RoomsModel> {
return Transformations.switchMap(query) { query -> return Transformations.switchMap(query) { query ->
return@switchMap if (query.isSearch()) { return@switchMap if (query.isSearch()) {
this@ChatRoomsViewModel.query.wrap(runContext) { _, data: MutableLiveData<RoomsModel> -> this@ChatRoomsViewModel.query.wrap(runContext) { _, data: MutableLiveData<RoomsModel> ->
val string = (query as Query.Search).query val string = (query as Query.Search).query
...@@ -53,11 +56,13 @@ class ChatRoomsViewModel( ...@@ -53,11 +56,13 @@ class ChatRoomsViewModel(
// TODO - find a better way for cancellation checking // TODO - find a better way for cancellation checking
if (!coroutineContext.isActive) return@wrap if (!coroutineContext.isActive) return@wrap
val rooms = repository.search(string).let { mapper.map(it) } val rooms = repository.search(string).let { mapper.map(it, showLastMessage = this.showLastMessage) }
data.postValue(rooms.toMutableList() + LoadingItemHolder()) data.postValue(rooms.toMutableList() + LoadingItemHolder())
if (!coroutineContext.isActive) return@wrap if (!coroutineContext.isActive) return@wrap
val spotlight = spotlight(query.query)?.let { mapper.map(it) } val spotlight = spotlight(query.query)?.let { mapper.map(it, showLastMessage = this.showLastMessage) }
if (!coroutineContext.isActive) return@wrap if (!coroutineContext.isActive) return@wrap
spotlight?.let { spotlight?.let {
...@@ -72,7 +77,7 @@ class ChatRoomsViewModel( ...@@ -72,7 +77,7 @@ class ChatRoomsViewModel(
.distinct() .distinct()
.transform(runContext) { rooms -> .transform(runContext) { rooms ->
val mappedRooms = rooms?.let { val mappedRooms = rooms?.let {
mapper.map(rooms, query.isGrouped()) mapper.map(rooms, query.isGrouped(), this.showLastMessage)
} }
if (loaded && mappedRooms?.isEmpty() == true) { if (loaded && mappedRooms?.isEmpty() == true) {
loadingState.postValue(LoadingState.Loaded(0)) loadingState.postValue(LoadingState.Loaded(0))
......
...@@ -13,7 +13,6 @@ import android.text.style.ReplacementSpan ...@@ -13,7 +13,6 @@ import android.text.style.ReplacementSpan
import android.view.View import android.view.View
import androidx.core.content.res.ResourcesCompat import androidx.core.content.res.ResourcesCompat
import androidx.core.util.PatternsCompat import androidx.core.util.PatternsCompat
import chat.rocket.android.R
import chat.rocket.android.chatroom.ui.StrikethroughDelimiterProcessor import chat.rocket.android.chatroom.ui.StrikethroughDelimiterProcessor
import chat.rocket.android.emoji.EmojiParser import chat.rocket.android.emoji.EmojiParser
import chat.rocket.android.emoji.EmojiRepository import chat.rocket.android.emoji.EmojiRepository
...@@ -32,6 +31,7 @@ import org.commonmark.node.Emphasis ...@@ -32,6 +31,7 @@ import org.commonmark.node.Emphasis
import org.commonmark.node.ListItem import org.commonmark.node.ListItem
import org.commonmark.node.Node import org.commonmark.node.Node
import org.commonmark.node.OrderedList import org.commonmark.node.OrderedList
import org.commonmark.node.SoftLineBreak
import org.commonmark.node.StrongEmphasis import org.commonmark.node.StrongEmphasis
import org.commonmark.parser.Parser import org.commonmark.parser.Parser
import ru.noties.markwon.SpannableBuilder import ru.noties.markwon.SpannableBuilder
...@@ -219,6 +219,11 @@ class MessageParser @Inject constructor( ...@@ -219,6 +219,11 @@ class MessageParser @Inject constructor(
builder.append('\n') builder.append('\n')
} }
} }
override fun visit(softLineBreak: SoftLineBreak) {
super.visit(softLineBreak)
builder.append("\n")
}
} }
class LinkVisitor(private val builder: SpannableBuilder) : AbstractVisitor() { class LinkVisitor(private val builder: SpannableBuilder) : AbstractVisitor() {
......
...@@ -43,6 +43,7 @@ class MembersAdapter(private val listener: (MemberUiModel) -> Unit) : ...@@ -43,6 +43,7 @@ class MembersAdapter(private val listener: (MemberUiModel) -> Unit) :
fun bind(memberUiModel: MemberUiModel, listener: (MemberUiModel) -> Unit) = with(itemView) { fun bind(memberUiModel: MemberUiModel, listener: (MemberUiModel) -> Unit) = with(itemView) {
image_avatar.setImageURI(memberUiModel.avatarUri) image_avatar.setImageURI(memberUiModel.avatarUri)
text_member.content = memberUiModel.displayName text_member.content = memberUiModel.displayName
text_member.setCompoundDrawablesRelativeWithIntrinsicBounds(DrawableHelper.getUserStatusDrawable(memberUiModel.status, context), null, null, null)
setOnClickListener { listener(memberUiModel) } setOnClickListener { listener(memberUiModel) }
} }
} }
......
...@@ -3,6 +3,7 @@ package chat.rocket.android.members.uimodel ...@@ -3,6 +3,7 @@ package chat.rocket.android.members.uimodel
import chat.rocket.android.server.domain.useRealName import chat.rocket.android.server.domain.useRealName
import chat.rocket.android.util.extensions.avatarUrl import chat.rocket.android.util.extensions.avatarUrl
import chat.rocket.common.model.User import chat.rocket.common.model.User
import chat.rocket.common.model.UserStatus
import chat.rocket.core.model.Value import chat.rocket.core.model.Value
class MemberUiModel( class MemberUiModel(
...@@ -16,6 +17,7 @@ class MemberUiModel( ...@@ -16,6 +17,7 @@ class MemberUiModel(
val username: String? val username: String?
val email: String? val email: String?
val utcOffset: Float? val utcOffset: Float?
val status: UserStatus?
init { init {
avatarUri = getUserAvatar() avatarUri = getUserAvatar()
...@@ -24,6 +26,7 @@ class MemberUiModel( ...@@ -24,6 +26,7 @@ class MemberUiModel(
username = getUserUsername() username = getUserUsername()
email = getUserEmail() email = getUserEmail()
utcOffset = getUserUtcOffset() utcOffset = getUserUtcOffset()
status = getUserStatus()
} }
private fun getUserAvatar(): String? { private fun getUserAvatar(): String? {
...@@ -47,4 +50,6 @@ class MemberUiModel( ...@@ -47,4 +50,6 @@ class MemberUiModel(
private fun getUserEmail(): String? = member.emails?.get(0)?.address private fun getUserEmail(): String? = member.emails?.get(0)?.address
private fun getUserUtcOffset(): Float? = member.utcOffset private fun getUserUtcOffset(): Float? = member.utcOffset
private fun getUserStatus(): UserStatus? = member.status
} }
\ No newline at end of file
...@@ -37,19 +37,6 @@ fun FragmentActivity.clearLightStatusBar() { ...@@ -37,19 +37,6 @@ fun FragmentActivity.clearLightStatusBar() {
} }
} }
// TODO: Remove. Use KTX instead.
fun View.setVisible(visible: Boolean) {
visibility = if (visible) {
View.VISIBLE
} else {
View.GONE
}
}
fun View.isVisible(): Boolean {
return visibility == View.VISIBLE
}
fun ViewGroup.inflate(@LayoutRes resource: Int, attachToRoot: Boolean = false): View = fun ViewGroup.inflate(@LayoutRes resource: Int, attachToRoot: Boolean = false): View =
LayoutInflater.from(context).inflate(resource, this, attachToRoot) LayoutInflater.from(context).inflate(resource, this, attachToRoot)
......
<vector xmlns:android="http://schemas.android.com/apk/res/android" <vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="108dp" android:width="108dp"
android:height="108dp" android:height="108dp"
android:viewportHeight="1055.0303" android:viewportWidth="247.7922"
android:viewportWidth="1055.0303"> android:viewportHeight="247.7922">
<group <group
android:translateX="281.28394" android:translateX="69.8961"
android:translateY="271.51514"> android:translateY="69.8961">
<path <path
android:fillColor="#FFDB2323" android:fillType="evenOdd"
android:pathData="M491.3,255.3c0,-24.1 -7.2,-47.2 -21.4,-68.7c-12.8,-19.3 -30.7,-36.4 -53.2,-50.7c-43.5,-27.8 -100.6,-43.1 -160.9,-43.1c-20.1,0 -40,1.7 -59.2,5.1c-11.9,-11.2 -25.9,-21.2 -40.7,-29.2c-79,-38.3 -144.6,-0.9 -144.6,-0.9s60.9,50.1 51,93.9c-27.3,27 -42,59.6 -42,93.6c0,0.1 0,0.2 0,0.3c0,0.1 0,0.2 0,0.3c0,33.9 14.8,66.6 42,93.6c9.9,43.9 -51,93.9 -51,93.9s65.5,37.4 144.6,-0.9c14.8,-8 28.8,-18 40.7,-29.2c19.2,3.4 39.1,5.1 59.2,5.1c60.3,0 117.4,-15.3 160.9,-43.1c22.5,-14.4 40.4,-31.5 53.2,-50.7c14.2,-21.5 21.4,-44.6 21.4,-68.7c0,-0.1 0,-0.2 0,-0.3C491.3,255.6 491.3,255.4 491.3,255.3z" /> android:pathData="M93.921,43.28L93.922,43.283C93.922,43.282 93.922,43.282 93.922,43.282C93.922,43.281 93.921,43.281 93.921,43.28ZM32.924,10.95C36.19,12.769 39.278,15.071 41.914,17.629C46.165,16.857 50.547,16.468 54.993,16.468C68.302,16.468 80.921,19.969 90.522,26.325C95.494,29.618 99.445,33.525 102.266,37.939C105.408,42.857 107,48.145 107,53.812C107,59.327 105.408,64.618 102.266,69.535C99.445,73.951 95.494,77.856 90.522,81.149C80.921,87.505 68.303,91.004 54.993,91.004C50.547,91.004 46.166,90.615 41.914,89.844C39.277,92.401 36.19,94.704 32.924,96.523C15.472,105.288 1,96.729 1,96.729C1,96.729 14.455,85.274 12.267,75.231C6.247,69.043 2.985,61.58 2.985,53.662C2.985,45.893 6.248,38.43 12.267,32.241C14.455,22.201 1.004,10.748 1,10.744C1.004,10.741 15.475,2.186 32.924,10.95Z"
android:strokeWidth="1"
android:strokeColor="#00000000">
<aapt:attr name="android:fillColor">
<gradient
android:endX="54"
android:endY="89.495674"
android:startX="54"
android:startY="-4.593772"
android:type="linear">
<item
android:color="#FFDB2323"
android:offset="0" />
<item
android:color="#FFDB2323"
android:offset="1" />
</gradient>
</aapt:attr>
</path>
<path <path
android:fillColor="#FFFFFF" android:fillColor="#FFFFFF"
android:pathData="M255.9,124.2c113.9,0 206.3,59 206.3,131.8c0,72.8 -92.4,131.8 -206.3,131.8c-25.4,0 -49.7,-2.9 -72.1,-8.3c-22.8,27.4 -73,65.6 -121.7,53.3c15.9,-17 39.4,-45.8 34.3,-93.2c-29.2,-22.7 -46.8,-51.8 -46.8,-83.5C49.6,183.2 142,124.2 255.9,124.2" /> android:fillType="nonZero"
android:pathData="M22.066,71.46C16.128,66.689 12.564,60.582 12.564,53.926C12.564,38.654 31.331,26.273 54.482,26.273C77.633,26.273 96.4,38.654 96.4,53.926C96.4,69.199 77.633,81.58 54.482,81.58C48.776,81.58 43.337,80.828 38.379,79.466L34.754,83.031C32.785,84.968 30.476,86.721 28.07,88.102C24.881,89.699 21.731,90.57 18.615,90.836C18.791,90.51 18.953,90.18 19.127,89.854C22.758,83.031 23.738,76.9 22.066,71.46Z"
android:strokeWidth="1"
android:strokeColor="#00000000" />
<path <path
android:fillColor="#FFDB2323" android:fillType="nonZero"
android:pathData="M255.9,256m-27.4,0a27.4,27.4 0,1 1,54.8 0a27.4,27.4 0,1 1,-54.8 0" /> android:pathData="M35.209,53.736m-6.264,0a6.264,6.264 0,1 1,12.527 0a6.264,6.264 0,1 1,-12.527 0"
android:strokeWidth="1"
android:strokeColor="#00000000">
<aapt:attr name="android:fillColor">
<gradient
android:endX="35.2085"
android:endY="58.20792"
android:startX="35.2085"
android:startY="46.44125"
android:type="linear">
<item
android:color="#FFDB2323"
android:offset="0" />
<item
android:color="#FFDB2323"
android:offset="1" />
</gradient>
</aapt:attr>
</path>
<path <path
android:fillColor="#FFDB2323" android:fillType="nonZero"
android:pathData="M351.2,256m-27.4,0a27.4,27.4 0,1 1,54.8 0a27.4,27.4 0,1 1,-54.8 0" /> android:pathData="M54.482,53.736m-6.264,0a6.264,6.264 0,1 1,12.527 0a6.264,6.264 0,1 1,-12.527 0"
android:strokeWidth="1"
android:strokeColor="#00000000">
<aapt:attr name="android:fillColor">
<gradient
android:endX="54.4815"
android:endY="58.20792"
android:startX="54.4815"
android:startY="46.44125"
android:type="linear">
<item
android:color="#FFDB2323"
android:offset="0" />
<item
android:color="#FFDB2323"
android:offset="1" />
</gradient>
</aapt:attr>
</path>
<path <path
android:fillColor="#FFDB2323" android:fillType="nonZero"
android:pathData="M160.6,256m-27.4,0a27.4,27.4 0,1 1,54.8 0a27.4,27.4 0,1 1,-54.8 0" /> android:pathData="M75.682,53.736m-6.264,0a6.264,6.264 0,1 1,12.527 0a6.264,6.264 0,1 1,-12.527 0"
android:strokeWidth="1"
android:strokeColor="#00000000">
<aapt:attr name="android:fillColor">
<gradient
android:endX="75.6815"
android:endY="58.20792"
android:startX="75.6815"
android:startY="46.44125"
android:type="linear">
<item
android:color="#FFDB2323"
android:offset="0" />
<item
android:color="#FFDB2323"
android:offset="1" />
</gradient>
</aapt:attr>
</path>
</group> </group>
</vector> </vector>
\ No newline at end of file
...@@ -5,10 +5,10 @@ ...@@ -5,10 +5,10 @@
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:background="?android:attr/selectableItemBackground"
android:paddingBottom="@dimen/member_item_top_and_bottom_padding"
android:paddingEnd="@dimen/screen_edge_left_and_right_padding"
android:paddingStart="@dimen/screen_edge_left_and_right_padding" android:paddingStart="@dimen/screen_edge_left_and_right_padding"
android:paddingTop="@dimen/member_item_top_and_bottom_padding"> android:paddingTop="@dimen/member_item_top_and_bottom_padding"
android:paddingEnd="@dimen/screen_edge_left_and_right_padding"
android:paddingBottom="@dimen/member_item_top_and_bottom_padding">
<include <include
android:id="@+id/layout_avatar" android:id="@+id/layout_avatar"
...@@ -24,9 +24,11 @@ ...@@ -24,9 +24,11 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="16dp" android:layout_marginStart="16dp"
android:drawablePadding="@dimen/text_view_drawable_padding"
app:layout_constraintBottom_toBottomOf="@+id/layout_avatar" app:layout_constraintBottom_toBottomOf="@+id/layout_avatar"
app:layout_constraintLeft_toRightOf="@+id/layout_avatar" app:layout_constraintLeft_toRightOf="@+id/layout_avatar"
app:layout_constraintTop_toTopOf="@+id/layout_avatar" app:layout_constraintTop_toTopOf="@+id/layout_avatar"
tools:drawableStart="@drawable/ic_status_invisible_12dp"
tools:text="Ronald Perkins" /> tools:text="Ronald Perkins" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
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