diff --git a/.idea/misc.xml b/.idea/misc.xml index 8af4157..362a8f0 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,4 +1,3 @@ - + - + diff --git a/Readme.md b/Readme.md index f576e7a..9df4826 100644 --- a/Readme.md +++ b/Readme.md @@ -247,12 +247,20 @@ click listeners can be added using: `overrideUrlClick`: keep it as true if you want to handle the url internally in your app. Else keep it false if you want to open a browser when url is clicked. -```kotlin -config?.setUrlClickListener(object : LiveChatUrlClickListener { - override fun buttonClicked(url: String?) { - // Add the app logic for url click +### Chat Started Listener + +Receive a callback when a new chat conversation has been started for the user. +This fires once the chat has been initiated and the backend has assigned a +`roomId` for the conversation. Use it to log analytics, persist the room +reference, or trigger any in-app behaviour that depends on a chat being live. + + ```kotlin + config?.setChatStartedListener(object : LiveChatStartedListener { + override fun onChatStarted(roomId: String?) { + // A new chat has started — `roomId` identifies this conversation + // Log.d("Chat Started","roomId = $roomId") } -}, overrideUrlClick) +}) ``` # User session management diff --git a/app/src/main/java/io/verloop/TestActivity.kt b/app/src/main/java/io/verloop/TestActivity.kt index 0d00ca5..eb90469 100644 --- a/app/src/main/java/io/verloop/TestActivity.kt +++ b/app/src/main/java/io/verloop/TestActivity.kt @@ -17,6 +17,7 @@ import io.verloop.sdk.utils.NetworkUtils import org.json.JSONException import org.json.JSONObject import android.net.Uri +import kotlin.math.log class TestActivity : AppCompatActivity() { @@ -24,6 +25,7 @@ class TestActivity : AppCompatActivity() { var verloop: Verloop? = null var verloop2: Verloop? = null + var headerConfig: HeaderConfig? = null override fun onCreate(savedInstanceState: Bundle?) { @@ -149,7 +151,7 @@ class TestActivity : AppCompatActivity() { .closeExistingChat(checkCloseExistingChat.isChecked) .openMenuWidgetOnStart(openMenuWidgetOnStart.isChecked) .overrideHeaderLayout(false) - .allowFileDownload(true) + .allowFileDownload(false) .headerConfig(headerConfig) .fields(customFields).build() @@ -171,6 +173,7 @@ class TestActivity : AppCompatActivity() { verloopConfig?.setButtonClickListener(object : LiveChatButtonClickListener { override fun buttonClicked(title: String?, type: String?, payload: String?) { if (type == "web_url"){ + Log.d("URL",payload.toString()) try { val jsonPayload = JSONObject(payload) val url = jsonPayload.optString("url") @@ -190,6 +193,16 @@ class TestActivity : AppCompatActivity() { } } }) + verloopConfig?.setChatStartedListener(object : LiveChatStartedListener{ + override fun onChatStarted(roomId: String?) { + Log.d("Chat Started"," roomId = $roomId") + } + }) + verloopConfig?.setRoomReadyListener(object : LiveChatRoomReadyListner{ + override fun onRoomReady(roomId: String?) { + Log.d("Room Ready","roomId = $roomId") + } + }) verloop = Verloop(this, verloopConfig!!) verloop?.showChat() } catch (e: VerloopException) { @@ -273,4 +286,5 @@ class TestActivity : AppCompatActivity() { } } } -} \ No newline at end of file +} + diff --git a/sdk/src/main/java/io/verloop/sdk/LiveChatRoomReadyListner.kt b/sdk/src/main/java/io/verloop/sdk/LiveChatRoomReadyListner.kt new file mode 100644 index 0000000..d91f53f --- /dev/null +++ b/sdk/src/main/java/io/verloop/sdk/LiveChatRoomReadyListner.kt @@ -0,0 +1,6 @@ +package io.verloop.sdk + + +fun interface LiveChatRoomReadyListner { + fun onRoomReady(roomId: String?) +} \ No newline at end of file diff --git a/sdk/src/main/java/io/verloop/sdk/LiveChatStartedListener.kt b/sdk/src/main/java/io/verloop/sdk/LiveChatStartedListener.kt new file mode 100644 index 0000000..722a481 --- /dev/null +++ b/sdk/src/main/java/io/verloop/sdk/LiveChatStartedListener.kt @@ -0,0 +1,5 @@ +package io.verloop.sdk + +fun interface LiveChatStartedListener { + fun onChatStarted(roomId: String?) +} \ No newline at end of file diff --git a/sdk/src/main/java/io/verloop/sdk/Verloop.kt b/sdk/src/main/java/io/verloop/sdk/Verloop.kt index dcbe3ee..ab3ab95 100644 --- a/sdk/src/main/java/io/verloop/sdk/Verloop.kt +++ b/sdk/src/main/java/io/verloop/sdk/Verloop.kt @@ -167,5 +167,13 @@ class Verloop(val context: Context, var verloopConfig: VerloopConfig) { fun onLogEvent(logEvent: LogEvent) { config.logEventListener?.logEvent(logEvent) } + + fun onChatStarted(roomId: String?) { + config.chatStartedListenerImpl?.onChatStarted(roomId) + } + + fun onRoomReady(roomId: String?) { + config.roomReadyListenerImpl?.onRoomReady(roomId) + } } } \ No newline at end of file diff --git a/sdk/src/main/java/io/verloop/sdk/VerloopConfig.kt b/sdk/src/main/java/io/verloop/sdk/VerloopConfig.kt index 7fff503..44a5762 100644 --- a/sdk/src/main/java/io/verloop/sdk/VerloopConfig.kt +++ b/sdk/src/main/java/io/verloop/sdk/VerloopConfig.kt @@ -29,6 +29,11 @@ data class VerloopConfig private constructor( var logLevel: LogLevel = LogLevel.WARNING var buttonOnClickListener: LiveChatButtonClickListener? = null + + var chatStartedListenerImpl: LiveChatStartedListener? = null + + var roomReadyListenerImpl: LiveChatRoomReadyListner? = null + var chatUrlClickListener: LiveChatUrlClickListener? = null var logEventListener: LiveLogEventListener? = null @@ -75,6 +80,22 @@ data class VerloopConfig private constructor( this.buttonOnClickListener = buttonOnClickListener } + /** + * Callback for chat started + * @param chatStartedListener + */ + fun setChatStartedListener(listener: LiveChatStartedListener) { + this.chatStartedListenerImpl = listener // ← uses new name + } + + /** + * Callback for chat started + * @param roomReadyListenerImpl + */ + fun setRoomReadyListener(listener: LiveChatRoomReadyListner) { + this.roomReadyListenerImpl = listener // ← uses new name + } + /** * Callback for url click event from within the chat * @param urlClickListener diff --git a/sdk/src/main/java/io/verloop/sdk/ui/VerloopFragment.kt b/sdk/src/main/java/io/verloop/sdk/ui/VerloopFragment.kt index 64c6f25..fc825ff 100644 --- a/sdk/src/main/java/io/verloop/sdk/ui/VerloopFragment.kt +++ b/sdk/src/main/java/io/verloop/sdk/ui/VerloopFragment.kt @@ -543,6 +543,8 @@ class VerloopFragment : Fragment() { ready() } else if (params.getString("fn").equals("roomReady")) { roomReady() + }else if (params.getString("fn").equals("callback")) { + handleCallback(params.optJSONArray("args")) } } @@ -574,6 +576,31 @@ class VerloopFragment : Fragment() { } } + private fun handleCallback(args: org.json.JSONArray?) { + val eventName = args?.optString(0) ?: return + val payload = args.optJSONObject(1) + val roomId = payload?.optString("roomId", null) + when (eventName) { + "chat-started" -> callChatStarted(roomId) + "room-ready" -> callRoomReady(roomId) + // room-ready, chat-ended, etc. — add later as needed + } + } + + private fun callChatStarted(roomId: String?){ + logEvent(LogLevel.INFO, "ChatStarted", null) + Handler(Looper.getMainLooper()).post { + viewModel?.chatStarted(roomId) + } + } + + private fun callRoomReady(roomId: String?){ + logEvent(LogLevel.INFO, "Room Ready", null) + Handler(Looper.getMainLooper()).post { + viewModel?.roomReady(roomId) + } + } + private fun logEvent(level: LogLevel, message: String, params: JSONObject?) { if (config?.logLevel?.ordinal!! >= level.ordinal) { viewModel?.logEvent(LogEvent(level.name, message, params)) diff --git a/sdk/src/main/java/io/verloop/sdk/viewmodel/MainViewModel.kt b/sdk/src/main/java/io/verloop/sdk/viewmodel/MainViewModel.kt index b9dedb5..abd7d7b 100644 --- a/sdk/src/main/java/io/verloop/sdk/viewmodel/MainViewModel.kt +++ b/sdk/src/main/java/io/verloop/sdk/viewmodel/MainViewModel.kt @@ -28,6 +28,14 @@ class MainViewModel(var configKey: String?, var repository: VerloopRepository) : } } + fun chatStarted(roomId: String?) { + Verloop.eventListeners[configKey]?.onChatStarted(roomId) + } + + fun roomReady(roomId: String?) { + Verloop.eventListeners[configKey]?.onRoomReady(roomId) + } + fun urlClicked(json: String) { configKey.let { Verloop.eventListeners[configKey]?.onURLClick(json)