Commit fcbaf1bd authored by Lucio Maciel's avatar Lucio Maciel

Add ui { } DSL to run stuff on the UI thread and check for valid

fragment and view
parent 34818d4b
...@@ -59,26 +59,36 @@ class RegisterUsernameFragment : Fragment(), RegisterUsernameView { ...@@ -59,26 +59,36 @@ class RegisterUsernameFragment : Fragment(), RegisterUsernameView {
} }
override fun alertBlankUsername() { override fun alertBlankUsername() {
vibrateSmartPhone() ui {
text_username.shake() vibrateSmartPhone()
text_username.shake()
}
} }
override fun showLoading() { override fun showLoading() {
disableUserInput() ui {
view_loading.setVisible(true) disableUserInput()
view_loading.setVisible(true)
}
} }
override fun hideLoading() { override fun hideLoading() {
view_loading.setVisible(false) ui {
enableUserInput() view_loading.setVisible(false)
enableUserInput()
}
} }
override fun showMessage(resId: Int) { override fun showMessage(resId: Int) {
showToast(resId) ui {
showToast(resId)
}
} }
override fun showMessage(message: String) { override fun showMessage(message: String) {
showToast(message) ui {
showToast(message)
}
} }
override fun showGenericErrorMessage() { override fun showGenericErrorMessage() {
...@@ -86,10 +96,10 @@ class RegisterUsernameFragment : Fragment(), RegisterUsernameView { ...@@ -86,10 +96,10 @@ class RegisterUsernameFragment : Fragment(), RegisterUsernameView {
} }
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,21 +47,29 @@ class ServerFragment : Fragment(), ServerView { ...@@ -47,21 +47,29 @@ 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() {
enableUserInput(false) ui {
view_loading.setVisible(true) enableUserInput(false)
view_loading.setVisible(true)
}
} }
override fun hideLoading() { override fun hideLoading() {
view_loading.setVisible(false) ui {
enableUserInput(true) view_loading.setVisible(false)
enableUserInput(true)
}
} }
override fun showMessage(resId: Int){ override fun showMessage(resId: Int){
showToast(resId) ui {
showToast(resId)
}
} }
override fun showMessage(message: String) { override fun showMessage(message: String) {
showToast(message) ui {
showToast(message)
}
} }
override fun showGenericErrorMessage() { override fun showGenericErrorMessage() {
......
...@@ -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,45 +64,61 @@ class SignupFragment : Fragment(), SignupView { ...@@ -64,45 +64,61 @@ class SignupFragment : Fragment(), SignupView {
} }
override fun alertBlankName() { override fun alertBlankName() {
vibrateSmartPhone() ui {
text_name.shake() vibrateSmartPhone()
text_name.requestFocus() text_name.shake()
text_name.requestFocus()
}
} }
override fun alertBlankUsername() { override fun alertBlankUsername() {
vibrateSmartPhone() ui {
text_username.shake() vibrateSmartPhone()
text_username.requestFocus() text_username.shake()
text_username.requestFocus()
}
} }
override fun alertEmptyPassword() { override fun alertEmptyPassword() {
vibrateSmartPhone() ui {
text_password.shake() vibrateSmartPhone()
text_password.requestFocus() text_password.shake()
text_password.requestFocus()
}
} }
override fun alertBlankEmail() { override fun alertBlankEmail() {
vibrateSmartPhone() ui {
text_email.shake() vibrateSmartPhone()
text_email.requestFocus() text_email.shake()
text_email.requestFocus()
}
} }
override fun showLoading() { override fun showLoading() {
enableUserInput(false) ui {
view_loading.setVisible(true) enableUserInput(false)
view_loading.setVisible(true)
}
} }
override fun hideLoading() { override fun hideLoading() {
view_loading.setVisible(false) ui {
enableUserInput(true) view_loading.setVisible(false)
enableUserInput(true)
}
} }
override fun showMessage(resId: Int) { override fun showMessage(resId: Int) {
showToast(resId) ui {
showToast(resId)
}
} }
override fun showMessage(message: String) { override fun showMessage(message: String) {
showToast(message) ui {
showToast(message)
}
} }
override fun showGenericErrorMessage() { override fun showGenericErrorMessage() {
...@@ -110,15 +126,15 @@ class SignupFragment : Fragment(), SignupView { ...@@ -110,15 +126,15 @@ class SignupFragment : Fragment(), SignupView {
} }
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,8 +63,10 @@ class TwoFAFragment : Fragment(), TwoFAView { ...@@ -63,8 +63,10 @@ class TwoFAFragment : Fragment(), TwoFAView {
} }
override fun alertBlankTwoFactorAuthenticationCode() { override fun alertBlankTwoFactorAuthenticationCode() {
vibrateSmartPhone() ui {
text_two_factor_auth.shake() vibrateSmartPhone()
text_two_factor_auth.shake()
}
} }
override fun alertInvalidTwoFactorAuthenticationCode() { override fun alertInvalidTwoFactorAuthenticationCode() {
...@@ -72,30 +74,38 @@ class TwoFAFragment : Fragment(), TwoFAView { ...@@ -72,30 +74,38 @@ class TwoFAFragment : Fragment(), TwoFAView {
} }
override fun showLoading() { override fun showLoading() {
enableUserInput(false) ui {
view_loading.setVisible(true) enableUserInput(false)
view_loading.setVisible(true)
}
} }
override fun hideLoading() { override fun hideLoading() {
view_loading.setVisible(false) ui {
enableUserInput(true) view_loading.setVisible(false)
enableUserInput(true)
}
} }
override fun showMessage(resId: Int) { override fun showMessage(resId: Int) {
showToast(resId) ui {
showToast(resId)
}
} }
override fun showMessage(message: String) { override fun showMessage(message: String) {
showToast(message) ui {
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
...@@ -183,28 +184,28 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR ...@@ -183,28 +184,28 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
} }
override fun showMessages(dataSet: List<BaseViewModel<*>>) { override fun showMessages(dataSet: List<BaseViewModel<*>>) {
// track the message sent immediately after the current message ui {
var prevMessageViewModel: MessageViewModel? = null // track the message sent immediately after the current message
var prevMessageViewModel: MessageViewModel? = null
// Loop over received messages to determine first unread
for (i in dataSet.indices) { // Loop over received messages to determine first unread
val msgModel = dataSet[i] for (i in dataSet.indices) {
val msgModel = dataSet[i]
if (msgModel is MessageViewModel) {
val msg = msgModel.rawData if (msgModel is MessageViewModel) {
if (msg.timestamp < chatRoomLastSeen) { val msg = msgModel.rawData
// This message was sent before the last seen of the room. Hence, it was seen. if (msg.timestamp < chatRoomLastSeen) {
// if there is a message after (below) this, mark it firstUnread. // This message was sent before the last seen of the room. Hence, it was seen.
if (prevMessageViewModel != null) { // if there is a message after (below) this, mark it firstUnread.
prevMessageViewModel.isFirstUnread = true if (prevMessageViewModel != null) {
prevMessageViewModel.isFirstUnread = true
}
break
} }
break prevMessageViewModel = msgModel
} }
prevMessageViewModel = msgModel
} }
}
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)
...@@ -282,11 +283,13 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR ...@@ -282,11 +283,13 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
} }
override fun sendMessage(text: String) { override fun sendMessage(text: String) {
if (!text.isBlank()) { ui {
if (!text.startsWith("/")) { if (!text.isBlank()) {
presenter.sendMessage(chatRoomId, text, editingMessageId) if (!text.startsWith("/")) {
} else { presenter.sendMessage(chatRoomId, text, editingMessageId)
presenter.runCommand(text, chatRoomId) } else {
presenter.runCommand(text, chatRoomId)
}
} }
} }
} }
...@@ -301,43 +304,55 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR ...@@ -301,43 +304,55 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
} }
override fun showNewMessage(message: List<BaseViewModel<*>>) { override fun showNewMessage(message: List<BaseViewModel<*>>) {
adapter.prependData(message) ui {
recycler_view.scrollToPosition(0) adapter.prependData(message)
verticalScrollOffset.set(0) recycler_view.scrollToPosition(0)
verticalScrollOffset.set(0)
}
} }
override fun disableSendMessageButton() { override fun disableSendMessageButton() {
button_send.isEnabled = false ui {
button_send.isEnabled = false
}
} }
override fun enableSendMessageButton(sendFailed: Boolean) { override fun enableSendMessageButton(sendFailed: Boolean) {
button_send.isEnabled = true ui {
text_message.isEnabled = true button_send.isEnabled = true
if (!sendFailed) { text_message.isEnabled = true
clearMessageComposition() if (!sendFailed) {
clearMessageComposition()
}
} }
} }
override fun clearMessageComposition() { override fun clearMessageComposition() {
citation = null ui {
editingMessageId = null citation = null
text_message.textContent = "" editingMessageId = null
actionSnackbar.dismiss() text_message.textContent = ""
actionSnackbar.dismiss()
}
} }
override fun dispatchUpdateMessage(index: Int, message: List<BaseViewModel<*>>) { override fun dispatchUpdateMessage(index: Int, message: List<BaseViewModel<*>>) {
adapter.updateItem(message.last()) ui {
if (message.size > 1) { adapter.updateItem(message.last())
adapter.prependData(listOf(message.first())) if (message.size > 1) {
adapter.prependData(listOf(message.first()))
}
} }
} }
override fun dispatchDeleteMessage(msgId: String) { override fun dispatchDeleteMessage(msgId: String) {
adapter.removeItem(msgId) ui {
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
...@@ -352,41 +367,55 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR ...@@ -352,41 +367,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) {
showToast(message) ui {
showToast(message)
}
} }
override fun showMessage(resId: Int) { override fun showMessage(resId: Int) {
showToast(resId) ui {
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>) {
suggestions_view.addItems("@", members) ui {
suggestions_view.addItems("@", members)
}
} }
override fun populateRoomSuggestions(chatRooms: List<ChatRoomSuggestionViewModel>) { override fun populateRoomSuggestions(chatRooms: List<ChatRoomSuggestionViewModel>) {
suggestions_view.addItems("#", chatRooms) ui {
suggestions_view.addItems("#", chatRooms)
}
} }
override fun populateCommandSuggestions(commands: List<CommandSuggestionViewModel>) { override fun populateCommandSuggestions(commands: List<CommandSuggestionViewModel>) {
suggestions_view.addItems("/", commands) ui {
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()
...@@ -422,7 +451,7 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR ...@@ -422,7 +451,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) {
...@@ -435,11 +464,11 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR ...@@ -435,11 +464,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,
...@@ -459,7 +488,7 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR ...@@ -459,7 +488,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)
} }
} }
...@@ -471,7 +500,7 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR ...@@ -471,7 +500,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) {
...@@ -489,10 +518,12 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR ...@@ -489,10 +518,12 @@ class ChatRoomFragment : Fragment(), ChatRoomView, EmojiKeyboardListener, EmojiR
} }
override fun onJoined() { override fun onJoined() {
input_container.setVisible(true) ui {
button_join_chat.setVisible(false) input_container.setVisible(true)
isSubscribed = true button_join_chat.setVisible(false)
setupMessageComposer() isSubscribed = true
setupMessageComposer()
}
} }
private val dismissStatus = { private val dismissStatus = {
......
...@@ -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) {
showToast(resId) ui {
showToast(resId)
}
} }
override fun showMessage(message: String) { override fun showMessage(message: String) {
showToast(message) ui {
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)
......
...@@ -32,6 +32,7 @@ import dagger.android.support.AndroidSupportInjection ...@@ -32,6 +32,7 @@ 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.CommonPool import kotlinx.coroutines.experimental.CommonPool
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.async import kotlinx.coroutines.experimental.async
import kotlinx.coroutines.experimental.launch import kotlinx.coroutines.experimental.launch
...@@ -101,8 +102,8 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView { ...@@ -101,8 +102,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)
...@@ -154,50 +155,56 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView { ...@@ -154,50 +155,56 @@ 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 = ui {
listJob = launch(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 /*val diff = async(CommonPool) {
/*val diff = async(CommonPool) { DiffUtil.calculateDiff(RoomsDiffCallback(adapter.baseAdapter.dataSet, newDataSet))
DiffUtil.calculateDiff(RoomsDiffCallback(adapter.baseAdapter.dataSet, newDataSet)) }.await()*/
}.await()*/
if (isActive) {
if (isActive) { adapter.baseAdapter.updateRooms(newDataSet)
adapter.baseAdapter.updateRooms(newDataSet) // TODO - fix crash to re-enable diff.dispatchUpdatesTo(adapter)
// TODO - fix crash to re-enable diff.dispatchUpdatesTo(adapter) adapter.notifyDataSetChanged()
adapter.notifyDataSetChanged()
//Set sections always after data set is updated
//Set sections always after data set is updated setSections()
setSections()
}
} }
} }
} }
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) {
showToast(resId) ui {
showToast(resId)
}
} }
override fun showMessage(message: String) { override fun showMessage(message: String) {
showToast(message) ui {
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 { ui {
connection_status_text.fadeIn() connection_status_text.fadeIn()
handler.removeCallbacks(dismissStatus) handler.removeCallbacks(dismissStatus)
when (state) { when (state) {
...@@ -221,22 +228,25 @@ class ChatRoomsFragment : Fragment(), ChatRoomsView { ...@@ -221,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) {
showToast(resId) ui {
showToast(resId)
}
} }
override fun showMessage(message: String) { override fun showMessage(message: String) {
showToast(message) ui {
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
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
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