Commit 4641c4ba authored by Filipe de Lima Brito's avatar Filipe de Lima Brito

Merge branch 'develop' into v3.0.0

parents edbf3109 f68e4a56
......@@ -12,7 +12,7 @@ android {
applicationId "chat.rocket.android"
minSdkVersion versions.minSdk
targetSdkVersion versions.targetSdk
versionCode 2032
versionCode 2034
versionName "2.5.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
multiDexEnabled true
......
......@@ -5,6 +5,7 @@ import androidx.lifecycle.LifecycleObserver
import androidx.lifecycle.OnLifecycleEvent
import chat.rocket.android.server.domain.GetAccountInteractor
import chat.rocket.android.server.domain.GetCurrentServerInteractor
import chat.rocket.android.server.infraestructure.ConnectionManagerFactory
import chat.rocket.android.server.infraestructure.RocketChatClientFactory
import chat.rocket.common.RocketChatException
import chat.rocket.common.model.UserStatus
......@@ -15,8 +16,7 @@ import javax.inject.Inject
class AppLifecycleObserver @Inject constructor(
private val serverInteractor: GetCurrentServerInteractor,
private val factory: RocketChatClientFactory,
private val getAccountInteractor: GetAccountInteractor
private val factory: ConnectionManagerFactory
) : LifecycleObserver {
@OnLifecycleEvent(Lifecycle.Event.ON_START)
......@@ -31,14 +31,8 @@ class AppLifecycleObserver @Inject constructor(
private fun changeTemporaryStatus(userStatus: UserStatus) {
launch {
val currentServer = serverInteractor.get()
val account = currentServer?.let { getAccountInteractor.get(currentServer) }
val client = account?.let { factory.create(currentServer) }
try {
client?.setTemporaryStatus(userStatus)
} catch (exception: RocketChatException) {
Timber.e(exception)
serverInteractor.get()?.let { currentServer ->
factory.create(currentServer).setTemporaryStatus(userStatus)
}
}
}
......
......@@ -44,39 +44,48 @@ object DateTimeHelper {
}
}
/**
fun getFormattedDateForMessages(localDateTime: LocalDateTime, context: Context): String {
val localDate = localDateTime.toLocalDate()
return when (localDate) {
today -> context.getString(R.string.msg_today)
yesterday -> context.getString(R.string.msg_yesterday)
else -> formatLocalDate(localDate)
}
}
/**
* Returns a time from a [LocalDateTime].
*
* @param localDateTime The [LocalDateTime].
* @return The time from a [LocalDateTime].
*/
fun getTime(localDateTime: LocalDateTime): String {
fun getTime(localDateTime: LocalDateTime): String {
val formatter = DateTimeFormatter.ofLocalizedTime(FormatStyle.SHORT)
return localDateTime.toLocalTime().format(formatter).toString()
}
}
/**
/**
* Returns a date time from a [LocalDateTime].
*
* @param localDateTime The [LocalDateTime].
* @return The time from a [LocalDateTime].
*/
fun getDateTime(localDateTime: LocalDateTime): String {
fun getDateTime(localDateTime: LocalDateTime): String {
return formatLocalDateTime(localDateTime)
}
}
private fun formatLocalDateTime(localDateTime: LocalDateTime): String {
private fun formatLocalDateTime(localDateTime: LocalDateTime): String {
val formatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT)
return localDateTime.format(formatter).toString()
}
}
private fun formatLocalDate(localDate: LocalDate): String {
val formatter = DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT)
private fun formatLocalDate(localDate: LocalDate): String {
val formatter = DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM)
return localDate.format(formatter).toString()
}
}
private fun formatLocalTime(localTime: LocalTime): String {
private fun formatLocalTime(localTime: LocalTime): String {
val formatter = DateTimeFormatter.ofLocalizedTime(FormatStyle.SHORT)
return localTime.format(formatter).toString()
}
}
}
\ No newline at end of file
......@@ -68,7 +68,7 @@ class MessageInfoFragment : Fragment(), MessageInfoView {
private fun setupRecyclerView() {
// Initialize the endlessRecyclerViewScrollListener so we don't NPE at onDestroyView
val linearLayoutManager = LinearLayoutManager(context, LinearLayoutManager.VERTICAL, true)
val linearLayoutManager = LinearLayoutManager(context, RecyclerView.VERTICAL, true)
adapter = ReadReceiptAdapter()
linearLayoutManager.stackFromEnd = true
receipt_list.layoutManager = linearLayoutManager
......
......@@ -26,20 +26,30 @@ class MessageViewHolder(
override fun bindViews(data: MessageUiModel) {
with(itemView) {
if (data.isFirstUnread) new_messages_notif.visibility = View.VISIBLE
else new_messages_notif.visibility = View.GONE
day_marker_layout.visibility = if (data.showDayMarker) {
day.text = data.currentDayMarkerText
View.VISIBLE
} else {
View.GONE
}
if (data.isFirstUnread) {
new_messages_notif.visibility = View.VISIBLE
} else {
new_messages_notif.visibility = View.GONE
}
text_message_time.text = data.time
text_sender.text = data.senderName
text_content.text = data.content
image_avatar.setImageURI(data.avatar)
text_content.setTextColor(
if (data.isTemporary) Color.GRAY else Color.BLACK
)
text_content.setTextColor(if (data.isTemporary) Color.GRAY else Color.BLACK)
data.message.let {
text_edit_indicator.isVisible = !it.isSystemMessage() && it.editedBy != null
image_star_indicator.isVisible = it.starred?.isNotEmpty() ?: false
}
if (data.unread == null) {
read_receipt_view.isVisible = false
} else {
......
......@@ -12,15 +12,14 @@ import android.text.SpannableStringBuilder
import android.view.KeyEvent
import android.view.LayoutInflater
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.Button
import android.widget.EditText
import android.widget.TextView
import android.widget.FrameLayout
import android.widget.ImageView
import android.widget.TextView
import androidx.annotation.DrawableRes
import androidx.core.text.bold
import androidx.core.view.isVisible
......@@ -53,9 +52,9 @@ import chat.rocket.android.emoji.EmojiParser
import chat.rocket.android.emoji.EmojiPickerPopup
import chat.rocket.android.emoji.EmojiReactionListener
import chat.rocket.android.helper.EndlessRecyclerViewScrollListener
import chat.rocket.android.helper.ImageHelper
import chat.rocket.android.helper.KeyboardHelper
import chat.rocket.android.helper.MessageParser
import chat.rocket.android.helper.ImageHelper
import chat.rocket.android.util.extension.asObservable
import chat.rocket.android.util.extensions.circularRevealOrUnreveal
import chat.rocket.android.util.extensions.fadeIn
......@@ -296,14 +295,30 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
adapter.clearData()
}
if (dataSet.isNotEmpty()) {
var prevMsgModel = dataSet[0]
// track the message sent immediately after the current message
var prevMessageUiModel: MessageUiModel? = null
// Checking for all messages to assign true to the required showDayMaker
// Loop over received messages to determine first unread
var firstUnread = false
for (i in dataSet.indices) {
val msgModel = dataSet[i]
if (msgModel is MessageUiModel) {
if (i > 0) {
prevMsgModel = dataSet[i - 1]
}
val currentDayMarkerText = msgModel.currentDayMarkerText
val previousDayMarkerText = prevMsgModel.currentDayMarkerText
println("$previousDayMarkerText then $currentDayMarkerText")
if (previousDayMarkerText != currentDayMarkerText) {
prevMsgModel.showDayMarker = true
}
if (!firstUnread && msgModel is MessageUiModel) {
val msg = msgModel.rawData
if (msg.timestamp < chatRoomLastSeen) {
// This message was sent before the last seen of the room. Hence, it was seen.
......@@ -311,11 +326,13 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
if (prevMessageUiModel != null) {
prevMessageUiModel.isFirstUnread = true
}
break
// Found first unread message.
firstUnread = true
}
prevMessageUiModel = msgModel
}
}
}
if (recycler_view.adapter == null) {
adapter = ChatRoomAdapter(
......@@ -428,7 +445,7 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
} else {
if (dy < 0 && !button_fab.isVisible) {
button_fab.show()
if (newMessageCount !=0) text_count.isVisible = true
if (newMessageCount != 0) text_count.isVisible = true
}
}
}
......@@ -493,8 +510,7 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
text_count.text = "99+"
text_count.isVisible = true
}
else if (!button_fab.isVisible)
} else if (!button_fab.isVisible)
recycler_view.scrollToPosition(0)
verticalScrollOffset.set(0)
empty_chat_view.isVisible = adapter.itemCount == 0
......
......@@ -14,20 +14,18 @@ import kotlinx.android.synthetic.main.message_bottomsheet.*
class MessageActionsBottomSheet : BottomSheetDialogFragment() {
private lateinit var adapter: MessageActionAdapter
private val adapter = MessageActionAdapter()
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
return inflater.inflate(R.layout.message_bottomsheet, container, false)
}
fun addItems(items: List<MenuItem>, itemClickListener: MenuItem.OnMenuItemClickListener) {
adapter = MessageActionAdapter()
adapter.addItems(items, ActionItemClickListener(dismissAction = { dismiss() },
itemClickListener = itemClickListener))
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
bottomsheet_recycler_view.layoutManager = LinearLayoutManager(context)
bottomsheet_recycler_view.adapter = adapter
}
......@@ -58,6 +56,7 @@ class MessageActionsBottomSheet : BottomSheetDialogFragment() {
this.itemClickListener = itemClickListener
menuItems.clear()
menuItems.addAll(items)
notifyDataSetChanged()
}
}
......
......@@ -16,7 +16,9 @@ data class AudioAttachmentUiModel(
override var preview: Message? = null,
override var isTemporary: Boolean = false,
override var unread: Boolean? = null,
override var menuItemsToHide: MutableList<Int> = mutableListOf()
override var menuItemsToHide: MutableList<Int> = mutableListOf(),
override var currentDayMarkerText: String,
override var showDayMarker: Boolean
) : BaseFileAttachmentUiModel<AudioAttachment> {
override val viewType: Int
get() = BaseUiModel.ViewType.AUDIO_ATTACHMENT.viewType
......
......@@ -18,7 +18,9 @@ data class AuthorAttachmentUiModel(
override var preview: Message? = null,
override var isTemporary: Boolean = false,
override var unread: Boolean? = null,
override var menuItemsToHide: MutableList<Int> = mutableListOf()
override var menuItemsToHide: MutableList<Int> = mutableListOf(),
override var currentDayMarkerText: String,
override var showDayMarker: Boolean
) : BaseAttachmentUiModel<AuthorAttachment> {
override val viewType: Int
get() = BaseUiModel.ViewType.AUTHOR_ATTACHMENT.viewType
......
......@@ -14,6 +14,8 @@ interface BaseUiModel<out T> {
var preview: Message?
var isTemporary: Boolean
var unread: Boolean?
var currentDayMarkerText: String
var showDayMarker: Boolean
var menuItemsToHide: MutableList<Int>
enum class ViewType(val viewType: Int) {
......
......@@ -17,7 +17,9 @@ data class ColorAttachmentUiModel(
override var preview: Message? = null,
override var isTemporary: Boolean = false,
override var unread: Boolean?,
override var menuItemsToHide: MutableList<Int> = mutableListOf()
override var menuItemsToHide: MutableList<Int> = mutableListOf(),
override var currentDayMarkerText: String,
override var showDayMarker: Boolean
) : BaseAttachmentUiModel<ColorAttachment> {
override val viewType: Int
get() = BaseUiModel.ViewType.COLOR_ATTACHMENT.viewType
......
......@@ -16,7 +16,9 @@ data class GenericFileAttachmentUiModel(
override var preview: Message? = null,
override var isTemporary: Boolean = false,
override var unread: Boolean? = null,
override var menuItemsToHide: MutableList<Int> = mutableListOf()
override var menuItemsToHide: MutableList<Int> = mutableListOf(),
override var currentDayMarkerText: String,
override var showDayMarker: Boolean
) : BaseFileAttachmentUiModel<GenericFileAttachment> {
override val viewType: Int
get() = BaseUiModel.ViewType.GENERIC_FILE_ATTACHMENT.viewType
......
......@@ -18,7 +18,9 @@ data class ImageAttachmentUiModel(
override var preview: Message? = null,
override var isTemporary: Boolean = false,
override var unread: Boolean? = null,
override var menuItemsToHide: MutableList<Int> = mutableListOf()
override var menuItemsToHide: MutableList<Int> = mutableListOf(),
override var currentDayMarkerText: String,
override var showDayMarker: Boolean
) : BaseFileAttachmentUiModel<ImageAttachment> {
override val viewType: Int
get() = BaseUiModel.ViewType.IMAGE_ATTACHMENT.viewType
......
......@@ -17,7 +17,9 @@ data class MessageAttachmentUiModel(
override var preview: Message? = null,
override var isTemporary: Boolean = false,
override var unread: Boolean? = null,
override var menuItemsToHide: MutableList<Int> = mutableListOf()
override var menuItemsToHide: MutableList<Int> = mutableListOf(),
override var currentDayMarkerText: String,
override var showDayMarker: Boolean
) : BaseUiModel<Message> {
override val viewType: Int
get() = BaseUiModel.ViewType.MESSAGE_ATTACHMENT.viewType
......
......@@ -13,7 +13,9 @@ data class MessageReplyUiModel(
override var isTemporary: Boolean = false,
override val message: Message,
override var unread: Boolean? = null,
override var menuItemsToHide: MutableList<Int> = mutableListOf()
override var menuItemsToHide: MutableList<Int> = mutableListOf(),
override var currentDayMarkerText: String,
override var showDayMarker: Boolean
) : BaseUiModel<MessageReply> {
override val viewType: Int
get() = BaseUiModel.ViewType.MESSAGE_REPLY.viewType
......
......@@ -12,6 +12,8 @@ data class MessageUiModel(
override val senderName: CharSequence,
override val content: CharSequence,
override val isPinned: Boolean,
override var currentDayMarkerText: String,
override var showDayMarker: Boolean,
override var reactions: List<ReactionUiModel>,
override var nextDownStreamMessage: BaseUiModel<*>? = null,
override var preview: Message? = null,
......
......@@ -265,6 +265,10 @@ class UiModelMapper @Inject constructor(
val roomName =
if (settings.useRealName() && name != null) name else message.sender?.username ?: ""
val permalink = messageHelper.createPermalink(message, chatRoom)
val localDateTime = DateTimeHelper.getLocalDateTime(message.timestamp)
val dayMarkerText = DateTimeHelper.getFormattedDateForMessages(localDateTime, context)
return MessageReplyUiModel(
messageId = message.id,
isTemporary = false,
......@@ -273,7 +277,9 @@ class UiModelMapper @Inject constructor(
preview = mapMessagePreview(message),
rawData = MessageReply(roomName = roomName, permalink = permalink),
nextDownStreamMessage = null,
unread = message.unread
unread = message.unread,
currentDayMarkerText = dayMarkerText,
showDayMarker = false
)
}
......@@ -285,8 +291,12 @@ class UiModelMapper @Inject constructor(
val title = url.meta?.title
val description = url.meta?.description
val localDateTime = DateTimeHelper.getLocalDateTime(message.timestamp)
val dayMarkerText = DateTimeHelper.getFormattedDateForMessages(localDateTime, context)
return UrlPreviewUiModel(message, url, message.id, title, hostname, description, thumb,
getReactions(message), preview = message.copy(message = url.url), unread = message.unread)
getReactions(message), preview = message.copy(message = url.url), unread = message.unread,
showDayMarker = false, currentDayMarkerText = dayMarkerText)
}
private fun mapAttachment(message: Message, attachment: Attachment): BaseUiModel<*>? {
......@@ -304,10 +314,14 @@ class UiModelMapper @Inject constructor(
val content = stripMessageQuotes(message)
val id = attachmentId(message, attachment)
val localDateTime = DateTimeHelper.getLocalDateTime(message.timestamp)
val dayMarkerText = DateTimeHelper.getFormattedDateForMessages(localDateTime, context)
ColorAttachmentUiModel(attachmentUrl = url, id = id, color = color.color,
text = text, message = message, rawData = attachment,
messageId = message.id, reactions = getReactions(message),
preview = message.copy(message = content.message), unread = message.unread)
preview = message.copy(message = content.message), unread = message.unread,
showDayMarker = false, currentDayMarkerText = dayMarkerText)
}
}
......@@ -332,10 +346,14 @@ class UiModelMapper @Inject constructor(
}
val id = attachmentId(message, attachment)
val localDateTime = DateTimeHelper.getLocalDateTime(message.timestamp)
val dayMarkerText = DateTimeHelper.getFormattedDateForMessages(localDateTime, context)
AuthorAttachmentUiModel(attachmentUrl = url, id = id, name = authorName,
icon = authorIcon, fields = fieldsText, message = message, rawData = attachment,
messageId = message.id, reactions = getReactions(message),
preview = message.copy(message = content.message), unread = message.unread)
preview = message.copy(message = content.message), unread = message.unread,
showDayMarker = false, currentDayMarkerText = dayMarkerText)
}
}
......@@ -349,11 +367,17 @@ class UiModelMapper @Inject constructor(
is GenericFileAttachment -> context.getString(R.string.msg_preview_file)
else -> attachment.text ?: ""
}
val localDateTime = DateTimeHelper.getLocalDateTime(message.timestamp)
val dayMarkerText = DateTimeHelper.getFormattedDateForMessages(localDateTime, context)
val content = stripMessageQuotes(message)
return MessageAttachmentUiModel(message = content, rawData = message,
messageId = message.id, time = time, senderName = attachmentAuthor,
content = attachmentText, isPinned = message.pinned, reactions = getReactions(message),
preview = message.copy(message = content.message), unread = message.unread)
preview = message.copy(message = content.message), unread = message.unread,
currentDayMarkerText = dayMarkerText, showDayMarker = false)
}
private fun mapFileAttachment(message: Message, attachment: FileAttachment): BaseUiModel<*>? {
......@@ -362,19 +386,27 @@ class UiModelMapper @Inject constructor(
val attachmentText = attachmentText(attachment)
val attachmentDescription = attachmentDescription(attachment)
val id = attachmentId(message, attachment)
val localDateTime = DateTimeHelper.getLocalDateTime(message.timestamp)
val dayMarkerText = DateTimeHelper.getFormattedDateForMessages(localDateTime, context)
return when (attachment) {
is ImageAttachment -> ImageAttachmentUiModel(message, attachment, message.id,
attachmentUrl, attachmentTitle, attachmentText, attachmentDescription, id, getReactions(message),
preview = message.copy(message = context.getString(R.string.msg_preview_photo)), unread = message.unread)
preview = message.copy(message = context.getString(R.string.msg_preview_photo)), unread = message.unread,
showDayMarker = false, currentDayMarkerText = dayMarkerText)
is VideoAttachment -> VideoAttachmentUiModel(message, attachment, message.id,
attachmentUrl, attachmentTitle, id, getReactions(message),
preview = message.copy(message = context.getString(R.string.msg_preview_video)), unread = message.unread)
preview = message.copy(message = context.getString(R.string.msg_preview_video)), unread = message.unread,
showDayMarker = false, currentDayMarkerText = dayMarkerText)
is AudioAttachment -> AudioAttachmentUiModel(message, attachment, message.id,
attachmentUrl, attachmentTitle, id, getReactions(message),
preview = message.copy(message = context.getString(R.string.msg_preview_audio)), unread = message.unread)
preview = message.copy(message = context.getString(R.string.msg_preview_audio)), unread = message.unread,
showDayMarker = false, currentDayMarkerText = dayMarkerText)
is GenericFileAttachment -> GenericFileAttachmentUiModel(message, attachment,
message.id, attachmentUrl, attachmentTitle, id, getReactions(message),
preview = message.copy(message = context.getString(R.string.msg_preview_file)), unread = message.unread)
preview = message.copy(message = context.getString(R.string.msg_preview_file)), unread = message.unread,
showDayMarker = false, currentDayMarkerText = dayMarkerText)
else -> null
}
}
......@@ -434,11 +466,15 @@ class UiModelMapper @Inject constructor(
null
}
val localDateTime = DateTimeHelper.getLocalDateTime(message.timestamp)
val dayMarkerText = DateTimeHelper.getFormattedDateForMessages(localDateTime, context)
val content = getContent(stripMessageQuotes(message))
MessageUiModel(message = stripMessageQuotes(message), rawData = message,
messageId = message.id, avatar = avatar!!, time = time, senderName = sender,
content = content, isPinned = message.pinned, reactions = getReactions(message),
isFirstUnread = false, preview = preview, isTemporary = isTemp, unread = unread)
content = content, isPinned = message.pinned, currentDayMarkerText = dayMarkerText,
showDayMarker = false, reactions = getReactions(message), isFirstUnread = false,
preview = preview, isTemporary = isTemp, unread = unread)
}
private fun mapMessagePreview(message: Message): Message {
......
......@@ -17,7 +17,9 @@ data class UrlPreviewUiModel(
override var preview: Message? = null,
override var isTemporary: Boolean = false,
override var unread: Boolean? = null,
override var menuItemsToHide: MutableList<Int> = mutableListOf()
override var menuItemsToHide: MutableList<Int> = mutableListOf(),
override var currentDayMarkerText: String,
override var showDayMarker: Boolean
) : BaseUiModel<Url> {
override val viewType: Int
get() = BaseUiModel.ViewType.URL_PREVIEW.viewType
......
......@@ -16,7 +16,9 @@ data class VideoAttachmentUiModel(
override var preview: Message? = null,
override var isTemporary: Boolean = false,
override var unread: Boolean? = null,
override var menuItemsToHide: MutableList<Int> = mutableListOf()
override var menuItemsToHide: MutableList<Int> = mutableListOf(),
override var currentDayMarkerText: String,
override var showDayMarker: Boolean
) : BaseFileAttachmentUiModel<VideoAttachment> {
override val viewType: Int
get() = BaseUiModel.ViewType.VIDEO_ATTACHMENT.viewType
......
......@@ -249,7 +249,7 @@ class DatabaseManager(val context: Application,
id = roomId,
subscriptionId = id,
type = type.toString(),
name = name,
name = name ?: throw NullPointerException(), // this should be filtered on the SDK
fullname = fullName ?: chatRoom.fullname,
userId = userId ?: chatRoom.userId,
readonly = readonly ?: chatRoom.readonly,
......@@ -330,7 +330,7 @@ class DatabaseManager(val context: Application,
id = room.id,
subscriptionId = subscription.id,
type = room.type.toString(),
name = room.name ?: subscription.name,
name = room.name ?: subscription.name ?: throw NullPointerException(),// this should be filtered on the SDK
fullname = subscription.fullName ?: room.fullName,
userId = userId,
ownerId = room.user?.id,
......@@ -436,6 +436,7 @@ private fun String.databaseName(): String {
val tmp = this.removePrefix("https://")
.removePrefix("http://")
.removeTrailingSlash()
.replace("/","-")
.replace(".", "_")
return "$tmp.db"
......
......@@ -152,7 +152,7 @@ class MainPresenter @Inject constructor(
}
fun connect() {
launch { refreshSettingsInteractor.refresh(currentServer) }
refreshSettingsInteractor.refreshAsync(currentServer)
manager.connect()
}
......@@ -176,7 +176,7 @@ class MainPresenter @Inject constructor(
fun changeDefaultStatus(userStatus: UserStatus) {
launchUI(strategy) {
try {
client.setDefaultStatus(userStatus)
manager.setDefaultStatus(userStatus)
view.showUserStatus(userStatus)
} catch (ex: RocketChatException) {
ex.message?.let {
......
......@@ -169,7 +169,7 @@ class MainActivity : AppCompatActivity(), MainView, HasActivityInjector,
}
headerLayout.image_avatar.setOnClickListener {
view_navigation.menu.findItem(R.id.action_update_profile).isChecked = true
view_navigation.menu.findItem(R.id.action_profile).isChecked = true
presenter.toUserProfile()
drawer_layout.closeDrawer(Gravity.START)
}
......@@ -218,19 +218,20 @@ class MainActivity : AppCompatActivity(), MainView, HasActivityInjector,
private fun setupToolbar() {
setSupportActionBar(toolbar)
toolbar.setNavigationIcon(R.drawable.ic_menu_white_24dp)
toolbar.setNavigationOnClickListener {
openDrawer()
}
}
private fun setupNavigationView() {
fun setupNavigationView() {
view_navigation.setNavigationItemSelectedListener { menuItem ->
menuItem.isChecked = true
closeDrawer()
onNavDrawerItemSelected(menuItem)
true
}
toolbar.setNavigationIcon(R.drawable.ic_menu_white_24dp)
toolbar.setNavigationOnClickListener {
openDrawer()
}
}
private fun onNavDrawerItemSelected(menuItem: MenuItem) {
......
......@@ -5,7 +5,9 @@ import chat.rocket.android.util.retryIO
import chat.rocket.core.internal.rest.settings
import kotlinx.coroutines.experimental.CommonPool
import kotlinx.coroutines.experimental.async
import kotlinx.coroutines.experimental.launch
import kotlinx.coroutines.experimental.withContext
import timber.log.Timber
import javax.inject.Inject
class RefreshSettingsInteractor @Inject constructor(
......@@ -30,7 +32,8 @@ class RefreshSettingsInteractor @Inject constructor(
suspend fun refresh(server: String) {
withContext(CommonPool) {
factory.create(server).let { client ->
val settings = retryIO(description = "settings", times = 5) {
val settings = retryIO(description = "settings", times = 5,
maxDelay = 5000, initialDelay = 300) {
client.settings(*settingsFilter)
}
repository.save(server, settings)
......@@ -39,11 +42,11 @@ class RefreshSettingsInteractor @Inject constructor(
}
fun refreshAsync(server: String) {
async {
launch(CommonPool) {
try {
refresh(server)
} catch (ex: Exception) {
ex.printStackTrace()
Timber.e(ex, "Error refreshing settings for: $server")
}
}
}
......
......@@ -5,7 +5,10 @@ import chat.rocket.android.db.DatabaseManager
import chat.rocket.android.infrastructure.LocalRepository
import chat.rocket.common.model.BaseRoom
import chat.rocket.common.model.User
import chat.rocket.common.model.UserStatus
import chat.rocket.core.RocketChatClient
import chat.rocket.core.internal.realtime.setDefaultStatus
import chat.rocket.core.internal.realtime.setTemporaryStatus
import chat.rocket.core.internal.realtime.socket.connect
import chat.rocket.core.internal.realtime.socket.disconnect
import chat.rocket.core.internal.realtime.socket.model.State
......@@ -49,6 +52,7 @@ class ConnectionManager(
private var roomsId: String? = null
private var userDataId: String? = null
private var activeUserId: String? = null
private var temporaryStatus: UserStatus? = null
private val activeUsersContext = newSingleThreadContext("activeUsersContext")
private val roomsContext = newSingleThreadContext("roomsContext")
......@@ -90,6 +94,10 @@ class ConnectionManager(
}
resubscribeRooms()
temporaryStatus?.let { status ->
client.setTemporaryStatus(status)
}
}
is State.Waiting -> {
Timber.d("Connection in: ${status.seconds}")
......@@ -176,6 +184,16 @@ class ConnectionManager(
}
}
fun setDefaultStatus(userStatus: UserStatus) {
temporaryStatus = null
client.setDefaultStatus(userStatus)
}
fun setTemporaryStatus(userStatus: UserStatus) {
temporaryStatus = userStatus
client.setTemporaryStatus(userStatus)
}
private fun resubscribeRooms() {
roomMessagesChannels.toList().map { (roomId, channel) ->
client.subscribeRoomMessages(roomId) { _, id ->
......@@ -190,6 +208,7 @@ class ConnectionManager(
client.removeStateChannel(statusChannel)
client.disconnect()
connectJob?.cancel()
temporaryStatus = null
}
fun addStatusChannel(channel: Channel<State>) = statusChannelList.add(channel)
......
......@@ -10,6 +10,7 @@ import android.view.ViewGroup
import android.widget.AdapterView
import chat.rocket.android.R
import chat.rocket.android.about.ui.AboutFragment
import chat.rocket.android.main.ui.MainActivity
import chat.rocket.android.settings.password.ui.PasswordActivity
import chat.rocket.android.settings.presentation.SettingsView
import chat.rocket.android.util.extensions.addFragmentBackStack
......@@ -34,6 +35,14 @@ class SettingsFragment : Fragment(), SettingsView, AdapterView.OnItemClickListen
setupListView()
}
override fun onResume() {
// FIXME - gambiarra ahead. will fix when moving to new androidx Navigation
(activity as? MainActivity)?.let {
it.setupNavigationView()
}
super.onResume()
}
override fun onItemClick(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
when (parent?.getItemAtPosition(position).toString()) {
resources.getString(R.string.title_password) -> {
......
......@@ -6,11 +6,11 @@ import chat.rocket.common.model.Token
import timber.log.Timber
fun String.removeTrailingSlash(): String {
return if (isNotEmpty() && this[length - 1] == '/') {
this.substring(0, length - 1)
} else {
this
var removed = this
while (removed.isNotEmpty() && removed[removed.length - 1] == '/') {
removed = removed.substring(0, removed.length - 1)
}
return removed
}
fun String.sanitize(): String {
......
......@@ -9,6 +9,8 @@
layout="@layout/layout_toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.constraintlayout.widget.ConstraintLayout
......@@ -51,9 +53,11 @@
android:layout_height="wrap_content"
android:backgroundTint="@android:color/transparent"
android:hint="@string/msg_search"
android:paddingBottom="8dp"
android:paddingEnd="8dp"
android:paddingStart="8dp"
android:paddingEnd="8dp"
android:paddingBottom="8dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/members_chips" />
<View
......@@ -61,6 +65,8 @@
android:layout_width="match_parent"
android:layout_height="0.2dp"
android:background="@color/colorDividerMessageComposer"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/text_search_member" />
<androidx.recyclerview.widget.RecyclerView
......@@ -69,6 +75,8 @@
android:layout_height="0dp"
android:scrollbars="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/separator_1" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
......@@ -10,8 +10,10 @@
android:layout_width="120dp"
android:layout_height="120dp"
android:layout_centerHorizontal="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:roundedCornerRadius="2dp" />
</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
......@@ -59,9 +59,9 @@
<Button
android:id="@+id/button_cas"
style="@style/Authentication.Button"
android:layout_marginEnd="@dimen/screen_edge_left_and_right_margins"
android:layout_marginStart="@dimen/screen_edge_left_and_right_margins"
android:layout_marginTop="16dp"
android:layout_marginEnd="@dimen/screen_edge_left_and_right_margins"
android:text="@string/action_login_or_sign_up"
android:visibility="gone"
app:layout_constraintLeft_toLeftOf="parent"
......@@ -73,9 +73,9 @@
android:id="@+id/text_new_to_rocket_chat"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/screen_edge_left_and_right_margins"
android:layout_marginStart="@dimen/screen_edge_left_and_right_margins"
android:layout_marginTop="16dp"
android:layout_marginEnd="@dimen/screen_edge_left_and_right_margins"
android:gravity="center"
android:textColorLink="@color/colorAccent"
android:visibility="gone"
......@@ -88,9 +88,9 @@
android:id="@+id/text_forgot_your_password"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/screen_edge_left_and_right_margins"
android:layout_marginStart="@dimen/screen_edge_left_and_right_margins"
android:layout_marginTop="8dp"
android:layout_marginEnd="@dimen/screen_edge_left_and_right_margins"
android:gravity="center"
android:textColorLink="@color/colorAccent"
android:visibility="gone"
......@@ -115,14 +115,14 @@
android:id="@+id/social_accounts_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/screen_edge_left_and_right_margins"
android:layout_marginStart="@dimen/screen_edge_left_and_right_margins"
android:layout_marginTop="20dp"
android:layout_marginEnd="@dimen/screen_edge_left_and_right_margins"
android:background="@color/colorPrimaryDark"
android:gravity="center"
android:orientation="vertical"
android:paddingBottom="32dp"
android:paddingTop="@dimen/screen_edge_left_and_right_margins"
android:paddingBottom="32dp"
android:visibility="gone"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
......@@ -242,7 +242,9 @@
style="@style/Authentication.Button"
android:text="@string/title_log_in"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent" />
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>
\ No newline at end of file
......@@ -12,9 +12,9 @@
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="@id/text_typing_status"
app:layout_constraintTop_toBottomOf="@+id/text_connection_status"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent">
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/text_connection_status">
<include
android:id="@+id/layout_message_list"
......@@ -68,25 +68,29 @@
android:id="@+id/empty_chat_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:constraint_referenced_ids="image_chat_icon, text_chat_title, text_chat_description"
android:visibility="gone"
app:constraint_referenced_ids="image_chat_icon, text_chat_title, text_chat_description"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:visibility="visible" />
<chat.rocket.android.widget.autocompletion.ui.SuggestionsView
android:id="@+id/suggestions_view"
android:layout_width="match_parent"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="@color/suggestion_background_color"
app:layout_constraintBottom_toTopOf="@id/layout_message_composer" />
app:layout_constraintBottom_toTopOf="@id/layout_message_composer"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<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:layout_marginEnd="16dp"
android:layout_marginBottom="5dp"
android:maxLines="2"
android:visibility="gone"
app:layout_constraintBottom_toTopOf="@id/layout_message_composer"
......@@ -95,30 +99,37 @@
<include
android:id="@+id/layout_message_composer"
layout="@layout/message_composer"
android:layout_width="match_parent"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent" />
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<View
android:id="@+id/view_dim"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="@color/colorDim"
android:visibility="gone"
app:layout_constraintBottom_toTopOf="@id/layout_message_composer" />
app:layout_constraintBottom_toTopOf="@id/layout_message_composer"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<include
android:id="@+id/layout_message_attachment_options"
layout="@layout/message_attachment_options"
android:layout_width="match_parent"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:visibility="gone"
app:layout_constraintBottom_toTopOf="@id/layout_message_composer" />
app:layout_constraintBottom_toTopOf="@id/layout_message_composer"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<TextView
android:id="@+id/text_connection_status"
android:layout_width="match_parent"
android:layout_width="0dp"
android:layout_height="32dp"
android:alpha="0"
android:background="@color/colorPrimary"
......@@ -127,6 +138,8 @@
android:textAppearance="@style/TextAppearance.AppCompat.Body2"
android:textColor="@color/colorWhite"
android:visibility="gone"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:alpha="1"
tools:text="connected"
......
......@@ -95,8 +95,8 @@
android:hint="@string/msg_channel_name"
android:inputType="text"
android:maxLines="1"
android:paddingEnd="10dp"
android:paddingStart="24dp"
android:paddingEnd="10dp"
android:textSize="16sp"
app:layout_constraintBottom_toBottomOf="@+id/image_channel_icon"
app:layout_constraintEnd_toEndOf="parent"
......@@ -120,8 +120,8 @@
android:hint="@string/msg_invite_members"
android:inputType="text"
android:maxLines="1"
android:paddingEnd="10dp"
android:paddingStart="24dp"
android:paddingEnd="10dp"
android:textSize="16sp"
app:layout_constraintBottom_toBottomOf="@+id/image_invite_member"
app:layout_constraintEnd_toEndOf="parent"
......@@ -130,21 +130,27 @@
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/view_member_suggestion"
android:layout_width="match_parent"
android:layout_width="0dp"
android:layout_height="100dp"
android:layout_marginEnd="12dp"
android:layout_marginStart="12dp"
android:layout_marginEnd="12dp"
android:background="@color/colorWhite"
android:elevation="2dp"
android:orientation="vertical"
android:visibility="gone"
app:layout_constraintBottom_toTopOf="@+id/text_invite_members">
app:layout_constraintBottom_toTopOf="@+id/text_invite_members"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone" />
android:layout_width="0dp"
android:layout_height="0dp"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.wang.avi.AVLoadingIndicatorView
android:id="@+id/view_member_suggestion_loading"
......@@ -173,11 +179,13 @@
<com.google.android.material.chip.ChipGroup
android:id="@+id/chip_group_member"
style="@style/Widget.MaterialComponents.Chip.Entry"
android:layout_width="match_parent"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:visibility="gone"
app:chipSpacing="3dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/text_invite_members" />
</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
......@@ -8,9 +8,13 @@
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical" />
android:layout_width="0dp"
android:layout_height="0dp"
android:scrollbars="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.wang.avi.AVLoadingIndicatorView
android:id="@+id/view_loading"
......@@ -72,6 +76,8 @@
android:layout_height="wrap_content"
android:visibility="gone"
app:constraint_referenced_ids="text_no_favorite_messages_description,image_star,text_no_favorite_messages"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:visibility="visible" />
</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
......@@ -9,9 +9,13 @@
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical" />
android:layout_width="0dp"
android:layout_height="0dp"
android:scrollbars="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.wang.avi.AVLoadingIndicatorView
android:id="@+id/view_loading"
......@@ -68,6 +72,10 @@
android:id="@+id/group_no_file"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:visibility="gone"
app:constraint_referenced_ids="image_file,text_no_file,text_all_files_appear_here"
tools:visibility="visible" />
......
......@@ -10,8 +10,11 @@
<com.facebook.drawee.view.SimpleDraweeView
android:id="@+id/image_bottom_sheet_avatar"
android:layout_width="match_parent"
android:layout_height="200dp" />
android:layout_width="0dp"
android:layout_height="200dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<LinearLayout
android:id="@+id/name_and_username_container"
......@@ -19,9 +22,9 @@
android:layout_height="wrap_content"
android:background="@color/colorBackgroundMemberContainer"
android:orientation="vertical"
android:paddingBottom="10dp"
android:paddingStart="16dp"
android:paddingTop="10dp"
android:paddingBottom="10dp"
app:layout_constraintBottom_toBottomOf="@+id/image_bottom_sheet_avatar"
app:layout_constraintLeft_toLeftOf="parent">
......
......@@ -8,9 +8,13 @@
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical" />
android:layout_width="0dp"
android:layout_height="0dp"
android:scrollbars="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.wang.avi.AVLoadingIndicatorView
android:id="@+id/view_loading"
......@@ -70,6 +74,10 @@
android:layout_height="wrap_content"
android:visibility="gone"
app:constraint_referenced_ids="image_mention,text_no_mention,text_all_mentions_appear_here"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:visibility="visible" />
</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
......@@ -8,17 +8,21 @@
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view_pinned"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical" />
android:layout_width="0dp"
android:layout_height="0dp"
android:scrollbars="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.wang.avi.AVLoadingIndicatorView
android:id="@+id/view_loading"
android:layout_width="48dp"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_marginBottom="8dp"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:visibility="gone"
app:indicatorColor="@color/colorBlack"
app:indicatorName="BallPulseIndicator"
......@@ -74,6 +78,8 @@
android:layout_height="wrap_content"
android:visibility="gone"
app:constraint_referenced_ids="tv_pin_description,iv_pin_icon,tv_pin_title"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:visibility="visible" />
</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
......@@ -8,10 +8,10 @@
android:background="?android:attr/selectableItemBackground"
android:clickable="true"
android:focusable="true"
android:paddingBottom="@dimen/message_item_top_and_bottom_padding"
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">
android:paddingTop="@dimen/message_item_top_and_bottom_padding"
android:paddingEnd="@dimen/screen_edge_left_and_right_padding"
android:paddingBottom="@dimen/message_item_top_and_bottom_padding">
<View
android:id="@+id/quote_bar"
......@@ -19,19 +19,20 @@
android:layout_height="0dp"
android:layout_marginStart="56dp"
android:background="@drawable/quote_vertical_gray_bar"
app:layout_constraintBottom_toTopOf="@id/recycler_view_reactions"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="@id/recycler_view_reactions"/>
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/attachment_text"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
android:autoLink="web"
app:layout_constraintStart_toEndOf="@id/quote_bar"
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/quote_bar"
app:layout_constraintTop_toTopOf="parent"
tools:text="#5571 - User profile from SSO must not have password change option" />
<include
......
......@@ -13,6 +13,47 @@
android:paddingEnd="@dimen/screen_edge_left_and_right_padding"
android:paddingBottom="@dimen/message_item_top_and_bottom_padding">
<LinearLayout
android:id="@+id/day_marker_layout"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingBottom="8dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/new_messages_notif">
<View
android:layout_width="0px"
android:layout_height="1dp"
android:layout_weight="1"
android:background="@color/colorDivider" />
<TextView
android:id="@+id/day"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:textAppearance="@style/Message.DayMarker"
tools:text="Wednesday" />
<View
android:layout_width="0dp"
android:layout_height="1dp"
android:layout_weight="1"
android:background="@color/colorDivider" />
</LinearLayout>
<include
android:id="@+id/layout_avatar"
layout="@layout/avatar"
android:layout_width="40dp"
android:layout_height="40dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="@+id/text_sender" />
<LinearLayout
android:id="@+id/new_messages_notif"
android:layout_width="match_parent"
......@@ -50,7 +91,7 @@
<include
android:id="@+id/layout_avatar"
layout="@layout/avatar"
android:layout_width="40dp"
android:layout_width="38dp"
android:layout_height="40dp"
android:layout_marginTop="5dp"
app:layout_constraintStart_toStartOf="parent"
......@@ -63,8 +104,9 @@
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintLeft_toRightOf="@+id/layout_avatar"
app:layout_constraintStart_toEndOf="@+id/layout_avatar"
app:layout_constraintTop_toBottomOf="@+id/new_messages_notif"
app:layout_constraintTop_toBottomOf="@+id/day_marker_layout"
tools:text="Ronald Perkins" />
<TextView
......
......@@ -7,24 +7,25 @@
android:background="?android:attr/selectableItemBackground"
android:clickable="true"
android:focusable="true"
android:paddingBottom="@dimen/message_item_top_and_bottom_padding"
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">
android:paddingTop="@dimen/message_item_top_and_bottom_padding"
android:paddingEnd="@dimen/screen_edge_left_and_right_padding"
android:paddingBottom="@dimen/message_item_top_and_bottom_padding">
<Button
android:id="@+id/button_message_reply"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="2dp"
android:layout_marginTop="5dp"
android:layout_marginStart="56dp"
android:layout_marginTop="5dp"
android:layout_marginBottom="2dp"
android:background="@drawable/message_reply_button_bg"
android:text="@string/action_msg_reply"
android:textAllCaps="false"
android:textColor="#1D74F5"
android:textSize="14sp"
app:layout_constraintLeft_toLeftOf="parent" />
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<include
layout="@layout/layout_reactions"
......
......@@ -7,9 +7,12 @@
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_width="0dp"
android:layout_height="@dimen/toolbar_height"
android:background="@color/colorPrimary"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
......
......@@ -3,8 +3,8 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="@color/default_background">
android:background="@color/default_background"
android:orientation="vertical">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/composer"
......@@ -13,19 +13,24 @@
<View
android:id="@+id/divider"
android:layout_width="match_parent"
android:layout_width="0dp"
android:layout_height="1dp"
android:background="@color/colorDividerMessageComposer" />
android:background="@color/colorDividerMessageComposer"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/text_room_is_read_only"
android:layout_width="match_parent"
android:layout_width="0dp"
android:layout_height="45dp"
android:background="@color/colorWhite"
android:gravity="center"
android:text="@string/msg_this_room_is_read_only"
android:textColor="@color/colorBlack"
android:visibility="gone"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/divider" />
<Button
......@@ -42,13 +47,15 @@
<LinearLayout
android:id="@+id/input_container"
android:layout_width="match_parent"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="10dp"
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp"
android:orientation="horizontal"
android:paddingBottom="10dp"
android:paddingTop="10dp"
android:paddingBottom="10dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/divider">
<ImageButton
......@@ -70,12 +77,12 @@
android:layout_weight="1"
android:background="@android:color/transparent"
android:hint="@string/msg_message"
android:imeOptions="flagNoExtractUi"
android:inputType="textCapSentences|textMultiLine"
android:lineSpacingExtra="4dp"
android:maxLines="4"
android:minHeight="24dp"
android:scrollbars="vertical"
android:imeOptions="flagNoExtractUi" />
android:scrollbars="vertical" />
<ImageButton
android:id="@+id/button_show_attachment_options"
......
......@@ -6,16 +6,16 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?android:attr/selectableItemBackground"
android:paddingEnd="24dp"
android:paddingStart="72dp">
android:paddingStart="72dp"
android:paddingEnd="24dp">
<com.facebook.drawee.view.SimpleDraweeView
android:id="@+id/image_preview"
android:layout_width="70dp"
android:layout_height="50dp"
app:actualImageScaleType="centerCrop"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:actualImageScaleType="centerCrop" />
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/text_host"
......@@ -23,9 +23,10 @@
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:textColor="@color/colorSecondaryText"
android:textDirection="locale"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/image_preview"
android:textDirection="locale"
app:layout_constraintTop_toTopOf="parent"
tools:text="www.uol.com.br" />
<TextView
......@@ -33,20 +34,20 @@
android:layout_width="0dp"
android:layout_height="wrap_content"
android:textColor="@color/colorAccent"
android:textDirection="locale"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="@+id/text_host"
app:layout_constraintTop_toBottomOf="@id/text_host"
android:textDirection="locale"
tools:text="Web page title" />
<TextView
android:id="@+id/text_description"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:textDirection="locale"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="@+id/text_host"
app:layout_constraintTop_toBottomOf="@id/text_title"
android:textDirection="locale"
tools:text="description" />
<include
......
......@@ -30,30 +30,35 @@
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/account_container"
android:layout_width="match_parent"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:background="?selectableItemBackground"
android:elevation="2dp"
android:paddingBottom="4dp"
android:paddingEnd="12dp"
android:paddingStart="12dp"
android:paddingTop="4dp"
android:paddingEnd="12dp"
android:paddingBottom="4dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/image_avatar">
<ImageView
android:id="@+id/image_user_status"
android:layout_width="12dp"
android:layout_height="12dp"
app:layout_constraintStart_toStartOf="parent" />
app:layout_constraintBottom_toTopOf="@+id/text_user_name"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@+id/text_user_name"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/text_user_name"
style="@style/Sender.Name.TextView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="10dp"
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp"
android:textColor="@color/colorWhite"
app:layout_constraintBottom_toBottomOf="@+id/image_user_status"
app:layout_constraintEnd_toStartOf="@+id/image_account_expand"
......
......@@ -15,6 +15,9 @@
android:layout_width="24dp"
android:layout_height="24dp"
app:roundedCornerRadius="3dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
tools:src="@tools:sample/avatars" />
<ImageView
......
<?xml version="1.0" encoding="utf-8"?>
<menu 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"
tools:ignore="AppCompatResource">
<item
android:id="@+id/action_search"
......
<?xml version="1.0" encoding="utf-8"?>
<menu 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"
tools:ignore="AppCompatResource">
<item
android:id="@+id/action_save_image"
......
This diff is collapsed.
......@@ -36,8 +36,7 @@
<string name="action_away">Ausente</string>
<string name="action_busy">Ocupado</string>
<string name="action_invisible">Invisible</string>
<!-- TODO Add translation -->
<string name="action_drawing">Drawing</string>
<string name="action_drawing">dibujo</string>
<string name="action_save_to_gallery">Guardar en la galería</string>
<!-- Settings List -->
......@@ -65,6 +64,7 @@
<string name="msg_new_user_agreement">Al continuar estás aceptando nuestra\n%1$s y %2$s</string>
<string name="msg_2fa_code">Código 2FA</string>
<string name="msg_yesterday">Ayer</string>
<string name="msg_today">Hoy</string>
<string name="msg_message">Mensaje</string>
<string name="msg_this_room_is_read_only">Esta sala es de solo lectura</string>
<string name="msg_invalid_2fa_code">Código 2FA no válido</string>
......@@ -121,12 +121,6 @@
<string name="msg_delete_message">Borrar mensaje</string>
<string name="msg_delete_description">Seguro que quieres borrar este mensaje</string>
<string name="msg_no_search_found">No se han encontrado resultados</string>
<!-- TODO Add translation -->
<string name="msg_upload_file">Upload file</string>
<!-- TODO Add translation -->
<string name="msg_file_description">File description</string>
<!-- TODO Add translation -->
<string name="msg_send">Send</string>
<!-- Create channel messages -->
<string name="msg_private_channel">Privado</string>
......@@ -179,7 +173,7 @@
<string name="permission_starring_not_allowed">Starring is not allowed</string>
<!-- Search message -->
<string name="title_search_message">Search message</string>
<string name="title_search_message">Búsqueda de mensajes</string>
<!-- Favorite/Unfavorite chat room -->
<string name="title_favorite_chat">Chat favorito</string>
......@@ -249,8 +243,7 @@
<!-- Emoji message-->
<string name="msg_no_recent_emoji">Sin emojis recientes</string>
<!-- TODO Add translation -->
<string name="alert_title_default_skin_tone">Default skin tone</string>
<string name="alert_title_default_skin_tone">Tono de piel predeterminado</string>
<!-- Sorting and grouping-->
<string name="menu_chatroom_sort">Ordenar</string>
......@@ -275,5 +268,8 @@
<string name="read_by">Leído por</string>
<string name="message_information_title">Información del mensaje</string>
<string name="msg_log_out">Saliendo de tu cuenta…</string>
<string name="msg_upload_file">Subir archivo</string>
<string name="msg_file_description">Descripción del archivo</string>
<string name="msg_send">Enviar</string>
<string name="msg_sent_attachment">Envió un archivo</string>
</resources>
......@@ -72,6 +72,7 @@
<string name="msg_new_user_agreement">En procédant, vous acceptez notre\n%1$s et %2$s</string>
<string name="msg_2fa_code">Code 2FA</string>
<string name="msg_yesterday">Hier</string>
<string name="msg_today">Aujourd\'hui</string>
<string name="msg_message">Message</string>
<string name="msg_this_room_is_read_only">Cette salle est seulement de lecture</string>
<string name="msg_invalid_2fa_code">Code 2FA non valide</string>
......@@ -184,6 +185,7 @@
<string name="action_msg_share">Partager</string>
<string name="action_title_editing">Modification du message</string>
<string name="action_msg_add_reaction">Ajouter une réaction</string>
<string name="action_share">Partager</string>
<!-- Permission messages -->
<string name="permission_editing_not_allowed">L\'édition n\'est pas autorisée</string>
......@@ -287,6 +289,7 @@
<string name="header_unknown">Inconnu</string>
<!--Notifications-->
<string name="share_label">Modifier le message partagé</string>
<string name="notif_action_reply_hint">RÉPONDRE</string>
<string name="notif_error_sending">La réponse a échoué. Veuillez réessayer.</string>
<string name="notif_success_sending">Message envoyé à %1$s!</string>
......
......@@ -39,6 +39,7 @@
<string name="action_invisible">अदृश्य</string>
<string name="action_save_to_gallery">गैलरी में सहेजें</string>
<string name="action_drawing">चित्रकारी</string>
<string name="action_share">शेयर</string>
<!-- Settings List -->
<string-array name="settings_actions">
......@@ -65,6 +66,7 @@
<string name="msg_new_user_agreement">आगे बढ़कर आप हमारे %1$s और %2$s से सहमत हो रहे हैं</string>
<string name="msg_2fa_code">कोड 2FA</string>
<string name="msg_yesterday">कल</string>
<string name="msg_today">आज</string>
<string name="msg_message">संदेश</string>
<string name="msg_this_room_is_read_only">यह रूम केवल पढ़ने के लिए है</string>
<string name="msg_invalid_2fa_code">अमान्य 2FA कोड</string>
......@@ -123,6 +125,7 @@
<string name="msg_upload_file">फाइल अपलोड करें</string>
<string name="msg_file_description">फाइल विवरण</string>
<string name="msg_send">भेजें</string>
<string name="msg_sent_attachment">एक अनुलग्नक भेजा</string>
<string name="msg_delete_message">संदेश को हटाएं</string>
<string name="msg_delete_description">क्या आप निश्चित रूप से यह संदेश हटाना चाहते हैं</string>
......@@ -266,6 +269,7 @@
<string name="header_unknown">अज्ञात</string>
<!--Notifications-->
<string name="share_label">साझा संदेश संपादित करें</string>
<string name="notif_action_reply_hint">जवाब</string>
<string name="notif_error_sending">उत्तर विफल हुआ है। कृपया फिर से प्रयास करें।</string>
<string name="notif_success_sending">संदेश भेजा गया %1$s!</string>
......
......@@ -64,7 +64,8 @@
<string name="msg_invalid_email">Por favor informe um e-mail válido</string>
<string name="msg_new_user_agreement">Ao proceder você concorda com nossos %1$s e %2$s</string>
<string name="msg_2fa_code">Código 2FA</string>
<string name="msg_yesterday">ontem</string>
<string name="msg_yesterday">Ontem</string>
<string name="msg_today">Hoje</string>
<string name="msg_message">Mensagem</string>
<string name="msg_this_room_is_read_only">Este chat é apenas de leitura</string>
<string name="msg_invalid_2fa_code">Código 2FA inválido</string>
......@@ -266,9 +267,11 @@
<string name="header_unknown">Desconhecido</string>
<!--Notifications-->
<string name="share_label">Editar mensagem compartilhada</string>
<string name="notif_action_reply_hint">RESPONDER</string>
<string name="notif_error_sending">Falha ao enviar a mensagem.</string>
<string name="notif_success_sending">Mensagem enviada para %1$s!</string>
<string name="action_share">Compartilhar</string>
<string name="read_by">Lida por</string>
<string name="message_information_title">Informações da mensagem</string>
<string name="msg_log_out">Deslogando…</string>
......
......@@ -65,6 +65,7 @@
<string name="msg_new_user_agreement">Продолжая, вы соглашаетесь с нашими\n%1$s и %2$s</string>
<string name="msg_2fa_code">Код 2FA</string>
<string name="msg_yesterday">Вчера</string>
<string name="msg_today">Сегодня</string>
<string name="msg_message">Сообщение</string>
<string name="msg_this_room_is_read_only">Этот канал только для чтения</string>
<string name="msg_invalid_2fa_code">Неверный код 2FA</string>
......@@ -120,6 +121,7 @@
<string name="msg_upload_file">Загрузить файл</string>
<string name="msg_file_description">Описание файла</string>
<string name="msg_send">послать</string>
<string name="msg_sent_attachment">Отправить вложение</string>
<string name="msg_delete_message">Удалить сообщение</string>
<string name="msg_delete_description">Вы уверены, что хотите удалить это сообщение?</string>
<string name="msg_channel_name">Название канала</string>
......@@ -166,6 +168,7 @@
<string name="action_msg_share">Поделиться</string>
<string name="action_title_editing">Редактирование сообщения</string>
<string name="action_msg_add_reaction">Добавить реакцию</string>
<string name="action_share">Поделиться</string>
<!-- Permission messages -->
<string name="permission_editing_not_allowed">Редактирование запрещено</string>
......@@ -263,6 +266,7 @@
<string name="header_unknown">Неизвестные</string>
<!--Notifications-->
<string name="share_label">Изменить общее сообщение</string>
<string name="notif_action_reply_hint">ОТВЕТИТЬ</string>
<string name="notif_error_sending">Ошибка ответа. Пожалуйста, попробуйте еще раз.</string>
<string name="notif_success_sending">Сообщение отправлено %1$s!</string>
......
......@@ -44,6 +44,8 @@
<color name="quoteBar">#A0A0A0</color>
<color name="colorDivider">#1F000000</color>
<!-- Suggestions -->
<color name="suggestion_background_color">@color/colorWhite</color>
......
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="font_fontFamily_medium" translatable="false">sans-serif-medium</string>
</resources>
......@@ -67,6 +67,7 @@
<string name="msg_2fa_code">2FA Code</string>
<string name="msg_more_than_ninety_nine_unread_messages" translatable="false">99+</string>
<string name="msg_yesterday">Yesterday</string>
<string name="msg_today">Today</string>
<string name="msg_message">Message</string>
<string name="msg_this_room_is_read_only">This room is read only</string>
<string name="msg_invalid_2fa_code">Invalid 2FA Code</string>
......@@ -170,6 +171,7 @@
<string name="action_msg_share">Share</string>
<string name="action_title_editing">Editing Message</string>
<string name="action_msg_add_reaction">Add reaction</string>
<string name="action_share">Share</string>
<!-- Permission messages -->
<string name="permission_editing_not_allowed">Editing is not allowed</string>
......@@ -267,6 +269,7 @@
<string name="header_unknown">Unknown</string>
<!--Notifications-->
<string name="share_label">Edit shared message</string>
<string name="notif_action_reply_hint">REPLY</string>
<string name="notif_error_sending">Reply has failed. Please try again.</string>
<string name="notif_success_sending">Message sent to %1$s!</string>
......
......@@ -101,6 +101,12 @@
<item name="android:textColor">@color/colorPrimaryText</item>
</style>
<style name="Message.DayMarker" parent="TextAppearance.AppCompat">
<item name="android:textSize">14sp</item>
<item name="android:textColor">@color/colorPrimaryText</item>
<item name="android:fontFamily">@string/font_fontFamily_medium</item>
</style>
<style name="Message.Quote.TextView" parent="Message.TextView">
<item name="android:textColor">@color/colorPrimaryText</item>
</style>
......
......@@ -111,6 +111,12 @@ class DrawingActivity : DaggerAppCompatActivity(), DrawView {
}
private fun colorSelector() {
image_color_black.setOnClickListener {
custom_draw_view.setColor(
ResourcesCompat.getColor(resources, R.color.color_black, null)
)
scaleColorView(image_color_black)
}
image_color_red.setOnClickListener {
custom_draw_view.setColor(
ResourcesCompat.getColor(resources, R.color.color_red, null)
......
......@@ -55,8 +55,10 @@
android:padding="8dp"
android:src="@drawable/ic_search_gray_24px"
android:visibility="invisible"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/emoji_backspace"
app:layout_constraintStart_toEndOf="@+id/color_change_view" />
app:layout_constraintStart_toEndOf="@+id/color_change_view"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/emoji_backspace"
......
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