Unverified Commit 0de209d8 authored by Filipe de Lima Brito's avatar Filipe de Lima Brito Committed by GitHub

Merge pull request #696 from filipedelimabrito/feature/support-sending-message-using-sdk

[NEW] Support sending message using SDK
parents 8f90d0f1 49ba5fbb
...@@ -6,8 +6,8 @@ import chat.rocket.android.server.infraestructure.RocketChatClientFactory ...@@ -6,8 +6,8 @@ import chat.rocket.android.server.infraestructure.RocketChatClientFactory
import chat.rocket.android.util.launchUI import chat.rocket.android.util.launchUI
import chat.rocket.common.model.BaseRoom import chat.rocket.common.model.BaseRoom
import chat.rocket.common.util.ifNull import chat.rocket.common.util.ifNull
import chat.rocket.core.RocketChatClient
import chat.rocket.core.internal.rest.messages import chat.rocket.core.internal.rest.messages
import chat.rocket.core.internal.rest.sendMessage
import javax.inject.Inject import javax.inject.Inject
class ChatRoomPresenter @Inject constructor(private val view: ChatRoomView, class ChatRoomPresenter @Inject constructor(private val view: ChatRoomView,
...@@ -16,7 +16,7 @@ class ChatRoomPresenter @Inject constructor(private val view: ChatRoomView, ...@@ -16,7 +16,7 @@ class ChatRoomPresenter @Inject constructor(private val view: ChatRoomView,
factory: RocketChatClientFactory) { factory: RocketChatClientFactory) {
private val client = factory.create(serverInteractor.get()!!) private val client = factory.create(serverInteractor.get()!!)
fun messages(chatRoomId: String, chatRoomType: String, offset: Int = 0) { fun loadMessages(chatRoomId: String, chatRoomType: String, offset: Int = 0) {
launchUI(strategy) { launchUI(strategy) {
view.showLoading() view.showLoading()
try { try {
...@@ -33,4 +33,19 @@ class ChatRoomPresenter @Inject constructor(private val view: ChatRoomView, ...@@ -33,4 +33,19 @@ class ChatRoomPresenter @Inject constructor(private val view: ChatRoomView,
} }
} }
} }
fun sendMessage(chatRoomId: String, text: String) {
launchUI(strategy) {
try {
val message = client.sendMessage(chatRoomId, text)
view.showSentMessage(message)
} catch (ex: Exception) {
ex.message?.let {
view.showMessage(it)
}.ifNull {
view.showGenericErrorMessage()
}
}
}
}
} }
\ No newline at end of file
...@@ -13,4 +13,18 @@ interface ChatRoomView : LoadingView, MessageView { ...@@ -13,4 +13,18 @@ interface ChatRoomView : LoadingView, MessageView {
* @param serverUrl The server URL. * @param serverUrl The server URL.
*/ */
fun showMessages(dataSet: MutableList<Message>, serverUrl: String) fun showMessages(dataSet: MutableList<Message>, serverUrl: String)
/**
* Send a message to a chat room.
*
* @param text The text to send.
*/
fun sendMessage(text: String)
/**
* Shows a (recent) message sent to a chat room.
* @param message The (recent) message sent to a chat room.
*/
fun showSentMessage(message: Message)
} }
\ No newline at end of file
...@@ -15,26 +15,26 @@ import dagger.android.support.HasSupportFragmentInjector ...@@ -15,26 +15,26 @@ import dagger.android.support.HasSupportFragmentInjector
import kotlinx.android.synthetic.main.app_bar_chat_room.* import kotlinx.android.synthetic.main.app_bar_chat_room.*
import javax.inject.Inject import javax.inject.Inject
fun Context.chatRoomIntent(chatRoomId: String, chatRoomName: String, chatRoomType: String, isChatRoomOpen: Boolean): Intent { fun Context.chatRoomIntent(chatRoomId: String, chatRoomName: String, chatRoomType: String, isChatRoomReadOnly: Boolean): Intent {
return Intent(this, ChatRoomActivity::class.java).apply { return Intent(this, ChatRoomActivity::class.java).apply {
putExtra(INTENT_CHAT_ROOM_ID, chatRoomId) putExtra(INTENT_CHAT_ROOM_ID, chatRoomId)
putExtra(INTENT_CHAT_ROOM_NAME, chatRoomName) putExtra(INTENT_CHAT_ROOM_NAME, chatRoomName)
putExtra(INTENT_CHAT_ROOM_TYPE, chatRoomType) putExtra(INTENT_CHAT_ROOM_TYPE, chatRoomType)
putExtra(INTENT_IS_CHAT_ROOM_OPEN, isChatRoomOpen) putExtra(INTENT_IS_CHAT_ROOM_READ_ONLY, isChatRoomReadOnly)
} }
} }
private const val INTENT_CHAT_ROOM_ID = "chat_room_id" private const val INTENT_CHAT_ROOM_ID = "chat_room_id"
private const val INTENT_CHAT_ROOM_NAME = "chat_room_name" private const val INTENT_CHAT_ROOM_NAME = "chat_room_name"
private const val INTENT_CHAT_ROOM_TYPE = "chat_room_type" private const val INTENT_CHAT_ROOM_TYPE = "chat_room_type"
private const val INTENT_IS_CHAT_ROOM_OPEN = "is_chat_room_open" private const val INTENT_IS_CHAT_ROOM_READ_ONLY = "is_chat_room_read_only"
class ChatRoomActivity : AppCompatActivity(), HasSupportFragmentInjector { class ChatRoomActivity : AppCompatActivity(), HasSupportFragmentInjector {
@Inject lateinit var fragmentDispatchingAndroidInjector: DispatchingAndroidInjector<Fragment> @Inject lateinit var fragmentDispatchingAndroidInjector: DispatchingAndroidInjector<Fragment>
private lateinit var chatRoomId: String private lateinit var chatRoomId: String
private lateinit var chatRoomName: String private lateinit var chatRoomName: String
private lateinit var chatRoomType: String private lateinit var chatRoomType: String
private var isChatRoomOpen: Boolean = true private var isChatRoomReadOnly: Boolean = false
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
...@@ -51,13 +51,13 @@ class ChatRoomActivity : AppCompatActivity(), HasSupportFragmentInjector { ...@@ -51,13 +51,13 @@ class ChatRoomActivity : AppCompatActivity(), HasSupportFragmentInjector {
chatRoomType = intent.getStringExtra(INTENT_CHAT_ROOM_TYPE) chatRoomType = intent.getStringExtra(INTENT_CHAT_ROOM_TYPE)
requireNotNull(chatRoomType) { "no chat_room_type provided in Intent extras" } requireNotNull(chatRoomType) { "no chat_room_type provided in Intent extras" }
isChatRoomOpen = intent.getBooleanExtra(INTENT_IS_CHAT_ROOM_OPEN, true) isChatRoomReadOnly = intent.getBooleanExtra(INTENT_IS_CHAT_ROOM_READ_ONLY, true)
requireNotNull(chatRoomType) { "no is_chat_room_open provided in Intent extras" } requireNotNull(chatRoomType) { "no is_chat_room_read_only provided in Intent extras" }
setupToolbar(chatRoomName) setupToolbar(chatRoomName)
addFragment("ChatRoomFragment", R.id.fragment_container) { addFragment("ChatRoomFragment", R.id.fragment_container) {
newInstance(chatRoomId, chatRoomName, chatRoomType, isChatRoomOpen) newInstance(chatRoomId, chatRoomName, chatRoomType, isChatRoomReadOnly)
} }
} }
......
...@@ -35,6 +35,11 @@ class ChatRoomAdapter(private val context: Context, ...@@ -35,6 +35,11 @@ class ChatRoomAdapter(private val context: Context,
notifyItemRangeInserted(previousDataSetSize, dataSet.size) notifyItemRangeInserted(previousDataSetSize, dataSet.size)
} }
fun addItem(message: Message) {
dataSet.add(0, message)
notifyItemInserted(0)
}
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
fun bind(message: Message) = with(itemView) { fun bind(message: Message) = with(itemView) {
......
...@@ -14,18 +14,20 @@ import chat.rocket.android.chatroom.presentation.ChatRoomView ...@@ -14,18 +14,20 @@ import chat.rocket.android.chatroom.presentation.ChatRoomView
import chat.rocket.android.helper.EndlessRecyclerViewScrollListener import chat.rocket.android.helper.EndlessRecyclerViewScrollListener
import chat.rocket.android.util.inflate import chat.rocket.android.util.inflate
import chat.rocket.android.util.setVisibility import chat.rocket.android.util.setVisibility
import chat.rocket.android.util.textContent
import chat.rocket.core.model.Message import chat.rocket.core.model.Message
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_room.*
import kotlinx.android.synthetic.main.message_composer.*
import javax.inject.Inject import javax.inject.Inject
fun newInstance(chatRoomId: String, chatRoomName: String, chatRoomType: String, isChatRoomOpen: Boolean): Fragment { fun newInstance(chatRoomId: String, chatRoomName: String, chatRoomType: String, isChatRoomReadOnly: Boolean): Fragment {
return ChatRoomFragment().apply { return ChatRoomFragment().apply {
arguments = Bundle(1).apply { arguments = Bundle(1).apply {
putString(BUNDLE_CHAT_ROOM_ID, chatRoomId) putString(BUNDLE_CHAT_ROOM_ID, chatRoomId)
putString(BUNDLE_CHAT_ROOM_NAME, chatRoomName) putString(BUNDLE_CHAT_ROOM_NAME, chatRoomName)
putString(BUNDLE_CHAT_ROOM_TYPE, chatRoomType) putString(BUNDLE_CHAT_ROOM_TYPE, chatRoomType)
putBoolean(BUNDLE_IS_CHAT_ROOM_OPEN, isChatRoomOpen) putBoolean(BUNDLE_IS_CHAT_ROOM_READ_ONLY, isChatRoomReadOnly)
} }
} }
} }
...@@ -33,14 +35,15 @@ fun newInstance(chatRoomId: String, chatRoomName: String, chatRoomType: String, ...@@ -33,14 +35,15 @@ fun newInstance(chatRoomId: String, chatRoomName: String, chatRoomType: String,
private const val BUNDLE_CHAT_ROOM_ID = "chat_room_id" private const val BUNDLE_CHAT_ROOM_ID = "chat_room_id"
private const val BUNDLE_CHAT_ROOM_NAME = "chat_room_name" private const val BUNDLE_CHAT_ROOM_NAME = "chat_room_name"
private const val BUNDLE_CHAT_ROOM_TYPE = "chat_room_type" private const val BUNDLE_CHAT_ROOM_TYPE = "chat_room_type"
private const val BUNDLE_IS_CHAT_ROOM_OPEN = "is_chat_room_open" private const val BUNDLE_IS_CHAT_ROOM_READ_ONLY = "is_chat_room_read_only"
class ChatRoomFragment : Fragment(), ChatRoomView { class ChatRoomFragment : Fragment(), ChatRoomView {
@Inject lateinit var presenter: ChatRoomPresenter @Inject lateinit var presenter: ChatRoomPresenter
private lateinit var chatRoomId: String private lateinit var chatRoomId: String
private lateinit var chatRoomName: String private lateinit var chatRoomName: String
private lateinit var chatRoomType: String private lateinit var chatRoomType: String
private var isChatRoomOpen: Boolean = true private var isChatRoomReadOnly: Boolean = false
private lateinit var adapter: ChatRoomAdapter
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
...@@ -51,7 +54,7 @@ class ChatRoomFragment : Fragment(), ChatRoomView { ...@@ -51,7 +54,7 @@ class ChatRoomFragment : Fragment(), ChatRoomView {
chatRoomId = bundle.getString(BUNDLE_CHAT_ROOM_ID) chatRoomId = bundle.getString(BUNDLE_CHAT_ROOM_ID)
chatRoomName = bundle.getString(BUNDLE_CHAT_ROOM_NAME) chatRoomName = bundle.getString(BUNDLE_CHAT_ROOM_NAME)
chatRoomType = bundle.getString(BUNDLE_CHAT_ROOM_TYPE) chatRoomType = bundle.getString(BUNDLE_CHAT_ROOM_TYPE)
isChatRoomOpen = bundle.getBoolean(BUNDLE_IS_CHAT_ROOM_OPEN) isChatRoomReadOnly = bundle.getBoolean(BUNDLE_IS_CHAT_ROOM_READ_ONLY)
} else { } else {
requireNotNull(bundle) { "no arguments supplied when the fragment was instantiated" } requireNotNull(bundle) { "no arguments supplied when the fragment was instantiated" }
} }
...@@ -61,28 +64,42 @@ class ChatRoomFragment : Fragment(), ChatRoomView { ...@@ -61,28 +64,42 @@ class ChatRoomFragment : Fragment(), ChatRoomView {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
presenter.messages(chatRoomId, chatRoomType) presenter.loadMessages(chatRoomId, chatRoomType)
setupComposer()
} }
override fun showMessages(dataSet: MutableList<Message>, serverUrl: String) { override fun showMessages(dataSet: MutableList<Message>, serverUrl: String) {
activity?.apply { activity?.apply {
if (recycler_view.adapter == null) { if (recycler_view.adapter == null) {
recycler_view.adapter = ChatRoomAdapter(this, dataSet, serverUrl) adapter = ChatRoomAdapter(this, dataSet, serverUrl)
recycler_view.adapter = adapter
val linearLayoutManager = LinearLayoutManager(context, LinearLayoutManager.VERTICAL, true) val linearLayoutManager = LinearLayoutManager(context, LinearLayoutManager.VERTICAL, true)
recycler_view.layoutManager = linearLayoutManager recycler_view.layoutManager = linearLayoutManager
if (dataSet.size >= 30) { if (dataSet.size >= 30) {
recycler_view.addOnScrollListener(object : EndlessRecyclerViewScrollListener(linearLayoutManager) { recycler_view.addOnScrollListener(object : EndlessRecyclerViewScrollListener(linearLayoutManager) {
override fun onLoadMore(page: Int, totalItemsCount: Int, recyclerView: RecyclerView?) { override fun onLoadMore(page: Int, totalItemsCount: Int, recyclerView: RecyclerView?) {
presenter.messages(chatRoomId, chatRoomType, page * 30) presenter.loadMessages(chatRoomId, chatRoomType, page * 30)
} }
}) })
} }
} else { } else {
(recycler_view.adapter as ChatRoomAdapter).addDataSet(dataSet) adapter.addDataSet(dataSet)
} }
} }
} }
override fun sendMessage(text: String) {
if (!text.isBlank()) {
presenter.sendMessage(chatRoomId, text)
}
}
override fun showSentMessage(message: Message) {
text_message.textContent = ""
adapter.addItem(message)
recycler_view.smoothScrollToPosition(0)
}
override fun showLoading() = view_loading.setVisibility(true) override fun showLoading() = view_loading.setVisibility(true)
override fun hideLoading() = view_loading.setVisibility(false) override fun hideLoading() = view_loading.setVisibility(false)
...@@ -90,4 +107,13 @@ class ChatRoomFragment : Fragment(), ChatRoomView { ...@@ -90,4 +107,13 @@ class ChatRoomFragment : Fragment(), ChatRoomView {
override fun showMessage(message: String) = Toast.makeText(activity, message, Toast.LENGTH_SHORT).show() override fun showMessage(message: String) = Toast.makeText(activity, message, Toast.LENGTH_SHORT).show()
override fun showGenericErrorMessage() = showMessage(getString(R.string.msg_generic_error)) override fun showGenericErrorMessage() = showMessage(getString(R.string.msg_generic_error))
private fun setupComposer() {
if (isChatRoomReadOnly) {
text_room_is_read_only.setVisibility(true)
top_container.setVisibility(false)
} else {
text_send.setOnClickListener { sendMessage(text_message.textContent) }
}
}
} }
\ No newline at end of file
...@@ -7,8 +7,8 @@ import chat.rocket.android.chatrooms.ui.MainActivity ...@@ -7,8 +7,8 @@ import chat.rocket.android.chatrooms.ui.MainActivity
class ChatRoomsNavigator(private val activity: MainActivity, private val context: Context) { class ChatRoomsNavigator(private val activity: MainActivity, private val context: Context) {
fun toChatRoom(chatRoomId: String, chatRoomName: String, chatRoomType: String, isChatRoomOpen: Boolean) { fun toChatRoom(chatRoomId: String, chatRoomName: String, chatRoomType: String, isChatRoomReadOnly: Boolean) {
activity.startActivity(context.chatRoomIntent(chatRoomId, chatRoomName, chatRoomType, isChatRoomOpen)) activity.startActivity(context.chatRoomIntent(chatRoomId, chatRoomName, chatRoomType, isChatRoomReadOnly))
activity.overridePendingTransition(R.anim.open_enter, R.anim.open_exit) activity.overridePendingTransition(R.anim.open_enter, R.anim.open_exit)
} }
} }
\ No newline at end of file
...@@ -36,8 +36,18 @@ class ChatRoomsPresenter @Inject constructor(private val view: ChatRoomsView, ...@@ -36,8 +36,18 @@ class ChatRoomsPresenter @Inject constructor(private val view: ChatRoomsView,
} }
} }
fun loadChatRoom(chatRoom: ChatRoom) { fun loadChatRoom(chatRoom: ChatRoom) = navigator.toChatRoom(chatRoom.id, chatRoom.name, chatRoom.type.name, chatRoom.readonly ?: false)
navigator.toChatRoom(chatRoom.id, chatRoom.name, chatRoom.type.name, chatRoom.readonly ?: false)
/**
* Gets a [ChatRoom] list from local repository.
* ChatRooms returned are filtered by name.
*/
fun chatRoomsByName(name: String) {
val currentServer = serverInteractor.get()!!
launchUI(strategy) {
val roomList = getChatRoomsInteractor.getByName(currentServer, name)
view.updateChatRooms(roomList)
}
} }
private suspend fun loadRooms(): List<ChatRoom> { private suspend fun loadRooms(): List<ChatRoom> {
...@@ -58,17 +68,6 @@ class ChatRoomsPresenter @Inject constructor(private val view: ChatRoomsView, ...@@ -58,17 +68,6 @@ class ChatRoomsPresenter @Inject constructor(private val view: ChatRoomsView,
} }
} }
/**
* Get a ChatRoom list from local repository. ChatRooms returned are filtered by name.
*/
fun chatRoomsByName(name: String) {
val currentServer = serverInteractor.get()!!
launchUI(strategy) {
val roomList = getChatRoomsInteractor.getByName(currentServer, name)
view.updateChatRooms(roomList)
}
}
private fun getOpenChatRooms(chatRooms: List<ChatRoom>): List<ChatRoom> { private fun getOpenChatRooms(chatRooms: List<ChatRoom>): List<ChatRoom> {
return chatRooms.filter(ChatRoom::open) return chatRooms.filter(ChatRoom::open)
} }
......
...@@ -10,6 +10,17 @@ ...@@ -10,6 +10,17 @@
android:layout_height="1dp" android:layout_height="1dp"
android:background="@color/colorDividerMessageComposer" /> android:background="@color/colorDividerMessageComposer" />
<TextView
android:id="@+id/text_room_is_read_only"
android:layout_width="match_parent"
android:layout_height="45dp"
android:background="@color/white"
android:gravity="center"
android:text="@string/msg_this_room_is_read_only"
android:textColor="@color/black"
android:visibility="gone"
app:layout_constraintTop_toBottomOf="@+id/divider" />
<LinearLayout <LinearLayout
android:id="@+id/top_container" android:id="@+id/top_container"
android:layout_width="match_parent" android:layout_width="match_parent"
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
<string name="msg_invalid_2fa_code">Código 2FA inválido</string> <string name="msg_invalid_2fa_code">Código 2FA inválido</string>
<string name="msg_yesterday">ontem</string> <string name="msg_yesterday">ontem</string>
<string name="msg_message">Messagem</string> <string name="msg_message">Messagem</string>
<string name="msg_this_room_is_read_only">Este chat é apenas de leitura</string>
<string name="msg_content_description_log_in_using_facebook">Fazer login através do Facebook</string> <string name="msg_content_description_log_in_using_facebook">Fazer login através do Facebook</string>
<string name="msg_content_description_log_in_using_github">Fazer login através do Github</string> <string name="msg_content_description_log_in_using_github">Fazer login através do Github</string>
<string name="msg_content_description_log_in_using_google">Fazer login através do Google</string> <string name="msg_content_description_log_in_using_google">Fazer login através do Google</string>
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
<string name="msg_more_than_ninety_nine_unread_messages" translatable="false">99+</string> <string name="msg_more_than_ninety_nine_unread_messages" translatable="false">99+</string>
<string name="msg_yesterday">Yesterday</string> <string name="msg_yesterday">Yesterday</string>
<string name="msg_message">Message</string> <string name="msg_message">Message</string>
<string name="msg_this_room_is_read_only">This room is read only</string>
<string name="msg_content_description_log_in_using_facebook">Login using Facebook</string> <string name="msg_content_description_log_in_using_facebook">Login using Facebook</string>
<string name="msg_content_description_log_in_using_github">Login using Github</string> <string name="msg_content_description_log_in_using_github">Login using Github</string>
<string name="msg_content_description_log_in_using_google">Login using Google</string> <string name="msg_content_description_log_in_using_google">Login using Google</string>
......
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