diff --git a/.idea/libraries/Dart_SDK.xml b/.idea/libraries/Dart_SDK.xml index e7bbf3c..170212a 100644 --- a/.idea/libraries/Dart_SDK.xml +++ b/.idea/libraries/Dart_SDK.xml @@ -1,26 +1,26 @@ - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + diff --git a/README.md b/README.md index 7ed4b16..f09fcd0 100644 --- a/README.md +++ b/README.md @@ -8,3 +8,22 @@ For help getting started with Flutter, view our online [documentation](https://flutter.io/). For help on editing plugin code, view the [documentation](https://flutter.io/developing-packages/#edit-plugin-package). + +## Release Notes +### Flutter v1 +- Version 1.0.0-no-null-safety: + + Add feature: live chat +- Version 1.1.0-no-null-safety: + + Add feature: video conference in android + + Add feature: share screen in StringeeCall2 in android + +### Flutter v2 +- Version 1.0.0: + + Add feature: live chat +- Version 1.1.0: + + Upgrade sdk +- Version 1.2.0: + + Add feature: video conference in android + + Add feature: share screen in StringeeCall2 in android +- Version 1.2.1: + + Fix bug: fix StringeeVideoView in android \ No newline at end of file diff --git a/android/build.gradle b/android/build.gradle index c0e80b0..a9f68af 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -40,7 +40,7 @@ android { dependencies { implementation fileTree(dir: "libs", include: ["*.jar", "*.aar"]) - implementation 'com.stringee.sdk.android:stringee-android-sdk:1.7.9' + implementation 'com.stringee.sdk.android:stringee-android-sdk:1.8.0' implementation 'androidx.annotation:annotation:1.2.0' - implementation 'com.android.volley:volley:1.1.0' + implementation 'com.android.volley:volley:1.2.1' } \ No newline at end of file diff --git a/android/src/main/java/com/stringee/stringeeflutterplugin/Call2Wrapper.java b/android/src/main/java/com/stringee/stringeeflutterplugin/Call2Wrapper.java index 661d072..b5693dd 100644 --- a/android/src/main/java/com/stringee/stringeeflutterplugin/Call2Wrapper.java +++ b/android/src/main/java/com/stringee/stringeeflutterplugin/Call2Wrapper.java @@ -34,6 +34,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Random; import java.util.Set; import io.flutter.plugin.common.MethodChannel.Result; @@ -564,7 +565,7 @@ public void startCapture(final Result result) { } if (VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) { - int REQUEST_CODE = (int) System.currentTimeMillis(); + final int REQUEST_CODE = new Random().nextInt(65536); _manager.getCaptureManager().getActivityResult(new ActivityResultListener() { @Override diff --git a/android/src/main/java/com/stringee/stringeeflutterplugin/ClientWrapper.java b/android/src/main/java/com/stringee/stringeeflutterplugin/ClientWrapper.java index 18e7d71..d8167d5 100644 --- a/android/src/main/java/com/stringee/stringeeflutterplugin/ClientWrapper.java +++ b/android/src/main/java/com/stringee/stringeeflutterplugin/ClientWrapper.java @@ -24,8 +24,8 @@ import com.stringee.messaging.StringeeObject.Type; import com.stringee.messaging.User; import com.stringee.messaging.listeners.CallbackListener; -import com.stringee.messaging.listeners.ChangeEventListenter; -import com.stringee.messaging.listeners.LiveChatEventListerner; +import com.stringee.messaging.listeners.ChangeEventListener; +import com.stringee.messaging.listeners.LiveChatEventListener; import com.stringee.messaging.listeners.UserTypingEventListener; import com.stringee.stringeeflutterplugin.StringeeManager.StringeeCallType; @@ -39,7 +39,7 @@ import io.flutter.plugin.common.MethodChannel.Result; -public class ClientWrapper implements StringeeConnectionListener, ChangeEventListenter, LiveChatEventListerner, UserTypingEventListener { +public class ClientWrapper implements StringeeConnectionListener, ChangeEventListener, LiveChatEventListener, UserTypingEventListener { private StringeeClient _client; private StringeeManager _manager; private ConversationManager _conversationManager; @@ -79,8 +79,8 @@ public ClientWrapper(final String uuid, final String baseAPIUrl) { private void setListener() { _client.setConnectionListener(this); - _client.setChangeEventListenter(this); - _client.setLiveChatEventListerner(this); + _client.setChangeEventListener(this); + _client.setLiveChatEventListener(this); _client.setUserTypingEventListener(this); } diff --git a/android/src/main/java/com/stringee/stringeeflutterplugin/ConversationManager.java b/android/src/main/java/com/stringee/stringeeflutterplugin/ConversationManager.java index b6260c8..a2d308c 100644 --- a/android/src/main/java/com/stringee/stringeeflutterplugin/ConversationManager.java +++ b/android/src/main/java/com/stringee/stringeeflutterplugin/ConversationManager.java @@ -1396,7 +1396,7 @@ public void beginTyping(String convId, final Result result) { Utils.getConversation(_clientWrapper.getClient(), convId, new CallbackListener() { @Override public void onSuccess(Conversation conversation) { - conversation.beginTyping(_clientWrapper.getClient(), new StatusListener() { + conversation.beginTyping(_clientWrapper.getClient(), new StatusListener() { @Override public void onSuccess() { _handler.post(new Runnable() { @@ -1478,7 +1478,7 @@ public void endTyping(String convId, final Result result) { Utils.getConversation(_clientWrapper.getClient(), convId, new CallbackListener() { @Override public void onSuccess(Conversation conversation) { - conversation.endTyping(_clientWrapper.getClient(), new StatusListener() { + conversation.endTyping(_clientWrapper.getClient(), new StatusListener() { @Override public void onSuccess() { _handler.post(new Runnable() { diff --git a/android/src/main/java/com/stringee/stringeeflutterplugin/RoomManager.java b/android/src/main/java/com/stringee/stringeeflutterplugin/RoomManager.java index b4d4e19..54114cc 100644 --- a/android/src/main/java/com/stringee/stringeeflutterplugin/RoomManager.java +++ b/android/src/main/java/com/stringee/stringeeflutterplugin/RoomManager.java @@ -5,6 +5,8 @@ import android.os.Handler; import android.util.Log; +import com.stringee.common.StringeeAudioManager.AudioDevice; +import com.stringee.common.StringeeAudioManager.AudioManagerEvents; import com.stringee.exception.StringeeError; import com.stringee.listener.StatusListener; import com.stringee.listener.StringeeRoomListener; @@ -19,6 +21,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Set; import io.flutter.plugin.common.MethodChannel.Result; @@ -233,7 +236,7 @@ public void run() { } public void sendMessage(final JSONObject msg, final Result result) { - _stringeeRoom.sendMessge(msg, new StatusListener() { + _stringeeRoom.sendMessage(msg, new StatusListener() { @Override public void onSuccess() { _handler.post(new Runnable() { @@ -298,6 +301,27 @@ public void run() { _connectRoomResult.success(map); _videoConferenceManager.getRoomsMap().put(stringeeRoom.getId(), RoomManager.this); + + _manager.startAudioManager(_manager.getContext(), new AudioManagerEvents() { + @Override + public void onAudioDeviceChanged(final AudioDevice selectedAudioDevice, final Set availableAudioDevices) { + _handler.post(new Runnable() { + @Override + public void run() { + Log.d(TAG, "onAudioDeviceChanged: " + availableAudioDevices + ", " + "selected: " + selectedAudioDevice); + switch (selectedAudioDevice) { + case BLUETOOTH: + case WIRED_HEADSET: + _manager.setSpeakerphoneOn(false); + break; + default: + _manager.setSpeakerphoneOn(true); + break; + } + } + }); + } + }); } }); } diff --git a/android/src/main/java/com/stringee/stringeeflutterplugin/StringeeFlutterPlugin.java b/android/src/main/java/com/stringee/stringeeflutterplugin/StringeeFlutterPlugin.java index 4f57ded..d79a1ca 100644 --- a/android/src/main/java/com/stringee/stringeeflutterplugin/StringeeFlutterPlugin.java +++ b/android/src/main/java/com/stringee/stringeeflutterplugin/StringeeFlutterPlugin.java @@ -326,7 +326,7 @@ public void onMethodCall(MethodCall call, final Result result) { option.setDistinct(optionObject.getBoolean("isDistinct")); option.setOaId(optionObject.optString("oaId").trim()); option.setCustomData(optionObject.optString("customData").trim()); - option.setCreatorId(optionObject.optString("setCreatorId").trim()); + option.setCreatorId(optionObject.optString("creatorId").trim()); clientWrapper.createConversation(participants, option, result); } catch (JSONException e) { e.printStackTrace(); diff --git a/android/src/main/java/com/stringee/stringeeflutterplugin/StringeeManager.java b/android/src/main/java/com/stringee/stringeeflutterplugin/StringeeManager.java index 41c726c..9f04998 100644 --- a/android/src/main/java/com/stringee/stringeeflutterplugin/StringeeManager.java +++ b/android/src/main/java/com/stringee/stringeeflutterplugin/StringeeManager.java @@ -168,4 +168,15 @@ public void setSpeakerphoneOn(boolean on, Result result) { result.success(map); } } + + /** + * Set speaker on/off + * + * @param on + */ + public void setSpeakerphoneOn(boolean on) { + if (audioManager != null) { + audioManager.setSpeakerphoneOn(on); + } + } } \ No newline at end of file diff --git a/android/src/main/java/com/stringee/stringeeflutterplugin/VideoConferenceManager.java b/android/src/main/java/com/stringee/stringeeflutterplugin/VideoConferenceManager.java index 4d2e23c..5c01e67 100644 --- a/android/src/main/java/com/stringee/stringeeflutterplugin/VideoConferenceManager.java +++ b/android/src/main/java/com/stringee/stringeeflutterplugin/VideoConferenceManager.java @@ -15,6 +15,7 @@ import java.util.HashMap; import java.util.Map; +import java.util.Random; import io.flutter.plugin.common.MethodChannel.Result; import io.flutter.plugin.common.PluginRegistry.ActivityResultListener; @@ -107,7 +108,7 @@ public void createCaptureScreenTrack(final String localId, final Result result) } if (VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) { - int REQUEST_CODE = (int) System.currentTimeMillis(); + final int REQUEST_CODE = new Random().nextInt(65536); _manager.getCaptureManager().getActivityResult(new ActivityResultListener() { @Override diff --git a/example/lib/button/circle_button.dart b/example/lib/button/circle_button.dart index f8e7860..194f9df 100644 --- a/example/lib/button/circle_button.dart +++ b/example/lib/button/circle_button.dart @@ -1,14 +1,14 @@ import 'package:flutter/material.dart'; class CircleButton extends StatelessWidget { - Icon? icon; - Color? primary; - VoidCallback? onPressed; + Icon icon; + Color primary; + VoidCallback onPressed; CircleButton({ - required this.icon, - required this.primary, - required this.onPressed, + this.icon, + this.primary, + this.onPressed, }); @override diff --git a/example/lib/button/rounded_button.dart b/example/lib/button/rounded_button.dart index f2775df..b388cdc 100644 --- a/example/lib/button/rounded_button.dart +++ b/example/lib/button/rounded_button.dart @@ -7,10 +7,10 @@ class RoundedButton extends StatelessWidget { Color color; RoundedButton({ - required this.icon, - required this.color, - required this.radius, - required this.onPressed, + this.icon, + this.color, + this.radius, + this.onPressed, }); @override diff --git a/example/lib/tab/call_tab.dart b/example/lib/tab/call_tab.dart index 8f1f3c3..aec6ad2 100644 --- a/example/lib/tab/call_tab.dart +++ b/example/lib/tab/call_tab.dart @@ -187,7 +187,7 @@ class CallTabState extends State { //region Handle Client Event void handleDidConnectEvent() { setState(() { - myUserId = client.userId!; + myUserId = client.userId; }); } @@ -218,8 +218,8 @@ class CallTabState extends State { MaterialPageRoute( builder: (context) => Call( client, - call.from!, - call.to!, + call.from, + call.to, true, call.isVideoCall, StringeeObjectEventType.call, @@ -235,8 +235,8 @@ class CallTabState extends State { MaterialPageRoute( builder: (context) => Call( client, - call.from!, - call.to!, + call.from, + call.to, true, call.isVideoCall, StringeeObjectEventType.call2, @@ -254,7 +254,7 @@ class CallTabState extends State { MaterialPageRoute( builder: (context) => Call( client, - client.userId!, + client.userId, toUser, false, isVideoCall, diff --git a/example/lib/tab/chat_tab.dart b/example/lib/tab/chat_tab.dart index 53d2b56..27a716d 100644 --- a/example/lib/tab/chat_tab.dart +++ b/example/lib/tab/chat_tab.dart @@ -62,9 +62,9 @@ class ChatTabState extends State { if (map['eventType'] == StringeeChatEvents.didReceiveObjectChange) { StringeeObjectChange objectChange = map['body']; if (objectChange.objectType == ObjectType.conversation) { - StringeeConversation conversation = objectChange.objects!.first; + StringeeConversation conversation = objectChange.objects.first; setState(() { - _log.add(conversation.id! + ' ' + objectChange.type.toString()); + _log.add(conversation.id + ' ' + objectChange.type.toString()); }); } } @@ -170,10 +170,10 @@ class ChatTabState extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - 'convId: ' + _conversations[index].id!, + 'convId: ' + _conversations[index].id, ), Text( - 'name: ' + _conversations[index].name!, + 'name: ' + _conversations[index].name, ), ], )), @@ -516,7 +516,7 @@ class ChatTabState extends State { //region Handle Client Event void handleDidConnectEvent() { setState(() { - myUserId = client.userId!; + myUserId = client.userId; }); } diff --git a/example/lib/tab/conference_tab.dart b/example/lib/tab/conference_tab.dart index 721c5af..06bf8d1 100644 --- a/example/lib/tab/conference_tab.dart +++ b/example/lib/tab/conference_tab.dart @@ -101,7 +101,7 @@ class ConferenceTabState extends State { //region Handle Client Event void handleDidConnectEvent() { setState(() { - myUserId = client.userId!; + myUserId = client.userId; }); } diff --git a/example/lib/ui/agent.dart b/example/lib/ui/agent.dart index ee32d5a..465fbdb 100644 --- a/example/lib/ui/agent.dart +++ b/example/lib/ui/agent.dart @@ -17,8 +17,8 @@ class AgentPageState extends State String token = ''; String userId = 'Not connected...'; - late StringeeChatRequest? _chatRequest; - late StringeeConversation _conversation; + StringeeChatRequest _chatRequest; + StringeeConversation _conversation; bool hasChatRequest = false; bool inConv = false; @@ -71,16 +71,16 @@ class AgentPageState extends State if (map['eventType'] == StringeeChatEvents.didReceiveObjectChange) { StringeeObjectChange objectChange = map['body']; if (objectChange.objectType == ObjectType.conversation) { - StringeeConversation conversation = objectChange.objects!.first; + StringeeConversation conversation = objectChange.objects.first; setState(() { - _log.add(conversation.id! + ' ' + objectChange.type.toString()); + _log.add(conversation.id + ' ' + objectChange.type.toString()); }); } if (objectChange.objectType == ObjectType.message) { - StringeeMessage message = objectChange.objects!.first; + StringeeMessage message = objectChange.objects.first; setState(() { _log.add((message.id != null) - ? message.id! + ? message.id : 'null' + ' ' + objectChange.type.toString()); }); } @@ -103,15 +103,13 @@ class AgentPageState extends State margin: EdgeInsets.only(right: 10.0), child: new ElevatedButton( onPressed: () { - _chatRequest!.accept().then((value) { + _chatRequest.accept().then((value) { bool status = value['status']; setState(() { _log.add('Accept chat request: msg:' + value['message']); }); if (status) { - chat - .getConversationById(_chatRequest!.convId) - .then((value) { + chat.getConversationById(_chatRequest.convId).then((value) { bool status = value['status']; setState(() { _log.add('get conversation: msg:' + value['message']); @@ -139,7 +137,7 @@ class AgentPageState extends State margin: EdgeInsets.only(left: 10.0), child: new ElevatedButton( onPressed: () { - _chatRequest!.reject().then((value) { + _chatRequest.reject().then((value) { bool status = value['status']; setState(() { _log.add('Reject chat request: msg:' + value['message']); @@ -285,7 +283,7 @@ class AgentPageState extends State void handleDidConnectEvent() { setState(() { - userId = client.userId!; + userId = client.userId; }); } diff --git a/example/lib/ui/call.dart b/example/lib/ui/call.dart index 913c809..75b0a22 100644 --- a/example/lib/ui/call.dart +++ b/example/lib/ui/call.dart @@ -6,13 +6,13 @@ import 'package:stringee_flutter_plugin/stringee_flutter_plugin.dart'; import 'package:stringee_flutter_plugin_example/button/circle_button.dart'; class Call extends StatefulWidget { - late StringeeClient _client; - late StringeeCall? _stringeeCall; - late StringeeCall2? _stringeeCall2; - late String _toUserId; - late String _fromUserId; - late String _callId; - late StringeeObjectEventType _callType; + StringeeClient _client; + StringeeCall _stringeeCall; + StringeeCall2 _stringeeCall2; + String _toUserId; + String _fromUserId; + String _callId; + StringeeObjectEventType _callType; bool _showIncomingUi = false; bool _isVideoCall = false; @@ -23,9 +23,9 @@ class Call extends StatefulWidget { bool showIncomingUi, bool isVideoCall, StringeeObjectEventType callType, { - Key? key, - StringeeCall2? stringeeCall2, - StringeeCall? stringeeCall, + Key key, + StringeeCall2 stringeeCall2, + StringeeCall stringeeCall, }) : super(key: key) { _client = client; _fromUserId = fromUserId; @@ -58,9 +58,9 @@ class _CallState extends State { bool _hasRemoteStream = false; bool _hasLocalScreen = false; - late StringeeVideoTrack _localScreenTrack; + StringeeVideoTrack _localScreenTrack; bool _hasRemoteScreen = false; - late StringeeVideoTrack _remoteScreenTrack; + StringeeVideoTrack _remoteScreenTrack; int _cameraId = 1; FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = @@ -322,7 +322,7 @@ class _CallState extends State { } // Listen events - widget._stringeeCall!.eventStreamController.stream.listen((event) { + widget._stringeeCall.eventStreamController.stream.listen((event) { Map map = event; print("Call " + map.toString()); switch (map['eventType']) { @@ -355,7 +355,7 @@ class _CallState extends State { }); if (widget._showIncomingUi) { - widget._stringeeCall!.initAnswer().then((event) { + widget._stringeeCall.initAnswer().then((event) { bool status = event['status']; if (!status) { clearDataEndDismiss(); @@ -370,12 +370,12 @@ class _CallState extends State { 'videoQuality': VideoQuality.fullHd, }; - widget._stringeeCall!.makeCall(parameters).then((result) { + widget._stringeeCall.makeCall(parameters).then((result) { bool status = result['status']; int code = result['code']; String message = result['message']; print( - 'MakeCall CallBack --- $status - $code - $message - ${widget._stringeeCall!.id} - ${widget._stringeeCall!.from} - ${widget._stringeeCall!.to}'); + 'MakeCall CallBack --- $status - $code - $message - ${widget._stringeeCall.id} - ${widget._stringeeCall.from} - ${widget._stringeeCall.to}'); if (!status) { Navigator.pop(context); } @@ -389,7 +389,7 @@ class _CallState extends State { } // Listen events - widget._stringeeCall2!.eventStreamController.stream.listen((event) { + widget._stringeeCall2.eventStreamController.stream.listen((event) { Map map = event; switch (map['eventType']) { case StringeeCall2Events.didChangeSignalingState: @@ -427,7 +427,7 @@ class _CallState extends State { }); if (widget._showIncomingUi) { - widget._stringeeCall2!.initAnswer().then((event) { + widget._stringeeCall2.initAnswer().then((event) { bool status = event['status']; if (!status) { clearDataEndDismiss(); @@ -442,12 +442,12 @@ class _CallState extends State { 'videoQuality': VideoQuality.fullHd, }; - widget._stringeeCall2!.makeCall(parameters).then((result) { + widget._stringeeCall2.makeCall(parameters).then((result) { bool status = result['status']; int code = result['code']; String message = result['message']; print( - 'MakeCall CallBack --- $status - $code - $message - ${widget._stringeeCall2!.id} - ${widget._stringeeCall2!.from} - ${widget._stringeeCall2!.to}'); + 'MakeCall CallBack --- $status - $code - $message - ${widget._stringeeCall2.id} - ${widget._stringeeCall2.from} - ${widget._stringeeCall2.to}'); if (!status) { Navigator.pop(context); } @@ -457,7 +457,7 @@ class _CallState extends State { void endCallTapped() { if (widget._callType == StringeeObjectEventType.call) { - widget._stringeeCall!.hangup().then((result) { + widget._stringeeCall.hangup().then((result) { print('_endCallTapped -- ${result['message']}'); bool status = result['status']; if (status) { @@ -467,7 +467,7 @@ class _CallState extends State { } }); } else if (widget._callType == StringeeObjectEventType.call2) { - widget._stringeeCall2!.hangup().then((result) { + widget._stringeeCall2.hangup().then((result) { print('_endCallTapped -- ${result['message']}'); bool status = result['status']; if (status) { @@ -481,7 +481,7 @@ class _CallState extends State { void acceptCallTapped() { if (widget._callType == StringeeObjectEventType.call) { - widget._stringeeCall!.answer().then((result) { + widget._stringeeCall.answer().then((result) { print('_acceptCallTapped -- ${result['message']}'); bool status = result['status']; if (!status) { @@ -489,7 +489,7 @@ class _CallState extends State { } }); } else if (widget._callType == StringeeObjectEventType.call2) { - widget._stringeeCall2!.answer().then((result) { + widget._stringeeCall2.answer().then((result) { print('_acceptCallTapped -- ${result['message']}'); bool status = result['status']; if (!status) { @@ -504,14 +504,14 @@ class _CallState extends State { void rejectCallTapped() { if (widget._callType == StringeeObjectEventType.call) { - widget._stringeeCall!.reject().then((result) { + widget._stringeeCall.reject().then((result) { print('_rejectCallTapped -- ${result['message']}'); if (Platform.isAndroid) { clearDataEndDismiss(); } }); } else if (widget._callType == StringeeObjectEventType.call2) { - widget._stringeeCall2!.reject().then((result) { + widget._stringeeCall2.reject().then((result) { print('_rejectCallTapped -- ${result['message']}'); if (Platform.isAndroid) { clearDataEndDismiss(); @@ -551,9 +551,9 @@ class _CallState extends State { switch (state) { case StringeeMediaState.connected: if (widget._callType == StringeeObjectEventType.call) { - widget._stringeeCall!.setSpeakerphoneOn(_isSpeaker); + widget._stringeeCall.setSpeakerphoneOn(_isSpeaker); } else if (widget._callType == StringeeObjectEventType.call2) { - widget._stringeeCall2!.setSpeakerphoneOn(_isSpeaker); + widget._stringeeCall2.setSpeakerphoneOn(_isSpeaker); } break; case StringeeMediaState.disconnected: @@ -569,6 +569,11 @@ class _CallState extends State { void handleHandleOnAnotherDeviceEvent(StringeeSignalingState state) { print('handleHandleOnAnotherDeviceEvent - $state'); + if (state == StringeeSignalingState.answered || + state == StringeeSignalingState.ended || + state == StringeeSignalingState.busy) { + clearDataEndDismiss(); + } } void handleReceiveLocalStreamEvent(String callId) { @@ -617,9 +622,9 @@ class _CallState extends State { case AudioDevice.speakerPhone: case AudioDevice.earpiece: if (widget._callType == StringeeObjectEventType.call) { - widget._stringeeCall!.setSpeakerphoneOn(_isSpeaker); + widget._stringeeCall.setSpeakerphoneOn(_isSpeaker); } else if (widget._callType == StringeeObjectEventType.call2) { - widget._stringeeCall2!.setSpeakerphoneOn(_isSpeaker); + widget._stringeeCall2.setSpeakerphoneOn(_isSpeaker); } break; case AudioDevice.bluetooth: @@ -628,9 +633,9 @@ class _CallState extends State { _isSpeaker = false; }); if (widget._callType == StringeeObjectEventType.call) { - widget._stringeeCall!.setSpeakerphoneOn(_isSpeaker); + widget._stringeeCall.setSpeakerphoneOn(_isSpeaker); } else if (widget._callType == StringeeObjectEventType.call2) { - widget._stringeeCall2!.setSpeakerphoneOn(_isSpeaker); + widget._stringeeCall2.setSpeakerphoneOn(_isSpeaker); } break; case AudioDevice.none: @@ -641,11 +646,11 @@ class _CallState extends State { void clearDataEndDismiss() { if (widget._callType == StringeeObjectEventType.call) { - widget._stringeeCall!.destroy(); + widget._stringeeCall.destroy(); widget._stringeeCall = null; Navigator.pop(context); } else if (widget._callType == StringeeObjectEventType.call2) { - widget._stringeeCall2!.destroy(); + widget._stringeeCall2.destroy(); widget._stringeeCall2 = null; Navigator.pop(context); } else { @@ -658,12 +663,12 @@ class _CallState extends State { _cameraId = _cameraId == 1 ? 0 : 1; }); if (widget._callType == StringeeObjectEventType.call) { - widget._stringeeCall!.switchCamera(cameraId: _cameraId).then((result) { + widget._stringeeCall.switchCamera(cameraId: _cameraId).then((result) { bool status = result['status']; if (status) {} }); } else if (widget._callType == StringeeObjectEventType.call2) { - widget._stringeeCall2!.switchCamera(cameraId: _cameraId).then((result) { + widget._stringeeCall2.switchCamera(cameraId: _cameraId).then((result) { bool status = result['status']; if (status) {} }); @@ -672,7 +677,7 @@ class _CallState extends State { void toggleSpeaker() { if (widget._callType == StringeeObjectEventType.call) { - widget._stringeeCall!.setSpeakerphoneOn(!_isSpeaker).then((result) { + widget._stringeeCall.setSpeakerphoneOn(!_isSpeaker).then((result) { bool status = result['status']; if (status) { setState(() { @@ -681,7 +686,7 @@ class _CallState extends State { } }); } else if (widget._callType == StringeeObjectEventType.call2) { - widget._stringeeCall2!.setSpeakerphoneOn(!_isSpeaker).then((result) { + widget._stringeeCall2.setSpeakerphoneOn(!_isSpeaker).then((result) { bool status = result['status']; if (status) { setState(() { @@ -694,7 +699,7 @@ class _CallState extends State { void toggleMicro() { if (widget._callType == StringeeObjectEventType.call) { - widget._stringeeCall!.mute(!_isMute).then((result) { + widget._stringeeCall.mute(!_isMute).then((result) { bool status = result['status']; if (status) { setState(() { @@ -703,7 +708,7 @@ class _CallState extends State { } }); } else if (widget._callType == StringeeObjectEventType.call2) { - widget._stringeeCall2!.mute(!_isMute).then((result) { + widget._stringeeCall2.mute(!_isMute).then((result) { bool status = result['status']; if (status) { setState(() { @@ -716,7 +721,7 @@ class _CallState extends State { void toggleVideo() { if (widget._callType == StringeeObjectEventType.call) { - widget._stringeeCall!.enableVideo(!_isVideoEnable).then((result) { + widget._stringeeCall.enableVideo(!_isVideoEnable).then((result) { bool status = result['status']; if (status) { setState(() { @@ -725,7 +730,7 @@ class _CallState extends State { } }); } else if (widget._callType == StringeeObjectEventType.call2) { - widget._stringeeCall2!.enableVideo(!_isVideoEnable).then((result) { + widget._stringeeCall2.enableVideo(!_isVideoEnable).then((result) { bool status = result['status']; if (status) { setState(() { @@ -766,7 +771,7 @@ class _CallState extends State { AndroidFlutterLocalNotificationsPlugin>() ?.stopForegroundService(); - widget._stringeeCall2!.stopCapture().then((result) { + widget._stringeeCall2.stopCapture().then((result) { bool status = result['status']; print('flutter stopCapture: $status'); if (status) { @@ -777,7 +782,7 @@ class _CallState extends State { }); } else { createForegroundServiceNotification(); - widget._stringeeCall2!.startCapture().then((result) { + widget._stringeeCall2.startCapture().then((result) { bool status = result['status']; print('flutter startCapture: $status'); if (status) { diff --git a/example/lib/ui/conversation_info.dart b/example/lib/ui/conversation_info.dart index c2d742c..f18f11b 100644 --- a/example/lib/ui/conversation_info.dart +++ b/example/lib/ui/conversation_info.dart @@ -3,9 +3,9 @@ import 'package:flutter/material.dart'; import 'package:stringee_flutter_plugin/stringee_flutter_plugin.dart'; class ConversationInfor extends StatefulWidget { - late StringeeConversation _conversation; - late StringeeClient _client; - late StringeeChat _chat; + StringeeConversation _conversation; + StringeeClient _client; + StringeeChat _chat; ConversationInfor( StringeeClient client, @@ -28,7 +28,7 @@ class ConversationInforState extends State { List _log = []; List _messages = []; List users = []; - late StringeeMessage msg; + StringeeMessage msg; @override void initState() { @@ -60,10 +60,10 @@ class ConversationInforState extends State { if (map['eventType'] == StringeeChatEvents.didReceiveObjectChange) { StringeeObjectChange objectChange = map['body']; if (objectChange.objectType == ObjectType.message) { - StringeeMessage message = objectChange.objects!.first; + StringeeMessage message = objectChange.objects.first; setState(() { _log.add((message.id != null) - ? message.id! + ? message.id : 'null' + ' ' + objectChange.type.toString()); }); } @@ -153,13 +153,13 @@ class ConversationInforState extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - 'msgId: ' + _messages[index].id!, + 'msgId: ' + _messages[index].id, ), Text( 'msgType: ' + _messages[index].type.toString(), ), Text( - 'text: ' + _messages[index].text!, + 'text: ' + _messages[index].text, ), ], )), @@ -455,7 +455,7 @@ class ConversationInforState extends State { textColor: Colors.black, onPressed: () { String newConvName = - widget._conversation.name! + ' NEW NAME'; + widget._conversation.name + ' NEW NAME'; widget._conversation .updateConversation(newConvName) .then((value) { @@ -594,7 +594,7 @@ class ConversationInforState extends State { context: context, builder: (context) => AlertDialog( title: Text('Message'), - content: Text('msgId: ' + message.id!), + content: Text('msgId: ' + message.id), actions: [ new FlatButton( color: Colors.grey[300], diff --git a/example/lib/ui/room.dart b/example/lib/ui/room.dart index 4c6b2a2..7dff28a 100644 --- a/example/lib/ui/room.dart +++ b/example/lib/ui/room.dart @@ -5,8 +5,8 @@ import 'package:stringee_flutter_plugin_example/button/circle_button.dart'; import 'package:stringee_flutter_plugin_example/button/rounded_button.dart'; class Room extends StatefulWidget { - late StringeeVideo _video; - late String _roomToken; + StringeeVideo _video; + String _roomToken; Room(StringeeClient client, String roomToken) { _video = StringeeVideo(client); @@ -21,10 +21,10 @@ class Room extends StatefulWidget { } class RoomState extends State { - late StringeeRoom _room; - late StringeeVideoTrack _localTrack; - late StringeeVideoTrack _shareTrack; - late StringeeVideoView _localTrackView; + StringeeRoom _room; + StringeeVideoTrack _localTrack; + StringeeVideoTrack _shareTrack; + StringeeVideoView _localTrackView; bool _hasLocalView = false; bool _sharingScreen = false; bool _isMute = false; @@ -261,8 +261,12 @@ class RoomState extends State { if (value['status']) { setState(() { if (_trackList.length > 0) { - _trackList.removeAt( - _trackList.indexWhere((track) => track.id == removeTrack.id)); + for (int i = 0; i < _trackList.length; i++) { + StringeeVideoTrack track = _trackList[i]; + if (track.id == removeTrack.id) { + _trackList.removeAt(i); + } + } } }); } diff --git a/example/lib/ui/visitor.dart b/example/lib/ui/visitor.dart index 02a2516..b7af76c 100644 --- a/example/lib/ui/visitor.dart +++ b/example/lib/ui/visitor.dart @@ -23,7 +23,7 @@ class _VisitorPageState extends State String visitorEmail = ''; String visitorPhone = ''; - late StringeeConversation _conversation; + StringeeConversation _conversation; bool connected = false; bool inConv = false; @@ -74,16 +74,16 @@ class _VisitorPageState extends State if (map['eventType'] == StringeeChatEvents.didReceiveObjectChange) { StringeeObjectChange objectChange = map['body']; if (objectChange.objectType == ObjectType.conversation) { - StringeeConversation conversation = objectChange.objects!.first; + StringeeConversation conversation = objectChange.objects.first; setState(() { - _log.add(conversation.id! + ' ' + objectChange.type.toString()); + _log.add(conversation.id + ' ' + objectChange.type.toString()); }); } if (objectChange.objectType == ObjectType.message) { - StringeeMessage message = objectChange.objects!.first; + StringeeMessage message = objectChange.objects.first; setState(() { _log.add((message.id != null) - ? message.id! + ? message.id : 'null' + ' ' + objectChange.type.toString()); }); } @@ -328,7 +328,7 @@ class _VisitorPageState extends State void handleDidConnectEvent() { setState(() { - userId = client.userId!; + userId = client.userId; connected = true; }); diff --git a/example/pubspec.yaml b/example/pubspec.yaml index 30fce7f..a95800a 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -3,7 +3,7 @@ description: Demonstrates how to use the stringee_flutter_plugin plugin. publish_to: 'none' environment: - sdk: '>=2.12.0 <3.0.0' + sdk: '>=2.7.0 <3.0.0' dependencies: flutter: diff --git a/example/test/widget_test.dart b/example/test/widget_test.dart index 13f156f..f4917f2 100644 --- a/example/test/widget_test.dart +++ b/example/test/widget_test.dart @@ -20,7 +20,7 @@ void main() { expect( find.byWidgetPredicate( (Widget widget) => widget is Text && - widget.data!.startsWith('Running on:'), + widget.data.startsWith('Running on:'), ), findsOneWidget, ); diff --git a/ios/Classes/StringeeClientWrapper.m b/ios/Classes/StringeeClientWrapper.m index b7c638a..7cbef4e 100644 --- a/ios/Classes/StringeeClientWrapper.m +++ b/ios/Classes/StringeeClientWrapper.m @@ -188,8 +188,8 @@ - (void)sendCustomMessage:(id)arguments result:(FlutterResult)result { } NSDictionary *data = (NSDictionary *)arguments; - NSString *userId = data[@"toUserId"]; - NSDictionary *message = data[@"message"]; + NSString *userId = data[@"userId"]; + NSDictionary *message = data[@"msg"]; if (!userId || [userId isKindOfClass:[NSNull class]]) { result(@{STEStatus : @(NO), STECode : @(-2), STEMessage: @"UserId is invalid."}); diff --git a/lib/src/StringeeClient.dart b/lib/src/StringeeClient.dart index 287b21e..0dcf7d7 100644 --- a/lib/src/StringeeClient.dart +++ b/lib/src/StringeeClient.dart @@ -21,18 +21,18 @@ class StringeeClient { StreamController _eventStreamController = StreamController.broadcast(); - String? _userId; - String? _projectId; + String _userId; + String _projectId; bool _hasConnected = false; bool _isReconnecting = true; // Multi Client - List? _serverAddresses; + List _serverAddresses; final String _uuid = GUIDGen.generate(); - String? get userId => _userId; + String get userId => _userId; - String? get projectId => _projectId; + String get projectId => _projectId; bool get hasConnected => _hasConnected; @@ -43,7 +43,7 @@ class StringeeClient { String get uuid => _uuid; StringeeClient( - {List? serverAddresses, String? baseAPIUrl}) { + {List serverAddresses, String baseAPIUrl}) { _serverAddresses = serverAddresses; final params = {'uuid': _uuid, 'baseAPIUrl': baseAPIUrl}; @@ -113,10 +113,14 @@ class StringeeClient { /// Connect to [StringeeClient] by [token] Future> connect(String token) async { - if (token.trim().isEmpty) return await reportInvalidValue('token'); + if (token == null || token.trim().isEmpty) + return await reportInvalidValue('token'); - var params = {'token': token.trim(), 'uuid': _uuid}; - if (_serverAddresses != null && _serverAddresses!.length > 0) { + var params = { + 'token': token.trim(), + 'uuid': _uuid, + }; + if (_serverAddresses != null && _serverAddresses.length > 0) { params['serverAddresses'] = json.encode(_serverAddresses); } @@ -139,10 +143,10 @@ class StringeeClient { /// Register push from Stringee by [deviceToken] Future> registerPush( String deviceToken, { - bool? isProduction, - bool? isVoip, + bool isProduction, + bool isVoip, }) async { - if (deviceToken.trim().isEmpty) + if (deviceToken == null || deviceToken.trim().isEmpty) return await reportInvalidValue('deviceToken'); Map params = { 'deviceToken': deviceToken.trim(), @@ -159,7 +163,7 @@ class StringeeClient { /// Unregister push from Stringee by [deviceToken[ Future> unregisterPush(String deviceToken) async { - if (deviceToken.trim().isEmpty) + if (deviceToken == null || deviceToken.trim().isEmpty) return await reportInvalidValue('deviceToken'); final params = { @@ -173,7 +177,9 @@ class StringeeClient { /// Send a [customData] to [userId] Future> sendCustomMessage( String userId, Map customData) async { - if (userId.trim().isEmpty) return await reportInvalidValue('userId'); + if (userId == null || userId.trim().isEmpty) + return await reportInvalidValue('userId'); + if (customData == null) return await reportInvalidValue('customData'); final params = {'userId': userId.trim(), 'msg': customData, 'uuid': _uuid}; return await methodChannel.invokeMethod('sendCustomMessage', params); } @@ -216,20 +222,20 @@ class StringeeClient { {"eventType": StringeeClientEvents.requestAccessToken, "body": null}); } - void _handleDidReceiveCustomMessageEvent(Map? map) { + void _handleDidReceiveCustomMessageEvent(Map map) { _eventStreamController.add({ "eventType": StringeeClientEvents.didReceiveCustomMessage, "body": map }); } - void _handleIncomingCallEvent(Map? map) { + void _handleIncomingCallEvent(Map map) { StringeeCall call = StringeeCall.fromCallInfo(map, this); _eventStreamController .add({"eventType": StringeeClientEvents.incomingCall, "body": call}); } - void _handleIncomingCall2Event(Map? map) { + void _handleIncomingCall2Event(Map map) { StringeeCall2 call = StringeeCall2.fromCallInfo(map, this); _eventStreamController .add({"eventType": StringeeClientEvents.incomingCall2, "body": call}); diff --git a/lib/src/StringeeConstants.dart b/lib/src/StringeeConstants.dart index 2bfbdb7..cd3a8db 100644 --- a/lib/src/StringeeConstants.dart +++ b/lib/src/StringeeConstants.dart @@ -140,46 +140,46 @@ enum ScalingType { ///Class represents options for make a call class MakeCallParams { - String? _from; - String? _to; - bool? _isVideoCall; - Map? _customData; - VideoQuality? _videoQuality; + String _from; + String _to; + bool _isVideoCall; + Map _customData; + VideoQuality _videoQuality; MakeCallParams( String from, String to, { - bool? isVideoCall, - Map? customData, - VideoQuality? videoQuality, - }) : assert(from.trim().isNotEmpty), - assert(to.trim().isNotEmpty) { + bool isVideoCall, + Map customData, + VideoQuality videoQuality, + }) : assert(from != null || from.trim().isNotEmpty), + assert(to != null || to.trim().isNotEmpty) { this._from = from.trim(); this._to = to.trim(); this._isVideoCall = (isVideoCall != null) ? isVideoCall : false; if (customData != null) this._customData = customData; - if (this._isVideoCall!) + if (this._isVideoCall) this._videoQuality = (videoQuality != null) ? videoQuality : VideoQuality.normal; } - VideoQuality? get videoQuality => _videoQuality; + VideoQuality get videoQuality => _videoQuality; - Map? get customData => _customData; + Map get customData => _customData; - bool? get isVideoCall => _isVideoCall; + bool get isVideoCall => _isVideoCall; - String? get to => _to; + String get to => _to; - String? get from => _from; + String get from => _from; Map toJson() { Map params = new Map(); - params['from'] = this._from!.trim(); - params['to'] = this._to!.trim(); + params['from'] = this._from.trim(); + params['to'] = this._to.trim(); if (this._customData != null) params['customData'] = this._customData; params['isVideoCall'] = this._isVideoCall; - if (this._isVideoCall!) { + if (this._isVideoCall) { switch (this._videoQuality) { case VideoQuality.normal: params['videoResolution'] = "NORMAL"; @@ -243,70 +243,96 @@ enum MsgType { notification, } -extension MsgTypeValueExtension on MsgType? { +extension MsgTypeValueExtension on MsgType { // ignore: missing_return int get value { switch (this) { case MsgType.text: return 1; + break; case MsgType.photo: return 2; + break; case MsgType.video: return 3; + break; case MsgType.audio: return 4; + break; case MsgType.file: return 5; + break; case MsgType.link: return 6; + break; case MsgType.createConversation: return 7; + break; case MsgType.renameConversation: return 8; + break; case MsgType.location: return 9; + break; case MsgType.contact: return 10; + break; case MsgType.sticker: return 11; + break; case MsgType.notification: return 100; + break; default: return 1; + break; } } } -extension MsgTypeExtension on int? { +extension MsgTypeExtension on int { // ignore: missing_return MsgType get msgType { switch (this) { case 1: return MsgType.text; + break; case 2: return MsgType.photo; + break; case 3: return MsgType.video; + break; case 4: return MsgType.audio; + break; case 5: return MsgType.file; + break; case 6: return MsgType.link; + break; case 7: return MsgType.createConversation; + break; case 8: return MsgType.renameConversation; + break; case 9: return MsgType.location; + break; case 10: return MsgType.contact; + break; case 11: return MsgType.sticker; + break; case 100: return MsgType.notification; + break; default: return MsgType.text; + break; } } } @@ -318,69 +344,73 @@ enum MsgNotifyType { changeGroupName, } -extension MsgNotifyTypeExtension on int? { +extension MsgNotifyTypeExtension on int { // ignore: missing_return MsgNotifyType get notifyType { switch (this) { case 1: return MsgNotifyType.addParticipants; + break; case 2: return MsgNotifyType.removeParticipants; + break; case 3: return MsgNotifyType.changeGroupName; + break; default: return MsgNotifyType.changeGroupName; + break; } } } ///Class represents options for create a new [StringeeConversation] class StringeeConversationOption { - String? _name; + String _name; bool _isGroup = false; bool _isDistinct = false; - String? _oaId; - String? _customData; - String? _creatorId; + String _oaId; + String _customData; + String _creatorId; StringeeConversationOption( - {required bool isGroup, - required bool isDistinct, - String? name, - String? oaId, - String? customData, - String? creatorId}) { + {bool isGroup, + String name, + bool isDistinct, + String oaId, + String customData, + String creatorId}) + : assert(isGroup != null) { if (name != null) this._name = name; this._isGroup = isGroup; this._isDistinct = isDistinct; if (oaId != null) this._oaId = oaId; if (customData != null) this._customData = customData; - if (creatorId != null) this._creatorId = creatorId; - } - Map toJson() { - return { - if (_name != null) 'name': _name!.trim(), - 'isGroup': _isGroup, - 'isDistinct': _isDistinct, - if (_oaId != null) 'oaId': _oaId!.trim(), - if (_customData != null) 'customData': _customData!.trim(), - if (_creatorId != null) 'creatorId': _creatorId!.trim(), - }; + Map toJson() { + return { + if (_name != null) 'name': _name.trim(), + 'isGroup': _isGroup, + 'isDistinct': _isDistinct, + if (_oaId != null) 'oaId': _oaId.trim(), + if (_customData != null) 'customData': _customData.trim(), + if (_creatorId != null) 'creatorId': _creatorId.trim(), + }; + } } } /// Class represents the change of [StringeeConversation] and [StringeeMessage] class StringeeObjectChange { - ChangeType? _type; - ObjectType? _objectType; - List? _objects; + ChangeType _type; + ObjectType _objectType; + List _objects; - ChangeType? get type => _type; + ChangeType get type => _type; - ObjectType? get objectType => _objectType; + ObjectType get objectType => _objectType; - List? get objects => _objects; + List get objects => _objects; StringeeObjectChange( ChangeType type, ObjectType objectType, List objects) { @@ -392,12 +422,12 @@ class StringeeObjectChange { ///Class represents server address class StringeeServerAddress { - String? _host; - int? _port; + String _host; + int _port; - String? get host => _host; + String get host => _host; - int? get port => _port; + int get port => _port; StringeeServerAddress(String host, int port) { this._host = host; @@ -406,7 +436,7 @@ class StringeeServerAddress { Map toJson() { Map params = new Map(); - if (_host != null) params['host'] = _host!.trim(); + if (_host != null) params['host'] = _host.trim(); if (_port != null) params['port'] = _port; return params; } @@ -414,9 +444,9 @@ class StringeeServerAddress { ///Class represents server address class StringeeVideoTrackOptions { - late bool _audio; - late bool _video; - late bool _screen; + bool _audio; + bool _video; + bool _screen; StringeeVideoDimensions _videoDimension = StringeeVideoDimensions.dimesion_288; @@ -429,10 +459,10 @@ class StringeeVideoTrackOptions { StringeeVideoDimensions get videoDimension => _videoDimension; StringeeVideoTrackOptions( - {required bool audio, - required bool video, - required bool screen, - StringeeVideoDimensions? videoDimension}) { + { bool audio, + bool video, + bool screen, + StringeeVideoDimensions videoDimension}) { this._audio = audio; this._video = video; this._screen = screen; @@ -478,15 +508,15 @@ class GUIDGen { Random random = new Random(new DateTime.now().millisecond); final String hexDigits = "0123456789abcdef"; - final List uuid = - new List.filled(36, null, growable: false); + final List uuid = + new List.filled(36, null, growable: false); for (int i = 0; i < 36; i++) { final int hexPos = random.nextInt(16); uuid[i] = (hexDigits.substring(hexPos, hexPos + 1)); } - int pos = (int.parse(uuid[19]!, radix: 16) & 0x3) | + int pos = (int.parse(uuid[19], radix: 16) & 0x3) | 0x8; // bits 6-7 of the clock_seq_hi_and_reserved to 01 uuid[14] = "4"; // bits 12-15 of the time_hi_and_version field to 0010 diff --git a/lib/src/StringeeVideoView.dart b/lib/src/StringeeVideoView.dart index 2492cec..d2831e1 100644 --- a/lib/src/StringeeVideoView.dart +++ b/lib/src/StringeeVideoView.dart @@ -9,25 +9,26 @@ import 'package:flutter/widgets.dart'; import 'StringeeConstants.dart'; class StringeeVideoView extends StatefulWidget { - late final String? callId; - late final String? trackId; + String callId; + String trackId; bool isLocal = true; - bool? isOverlay = false; - bool? isMirror = false; - final EdgeInsetsGeometry? margin; - final AlignmentGeometry? alignment; - final EdgeInsetsGeometry? padding; - ScalingType? scalingType = ScalingType.fill; - final double? height; - final double? width; - final Color? color; - final Widget? child; - late final bool forCall; + + bool isOverlay = false; + bool isMirror = false; + final EdgeInsetsGeometry margin; + final AlignmentGeometry alignment; + final EdgeInsetsGeometry padding; + ScalingType scalingType = ScalingType.fill; + final double height; + final double width; + final Color color; + final Widget child; + bool forCall; StringeeVideoView( this.callId, this.isLocal, { - Key? key, + Key key, this.isOverlay, this.isMirror, this.color, @@ -46,7 +47,7 @@ class StringeeVideoView extends StatefulWidget { StringeeVideoView.forTrack( this.trackId, { - Key? key, + Key key, this.isOverlay, this.isMirror, this.color, @@ -141,6 +142,7 @@ class StringeeVideoViewState extends State { ..create(); }, ); + break; case TargetPlatform.iOS: // Co loi FlutterPlatformView chua duoc fix => dung tam cach nay if (widget.width == null) { @@ -157,8 +159,10 @@ class StringeeVideoViewState extends State { creationParams: creationParams, creationParamsCodec: const StandardMessageCodec(), ); + break; default: throw UnsupportedError("Unsupported platform view"); + break; } } @@ -178,17 +182,17 @@ class StringeeVideoViewState extends State { ); if (widget.child != null) { - Widget? child = widget.child; + Widget child = widget.child; if (widget.padding != null) { - child = Padding(padding: widget.padding!, child: child); + child = Padding(padding: widget.padding, child: child); } - childrenWidget.add(child!); + childrenWidget.add(child); } if (widget.alignment != null) { - current = Align(alignment: widget.alignment!, child: current); + current = Align(alignment: widget.alignment, child: current); } return current; diff --git a/lib/src/call/StringeeCall.dart b/lib/src/call/StringeeCall.dart index 6da26a7..3430f56 100644 --- a/lib/src/call/StringeeCall.dart +++ b/lib/src/call/StringeeCall.dart @@ -6,52 +6,59 @@ import '../StringeeClient.dart'; import '../StringeeConstants.dart'; class StringeeCall { - String? _id; - int? _serial; - String? _from; - String? _to; - String? _fromAlias; - String? _toAlias; - StringeeCallType? _callType; - String? _customDataFromYourServer; + String _id; + int _serial; + String _from; + String _to; + String _fromAlias; + String _toAlias; + StringeeCallType _callType; + String _customDataFromYourServer; bool _isVideoCall = false; StreamController _eventStreamController = StreamController(); - late StreamSubscription _subscriber; - late StringeeClient _client; + StreamSubscription _subscriber; + StringeeClient _client; - String? get id => _id; + String get id => _id; - int? get serial => _serial; + int get serial => _serial; - String? get from => _from; + String get from => _from; - String? get to => _to; + String get to => _to; - String? get fromAlias => _fromAlias; + String get fromAlias => _fromAlias; - String? get toAlias => _toAlias; + String get toAlias => _toAlias; bool get isVideoCall => _isVideoCall; - StringeeCallType? get callType => _callType; + StringeeCallType get callType => _callType; - String? get customDataFromYourServer => _customDataFromYourServer; + String get customDataFromYourServer => _customDataFromYourServer; StreamController get eventStreamController => _eventStreamController; StringeeCall(StringeeClient client) { + if (client == null) { + throw Exception("Client can not be null"); + } + _client = client; _subscriber = client.eventStreamController.stream.listen(this._listener); } - StringeeCall.fromCallInfo( - Map? info, StringeeClient client) { + StringeeCall.fromCallInfo(Map info, StringeeClient client) { + if (client == null) { + throw Exception("Client can not be null"); + } + this.initCallInfo(info); _client = client; _subscriber = client.eventStreamController.stream.listen(this._listener); } - void initCallInfo(Map? callInfo) { + void initCallInfo(Map callInfo) { if (callInfo == null) { return; } @@ -99,11 +106,11 @@ class StringeeCall { } void handleDidChangeSignalingState(Map map) { - String? callId = map['callId']; + String callId = map['callId']; if (callId != this._id) return; StringeeSignalingState signalingState = - StringeeSignalingState.values[map['code']]; + StringeeSignalingState.values[map['code']]; _eventStreamController.add({ "eventType": StringeeCallEvents.didChangeSignalingState, "body": signalingState @@ -111,7 +118,7 @@ class StringeeCall { } void handleDidChangeMediaState(Map map) { - String? callId = map['callId']; + String callId = map['callId']; if (callId != this._id) return; StringeeMediaState mediaState = StringeeMediaState.values[map['code']]; @@ -122,17 +129,17 @@ class StringeeCall { } void handleDidReceiveCallInfo(Map map) { - String? callId = map['callId']; + String callId = map['callId']; if (callId != this._id) return; - Map? data = map['info']; + Map data = map['info']; _eventStreamController.add( {"eventType": StringeeCallEvents.didReceiveCallInfo, "body": data}); } void handleDidHandleOnAnotherDevice(Map map) { StringeeSignalingState signalingState = - StringeeSignalingState.values[map['code']]; + StringeeSignalingState.values[map['code']]; _eventStreamController.add({ "eventType": StringeeCallEvents.didHandleOnAnotherDevice, "body": signalingState @@ -172,7 +179,8 @@ class StringeeCall { /// Make a new coll with custom [parameters] Future> makeCall( Map parameters) async { - if (!parameters.containsKey('from') || + if (parameters == null || + !parameters.containsKey('from') || (parameters['from'] as String).trim().isEmpty || !parameters.containsKey('to') || (parameters['to'] as String).trim().isEmpty) @@ -219,8 +227,8 @@ class StringeeCall { params['uuid'] = _client.uuid; Map results = - await StringeeClient.methodChannel.invokeMethod('makeCall', params); - Map? callInfo = results['callInfo']; + await StringeeClient.methodChannel.invokeMethod('makeCall', params); + Map callInfo = results['callInfo']; this.initCallInfo(callInfo); final Map resultDatas = { @@ -234,12 +242,13 @@ class StringeeCall { /// Make a new coll with [MakeCallParams] Future> makeCallFromParams( MakeCallParams params) async { + if (params == null) return await reportInvalidValue('MakeCallParams'); Map parameters = { - 'from': params.from!.trim(), - 'to': params.to!.trim(), + 'from': params.from.trim(), + 'to': params.to.trim(), if (params.customData != null) 'customData': params.customData, 'isVideoCall': params.isVideoCall, - if (params.isVideoCall!) 'videoQuality': params.videoQuality, + if (params.isVideoCall) 'videoQuality': params.videoQuality, }; return await makeCall(parameters); } @@ -274,7 +283,8 @@ class StringeeCall { /// Send a [dtmf] Future> sendDtmf(String dtmf) async { - if (dtmf.trim().isEmpty) return await reportInvalidValue('dtmf'); + if (dtmf == null || dtmf.trim().isEmpty) + return await reportInvalidValue('dtmf'); final params = { 'callId': this._id, 'dtmf': dtmf.trim(), @@ -286,6 +296,7 @@ class StringeeCall { /// Send a call info Future> sendCallInfo( Map callInfo) async { + if (callInfo == null) return await reportInvalidValue('callInfo'); final params = { 'callId': this._id, 'callInfo': callInfo, @@ -308,6 +319,7 @@ class StringeeCall { /// Mute/Unmute Future> mute(bool mute) async { + if (mute == null) return await reportInvalidValue('mute'); final params = { 'callId': this._id, 'mute': mute, @@ -318,6 +330,7 @@ class StringeeCall { /// Enable/ Disable video Future> enableVideo(bool enableVideo) async { + if (enableVideo == null) return await reportInvalidValue('enableVideo'); final params = { 'callId': this._id, 'enableVideo': enableVideo, @@ -329,6 +342,8 @@ class StringeeCall { /// Set speaker phone on/off Future> setSpeakerphoneOn(bool speakerPhoneOn) async { + if (speakerPhoneOn == null) + return await reportInvalidValue('speakerPhoneOn'); final params = { 'callId': this._id, 'speaker': speakerPhoneOn, @@ -339,12 +354,16 @@ class StringeeCall { } /// Switch camera - Future> switchCamera({int? cameraId}) async { + Future> switchCamera({int cameraId}) async { Map params = { 'callId': this._id, 'uuid': _client.uuid, - if (cameraId != null) 'cameraId': cameraId, }; + if (Platform.isAndroid) { + if (cameraId != null) { + params['cameraId'] = cameraId; + } + } return await StringeeClient.methodChannel .invokeMethod('switchCamera', params); } @@ -370,6 +389,8 @@ class StringeeCall { /// Set stream like a mirror Future> setMirror(bool isLocal, bool isMirror) async { + if (isLocal == null) return await reportInvalidValue('isLocal'); + if (isMirror == null) return await reportInvalidValue('isMirror'); if (Platform.isIOS) { final params = { 'status': false, @@ -391,7 +412,9 @@ class StringeeCall { /// close event stream void destroy() { - _subscriber.cancel(); - _eventStreamController.close(); + if (_subscriber != null) { + _subscriber.cancel(); + _eventStreamController.close(); + } } } diff --git a/lib/src/call/StringeeCall2.dart b/lib/src/call/StringeeCall2.dart index 4eefcb9..53b0bee 100644 --- a/lib/src/call/StringeeCall2.dart +++ b/lib/src/call/StringeeCall2.dart @@ -5,52 +5,60 @@ import 'dart:io'; import 'package:stringee_flutter_plugin/stringee_flutter_plugin.dart'; class StringeeCall2 { - String? _id; - int? _serial; - String? _from; - String? _to; - String? _fromAlias; - String? _toAlias; - StringeeCallType? _callType; - String? _customDataFromYourServer; + String _id; + int _serial; + String _from; + String _to; + String _fromAlias; + String _toAlias; + StringeeCallType _callType; + String _customDataFromYourServer; bool _isVideoCall = false; StreamController _eventStreamController = StreamController(); - late StreamSubscription _subscriber; - late StringeeClient _client; + StreamSubscription _subscriber; + StringeeClient _client; - String? get id => _id; + String get id => _id; - int? get serial => _serial; + int get serial => _serial; - String? get from => _from; + String get from => _from; - String? get to => _to; + String get to => _to; - String? get fromAlias => _fromAlias; + String get fromAlias => _fromAlias; - String? get toAlias => _toAlias; + String get toAlias => _toAlias; bool get isVideoCall => _isVideoCall; - StringeeCallType? get callType => _callType; + StringeeCallType get callType => _callType; - String? get customDataFromYourServer => _customDataFromYourServer; + String get customDataFromYourServer => _customDataFromYourServer; StreamController get eventStreamController => _eventStreamController; StringeeCall2(StringeeClient client) { + if (client == null) { + throw Exception("Client can not be null"); + } + _client = client; _subscriber = client.eventStreamController.stream.listen(this._listener); } StringeeCall2.fromCallInfo( - Map? info, StringeeClient client) { + Map info, StringeeClient client) { + if (client == null) { + throw Exception("Client can not be null"); + } + this.initCallInfo(info); _client = client; _subscriber = client.eventStreamController.stream.listen(this._listener); } - void initCallInfo(Map? callInfo) { + void initCallInfo(Map callInfo) { if (callInfo == null) { return; } @@ -104,7 +112,7 @@ class StringeeCall2 { } void handleDidChangeSignalingState(Map map) { - String? callId = map['callId']; + String callId = map['callId']; if (callId != this._id) return; StringeeSignalingState signalingState = @@ -116,7 +124,7 @@ class StringeeCall2 { } void handleDidChangeMediaState(Map map) { - String? callId = map['callId']; + String callId = map['callId']; if (callId != this._id) return; StringeeMediaState mediaState = StringeeMediaState.values[map['code']]; @@ -127,10 +135,10 @@ class StringeeCall2 { } void handleDidReceiveCallInfo(Map map) { - String? callId = map['callId']; + String callId = map['callId']; if (callId != this._id) return; - Map? data = map['info']; + Map data = map['info']; _eventStreamController.add( {"eventType": StringeeCall2Events.didReceiveCallInfo, "body": data}); } @@ -195,7 +203,8 @@ class StringeeCall2 { /// Make a new coll with custom [parameters] Future> makeCall( Map parameters) async { - if (!parameters.containsKey('from') || + if (parameters == null || + !parameters.containsKey('from') || (parameters['from'] as String).trim().isEmpty || !parameters.containsKey('to') || (parameters['to'] as String).trim().isEmpty) @@ -243,7 +252,7 @@ class StringeeCall2 { Map results = await StringeeClient.methodChannel.invokeMethod('makeCall2', params); - Map? callInfo = results['callInfo']; + Map callInfo = results['callInfo']; this.initCallInfo(callInfo); final Map resultDatas = { @@ -257,12 +266,13 @@ class StringeeCall2 { /// Make a new coll with [MakeCallParams] Future> makeCallFromParams( MakeCallParams params) async { + if (params == null) return await reportInvalidValue('MakeCallParams'); Map parameters = { - 'from': params.from!.trim(), - 'to': params.to!.trim(), + 'from': params.from.trim(), + 'to': params.to.trim(), if (params.customData != null) 'customData': params.customData, 'isVideoCall': params.isVideoCall, - if (params.isVideoCall!) 'videoQuality': params.videoQuality, + if (params.isVideoCall) 'videoQuality': params.videoQuality, }; return await makeCall(parameters); } @@ -298,7 +308,8 @@ class StringeeCall2 { /// Send a [dtmf] Future> sendDtmf(String dtmf) async { - if (dtmf.trim().isEmpty) return await reportInvalidValue('dtmf'); + if (dtmf == null || dtmf.trim().isEmpty) + return await reportInvalidValue('dtmf'); final params = { 'callId': this._id, 'dtmf': dtmf.trim(), @@ -310,6 +321,7 @@ class StringeeCall2 { /// Send a call info Future> sendCallInfo( Map callInfo) async { + if (callInfo == null) return await reportInvalidValue('callInfo'); final params = { 'callId': this._id, 'callInfo': callInfo, @@ -332,12 +344,14 @@ class StringeeCall2 { /// Mute/Unmute Future> mute(bool mute) async { + if (mute == null) return await reportInvalidValue('mute'); final params = {'callId': this._id, 'mute': mute, 'uuid': _client.uuid}; return await StringeeClient.methodChannel.invokeMethod('mute2', params); } /// Enable/ Disable video Future> enableVideo(bool enableVideo) async { + if (enableVideo == null) return await reportInvalidValue('enableVideo'); final params = { 'callId': this._id, 'enableVideo': enableVideo, @@ -349,6 +363,8 @@ class StringeeCall2 { /// Set speaker phone on/off Future> setSpeakerphoneOn(bool speakerPhoneOn) async { + if (speakerPhoneOn == null) + return await reportInvalidValue('speakerPhoneOn'); final params = { 'callId': this._id, 'speaker': speakerPhoneOn, @@ -359,12 +375,16 @@ class StringeeCall2 { } /// Switch camera - Future> switchCamera({int? cameraId}) async { + Future> switchCamera({int cameraId}) async { Map params = { 'callId': this._id, 'uuid': _client.uuid, - if (cameraId != null) 'cameraId': cameraId, }; + if (Platform.isAndroid) { + if (cameraId != null) { + params['cameraId'] = cameraId; + } + } return await StringeeClient.methodChannel .invokeMethod('switchCamera2', params); } @@ -390,6 +410,8 @@ class StringeeCall2 { /// Set stream like a mirror Future> setMirror(bool isLocal, bool isMirror) async { + if (isLocal == null) return await reportInvalidValue('isLocal'); + if (isMirror == null) return await reportInvalidValue('isMirror'); if (Platform.isIOS) { final params = { 'status': false, @@ -431,7 +453,9 @@ class StringeeCall2 { /// close event stream void destroy() { - _subscriber.cancel(); - _eventStreamController.close(); + if (_subscriber != null) { + _subscriber.cancel(); + _eventStreamController.close(); + } } } diff --git a/lib/src/conference/StringeeRoom.dart b/lib/src/conference/StringeeRoom.dart index 3b394d8..7d6e0b7 100644 --- a/lib/src/conference/StringeeRoom.dart +++ b/lib/src/conference/StringeeRoom.dart @@ -3,11 +3,11 @@ import 'dart:async'; import '../../stringee_flutter_plugin.dart'; class StringeeRoom { - late String _id; - late bool _recorded; - late StringeeClient _client; + String _id; + bool _recorded; + StringeeClient _client; StreamController _eventStreamController = StreamController(); - late StreamSubscription _subscriber; + StreamSubscription _subscriber; String get id => _id; @@ -51,7 +51,7 @@ class StringeeRoom { } void handleDidJoinRoom(Map map) { - String? roomId = map['roomId']; + String roomId = map['roomId']; if (roomId != this._id) return; _eventStreamController.add({ "eventType": StringeeRoomEvents.didJoinRoom, @@ -60,7 +60,7 @@ class StringeeRoom { } void handleDidLeaveRoom(Map map) { - String? roomId = map['roomId']; + String roomId = map['roomId']; if (roomId != this._id) return; _eventStreamController.add({ @@ -70,7 +70,7 @@ class StringeeRoom { } void handleDidAddVideoTrack(Map map) { - String? roomId = map['roomId']; + String roomId = map['roomId']; if (roomId != this._id) return; _eventStreamController.add({ @@ -80,7 +80,7 @@ class StringeeRoom { } void handleDidRemoveVideoTrack(Map map) { - String? roomId = map['roomId']; + String roomId = map['roomId']; if (roomId != this._id) return; _eventStreamController.add({ @@ -90,7 +90,7 @@ class StringeeRoom { } void handleDidReceiveRoomMessage(Map map) { - String? roomId = map['roomId']; + String roomId = map['roomId']; if (roomId != this._id) return; Map bodyMap = { 'msg': map['msg'], @@ -168,7 +168,7 @@ class StringeeRoom { /// Leave [StringeeRoom] Future> leave({ - required bool allClient, + bool allClient, }) async { final params = { 'roomId': _id, diff --git a/lib/src/conference/StringeeRoomUser.dart b/lib/src/conference/StringeeRoomUser.dart index d1d3a43..24a05be 100644 --- a/lib/src/conference/StringeeRoomUser.dart +++ b/lib/src/conference/StringeeRoomUser.dart @@ -1,5 +1,5 @@ class StringeeRoomUser { - late String _id; + String _id; StringeeRoomUser(Map info) { this._id = info['id']; diff --git a/lib/src/conference/StringeeVideo.dart b/lib/src/conference/StringeeVideo.dart index 4f836a4..34efdbf 100644 --- a/lib/src/conference/StringeeVideo.dart +++ b/lib/src/conference/StringeeVideo.dart @@ -3,7 +3,7 @@ import 'dart:io'; import '../../stringee_flutter_plugin.dart'; class StringeeVideo { - late StringeeClient _client; + StringeeClient _client; StringeeVideo(StringeeClient client) { _client = client; diff --git a/lib/src/conference/StringeeVideoTrack.dart b/lib/src/conference/StringeeVideoTrack.dart index d34a175..09b8f50 100644 --- a/lib/src/conference/StringeeVideoTrack.dart +++ b/lib/src/conference/StringeeVideoTrack.dart @@ -3,14 +3,14 @@ import 'package:flutter/material.dart'; import '../../stringee_flutter_plugin.dart'; class StringeeVideoTrack { - late String _id; - late String _localId; - late StringeeRoomUser _publisher; - late bool _audioEnable; - late bool _videoEnable; - late bool _isScreenCapture; - late bool _isLocal; - late final StringeeClient _client; + String _id; + String _localId; + StringeeRoomUser _publisher; + bool _audioEnable; + bool _videoEnable; + bool _isScreenCapture; + bool _isLocal; + StringeeClient _client; String get id => _id; @@ -80,7 +80,7 @@ class StringeeVideoTrack { } /// Switch camera - Future> switchCamera({int? cameraId}) async { + Future> switchCamera({int cameraId}) async { final params = { 'trackId': _id, 'uuid': _client.uuid, @@ -92,17 +92,17 @@ class StringeeVideoTrack { /// Attach view StringeeVideoView attach({ - Key? key, - Color? color, - bool? isOverlay, - bool? isMirror, - double? height, - double? width, - EdgeInsetsGeometry? margin, - AlignmentGeometry? alignment, - EdgeInsetsGeometry? padding, - Widget? child, - ScalingType? scalingType, + Key key, + Color color, + bool isOverlay, + bool isMirror, + double height, + double width, + EdgeInsetsGeometry margin, + AlignmentGeometry alignment, + EdgeInsetsGeometry padding, + Widget child, + ScalingType scalingType, }) { StringeeVideoView videoView = StringeeVideoView.forTrack( _id, diff --git a/lib/src/messaging/StringeeChat.dart b/lib/src/messaging/StringeeChat.dart index ec6479e..b35719e 100644 --- a/lib/src/messaging/StringeeChat.dart +++ b/lib/src/messaging/StringeeChat.dart @@ -1,15 +1,11 @@ import 'dart:async'; import 'dart:convert'; -import '../StringeeClient.dart'; -import '../StringeeConstants.dart'; -import 'StringeeConversation.dart'; -import 'StringeeMessage.dart'; -import 'StringeeUser.dart'; +import 'package:stringee_flutter_plugin/stringee_flutter_plugin.dart'; class StringeeChat { - late StringeeClient _client; - late StreamSubscription _subscriber; + StringeeClient _client; + StreamSubscription _subscriber; StreamController _eventStreamController = StreamController.broadcast(); @@ -47,10 +43,7 @@ class StringeeChat { /// Get live-chat token Future> getLiveChatToken( - String key, - String name, - String email, - ) async { + String key, String name, String email) async { if (key.trim().isEmpty) return await reportInvalidValue('key'); if (name.trim().isEmpty) return await reportInvalidValue('name'); if (email.trim().isEmpty) return await reportInvalidValue('email'); @@ -59,7 +52,7 @@ class StringeeChat { 'key': key.trim(), 'name': name.trim(), 'email': email.trim(), - 'uuid': _client.uuid, + 'uuid': _client.uuid }; return await StringeeClient.methodChannel @@ -81,13 +74,11 @@ class StringeeChat { } /// Create live-chat [StringeeConversation] - Future> createLiveChatConversation(String queueId) async { + Future> createLiveChatConversation( + String queueId) async { if (queueId.trim().isEmpty) return await reportInvalidValue('queueId'); - final params = { - 'queueId': queueId, - 'uuid': _client.uuid, - }; + final params = {'queueId': queueId, 'uuid': _client.uuid}; Map result = await StringeeClient.methodChannel .invokeMethod('createLiveChatConversation', params); @@ -163,7 +154,7 @@ class StringeeChat { } /// Get local [StringeeConversation] - Future> getLocalConversations({String? oaId}) async { + Future> getLocalConversations({String oaId}) async { final params = { if (oaId != null) 'oaId': oaId, 'uuid': _client.uuid, @@ -185,7 +176,7 @@ class StringeeChat { /// Get [count] of lastest [StringeeConversation] from Stringee server Future> getLastConversation( int count, { - String? oaId, + String oaId, }) async { if (count <= 0) return await reportInvalidValue('count'); @@ -212,16 +203,17 @@ class StringeeChat { Future> getConversationsBefore( int count, int datetime, { - String? oaId, + String oaId, }) async { if (count <= 0) return await reportInvalidValue('count'); if (datetime <= 0) return await reportInvalidValue('datetime'); final param = { 'count': count, - 'datetime': datetime, if (oaId != null) 'oaId': oaId, + 'datetime': datetime, 'uuid': _client.uuid }; + Map result = await StringeeClient.methodChannel .invokeMethod('getConversationsBefore', param); if (result['status']) { @@ -239,16 +231,17 @@ class StringeeChat { Future> getConversationsAfter( int count, int datetime, { - String? oaId, + String oaId, }) async { if (count <= 0) return await reportInvalidValue('count'); if (datetime <= 0) return await reportInvalidValue('datetime'); final param = { 'count': count, - 'datetime': datetime, if (oaId != null) 'oaId': oaId, + 'datetime': datetime, 'uuid': _client.uuid }; + Map result = await StringeeClient.methodChannel .invokeMethod('getConversationsAfter', param); if (result['status']) { @@ -290,19 +283,19 @@ class StringeeChat { void _handleReceiveChangeEvent(Map map) { ChangeType changeType = ChangeType.values[map['changeType']]; ObjectType objectType = ObjectType.values[map['objectType']]; - List? objectDatas = map['objects']; + List objectDatas = map['objects']; List objects = []; switch (objectType) { case ObjectType.conversation: - for (int i = 0; i < objectDatas!.length; i++) { + for (int i = 0; i < objectDatas.length; i++) { StringeeConversation conv = new StringeeConversation.fromJson(objectDatas[i], _client); objects.add(conv); } break; case ObjectType.message: - for (int i = 0; i < objectDatas!.length; i++) { + for (int i = 0; i < objectDatas.length; i++) { StringeeMessage msg = new StringeeMessage.fromJson(objectDatas[i], _client); objects.add(msg); diff --git a/lib/src/messaging/StringeeChatRequest.dart b/lib/src/messaging/StringeeChatRequest.dart index 6c28360..de29c21 100644 --- a/lib/src/messaging/StringeeChatRequest.dart +++ b/lib/src/messaging/StringeeChatRequest.dart @@ -2,9 +2,9 @@ import '../StringeeClient.dart'; import '../StringeeConstants.dart'; class StringeeChatRequest { - late String _convId; - late String _customerId; - late String _customerName; + String _convId; + String _customerId; + String _customerName; StringeeChannelType _channelType = StringeeChannelType.livechat; StringeeChatRequestType _type = StringeeChatRequestType.normal; @@ -18,7 +18,7 @@ class StringeeChatRequest { StringeeChatRequestType get type => _type; - late StringeeClient _client; + StringeeClient _client; StringeeChatRequest(Map data, StringeeClient client) { _convId = data["convId"]; diff --git a/lib/src/messaging/StringeeConversation.dart b/lib/src/messaging/StringeeConversation.dart index 9a6f819..a8f9235 100644 --- a/lib/src/messaging/StringeeConversation.dart +++ b/lib/src/messaging/StringeeConversation.dart @@ -8,46 +8,46 @@ import '../StringeeConstants.dart'; import 'StringeeUser.dart'; class StringeeConversation { - String? _id; - String? _name; - bool? _isGroup; - String? _creator; - int? _createdAt; - int? _updatedAt; - int? _totalUnread; - Map? _text; - StringeeMessage? _lastMsg; - String? _pinnedMsgId; - List? _participants; - String? _oaId; - String? _customData; - late StringeeClient _client; + String _id; + String _name; + bool _isGroup; + String _creator; + int _createdAt; + int _updatedAt; + int _totalUnread; + Map _text; + StringeeMessage _lastMsg; + String _pinnedMsgId; + List _participants; + String _oaId; + String _customData; + StringeeClient _client; - String? get id => _id; + String get id => _id; - String? get name => _name; + String get name => _name; - bool? get isGroup => _isGroup; + bool get isGroup => _isGroup; - String? get creator => _creator; + String get creator => _creator; - int? get totalUnread => _totalUnread; + int get totalUnread => _totalUnread; - int? get updatedAt => _updatedAt; + int get updatedAt => _updatedAt; - int? get createdAt => _createdAt; + int get createdAt => _createdAt; - Map? get text => _text; + Map get text => _text; - StringeeMessage? get lastMsg => _lastMsg; + StringeeMessage get lastMsg => _lastMsg; - String? get pinnedMsgId => _pinnedMsgId; + String get pinnedMsgId => _pinnedMsgId; - List? get participants => _participants; + List get participants => _participants; - String? get oaId => _oaId; + String get oaId => _oaId; - String? get customData => _customData; + String get customData => _customData; @override String toString() { @@ -67,7 +67,7 @@ class StringeeConversation { } StringeeConversation.fromJson( - Map? convInfor, StringeeClient client) { + Map convInfor, StringeeClient client) { if (convInfor == null) { return; } @@ -84,7 +84,7 @@ class StringeeConversation { this._lastMsg = new StringeeMessage.lstMsg( convInfor['lastMsgId'], this._id, - (convInfor['lastMsgType'] as int?).msgType, + (convInfor['lastMsgType'] as int).msgType, convInfor['lastMsgSender'], convInfor['lastMsgSeqReceived'], MsgState.values[convInfor['lastMsgState']], @@ -108,9 +108,11 @@ class StringeeConversation { /// Send chat transcript Future> sendChatTranscript( String email, String domain) async { - if (email.trim().isEmpty) return await reportInvalidValue('email'); - if (domain.trim().isEmpty) return await reportInvalidValue('domain'); - if (_id == null || _id!.isEmpty) return await reportInvalidValue('convId'); + if (email == null || email.trim().isEmpty) + return await reportInvalidValue('email'); + if (domain == null || domain.trim().isEmpty) + return await reportInvalidValue('domain'); + if (_id == null || _id.isEmpty) return await reportInvalidValue('convId'); final params = { 'email': email.trim(), @@ -125,7 +127,7 @@ class StringeeConversation { /// End live-chat [StringeeConversation] Future> endChat() async { - if (_id == null || _id!.isEmpty) return await reportInvalidValue('convId'); + if (_id == null || _id.isEmpty) return await reportInvalidValue('convId'); final params = {'convId': _id, 'uuid': _client.uuid}; @@ -136,7 +138,7 @@ class StringeeConversation { /// Send begin typing Future> beginTyping() async { - if (_id == null || _id!.isEmpty) return await reportInvalidValue('convId'); + if (_id == null || _id.isEmpty) return await reportInvalidValue('convId'); final params = {'convId': _id, 'uuid': _client.uuid}; return await StringeeClient.methodChannel .invokeMethod('beginTyping', params); @@ -144,14 +146,17 @@ class StringeeConversation { /// Send end typing Future> endTyping() async { - if (_id == null || _id!.isEmpty) return await reportInvalidValue('convId'); + if (_id == null || _id.isEmpty) return await reportInvalidValue('convId'); final params = {'convId': _id, 'uuid': _client.uuid}; return await StringeeClient.methodChannel.invokeMethod('endTyping', params); } /// Delete [StringeeConversation] Future> delete() async { - final params = {'convId': this._id, 'uuid': _client.uuid}; + final params = { + 'convId': this._id, + 'uuid': _client.uuid, + }; return await StringeeClient.methodChannel.invokeMethod('delete', params); } @@ -159,7 +164,7 @@ class StringeeConversation { /// Add [List] of [participants] of [StringeeConversation] Future> addParticipants( List participants) async { - if (participants.length == 0) + if (participants == null || participants.length == 0) return await reportInvalidValue('participants'); final params = { 'convId': this._id, @@ -183,7 +188,7 @@ class StringeeConversation { /// Remove [List] of [participants] of [StringeeConversation] Future> removeParticipants( List participants) async { - if (participants.length == 0) + if (participants == null || participants.length == 0) return await reportInvalidValue('participants'); final params = { 'convId': this._id, @@ -206,6 +211,7 @@ class StringeeConversation { /// Send [StringeeMessage] Future> sendMessage(StringeeMessage message) async { + if (message == null) return await reportInvalidValue('message'); message.convId = this._id; Map params = message.toJson(); @@ -218,8 +224,13 @@ class StringeeConversation { /// Get [List] of [StringeeMessage] of [StringeeConversation] by [msgIds] Future> getMessages(List msgIds) async { - if (msgIds.length == 0) return await reportInvalidValue('msgIds'); - final params = {'convId': this._id, 'msgIds': msgIds, 'uuid': _client.uuid}; + if (msgIds == null || msgIds.length == 0) + return await reportInvalidValue('msgIds'); + final params = { + 'convId': this._id, + 'msgIds': msgIds, + 'uuid': _client.uuid, + }; Map result = await StringeeClient.methodChannel.invokeMethod('getMessages', params); if (result['status']) { @@ -236,8 +247,12 @@ class StringeeConversation { /// Get [count] of local [StringeeMessage] of [StringeeConversation] Future> getLocalMessages(int count) async { - if (count <= 0) return await reportInvalidValue('count'); - final params = {'convId': this._id, 'count': count, 'uuid': _client.uuid}; + if (count == null || count <= 0) return await reportInvalidValue('count'); + final params = { + 'convId': this._id, + 'count': count, + 'uuid': _client.uuid, + }; Map result = await StringeeClient.methodChannel .invokeMethod('getLocalMessages', params); if (result['status']) { @@ -254,8 +269,12 @@ class StringeeConversation { /// Get [count] of lastest [StringeeMessage] of [StringeeConversation] Future> getLastMessages(int count) async { - if (count <= 0) return await reportInvalidValue('count'); - final params = {'convId': this._id, 'count': count, 'uuid': _client.uuid}; + if (count == null || count <= 0) return await reportInvalidValue('count'); + final params = { + 'convId': this._id, + 'count': count, + 'uuid': _client.uuid, + }; Map result = await StringeeClient.methodChannel .invokeMethod('getLastMessages', params); if (result['status']) { @@ -273,8 +292,9 @@ class StringeeConversation { /// Get [count] of [StringeeMessage] after [StringeeMessage.sequence] of [StringeeConversation] Future> getMessagesAfter( int count, int sequence) async { - if (count <= 0) return await reportInvalidValue('count'); - if (sequence < 0) return await reportInvalidValue('sequence'); + if (count == null || count <= 0) return await reportInvalidValue('count'); + if (sequence == null || sequence < 0) + return await reportInvalidValue('sequence'); final params = { 'convId': this._id, 'count': count, @@ -298,8 +318,9 @@ class StringeeConversation { /// Get [count] of [StringeeMessage] before [StringeeMessage.sequence] of [StringeeConversation] Future> getMessagesBefore( int count, int sequence) async { - if (count <= 0) return await reportInvalidValue('count'); - if (sequence < 0) return await reportInvalidValue('sequence'); + if (count == null || count <= 0) return await reportInvalidValue('count'); + if (sequence == null || sequence < 0) + return await reportInvalidValue('sequence'); final params = { 'convId': this._id, 'count': count, @@ -322,7 +343,8 @@ class StringeeConversation { /// Update [StringeeConversation.name] Future> updateConversation(String name) async { - if (name.trim().isEmpty) return await reportInvalidValue('name'); + if (name == null || name.trim().isEmpty) + return await reportInvalidValue('name'); final params = { 'convId': this._id, 'name': name.trim(), @@ -334,7 +356,9 @@ class StringeeConversation { /// Change [UserRole] Future> setRole(String userId, UserRole role) async { - if (userId.trim().isEmpty) return await reportInvalidValue('userId'); + if (userId == null || userId.trim().isEmpty) + return await reportInvalidValue('userId'); + if (role == null) return await reportInvalidValue('role'); final params = { 'convId': this._id, 'userId': userId.trim(), @@ -346,8 +370,13 @@ class StringeeConversation { /// Delete [List] of [StringeeMessage] Future> deleteMessages(List msgIds) async { - if (msgIds.length == 0) return await reportInvalidValue('msgIds'); - final params = {'convId': this._id, 'msgIds': msgIds, 'uuid': _client.uuid}; + if (msgIds == null || msgIds.length == 0) + return await reportInvalidValue('msgIds'); + final params = { + 'convId': this._id, + 'msgIds': msgIds, + 'uuid': _client.uuid, + }; return await StringeeClient.methodChannel .invokeMethod('deleteMessages', params); } @@ -355,7 +384,9 @@ class StringeeConversation { /// Revoke [List] of [StringeeMessage] include deleted [StringeeMessage] or not Future> revokeMessages( List msgIds, bool isDeleted) async { - if (msgIds.length == 0) return await reportInvalidValue('msgIds'); + if (msgIds == null || msgIds.length == 0) + return await reportInvalidValue('msgIds'); + if (isDeleted == null) return await reportInvalidValue('isDeleted'); final params = { 'convId': this._id, 'msgIds': msgIds, @@ -368,7 +399,10 @@ class StringeeConversation { /// Mark [StringeeConversation] as readed Future> markAsRead() async { - final params = {'convId': this._id, 'uuid': _client.uuid}; + final params = { + 'convId': this._id, + 'uuid': _client.uuid, + }; return await StringeeClient.methodChannel .invokeMethod('markAsRead', params); diff --git a/lib/src/messaging/StringeeMessage.dart b/lib/src/messaging/StringeeMessage.dart index 6fedb70..7d3b510 100644 --- a/lib/src/messaging/StringeeMessage.dart +++ b/lib/src/messaging/StringeeMessage.dart @@ -5,44 +5,44 @@ import '../StringeeConstants.dart'; class StringeeMessage { /// Base - String? _id; - String? _localId; - String? _convId; - String? _senderId; - int? _createdAt; - int? _sequence; - MsgState? _state; - MsgType? _type; - String? _text; + String _id; + String _localId; + String _convId; + String _senderId; + int _createdAt; + int _sequence; + MsgState _state; + MsgType _type; + String _text; /// Photo - String? _thumbnail; - String? _filePath; - String? _fileUrl; + String _thumbnail; + String _filePath; + String _fileUrl; /// Location - double? _latitude; - double? _longitude; + double _latitude; + double _longitude; /// File - String? _fileName; - int? _fileLength; + String _fileName; + int _fileLength; /// Audio + Video - int? _duration; - double? _ratio; + int _duration; + double _ratio; - String? _vcard; + String _vcard; /// Sticker - String? _stickerCategory; - String? _stickerName; + String _stickerCategory; + String _stickerName; - Map? _customData; - Map? _notiContent; + Map _customData; + Map _notiContent; // Multi Client - late StringeeClient _client; + StringeeClient _client; @override String toString() { @@ -56,8 +56,11 @@ class StringeeMessage { StringeeMessage.typeText( StringeeClient client, String text, { - Map? customData, - }) : assert(text.trim().isNotEmpty) { + Map customData, + }) : assert(text != null || text.trim().isNotEmpty) { + if (client == null) { + throw Exception("Client can not be null"); + } _client = client; this._type = MsgType.text; this._text = text.trim(); @@ -69,10 +72,13 @@ class StringeeMessage { StringeeMessage.typePhoto( StringeeClient client, String filePath, { - String? thumbnail, - double? ratio, - Map? customData, - }) : assert(filePath.trim().isNotEmpty) { + String thumbnail, + double ratio, + Map customData, + }) : assert(filePath != null || filePath.trim().isNotEmpty) { + if (client == null) { + throw Exception("Client can not be null"); + } _client = client; this._type = MsgType.photo; @@ -92,11 +98,14 @@ class StringeeMessage { StringeeClient client, String filePath, int duration, { - String? thumbnail, - double? ratio, - Map? customData, - }) : assert(filePath.trim().isNotEmpty), - assert(duration > 0) { + String thumbnail, + double ratio, + Map customData, + }) : assert(filePath != null || filePath.trim().isNotEmpty), + assert(duration != null || duration > 0) { + if (client == null) { + throw Exception("Client can not be null"); + } _client = client; this._type = MsgType.video; @@ -117,9 +126,12 @@ class StringeeMessage { StringeeClient client, String filePath, int duration, { - Map? customData, - }) : assert(filePath.trim().isNotEmpty), - assert(duration > 0) { + Map customData, + }) : assert(filePath != null || filePath.trim().isNotEmpty), + assert(duration != null || duration > 0) { + if (client == null) { + throw Exception("Client can not be null"); + } _client = client; this._type = MsgType.audio; @@ -133,10 +145,13 @@ class StringeeMessage { StringeeMessage.typeFile( StringeeClient client, String filePath, { - String? fileName, - int? fileLength, - Map? customData, - }) : assert(filePath.trim().isNotEmpty) { + String fileName, + int fileLength, + Map customData, + }) : assert(filePath != null || filePath.trim().isNotEmpty) { + if (client == null) { + throw Exception("Client can not be null"); + } _client = client; this._type = MsgType.file; @@ -156,8 +171,11 @@ class StringeeMessage { StringeeMessage.typeLink( StringeeClient client, String text, { - Map? customData, - }) : assert(text.trim().isNotEmpty) { + Map customData, + }) : assert(text != null || text.trim().isNotEmpty) { + if (client == null) { + throw Exception("Client can not be null"); + } _client = client; this._type = MsgType.link; @@ -171,9 +189,12 @@ class StringeeMessage { StringeeClient client, double latitude, double longitude, { - Map? customData, - }) : assert(latitude > 0), - assert(longitude > 0) { + Map customData, + }) : assert(latitude != null || latitude > 0), + assert(longitude != null || longitude > 0) { + if (client == null) { + throw Exception("Client can not be null"); + } _client = client; this._type = MsgType.location; @@ -187,8 +208,11 @@ class StringeeMessage { StringeeMessage.typeContact( StringeeClient client, String vcard, { - Map? customData, - }) : assert(vcard.trim().isNotEmpty) { + Map customData, + }) : assert(vcard != null || vcard.trim().isNotEmpty) { + if (client == null) { + throw Exception("Client can not be null"); + } _client = client; this._type = MsgType.contact; @@ -202,9 +226,12 @@ class StringeeMessage { StringeeClient client, String stickerCategory, String stickerName, { - Map? customData, - }) : assert(stickerCategory.trim().isNotEmpty), - assert(stickerName.trim().isNotEmpty) { + Map customData, + }) : assert(stickerCategory != null || stickerCategory.trim().isNotEmpty), + assert(stickerName != null || stickerName.trim().isNotEmpty) { + if (client == null) { + throw Exception("Client can not be null"); + } _client = client; this._type = MsgType.contact; @@ -215,58 +242,61 @@ class StringeeMessage { } } - Map? get customData => _customData; + Map get customData => _customData; - Map? get notiContent => _notiContent; + Map get notiContent => _notiContent; - String? get stickerName => _stickerName; + String get stickerName => _stickerName; - String? get stickerCategory => _stickerCategory; + String get stickerCategory => _stickerCategory; - double? get ratio => _ratio; + double get ratio => _ratio; - int? get duration => _duration; + int get duration => _duration; - int? get fileLength => _fileLength; + int get fileLength => _fileLength; - String? get fileName => _fileName; + String get fileName => _fileName; - String? get fileUrl => _fileUrl; + String get fileUrl => _fileUrl; - String? get filePath => _filePath; + String get filePath => _filePath; - double? get longitude => _longitude; + double get longitude => _longitude; - double? get latitude => _latitude; + double get latitude => _latitude; - String? get thumbnail => _thumbnail; + String get thumbnail => _thumbnail; - String? get text => _text; + String get text => _text; - MsgType? get type => _type; + MsgType get type => _type; - MsgState? get state => _state; + MsgState get state => _state; - int? get sequence => _sequence; + int get sequence => _sequence; - int? get createdAt => _createdAt; + int get createdAt => _createdAt; - String? get senderId => _senderId; + String get senderId => _senderId; - String? get convId => _convId; + String get convId => _convId; - String? get id => _id; + String get id => _id; - String? get localId => _localId; + String get localId => _localId; - String? get vcard => _vcard; + String get vcard => _vcard; - set convId(String? value) { + set convId(String value) { _convId = value; } StringeeMessage.fromJson( Map msgInfor, StringeeClient client) { + if (msgInfor == null) { + return; + } _client = client; this._id = msgInfor['id']; @@ -278,9 +308,9 @@ class StringeeMessage { this._customData = msgInfor['customData']; this._state = MsgState.values[msgInfor['state']]; - MsgType msgType = (msgInfor['type'] as int?).msgType; + MsgType msgType = (msgInfor['type'] as int).msgType; this._type = msgType; - String? text = ''; + String text = ''; switch (this._type) { case MsgType.text: case MsgType.link: @@ -288,8 +318,8 @@ class StringeeMessage { break; case MsgType.createConversation: case MsgType.renameConversation: - String? groupName = msgInfor['content']['groupName']; - String? creator = msgInfor['content']['creator']; + String groupName = msgInfor['content']['groupName']; + String creator = msgInfor['content']['creator']; List participants = []; List participantArray = msgInfor['content']['participants']; @@ -299,9 +329,9 @@ class StringeeMessage { } this._notiContent = new Map(); - this._notiContent!["groupName"] = groupName; - this._notiContent!["creator"] = creator; - this._notiContent!["participants"] = participants; + this._notiContent["groupName"] = groupName; + this._notiContent["creator"] = creator; + this._notiContent["participants"] = participants; break; case MsgType.photo: Map photoMap = msgInfor['content']['photo']; @@ -348,35 +378,35 @@ class StringeeMessage { case MsgType.notification: Map notifyMap = msgInfor['content']; this._notiContent = new Map(); - MsgNotifyType notifyType = (notifyMap['type'] as int?).notifyType; - this._notiContent!['type'] = notifyType; + MsgNotifyType notifyType = (notifyMap['type'] as int).notifyType; + this._notiContent['type'] = notifyType; switch (notifyType) { case MsgNotifyType.addParticipants: StringeeUser user = new StringeeUser.fromJson(notifyMap['addedInfo']); - this._notiContent!['addedby'] = user; + this._notiContent['addedby'] = user; List participants = []; List participantArray = notifyMap['participants']; for (int i = 0; i < participantArray.length; i++) { StringeeUser user = StringeeUser.fromJson(participantArray[i]); participants.add(user); } - this._notiContent!["participants"] = participants; + this._notiContent["participants"] = participants; break; case MsgNotifyType.removeParticipants: StringeeUser user = new StringeeUser.fromJson(notifyMap['removedInfo']); - this._notiContent!['removedBy'] = user; + this._notiContent['removedBy'] = user; List participants = []; List participantArray = notifyMap['participants']; for (int i = 0; i < participantArray.length; i++) { StringeeUser user = StringeeUser.fromJson(participantArray[i]); participants.add(user); } - this._notiContent!["participants"] = participants; + this._notiContent["participants"] = participants; break; case MsgNotifyType.changeGroupName: - this._notiContent!['groupName'] = notifyMap['groupName']; + this._notiContent['groupName'] = notifyMap['groupName']; break; } break; @@ -385,17 +415,19 @@ class StringeeMessage { } StringeeMessage.lstMsg( - String? msgId, - String? convId, + String msgId, + String convId, MsgType msgType, - String? senderId, - int? sequence, + String senderId, + int sequence, MsgState msgState, - int? createdAt, - Map? msgInfor) { + int createdAt, + Map msgInfor) { if (msgId == null || + msgType == null || senderId == null || sequence == null || + msgState == null || createdAt == null || msgInfor == null) { return; @@ -405,12 +437,14 @@ class StringeeMessage { this._senderId = senderId; this._createdAt = createdAt; this._sequence = sequence; - if (msgInfor.containsKey('metadata') && msgInfor['metadata'] != null && msgInfor['metadata'].toString().isNotEmpty) { + if (msgInfor.containsKey('metadata') && + msgInfor['metadata'] != null && + msgInfor['metadata'].toString().isNotEmpty) { this._customData = msgInfor['metadata']; } this._state = msgState; this._type = msgType; - String? text = ''; + String text = ''; switch (this._type) { case MsgType.text: case MsgType.link: @@ -426,9 +460,9 @@ class StringeeMessage { } this._notiContent = new Map(); - this._notiContent!["groupName"] = msgInfor['groupName']; - this._notiContent!["creator"] = msgInfor['creator']; - this._notiContent!["participants"] = participants; + this._notiContent["groupName"] = msgInfor['groupName']; + this._notiContent["creator"] = msgInfor['creator']; + this._notiContent["participants"] = participants; break; case MsgType.photo: Map photoMap = msgInfor['photo']; @@ -474,13 +508,13 @@ class StringeeMessage { break; case MsgType.notification: this._notiContent = new Map(); - MsgNotifyType notifyType = (msgInfor['type'] as int?).notifyType; - this._notiContent!['type'] = notifyType; + MsgNotifyType notifyType = (msgInfor['type'] as int).notifyType; + this._notiContent['type'] = notifyType; switch (notifyType) { case MsgNotifyType.addParticipants: StringeeUser user = new StringeeUser.fromJsonNotify(msgInfor['addedInfo']); - this._notiContent!['addedby'] = user; + this._notiContent['addedby'] = user; List participants = []; List participantArray = msgInfor['participants']; for (int i = 0; i < participantArray.length; i++) { @@ -488,12 +522,12 @@ class StringeeMessage { StringeeUser.fromJsonNotify(participantArray[i]); participants.add(user); } - this._notiContent!["participants"] = participants; + this._notiContent["participants"] = participants; break; case MsgNotifyType.removeParticipants: StringeeUser user = new StringeeUser.fromJsonNotify(msgInfor['removedInfo']); - this._notiContent!['removedBy'] = user; + this._notiContent['removedBy'] = user; List participants = []; List participantArray = msgInfor['participants']; for (int i = 0; i < participantArray.length; i++) { @@ -501,10 +535,10 @@ class StringeeMessage { StringeeUser.fromJsonNotify(participantArray[i]); participants.add(user); } - this._notiContent!["participants"] = participants; + this._notiContent["participants"] = participants; break; case MsgNotifyType.changeGroupName: - this._notiContent!['groupName'] = msgInfor['groupName']; + this._notiContent['groupName'] = msgInfor['groupName']; break; } break; @@ -514,32 +548,32 @@ class StringeeMessage { Map toJson() { Map params = new Map(); - params['convId'] = _convId!.trim(); + params['convId'] = _convId.trim(); params['type'] = _type.value; if (_customData != null) params['customData'] = _customData; switch (this._type) { case MsgType.text: case MsgType.link: - params['text'] = _text!.trim(); + params['text'] = _text.trim(); break; case MsgType.photo: - if (_filePath != null) params['filePath'] = _filePath!.trim(); - if (_thumbnail != null) params['thumbnail'] = _thumbnail!.trim(); + if (_filePath != null) params['filePath'] = _filePath.trim(); + if (_thumbnail != null) params['thumbnail'] = _thumbnail.trim(); if (_ratio != null) params['ratio'] = _ratio; break; case MsgType.file: - if (_filePath != null) params['filePath'] = _filePath!.trim(); - if (_fileName != null) params['filename'] = _fileName!.trim(); + if (_filePath != null) params['filePath'] = _filePath.trim(); + if (_fileName != null) params['filename'] = _fileName.trim(); if (_fileLength != null) params['length'] = _fileLength; break; case MsgType.video: - if (_filePath != null) params['filePath'] = _filePath!.trim(); - if (_thumbnail != null) params['thumbnail'] = _thumbnail!.trim(); + if (_filePath != null) params['filePath'] = _filePath.trim(); + if (_thumbnail != null) params['thumbnail'] = _thumbnail.trim(); if (_ratio != null) params['ratio'] = _ratio; if (_duration != null) params['duration'] = _duration; break; case MsgType.audio: - if (_filePath != null) params['filePath'] = _filePath!.trim(); + if (_filePath != null) params['filePath'] = _filePath.trim(); if (_duration != null) params['duration'] = _duration; break; case MsgType.location: @@ -547,12 +581,12 @@ class StringeeMessage { if (_longitude != null) params['lon'] = _longitude; break; case MsgType.contact: - if (_vcard != null) params['vcard'] = _vcard!.trim(); + if (_vcard != null) params['vcard'] = _vcard.trim(); break; case MsgType.sticker: if (_stickerCategory != null) - params['stickerCategory'] = _stickerCategory!.trim(); - if (_stickerName != null) params['stickerName'] = _stickerName!.trim(); + params['stickerCategory'] = _stickerCategory.trim(); + if (_stickerName != null) params['stickerName'] = _stickerName.trim(); break; } return params; @@ -560,9 +594,9 @@ class StringeeMessage { /// Edit [StringeeMessage.typeText] Future> edit(String content) async { - assert(content.trim().isNotEmpty); + assert(content != null || content.trim().isNotEmpty); final params = { - 'convId': this._convId!.trim(), + 'convId': this._convId.trim(), 'msgId': this._id, 'content': content, 'uuid': _client.uuid @@ -572,8 +606,9 @@ class StringeeMessage { /// Pin/Un pin [StringeeMessage] Future> pinOrUnPin(bool pinOrUnPin) async { + if (pinOrUnPin == null) return await reportInvalidValue('pinOrUnPin'); final params = { - 'convId': this._convId!.trim(), + 'convId': this._convId.trim(), 'msgId': this._id, 'pinOrUnPin': pinOrUnPin, 'uuid': _client.uuid diff --git a/lib/src/messaging/StringeeUser.dart b/lib/src/messaging/StringeeUser.dart index 4460944..821f031 100644 --- a/lib/src/messaging/StringeeUser.dart +++ b/lib/src/messaging/StringeeUser.dart @@ -1,22 +1,23 @@ +import 'package:flutter/material.dart'; import 'package:stringee_flutter_plugin/src/StringeeConstants.dart'; class StringeeUser { - String? _userId; - String? _name; - String? _avatarUrl; + String _userId; + String _name; + String _avatarUrl; UserRole _role = UserRole.member; - StringeeUser({required String userId, String? name, String? avatarUrl}) { + StringeeUser({@required String userId, String name, String avatarUrl}) { this._userId = userId; this._name = name; this._avatarUrl = avatarUrl; } - String? get userId => _userId; + String get userId => _userId; - String? get name => _name; + String get name => _name; - String? get avatarUrl => _avatarUrl; + String get avatarUrl => _avatarUrl; UserRole get role => _role; @@ -27,10 +28,10 @@ class StringeeUser { Map toJson() { Map params = new Map(); - params['userId'] = _userId!.trim(); - if (_name != null) params['name'] = _name!.trim(); - if (_avatarUrl != null) params['avatarUrl'] = _avatarUrl!.trim(); - params['role'] = _role.index; + params['userId'] = _userId.trim(); + if (_name != null) params['name'] = _name.trim(); + if (_avatarUrl != null) params['avatarUrl'] = _avatarUrl.trim(); + if (_role != null) params['role'] = _role.index; return params; } @@ -39,7 +40,7 @@ class StringeeUser { this._name = json['name']; this._avatarUrl = json['avatarUrl']; if (json.containsKey('role')) { - String? role = json['role']; + String role = json['role']; switch (role) { case 'member': this._role = UserRole.member; @@ -59,7 +60,7 @@ class StringeeUser { this._name = json['displayName']; this._avatarUrl = json['avatarUrl']; if (json.containsKey('role')) { - String? role = json['role']; + String role = json['role']; switch (role) { case 'member': this._role = UserRole.member;