diff --git a/android/src/main/kotlin/twilio/flutter/twilio_conversations/Mapper.kt b/android/src/main/kotlin/twilio/flutter/twilio_conversations/Mapper.kt index 25b8590..3a19644 100644 --- a/android/src/main/kotlin/twilio/flutter/twilio_conversations/Mapper.kt +++ b/android/src/main/kotlin/twilio/flutter/twilio_conversations/Mapper.kt @@ -82,9 +82,9 @@ object Mapper { return result } - fun chatClientToMap(chatClient: ConversationsClient): Map { + fun chatClientToMap(pluginInstance: TwilioConversationsPlugin, chatClient: ConversationsClient): Map { return mapOf( - "channels" to channelsToMap(chatClient.myConversations), + "channels" to channelsToMap(pluginInstance, chatClient.myConversations), "myIdentity" to chatClient.myIdentity, "connectionState" to chatClient.connectionState.toString(), "users" to usersToMap(chatClient.subscribedUsers), @@ -121,33 +121,33 @@ object Mapper { } } - private fun channelsToMap(channels: List): Map { - val subscribedChannelsMap = channels.map { channelToMap(it) } + private fun channelsToMap(pluginInstance: TwilioConversationsPlugin, channels: List): Map { + val subscribedChannelsMap = channels.map { channelToMap(pluginInstance, it) } return mapOf( "subscribedChannels" to subscribedChannelsMap ) } - fun channelToMap(channel: Conversation?): Map? { + fun channelToMap(pluginInstance: TwilioConversationsPlugin, channel: Conversation?): Map? { if (channel == null) { return null } // Setting flutter event listener for the given channel if one does not yet exist. - if (!TwilioConversationsPlugin.channelChannels.containsKey(channel.sid)) { - TwilioConversationsPlugin.channelChannels[channel.sid] = EventChannel(TwilioConversationsPlugin.messenger, "flutter_twilio_conversations/${channel.sid}") - TwilioConversationsPlugin.channelChannels[channel.sid]?.setStreamHandler(object : EventChannel.StreamHandler { + if (!pluginInstance.channelChannels.containsKey(channel.sid)) { + pluginInstance.channelChannels[channel.sid] = EventChannel(pluginInstance.messenger, "flutter_twilio_conversations/${channel.sid}") + pluginInstance.channelChannels[channel.sid]?.setStreamHandler(object : EventChannel.StreamHandler { override fun onListen(arguments: Any?, events: EventChannel.EventSink) { Log.d("TwilioInfo", "Mapper.channelToMap => EventChannel for Channel(${channel.sid}) attached") - TwilioConversationsPlugin.channelListeners[channel.sid] = ChannelListener(events) - channel.addListener(TwilioConversationsPlugin.channelListeners[channel.sid]) + pluginInstance.channelListeners[channel.sid] = ChannelListener(pluginInstance, events) + channel.addListener(pluginInstance.channelListeners[channel.sid]) } override fun onCancel(arguments: Any?) { Log.d("TwilioInfo", "Mapper.channelToMap => EventChannel for Channel(${channel.sid}) detached") - channel.removeListener(TwilioConversationsPlugin.channelListeners[channel.sid]) - TwilioConversationsPlugin.channelListeners.remove(channel.sid) - TwilioConversationsPlugin.channelChannels.remove(channel.sid) + channel.removeListener(pluginInstance.channelListeners[channel.sid]) + pluginInstance.channelListeners.remove(channel.sid) + pluginInstance.channelChannels.remove(channel.sid) } }) } diff --git a/android/src/main/kotlin/twilio/flutter/twilio_conversations/PluginHandler.kt b/android/src/main/kotlin/twilio/flutter/twilio_conversations/PluginHandler.kt index 247fc48..53ccabe 100644 --- a/android/src/main/kotlin/twilio/flutter/twilio_conversations/PluginHandler.kt +++ b/android/src/main/kotlin/twilio/flutter/twilio_conversations/PluginHandler.kt @@ -6,6 +6,7 @@ import android.util.Log import com.twilio.conversations.CallbackListener import com.twilio.conversations.ConversationsClient import com.twilio.util.ErrorInfo +import io.flutter.plugin.common.BinaryMessenger import io.flutter.plugin.common.MethodCall import io.flutter.plugin.common.MethodChannel import io.flutter.plugin.common.MethodChannel.MethodCallHandler @@ -20,27 +21,26 @@ import twilio.flutter.twilio_conversations.methods.MessagesMethods import twilio.flutter.twilio_conversations.methods.UserMethods import twilio.flutter.twilio_conversations.methods.UsersMethods -class PluginHandler(private val applicationContext: Context) : MethodCallHandler { - - override fun onMethodCall(@NonNull call: MethodCall, @NonNull result: MethodChannel.Result) { +class PluginHandler(private val pluginInstance: TwilioConversationsPlugin, private val applicationContext: Context) : MethodCallHandler { + override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) { Log.d("TwilioInfo", "TwilioConversationsPlugin.onMethodCall => received ${call.method}") if (call.method != "cancel" && call.method != "listen") { when (call.method) { "debug" -> debug(call, result) "create" -> create(call, result) - "registerForNotification" -> TwilioConversationsPlugin.instance.registerForNotification(call, result) - "unregisterForNotification" -> TwilioConversationsPlugin.instance.unregisterForNotification(call, result) - "handleReceivedNotification" -> TwilioConversationsPlugin.instance.handleReceivedNotification(call, result) + "registerForNotification" -> pluginInstance.registerForNotification(call, result) + "unregisterForNotification" -> pluginInstance.unregisterForNotification(call, result) + "handleReceivedNotification" -> pluginInstance.handleReceivedNotification(call, result) "ChatClient#updateToken" -> ChatClientMethods.updateToken(call, result) "ChatClient#shutdown" -> ChatClientMethods.shutdown(call, result) - + "User#unsubscribe" -> UserMethods.unsubscribe(call, result) - + "Users#getChannelUserDescriptors" -> UsersMethods.getChannelUserDescriptors(call, result) "Users#getUserDescriptor" -> UsersMethods.getUserDescriptor(call, result) "Users#getAndSubscribeUser" -> UsersMethods.getAndSubscribeUser(call, result) - + "Channel#join" -> ChannelMethods.join(call, result) "Channel#leave" -> ChannelMethods.leave(call, result) "Channel#typing" -> ChannelMethods.typing(call, result) @@ -55,27 +55,27 @@ class PluginHandler(private val applicationContext: Context) : MethodCallHandler "Channel#setNotificationLevel" -> ChannelMethods.setNotificationLevel(call, result) "Channel#getUniqueName" -> ChannelMethods.getUniqueName(call, result) "Channel#setUniqueName" -> ChannelMethods.setUniqueName(call, result) - - "Channels#getChannel" -> ChannelsMethods.getChannel(call, result) + + "Channels#getChannel" -> ChannelsMethods.getChannel(pluginInstance, call, result) "Channels#getPublicChannelsList" -> ChannelsMethods.getPublicChannelsList(call, result) "Channels#getUserChannelsList" -> ChannelsMethods.getUserChannelsList(call, result) - "Channels#createChannel" -> ChannelsMethods.createChannel(call, result) + "Channels#createChannel" -> ChannelsMethods.createChannel(pluginInstance, call, result) "Member#getUserDescriptor" -> MemberMethods.getUserDescriptor(call, result) "Member#getAndSubscribeUser" -> MemberMethods.getAndSubscribeUser(call, result) "Member#setAttributes" -> MemberMethods.setAttributes(call, result) - + "Members#getMembersList" -> MembersMethods.getMembersList(call, result) "Members#getMember" -> MembersMethods.getMember(call, result) "Members#addByIdentity" -> MembersMethods.addByIdentity(call, result) "Members#inviteByIdentity" -> MembersMethods.inviteByIdentity(call, result) "Members#removeByIdentity" -> MembersMethods.removeByIdentity(call, result) - + "Message#updateMessageBody" -> MessageMethods.updateMessageBody(call, result) "Message#setAttributes" -> MessageMethods.setAttributes(call, result) "Message#getMedia" -> MessageMethods.getMedia(call, result) - - "Messages#sendMessage" -> MessagesMethods.sendMessage(call, result) + + "Messages#sendMessage" -> MessagesMethods.sendMessage(pluginInstance, call, result) "Messages#removeMessage" -> MessagesMethods.removeMessage(call, result) "Messages#getMessagesBefore" -> MessagesMethods.getMessagesBefore(call, result) "Messages#getMessagesAfter" -> MessagesMethods.getMessagesAfter(call, result) @@ -85,7 +85,7 @@ class PluginHandler(private val applicationContext: Context) : MethodCallHandler "Messages#advanceLastReadMessageIndexWithResult" -> MessagesMethods.advanceLastReadMessageIndexWithResult(call, result) "Messages#setAllMessagesReadWithResult" -> MessagesMethods.setAllMessagesReadWithResult(call, result) "Messages#setNoMessagesReadWithResult" -> MessagesMethods.setNoMessagesReadWithResult(call, result) - + else -> result.notImplemented() } } @@ -99,56 +99,78 @@ class PluginHandler(private val applicationContext: Context) : MethodCallHandler if (token == null) { return result.error("ERROR", "Missing token", null) } + if (propertiesObj == null) { return result.error("ERROR", "Missing properties", null) } + val callRegion = propertiesObj["region"] as String? + val callDeferCA = propertiesObj["deferCA"] as Boolean? + + + val currentChatClient = TwilioConversationsPlugin.chatClient + val currentChatClientRegion = TwilioConversationsPlugin.chatClientRegion + val currentChatClientDeferCA = TwilioConversationsPlugin.chatClientDeferCA + try { - if (TwilioConversationsPlugin.chatClient == null) { + if (currentChatClient == null) { Log.d("TwilioInfo", "TwilioConversationsPlugin.create => making a fresh ChatClient") } else { - Log.d("TwilioInfo", "TwilioConversationsPlugin.create => ChatClient is already set, overriding") - TwilioConversationsPlugin.chatClient = null - Log.d("TwilioInfo", "TwilioConversationsPlugin.create => ChatClient is set to null") - } - val propertiesBuilder = ConversationsClient.Properties.newBuilder() - if (propertiesObj["region"] != null) { - Log.d("TwilioInfo", "TwilioConversationsPlugin.create => setting Properties.region to '${propertiesObj["region"]}'") - propertiesBuilder.setRegion(propertiesObj["region"] as String) - } - - if (propertiesObj["deferCA"] != null) { - Log.d("TwilioInfo", "TwilioConversationsPlugin.create => setting Properties.setDeferCertificateTrustToPlatform to '${propertiesObj["deferCA"]}'") - propertiesBuilder.setDeferCertificateTrustToPlatform(propertiesObj["deferCA"] as Boolean) + Log.w("TwilioInfo", "TwilioConversationsPlugin.create => ChatClient is already exists.") + if (callRegion != currentChatClientRegion) { + result.error("ERROR", "ChatClient already exists with a different region", null) + return + } else if (callDeferCA != currentChatClientDeferCA) { + result.error("ERROR", "ChatClient already exists with a different deferCA", null) + return } - - TwilioConversationsPlugin.chatListener = ChatListener(propertiesBuilder.createProperties()) - - ConversationsClient.create(applicationContext, token, TwilioConversationsPlugin.chatListener.properties, object : CallbackListener { - override fun onSuccess(chatClient: ConversationsClient) { - if (TwilioConversationsPlugin.chatClient == null) { - Log.d("Twilio init success", "TwilioConversationsPlugin.create => ChatClient.create onSuccess: myIdentity is '${chatClient.myIdentity}'") - try { - TwilioConversationsPlugin.chatClient = chatClient - val chatClientMap = Mapper.chatClientToMap(chatClient) - result.success(chatClientMap) - } catch (e: Exception) { - Log.d("TwilioInfo", "TwilioConversationsPlugin.create => ChatClient.create onSuccess: failed to give result") - Log.d("Twilio error", "TwilioConversationsPlugin.create => ChatClient.create onSuccess: failed to give result: $e : $chatClient : ${Mapper.chatClientToMap(chatClient)}") - result.error("$e", "Failed to map chatClient", null) - } - } - } + } + + val propertiesBuilder = ConversationsClient.Properties.newBuilder() + if (callRegion != null) { + Log.d("TwilioInfo", "TwilioConversationsPlugin.create => setting Properties.region to '${callRegion}'") + propertiesBuilder.setRegion(callRegion) + } + + if (callDeferCA != null) { + Log.d("TwilioInfo", "TwilioConversationsPlugin.create => setting Properties.setDeferCertificateTrustToPlatform to '${callDeferCA}'") + propertiesBuilder.setDeferCertificateTrustToPlatform(callDeferCA) + } + + pluginInstance.chatListener = ChatListener(pluginInstance, propertiesBuilder.createProperties()) - override fun onError(errorInfo: ErrorInfo) { - try { - with(TwilioConversationsPlugin) { debug("TwilioConversationsPlugin.create => ChatClient.create onError: $errorInfo") } - result.error("${errorInfo.code}", errorInfo.message, errorInfo.status) - } catch (e1: Exception) { - Log.d("TwilioInfo", "TwilioConversationsPlugin.create => ChatClient.create error: failed to send result of onError: $e1") - } + if (currentChatClient != null) { + val chatClientMap = Mapper.chatClientToMap(pluginInstance, currentChatClient) + result.success(chatClientMap) + return + } + + ConversationsClient.create(applicationContext, token, pluginInstance.chatListener.properties, object : CallbackListener { + override fun onSuccess(chatClient: ConversationsClient) { + Log.d("Twilio init success", "TwilioConversationsPlugin.create => ChatClient.create onSuccess: myIdentity is '${chatClient.myIdentity}'") + try { + TwilioConversationsPlugin.chatClient = chatClient + TwilioConversationsPlugin.chatClientRegion = callRegion + TwilioConversationsPlugin.chatClientDeferCA = callDeferCA + + val chatClientMap = Mapper.chatClientToMap(pluginInstance, chatClient) + result.success(chatClientMap) + } catch (e: Exception) { + Log.d("TwilioInfo", "TwilioConversationsPlugin.create => ChatClient.create onSuccess: failed to give result") + Log.d("Twilio error", "TwilioConversationsPlugin.create => ChatClient.create onSuccess: failed to give result: $e : $chatClient : ${Mapper.chatClientToMap(pluginInstance, chatClient)}") + result.error("$e", "Failed to map chatClient", null) } - }) + } + + override fun onError(errorInfo: ErrorInfo) { + try { + with(pluginInstance) { debug("TwilioConversationsPlugin.create => ChatClient.create onError: $errorInfo") } + result.error("${errorInfo.code}", errorInfo.message, errorInfo.status) + } catch (e1: Exception) { + Log.d("TwilioInfo", "TwilioConversationsPlugin.create => ChatClient.create error: failed to send result of onError: $e1") + } + } + }) } catch (e: Exception) { result.error("ERROR", e.toString(), e) } @@ -163,7 +185,7 @@ class PluginHandler(private val applicationContext: Context) : MethodCallHandler } if (enableNative != null) { - TwilioConversationsPlugin.nativeDebug = enableNative + pluginInstance.nativeDebug = enableNative result.success(enableNative) } else { result.error("MISSING_PARAMS", "Missing 'native' parameter", null) diff --git a/android/src/main/kotlin/twilio/flutter/twilio_conversations/TwilioConversationsPlugin.kt b/android/src/main/kotlin/twilio/flutter/twilio_conversations/TwilioConversationsPlugin.kt index 7ca9de5..7c30ad2 100644 --- a/android/src/main/kotlin/twilio/flutter/twilio_conversations/TwilioConversationsPlugin.kt +++ b/android/src/main/kotlin/twilio/flutter/twilio_conversations/TwilioConversationsPlugin.kt @@ -4,7 +4,6 @@ import android.content.Context import android.os.Handler import android.os.Looper import android.util.Log -import androidx.annotation.NonNull import com.twilio.conversations.ConversationsClient import com.twilio.util.ErrorInfo import com.twilio.conversations.StatusListener @@ -13,12 +12,20 @@ import io.flutter.plugin.common.BinaryMessenger import io.flutter.plugin.common.EventChannel import io.flutter.plugin.common.MethodCall import io.flutter.plugin.common.MethodChannel -import io.flutter.plugin.common.PluginRegistry.Registrar import twilio.flutter.twilio_conversations.listeners.ChannelListener import twilio.flutter.twilio_conversations.listeners.ChatListener /** TwilioConversationsPlugin */ class TwilioConversationsPlugin : FlutterPlugin { + companion object { + const val LOG_TAG = "Twilio_PChat" + + // One Twilio conversation client and each Flutter engine will have it's own listener + var chatClient: ConversationsClient? = null + var chatClientRegion: String? = null + var chatClientDeferCA: Boolean? = null + } + private lateinit var methodChannel: MethodChannel private lateinit var chatChannel: EventChannel @@ -29,76 +36,40 @@ class TwilioConversationsPlugin : FlutterPlugin { private lateinit var notificationChannel: EventChannel - // This static function is optional and equivalent to onAttachedToEngine. It supports the old - // pre-Flutter-1.12 Android projects. You are encouraged to continue supporting - // plugin registration via this function while apps migrate to use the new Android APIs - // post-flutter-1.12 via https://flutter.dev/go/android-project-migration. - // - // It is encouraged to share logic between onAttachedToEngine and registerWith to keep - // them functionally equivalent. Only one of onAttachedToEngine or registerWith will be called - // depending on the user's project. onAttachedToEngine or registerWith must both be defined - // in the same class. - companion object { - @Suppress("unused") - @JvmStatic - fun registerWith(registrar: Registrar) { - instance = TwilioConversationsPlugin() - instance.onAttachedToEngine(registrar.context(), registrar.messenger()) - } - - lateinit var messenger: BinaryMessenger + lateinit var messenger: BinaryMessenger - @JvmStatic - lateinit var instance: TwilioConversationsPlugin + lateinit var chatListener: ChatListener - private var initialized = false + var mediaProgressSink: EventChannel.EventSink? = null - var chatClient: ConversationsClient? = null - - val LOG_TAG = "Twilio_PChat" - - var mediaProgressSink: EventChannel.EventSink? = null - - var loggingSink: EventChannel.EventSink? = null + var loggingSink: EventChannel.EventSink? = null - var notificationSink: EventChannel.EventSink? = null + var notificationSink: EventChannel.EventSink? = null - var handler = Handler(Looper.getMainLooper()) + var handler = Handler(Looper.getMainLooper()) - var nativeDebug: Boolean = false + var channelChannels: HashMap = hashMapOf() + var channelListeners: HashMap = hashMapOf() - lateinit var chatListener: ChatListener + var nativeDebug: Boolean = false - var channelChannels: HashMap = hashMapOf() - var channelListeners: HashMap = hashMapOf() - - @JvmStatic - fun debug(msg: String) { - if (nativeDebug) { - Log.d(LOG_TAG, msg) - handler.post(Runnable { - loggingSink?.success(msg) - }) + fun debug(msg: String) { + if (nativeDebug) { + Log.d(LOG_TAG, msg) + handler.post { + loggingSink?.success(msg) } } } override fun onAttachedToEngine(binding: FlutterPlugin.FlutterPluginBinding) { - if (initialized) { - debug("TwilioConversationsPlugin.onAttachedToEngine => return") - return - } else { - debug("TwilioConversationsPlugin.onAttachedToEngine => initializing") - } - - initialized = true - instance = this onAttachedToEngine(binding.applicationContext, binding.binaryMessenger) } - private fun onAttachedToEngine(applicationContext: Context, messenger: BinaryMessenger) { - TwilioConversationsPlugin.messenger = messenger - val pluginHandler = PluginHandler(applicationContext) + private fun onAttachedToEngine(applicationContext: Context, binaryMessenger: BinaryMessenger) { + messenger = binaryMessenger + + val pluginHandler = PluginHandler(this, applicationContext) methodChannel = MethodChannel(messenger, "flutter_twilio_conversations") methodChannel.setMethodCallHandler(pluginHandler) @@ -156,7 +127,7 @@ class TwilioConversationsPlugin : FlutterPlugin { }) } - override fun onDetachedFromEngine(@NonNull binding: FlutterPlugin.FlutterPluginBinding) { + override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) { debug("TwilioConversationsPlugin.onDetachedFromEngine") methodChannel.setMethodCallHandler(null) chatChannel.setStreamHandler(null) @@ -165,7 +136,6 @@ class TwilioConversationsPlugin : FlutterPlugin { mediaProgressChannel.setStreamHandler(null) channelChannels.clear() channelListeners.clear() - initialized = false } fun registerForNotification(call: MethodCall, result: MethodChannel.Result) { diff --git a/android/src/main/kotlin/twilio/flutter/twilio_conversations/listeners/ChannelListener.kt b/android/src/main/kotlin/twilio/flutter/twilio_conversations/listeners/ChannelListener.kt index 83861dd..3b12792 100644 --- a/android/src/main/kotlin/twilio/flutter/twilio_conversations/listeners/ChannelListener.kt +++ b/android/src/main/kotlin/twilio/flutter/twilio_conversations/listeners/ChannelListener.kt @@ -6,8 +6,9 @@ import io.flutter.plugin.common.EventChannel import twilio.flutter.twilio_conversations.Mapper import com.twilio.util.ErrorInfo import android.util.Log +import twilio.flutter.twilio_conversations.TwilioConversationsPlugin -class ChannelListener(private val events: EventChannel.EventSink) : TwilioChannelListener { +class ChannelListener(private val pluginInstance: TwilioConversationsPlugin, private val events: EventChannel.EventSink) : TwilioChannelListener { override fun onMessageAdded(message: Message) { Log.d("TwilioInfo", "ChannelListener.onMessageAdded => messageSid = ${message.sid}") sendEvent("messageAdded", mapOf("message" to Mapper.messageToMap(message))) @@ -54,17 +55,17 @@ class ChannelListener(private val events: EventChannel.EventSink) : TwilioChanne override fun onTypingStarted(channel: Conversation, member: Participant) { Log.d("TwilioInfo", "ChannelListener.onTypingStarted => channelSid = ${channel.sid}, memberSid = ${member.sid}") - sendEvent("typingStarted", mapOf("channel" to Mapper.channelToMap(channel), "member" to Mapper.memberToMap(member))) + sendEvent("typingStarted", mapOf("channel" to Mapper.channelToMap(pluginInstance, channel), "member" to Mapper.memberToMap(member))) } override fun onTypingEnded(channel: Conversation, member: Participant) { Log.d("TwilioInfo", "ChannelListener.onTypingEnded => channelSid = ${channel.sid}, memberSid = ${member.sid}") - sendEvent("typingEnded", mapOf("channel" to Mapper.channelToMap(channel), "member" to Mapper.memberToMap(member))) + sendEvent("typingEnded", mapOf("channel" to Mapper.channelToMap(pluginInstance, channel), "member" to Mapper.memberToMap(member))) } override fun onSynchronizationChanged(channel: Conversation) { Log.d("TwilioInfo", "ChannelListener.onSynchronizationChanged => channelSid = ${channel.sid}") - sendEvent("synchronizationChanged", mapOf("channel" to Mapper.channelToMap(channel))) + sendEvent("synchronizationChanged", mapOf("channel" to Mapper.channelToMap(pluginInstance, channel))) } private fun sendEvent(name: String, data: Any?, e: ErrorInfo? = null) { diff --git a/android/src/main/kotlin/twilio/flutter/twilio_conversations/listeners/ChatListener.kt b/android/src/main/kotlin/twilio/flutter/twilio_conversations/listeners/ChatListener.kt index 9108b02..84b4ed4 100644 --- a/android/src/main/kotlin/twilio/flutter/twilio_conversations/listeners/ChatListener.kt +++ b/android/src/main/kotlin/twilio/flutter/twilio_conversations/listeners/ChatListener.kt @@ -5,8 +5,9 @@ import io.flutter.plugin.common.EventChannel import twilio.flutter.twilio_conversations.Mapper import com.twilio.util.ErrorInfo import android.util.Log +import twilio.flutter.twilio_conversations.TwilioConversationsPlugin -class ChatListener(val properties: ConversationsClient.Properties) : ConversationsClientListener { +class ChatListener(private val pluginInstance: TwilioConversationsPlugin, val properties: ConversationsClient.Properties) : ConversationsClientListener { var events: EventChannel.EventSink? = null override fun onClientSynchronization(synchronizationStatus: ConversationsClient.SynchronizationStatus) { @@ -16,7 +17,7 @@ class ChatListener(val properties: ConversationsClient.Properties) : Conversatio override fun onConversationSynchronizationChange(conversation: Conversation?) { Log.d("TwilioInfo", "ChatListener.onConversationSynchronizationChange => conversation = '${conversation?.sid}' ") - sendEvent("channelSynchronizationChange", mapOf("channel" to Mapper.channelToMap(conversation!!))) + sendEvent("channelSynchronizationChange", mapOf("channel" to Mapper.channelToMap(pluginInstance, conversation!!))) } override fun onConnectionStateChange(connectionState: ConversationsClient.ConnectionState) { @@ -28,11 +29,6 @@ class ChatListener(val properties: ConversationsClient.Properties) : Conversatio sendEvent("error", null, errorInfo) } -// override fun onInvitedToChannelNotification(channelSid: String) { -// Log.d("TwilioInfo", "ChatListener.onInvitedToChannelNotification => channelSid = $channelSid") -// sendEvent("invitedToChannelNotification", mapOf("channelSid" to channelSid)) -// } - override fun onNewMessageNotification(channelSid: String?, messageSid: String?, messageIndex: Long) { Log.d("TwilioInfo", "ChatListener.onNewMessageNotification => channelSid = $channelSid, messageSid = $messageSid, messageIndex = $messageIndex") sendEvent("newMessageNotification", mapOf( @@ -81,7 +77,7 @@ class ChatListener(val properties: ConversationsClient.Properties) : Conversatio override fun onConversationUpdated(conversation: Conversation?, reason: Conversation.UpdateReason?) { Log.d("TwilioInfo", "ChatListener.onConversationUpdated => conversation '${conversation?.sid}' updated, $reason") sendEvent("channelUpdated", mapOf( - "channel" to Mapper.channelToMap(conversation!!), + "channel" to Mapper.channelToMap(pluginInstance, conversation!!), "reason" to mapOf( "type" to "channel", "value" to reason.toString() @@ -92,7 +88,7 @@ class ChatListener(val properties: ConversationsClient.Properties) : Conversatio override fun onConversationAdded(conversation: Conversation?) { Log.d("TwilioInfo", "ChatListener.onConversationAdded => conversation '${conversation?.sid}' added") sendEvent("channelAdded", mapOf( - "channel" to Mapper.channelToMap(conversation!!) + "channel" to Mapper.channelToMap(pluginInstance, conversation!!) )) } @@ -110,7 +106,7 @@ class ChatListener(val properties: ConversationsClient.Properties) : Conversatio override fun onConversationDeleted(conversation: Conversation?) { Log.d("TwilioInfo", "ChatListener.onConversationDeleted => conversation '${conversation?.sid}' deleted") sendEvent("channelDeleted", mapOf( - "channel" to Mapper.channelToMap(conversation!!) + "channel" to Mapper.channelToMap(pluginInstance, conversation!!) )) } diff --git a/android/src/main/kotlin/twilio/flutter/twilio_conversations/methods/ChannelsMethods.kt b/android/src/main/kotlin/twilio/flutter/twilio_conversations/methods/ChannelsMethods.kt index f419995..aa14c69 100644 --- a/android/src/main/kotlin/twilio/flutter/twilio_conversations/methods/ChannelsMethods.kt +++ b/android/src/main/kotlin/twilio/flutter/twilio_conversations/methods/ChannelsMethods.kt @@ -10,15 +10,14 @@ import twilio.flutter.twilio_conversations.TwilioConversationsPlugin import android.util.Log object ChannelsMethods { - - fun getChannel(call: MethodCall, result: MethodChannel.Result) { + fun getChannel(pluginInstance: TwilioConversationsPlugin, call: MethodCall, result: MethodChannel.Result) { val channelSidOrUniqueName = call.argument("channelSidOrUniqueName") ?: return result.error("ERROR", "Missing 'channelSidOrUniqueName'", null) TwilioConversationsPlugin.chatClient?.getConversation(channelSidOrUniqueName, object : CallbackListener { override fun onSuccess(newChannel: Conversation) { Log.d("TwilioInfo", "ChannelsMethods.getChannel => onSuccess") - result.success(Mapper.channelToMap(newChannel)) + result.success(Mapper.channelToMap(pluginInstance, newChannel)) } override fun onError(errorInfo: ErrorInfo) { @@ -36,14 +35,14 @@ object ChannelsMethods { result.success(TwilioConversationsPlugin.chatClient?.myConversations) } - fun createChannel(call: MethodCall, result: MethodChannel.Result) { + fun createChannel(pluginInstance: TwilioConversationsPlugin, call: MethodCall, result: MethodChannel.Result) { val friendlyName = call.argument("friendlyName") ?: return result.error("ERROR", "Missing 'friendlyName'", null) TwilioConversationsPlugin.chatClient?.createConversation(friendlyName, object : CallbackListener { override fun onSuccess(newChannel: Conversation) { Log.d("TwilioInfo", "ChannelsMethods.createChannel => onSuccess") - result.success(Mapper.channelToMap(newChannel)) + result.success(Mapper.channelToMap(pluginInstance, newChannel)) } override fun onError(errorInfo: ErrorInfo) { diff --git a/android/src/main/kotlin/twilio/flutter/twilio_conversations/methods/ChatClientMethods.kt b/android/src/main/kotlin/twilio/flutter/twilio_conversations/methods/ChatClientMethods.kt index 0d0d85e..0cbb6b9 100644 --- a/android/src/main/kotlin/twilio/flutter/twilio_conversations/methods/ChatClientMethods.kt +++ b/android/src/main/kotlin/twilio/flutter/twilio_conversations/methods/ChatClientMethods.kt @@ -28,6 +28,10 @@ object ChatClientMethods { fun shutdown(call: MethodCall, result: MethodChannel.Result) { return try { TwilioConversationsPlugin.chatClient?.shutdown() + TwilioConversationsPlugin.chatClient = null + TwilioConversationsPlugin.chatClientRegion = null + TwilioConversationsPlugin.chatClientDeferCA = null + result.success(null) } catch (err: Exception) { result.error("ERROR", err.message, null) diff --git a/android/src/main/kotlin/twilio/flutter/twilio_conversations/methods/MemberMethods.kt b/android/src/main/kotlin/twilio/flutter/twilio_conversations/methods/MemberMethods.kt index 3e75763..f1c4318 100644 --- a/android/src/main/kotlin/twilio/flutter/twilio_conversations/methods/MemberMethods.kt +++ b/android/src/main/kotlin/twilio/flutter/twilio_conversations/methods/MemberMethods.kt @@ -10,14 +10,14 @@ import com.twilio.util.ErrorInfo import android.util.Log object MemberMethods { - fun getChannel(call: MethodCall, result: MethodChannel.Result) { + fun getChannel(pluginInstance: TwilioConversationsPlugin, call: MethodCall, result: MethodChannel.Result) { val channelSid = call.argument("channelSid") ?: return result.error("ERROR", "Missing 'channelSid'", null) TwilioConversationsPlugin.chatClient?.getConversation(channelSid, object : CallbackListener { override fun onSuccess(channel: Conversation) { Log.d("TwilioInfo", "MemberMethods.getChannel => onSuccess") - result.success(Mapper.channelToMap(channel)) + result.success(Mapper.channelToMap(pluginInstance, channel)) } override fun onError(errorInfo: ErrorInfo) { diff --git a/android/src/main/kotlin/twilio/flutter/twilio_conversations/methods/MembersMethods.kt b/android/src/main/kotlin/twilio/flutter/twilio_conversations/methods/MembersMethods.kt index 09a7ff3..69c0048 100644 --- a/android/src/main/kotlin/twilio/flutter/twilio_conversations/methods/MembersMethods.kt +++ b/android/src/main/kotlin/twilio/flutter/twilio_conversations/methods/MembersMethods.kt @@ -9,14 +9,14 @@ import com.twilio.util.ErrorInfo import android.util.Log object MembersMethods { - fun getChannel(call: MethodCall, result: MethodChannel.Result) { + fun getChannel(pluginInstance: TwilioConversationsPlugin, call: MethodCall, result: MethodChannel.Result) { val channelSid = call.argument("channelSid") ?: return result.error("ERROR", "Missing 'channelSid'", null) TwilioConversationsPlugin.chatClient?.getConversation(channelSid, object : CallbackListener { override fun onSuccess(channel: Conversation) { Log.d("TwilioInfo", "MembersMethods.getChannel => onSuccess") - result.success(Mapper.channelToMap(channel)) + result.success(Mapper.channelToMap(pluginInstance, channel)) } override fun onError(errorInfo: ErrorInfo) { diff --git a/android/src/main/kotlin/twilio/flutter/twilio_conversations/methods/MessageMethods.kt b/android/src/main/kotlin/twilio/flutter/twilio_conversations/methods/MessageMethods.kt index f2113de..7b76ce0 100644 --- a/android/src/main/kotlin/twilio/flutter/twilio_conversations/methods/MessageMethods.kt +++ b/android/src/main/kotlin/twilio/flutter/twilio_conversations/methods/MessageMethods.kt @@ -10,14 +10,14 @@ import twilio.flutter.twilio_conversations.TwilioConversationsPlugin import android.util.Log object MessageMethods { - fun getChannel(call: MethodCall, result: MethodChannel.Result) { + fun getChannel(pluginInstance: TwilioConversationsPlugin, call: MethodCall, result: MethodChannel.Result) { val channelSid = call.argument("channelSid") ?: return result.error("ERROR", "Missing 'channelSid'", null) TwilioConversationsPlugin.chatClient?.getConversation(channelSid, object : CallbackListener { override fun onSuccess(channel: Conversation) { Log.d("TwilioInfo", "MessageMethods.getChannel => onSuccess") - result.success(Mapper.channelToMap(channel)) + result.success(Mapper.channelToMap(pluginInstance, channel)) } override fun onError(errorInfo: ErrorInfo) { @@ -136,7 +136,7 @@ object MessageMethods { val messageIndex = call.argument("messageIndex")?.toLong() ?: return result.error("ERROR", "Missing 'messageIndex'", null) - TwilioConversationsPlugin.chatClient?.getConversation(channelSid, object : CallbackListener { + TwilioConversationsPlugin.chatClient?.getConversation(channelSid, object : CallbackListener { override fun onSuccess(channel: Conversation) { Log.d("TwilioInfo", "MessageMethods.getMedia => onSuccess") channel.getMessageByIndex(messageIndex, object : CallbackListener { diff --git a/android/src/main/kotlin/twilio/flutter/twilio_conversations/methods/MessagesMethods.kt b/android/src/main/kotlin/twilio/flutter/twilio_conversations/methods/MessagesMethods.kt index d19c95e..b38ede0 100644 --- a/android/src/main/kotlin/twilio/flutter/twilio_conversations/methods/MessagesMethods.kt +++ b/android/src/main/kotlin/twilio/flutter/twilio_conversations/methods/MessagesMethods.kt @@ -10,14 +10,14 @@ import com.twilio.util.ErrorInfo import android.util.Log object MessagesMethods { - fun sendMessage(call: MethodCall, result: MethodChannel.Result) { + fun sendMessage(pluginInstance: TwilioConversationsPlugin, call: MethodCall, result: MethodChannel.Result) { val options = call.argument>("options") ?: return result.error("ERROR", "Missing 'options'", null) val channelSid = call.argument("channelSid") ?: return result.error("ERROR", "Missing 'channelSid'", null) Log.d("TwilioInfo", "MessagesMethods.sendMessage => started") - + TwilioConversationsPlugin.chatClient?.getConversation(channelSid, object : CallbackListener { override fun onSuccess(channel: Conversation) { Log.d("TwilioInfo", "MessagesMethods.sendMessage (Channels.getChannel) => onSuccess") @@ -40,7 +40,7 @@ object MessagesMethods { channel.prepareMessage().addMedia(FileInputStream(input), mimeType, "image.jpeg", object : MediaUploadListener { override fun onCompleted(mediaSid: String) { Log.d("TwilioInfo", "MessagesMethods.sendMessage (Message.addMedia) => onCompleted") - TwilioConversationsPlugin.mediaProgressSink?.success({ + pluginInstance.mediaProgressSink?.success({ "mediaProgressListenerId" to options["mediaProgressListenerId"] "name" to "completed" "data" to mediaSid @@ -49,7 +49,7 @@ object MessagesMethods { override fun onStarted() { Log.d("TwilioInfo", "MessagesMethods.sendMessage (Message.addMedia) => onStarted") - TwilioConversationsPlugin.mediaProgressSink?.success({ + pluginInstance.mediaProgressSink?.success({ "mediaProgressListenerId" to options["mediaProgressListenerId"] "name" to "started" })