Unverified Commit 3a029395 authored by Lucio Maciel's avatar Lucio Maciel Committed by GitHub

Merge branch 'develop-2.x' into fix/crash-fixes

parents 2993bdea 6f0cc896
...@@ -117,4 +117,32 @@ object DrawableHelper { ...@@ -117,4 +117,32 @@ object DrawableHelper {
} }
return userStatusDrawable return userStatusDrawable
} }
// TODO Why we need to UserStatus?
/**
* Returns the user status drawable.
*
* @param userStatus The user status.
* @param context The context.
* @sse [chat.rocket.core.internal.realtime.UserStatus]
* @return The user status drawable.
*/
fun getUserStatusDrawable(
userStatus: chat.rocket.core.internal.realtime.UserStatus,
context: Context
): Drawable {
return when (userStatus) {
is chat.rocket.core.internal.realtime.UserStatus.Online -> {
getDrawableFromId(R.drawable.ic_status_online_24dp, context)
}
is chat.rocket.core.internal.realtime.UserStatus.Away -> {
getDrawableFromId(R.drawable.ic_status_away_24dp, context)
}
is chat.rocket.core.internal.realtime.UserStatus.Busy -> {
getDrawableFromId(R.drawable.ic_status_busy_24dp, context)
}
else -> getDrawableFromId(R.drawable.ic_status_invisible_24dp, context)
}
}
} }
\ No newline at end of file
...@@ -36,6 +36,7 @@ import kotlinx.coroutines.experimental.channels.Channel ...@@ -36,6 +36,7 @@ import kotlinx.coroutines.experimental.channels.Channel
import kotlinx.coroutines.experimental.launch import kotlinx.coroutines.experimental.launch
import org.threeten.bp.Instant import org.threeten.bp.Instant
import timber.log.Timber import timber.log.Timber
import java.util.*
import javax.inject.Inject import javax.inject.Inject
class ChatRoomPresenter @Inject constructor(private val view: ChatRoomView, class ChatRoomPresenter @Inject constructor(private val view: ChatRoomView,
...@@ -107,12 +108,13 @@ class ChatRoomPresenter @Inject constructor(private val view: ChatRoomView, ...@@ -107,12 +108,13 @@ class ChatRoomPresenter @Inject constructor(private val view: ChatRoomView,
// ignore message for now, will receive it on the stream // ignore message for now, will receive it on the stream
val message = retryIO { val message = retryIO {
if (messageId == null) { if (messageId == null) {
client.sendMessage(chatRoomId, text) val id = UUID.randomUUID().toString()
client.sendMessage(id, chatRoomId, text)
} else { } else {
client.updateMessage(chatRoomId, messageId, text) client.updateMessage(chatRoomId, messageId, text)
} }
} }
view.clearMessageComposition() view.enableSendMessageButton(false)
} catch (ex: Exception) { } catch (ex: Exception) {
Timber.d(ex, "Error sending message...") Timber.d(ex, "Error sending message...")
ex.message?.let { ex.message?.let {
...@@ -120,8 +122,7 @@ class ChatRoomPresenter @Inject constructor(private val view: ChatRoomView, ...@@ -120,8 +122,7 @@ class ChatRoomPresenter @Inject constructor(private val view: ChatRoomView,
}.ifNull { }.ifNull {
view.showGenericErrorMessage() view.showGenericErrorMessage()
} }
} finally { view.enableSendMessageButton(true)
view.enableSendMessageButton()
} }
} }
} }
...@@ -542,9 +543,11 @@ class ChatRoomPresenter @Inject constructor(private val view: ChatRoomView, ...@@ -542,9 +543,11 @@ class ChatRoomPresenter @Inject constructor(private val view: ChatRoomView,
launchUI(strategy) { launchUI(strategy) {
try { try {
if (text.length == 1) { if (text.length == 1) {
view.disableSendMessageButton()
// we have just the slash, post it anyway // we have just the slash, post it anyway
sendMessage(roomId, text, null) sendMessage(roomId, text, null)
} else { } else {
view.disableSendMessageButton()
val command = text.split(" ") val command = text.split(" ")
val name = command[0].substring(1) val name = command[0].substring(1)
var params = "" var params = ""
...@@ -560,6 +563,7 @@ class ChatRoomPresenter @Inject constructor(private val view: ChatRoomView, ...@@ -560,6 +563,7 @@ class ChatRoomPresenter @Inject constructor(private val view: ChatRoomView,
// failed, command is not valid so post it // failed, command is not valid so post it
sendMessage(roomId, text, null) sendMessage(roomId, text, null)
} }
view.enableSendMessageButton(false)
} }
} catch (ex: RocketChatException) { } catch (ex: RocketChatException) {
Timber.e(ex) Timber.e(ex)
......
...@@ -92,8 +92,10 @@ interface ChatRoomView : LoadingView, MessageView { ...@@ -92,8 +92,10 @@ interface ChatRoomView : LoadingView, MessageView {
/** /**
* Enables the send message button. * Enables the send message button.
*
* @param sendFailed Whether the sent message has failed.
*/ */
fun enableSendMessageButton() fun enableSendMessageButton(sendFailed: Boolean)
/** /**
* Clears the message composition. * Clears the message composition.
......
...@@ -35,10 +35,8 @@ import kotlinx.android.synthetic.main.fragment_chat_room.* ...@@ -35,10 +35,8 @@ import kotlinx.android.synthetic.main.fragment_chat_room.*
import kotlinx.android.synthetic.main.message_attachment_options.* import kotlinx.android.synthetic.main.message_attachment_options.*
import kotlinx.android.synthetic.main.message_composer.* import kotlinx.android.synthetic.main.message_composer.*
import kotlinx.android.synthetic.main.message_list.* import kotlinx.android.synthetic.main.message_list.*
import timber.log.Timber
import java.util.concurrent.atomic.AtomicInteger import java.util.concurrent.atomic.AtomicInteger
import javax.inject.Inject import javax.inject.Inject
import kotlin.math.absoluteValue
fun newInstance(chatRoomId: String, fun newInstance(chatRoomId: String,
chatRoomName: String, chatRoomName: String,
...@@ -126,7 +124,6 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR ...@@ -126,7 +124,6 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
activity?.apply { activity?.apply {
(this as? ChatRoomActivity)?.showRoomTypeIcon(true) (this as? ChatRoomActivity)?.showRoomTypeIcon(true)
} }
} }
override fun onActivityCreated(savedInstanceState: Bundle?) { override fun onActivityCreated(savedInstanceState: Bundle?) {
...@@ -306,10 +303,12 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR ...@@ -306,10 +303,12 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
button_send.isEnabled = false button_send.isEnabled = false
} }
override fun enableSendMessageButton() { override fun enableSendMessageButton(sendFailed: Boolean) {
button_send.isEnabled = true button_send.isEnabled = true
text_message.isEnabled = true text_message.isEnabled = true
text_message.erase() if (!sendFailed) {
clearMessageComposition()
}
} }
override fun clearMessageComposition() { override fun clearMessageComposition() {
...@@ -475,7 +474,6 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR ...@@ -475,7 +474,6 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
private fun setupRecyclerView() { private fun setupRecyclerView() {
recycler_view.addOnScrollListener(object : RecyclerView.OnScrollListener() { recycler_view.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) { override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
Timber.i("Scrolling vertically: $dy")
if (!recyclerView.canScrollVertically(1)) { if (!recyclerView.canScrollVertically(1)) {
button_fab.hide() button_fab.hide()
} else { } else {
...@@ -532,8 +530,6 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR ...@@ -532,8 +530,6 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
var textMessage = citation ?: "" var textMessage = citation ?: ""
textMessage += text_message.textContent textMessage += text_message.textContent
sendMessage(textMessage) sendMessage(textMessage)
clearMessageComposition()
} }
button_show_attachment_options.setOnClickListener { button_show_attachment_options.setOnClickListener {
...@@ -598,7 +594,6 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR ...@@ -598,7 +594,6 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
text_message.requestFocus() text_message.requestFocus()
emojiKeyboardPopup.showAtBottomPending() emojiKeyboardPopup.showAtBottomPending()
KeyboardHelper.showSoftKeyboard(text_message) KeyboardHelper.showSoftKeyboard(text_message)
} }
setReactionButtonIcon(R.drawable.ic_keyboard_black_24dp) setReactionButtonIcon(R.drawable.ic_keyboard_black_24dp)
} else { } else {
......
...@@ -6,6 +6,7 @@ import chat.rocket.android.server.domain.model.Account ...@@ -6,6 +6,7 @@ import chat.rocket.android.server.domain.model.Account
import kotlinx.android.synthetic.main.item_account.view.* import kotlinx.android.synthetic.main.item_account.view.*
class AccountViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { class AccountViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
fun bind(account: Account) { fun bind(account: Account) {
with(itemView) { with(itemView) {
server_logo.setImageURI(account.serverLogo) server_logo.setImageURI(account.serverLogo)
......
...@@ -5,50 +5,64 @@ import android.view.ViewGroup ...@@ -5,50 +5,64 @@ import android.view.ViewGroup
import chat.rocket.android.R import chat.rocket.android.R
import chat.rocket.android.server.domain.model.Account import chat.rocket.android.server.domain.model.Account
import chat.rocket.android.util.extensions.inflate import chat.rocket.android.util.extensions.inflate
import chat.rocket.core.internal.realtime.UserStatus
private const val VIEW_TYPE_CHANGE_STATUS = 0
private const val VIEW_TYPE_ACCOUNT = 1
private const val VIEW_TYPE_ADD_ACCOUNT = 2
class AccountsAdapter( class AccountsAdapter(
private val accounts: List<Account>, private val accounts: List<Account>,
private val selector: AccountSelector private val selector: Selector
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() { ) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return when (viewType) { return when (viewType) {
VIEW_TYPE_CHANGE_STATUS -> StatusViewHolder(parent.inflate(R.layout.item_change_status))
VIEW_TYPE_ACCOUNT -> AccountViewHolder(parent.inflate(R.layout.item_account)) VIEW_TYPE_ACCOUNT -> AccountViewHolder(parent.inflate(R.layout.item_account))
else -> AddAccountViewHolder(parent.inflate(R.layout.item_add_account)) else -> AddAccountViewHolder(parent.inflate(R.layout.item_add_account))
} }
} }
override fun getItemCount() = accounts.size + 1 override fun getItemCount() = accounts.size + 2
override fun getItemViewType(position: Int) = override fun getItemViewType(position: Int): Int {
if (position == accounts.size) VIEW_TYPE_ADD_ACCOUNT else VIEW_TYPE_ACCOUNT return when {
position == 0 -> VIEW_TYPE_CHANGE_STATUS
position <= accounts.size -> VIEW_TYPE_ACCOUNT
else -> VIEW_TYPE_ADD_ACCOUNT
}
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
when (holder) { when (holder) {
is StatusViewHolder -> bindStatusViewHolder(holder)
is AccountViewHolder -> bindAccountViewHolder(holder, position) is AccountViewHolder -> bindAccountViewHolder(holder, position)
is AddAccountViewHolder -> bindAddAccountViewHolder(holder, position) is AddAccountViewHolder -> bindAddAccountViewHolder(holder)
} }
} }
private fun bindStatusViewHolder(holder: StatusViewHolder) {
holder.bind { userStatus -> selector.onStatusSelected(userStatus) }
}
private fun bindAccountViewHolder(holder: AccountViewHolder, position: Int) { private fun bindAccountViewHolder(holder: AccountViewHolder, position: Int) {
val account = accounts[position] val account = accounts[position - 1]
holder.bind(account) holder.bind(account)
holder.itemView.setOnClickListener { holder.itemView.setOnClickListener {
selector.onAccountSelected(account.serverUrl) selector.onAccountSelected(account.serverUrl)
} }
} }
private fun bindAddAccountViewHolder(holder: AddAccountViewHolder, position: Int) { private fun bindAddAccountViewHolder(holder: AddAccountViewHolder) {
holder.itemView.setOnClickListener { holder.itemView.setOnClickListener {
selector.onAddedAccountSelected() selector.onAddedAccountSelected()
} }
} }
} }
interface AccountSelector { interface Selector {
fun onStatusSelected(userStatus: UserStatus)
fun onAccountSelected(serverUrl: String) fun onAccountSelected(serverUrl: String)
fun onAddedAccountSelected() fun onAddedAccountSelected()
} }
\ No newline at end of file
private const val VIEW_TYPE_ACCOUNT = 0
private const val VIEW_TYPE_ADD_ACCOUNT = 1
\ No newline at end of file
package chat.rocket.android.main.adapter
import android.support.v7.widget.RecyclerView
import android.view.View
import chat.rocket.core.internal.realtime.UserStatus
import kotlinx.android.synthetic.main.item_change_status.view.*
class StatusViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
fun bind(listener: (UserStatus) -> Unit) {
with(itemView) {
text_online.setOnClickListener { listener(UserStatus.Online) }
text_away.setOnClickListener { listener(UserStatus.Away) }
text_busy.setOnClickListener { listener(UserStatus.Busy) }
text_invisible.setOnClickListener { listener(UserStatus.Offline) }
}
}
}
\ No newline at end of file
...@@ -17,6 +17,8 @@ import chat.rocket.common.RocketChatAuthException ...@@ -17,6 +17,8 @@ import chat.rocket.common.RocketChatAuthException
import chat.rocket.common.RocketChatException import chat.rocket.common.RocketChatException
import chat.rocket.common.util.ifNull import chat.rocket.common.util.ifNull
import chat.rocket.core.RocketChatClient import chat.rocket.core.RocketChatClient
import chat.rocket.core.internal.realtime.UserStatus
import chat.rocket.core.internal.realtime.setDefaultStatus
import chat.rocket.core.internal.rest.logout import chat.rocket.core.internal.rest.logout
import chat.rocket.core.internal.rest.me import chat.rocket.core.internal.rest.me
import chat.rocket.core.internal.rest.unregisterPushToken import chat.rocket.core.internal.rest.unregisterPushToken
...@@ -147,6 +149,21 @@ class MainPresenter @Inject constructor( ...@@ -147,6 +149,21 @@ class MainPresenter @Inject constructor(
navigator.toServerScreen() navigator.toServerScreen()
} }
fun changeStatus(userStatus: UserStatus) {
launchUI(strategy) {
try {
client.setDefaultStatus(userStatus)
view.showUserStatus(userStatus)
} catch (ex: RocketChatException) {
ex.message?.let {
view.showMessage(it)
}.ifNull {
view.showGenericErrorMessage()
}
}
}
}
suspend fun refreshToken(token: String?) { suspend fun refreshToken(token: String?) {
token?.let { token?.let {
localRepository.save(LocalRepository.KEY_PUSH_TOKEN, token) localRepository.save(LocalRepository.KEY_PUSH_TOKEN, token)
......
...@@ -4,8 +4,24 @@ import chat.rocket.android.authentication.server.presentation.VersionCheckView ...@@ -4,8 +4,24 @@ import chat.rocket.android.authentication.server.presentation.VersionCheckView
import chat.rocket.android.core.behaviours.MessageView import chat.rocket.android.core.behaviours.MessageView
import chat.rocket.android.main.viewmodel.NavHeaderViewModel import chat.rocket.android.main.viewmodel.NavHeaderViewModel
import chat.rocket.android.server.domain.model.Account import chat.rocket.android.server.domain.model.Account
import chat.rocket.core.internal.realtime.UserStatus
interface MainView : MessageView, VersionCheckView { interface MainView : MessageView, VersionCheckView {
/**
* Shows the current user status.
*
* @see [UserStatus]
*/
fun showUserStatus(userStatus: UserStatus)
/**
* Setups the navigation header.
*
* @param model The [NavHeaderViewModel].
* @param accounts The list of accounts.
*/
fun setupNavHeader(model: NavHeaderViewModel, accounts: List<Account>) fun setupNavHeader(model: NavHeaderViewModel, accounts: List<Account>)
fun closeServerSelection() fun closeServerSelection()
} }
\ No newline at end of file
...@@ -11,7 +11,7 @@ import android.view.MenuItem ...@@ -11,7 +11,7 @@ import android.view.MenuItem
import android.view.View import android.view.View
import chat.rocket.android.BuildConfig import chat.rocket.android.BuildConfig
import chat.rocket.android.R import chat.rocket.android.R
import chat.rocket.android.main.adapter.AccountSelector import chat.rocket.android.main.adapter.Selector
import chat.rocket.android.main.adapter.AccountsAdapter import chat.rocket.android.main.adapter.AccountsAdapter
import chat.rocket.android.main.presentation.MainPresenter import chat.rocket.android.main.presentation.MainPresenter
import chat.rocket.android.main.presentation.MainView import chat.rocket.android.main.presentation.MainView
...@@ -21,6 +21,7 @@ import chat.rocket.android.util.extensions.fadeIn ...@@ -21,6 +21,7 @@ import chat.rocket.android.util.extensions.fadeIn
import chat.rocket.android.util.extensions.fadeOut import chat.rocket.android.util.extensions.fadeOut
import chat.rocket.android.util.extensions.rotateBy import chat.rocket.android.util.extensions.rotateBy
import chat.rocket.android.util.extensions.showToast import chat.rocket.android.util.extensions.showToast
import chat.rocket.core.internal.realtime.UserStatus
import com.google.android.gms.gcm.GoogleCloudMessaging import com.google.android.gms.gcm.GoogleCloudMessaging
import com.google.android.gms.iid.InstanceID import com.google.android.gms.iid.InstanceID
import dagger.android.AndroidInjection import dagger.android.AndroidInjection
...@@ -42,6 +43,7 @@ class MainActivity : AppCompatActivity(), MainView, HasActivityInjector, HasSupp ...@@ -42,6 +43,7 @@ class MainActivity : AppCompatActivity(), MainView, HasActivityInjector, HasSupp
@Inject lateinit var presenter: MainPresenter @Inject lateinit var presenter: MainPresenter
private var isFragmentAdded: Boolean = false private var isFragmentAdded: Boolean = false
private var expanded = false private var expanded = false
private val headerLayout by lazy { view_navigation.getHeaderView(0) }
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
AndroidInjection.inject(this) AndroidInjection.inject(this)
...@@ -79,15 +81,27 @@ class MainActivity : AppCompatActivity(), MainView, HasActivityInjector, HasSupp ...@@ -79,15 +81,27 @@ class MainActivity : AppCompatActivity(), MainView, HasActivityInjector, HasSupp
} }
} }
override fun showUserStatus(userStatus: UserStatus) {
headerLayout.apply {
image_user_status.setImageDrawable(
DrawableHelper.getUserStatusDrawable(
userStatus,
this.context
)
)
}
}
override fun setupNavHeader(model: NavHeaderViewModel, accounts: List<Account>) { override fun setupNavHeader(model: NavHeaderViewModel, accounts: List<Account>) {
Timber.d("Setting up nav header: $model") Timber.d("Setting up nav header: $model")
val headerLayout = view_navigation.getHeaderView(0) with(headerLayout) {
headerLayout.text_name.text = model.username text_user_name.text = model.username
headerLayout.text_server.text = model.server text_server_url.text = model.server
headerLayout.image_avatar.setImageURI(model.avatar) image_avatar.setImageURI(model.avatar)
headerLayout.server_logo.setImageURI(model.serverLogo) server_logo.setImageURI(model.serverLogo)
setupAccountsList(headerLayout, accounts) setupAccountsList(headerLayout, accounts)
} }
}
override fun closeServerSelection() { override fun closeServerSelection() {
view_navigation.getHeaderView(0).account_container.performClick() view_navigation.getHeaderView(0).account_container.performClick()
...@@ -112,7 +126,11 @@ class MainActivity : AppCompatActivity(), MainView, HasActivityInjector, HasSupp ...@@ -112,7 +126,11 @@ class MainActivity : AppCompatActivity(), MainView, HasActivityInjector, HasSupp
private fun setupAccountsList(header: View, accounts: List<Account>) { private fun setupAccountsList(header: View, accounts: List<Account>) {
accounts_list.layoutManager = LinearLayoutManager(this) accounts_list.layoutManager = LinearLayoutManager(this)
accounts_list.adapter = AccountsAdapter(accounts, object : AccountSelector { accounts_list.adapter = AccountsAdapter(accounts, object : Selector {
override fun onStatusSelected(userStatus: UserStatus) {
presenter.changeStatus(userStatus)
}
override fun onAccountSelected(serverUrl: String) { override fun onAccountSelected(serverUrl: String) {
presenter.changeServer(serverUrl) presenter.changeServer(serverUrl)
} }
...@@ -120,11 +138,10 @@ class MainActivity : AppCompatActivity(), MainView, HasActivityInjector, HasSupp ...@@ -120,11 +138,10 @@ class MainActivity : AppCompatActivity(), MainView, HasActivityInjector, HasSupp
override fun onAddedAccountSelected() { override fun onAddedAccountSelected() {
presenter.addNewServer() presenter.addNewServer()
} }
}) })
header.account_container.setOnClickListener { header.account_container.setOnClickListener {
header.account_expand.rotateBy(180f) header.image_account_expand.rotateBy(180f)
if (expanded) { if (expanded) {
accounts_list.fadeOut() accounts_list.fadeOut()
} else { } else {
......
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<shape <shape xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle"> android:shape="rectangle">
<gradient <gradient
android:angle="90" android:angle="90"
android:endColor="#00000000"
android:centerColor="#30000000" android:centerColor="#30000000"
android:endColor="#00000000"
android:startColor="#C0000000" android:startColor="#C0000000"
android:type="linear" /> android:type="linear" />
</shape> </shape>
\ No newline at end of file
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="24"
android:viewportWidth="24">
<path
android:fillColor="#FFFFD100"
android:fillType="evenOdd"
android:pathData="M12,12m-10,0a10,10 0,1 1,20 0a10,10 0,1 1,-20 0"
android:strokeColor="#00000000"
android:strokeWidth="1" />
<path
android:fillColor="#00000000"
android:fillType="evenOdd"
android:pathData="M12,12m-11,0a11,11 0,1 1,22 0a11,11 0,1 1,-22 0"
android:strokeColor="#FFFFFFFF"
android:strokeWidth="2" />
</vector>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="24"
android:viewportWidth="24">
<path
android:fillColor="#FFFF2A57"
android:fillType="evenOdd"
android:pathData="M12,12m-10,0a10,10 0,1 1,20 0a10,10 0,1 1,-20 0"
android:strokeColor="#00000000"
android:strokeWidth="1" />
<path
android:fillColor="#00000000"
android:fillType="evenOdd"
android:pathData="M12,12m-11,0a11,11 0,1 1,22 0a11,11 0,1 1,-22 0"
android:strokeColor="#FFFFFFFF"
android:strokeWidth="2" />
</vector>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="24"
android:viewportWidth="24">
<path
android:fillColor="#FFCBCED1"
android:fillType="evenOdd"
android:pathData="M12,12m-10,0a10,10 0,1 1,20 0a10,10 0,1 1,-20 0"
android:strokeColor="#00000000"
android:strokeWidth="1" />
<path
android:fillColor="#00000000"
android:fillType="evenOdd"
android:pathData="M12,12m-11,0a11,11 0,1 1,22 0a11,11 0,1 1,-22 0"
android:strokeColor="#FFFFFFFF"
android:strokeWidth="2" />
</vector>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="24"
android:viewportWidth="24">
<path
android:fillColor="#FF2DE0A5"
android:fillType="evenOdd"
android:pathData="M12,12m-10,0a10,10 0,1 1,20 0a10,10 0,1 1,-20 0"
android:strokeColor="#00000000"
android:strokeWidth="1" />
<path
android:fillColor="#00000000"
android:fillType="evenOdd"
android:pathData="M12,12m-11,0a11,11 0,1 1,22 0a11,11 0,1 1,-22 0"
android:strokeColor="#FFFFFFFF"
android:strokeWidth="2" />
</vector>
...@@ -28,21 +28,23 @@ ...@@ -28,21 +28,23 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_gravity="start"> android:layout_gravity="start">
<android.support.design.widget.NavigationView <android.support.design.widget.NavigationView
android:id="@+id/view_navigation" android:id="@+id/view_navigation"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="match_parent" android:layout_height="match_parent"
app:menu="@menu/navigation" app:headerLayout="@layout/nav_header"
app:headerLayout="@layout/nav_header" /> app:menu="@menu/navigation" />
<android.support.v7.widget.RecyclerView <android.support.v7.widget.RecyclerView
android:id="@+id/accounts_list" android:id="@+id/accounts_list"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_marginTop="@dimen/nav_header_height" android:layout_marginTop="@dimen/nav_header_height"
android:elevation="20dp"
android:background="@color/white"
android:alpha="0" android:alpha="0"
android:visibility="gone"/> android:background="@color/white"
android:elevation="20dp"
android:visibility="gone" />
</FrameLayout> </FrameLayout>
</android.support.v4.widget.DrawerLayout> </android.support.v4.widget.DrawerLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="?selectableItemBackground" > android:paddingEnd="16dp"
android:paddingStart="16dp"
android:paddingTop="16dp"
android:background="?selectableItemBackground">
<com.facebook.drawee.view.SimpleDraweeView <com.facebook.drawee.view.SimpleDraweeView
android:id="@+id/server_logo" android:id="@+id/server_logo"
android:layout_width="40dp" android:layout_width="40dp"
android:layout_height="40dp" android:layout_height="40dp"
android:layout_marginTop="8dp" app:actualImageScaleType="centerInside"
android:layout_marginStart="16dp"
android:layout_marginBottom="8dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:actualImageScaleType="centerInside" /> app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView <TextView
android:id="@+id/text_server_url" android:id="@+id/text_server_url"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="8dp" android:layout_marginStart="8dp"
android:layout_marginEnd="16dp" android:ellipsize="end"
android:maxLines="1"
android:textStyle="bold" android:textStyle="bold"
app:layout_constraintTop_toTopOf="@id/server_logo"
app:layout_constraintStart_toEndOf="@id/server_logo"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/server_logo"
app:layout_constraintTop_toTopOf="@id/server_logo"
tools:text="https://open.rocket.chat" /> tools:text="https://open.rocket.chat" />
<TextView <TextView
...@@ -36,10 +36,11 @@ ...@@ -36,10 +36,11 @@
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="8dp" android:layout_marginStart="8dp"
android:layout_marginEnd="16dp" android:ellipsize="end"
android:maxLines="1"
app:layout_constraintBottom_toBottomOf="@id/server_logo" app:layout_constraintBottom_toBottomOf="@id/server_logo"
app:layout_constraintStart_toEndOf="@id/server_logo"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
tools:text="Lucio Maciel"/> app:layout_constraintStart_toEndOf="@id/server_logo"
tools:text="Lucio Maciel" />
</android.support.constraint.ConstraintLayout> </android.support.constraint.ConstraintLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="?selectableItemBackground" > android:padding="16dp"
android:background="?selectableItemBackground">
<ImageView <ImageView
android:id="@+id/server_logo" android:id="@+id/server_logo"
android:layout_width="40dp" android:layout_width="40dp"
android:layout_height="40dp" android:layout_height="40dp"
android:layout_marginTop="8dp"
android:layout_marginStart="16dp"
android:layout_marginBottom="8dp"
android:src="@drawable/ic_add_24dp" android:src="@drawable/ic_add_24dp"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
...@@ -23,8 +19,7 @@ ...@@ -23,8 +19,7 @@
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="8dp" android:layout_marginStart="8dp"
android:layout_marginEnd="16dp" android:textAppearance="@style/TextAppearance.AppCompat.Body2"
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
android:text="@string/action_add_account" android:text="@string/action_add_account"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
......
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:divider="?android:dividerHorizontal"
android:orientation="vertical"
android:showDividers="end">
<TextView
android:id="@+id/text_online"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:layout_marginEnd="16dp"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:drawablePadding="10dp"
android:drawableStart="@drawable/ic_status_online_24dp"
android:text="@string/action_online" />
<TextView
android:id="@+id/text_away"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:layout_marginEnd="16dp"
android:layout_marginStart="16dp"
android:drawablePadding="10dp"
android:drawableStart="@drawable/ic_status_away_24dp"
android:text="@string/action_away" />
<TextView
android:id="@+id/text_busy"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:layout_marginEnd="16dp"
android:layout_marginStart="16dp"
android:drawablePadding="10dp"
android:drawableStart="@drawable/ic_status_busy_24dp"
android:text="@string/action_busy" />
<TextView
android:id="@+id/text_invisible"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:layout_marginEnd="16dp"
android:layout_marginStart="16dp"
android:drawablePadding="10dp"
android:drawableStart="@drawable/ic_status_invisible_24dp"
android:text="@string/action_invisible" />
</LinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
...@@ -11,11 +10,11 @@ ...@@ -11,11 +10,11 @@
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="0dp" android:layout_height="0dp"
android:foreground="@drawable/black_gradient" android:foreground="@drawable/black_gradient"
app:actualImageScaleType="centerCrop"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
app:actualImageScaleType="centerCrop"
tools:src="@tools:sample/backgrounds/scenic" /> tools:src="@tools:sample/backgrounds/scenic" />
<com.facebook.drawee.view.SimpleDraweeView <com.facebook.drawee.view.SimpleDraweeView
...@@ -33,50 +32,58 @@ ...@@ -33,50 +32,58 @@
android:id="@+id/account_container" android:id="@+id/account_container"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginStart="12dp"
android:layout_marginEnd="12dp"
android:layout_marginTop="16dp" android:layout_marginTop="16dp"
android:padding="4dp"
android:elevation="2dp"
android:background="?selectableItemBackground" android:background="?selectableItemBackground"
app:layout_constraintBottom_toBottomOf="parent" android:elevation="2dp"
app:layout_constraintStart_toStartOf="@+id/image_avatar" android:paddingBottom="4dp"
android:paddingEnd="12dp"
android:paddingStart="12dp"
android:paddingTop="4dp"
app:layout_constraintTop_toBottomOf="@+id/image_avatar"> app:layout_constraintTop_toBottomOf="@+id/image_avatar">
<ImageView
android:id="@+id/image_user_status"
android:layout_width="14dp"
android:layout_height="14dp"
android:src="@drawable/ic_status_online_24dp"
app:layout_constraintStart_toStartOf="parent" />
<TextView <TextView
android:id="@+id/text_name" android:id="@+id/text_user_name"
style="@style/Sender.Name.TextView"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginEnd="8dp" android:layout_marginEnd="10dp"
android:textAppearance="@style/TextAppearance.AppCompat.Medium" android:layout_marginStart="10dp"
android:textColor="@color/white" android:textColor="@color/white"
app:layout_constraintEnd_toStartOf="@+id/account_expand" app:layout_constraintBottom_toBottomOf="@+id/image_user_status"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toStartOf="@+id/image_account_expand"
app:layout_constraintStart_toEndOf="@+id/image_user_status"
app:layout_constraintTop_toTopOf="@+id/image_user_status"
tools:text="Lucio Maciel" /> tools:text="Lucio Maciel" />
<TextView <TextView
android:id="@+id/text_server" android:id="@+id/text_server_url"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginEnd="8dp" android:layout_marginEnd="10dp"
android:ellipsize="end"
android:maxLines="1"
android:textAppearance="@style/TextAppearance.AppCompat.Small" android:textAppearance="@style/TextAppearance.AppCompat.Small"
android:textColor="@color/white" android:textColor="@color/white"
app:layout_constraintEnd_toStartOf="@+id/account_expand" app:layout_constraintEnd_toStartOf="@+id/image_account_expand"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/text_name" app:layout_constraintTop_toBottomOf="@+id/text_user_name"
tools:text="https://open.rocket.chat" /> tools:text="https://open.rocket.chat" />
<ImageView <ImageView
android:id="@+id/account_expand" android:id="@+id/image_account_expand"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:src="@drawable/ic_expand_more_24dp" android:src="@drawable/ic_expand_more_24dp"
android:tint="@color/whitesmoke" android:tint="@color/white"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="@+id/text_server_url"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent" />
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout> </android.support.constraint.ConstraintLayout>
</android.support.constraint.ConstraintLayout> </android.support.constraint.ConstraintLayout>
\ No newline at end of file
...@@ -28,6 +28,10 @@ ...@@ -28,6 +28,10 @@
<string name="action_confirm_password">पासवर्ड परिवर्तन की पुष्टि करें</string> <string name="action_confirm_password">पासवर्ड परिवर्तन की पुष्टि करें</string>
<string name="action_join_chat">चैट में शामिल हों</string> <string name="action_join_chat">चैट में शामिल हों</string>
<string name="action_add_account">खाता जोड़ो</string> <string name="action_add_account">खाता जोड़ो</string>
<string name="action_online">ऑनलाइन</string>
<string name="action_away">दूर</string>
<string name="action_busy">व्यस्त</string>
<string name="action_invisible">अदृश्य</string>
<!-- Settings List --> <!-- Settings List -->
<string-array name="settings_actions"> <string-array name="settings_actions">
......
...@@ -27,7 +27,11 @@ ...@@ -27,7 +27,11 @@
<string name="action_files">Arquivos</string> <string name="action_files">Arquivos</string>
<string name="action_confirm_password">Confirme a nova senha</string> <string name="action_confirm_password">Confirme a nova senha</string>
<string name="action_join_chat">Entrar no Chat</string> <string name="action_join_chat">Entrar no Chat</string>
<string name="action_add_account">Adicionar Conta</string> <string name="action_add_account">Adicionar conta</string>
<string name="action_online">Online</string>
<string name="action_away">Ausente</string>
<string name="action_busy">Ocupado</string>
<string name="action_invisible">Invisível</string>
<!-- Settings List --> <!-- Settings List -->
<string-array name="settings_actions"> <string-array name="settings_actions">
...@@ -50,7 +54,7 @@ ...@@ -50,7 +54,7 @@
<string name="msg_new_user_agreement">Ao proceder você concorda com nossos %1$s e %2$s</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_2fa_code">Código 2FA</string>
<string name="msg_yesterday">ontem</string> <string name="msg_yesterday">ontem</string>
<string name="msg_message">Messagem</string> <string name="msg_message">Mensagem</string>
<string name="msg_this_room_is_read_only">Este chat é apenas de leitura</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> <string name="msg_invalid_2fa_code">Código 2FA inválido</string>
<string name="msg_invalid_file">Arquivo inválido</string> <string name="msg_invalid_file">Arquivo inválido</string>
......
...@@ -21,6 +21,8 @@ ...@@ -21,6 +21,8 @@
<dimen name="message_time_text_size">12sp</dimen> <dimen name="message_time_text_size">12sp</dimen>
<dimen name="nav_header_height">140dp</dimen>
<!-- Emoji --> <!-- Emoji -->
<dimen name="picker_padding_bottom">16dp</dimen> <dimen name="picker_padding_bottom">16dp</dimen>
<dimen name="supposed_keyboard_height">252dp</dimen> <dimen name="supposed_keyboard_height">252dp</dimen>
...@@ -35,6 +37,5 @@ ...@@ -35,6 +37,5 @@
<!-- Autocomplete Popup --> <!-- Autocomplete Popup -->
<dimen name="popup_max_height">150dp</dimen> <dimen name="popup_max_height">150dp</dimen>
<dimen name="suggestions_box_max_height">250dp</dimen> <dimen name="suggestions_box_max_height">250dp</dimen>
<dimen name="nav_header_height">160dp</dimen>
</resources> </resources>
\ No newline at end of file
...@@ -28,7 +28,11 @@ ...@@ -28,7 +28,11 @@
<string name="action_files">Files</string> <string name="action_files">Files</string>
<string name="action_confirm_password">Confirm Password Change</string> <string name="action_confirm_password">Confirm Password Change</string>
<string name="action_join_chat">Join Chat</string> <string name="action_join_chat">Join Chat</string>
<string name="action_add_account">Add Account</string> <string name="action_add_account">Add account</string>
<string name="action_online">Online</string>
<string name="action_away">Away</string>
<string name="action_busy">Busy</string>
<string name="action_invisible">Invisible</string>
<!-- Settings List --> <!-- Settings List -->
<string-array name="settings_actions"> <string-array name="settings_actions">
......
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