diff --git a/CHANGELOG.md b/CHANGELOG.md index 1200b4b4..10f40211 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,10 @@ ## NEXT -## 3.8.3+7 +## 3.8.3+9 + +- 将设置推送相关操作从EMPushConfigs中移到EMPushManager中; + +## 3.8.3+8 - 修复ios使用token登录失败; - 修改Login方法和Logout方法返回值; diff --git a/README.md b/README.md index 2f7367cd..3243c7a4 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ Demo中使用的音视频是针对声网音视频封装的[EaseCallKit](https:// ```dart dependencies: - im_flutter_sdk: ^3.8.3+7 + im_flutter_sdk: ^3.8.3+9 ``` 2. 执行`flutter pub get`; @@ -1558,7 +1558,7 @@ try{ ```dart try{ - EMImPushConfig pushManager = await EMClient.getInstance.pushManager.getImPushConfigFromServer(); + EMPushConfigs pushConfigs = await EMClient.getInstance.pushManager.getPushConfigsFromServer(); } on EMError catch(e) { print('操作失败,原因是: $e'); } @@ -1568,7 +1568,7 @@ try{ ```dart try{ - EMImPushConfig pushConfig = await EMClient.getInstance.pushManager.getImPushConfig(); + EMPushConfigs pushConfigs = await EMClient.getInstance.pushManager.getPushConfigsFromCache(); } on EMError catch(e) { print('操作失败,原因是: $e'); } @@ -1578,13 +1578,13 @@ try{ ```dart try{ - await pushConfig.setPushStyle(EMImPushStyle.Simple); + await EMClient.getInstance.pushManager.updatePushDisplayStyle(DisplayStyle.Simple); } on EMError catch(e) { print('操作失败,原因是: $e'); } ``` -> `EMImPushStyle`是收推送时样式,目前有两种样式: +> `DisplayStyle`是收推送时样式,目前有两种样式: > `Simple`显示“您有一条新消息”; > `Summary`显示推送详情; @@ -1592,7 +1592,7 @@ try{ ```dart try{ - await pushConfig.setNoDisturb(true, 10, 22); + await EMClient.getInstance.pushManager.disableOfflinePush(10, 22); } on EMError catch(e) { print('操作失败,原因是: $e'); } @@ -1604,7 +1604,7 @@ try{ ```dart try{ - await pushConfig.setNoDisturb(false); + await EMClient.getInstance.pushManager.enableOfflinePush(); } on EMError catch(e) { print('操作失败,原因是: $e'); } @@ -1614,7 +1614,7 @@ try{ ```dart try{ - await pushConfig.setGroupToDisturb(groupId, true); + await EMClient.getInstance.pushManager.updatePushServiceForGroup(groupId, false); } on EMError catch(e) { print('操作失败,原因是: $e'); } @@ -1624,7 +1624,7 @@ try{ ```dart try{ - List groupIdsList = await pushConfig.noDisturbGroupsFromServer(); + List groupIdsList = await EMClient.getInstance.pushManager.getNoPushGroupsFromCache(); } on EMError catch(e) { print('操作失败,原因是: $e'); } diff --git a/android/src/main/java/com/easemob/im_flutter_sdk/EMHelper.java b/android/src/main/java/com/easemob/im_flutter_sdk/EMHelper.java index 9d7511a7..402e4317 100644 --- a/android/src/main/java/com/easemob/im_flutter_sdk/EMHelper.java +++ b/android/src/main/java/com/easemob/im_flutter_sdk/EMHelper.java @@ -732,8 +732,8 @@ static EMImageMessageBody imageBodyFromJson(JSONObject json) throws JSONExceptio body.setThumbnailUrl(json.getString("thumbnailRemotePath")); body.setThumbnailSecret(json.getString("thumbnailSecret")); body.setFileLength(json.getInt("fileSize")); - int width = json.getInt("height"); - int height = json.getInt("width"); + int width = json.getInt("width"); + int height = json.getInt("height"); body.setThumbnailSize(width, height); body.setSendOriginalImage(json.getBoolean("sendOriginalImage")); @@ -770,8 +770,8 @@ static EMVideoMessageBody videoBodyFromJson(JSONObject json) throws JSONExceptio } body.setThumbnailSecret(json.getString("thumbnailSecret")); body.setFileName(json.getString("displayName")); - int width = json.getInt("height"); - int height = json.getInt("width"); + int width = json.getInt("width"); + int height = json.getInt("height"); body.setThumbnailSize(width, height); body.setRemoteUrl(json.getString("remotePath")); body.setDownloadStatus(downloadStatusFromInt(json.getInt("fileStatus"))); diff --git a/android/src/main/java/com/easemob/im_flutter_sdk/EMPushManagerWrapper.java b/android/src/main/java/com/easemob/im_flutter_sdk/EMPushManagerWrapper.java index 7614fff6..5049cf4c 100644 --- a/android/src/main/java/com/easemob/im_flutter_sdk/EMPushManagerWrapper.java +++ b/android/src/main/java/com/easemob/im_flutter_sdk/EMPushManagerWrapper.java @@ -8,6 +8,7 @@ import com.hyphenate.chat.EMPushManager.DisplayStyle; import com.hyphenate.exceptions.HyphenateException; +import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; @@ -58,6 +59,15 @@ else if(EMSDKMethod.updateHMSPushToken.equals(call.method)){ else if(EMSDKMethod.updateFCMPushToken.equals(call.method)){ updateFCMPushToken(param, call.method, result); } + else if (EMSDKMethod.enableOfflinePush.equals(call.method)) { + enableOfflinePush(param, call.method, result); + } + else if (EMSDKMethod.disableOfflinePush.equals(call.method)){ + disableOfflinePush(param, call.method, result); + } + else if (EMSDKMethod.getNoPushGroups.equals(call.method)) { + getNoPushGroups(param, call.method, result); + } else { super.onMethodCall(call, result); } @@ -112,21 +122,57 @@ private void imPushNoDisturb(JSONObject params, String channelName, Result resu }); } + private void enableOfflinePush(JSONObject params, String channelName, Result result) throws JSONException + { + asyncRunnable(()-> { + try { + EMClient.getInstance().pushManager().enableOfflinePush(); + onSuccess(result, channelName, null); + } catch(HyphenateException e) { + onError(result, e); + } + }); + } + + private void disableOfflinePush(JSONObject params, String channelName, Result result) throws JSONException + { + int startTime = params.getInt("start"); + int endTime = params.getInt("end"); + asyncRunnable(()-> { + try { + EMClient.getInstance().pushManager().disableOfflinePush(startTime, endTime); + onSuccess(result, channelName, null); + } catch(HyphenateException e) { + onError(result, e); + } + }); + } + + private void getNoPushGroups(JSONObject params, String channelName, Result result) { + asyncRunnable(()-> { + List groups = EMClient.getInstance().pushManager().getNoPushGroups(); + onSuccess(result, channelName, groups); + }); + + } + private void updateImPushStyle(JSONObject params, String channelName, Result result) throws JSONException { DisplayStyle style = params.getInt("pushStyle") == 0 ? DisplayStyle.SimpleBanner : DisplayStyle.MessageSummary; EMClient.getInstance().pushManager().asyncUpdatePushDisplayStyle(style, new EMWrapperCallBack(result, channelName, true)); } private void updateGroupPushService(JSONObject params, String channelName, Result result) throws JSONException { - String groupId = params.getString("group_id"); - boolean enablePush = params.getBoolean("noDisturb"); + JSONArray groupIds = params.getJSONArray("group_ids"); + boolean noPush = params.getBoolean("noPush"); List groupList = new ArrayList<>(); - groupList.add(groupId); + for (int i = 0; i < groupIds.length(); i++) { + String groupId = groupIds.getString(i); + groupList.add(groupId); + } asyncRunnable(()-> { try { - EMClient.getInstance().pushManager().updatePushServiceForGroup(groupList, !enablePush); - EMGroup group = EMClient.getInstance().groupManager().getGroup(groupId); - onSuccess(result, channelName, EMGroupHelper.toJson(group)); + EMClient.getInstance().pushManager().updatePushServiceForGroup(groupList, noPush); + onSuccess(result, channelName, null); } catch(HyphenateException e) { onError(result, e); } diff --git a/android/src/main/java/com/easemob/im_flutter_sdk/EMSDKMethod.java b/android/src/main/java/com/easemob/im_flutter_sdk/EMSDKMethod.java index be776508..590f20d9 100644 --- a/android/src/main/java/com/easemob/im_flutter_sdk/EMSDKMethod.java +++ b/android/src/main/java/com/easemob/im_flutter_sdk/EMSDKMethod.java @@ -200,6 +200,9 @@ public class EMSDKMethod { static final String updatePushNickname = "updatePushNickname"; static final String updateHMSPushToken = "updateHMSPushToken"; static final String updateFCMPushToken = "updateFCMPushToken"; + static final String enableOfflinePush = "enableOfflinePush"; + static final String disableOfflinePush = "disableOfflinePush"; + static final String getNoPushGroups = "getNoPushGroups"; /// ImPushConfig static final String imPushNoDisturb = "imPushNoDisturb"; diff --git a/example/android/app/build.gradle b/example/android/app/build.gradle index 2fc41a4b..c2cc2f63 100644 --- a/example/android/app/build.gradle +++ b/example/android/app/build.gradle @@ -26,7 +26,7 @@ apply plugin: 'kotlin-android' apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" android { - compileSdkVersion 29 + compileSdkVersion 31 sourceSets { main.java.srcDirs += 'src/main/kotlin' diff --git a/example/android/app/src/main/AndroidManifest.xml b/example/android/app/src/main/AndroidManifest.xml index 66731b18..52b6d4b2 100644 --- a/example/android/app/src/main/AndroidManifest.xml +++ b/example/android/app/src/main/AndroidManifest.xml @@ -6,7 +6,7 @@ additional functionality it is fine to subclass or reimplement FlutterApplication and put your custom class here. --> diff --git a/example/android/build.gradle b/example/android/build.gradle index 4c0e9cc5..3ae9bf12 100644 --- a/example/android/build.gradle +++ b/example/android/build.gradle @@ -1,5 +1,5 @@ buildscript { - ext.kotlin_version = '1.3.50' + ext.kotlin_version = '1.5.31' repositories { google() mavenCentral() diff --git a/example/lib/main.dart b/example/lib/main.dart index 18edb6dc..68b700d0 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -30,6 +30,7 @@ void initSDK() async { var options = EMOptions(appKey: 'easemob-demo#easeim'); options.deleteMessagesAsExitGroup = false; options.deleteMessagesAsExitChatRoom = false; + options.autoAcceptGroupInvitation = true; options.debugModel = true; options.enableAPNs("EaseIM_APNS_Product"); diff --git a/example/lib/pages/contacts/contacts_page.dart b/example/lib/pages/contacts/contacts_page.dart index fc6ccf7b..a3a74411 100644 --- a/example/lib/pages/contacts/contacts_page.dart +++ b/example/lib/pages/contacts/contacts_page.dart @@ -249,6 +249,7 @@ class ContactsPageState extends State _contactList.addAll(list); } } on EMError { + _contactList.clear(); SmartDialog.showToast('获取失败'); _loadLocalContacts(count); } finally { diff --git a/ios/Classes/EMChatManagerWrapper.m b/ios/Classes/EMChatManagerWrapper.m index 819d7c8c..91b6a994 100644 --- a/ios/Classes/EMChatManagerWrapper.m +++ b/ios/Classes/EMChatManagerWrapper.m @@ -54,9 +54,9 @@ - (void)handleMethodCall:(FlutterMethodCall*)call channelName:call.method result:result]; } else if ([EMMethodKeyAckGroupMessageRead isEqualToString:call.method]) { - [self ackMessageRead:call.arguments - channelName:call.method - result:result]; + [self ackGroupMessageRead:call.arguments + channelName:call.method + result:result]; } else if ([EMMethodKeyAckConversationRead isEqualToString:call.method]) { [self ackConversationRead:call.arguments channelName:call.method diff --git a/ios/Classes/EMClientWrapper.m b/ios/Classes/EMClientWrapper.m index 89318bd2..5519db3c 100644 --- a/ios/Classes/EMClientWrapper.m +++ b/ios/Classes/EMClientWrapper.m @@ -227,7 +227,6 @@ - (void)login:(NSDictionary *)param channelName:(NSString *)aChannelName result: password:pwdOrToken completion:^(NSString *aUsername, EMError *aError) { - [weakSelf wrapperCallBack:result channelName:aChannelName error:aError @@ -241,7 +240,7 @@ - (void)login:(NSDictionary *)param channelName:(NSString *)aChannelName result: [weakSelf wrapperCallBack:result channelName:aChannelName error:aError - object:EMClient.sharedClient.accessUserToken]; + object:EMClient.sharedClient.currentUsername]; }]; } } diff --git a/ios/Classes/EMPushManagerWrapper.m b/ios/Classes/EMPushManagerWrapper.m index 75f48373..eb5aeea6 100644 --- a/ios/Classes/EMPushManagerWrapper.m +++ b/ios/Classes/EMPushManagerWrapper.m @@ -56,6 +56,18 @@ - (void)handleMethodCall:(FlutterMethodCall*)call [self bindDeviceToken:call.arguments channelName:call.method result:result]; + } else if ([EMMethodKeyEnablePush isEqualToString:call.method]) { + [self enablePush:call.arguments + channelName:call.method + result:result]; + } else if ([EMMethodKeyDisablePush isEqualToString:call.method]) { + [self disablePush:call.arguments + channelName:call.method + result:result]; + } else if ([EMMethodKeyGetNoPushGroups isEqualToString:call.method]) { + [self getNoPushGroups:call.arguments + channelName:call.method + result:result]; } else{ [super handleMethodCall:call result:result]; @@ -153,18 +165,17 @@ - (void)updateGroupPushService:(NSDictionary *)param channelName:(NSString *)aChannelName result:(FlutterResult)result { __weak typeof(self) weakSelf = self; - NSString *groupId = param[@"group_id"]; - bool enablePush = [param[@"enablePush"] boolValue]; + NSArray *groupIds = param[@"group_ids"]; + bool noPush = [param[@"noPush"] boolValue]; - [EMClient.sharedClient.pushManager updatePushServiceForGroups:@[groupId] - disablePush:!enablePush + [EMClient.sharedClient.pushManager updatePushServiceForGroups:groupIds + disablePush:noPush completion:^(EMError * _Nonnull aError) { - EMGroup *aGroup = [EMGroup groupWithId:groupId]; [weakSelf wrapperCallBack:result channelName:aChannelName error:aError - object:[aGroup toJson]]; + object:nil]; }]; } @@ -202,4 +213,51 @@ - (void)bindDeviceToken:(NSDictionary *)param } +- (void)enablePush:(NSDictionary *)param + channelName:(NSString *)aChannelName + result:(FlutterResult)result { + __weak typeof(self) weakSelf = self; + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + EMError *error = [EMClient.sharedClient.pushManager enableOfflinePush]; + dispatch_async(dispatch_get_main_queue(), ^{ + [weakSelf wrapperCallBack:result + channelName:aChannelName + error:error + object:nil]; + }); + }); +} + +- (void)disablePush:(NSDictionary *)param + channelName:(NSString *)aChannelName + result:(FlutterResult)result { + int startTime = [param[@"start"] intValue]; + int endTime = [param[@"end"] intValue]; + __weak typeof(self) weakSelf = self; + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + EMError *error = [EMClient.sharedClient.pushManager disableOfflinePushStart:startTime end:endTime]; + dispatch_async(dispatch_get_main_queue(), ^{ + [weakSelf wrapperCallBack:result + channelName:aChannelName + error:error + object:nil]; + }); + }); +} + +- (void)getNoPushGroups:(NSDictionary *)param + channelName:(NSString *)aChannelName + result:(FlutterResult)result { + __weak typeof(self) weakSelf = self; + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + NSArray* groups = [EMClient.sharedClient.pushManager noPushGroups]; + dispatch_async(dispatch_get_main_queue(), ^{ + [weakSelf wrapperCallBack:result + channelName:aChannelName + error:nil + object:groups]; + }); + }); +} + @end diff --git a/ios/Classes/EMSDKMethod.h b/ios/Classes/EMSDKMethod.h index ed8e64e2..33c158e8 100644 --- a/ios/Classes/EMSDKMethod.h +++ b/ios/Classes/EMSDKMethod.h @@ -209,12 +209,17 @@ static NSString *const EMMethodKeyOnGroupChanged = @"onGroupChanged"; static NSString *const EMMethodKeyGetImPushConfig = @"getImPushConfig"; static NSString *const EMMethodKeyGetImPushConfigFromServer = @"getImPushConfigFromServer"; static NSString *const EMMethodKeyUpdatePushNickname = @"updatePushNickname"; +static NSString *const EMMethodKeyBindDeviceToken = @"updateAPNsPushToken"; +static NSString *const EMMethodKeyEnablePush = @"enableOfflinePush"; +static NSString *const EMMethodKeyDisablePush = @"disableOfflinePush"; +static NSString *const EMMethodKeyGetNoPushGroups = @"getNoPushGroups"; + static NSString *const EMMethodKeyImPushNoDisturb = @"imPushNoDisturb"; static NSString *const EMMethodKeyUpdateImPushStyle = @"updateImPushStyle"; static NSString *const EMMethodKeyUpdateGroupPushService = @"updateGroupPushService"; static NSString *const EMMethodKeyGetNoDisturbGroups = @"getNoDisturbGroups"; -static NSString *const EMMethodKeyBindDeviceToken = @"updateAPNsPushToken"; + #pragma mark - EMUserInfoManagerWrapper diff --git a/lib/src/em_chat_manager.dart b/lib/src/em_chat_manager.dart index 206e3956..3ef12916 100644 --- a/lib/src/em_chat_manager.dart +++ b/lib/src/em_chat_manager.dart @@ -4,7 +4,6 @@ import 'package:flutter/services.dart'; import 'tools/em_extension.dart'; import '../im_flutter_sdk.dart'; import 'internal/chat_method_keys.dart'; -import 'tools/em_message_callback_manager.dart'; class EMChatManager { static const _channelPrefix = 'com.chat.im'; diff --git a/lib/src/em_push_manager.dart b/lib/src/em_push_manager.dart index 1e5e48fa..ec2d93dd 100644 --- a/lib/src/em_push_manager.dart +++ b/lib/src/em_push_manager.dart @@ -5,6 +5,14 @@ import 'internal/chat_method_keys.dart'; import 'models/em_error.dart'; import 'models/em_push_configs.dart'; +enum DisplayStyle { + /// 显示 ”您有一条新消息“ + Simple, + + /// 显示推送内容详情 + Summary, +} + class EMPushManager { static const _channelPrefix = 'com.chat.im'; static const MethodChannel _channel = const MethodChannel( @@ -20,6 +28,7 @@ class EMPushManager { } } + /// 从服务器获取 `EMPushConfigs` Future getPushConfigsFromServer() async { Map result = await _channel.invokeMethod(ChatMethodKeys.getImPushConfigFromServer); @@ -32,6 +41,62 @@ class EMPushManager { } } + /// 开启离线推送 + Future enableOfflinePush() async { + Map result = await _channel.invokeMethod(ChatMethodKeys.enableOfflinePush); + try { + EMError.hasErrorFromResult(result); + } on EMError catch (e) { + throw e; + } + } + + /// 关闭离线推送 + /// [start]: 开始时间 + /// [to]: 结束时间 + /// 如果需要设置24小时免打扰,可以设置start:0, to:24 + Future disableOfflinePush({ + required int start, + required int to, + }) async { + Map req = {'start': start, 'end': to}; + Map result = + await _channel.invokeMethod(ChatMethodKeys.disableOfflinePush, req); + try { + EMError.hasErrorFromResult(result); + } on EMError catch (e) { + throw e; + } + } + + /// 设置群组不接收推送 + /// [groupIds] 群组ids + /// [enablePush] 是否接收离线推送 + Future updatePushServiceForGroup({ + required List groupIds, + required bool enablePush, + }) async { + Map req = {'noPush': !enablePush, 'group_ids': groupIds}; + Map result = + await _channel.invokeMethod(ChatMethodKeys.updateGroupPushService, req); + try { + EMError.hasErrorFromResult(result); + } on EMError catch (e) { + throw e; + } + } + + /// 从本地获取不接收推送的群组 + /// 如果需要从服务器获取,需要调用{@link #getPushConfigsFromServer}后再调用本方法 + Future?> getNoPushGroupsFromCache() async { + Map result = await _channel.invokeMethod(ChatMethodKeys.getNoPushGroups); + List list = []; + if (result.containsKey(ChatMethodKeys.getNoPushGroups)) { + list = result[ChatMethodKeys.getNoPushGroups]?.cast(); + } + return list; + } + /// 更新当前用户的[nickname],这样离线消息推送的时候可以显示用户昵称而不是id,需要登录环信服务器成功后调用才生效 Future updatePushNickname(String nickname) async { Map req = {'nickname': nickname}; @@ -44,6 +109,18 @@ class EMPushManager { } } + /// 设置推送样式 + Future updatePushDisplayStyle(DisplayStyle displayStyle) async { + Map req = {'pushStyle': displayStyle == DisplayStyle.Simple ? 0 : 1}; + Map result = + await _channel.invokeMethod(ChatMethodKeys.updateImPushStyle, req); + try { + EMError.hasErrorFromResult(result); + } on EMError catch (e) { + throw e; + } + } + /// 上传华为推送token, 需要确保登录成功后再调用(可以是进入home页面后) Future updateHMSPushToken(String token) async { if (Platform.isAndroid) { diff --git a/lib/src/internal/chat_method_keys.dart b/lib/src/internal/chat_method_keys.dart index 89d9668e..6dc0096d 100644 --- a/lib/src/internal/chat_method_keys.dart +++ b/lib/src/internal/chat_method_keys.dart @@ -215,6 +215,9 @@ class ChatMethodKeys { static const String updateHMSPushToken = 'updateHMSPushToken'; static const String updateFCMPushToken = 'updateFCMPushToken'; static const String updateAPNsPushToken = 'updateAPNsPushToken'; + static const String enableOfflinePush = 'enableOfflinePush'; + static const String disableOfflinePush = 'disableOfflinePush'; + static const String getNoPushGroups = 'getNoPushGroups'; /// ImPushConfig static const String imPushNoDisturb = 'imPushNoDisturb'; diff --git a/lib/src/models/em_chat_enums.dart b/lib/src/models/em_chat_enums.dart index 0cc680ed..1354281b 100644 --- a/lib/src/models/em_chat_enums.dart +++ b/lib/src/models/em_chat_enums.dart @@ -17,6 +17,7 @@ enum EMConversationType { ChatRoom, // 聊天室消息 } +@Deprecated('Switch to using EMPushManager#DisplayStyle instead') enum EMPushStyle { Simple, Summary, diff --git a/lib/src/models/em_message.dart b/lib/src/models/em_message.dart index 70411105..db9d223d 100644 --- a/lib/src/models/em_message.dart +++ b/lib/src/models/em_message.dart @@ -1,11 +1,9 @@ import 'dart:math'; -import '../tools/em_log.dart'; - -import '../tools/em_message_callback_manager.dart'; +import 'package:flutter/services.dart'; +import '../internal/chat_method_keys.dart'; import '../tools/em_extension.dart'; import '../../im_flutter_sdk.dart'; -import '../internal/em_message_state_handle.dart'; // 消息类型 enum EMMessageChatType { @@ -68,30 +66,58 @@ abstract class EMMessageStatusListener { void onStatusChanged() {} } -class EMMessage { - EMMessage._private() { - _tmpKey = localTime.toString(); +class MessageCallBackManager { + static const _channelPrefix = 'com.chat.im'; + static const MethodChannel _emMessageChannel = + const MethodChannel('$_channelPrefix/chat_message', JSONMethodCodec()); + Map cacheMessageMap = {}; + static MessageCallBackManager? _instance; + static MessageCallBackManager get getInstance => + _instance = _instance ?? MessageCallBackManager._internal(); + MessageCallBackManager._internal() { + _emMessageChannel.setMethodCallHandler((MethodCall call) async { + Map argMap = call.arguments; + int? localTime = argMap['localTime']; + EMMessage? msg = cacheMessageMap[localTime.toString()]; + if (msg == null) { + return null; + } + if (call.method == ChatMethodKeys.onMessageProgressUpdate) { + return msg._onMessageProgressChanged(argMap); + } else if (call.method == ChatMethodKeys.onMessageError) { + return msg._onMessageError(argMap); + } else if (call.method == ChatMethodKeys.onMessageSuccess) { + return msg._onMessageSuccess(argMap); + } else if (call.method == ChatMethodKeys.onMessageReadAck) { + return msg._onMessageReadAck(argMap); + } else if (call.method == ChatMethodKeys.onMessageDeliveryAck) { + return msg._onMessageDeliveryAck(argMap); + } else if (call.method == ChatMethodKeys.onMessageStatusChanged) { + return msg._onMessageStatusChanged(argMap); + } + return null; + }); + } + + addMessage(EMMessage message) { + cacheMessageMap[message.localTime.toString()] = message; + } + + removeMessage(EMMessage message) { + if (cacheMessageMap.containsKey(message.localTime.toString())) { + cacheMessageMap.remove(message.localTime.toString()); + } } +} - late EMMessageStateHandle _handle; +class EMMessage { + EMMessage._private(); /// 构造接收的消息 EMMessage.createReceiveMessage({ required this.body, this.direction = EMMessageDirection.RECEIVE, - }) { - _tmpKey = localTime.toString(); - _handle = EMMessageStateHandle( - _tmpKey, - onMessageDeliveryAck: _onMessageDeliveryAck, - onMessageError: _onMessageError, - onMessageProgressChanged: _onMessageProgressChanged, - onMessageReadAck: _onMessageReadAck, - onMessageSuccess: _onMessageSuccess, - onMessageStatusChanged: _onMessageStatusChanged, - ); - MessageCallBackManager.getInstance.addMessage(_tmpKey, _handle); - } + }); /// 构造发送的消息 EMMessage.createSendMessage({ @@ -100,74 +126,70 @@ class EMMessage { this.to, this.hasRead = true, }) : this.from = EMClient.getInstance.currentUsername, - this.conversationId = to { - _tmpKey = localTime.toString(); - _handle = EMMessageStateHandle( - _tmpKey, - onMessageDeliveryAck: _onMessageDeliveryAck, - onMessageError: _onMessageError, - onMessageProgressChanged: _onMessageProgressChanged, - onMessageReadAck: _onMessageReadAck, - onMessageSuccess: _onMessageSuccess, - onMessageStatusChanged: _onMessageStatusChanged, - ); - MessageCallBackManager.getInstance.addMessage(_tmpKey, _handle); - } + this.conversationId = to; void dispose() { - MessageCallBackManager.getInstance.removeMessage(_tmpKey); - // listener = null; + MessageCallBackManager.getInstance.removeMessage(this); } - void _onMessageError(Map map) { - EMLog.v('发送失败 -- ' + map.toString()); + Future? _onMessageError(Map map) { EMMessage msg = EMMessage.fromJson(map['message']); this._msgId = msg.msgId; this.status = msg.status; this.body = msg.body; - listener?.onError(EMError.fromJson(map['error'])); + if (listener != null) { + listener!.onError(EMError.fromJson(map['error'])); + } return null; } - void _onMessageProgressChanged(Map map) { - EMLog.v( - '发送 -- ' + ' msg_id: ' + this.msgId! + ' ' + map['progress'].toString(), - ); - int progress = map['progress']; - listener?.onProgress(progress); + Future? _onMessageProgressChanged(Map map) { + if (this.listener != null) { + int progress = map['progress']; + listener!.onProgress(progress); + } return null; } - void _onMessageSuccess(Map map) { + Future? _onMessageSuccess(Map map) { EMMessage msg = EMMessage.fromJson(map['message']); this._msgId = msg.msgId; this.status = msg.status; this.body = msg.body; - listener?.onSuccess(); - EMLog.v('发送成功 -- ' + this.toString()); + if (listener != null) { + listener!.onSuccess(); + } + return null; } - void _onMessageReadAck(Map map) { - EMLog.v('消息已读 -- ' + ' msg_id: ' + this.msgId!); + Future? _onMessageReadAck(Map map) { EMMessage msg = EMMessage.fromJson(map); this.hasReadAck = msg.hasReadAck; - listener?.onReadAck(); + if (listener != null) { + listener!.onReadAck(); + } return null; } - void _onMessageDeliveryAck(Map map) { + Future? _onMessageDeliveryAck(Map map) { EMMessage msg = EMMessage.fromJson(map); this.hasDeliverAck = msg.hasDeliverAck; - listener?.onDeliveryAck(); + + if (listener != null) { + listener!.onDeliveryAck(); + } return null; } - void _onMessageStatusChanged(Map map) { + Future? _onMessageStatusChanged(Map map) { EMMessage msg = EMMessage.fromJson(map); this.status = msg.status; - listener?.onStatusChanged(); + + if (listener != null) { + listener!.onStatusChanged(); + } return null; } @@ -279,10 +301,13 @@ class EMMessage { void setMessageListener(EMMessageStatusListener? listener) { this.listener = listener; + if (listener != null) { + MessageCallBackManager.getInstance.addMessage(this); + } else { + MessageCallBackManager.getInstance.removeMessage(this); + } } - late String _tmpKey; - /// 消息id String? _msgId, msgLocalId = DateTime.now().millisecondsSinceEpoch.toString() + diff --git a/lib/src/models/em_push_configs.dart b/lib/src/models/em_push_configs.dart index 7bc66a65..a4f55257 100644 --- a/lib/src/models/em_push_configs.dart +++ b/lib/src/models/em_push_configs.dart @@ -4,17 +4,24 @@ import '../internal/chat_method_keys.dart'; import '../tools/em_extension.dart'; import 'em_chat_enums.dart'; import 'em_error.dart'; +import '../em_push_manager.dart'; class EMPushConfigs { EMPushConfigs._private(); + DisplayStyle? _displayStyle; + @Deprecated("Switch to using DisplayStyle instead") EMPushStyle? _pushStyle; bool? _noDisturb; int? _noDisturbStartHour; int? _noDisturbEndHour; List? _noDisturbGroups = []; + @Deprecated("Switch to using DisplayStyle instead") EMPushStyle? get pushStyle => _pushStyle; + + DisplayStyle? get displayStyle => _displayStyle; + bool? get noDisturb => _noDisturb; int? get noDisturbStartHour => _noDisturbStartHour; int? get noDisturbEndHour => _noDisturbEndHour; @@ -22,8 +29,8 @@ class EMPushConfigs { factory EMPushConfigs.fromJson(Map map) { return EMPushConfigs._private() - .._pushStyle = - map['pushStyle'] == 0 ? EMPushStyle.Simple : EMPushStyle.Summary + .._displayStyle = + map['pushStyle'] == 0 ? DisplayStyle.Simple : DisplayStyle.Summary .._noDisturb = map.boolValue('noDisturb') .._noDisturbStartHour = map['noDisturbStartHour'] .._noDisturbEndHour = map['noDisturbEndHour']; @@ -31,7 +38,7 @@ class EMPushConfigs { Map toJson() { Map data = Map(); - data['pushStyle'] = _pushStyle == EMPushStyle.Simple; + data['pushStyle'] = _displayStyle == DisplayStyle.Simple; data['noDisturb'] = _noDisturb; data['noDisturbStartHour'] = _noDisturbStartHour; data['noDisturbEndHour'] = _noDisturbEndHour; @@ -44,7 +51,8 @@ extension EMPushConfigsExtension on EMPushConfigs { static const MethodChannel _channel = const MethodChannel('com.chat.im/chat_push_manager', JSONMethodCodec()); - /// 设置是否免打扰[isNoDisturb], [startTime], [endTime] + @Deprecated( + "Switch to using EMPushManager#enableOfflinePush and EMPushManager#disableOfflinePush instead") Future setNoDisturb( bool isNoDisturb, [ int startTime = 0, @@ -72,7 +80,7 @@ extension EMPushConfigsExtension on EMPushConfigs { } } - /// 设置消息推送显示样式[pushStyle] + @Deprecated("Switch to using EMPushManager#updatePushDisplayStyle instead") Future setPushStyle(EMPushStyle pushStyle) async { Map req = {'pushStyle': pushStyle == EMPushStyle.Simple ? 0 : 1}; Map result = @@ -84,7 +92,7 @@ extension EMPushConfigsExtension on EMPushConfigs { } } - /// 通过群id[groupId]设置群组是否免打扰[isNoDisturb] + @Deprecated("Switch to using EMPushManager#updatePushServiceForGroup instead") Future setGroupToDisturb( String groupId, bool isNoDisturb, @@ -99,7 +107,7 @@ extension EMPushConfigsExtension on EMPushConfigs { } } - /// 获取免打扰群组列表 + @Deprecated("Switch to using EMPushManager#getNoPushGroups instead") Future?> noDisturbGroupsFromServer() async { Map result = await _channel.invokeMethod(ChatMethodKeys.getNoDisturbGroups); try { diff --git a/lib/src/models/em_userInfo.dart b/lib/src/models/em_userInfo.dart index bc956df6..a6eda39a 100644 --- a/lib/src/models/em_userInfo.dart +++ b/lib/src/models/em_userInfo.dart @@ -11,7 +11,7 @@ enum EMUserInfoType { } class EMUserInfo { - EMUserInfo(String aUserId); + EMUserInfo(this.userId); EMUserInfo._private({ required this.userId, @@ -98,7 +98,7 @@ class EMUserInfo { return data; } - String userId = ''; + final String userId; String? nickName; String? avatarUrl; String? mail; @@ -107,5 +107,5 @@ class EMUserInfo { String? sign; String? birth; String? ext; - int expireTime = DateTime.now().millisecondsSinceEpoch; + final int expireTime = DateTime.now().millisecondsSinceEpoch; } diff --git a/lib/src/tools/em_extension.dart b/lib/src/tools/em_extension.dart index 25d631d8..54684545 100644 --- a/lib/src/tools/em_extension.dart +++ b/lib/src/tools/em_extension.dart @@ -1,6 +1,8 @@ // 思考: 是否要把所有格式转换的部分都放到这个extension中? import '../models/em_group_shared_file.dart'; +Type typeOf() => T; + extension MapExtension on Map { bool boolValue(String key) { if (!containsKey(key)) { @@ -35,13 +37,13 @@ extension MapExtension on Map { List? listValue(String key) { if (this.containsKey(key)) { List obj = this[key]; - if (T is String) { + if (typeOf().toString() == "String") { List strList = []; for (var item in obj) { strList.add(item); } return strList as List; - } else if (T is EMGroupSharedFile) { + } else if (typeOf().toString() == "EMGroupSharedFile") { List fileList = []; for (var item in obj) { var file = EMGroupSharedFile.fromJson(item); @@ -49,9 +51,8 @@ extension MapExtension on Map { } return fileList as List; } - } else { - return null; } + return null; } } diff --git a/pubspec.yaml b/pubspec.yaml index cb7bf69d..3f95d509 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: im_flutter_sdk description: Easemob IM flutter SDK. -version: 3.8.3+7 +version: 3.8.3+9 homepage: http://www.easemob.com/product/im environment: