Unverified Commit 6d73aff8 authored by Filipe de Lima Brito's avatar Filipe de Lima Brito Committed by GitHub

Merge branch 'develop-2.x' into project/sdk-changes

parents d293407e 2e5639c0
...@@ -20,7 +20,9 @@ ...@@ -20,7 +20,9 @@
android:icon="@mipmap/ic_launcher" android:icon="@mipmap/ic_launcher"
android:label="@string/app_name" android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round" android:roundIcon="@mipmap/ic_launcher_round"
android:networkSecurityConfig="@xml/network_security_config">
android:supportsRtl="true"> android:supportsRtl="true">
<activity <activity
android:name=".authentication.ui.AuthenticationActivity" android:name=".authentication.ui.AuthenticationActivity"
android:configChanges="orientation" android:configChanges="orientation"
......
...@@ -86,85 +86,114 @@ class LoginFragment : Fragment(), LoginView { ...@@ -86,85 +86,114 @@ class LoginFragment : Fragment(), LoginView {
} }
private fun tintEditTextDrawableStart() { private fun tintEditTextDrawableStart() {
activity?.apply { ui {
val personDrawable = DrawableHelper.getDrawableFromId(R.drawable.ic_assignment_ind_black_24dp, this) val personDrawable = DrawableHelper.getDrawableFromId(R.drawable.ic_assignment_ind_black_24dp, it)
val lockDrawable = DrawableHelper.getDrawableFromId(R.drawable.ic_lock_black_24dp, this) val lockDrawable = DrawableHelper.getDrawableFromId(R.drawable.ic_lock_black_24dp, it)
val drawables = arrayOf(personDrawable, lockDrawable) val drawables = arrayOf(personDrawable, lockDrawable)
DrawableHelper.wrapDrawables(drawables) DrawableHelper.wrapDrawables(drawables)
DrawableHelper.tintDrawables(drawables, this, R.color.colorDrawableTintGrey) DrawableHelper.tintDrawables(drawables, it, R.color.colorDrawableTintGrey)
DrawableHelper.compoundDrawables(arrayOf(text_username_or_email, text_password), drawables) DrawableHelper.compoundDrawables(arrayOf(text_username_or_email, text_password), drawables)
} }
} }
override fun showLoading() { override fun showLoading() {
ui {
view_loading.setVisible(true) view_loading.setVisible(true)
} }
}
override fun hideLoading() { override fun hideLoading() {
ui {
view_loading.setVisible(false) view_loading.setVisible(false)
} }
}
override fun showMessage(resId: Int) { override fun showMessage(resId: Int) {
ui {
showToast(resId) showToast(resId)
} }
}
override fun showMessage(message: String) { override fun showMessage(message: String) {
ui {
showToast(message) showToast(message)
} }
}
override fun showGenericErrorMessage() { override fun showGenericErrorMessage() {
showMessage(R.string.msg_generic_error) showMessage(R.string.msg_generic_error)
} }
override fun showFormView() { override fun showFormView() {
ui {
text_username_or_email.setVisible(true) text_username_or_email.setVisible(true)
text_password.setVisible(true) text_password.setVisible(true)
} }
}
override fun hideFormView() { override fun hideFormView() {
ui {
text_username_or_email.setVisible(false) text_username_or_email.setVisible(false)
text_password.setVisible(false) text_password.setVisible(false)
} }
}
override fun setupLoginButtonListener() { override fun setupLoginButtonListener() {
ui {
button_log_in.setOnClickListener { button_log_in.setOnClickListener {
presenter.authenticateWithUserAndPassword(text_username_or_email.textContent, text_password.textContent) presenter.authenticateWithUserAndPassword(text_username_or_email.textContent,
text_password.textContent)
}
} }
} }
override fun enableUserInput() { override fun enableUserInput() {
ui {
button_log_in.isEnabled = true button_log_in.isEnabled = true
text_username_or_email.isEnabled = true text_username_or_email.isEnabled = true
text_password.isEnabled = true text_password.isEnabled = true
} }
}
override fun disableUserInput() { override fun disableUserInput() {
ui {
button_log_in.isEnabled = false button_log_in.isEnabled = false
text_username_or_email.isEnabled = false text_username_or_email.isEnabled = false
text_password.isEnabled = false text_password.isEnabled = false
} }
}
override fun showCasButton() { override fun showCasButton() {
ui {
button_cas.setVisible(true) button_cas.setVisible(true)
} }
}
override fun hideCasButton() { override fun hideCasButton() {
ui {
button_cas.setVisible(false) button_cas.setVisible(false)
} }
}
override fun setupCasButtonListener(casUrl: String, casToken: String) { override fun setupCasButtonListener(casUrl: String, casToken: String) {
ui { activity ->
button_cas.setOnClickListener { button_cas.setOnClickListener {
startActivityForResult(context?.casWebViewIntent(casUrl, casToken), REQUEST_CODE_FOR_CAS) startActivityForResult(activity.casWebViewIntent(casUrl, casToken),
activity?.overridePendingTransition(R.anim.slide_up, R.anim.hold) REQUEST_CODE_FOR_CAS)
activity.overridePendingTransition(R.anim.slide_up, R.anim.hold)
}
} }
} }
override fun showSignUpView() { override fun showSignUpView() {
ui {
text_new_to_rocket_chat.setVisible(true) text_new_to_rocket_chat.setVisible(true)
} }
}
override fun setupSignUpView() { override fun setupSignUpView() {
ui {
val signUp = getString(R.string.title_sign_up) val signUp = getString(R.string.title_sign_up)
val newToRocketChat = String.format(getString(R.string.msg_new_user), signUp) val newToRocketChat = String.format(getString(R.string.msg_new_user), signUp)
...@@ -176,88 +205,122 @@ class LoginFragment : Fragment(), LoginView { ...@@ -176,88 +205,122 @@ class LoginFragment : Fragment(), LoginView {
TextHelper.addLink(text_new_to_rocket_chat, arrayOf(signUp), arrayOf(signUpListener)) TextHelper.addLink(text_new_to_rocket_chat, arrayOf(signUp), arrayOf(signUpListener))
} }
}
override fun hideSignUpView() { override fun hideSignUpView() {
ui {
text_new_to_rocket_chat.setVisible(false) text_new_to_rocket_chat.setVisible(false)
} }
}
override fun enableOauthView() { override fun enableOauthView() {
ui {
isOauthViewEnable = true isOauthViewEnable = true
showThreeSocialAccountsMethods() showThreeSocialAccountsMethods()
social_accounts_container.setVisible(true) social_accounts_container.setVisible(true)
} }
}
override fun disableOauthView() { override fun disableOauthView() {
ui {
isOauthViewEnable = false isOauthViewEnable = false
social_accounts_container.setVisible(false) social_accounts_container.setVisible(false)
} }
}
override fun showLoginButton() { override fun showLoginButton() {
ui {
button_log_in.setVisible(true) button_log_in.setVisible(true)
} }
}
override fun hideLoginButton() { override fun hideLoginButton() {
ui {
button_log_in.setVisible(false) button_log_in.setVisible(false)
} }
}
override fun enableLoginByFacebook() { override fun enableLoginByFacebook() {
ui {
button_facebook.isClickable = true button_facebook.isClickable = true
} }
}
override fun enableLoginByGithub() { override fun enableLoginByGithub() {
ui {
button_github.isClickable = true button_github.isClickable = true
} }
}
override fun setupGithubButtonListener(githubUrl: String, state: String) { override fun setupGithubButtonListener(githubUrl: String, state: String) {
ui { activity ->
button_github.setOnClickListener { button_github.setOnClickListener {
startActivityForResult(context?.oauthWebViewIntent(githubUrl, state), REQUEST_CODE_FOR_OAUTH) startActivityForResult(activity.oauthWebViewIntent(githubUrl, state), REQUEST_CODE_FOR_OAUTH)
activity?.overridePendingTransition(R.anim.slide_up, R.anim.hold) activity.overridePendingTransition(R.anim.slide_up, R.anim.hold)
}
} }
} }
override fun enableLoginByGoogle() { override fun enableLoginByGoogle() {
ui {
button_google.isClickable = true button_google.isClickable = true
} }
}
// TODO: Use custom tabs instead of web view. See https://github.com/RocketChat/Rocket.Chat.Android/issues/968 // TODO: Use custom tabs instead of web view. See https://github.com/RocketChat/Rocket.Chat.Android/issues/968
override fun setupGoogleButtonListener(googleUrl: String, state: String) { override fun setupGoogleButtonListener(googleUrl: String, state: String) {
ui { activity ->
button_google.setOnClickListener { button_google.setOnClickListener {
startActivityForResult(context?.oauthWebViewIntent(googleUrl, state), REQUEST_CODE_FOR_OAUTH) startActivityForResult(activity.oauthWebViewIntent(googleUrl, state), REQUEST_CODE_FOR_OAUTH)
activity?.overridePendingTransition(R.anim.slide_up, R.anim.hold) activity.overridePendingTransition(R.anim.slide_up, R.anim.hold)
}
} }
} }
override fun enableLoginByLinkedin() { override fun enableLoginByLinkedin() {
ui {
button_linkedin.isClickable = true button_linkedin.isClickable = true
} }
}
override fun setupLinkedinButtonListener(linkedinUrl: String, state: String) { override fun setupLinkedinButtonListener(linkedinUrl: String, state: String) {
ui { activity ->
button_linkedin.setOnClickListener { button_linkedin.setOnClickListener {
startActivityForResult(context?.oauthWebViewIntent(linkedinUrl, state), REQUEST_CODE_FOR_OAUTH) startActivityForResult(activity.oauthWebViewIntent(linkedinUrl, state), REQUEST_CODE_FOR_OAUTH)
activity?.overridePendingTransition(R.anim.slide_up, R.anim.hold) activity.overridePendingTransition(R.anim.slide_up, R.anim.hold)
}
} }
} }
override fun enableLoginByMeteor() { override fun enableLoginByMeteor() {
ui {
button_meteor.isClickable = true button_meteor.isClickable = true
} }
}
override fun enableLoginByTwitter() { override fun enableLoginByTwitter() {
ui {
button_twitter.isClickable = true button_twitter.isClickable = true
} }
}
override fun enableLoginByGitlab() { override fun enableLoginByGitlab() {
ui {
button_gitlab.isClickable = true button_gitlab.isClickable = true
} }
}
override fun setupGitlabButtonListener(gitlabUrl: String, state: String) { override fun setupGitlabButtonListener(gitlabUrl: String, state: String) {
ui { activity ->
button_gitlab.setOnClickListener { button_gitlab.setOnClickListener {
startActivityForResult(context?.oauthWebViewIntent(gitlabUrl, state), REQUEST_CODE_FOR_OAUTH) startActivityForResult(activity.oauthWebViewIntent(gitlabUrl, state), REQUEST_CODE_FOR_OAUTH)
activity?.overridePendingTransition(R.anim.slide_up, R.anim.hold) activity.overridePendingTransition(R.anim.slide_up, R.anim.hold)
}
} }
} }
override fun setupFabListener() { override fun setupFabListener() {
ui {
button_fab.setVisible(true) button_fab.setVisible(true)
button_fab.setOnClickListener({ button_fab.setOnClickListener({
button_fab.hide() button_fab.hide()
...@@ -265,6 +328,7 @@ class LoginFragment : Fragment(), LoginView { ...@@ -265,6 +328,7 @@ class LoginFragment : Fragment(), LoginView {
scrollToBottom() scrollToBottom()
}) })
} }
}
override fun setupGlobalListener() { override fun setupGlobalListener() {
// We need to setup the layout to hide and show the oauth interface when the soft keyboard is shown // We need to setup the layout to hide and show the oauth interface when the soft keyboard is shown
...@@ -276,19 +340,23 @@ class LoginFragment : Fragment(), LoginView { ...@@ -276,19 +340,23 @@ class LoginFragment : Fragment(), LoginView {
} }
override fun alertWrongUsernameOrEmail() { override fun alertWrongUsernameOrEmail() {
ui {
vibrateSmartPhone() vibrateSmartPhone()
text_username_or_email.shake() text_username_or_email.shake()
text_username_or_email.requestFocus() text_username_or_email.requestFocus()
} }
}
override fun alertWrongPassword() { override fun alertWrongPassword() {
ui {
vibrateSmartPhone() vibrateSmartPhone()
text_password.shake() text_password.shake()
text_password.requestFocus() text_password.requestFocus()
} }
}
override fun alertNotRecommendedVersion() { override fun alertNotRecommendedVersion() {
context?.let { ui {
AlertDialog.Builder(it) AlertDialog.Builder(it)
.setMessage(getString(R.string.msg_ver_not_recommended, BuildConfig.RECOMMENDED_SERVER_VERSION)) .setMessage(getString(R.string.msg_ver_not_recommended, BuildConfig.RECOMMENDED_SERVER_VERSION))
.setPositiveButton(R.string.msg_ok, null) .setPositiveButton(R.string.msg_ok, null)
...@@ -298,7 +366,7 @@ class LoginFragment : Fragment(), LoginView { ...@@ -298,7 +366,7 @@ class LoginFragment : Fragment(), LoginView {
} }
override fun blockAndAlertNotRequiredVersion() { override fun blockAndAlertNotRequiredVersion() {
context?.let { ui {
AlertDialog.Builder(it) AlertDialog.Builder(it)
.setMessage(getString(R.string.msg_ver_not_minimum, BuildConfig.REQUIRED_SERVER_VERSION)) .setMessage(getString(R.string.msg_ver_not_minimum, BuildConfig.REQUIRED_SERVER_VERSION))
.setOnDismissListener { activity?.onBackPressed() } .setOnDismissListener { activity?.onBackPressed() }
...@@ -313,14 +381,14 @@ class LoginFragment : Fragment(), LoginView { ...@@ -313,14 +381,14 @@ class LoginFragment : Fragment(), LoginView {
(0..social_accounts_container.childCount) (0..social_accounts_container.childCount)
.mapNotNull { social_accounts_container.getChildAt(it) as? ImageButton } .mapNotNull { social_accounts_container.getChildAt(it) as? ImageButton }
.filter { it.isClickable } .filter { it.isClickable }
.forEach { it.setVisible(true)} .forEach { ui { it.setVisible(true) }}
}, 1000) }, 1000)
} }
// Scrolling to the bottom of the screen. // Scrolling to the bottom of the screen.
private fun scrollToBottom() { private fun scrollToBottom() {
scroll_view.postDelayed({ scroll_view.postDelayed({
scroll_view.fullScroll(ScrollView.FOCUS_DOWN) ui { scroll_view.fullScroll(ScrollView.FOCUS_DOWN) }
}, 1250) }, 1250)
} }
...@@ -350,13 +418,13 @@ class LoginFragment : Fragment(), LoginView { ...@@ -350,13 +418,13 @@ class LoginFragment : Fragment(), LoginView {
.forEach { it.setVisible(true) } .forEach { it.setVisible(true) }
} }
fun showOauthView() { private fun showOauthView() {
if (isOauthViewEnable) { if (isOauthViewEnable) {
social_accounts_container.setVisible(true) social_accounts_container.setVisible(true)
} }
} }
fun hideOauthView() { private fun hideOauthView() {
if (isOauthViewEnable) { if (isOauthViewEnable) {
social_accounts_container.setVisible(false) social_accounts_container.setVisible(false)
button_fab.setVisible(false) button_fab.setVisible(false)
......
...@@ -59,37 +59,47 @@ class RegisterUsernameFragment : Fragment(), RegisterUsernameView { ...@@ -59,37 +59,47 @@ class RegisterUsernameFragment : Fragment(), RegisterUsernameView {
} }
override fun alertBlankUsername() { override fun alertBlankUsername() {
ui {
vibrateSmartPhone() vibrateSmartPhone()
text_username.shake() text_username.shake()
} }
}
override fun showLoading() { override fun showLoading() {
ui {
disableUserInput() disableUserInput()
view_loading.setVisible(true) view_loading.setVisible(true)
} }
}
override fun hideLoading() { override fun hideLoading() {
ui {
view_loading.setVisible(false) view_loading.setVisible(false)
enableUserInput() enableUserInput()
} }
}
override fun showMessage(resId: Int) { override fun showMessage(resId: Int) {
ui {
showToast(resId) showToast(resId)
} }
}
override fun showMessage(message: String) { override fun showMessage(message: String) {
ui {
showToast(message) showToast(message)
} }
}
override fun showGenericErrorMessage() { override fun showGenericErrorMessage() {
showMessage(getString(R.string.msg_generic_error)) showMessage(getString(R.string.msg_generic_error))
} }
private fun tintEditTextDrawableStart() { private fun tintEditTextDrawableStart() {
activity?.apply { ui {
val atDrawable = DrawableHelper.getDrawableFromId(R.drawable.ic_at_black_24dp, this) val atDrawable = DrawableHelper.getDrawableFromId(R.drawable.ic_at_black_24dp, it)
DrawableHelper.wrapDrawable(atDrawable) DrawableHelper.wrapDrawable(atDrawable)
DrawableHelper.tintDrawable(atDrawable, this, R.color.colorDrawableTintGrey) DrawableHelper.tintDrawable(atDrawable, it, R.color.colorDrawableTintGrey)
DrawableHelper.compoundDrawable(text_username, atDrawable) DrawableHelper.compoundDrawable(text_username, atDrawable)
} }
} }
......
...@@ -47,22 +47,30 @@ class ServerFragment : Fragment(), ServerView { ...@@ -47,22 +47,30 @@ class ServerFragment : Fragment(), ServerView {
override fun showInvalidServerUrlMessage() = showMessage(getString(R.string.msg_invalid_server_url)) override fun showInvalidServerUrlMessage() = showMessage(getString(R.string.msg_invalid_server_url))
override fun showLoading() { override fun showLoading() {
ui {
enableUserInput(false) enableUserInput(false)
view_loading.setVisible(true) view_loading.setVisible(true)
} }
}
override fun hideLoading() { override fun hideLoading() {
ui {
view_loading.setVisible(false) view_loading.setVisible(false)
enableUserInput(true) enableUserInput(true)
} }
}
override fun showMessage(resId: Int){ override fun showMessage(resId: Int){
ui {
showToast(resId) showToast(resId)
} }
}
override fun showMessage(message: String) { override fun showMessage(message: String) {
ui {
showToast(message) showToast(message)
} }
}
override fun showGenericErrorMessage() { override fun showGenericErrorMessage() {
showMessage(getString(R.string.msg_generic_error)) showMessage(getString(R.string.msg_generic_error))
......
...@@ -25,7 +25,7 @@ class SignupFragment : Fragment(), SignupView { ...@@ -25,7 +25,7 @@ class SignupFragment : Fragment(), SignupView {
} else { } else {
bottom_container.apply { bottom_container.apply {
postDelayed({ postDelayed({
setVisible(true) ui { setVisible(true) }
}, 3) }, 3)
} }
} }
...@@ -64,61 +64,77 @@ class SignupFragment : Fragment(), SignupView { ...@@ -64,61 +64,77 @@ class SignupFragment : Fragment(), SignupView {
} }
override fun alertBlankName() { override fun alertBlankName() {
ui {
vibrateSmartPhone() vibrateSmartPhone()
text_name.shake() text_name.shake()
text_name.requestFocus() text_name.requestFocus()
} }
}
override fun alertBlankUsername() { override fun alertBlankUsername() {
ui {
vibrateSmartPhone() vibrateSmartPhone()
text_username.shake() text_username.shake()
text_username.requestFocus() text_username.requestFocus()
} }
}
override fun alertEmptyPassword() { override fun alertEmptyPassword() {
ui {
vibrateSmartPhone() vibrateSmartPhone()
text_password.shake() text_password.shake()
text_password.requestFocus() text_password.requestFocus()
} }
}
override fun alertBlankEmail() { override fun alertBlankEmail() {
ui {
vibrateSmartPhone() vibrateSmartPhone()
text_email.shake() text_email.shake()
text_email.requestFocus() text_email.requestFocus()
} }
}
override fun showLoading() { override fun showLoading() {
ui {
enableUserInput(false) enableUserInput(false)
view_loading.setVisible(true) view_loading.setVisible(true)
} }
}
override fun hideLoading() { override fun hideLoading() {
ui {
view_loading.setVisible(false) view_loading.setVisible(false)
enableUserInput(true) enableUserInput(true)
} }
}
override fun showMessage(resId: Int) { override fun showMessage(resId: Int) {
ui {
showToast(resId) showToast(resId)
} }
}
override fun showMessage(message: String) { override fun showMessage(message: String) {
ui {
showToast(message) showToast(message)
} }
}
override fun showGenericErrorMessage() { override fun showGenericErrorMessage() {
showMessage(getString(R.string.msg_generic_error)) showMessage(getString(R.string.msg_generic_error))
} }
private fun tintEditTextDrawableStart() { private fun tintEditTextDrawableStart() {
activity?.apply { ui {
val personDrawable = DrawableHelper.getDrawableFromId(R.drawable.ic_person_black_24dp, this) val personDrawable = DrawableHelper.getDrawableFromId(R.drawable.ic_person_black_24dp, it)
val atDrawable = DrawableHelper.getDrawableFromId(R.drawable.ic_at_black_24dp, this) val atDrawable = DrawableHelper.getDrawableFromId(R.drawable.ic_at_black_24dp, it)
val lockDrawable = DrawableHelper.getDrawableFromId(R.drawable.ic_lock_black_24dp, this) val lockDrawable = DrawableHelper.getDrawableFromId(R.drawable.ic_lock_black_24dp, it)
val emailDrawable = DrawableHelper.getDrawableFromId(R.drawable.ic_email_black_24dp, this) val emailDrawable = DrawableHelper.getDrawableFromId(R.drawable.ic_email_black_24dp, it)
val drawables = arrayOf(personDrawable, atDrawable, lockDrawable, emailDrawable) val drawables = arrayOf(personDrawable, atDrawable, lockDrawable, emailDrawable)
DrawableHelper.wrapDrawables(drawables) DrawableHelper.wrapDrawables(drawables)
DrawableHelper.tintDrawables(drawables, this, R.color.colorDrawableTintGrey) DrawableHelper.tintDrawables(drawables, it, R.color.colorDrawableTintGrey)
DrawableHelper.compoundDrawables(arrayOf(text_name, text_username, text_password, text_email), drawables) DrawableHelper.compoundDrawables(arrayOf(text_name, text_username, text_password, text_email), drawables)
} }
} }
......
...@@ -63,39 +63,49 @@ class TwoFAFragment : Fragment(), TwoFAView { ...@@ -63,39 +63,49 @@ class TwoFAFragment : Fragment(), TwoFAView {
} }
override fun alertBlankTwoFactorAuthenticationCode() { override fun alertBlankTwoFactorAuthenticationCode() {
ui {
vibrateSmartPhone() vibrateSmartPhone()
text_two_factor_auth.shake() text_two_factor_auth.shake()
} }
}
override fun alertInvalidTwoFactorAuthenticationCode() { override fun alertInvalidTwoFactorAuthenticationCode() {
showMessage(getString(R.string.msg_invalid_2fa_code)) showMessage(getString(R.string.msg_invalid_2fa_code))
} }
override fun showLoading() { override fun showLoading() {
ui {
enableUserInput(false) enableUserInput(false)
view_loading.setVisible(true) view_loading.setVisible(true)
} }
}
override fun hideLoading() { override fun hideLoading() {
ui {
view_loading.setVisible(false) view_loading.setVisible(false)
enableUserInput(true) enableUserInput(true)
} }
}
override fun showMessage(resId: Int) { override fun showMessage(resId: Int) {
ui {
showToast(resId) showToast(resId)
} }
}
override fun showMessage(message: String) { override fun showMessage(message: String) {
ui {
showToast(message) showToast(message)
} }
}
override fun showGenericErrorMessage() = showMessage(getString(R.string.msg_generic_error)) override fun showGenericErrorMessage() = showMessage(getString(R.string.msg_generic_error))
private fun tintEditTextDrawableStart() { private fun tintEditTextDrawableStart() {
activity?.apply { ui {
val lockDrawable = DrawableHelper.getDrawableFromId(R.drawable.ic_vpn_key_black_24dp, this) val lockDrawable = DrawableHelper.getDrawableFromId(R.drawable.ic_vpn_key_black_24dp, it)
DrawableHelper.wrapDrawable(lockDrawable) DrawableHelper.wrapDrawable(lockDrawable)
DrawableHelper.tintDrawable(lockDrawable, this, R.color.colorDrawableTintGrey) DrawableHelper.tintDrawable(lockDrawable, it, R.color.colorDrawableTintGrey)
DrawableHelper.compoundDrawable(text_two_factor_auth, lockDrawable) DrawableHelper.compoundDrawable(text_two_factor_auth, lockDrawable)
} }
} }
......
...@@ -18,6 +18,7 @@ import android.support.v7.widget.DefaultItemAnimator ...@@ -18,6 +18,7 @@ import android.support.v7.widget.DefaultItemAnimator
import android.support.v7.widget.LinearLayoutManager import android.support.v7.widget.LinearLayoutManager
import android.support.v7.widget.RecyclerView import android.support.v7.widget.RecyclerView
import android.view.* import android.view.*
import androidx.core.content.systemService
import chat.rocket.android.R import chat.rocket.android.R
import chat.rocket.android.chatroom.adapter.* import chat.rocket.android.chatroom.adapter.*
import chat.rocket.android.chatroom.presentation.ChatRoomPresenter import chat.rocket.android.chatroom.presentation.ChatRoomPresenter
...@@ -182,6 +183,7 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR ...@@ -182,6 +183,7 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
} }
override fun showMessages(dataSet: List<BaseViewModel<*>>) { override fun showMessages(dataSet: List<BaseViewModel<*>>) {
ui {
// track the message sent immediately after the current message // track the message sent immediately after the current message
var prevMessageViewModel: MessageViewModel? = null var prevMessageViewModel: MessageViewModel? = null
...@@ -203,7 +205,6 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR ...@@ -203,7 +205,6 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
} }
} }
activity?.apply {
if (recycler_view.adapter == null) { if (recycler_view.adapter == null) {
adapter = ChatRoomAdapter(chatRoomType, chatRoomName, presenter, adapter = ChatRoomAdapter(chatRoomType, chatRoomName, presenter,
reactionListener = this@ChatRoomFragment) reactionListener = this@ChatRoomFragment)
...@@ -281,6 +282,7 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR ...@@ -281,6 +282,7 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
} }
override fun sendMessage(text: String) { override fun sendMessage(text: String) {
ui {
if (!text.isBlank()) { if (!text.isBlank()) {
if (!text.startsWith("/")) { if (!text.startsWith("/")) {
presenter.sendMessage(chatRoomId, text, editingMessageId) presenter.sendMessage(chatRoomId, text, editingMessageId)
...@@ -289,6 +291,7 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR ...@@ -289,6 +291,7 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
} }
} }
} }
}
override fun uploadFile(uri: Uri) { override fun uploadFile(uri: Uri) {
// TODO Just leaving a blank message that comes with the file for now. In the future lets add the possibility to add a message with the file to be uploaded. // TODO Just leaving a blank message that comes with the file for now. In the future lets add the possibility to add a message with the file to be uploaded.
...@@ -300,43 +303,55 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR ...@@ -300,43 +303,55 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
} }
override fun showNewMessage(message: List<BaseViewModel<*>>) { override fun showNewMessage(message: List<BaseViewModel<*>>) {
ui {
adapter.prependData(message) adapter.prependData(message)
recycler_view.scrollToPosition(0) recycler_view.scrollToPosition(0)
verticalScrollOffset.set(0) verticalScrollOffset.set(0)
} }
}
override fun disableSendMessageButton() { override fun disableSendMessageButton() {
ui {
button_send.isEnabled = false button_send.isEnabled = false
} }
}
override fun enableSendMessageButton(sendFailed: Boolean) { override fun enableSendMessageButton(sendFailed: Boolean) {
ui {
button_send.isEnabled = true button_send.isEnabled = true
text_message.isEnabled = true text_message.isEnabled = true
if (!sendFailed) { if (!sendFailed) {
clearMessageComposition() clearMessageComposition()
} }
} }
}
override fun clearMessageComposition() { override fun clearMessageComposition() {
ui {
citation = null citation = null
editingMessageId = null editingMessageId = null
text_message.textContent = "" text_message.textContent = ""
actionSnackbar.dismiss() actionSnackbar.dismiss()
} }
}
override fun dispatchUpdateMessage(index: Int, message: List<BaseViewModel<*>>) { override fun dispatchUpdateMessage(index: Int, message: List<BaseViewModel<*>>) {
ui {
adapter.updateItem(message.last()) adapter.updateItem(message.last())
if (message.size > 1) { if (message.size > 1) {
adapter.prependData(listOf(message.first())) adapter.prependData(listOf(message.first()))
} }
} }
}
override fun dispatchDeleteMessage(msgId: String) { override fun dispatchDeleteMessage(msgId: String) {
ui {
adapter.removeItem(msgId) adapter.removeItem(msgId)
} }
}
override fun showReplyingAction(username: String, replyMarkdown: String, quotedMessage: String) { override fun showReplyingAction(username: String, replyMarkdown: String, quotedMessage: String) {
activity?.apply { ui {
citation = replyMarkdown citation = replyMarkdown
actionSnackbar.title = username actionSnackbar.title = username
actionSnackbar.text = quotedMessage actionSnackbar.text = quotedMessage
...@@ -351,41 +366,55 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR ...@@ -351,41 +366,55 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
} }
} }
override fun showLoading() = view_loading.setVisible(true) override fun showLoading() {
ui { view_loading.setVisible(true) }
}
override fun hideLoading() = view_loading.setVisible(false) override fun hideLoading() {
ui { view_loading.setVisible(false) }
}
override fun showMessage(message: String) { override fun showMessage(message: String) {
ui {
showToast(message) showToast(message)
} }
}
override fun showMessage(resId: Int) { override fun showMessage(resId: Int) {
ui {
showToast(resId) showToast(resId)
} }
}
override fun showGenericErrorMessage() = showMessage(getString(R.string.msg_generic_error)) override fun showGenericErrorMessage() = showMessage(getString(R.string.msg_generic_error))
override fun populatePeopleSuggestions(members: List<PeopleSuggestionViewModel>) { override fun populatePeopleSuggestions(members: List<PeopleSuggestionViewModel>) {
ui {
suggestions_view.addItems("@", members) suggestions_view.addItems("@", members)
} }
}
override fun populateRoomSuggestions(chatRooms: List<ChatRoomSuggestionViewModel>) { override fun populateRoomSuggestions(chatRooms: List<ChatRoomSuggestionViewModel>) {
ui {
suggestions_view.addItems("#", chatRooms) suggestions_view.addItems("#", chatRooms)
} }
}
override fun populateCommandSuggestions(commands: List<CommandSuggestionViewModel>) { override fun populateCommandSuggestions(commands: List<CommandSuggestionViewModel>) {
ui {
suggestions_view.addItems("/", commands) suggestions_view.addItems("/", commands)
} }
}
override fun copyToClipboard(message: String) { override fun copyToClipboard(message: String) {
activity?.apply { ui {
val clipboard = getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager val clipboard: ClipboardManager = it.systemService()
clipboard.primaryClip = ClipData.newPlainText("", message) clipboard.primaryClip = ClipData.newPlainText("", message)
} }
} }
override fun showEditingAction(roomId: String, messageId: String, text: String) { override fun showEditingAction(roomId: String, messageId: String, text: String) {
activity?.apply { ui {
actionSnackbar.title = getString(R.string.action_title_editing) actionSnackbar.title = getString(R.string.action_title_editing)
actionSnackbar.text = text actionSnackbar.text = text
actionSnackbar.show() actionSnackbar.show()
...@@ -421,7 +450,7 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR ...@@ -421,7 +450,7 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
} }
override fun showReactionsPopup(messageId: String) { override fun showReactionsPopup(messageId: String) {
context?.let { ui {
val emojiPickerPopup = EmojiPickerPopup(it) val emojiPickerPopup = EmojiPickerPopup(it)
emojiPickerPopup.listener = object : EmojiListenerAdapter() { emojiPickerPopup.listener = object : EmojiListenerAdapter() {
override fun onEmojiAdded(emoji: Emoji) { override fun onEmojiAdded(emoji: Emoji) {
...@@ -434,11 +463,11 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR ...@@ -434,11 +463,11 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
private fun setReactionButtonIcon(@DrawableRes drawableId: Int) { private fun setReactionButtonIcon(@DrawableRes drawableId: Int) {
button_add_reaction.setImageResource(drawableId) button_add_reaction.setImageResource(drawableId)
button_add_reaction.setTag(drawableId) button_add_reaction.tag = drawableId
} }
override fun showFileSelection(filter: Array<String>) { override fun showFileSelection(filter: Array<String>) {
activity?.let { ui {
if (ContextCompat.checkSelfPermission(it, Manifest.permission.READ_EXTERNAL_STORAGE) if (ContextCompat.checkSelfPermission(it, Manifest.permission.READ_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) { != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(it, ActivityCompat.requestPermissions(it,
...@@ -458,7 +487,7 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR ...@@ -458,7 +487,7 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
1 -> { 1 -> {
if (!(grantResults.isNotEmpty() && grantResults.first() == PackageManager.PERMISSION_GRANTED)) { if (!(grantResults.isNotEmpty() && grantResults.first() == PackageManager.PERMISSION_GRANTED)) {
handler.postDelayed({ handler.postDelayed({
hideAttachmentOptions() ui { hideAttachmentOptions() }
}, 400) }, 400)
} }
} }
...@@ -470,7 +499,7 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR ...@@ -470,7 +499,7 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
} }
override fun showConnectionState(state: State) { override fun showConnectionState(state: State) {
activity?.apply { ui {
connection_status_text.fadeIn() connection_status_text.fadeIn()
handler.removeCallbacks(dismissStatus) handler.removeCallbacks(dismissStatus)
when (state) { when (state) {
...@@ -488,11 +517,13 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR ...@@ -488,11 +517,13 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
} }
override fun onJoined() { override fun onJoined() {
ui {
input_container.setVisible(true) input_container.setVisible(true)
button_join_chat.setVisible(false) button_join_chat.setVisible(false)
isSubscribed = true isSubscribed = true
setupMessageComposer() setupMessageComposer()
} }
}
private val dismissStatus = { private val dismissStatus = {
connection_status_text.fadeOut() connection_status_text.fadeOut()
......
...@@ -16,6 +16,7 @@ import chat.rocket.android.chatroom.viewmodel.BaseViewModel ...@@ -16,6 +16,7 @@ import chat.rocket.android.chatroom.viewmodel.BaseViewModel
import chat.rocket.android.helper.EndlessRecyclerViewScrollListener import chat.rocket.android.helper.EndlessRecyclerViewScrollListener
import chat.rocket.android.util.extensions.setVisible import chat.rocket.android.util.extensions.setVisible
import chat.rocket.android.util.extensions.showToast import chat.rocket.android.util.extensions.showToast
import chat.rocket.android.util.extensions.ui
import dagger.android.support.AndroidSupportInjection import dagger.android.support.AndroidSupportInjection
import kotlinx.android.synthetic.main.fragment_pinned_messages.* import kotlinx.android.synthetic.main.fragment_pinned_messages.*
import javax.inject.Inject import javax.inject.Inject
...@@ -62,22 +63,30 @@ class PinnedMessagesFragment : Fragment(), PinnedMessagesView { ...@@ -62,22 +63,30 @@ class PinnedMessagesFragment : Fragment(), PinnedMessagesView {
presenter.loadPinnedMessages(chatRoomId) presenter.loadPinnedMessages(chatRoomId)
} }
override fun showLoading() = view_loading.setVisible(true) override fun showLoading() {
ui { view_loading.setVisible(true) }
}
override fun hideLoading() = view_loading.setVisible(false) override fun hideLoading() {
ui { view_loading.setVisible(false) }
}
override fun showMessage(resId: Int) { override fun showMessage(resId: Int) {
ui {
showToast(resId) showToast(resId)
} }
}
override fun showMessage(message: String) { override fun showMessage(message: String) {
ui {
showToast(message) showToast(message)
} }
}
override fun showGenericErrorMessage() = showMessage(getString(R.string.msg_generic_error)) override fun showGenericErrorMessage() = showMessage(getString(R.string.msg_generic_error))
override fun showPinnedMessages(pinnedMessages: List<BaseViewModel<*>>) { override fun showPinnedMessages(pinnedMessages: List<BaseViewModel<*>>) {
activity?.apply { ui {
if (recycler_view_pinned.adapter == null) { if (recycler_view_pinned.adapter == null) {
// TODO - add a better constructor for this case... // TODO - add a better constructor for this case...
adapter = ChatRoomAdapter(chatRoomType, chatRoomName, null, false) adapter = ChatRoomAdapter(chatRoomType, chatRoomName, null, false)
...@@ -92,9 +101,22 @@ class PinnedMessagesFragment : Fragment(), PinnedMessagesView { ...@@ -92,9 +101,22 @@ class PinnedMessagesFragment : Fragment(), PinnedMessagesView {
} }
}) })
} }
togglePinView(pinnedMessages.size)
} }
adapter.appendData(pinnedMessages) adapter.appendData(pinnedMessages)
} }
} }
private fun togglePinView(size: Int) {
if (size == 0){
iv_pin_icon.setVisible(true)
tv_pin_title.setVisible(true)
tv_pin_description.setVisible(true)
}else{
iv_pin_icon.setVisible(false)
tv_pin_title.setVisible(false)
tv_pin_description.setVisible(false)
}
}
} }
\ No newline at end of file
...@@ -270,6 +270,7 @@ class ChatRoomsPresenter @Inject constructor(private val view: ChatRoomsView, ...@@ -270,6 +270,7 @@ class ChatRoomsPresenter @Inject constructor(private val view: ChatRoomsView,
// TODO - Temporary stuff, remove when adding DB support // TODO - Temporary stuff, remove when adding DB support
private suspend fun subscribeRoomUpdates() { private suspend fun subscribeRoomUpdates() {
manager.addStatusChannel(stateChannel) manager.addStatusChannel(stateChannel)
view.showConnectionState(client.state)
manager.addRoomsAndSubscriptionsChannel(subscriptionsChannel) manager.addRoomsAndSubscriptionsChannel(subscriptionsChannel)
launch(CommonPool + strategy.jobs) { launch(CommonPool + strategy.jobs) {
for (message in subscriptionsChannel) { for (message in subscriptionsChannel) {
......
...@@ -24,7 +24,6 @@ import chat.rocket.android.util.extensions.textContent ...@@ -24,7 +24,6 @@ import chat.rocket.android.util.extensions.textContent
import chat.rocket.common.model.RoomType import chat.rocket.common.model.RoomType
import chat.rocket.core.model.ChatRoom import chat.rocket.core.model.ChatRoom
import com.facebook.drawee.view.SimpleDraweeView import com.facebook.drawee.view.SimpleDraweeView
import kotlinx.android.synthetic.main.avatar.view.*
import kotlinx.android.synthetic.main.item_chat.view.* import kotlinx.android.synthetic.main.item_chat.view.*
import kotlinx.android.synthetic.main.unread_messages_badge.view.* import kotlinx.android.synthetic.main.unread_messages_badge.view.*
......
...@@ -31,8 +31,10 @@ import chat.rocket.core.model.ChatRoom ...@@ -31,8 +31,10 @@ import chat.rocket.core.model.ChatRoom
import dagger.android.support.AndroidSupportInjection import dagger.android.support.AndroidSupportInjection
import kotlinx.android.synthetic.main.fragment_chat_rooms.* import kotlinx.android.synthetic.main.fragment_chat_rooms.*
import kotlinx.coroutines.experimental.Job import kotlinx.coroutines.experimental.Job
import kotlinx.coroutines.experimental.NonCancellable.isActive
import kotlinx.coroutines.experimental.android.UI import kotlinx.coroutines.experimental.android.UI
import kotlinx.coroutines.experimental.launch import kotlinx.coroutines.experimental.launch
import timber.log.Timber
import javax.inject.Inject import javax.inject.Inject
...@@ -99,8 +101,8 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView { ...@@ -99,8 +101,8 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView {
} }
override fun onOptionsItemSelected(item: MenuItem?): Boolean { override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item?.itemId) { when (item.itemId) {
R.id.action_sort -> { R.id.action_sort -> {
val dialogLayout = layoutInflater.inflate(R.layout.chatroom_sort_dialog, null) val dialogLayout = layoutInflater.inflate(R.layout.chatroom_sort_dialog, null)
val sortType = SharedPreferenceHelper.getInt(Constants.CHATROOM_SORT_TYPE_KEY, ChatRoomsSortOrder.ACTIVITY) val sortType = SharedPreferenceHelper.getInt(Constants.CHATROOM_SORT_TYPE_KEY, ChatRoomsSortOrder.ACTIVITY)
...@@ -152,9 +154,8 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView { ...@@ -152,9 +154,8 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView {
} }
override suspend fun updateChatRooms(newDataSet: List<ChatRoom>) { override suspend fun updateChatRooms(newDataSet: List<ChatRoom>) {
activity?.apply {
listJob?.cancel() listJob?.cancel()
listJob = launch(UI) { listJob = ui {
val adapter = recycler_view.adapter as SimpleSectionedRecyclerViewAdapter val adapter = recycler_view.adapter as SimpleSectionedRecyclerViewAdapter
// FIXME https://fabric.io/rocketchat3/android/apps/chat.rocket.android/issues/5ac2916c36c7b235275ccccf // FIXME https://fabric.io/rocketchat3/android/apps/chat.rocket.android/issues/5ac2916c36c7b235275ccccf
// TODO - fix this bug to re-enable DiffUtil // TODO - fix this bug to re-enable DiffUtil
...@@ -172,30 +173,38 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView { ...@@ -172,30 +173,38 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView {
} }
} }
} }
}
override fun showNoChatRoomsToDisplay() = text_no_data_to_display.setVisible(true) override fun showNoChatRoomsToDisplay() {
ui { text_no_data_to_display.setVisible(true) }
}
override fun showLoading() = view_loading.setVisible(true) override fun showLoading(){
ui { view_loading.setVisible(true) }
}
override fun hideLoading() { override fun hideLoading() {
if (view_loading != null) { ui {
view_loading.setVisible(false) view_loading.setVisible(false)
} }
} }
override fun showMessage(resId: Int) { override fun showMessage(resId: Int) {
ui {
showToast(resId) showToast(resId)
} }
}
override fun showMessage(message: String) { override fun showMessage(message: String) {
ui {
showToast(message) showToast(message)
} }
}
override fun showGenericErrorMessage() = showMessage(getString(R.string.msg_generic_error)) override fun showGenericErrorMessage() = showMessage(getString(R.string.msg_generic_error))
override fun showConnectionState(state: State) { override fun showConnectionState(state: State) {
activity?.apply { Timber.d("Got new state: $state")
ui {
connection_status_text.fadeIn() connection_status_text.fadeIn()
handler.removeCallbacks(dismissStatus) handler.removeCallbacks(dismissStatus)
when (state) { when (state) {
...@@ -219,22 +228,25 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView { ...@@ -219,22 +228,25 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView {
} }
private fun setupToolbar() { private fun setupToolbar() {
(activity as AppCompatActivity).supportActionBar?.title = getString(R.string.title_chats) (activity as AppCompatActivity?)?.supportActionBar?.title = getString(R.string.title_chats)
} }
private fun setupRecyclerView() { private fun setupRecyclerView() {
activity?.apply { ui {
recycler_view.layoutManager = LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false) recycler_view.layoutManager = LinearLayoutManager(it, LinearLayoutManager.VERTICAL, false)
recycler_view.addItemDecoration(DividerItemDecoration(this, recycler_view.addItemDecoration(DividerItemDecoration(it,
resources.getDimensionPixelSize(R.dimen.divider_item_decorator_bound_start), resources.getDimensionPixelSize(R.dimen.divider_item_decorator_bound_start),
resources.getDimensionPixelSize(R.dimen.divider_item_decorator_bound_end))) resources.getDimensionPixelSize(R.dimen.divider_item_decorator_bound_end)))
recycler_view.itemAnimator = DefaultItemAnimator() recycler_view.itemAnimator = DefaultItemAnimator()
// TODO - use a ViewModel Mapper instead of using settings on the adapter // TODO - use a ViewModel Mapper instead of using settings on the adapter
val baseAdapter = ChatRoomsAdapter(this, val baseAdapter = ChatRoomsAdapter(it,
settingsRepository.get(serverInteractor.get()!!), localRepository) { chatRoom -> presenter.loadChatRoom(chatRoom) } settingsRepository.get(serverInteractor.get()!!), localRepository) {
chatRoom -> presenter.loadChatRoom(chatRoom)
}
sectionedAdapter = SimpleSectionedRecyclerViewAdapter(this, R.layout.item_chatroom_header, R.id.text_chatroom_header, baseAdapter!!) sectionedAdapter = SimpleSectionedRecyclerViewAdapter(it,
R.layout.item_chatroom_header, R.id.text_chatroom_header, baseAdapter)
recycler_view.adapter = sectionedAdapter recycler_view.adapter = sectionedAdapter
} }
} }
......
package chat.rocket.android.members.presentation package chat.rocket.android.members.presentation
import chat.rocket.android.chatroom.ui.ChatRoomActivity import chat.rocket.android.chatroom.ui.ChatRoomActivity
import chat.rocket.android.member.ui.newInstance import chat.rocket.android.members.ui.newInstance
class MembersNavigator(internal val activity: ChatRoomActivity) { class MembersNavigator(internal val activity: ChatRoomActivity) {
......
package chat.rocket.android.member.ui package chat.rocket.android.members.ui
import android.os.Bundle import android.os.Bundle
import android.support.design.widget.BottomSheetDialogFragment import android.support.design.widget.BottomSheetDialogFragment
......
...@@ -19,6 +19,7 @@ import chat.rocket.android.members.viewmodel.MemberViewModel ...@@ -19,6 +19,7 @@ import chat.rocket.android.members.viewmodel.MemberViewModel
import chat.rocket.android.util.extensions.inflate import chat.rocket.android.util.extensions.inflate
import chat.rocket.android.util.extensions.setVisible import chat.rocket.android.util.extensions.setVisible
import chat.rocket.android.util.extensions.showToast import chat.rocket.android.util.extensions.showToast
import chat.rocket.android.util.extensions.ui
import chat.rocket.android.widget.DividerItemDecoration import chat.rocket.android.widget.DividerItemDecoration
import dagger.android.support.AndroidSupportInjection import dagger.android.support.AndroidSupportInjection
import kotlinx.android.synthetic.main.fragment_members.* import kotlinx.android.synthetic.main.fragment_members.*
...@@ -70,7 +71,7 @@ class MembersFragment : Fragment(), MembersView { ...@@ -70,7 +71,7 @@ class MembersFragment : Fragment(), MembersView {
} }
override fun showMembers(dataSet: List<MemberViewModel>, total: Long) { override fun showMembers(dataSet: List<MemberViewModel>, total: Long) {
activity?.apply { ui {
setupToolbar(total) setupToolbar(total)
if (adapter.itemCount == 0) { if (adapter.itemCount == 0) {
adapter.prependData(dataSet) adapter.prependData(dataSet)
...@@ -84,8 +85,8 @@ class MembersFragment : Fragment(), MembersView { ...@@ -84,8 +85,8 @@ class MembersFragment : Fragment(), MembersView {
} else { } else {
adapter.appendData(dataSet) adapter.appendData(dataSet)
} }
if (this is ChatRoomActivity) { if (it is ChatRoomActivity) {
this.showRoomTypeIcon(false) it.showRoomTypeIcon(false)
} }
} }
} }
...@@ -98,29 +99,37 @@ class MembersFragment : Fragment(), MembersView { ...@@ -98,29 +99,37 @@ class MembersFragment : Fragment(), MembersView {
return super.onOptionsItemSelected(item) return super.onOptionsItemSelected(item)
} }
override fun showLoading() = view_loading.setVisible(true) override fun showLoading() {
ui { view_loading.setVisible(true) }
}
override fun hideLoading() = view_loading.setVisible(false) override fun hideLoading() {
ui { view_loading.setVisible(false) }
}
override fun showMessage(resId: Int) { override fun showMessage(resId: Int) {
ui {
showToast(resId) showToast(resId)
} }
}
override fun showMessage(message: String) { override fun showMessage(message: String) {
ui {
showToast(message) showToast(message)
} }
}
override fun showGenericErrorMessage() = showMessage(getString(R.string.msg_generic_error)) override fun showGenericErrorMessage() = showMessage(getString(R.string.msg_generic_error))
private fun setupRecyclerView() { private fun setupRecyclerView() {
activity?.apply { ui {
recycler_view.layoutManager = linearLayoutManager recycler_view.layoutManager = linearLayoutManager
recycler_view.addItemDecoration(DividerItemDecoration(this)) recycler_view.addItemDecoration(DividerItemDecoration(it))
recycler_view.adapter = adapter recycler_view.adapter = adapter
} }
} }
private fun setupToolbar(totalMembers: Long) { private fun setupToolbar(totalMembers: Long) {
(activity as ChatRoomActivity).setupToolbarTitle(getString(R.string.title_members, totalMembers)) (activity as ChatRoomActivity?)?.setupToolbarTitle(getString(R.string.title_members, totalMembers))
} }
} }
\ No newline at end of file
...@@ -22,7 +22,7 @@ import java.util.concurrent.CopyOnWriteArrayList ...@@ -22,7 +22,7 @@ import java.util.concurrent.CopyOnWriteArrayList
class ConnectionManager(internal val client: RocketChatClient) { class ConnectionManager(internal val client: RocketChatClient) {
private val statusChannelList = CopyOnWriteArrayList<Channel<State>>() private val statusChannelList = CopyOnWriteArrayList<Channel<State>>()
private val statusChannel = Channel<State>() private val statusChannel = Channel<State>(Channel.CONFLATED)
private var connectJob: Job? = null private var connectJob: Job? = null
private val roomAndSubscriptionChannels = ArrayList<Channel<StreamMessage<BaseRoom>>>() private val roomAndSubscriptionChannels = ArrayList<Channel<StreamMessage<BaseRoom>>>()
...@@ -73,7 +73,8 @@ class ConnectionManager(internal val client: RocketChatClient) { ...@@ -73,7 +73,8 @@ class ConnectionManager(internal val client: RocketChatClient) {
} }
for (channel in statusChannelList) { for (channel in statusChannelList) {
channel.send(status) Timber.d("Sending status: $status to $channel")
channel.offer(status)
} }
} }
} }
......
...@@ -11,7 +11,10 @@ import chat.rocket.android.util.extensions.asObservable ...@@ -11,7 +11,10 @@ import chat.rocket.android.util.extensions.asObservable
import chat.rocket.android.util.extensions.inflate import chat.rocket.android.util.extensions.inflate
import chat.rocket.android.util.extensions.textContent import chat.rocket.android.util.extensions.textContent
import android.support.v7.view.ActionMode import android.support.v7.view.ActionMode
import chat.rocket.android.util.extensions.ui
import dagger.android.support.AndroidSupportInjection import dagger.android.support.AndroidSupportInjection
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.disposables.Disposable
import io.reactivex.rxkotlin.Observables import io.reactivex.rxkotlin.Observables
import kotlinx.android.synthetic.main.fragment_password.* import kotlinx.android.synthetic.main.fragment_password.*
import javax.inject.Inject import javax.inject.Inject
...@@ -19,6 +22,7 @@ import javax.inject.Inject ...@@ -19,6 +22,7 @@ import javax.inject.Inject
class PasswordFragment: Fragment(), PasswordView, android.support.v7.view.ActionMode.Callback { class PasswordFragment: Fragment(), PasswordView, android.support.v7.view.ActionMode.Callback {
@Inject lateinit var presenter: PasswordPresenter @Inject lateinit var presenter: PasswordPresenter
private var actionMode: ActionMode? = null private var actionMode: ActionMode? = null
private val disposables = CompositeDisposable()
companion object { companion object {
fun newInstance() = PasswordFragment() fun newInstance() = PasswordFragment()
...@@ -34,14 +38,21 @@ class PasswordFragment: Fragment(), PasswordView, android.support.v7.view.Action ...@@ -34,14 +38,21 @@ class PasswordFragment: Fragment(), PasswordView, android.support.v7.view.Action
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
listenToChanges() disposables.add(listenToChanges())
}
override fun onDestroyView() {
disposables.clear()
super.onDestroyView()
} }
override fun hideLoading() { override fun hideLoading() {
ui {
layout_new_password.visibility = View.VISIBLE layout_new_password.visibility = View.VISIBLE
layout_confirm_password.visibility = View.VISIBLE layout_confirm_password.visibility = View.VISIBLE
view_loading.visibility = View.GONE view_loading.visibility = View.GONE
} }
}
override fun onActionItemClicked(mode: ActionMode, menuItem: MenuItem): Boolean { override fun onActionItemClicked(mode: ActionMode, menuItem: MenuItem): Boolean {
return when (menuItem.itemId) { return when (menuItem.itemId) {
...@@ -69,10 +80,12 @@ class PasswordFragment: Fragment(), PasswordView, android.support.v7.view.Action ...@@ -69,10 +80,12 @@ class PasswordFragment: Fragment(), PasswordView, android.support.v7.view.Action
} }
override fun showLoading() { override fun showLoading() {
ui {
layout_new_password.visibility = View.GONE layout_new_password.visibility = View.GONE
layout_confirm_password.visibility = View.GONE layout_confirm_password.visibility = View.GONE
view_loading.visibility = View.VISIBLE view_loading.visibility = View.VISIBLE
} }
}
override fun showPasswordFailsUpdateMessage(error: String?) { override fun showPasswordFailsUpdateMessage(error: String?) {
showToast("Password fails to update: " + error) showToast("Password fails to update: " + error)
...@@ -84,8 +97,9 @@ class PasswordFragment: Fragment(), PasswordView, android.support.v7.view.Action ...@@ -84,8 +97,9 @@ class PasswordFragment: Fragment(), PasswordView, android.support.v7.view.Action
private fun finishActionMode() = actionMode?.finish() private fun finishActionMode() = actionMode?.finish()
private fun listenToChanges() { private fun listenToChanges(): Disposable {
Observables.combineLatest(text_new_password.asObservable(), text_confirm_password.asObservable()).subscribe { return Observables.combineLatest(text_new_password.asObservable(),
text_confirm_password.asObservable()).subscribe {
val textPassword = text_new_password.textContent val textPassword = text_new_password.textContent
val textConfirmPassword = text_confirm_password.textContent val textConfirmPassword = text_confirm_password.textContent
...@@ -97,7 +111,9 @@ class PasswordFragment: Fragment(), PasswordView, android.support.v7.view.Action ...@@ -97,7 +111,9 @@ class PasswordFragment: Fragment(), PasswordView, android.support.v7.view.Action
} }
private fun showToast(msg: String?) { private fun showToast(msg: String?) {
Toast.makeText(context, msg, Toast.LENGTH_LONG).show() ui {
Toast.makeText(it, msg, Toast.LENGTH_LONG).show()
}
} }
private fun startActionMode() { private fun startActionMode() {
......
package chat.rocket.android.util.extensions
import android.os.Looper
import android.support.v4.app.Fragment
import android.support.v4.app.FragmentActivity
import kotlinx.coroutines.experimental.Job
import kotlinx.coroutines.experimental.android.UI
import kotlinx.coroutines.experimental.launch
inline fun Fragment.ui(crossinline block: (activity: FragmentActivity) -> Unit): Job? {
// Checking first for activity and view saves us from some synchronyzed and thread local checks
if (activity != null && view != null) {
// If we already are running on the Main Thread (UI Thread), just go ahead and execute the block
return if (Looper.getMainLooper() == Looper.myLooper()) {
block(activity!!)
null
} else {
// Launch a Job on the UI context and check again if the activity and view are still valid
launch(UI) {
if (activity != null && view != null) {
block(activity!!)
}
}
}
}
return null
}
\ No newline at end of file
<vector android:height="24dp" android:viewportHeight="800.0" <?xml version="1.0" encoding="utf-8"?>
android:viewportWidth="800.0" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> <vector xmlns:android="http://schemas.android.com/apk/res/android"
<path android:fillColor="@color/actionMenuColor" android:pathData="M511.8,390H520V84C567,67.8 596.3,42 596.3,16H203.7c0,26 29.3,51.8 76.3,68V390h8.2c-92.9,16 -157.5,61 -157.5,108H377v288h48V498h244.3C669.3,451 604.7,406 511.8,390z"/> android:viewportWidth="197.218"
android:viewportHeight="197.218"
android:width="197.218dp"
android:height="197.218dp">
<group
android:translateX="-570.396"
android:translateY="-306.782">
<path
android:pathData="M704.445 306.782l-6.785 6.785c-6.084 6.084 -7.622 14.712 -4.309 21.871l-44.068 35.44 -3.086 -3.086c-7.889 -7.889 -19.525 -7.889 -27.414 0l-8.944 8.953 87.821 87.811 8.934 -8.933c7.899 -7.899 7.899 -19.525 0 -27.433l-3.076 -3.077 36.051 -44.68c6.824 2.466 14.367 1.036 20.037 -4.624l8.008 -5.858 -63.169 -63.169zm-66.867 116.487l-67.182 66.857 0 13.874 13.864 0 66.867 -67.182 -13.549 -13.549z"
android:fillColor="@color/actionMenuColor"
/>
</group>
</vector> </vector>
\ No newline at end of file
...@@ -32,4 +32,50 @@ ...@@ -32,4 +32,50 @@
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
tools:visibility="visible" /> tools:visibility="visible" />
<ImageView
android:id="@+id/iv_pin_icon"
android:layout_width="100dp"
android:layout_height="100dp"
android:src="@drawable/ic_pin_black_24dp"
android:tint="#AFADAF"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="@id/tv_pin_title"
app:layout_constraintVertical_chainStyle="packed"
android:visibility="gone"
tools:visibility="visible" />
<TextView
android:id="@+id/tv_pin_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/no_pinned_messages"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/iv_pin_icon"
app:layout_constraintBottom_toTopOf="@id/tv_pin_description"
android:textSize="20sp"
android:layout_marginTop="24dp"
android:textStyle="bold"
android:textColor="#8B8B8B"
android:visibility="gone"
tools:visibility="visible"/>
<TextView
android:id="@+id/tv_pin_description"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/no_pinned_description"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_pin_title"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_marginTop="16dp"
android:textAlignment="center"
android:textSize="16sp"
android:textColor="#c1c1c1"
android:visibility="gone"
tools:visibility="visible"/>
</android.support.constraint.ConstraintLayout> </android.support.constraint.ConstraintLayout>
\ No newline at end of file
...@@ -10,14 +10,14 @@ ...@@ -10,14 +10,14 @@
android:paddingTop="@dimen/chat_item_top_and_bottom_padding" android:paddingTop="@dimen/chat_item_top_and_bottom_padding"
android:paddingBottom="@dimen/chat_item_top_and_bottom_padding"> android:paddingBottom="@dimen/chat_item_top_and_bottom_padding">
<include <com.facebook.drawee.view.SimpleDraweeView
android:id="@+id/layout_avatar" android:id="@+id/image_avatar"
layout="@layout/avatar"
android:layout_width="40dp" android:layout_width="40dp"
android:layout_height="40dp" android:layout_height="40dp"
app:roundedCornerRadius="3dp"
android:layout_marginTop="6dp" android:layout_marginTop="6dp"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent"/>
<TextView <TextView
android:id="@+id/text_chat_name" android:id="@+id/text_chat_name"
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="16dp" android:layout_marginStart="16dp"
app:layout_constraintStart_toEndOf="@id/layout_avatar" app:layout_constraintStart_toEndOf="@id/image_avatar"
android:textDirection="locale" android:textDirection="locale"
tools:text="General"/> tools:text="General"/>
...@@ -51,7 +51,7 @@ ...@@ -51,7 +51,7 @@
app:layout_constraintTop_toBottomOf="@id/text_chat_name" app:layout_constraintTop_toBottomOf="@id/text_chat_name"
app:layout_constraintEnd_toStartOf="@id/layout_unread_messages_badge" app:layout_constraintEnd_toStartOf="@id/layout_unread_messages_badge"
android:textDirection="locale" android:textDirection="locale"
tools:text="You: Type something"/> tools:text="You: Type something that is very big and need at least to lines, or maybe even more"/>
<include <include
android:id="@+id/layout_unread_messages_badge" android:id="@+id/layout_unread_messages_badge"
......
...@@ -123,6 +123,8 @@ ...@@ -123,6 +123,8 @@
<!-- Pinned Messages --> <!-- Pinned Messages -->
<string name="title_pinned_messages">पिन किए गए संदेश</string> <string name="title_pinned_messages">पिन किए गए संदेश</string>
<string name="no_pinned_messages">कोई पिन संदेश नहीं</string>
<string name="no_pinned_description">सभी पिन किए गए संदेश यहां\nदिखाई देते हैं।</string>
<!-- Upload Messages --> <!-- Upload Messages -->
<string name="max_file_size_exceeded">फ़ाइल का आकार %1$d बाइट्स ने %2$d बाइट्स के अधिकतम अपलोड आकार को पार कर लिया है</string> <string name="max_file_size_exceeded">फ़ाइल का आकार %1$d बाइट्स ने %2$d बाइट्स के अधिकतम अपलोड आकार को पार कर लिया है</string>
......
...@@ -123,6 +123,8 @@ ...@@ -123,6 +123,8 @@
<!-- Pinned Messages --> <!-- Pinned Messages -->
<string name="title_pinned_messages">Mensagens Pinadas</string> <string name="title_pinned_messages">Mensagens Pinadas</string>
<string name="no_pinned_messages">Nenhuma mensagem pinada</string>
<string name="no_pinned_description">Todas as mensagens pinadas\naparecerão aqui</string>
<!-- Upload Messages --> <!-- Upload Messages -->
<string name="max_file_size_exceeded">Tamanho de arquivo (%1$d bytes) excedeu tamanho máximo de upload (%2$d bytes)</string> <string name="max_file_size_exceeded">Tamanho de arquivo (%1$d bytes) excedeu tamanho máximo de upload (%2$d bytes)</string>
......
...@@ -124,6 +124,8 @@ ...@@ -124,6 +124,8 @@
<!-- Pinned Messages --> <!-- Pinned Messages -->
<string name="title_pinned_messages">Pinned Messages</string> <string name="title_pinned_messages">Pinned Messages</string>
<string name="no_pinned_messages">No pinned messages</string>
<string name="no_pinned_description">All the pinned messages\nappear here.</string>
<!-- Upload Messages --> <!-- Upload Messages -->
<string name="max_file_size_exceeded">File size %1$d bytes exceeded max upload size of %2$d bytes</string> <string name="max_file_size_exceeded">File size %1$d bytes exceeded max upload size of %2$d bytes</string>
......
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted="true">
<trust-anchors>
<certificates src="system" />
<certificates src="user" />
</trust-anchors>
</base-config>
</network-security-config>
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