Compare commits

..

9 Commits

Author SHA1 Message Date
Brett
8b4b21e18d feat: https://github.com/openimsdk/openim-sdk-core/releases/tag/v3.5.0-rc.1 2023-12-29 20:19:29 +08:00
Brett
2814122ba4 Merge branch 'main' of https://github.com/OpenIMSDK/Open-IM-SDK-Flutter 2023-12-13 16:28:33 +08:00
Brett
2e94254192 feat: Add the log upload function of SDK. 2023-12-13 16:28:25 +08:00
Brett
a9573dbc63 Update README.md 2023-11-22 11:30:48 +08:00
Brett
92dd3adad5 Correct homepage and other information. 2023-11-17 17:01:22 +08:00
Brett
ebae12f11d fix: 'Fix return value type of 'getFriendsInfo'. 2023-11-17 16:45:22 +08:00
Brett
0dec034a55 Adjust some fields and APIs. 2023-11-17 15:05:27 +08:00
Brett
2b3f062e5c chore: Adjust the default values of some properties. 2023-11-16 18:28:39 +08:00
Brett
a4b52f5895 fix: Fixed some parameter errors. 2023-11-16 16:20:54 +08:00
33 changed files with 331 additions and 133 deletions

View File

@@ -1,3 +1,11 @@
## 3.5.0-rc.1
- [Bug fixes and performance enhancements.](https://github.com/openimsdk/openim-sdk-core/releases/tag/v3.5.0-rc.1)
## 3.4.0+1
- Adjust some fields and APIs.
## 3.4.0
- [Bug fixes and performance enhancements.](https://github.com/openimsdk/openim-sdk-core/releases/tag/v3.4.0)

View File

@@ -36,7 +36,6 @@ final success = await OpenIM.iMManager.initSDK(
apiAddr: "", // SDK's API interface address.
wsAddr: "", // SDK's WebSocket address.
dataDir: "", // Data storage path. For example, you can use getApplicationDocumentsDirectory() to get a path.
objectStorage: 'cos', // Image server (default is 'cos').
logLevel: 6, // Log level (default value is 6).
listener: OnConnectListener(
onConnectSuccess: () {

View File

@@ -52,5 +52,5 @@ android {
dependencies {
// 本地依赖现将aar复制到libs/io/openim/core-sdk/0.0.1/ 下命名core-sdk-0.0.1.aar
// implementation 'io.openim:core-sdk:0.0.1@aar'
implementation 'io.openim:core-sdk:3.4.0@aar'
implementation 'io.openim:core-sdk:3.5.0-rc1@aar'
}

View File

@@ -0,0 +1,26 @@
package io.openim.flutter_openim_sdk.listener;
import android.util.ArrayMap;
import java.util.Map;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import io.openim.flutter_openim_sdk.util.CommonUtil;
import open_im_sdk_callback.UploadLogProgress;
public class OnUploadLogsListener implements UploadLogProgress {
final private MethodChannel.Result result;
public OnUploadLogsListener(MethodChannel.Result result, MethodCall call) {
this.result = result;
}
@Override
public void onProgress(long current, long size) {
final Map<String, Object> values = new ArrayMap<>();
values.put("current", current);
values.put("size", size);
CommonUtil.emitEvent("uploadLogsListener", "onProgress", values);
}
}

View File

@@ -196,4 +196,21 @@ public class ConversationManager extends BaseManager {
value(methodCall, "operationID")
);
}
public void searchConversation(MethodCall methodCall, MethodChannel.Result result) {
Open_im_sdk.searchConversation(
new OnBaseListener(result, methodCall),
value(methodCall, "operationID"),
value(methodCall, "name")
);
}
public void setConversationEx(MethodCall methodCall, MethodChannel.Result result) {
Open_im_sdk.setConversationEx(
new OnBaseListener(result, methodCall),
value(methodCall, "operationID"),
value(methodCall, "conversationID"),
value(methodCall, "ex")
);
}
}

View File

@@ -64,7 +64,8 @@ public class FriendshipManager extends BaseManager {
Open_im_sdk.addBlack(
new OnBaseListener(result, methodCall),
value(methodCall, "operationID"),
value(methodCall, "userID")
value(methodCall, "userID"),
value(methodCall, "ex")
);
}
@@ -122,4 +123,13 @@ public class FriendshipManager extends BaseManager {
jsonValue(methodCall, "searchParam")
);
}
public void setFriendsEx(MethodCall methodCall, MethodChannel.Result result) {
Open_im_sdk.setFriendsEx(
new OnBaseListener(result, methodCall),
value(methodCall, "operationID"),
jsonValue(methodCall, "friendIDs"),
value(methodCall, "ex")
);
}
}

View File

@@ -92,7 +92,8 @@ public class GroupManager extends BaseManager {
value(methodCall, "operationID"),
value(methodCall, "groupID"),
value(methodCall, "reason"),
value(methodCall, "joinSource")
value(methodCall, "joinSource"),
value(methodCall, "ex")
);
}

View File

@@ -6,6 +6,7 @@ import io.openim.flutter_openim_sdk.FlutterOpenimSdkPlugin;
import io.openim.flutter_openim_sdk.listener.OnBaseListener;
import io.openim.flutter_openim_sdk.listener.OnConnListener;
import io.openim.flutter_openim_sdk.listener.OnUploadFileListener;
import io.openim.flutter_openim_sdk.listener.OnUploadLogsListener;
import io.openim.flutter_openim_sdk.util.CommonUtil;
import open_im_sdk.Open_im_sdk;
@@ -62,6 +63,13 @@ public class IMManager extends BaseManager {
);
}
public void uploadLogs(MethodCall methodCall, MethodChannel.Result result) {
Open_im_sdk.uploadLogs(
new OnBaseListener(result, methodCall),
value(methodCall, "operationID"),
new OnUploadLogsListener(result, methodCall)
);
}
public void setAppBackgroundStatus(MethodCall methodCall, MethodChannel.Result result) {
Open_im_sdk.setAppBackgroundStatus(

View File

@@ -69,4 +69,11 @@ public class UserManager extends BaseManager {
jsonValue(methodCall, "userIDs"),
value(methodCall, "groupID"));
}
public void setSelfInfoEx(MethodCall methodCall, MethodChannel.Result result) {
Open_im_sdk.setSelfInfoEx(
new OnBaseListener(result, methodCall),
value(methodCall, "operationID"),
jsonValue(methodCall));
}
}

View File

@@ -30,6 +30,6 @@ subprojects {
project.evaluationDependsOn(':app')
}
task clean(type: Delete) {
tasks.register("clean", Delete) {
delete rootProject.buildDir
}

29
example/ios/Podfile.lock Normal file
View File

@@ -0,0 +1,29 @@
PODS:
- Flutter (1.0.0)
- flutter_openim_sdk (0.0.1):
- Flutter
- OpenIMSDKCore (= 3.4.0)
- OpenIMSDKCore (3.4.0)
DEPENDENCIES:
- Flutter (from `Flutter`)
- flutter_openim_sdk (from `.symlinks/plugins/flutter_openim_sdk/ios`)
SPEC REPOS:
trunk:
- OpenIMSDKCore
EXTERNAL SOURCES:
Flutter:
:path: Flutter
flutter_openim_sdk:
:path: ".symlinks/plugins/flutter_openim_sdk/ios"
SPEC CHECKSUMS:
Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854
flutter_openim_sdk: 54d1c836ff60ebb5b99d246521ef0cb1d834fb13
OpenIMSDKCore: 47e0e830afe0d2dd905ad3dda255e6a6d26a555c
PODFILE CHECKSUM: 7368163408c647b7eb699d0d788ba6718e18fb8d
COCOAPODS: 1.13.0

View File

@@ -5,10 +5,10 @@ packages:
dependency: transitive
description:
name: async
sha256: bfe67ef28df125b7dddcea62755991f807aa39a2492a23e1550161692950bbe0
sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c"
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.10.0"
version: "2.11.0"
boolean_selector:
dependency: transitive
description:
@@ -21,10 +21,10 @@ packages:
dependency: transitive
description:
name: characters
sha256: e6a326c8af69605aec75ed6c187d06b349707a27fbff8222ca9cc2cff167975c
sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605"
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.2.1"
version: "1.3.0"
clock:
dependency: transitive
description:
@@ -37,10 +37,10 @@ packages:
dependency: transitive
description:
name: collection
sha256: cfc915e6923fe5ce6e153b0723c753045de46de1b4d63771530504004a45fae0
sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.17.0"
version: "1.18.0"
cupertino_icons:
dependency: "direct main"
description:
@@ -68,52 +68,44 @@ packages:
path: ".."
relative: true
source: path
version: "3.4.0"
version: "3.5.0-rc.1"
flutter_test:
dependency: "direct dev"
description: flutter
source: sdk
version: "0.0.0"
js:
dependency: transitive
description:
name: js
sha256: "5528c2f391ededb7775ec1daa69e65a2d61276f7552de2b5f7b8d34ee9fd4ab7"
url: "https://pub.flutter-io.cn"
source: hosted
version: "0.6.5"
matcher:
dependency: transitive
description:
name: matcher
sha256: "16db949ceee371e9b99d22f88fa3a73c4e59fd0afed0bd25fc336eb76c198b72"
sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e"
url: "https://pub.flutter-io.cn"
source: hosted
version: "0.12.13"
version: "0.12.16"
material_color_utilities:
dependency: transitive
description:
name: material_color_utilities
sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724
sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41"
url: "https://pub.flutter-io.cn"
source: hosted
version: "0.2.0"
version: "0.5.0"
meta:
dependency: transitive
description:
name: meta
sha256: "6c268b42ed578a53088d834796959e4a1814b5e9e164f147f580a386e5decf42"
sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.8.0"
version: "1.10.0"
path:
dependency: transitive
description:
name: path
sha256: db9d4f58c908a4ba5953fcee2ae317c94889433e5024c27ce74a37f94267945b
sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917"
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.8.2"
version: "1.8.3"
sky_engine:
dependency: transitive
description: flutter
@@ -123,26 +115,26 @@ packages:
dependency: transitive
description:
name: source_span
sha256: dd904f795d4b4f3b870833847c461801f6750a9fa8e61ea5ac53f9422b31f250
sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c"
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.9.1"
version: "1.10.0"
stack_trace:
dependency: transitive
description:
name: stack_trace
sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5
sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b"
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.11.0"
version: "1.11.1"
stream_channel:
dependency: transitive
description:
name: stream_channel
sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8"
sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.1.1"
version: "2.1.2"
string_scanner:
dependency: transitive
description:
@@ -163,10 +155,10 @@ packages:
dependency: transitive
description:
name: test_api
sha256: ad540f65f92caa91bf21dfc8ffb8c589d6e4dc0c2267818b4cc2792857706206
sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b"
url: "https://pub.flutter-io.cn"
source: hosted
version: "0.4.16"
version: "0.6.1"
vector_math:
dependency: transitive
description:
@@ -175,6 +167,14 @@ packages:
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.1.4"
web:
dependency: transitive
description:
name: web
sha256: afe077240a270dcfd2aafe77602b4113645af95d0ad31128cc02bce5ac5d5152
url: "https://pub.flutter-io.cn"
source: hosted
version: "0.3.0"
sdks:
dart: ">=2.18.0 <3.0.0"
dart: ">=3.2.0-194.0.dev <4.0.0"
flutter: ">=1.20.0"

38
ios/.gitignore vendored
View File

@@ -1,38 +0,0 @@
.idea/
.vagrant/
.sconsign.dblite
.svn/
.DS_Store
*.swp
profile
DerivedData/
build/
GeneratedPluginRegistrant.h
GeneratedPluginRegistrant.m
.generated/
*.pbxuser
*.mode1v3
*.mode2v3
*.perspectivev3
!default.pbxuser
!default.mode1v3
!default.mode2v3
!default.perspectivev3
xcuserdata
*.moved-aside
*.pyc
*sync/
Icon?
.tags*
/Flutter/Generated.xcconfig
/Flutter/ephemeral/
/Flutter/flutter_export_environment.sh

View File

View File

@@ -27,6 +27,8 @@ public class ConversationManager: BaseServiceManager {
self["setGlobalRecvMessageOpt"] = setGlobalRecvMessageOpt
self["setConversationBurnDuration"] = setConversationBurnDuration
self["hideAllConversations"] = hideAllConversations
self["searchConversation"] = searchConversation
self["setConversationEx"] = setConversationEx
}
func setConversationListener(methodCall: FlutterMethodCall, result: @escaping FlutterResult){
@@ -117,6 +119,14 @@ public class ConversationManager: BaseServiceManager {
func hideAllConversations(methodCall: FlutterMethodCall, result: @escaping FlutterResult){
Open_im_sdkHideAllConversations(BaseCallback(result: result), methodCall[string: "operationID"])
}
func searchConversation(methodCall: FlutterMethodCall, result: @escaping FlutterResult){
Open_im_sdkSearchConversation(BaseCallback(result: result), methodCall[string: "operationID"], methodCall[string: "name"])
}
func setConversationEx(methodCall: FlutterMethodCall, result: @escaping FlutterResult){
Open_im_sdkSetConversationEx(BaseCallback(result: result), methodCall[string: "operationID"], methodCall[string: "conversationID"], methodCall[jsonString: "ex"])
}
}

View File

@@ -20,6 +20,7 @@ public class FriendshipManager: BaseServiceManager {
self["acceptFriendApplication"] = acceptFriendApplication
self["refuseFriendApplication"] = refuseFriendApplication
self["searchFriends"] = searchFriends
self["setFriendsEx"] = setFriendsEx
}
func setFriendListener(methodCall: FlutterMethodCall, result: @escaping FlutterResult){
@@ -52,7 +53,7 @@ public class FriendshipManager: BaseServiceManager {
}
func addBlacklist(methodCall: FlutterMethodCall, result: @escaping FlutterResult){
Open_im_sdkAddBlack(BaseCallback(result: result), methodCall[string: "operationID"], methodCall[string: "userID"])
Open_im_sdkAddBlack(BaseCallback(result: result), methodCall[string: "operationID"], methodCall[string: "userID"], methodCall[string: "ex"])
}
func getBlacklist(methodCall: FlutterMethodCall, result: @escaping FlutterResult){
@@ -82,6 +83,10 @@ public class FriendshipManager: BaseServiceManager {
func searchFriends(methodCall: FlutterMethodCall, result: @escaping FlutterResult){
Open_im_sdkSearchFriends(BaseCallback(result: result), methodCall[string: "operationID"], methodCall[jsonString: "searchParam"])
}
func setFriendsEx(methodCall: FlutterMethodCall, result: @escaping FlutterResult){
Open_im_sdkSetFriendsEx(BaseCallback(result: result), methodCall[string: "operationID"], methodCall[jsonString: "friendIDs"], methodCall[string: "ex"])
}
}
public class FriendshipListener: NSObject, Open_im_sdk_callbackOnFriendshipListenerProtocol {

View File

@@ -78,7 +78,8 @@ public class GroupManager: BaseServiceManager {
}
func joinGroup(methodCall: FlutterMethodCall, result: @escaping FlutterResult){
Open_im_sdkJoinGroup(BaseCallback(result: result), methodCall[string: "operationID"], methodCall[string: "groupID"], methodCall[string: "reason"], methodCall[int32: "joinSource"])
Open_im_sdkJoinGroup(BaseCallback(result: result), methodCall[string: "operationID"], methodCall[string: "groupID"], methodCall[string:
"reason"], methodCall[int32: "joinSource"], methodCall[jsonString: "ex"])
}
func quitGroup(methodCall: FlutterMethodCall, result: @escaping FlutterResult){

View File

@@ -13,6 +13,7 @@ public class IMMananger: BaseServiceManager {
self["logout"] = logout
self["getLoginStatus"] = getLoginStatus
self["uploadFile"] = uploadFile
self["uploadLogs"] = uploadLogs
self["updateFcmToken"] = updateFcmToken
self["setAppBackgroundStatus"] = setAppBackgroundStatus
self["networkStatusChanged"] = networkStatusChanged
@@ -83,6 +84,10 @@ public class IMMananger: BaseServiceManager {
func uploadFile(methodCall: FlutterMethodCall, result: @escaping FlutterResult) {
Open_im_sdkUploadFile(BaseCallback(result: result), methodCall[string: "operationID"], methodCall.toJsonString(), UploadFileListener(channel: self.channel,id: methodCall[string: "id"]))
}
func uploadLogs(methodCall: FlutterMethodCall, result: @escaping FlutterResult) {
Open_im_sdkUploadLogs(BaseCallback(result: result), methodCall[string: "operationID"], UploadLogsListener(channel: self.channel))
}
func updateFcmToken(methodCall: FlutterMethodCall, result: @escaping FlutterResult) {
Open_im_sdkUpdateFcmToken(BaseCallback(result: result), methodCall[string: "operationID"], methodCall[string: "fcmToken"], methodCall[int64:
@@ -126,11 +131,28 @@ public class ConnListener: NSObject, Open_im_sdk_callbackOnConnListenerProtocol
}
}
public class UploadLogsListener: NSObject, Open_im_sdk_callbackUploadLogProgressProtocol {
private let channel:FlutterMethodChannel
init(channel:FlutterMethodChannel) {
self.channel = channel
}
public func onProgress(_ current: Int64, size: Int64) {
var values: [String: Any] = [:]
values["current"] = current
values["size"] = size
CommonUtil.emitEvent(channel: channel, method: "uploadLogsListener", type: "onProgress", errCode: nil, errMsg: nil, data: values)
}
}
public class UploadFileListener: NSObject, Open_im_sdk_callbackUploadFileCallbackProtocol {
private let channel:FlutterMethodChannel
private let id: String
init(channel:FlutterMethodChannel, id: String) {
self.channel = channel
self.id = id

View File

@@ -14,6 +14,7 @@ public class UserManager: BaseServiceManager {
self["getSubscribeUsersStatus"] = getSubscribeUsersStatus
self["getUserStatus"] = getUserStatus
self["getUsersInfoWithCache"] = getUsersInfoWithCache
self["setSelfInfoEx"] = setSelfInfoEx
}
func setUserListener(methodCall: FlutterMethodCall, result: @escaping FlutterResult){
@@ -53,6 +54,10 @@ public class UserManager: BaseServiceManager {
Open_im_sdkGetUsersInfoWithCache(BaseCallback(result: result), methodCall[string: "operationID"], methodCall[jsonString: "userIDs"],
methodCall[string: "groupID"])
}
func setSelfInfoEx(methodCall: FlutterMethodCall, result: @escaping FlutterResult){
Open_im_sdkSetSelfInfoEx(BaseCallback(result: result), methodCall[string: "operationID"], methodCall.toJsonString())
}
}
public class UserListener: NSObject, Open_im_sdk_callbackOnUserListenerProtocol {

View File

@@ -17,7 +17,7 @@ A new Flutter project.
s.dependency 'Flutter'
s.platform = :ios, '11.0'
s.dependency 'OpenIMSDKCore','3.4.0'
s.dependency 'OpenIMSDKCore','3.5.0-rc1'
s.static_framework = true
# s.vendored_frameworks = 'Framework/*.framework'
# Flutter.framework does not contain a i386 slice.

BIN
lib/.DS_Store vendored

Binary file not shown.

View File

@@ -15,4 +15,5 @@ class ListenerType {
static const messageKvInfoListener = "messageKvInfoListener";
static const listenerForService = "listenerForService";
static const uploadFileListener = "uploadFileListener";
static const uploadLogsListener = "uploadLogsListener";
}

View File

@@ -1,3 +1,12 @@
class OnUploadLogsListener {
Function(int current, int size)? onUploadProgress;
OnUploadLogsListener({this.onUploadProgress});
void onProgress(int current, int size) {
onUploadProgress?.call(current, size);
}
}
class OnUploadFileListener {
Function(String id, int size, String url, int type)? onComplete;
Function(String id, String partHash, String fileHash)? onHashPartComplete;

View File

@@ -341,6 +341,37 @@ class ConversationManager {
"operationID": Utils.checkOperationID(operationID),
}));
/// search Conversations
Future<List<ConversationInfo>> searchConversations(
String name, {
String? operationID,
}) {
return _channel
.invokeMethod(
'searchConversations',
_buildParam({
'name': name,
"operationID": Utils.checkOperationID(operationID),
}))
.then((value) => Utils.toList(value, (map) => ConversationInfo.fromJson(map)));
}
Future<List<ConversationInfo>> setConversationEx(
String conversationID, {
String? ex,
String? operationID,
}) {
return _channel
.invokeMethod(
'setConversationEx',
_buildParam({
'conversationID': conversationID,
'ex': ex,
"operationID": Utils.checkOperationID(operationID),
}))
.then((value) => Utils.toList(value, (map) => ConversationInfo.fromJson(map)));
}
/// Custom Sort for Conversation List
List<ConversationInfo> simpleSort(List<ConversationInfo> list) => list
..sort((a, b) {

View File

@@ -15,7 +15,7 @@ class FriendshipManager {
/// Query Friend Information
/// [userIDList] List of user IDs
Future<List<FriendInfo>> getFriendsInfo({
Future<List<FullUserInfo>> getFriendsInfo({
required List<String> userIDList,
String? operationID,
}) =>
@@ -26,7 +26,7 @@ class FriendshipManager {
"userIDList": userIDList,
"operationID": Utils.checkOperationID(operationID),
}))
.then((value) => Utils.toList(value, (v) => FriendInfo.fromJson(v)));
.then((value) => Utils.toList(value, (v) => FullUserInfo.fromJson(v)));
/// Send a Friend Request, the other party needs to accept the request to become friends.
/// [userID] User ID to be invited
@@ -63,13 +63,13 @@ class FriendshipManager {
.then((value) => Utils.toList(value, (v) => FriendApplicationInfo.fromJson(v)));
/// Get Friend List, including friends who have been put into the blacklist
Future<List<FriendInfo>> getFriendList({String? operationID}) => _channel
Future<List<FullUserInfo>> getFriendList({String? operationID}) => _channel
.invokeMethod(
'getFriendList',
_buildParam({
"operationID": Utils.checkOperationID(operationID),
}))
.then((value) => Utils.toList(value, (v) => FriendInfo.fromJson(v)));
.then((value) => Utils.toList(value, (v) => FullUserInfo.fromJson(v)));
/// Get Friend List, including friends who have been put into the blacklist (returns a map)
Future<List<dynamic>> getFriendListMap({String? operationID}) => _channel
@@ -100,12 +100,14 @@ class FriendshipManager {
/// [userID] Friend's ID to be added to the blacklist
Future<dynamic> addBlacklist({
required String userID,
String? ex,
String? operationID,
}) =>
_channel.invokeMethod(
'addBlacklist',
_buildParam({
"userID": userID,
"ex": ex,
"operationID": Utils.checkOperationID(operationID),
}));
@@ -217,6 +219,20 @@ class FriendshipManager {
}))
.then((value) => Utils.toList(value, (map) => SearchFriendsInfo.fromJson(map)));
Future<String?> setFriendsEx(
List<String> friendIDs, {
String? ex,
String? operationID,
}) {
return _channel.invokeMethod(
'setFriendsEx',
_buildParam({
"friendIDs": friendIDs,
"ex": ex,
"operationID": Utils.checkOperationID(operationID),
}));
}
static Map _buildParam(Map param) {
param["ManagerName"] = "friendshipManager";
return param;

View File

@@ -207,20 +207,15 @@ class GroupManager {
/// Apply to join a group, requiring approval from an administrator or the group.
/// [joinSource] 2: Invited, 3: Searched, 4: Using a QR code
Future<dynamic> joinGroup({
required String groupID,
String? reason,
String? operationID,
int joinSource = 3,
}) =>
_channel.invokeMethod(
'joinGroup',
_buildParam({
'groupID': groupID,
'reason': reason,
'joinSource': joinSource,
'operationID': Utils.checkOperationID(operationID),
}));
Future<dynamic> joinGroup({required String groupID, String? reason, String? operationID, int joinSource = 3, String? ex}) => _channel.invokeMethod(
'joinGroup',
_buildParam({
'groupID': groupID,
'reason': reason,
'joinSource': joinSource,
'ex': ex,
'operationID': Utils.checkOperationID(operationID),
}));
/// Exit a group
Future<dynamic> quitGroup({
@@ -566,8 +561,6 @@ class GroupManager {
/// Modify the GroupMemberInfo ex field
Future<dynamic> setGroupMemberInfo({
required String groupID,
required String userID,
required GroupMembersInfo groupMembersInfo,
String? operationID,
}) =>

View File

@@ -16,6 +16,8 @@ class IMManager {
late OnConnectListener _connectListener;
OnListenerForService? _listenerForService;
OnUploadFileListener? _uploadFileListener;
OnUploadLogsListener? _uploadLogsListener;
late String userID;
late UserInfo userInfo;
bool isLogined = false;
@@ -273,6 +275,15 @@ class IMManager {
_listenerForService?.recvNewMessage(msg);
break;
}
} else if (call.method == ListenerType.uploadLogsListener) {
String type = call.arguments['type'];
dynamic data = call.arguments['data'];
switch (type) {
case 'onProgress':
int size = data['size'];
int current = data['current'];
_uploadLogsListener?.onProgress(current, size);
}
} else if (call.method == ListenerType.uploadFileListener) {
String type = call.arguments['type'];
dynamic data = call.arguments['data'];
@@ -511,6 +522,21 @@ class IMManager {
'operationID': Utils.checkOperationID(operationID),
}));
/// 上传日志
/// [uploadlogParams] system_type、ex
Future uploadLogs({
String? operationID,
}) =>
_channel.invokeMethod(
'uploadLogs',
_buildParam({
'operationID': Utils.checkOperationID(operationID),
}));
void setUploadLogsListener(OnUploadLogsListener listener) {
_uploadLogsListener = listener;
}
void setUploadFileListener(OnUploadFileListener listener) {
_uploadFileListener = listener;
}

View File

@@ -15,7 +15,7 @@ class UserManager {
/// Get user information
/// [userIDList] List of user IDs
Future<List<UserInfo>> getUsersInfo({
Future<List<FullUserInfo>> getUsersInfo({
required List<String> userIDList,
String? operationID,
}) =>
@@ -26,7 +26,7 @@ class UserManager {
'userIDList': userIDList,
'operationID': Utils.checkOperationID(operationID),
}))
.then((value) => Utils.toList(value, (v) => UserInfo.fromJson(v)));
.then((value) => Utils.toList(value, (v) => FullUserInfo.fromJson(v)));
/// Get information of the currently logged-in user
Future<UserInfo> getSelfUserInfo({
@@ -115,7 +115,7 @@ class UserManager {
.then((value) => Utils.toList(value, (map) => UserStatusInfo.fromJson(map)));
}
Future<List<UserInfo>> getUsersInfoWithCache(
Future<List<FullUserInfo>> getUsersInfoWithCache(
List<String> userIDs, {
String? groupID,
String? operationID,
@@ -128,7 +128,19 @@ class UserManager {
'groupID': groupID,
'operationID': Utils.checkOperationID(operationID),
}))
.then((value) => Utils.toList(value, (map) => UserInfo.fromJson(map)));
.then((value) => Utils.toList(value, (map) => FullUserInfo.fromJson(map)));
}
Future<String?> setSelfUserInfoEx(
UserInfo userInfo, {
String? operationID,
}) {
return _channel.invokeMethod(
'setSelfUserInfoEx',
_buildParam({
...userInfo.toJson(),
'operationID': Utils.checkOperationID(operationID),
}));
}
static Map _buildParam(Map param) {

View File

@@ -25,7 +25,7 @@ class ConversationInfo {
int? recvMsgOpt;
// Number of unread messages in the conversation
int? unreadCount;
int unreadCount = 0;
// Latest message in the conversation
Message? latestMsg;
@@ -72,7 +72,7 @@ class ConversationInfo {
this.showName,
this.faceURL,
this.recvMsgOpt,
this.unreadCount,
this.unreadCount = 0,
this.latestMsg,
this.latestMsgSendTime,
this.draftText,
@@ -87,8 +87,7 @@ class ConversationInfo {
this.msgDestructTime,
});
ConversationInfo.fromJson(Map<String, dynamic> json)
: conversationID = json['conversationID'] {
ConversationInfo.fromJson(Map<String, dynamic> json) : conversationID = json['conversationID'] {
conversationType = json['conversationType'];
userID = json['userID'];
groupID = json['groupID'];
@@ -146,19 +145,14 @@ class ConversationInfo {
bool get isSingleChat => conversationType == ConversationType.single;
// Check if it's a group chat
bool get isGroupChat =>
conversationType == ConversationType.group ||
conversationType == ConversationType.superGroup;
bool get isGroupChat => conversationType == ConversationType.group || conversationType == ConversationType.superGroup;
// Check if it's a valid conversation (not in a group if isNotInGroup is true)
bool get isValid => isSingleChat || (isGroupChat && !isNotInGroup!);
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is ConversationInfo &&
runtimeType == other.runtimeType &&
conversationID == other.conversationID;
identical(this, other) || other is ConversationInfo && runtimeType == other.runtimeType && conversationID == other.conversationID;
@override
int get hashCode => conversationID.hashCode;

View File

@@ -920,37 +920,27 @@ class MessageEntity {
/// Group message read information
class GroupHasReadInfo {
/// List of user IDs that have read the message
List<String>? hasReadUserIDList;
/// Total number of messages read
/// Total number of reads
int? hasReadCount;
/// Number of group members when this message was sent
int? groupMemberCount;
int? unreadCount;
GroupHasReadInfo.fromJson(Map<String, dynamic> json) {
if (json['hasReadUserIDList'] == null) {
hasReadUserIDList = <String>[];
} else {
hasReadUserIDList = (json['hasReadUserIDList'] as List).cast<String>();
}
hasReadCount = json['hasReadCount'] ?? 0;
groupMemberCount = json['groupMemberCount'] ?? 0;
unreadCount = json['unreadCount'] ?? 0;
}
Map<String, dynamic> toJson() {
final data = Map<String, dynamic>();
data['hasReadUserIDList'] = this.hasReadUserIDList;
data['hasReadCount'] = this.hasReadCount;
data['groupMemberCount'] = this.groupMemberCount;
data['unreadCount'] = this.unreadCount;
return data;
}
}
/// Message read receipt information
class ReadReceiptInfo {
/// Sender's ID
/// Sender ID
String? userID;
/// Group ID

View File

@@ -98,6 +98,22 @@ class FullUserInfo {
return data;
}
String get userID {
return publicInfo?.userID ?? friendInfo?.userID ?? blackInfo?.userID ?? '';
}
String get nickname {
return publicInfo?.nickname ?? friendInfo?.nickname ?? blackInfo?.nickname ?? '';
}
String get faceURL {
return publicInfo?.faceURL ?? friendInfo?.faceURL ?? blackInfo?.faceURL ?? '';
}
String get showName {
return friendInfo?.nickname ?? nickname;
}
}
class PublicUserInfo {

View File

@@ -2,7 +2,7 @@ import 'package:flutter/services.dart';
import 'package:flutter_openim_sdk/flutter_openim_sdk.dart';
class OpenIM {
static const version = '3.4.0';
static const version = '3.5.0-rc.1';
static const _channel = const MethodChannel('flutter_openim_sdk');

View File

@@ -1,8 +1,8 @@
name: flutter_openim_sdk
description: An instant messaging plug-in that supports Android and IOS. And the server is also all open source.
version: 3.4.0
homepage: https://www.rentsoft.cn
repository: https://github.com/OpenIMSDK/Open-IM-SDK-Flutter
version: 3.5.0-rc.1
homepage: https://www.openim.io
repository: https://github.com/openimsdk/open-im-sdk-flutter
environment:
sdk: ">=2.12.0 <3.0.0"