diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index de9e212c02..16fe887abf 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -10,30 +10,31 @@
+
-
-
@@ -42,92 +43,76 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -139,7 +124,7 @@
-
+ android:name=".utils.fcm.RegistrationIntentService"
+ android:exported="false" />
-
+
-
+
\ No newline at end of file
diff --git a/app/src/main/java/org/mifos/mobile/rocketchat/RocketChatActivity.kt b/app/src/main/java/org/mifos/mobile/rocketchat/RocketChatActivity.kt
new file mode 100644
index 0000000000..569103a08e
--- /dev/null
+++ b/app/src/main/java/org/mifos/mobile/rocketchat/RocketChatActivity.kt
@@ -0,0 +1,14 @@
+package org.mifos.mobile.rocketchat
+
+import androidx.appcompat.app.AppCompatActivity
+import android.os.Bundle
+import org.mifos.mobile.databinding.ActivityRocketChatBinding
+
+class RocketChatActivity : AppCompatActivity() {
+ private lateinit var binding : ActivityRocketChatBinding
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ binding = ActivityRocketChatBinding.inflate(layoutInflater)
+ setContentView(binding.root)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/mifos/mobile/rocketchat/RocketChatFragment.kt b/app/src/main/java/org/mifos/mobile/rocketchat/RocketChatFragment.kt
new file mode 100644
index 0000000000..f4d7802f4e
--- /dev/null
+++ b/app/src/main/java/org/mifos/mobile/rocketchat/RocketChatFragment.kt
@@ -0,0 +1,67 @@
+package org.mifos.mobile.rocketchat
+
+import android.os.Bundle
+import androidx.fragment.app.Fragment
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.lifecycle.ViewModelProvider
+import okhttp3.WebSocket
+import okhttp3.WebSocketListener
+import org.mifos.mobile.databinding.FragmentRocketChatBinding
+import org.mifos.mobile.rocketchat.adapter.RocketChatAdapter
+import org.mifos.mobile.rocketchat.model.SupportChatMessage
+
+class RocketChatFragment : Fragment() {
+ private var _binding: FragmentRocketChatBinding? = null
+ private val binding get() = _binding!!
+ private lateinit var viewModel: RocketChatViewModel
+ private var webSocket: WebSocket? = null
+ private lateinit var webSocketListener: WebSocketListener
+ private lateinit var adapter: RocketChatAdapter
+ override fun onCreateView(
+ inflater: LayoutInflater, container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ _binding = FragmentRocketChatBinding.inflate(inflater, container, false)
+ viewModel = ViewModelProvider(this)[RocketChatViewModel::class.java]
+ webSocketListener = RocketChatService(viewModel)
+ adapter = RocketChatAdapter()
+ binding.rvSupportChat.adapter = adapter
+ return binding.root
+ }
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+ with(binding) {
+ viewModel.socketStatus.observe(viewLifecycleOwner) {
+ statusTV.text = if (it) "Connected" else "Disconnected"
+ }
+
+ viewModel.messages.observe(viewLifecycleOwner) {
+ adapter.addNewMessage(it)
+ }
+
+ connectButton.setOnClickListener {
+ webSocket = viewModel.createWebSocketConnection(webSocketListener)
+ }
+
+ disconnectButton.setOnClickListener {
+ webSocket?.close(1000, "Canceled manually.")
+ }
+
+ sendButton.setOnClickListener {
+ viewModel.sendCustomerMessage(webSocket, messageET.text.toString())
+ viewModel.addMessage(
+ SupportChatMessage(
+ messageET.text.toString().trim(),
+ SupportChatMessage.MessageType.USER
+ )
+ )
+ messageET.text = null
+ }
+ }
+
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/mifos/mobile/rocketchat/RocketChatService.kt b/app/src/main/java/org/mifos/mobile/rocketchat/RocketChatService.kt
new file mode 100644
index 0000000000..75ca49fbad
--- /dev/null
+++ b/app/src/main/java/org/mifos/mobile/rocketchat/RocketChatService.kt
@@ -0,0 +1,92 @@
+package org.mifos.mobile.rocketchat
+
+import okhttp3.Response
+import okhttp3.WebSocket
+import okhttp3.WebSocketListener
+import org.json.JSONObject
+import org.mifos.mobile.rocketchat.model.SupportChatMessage
+import javax.inject.Inject
+
+class RocketChatService @Inject constructor(
+ private val viewModel: RocketChatViewModel
+) : WebSocketListener() {
+ override fun onOpen(webSocket: WebSocket, response: Response) {
+ super.onOpen(webSocket, response)
+ viewModel.setStatus(true)
+ val connectMessage = """
+ {
+ "msg": "connect",
+ "version": "1",
+ "support": ["1"]
+ }
+ """.trimIndent()
+ webSocket.send(connectMessage)
+
+ val loginRequest = """
+ {
+ "msg": "method",
+ "method": "login",
+ "id": "42",
+ "params": [
+ { "resume": "EDFOiOPiwS5k-ptDA9-bDQ7qM2DVXiDDh-5YrzrLfxA" }
+ ]
+ }
+ """.trimIndent()
+ webSocket.send(loginRequest)
+
+ val subscribeRequest = """
+ {
+ "msg": "sub",
+ "id": "sub1",
+ "name": "stream-room-messages",
+ "params": ["GENERAL", false]
+ }
+ """.trimIndent()
+ webSocket.send(subscribeRequest)
+
+ }
+
+ override fun onMessage(webSocket: WebSocket, text: String) {
+ super.onMessage(webSocket, text)
+
+ if (text.contains("\"msg\":\"changed\"") && text.contains("\"collection\":\"stream-room-messages\"") && !text.contains(
+ "\"username\":\"CustomerTestMifosRCWorkspace\""
+ )
+ ) {
+ val jsonObject = JSONObject(text)
+ val fieldsObject = jsonObject.getJSONObject("fields")
+ val argsArray = fieldsObject.getJSONArray("args")
+ val messageObject = argsArray.getJSONObject(0)
+ val message = messageObject.getString("msg")
+
+ viewModel.addMessage(
+ SupportChatMessage(
+ message,
+ SupportChatMessage.MessageType.SUPPORT
+ )
+ )
+ }
+
+ if (text.contains("\"msg\":\"ping\"")) {
+ val pongMessage = """
+ {
+ "msg": "pong"
+ }
+ """.trimIndent()
+ webSocket.send(pongMessage)
+ }
+ }
+
+ override fun onClosing(webSocket: WebSocket, code: Int, reason: String) {
+ super.onClosing(webSocket, code, reason)
+ }
+
+ override fun onClosed(webSocket: WebSocket, code: Int, reason: String) {
+ super.onClosed(webSocket, code, reason)
+ viewModel.setStatus(false)
+ }
+
+ override fun onFailure(webSocket: WebSocket, t: Throwable, response: Response?) {
+ super.onFailure(webSocket, t, response)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/mifos/mobile/rocketchat/RocketChatViewModel.kt b/app/src/main/java/org/mifos/mobile/rocketchat/RocketChatViewModel.kt
new file mode 100644
index 0000000000..5770a2a2ba
--- /dev/null
+++ b/app/src/main/java/org/mifos/mobile/rocketchat/RocketChatViewModel.kt
@@ -0,0 +1,64 @@
+package org.mifos.mobile.rocketchat
+
+import androidx.lifecycle.LiveData
+import androidx.lifecycle.MutableLiveData
+import androidx.lifecycle.ViewModel
+import androidx.lifecycle.viewModelScope
+import dagger.hilt.android.lifecycle.HiltViewModel
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
+import okhttp3.OkHttpClient
+import okhttp3.Request
+import okhttp3.WebSocket
+import okhttp3.WebSocketListener
+import org.mifos.mobile.rocketchat.model.SupportChatMessage
+import javax.inject.Inject
+
+@HiltViewModel
+class RocketChatViewModel @Inject constructor(
+) : ViewModel() {
+ private val webSocketURL = "wss://testrcmifosworkspace.rocket.chat/websocket"
+ private val okHttpClient = OkHttpClient()
+ private val _socketStatus = MutableLiveData(false)
+ val socketStatus: LiveData = _socketStatus
+ private val _messages = MutableLiveData()
+ val messages: LiveData = _messages
+
+ fun createWebSocketConnection(webSocketListener: WebSocketListener): WebSocket? {
+ return okHttpClient.newWebSocket(createRequest(), webSocketListener)
+ }
+
+ fun sendCustomerMessage(webSocket: WebSocket?, message: String) {
+ val messageObject = """
+ {
+ "msg": "method",
+ "method": "sendMessage",
+ "id": "42",
+ "params": [
+ {
+ "_id": "${System.currentTimeMillis()}",
+ "rid": "GENERAL",
+ "msg": "$message"
+ }
+ ]
+ }
+ """.trimIndent()
+ webSocket?.send(messageObject)
+ }
+
+ private fun createRequest(): Request {
+ return Request.Builder()
+ .url(webSocketURL)
+ .build()
+ }
+
+ fun addMessage(message: SupportChatMessage) = viewModelScope.launch(Dispatchers.Main) {
+ if (_socketStatus.value == true) {
+ _messages.value = message
+ }
+ }
+
+ fun setStatus(status: Boolean) = viewModelScope.launch(Dispatchers.Main) {
+ _socketStatus.value = status
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/mifos/mobile/rocketchat/adapter/RocketChatAdapter.kt b/app/src/main/java/org/mifos/mobile/rocketchat/adapter/RocketChatAdapter.kt
new file mode 100644
index 0000000000..a04d4d2c47
--- /dev/null
+++ b/app/src/main/java/org/mifos/mobile/rocketchat/adapter/RocketChatAdapter.kt
@@ -0,0 +1,85 @@
+package org.mifos.mobile.rocketchat.adapter
+
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.recyclerview.widget.DiffUtil
+import androidx.recyclerview.widget.RecyclerView
+import kotlinx.android.synthetic.main.item_chat_support.view.tv_message_support
+import kotlinx.android.synthetic.main.item_chat_user.view.tv_message_user
+import org.mifos.mobile.R
+import org.mifos.mobile.rocketchat.model.SupportChatMessage
+
+class RocketChatAdapter : RecyclerView.Adapter() {
+ private val messages = mutableListOf()
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
+ return when (viewType) {
+ SupportChatMessage.MessageType.USER.ordinal -> {
+ val view = LayoutInflater.from(parent.context)
+ .inflate(R.layout.item_chat_user, parent, false)
+
+ UserMessageViewHolder(view)
+ }
+
+ SupportChatMessage.MessageType.SUPPORT.ordinal -> {
+ val view = LayoutInflater.from(parent.context)
+ .inflate(R.layout.item_chat_support, parent, false)
+ SupportMessageViewHolder(view)
+ }
+
+ else -> throw IllegalArgumentException("Invalid view type")
+ }
+ }
+
+ override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
+ val message = messages[position]
+ when (holder) {
+ is UserMessageViewHolder -> holder.bind(message)
+ is SupportMessageViewHolder -> holder.bind(message)
+ }
+ }
+
+ override fun getItemViewType(position: Int): Int {
+ return messages[position].messageType.ordinal
+ }
+
+ override fun getItemCount(): Int {
+ return messages.size
+ }
+
+ fun addNewMessage(supportChatMessage: SupportChatMessage) {
+ messages.add(supportChatMessage)
+ notifyDataSetChanged()
+ }
+
+ inner class UserMessageViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
+ fun bind(message: SupportChatMessage) {
+ itemView.tv_message_user.tv_message_user.text = message.text
+ }
+ }
+
+ inner class SupportMessageViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
+ fun bind(message: SupportChatMessage) {
+ itemView.tv_message_support.text = message.text
+ }
+ }
+
+
+}
+
+class MessageDiffCallback : DiffUtil.ItemCallback() {
+ override fun areItemsTheSame(
+ oldItem: SupportChatMessage,
+ newItem: SupportChatMessage
+ ): Boolean {
+ return oldItem == newItem
+ }
+
+ override fun areContentsTheSame(
+ oldItem: SupportChatMessage,
+ newItem: SupportChatMessage
+ ): Boolean {
+ return oldItem == newItem
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/mifos/mobile/rocketchat/model/SupportChatMessage.kt b/app/src/main/java/org/mifos/mobile/rocketchat/model/SupportChatMessage.kt
new file mode 100644
index 0000000000..1ae2e20934
--- /dev/null
+++ b/app/src/main/java/org/mifos/mobile/rocketchat/model/SupportChatMessage.kt
@@ -0,0 +1,10 @@
+package org.mifos.mobile.rocketchat.model
+
+data class SupportChatMessage(
+ val text : String,
+ val messageType : MessageType
+) {
+ enum class MessageType{
+ USER, SUPPORT
+ }
+}
diff --git a/app/src/main/java/org/mifos/mobile/ui/fragments/HomeOldFragment.kt b/app/src/main/java/org/mifos/mobile/ui/fragments/HomeOldFragment.kt
index ea8a7ee229..efc7d4cfca 100644
--- a/app/src/main/java/org/mifos/mobile/ui/fragments/HomeOldFragment.kt
+++ b/app/src/main/java/org/mifos/mobile/ui/fragments/HomeOldFragment.kt
@@ -19,6 +19,7 @@ import org.mifos.mobile.R
import org.mifos.mobile.api.local.PreferencesHelper
import org.mifos.mobile.databinding.FragmentHomeOldBinding
import org.mifos.mobile.models.client.Client
+import org.mifos.mobile.rocketchat.RocketChatActivity
import org.mifos.mobile.ui.activities.HomeActivity
import org.mifos.mobile.ui.activities.LoanApplicationActivity
import org.mifos.mobile.ui.activities.NotificationActivity
@@ -328,6 +329,14 @@ class HomeOldFragment : BaseFragment(), OnRefreshListener {
binding.llSurveys.setOnClickListener {
surveys()
}
+
+ binding.btnContactUs.setOnClickListener {
+ contactUs()
+ }
+ }
+
+ private fun contactUs() {
+ startActivity(Intent(activity, RocketChatActivity::class.java))
}
private fun toggleVisibilityButton(
diff --git a/app/src/main/res/drawable/ic_send.xml b/app/src/main/res/drawable/ic_send.xml
new file mode 100644
index 0000000000..3abc6cb33b
--- /dev/null
+++ b/app/src/main/res/drawable/ic_send.xml
@@ -0,0 +1,5 @@
+
+
+
diff --git a/app/src/main/res/layout/activity_rocket_chat.xml b/app/src/main/res/layout/activity_rocket_chat.xml
new file mode 100644
index 0000000000..64715a476c
--- /dev/null
+++ b/app/src/main/res/layout/activity_rocket_chat.xml
@@ -0,0 +1,9 @@
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_home_old.xml b/app/src/main/res/layout/fragment_home_old.xml
index fa4664f368..84734871c5 100644
--- a/app/src/main/res/layout/fragment_home_old.xml
+++ b/app/src/main/res/layout/fragment_home_old.xml
@@ -375,12 +375,14 @@
android:orientation="horizontal"
android:padding="@dimen/Mifos.DesignSystem.Spacing.CardInnerPaddingLarger">
-
-
-
-
-
diff --git a/app/src/main/res/layout/fragment_rocket_chat.xml b/app/src/main/res/layout/fragment_rocket_chat.xml
new file mode 100644
index 0000000000..8f3b29c4c6
--- /dev/null
+++ b/app/src/main/res/layout/fragment_rocket_chat.xml
@@ -0,0 +1,85 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_chat_support.xml b/app/src/main/res/layout/item_chat_support.xml
new file mode 100644
index 0000000000..d67702403a
--- /dev/null
+++ b/app/src/main/res/layout/item_chat_support.xml
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/item_chat_user.xml b/app/src/main/res/layout/item_chat_user.xml
new file mode 100644
index 0000000000..97f08fce72
--- /dev/null
+++ b/app/src/main/res/layout/item_chat_user.xml
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 7ce29f1a91..11a2c8feef 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -646,5 +646,7 @@
App Info
Login Failed, Please Try Again Later.
+
+ Hello blank fragment