feat(mobile-next): 导入官方 openim-flutter-demo 固定基线 3.8.3-patch.3 并完成双构建
- 上游: github.com/OpenIMSDK/openim-flutter-demo tag 3.8.3-patch.3 commit b3dfdb1e8aaeaaf6f0793e10cadd20d5c184a31f - 并行目录 mobile-next/ 原样导入(含 LICENSE),不覆盖现网 mobile/ - 锁定 Flutter 3.24.5 / Dart 3.5.4 / JDK 17 / Gradle 7.6.3 / AGP 7.3.1 - 实测 Android debug 与 release 构建均成功(见 docs/mobile-next-baseline-import.md) - 本提交可单独回退:git revert 1db1229(重写前) Co-authored-by: multica-agent <github@multica.ai>
This commit is contained in:
@@ -0,0 +1,214 @@
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_openim_sdk/flutter_openim_sdk.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:openim_common/openim_common.dart';
|
||||
import 'package:permission_handler/permission_handler.dart';
|
||||
import 'package:openim_live/openim_live.dart';
|
||||
|
||||
import '../im_callback.dart';
|
||||
|
||||
class IMController extends GetxController with IMCallback, OpenIMLive {
|
||||
late Rx<UserFullInfo> userInfo;
|
||||
late String atAllTag;
|
||||
|
||||
@override
|
||||
void onClose() {
|
||||
super.close();
|
||||
onCloseLive();
|
||||
super.onClose();
|
||||
}
|
||||
|
||||
@override
|
||||
void onInit() async {
|
||||
super.onInit();
|
||||
onInitLive();
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) => initOpenIM());
|
||||
}
|
||||
|
||||
void initOpenIM() async {
|
||||
final initialized = await OpenIM.iMManager.initSDK(
|
||||
platformID: IMUtils.getPlatform(),
|
||||
apiAddr: Config.imApiUrl,
|
||||
wsAddr: Config.imWsUrl,
|
||||
dataDir: Config.cachePath,
|
||||
logLevel: Config.logLevel,
|
||||
logFilePath: Config.cachePath,
|
||||
listener: OnConnectListener(
|
||||
onConnecting: () {
|
||||
imSdkStatus(IMSdkStatus.connecting);
|
||||
},
|
||||
onConnectFailed: (code, error) {
|
||||
imSdkStatus(IMSdkStatus.connectionFailed);
|
||||
},
|
||||
onConnectSuccess: () {
|
||||
imSdkStatus(IMSdkStatus.connectionSucceeded);
|
||||
},
|
||||
onKickedOffline: kickedOffline,
|
||||
onUserTokenExpired: kickedOffline,
|
||||
onUserTokenInvalid: userTokenInvalid,
|
||||
),
|
||||
);
|
||||
|
||||
OpenIM.iMManager
|
||||
..setUploadLogsListener(OnUploadLogsListener(onUploadProgress: uploadLogsProgress))
|
||||
..userManager.setUserListener(OnUserListener(
|
||||
onSelfInfoUpdated: (u) {
|
||||
selfInfoUpdated(u);
|
||||
|
||||
userInfo.update((val) {
|
||||
val?.nickname = u.nickname;
|
||||
val?.faceURL = u.faceURL;
|
||||
|
||||
val?.remark = u.remark;
|
||||
val?.ex = u.ex;
|
||||
val?.globalRecvMsgOpt = u.globalRecvMsgOpt;
|
||||
});
|
||||
},
|
||||
onUserStatusChanged: userStausChanged))
|
||||
..messageManager.setAdvancedMsgListener(OnAdvancedMsgListener(
|
||||
onRecvC2CReadReceipt: recvC2CMessageReadReceipt,
|
||||
onRecvNewMessage: recvNewMessage,
|
||||
onNewRecvMessageRevoked: recvMessageRevoked,
|
||||
onRecvOfflineNewMessage: recvOfflineMessage,
|
||||
onRecvOnlineOnlyMessage: (msg) {
|
||||
if (msg.isCustomType) {
|
||||
final data = msg.customElem!.data;
|
||||
final map = jsonDecode(data!);
|
||||
final customType = map['customType'];
|
||||
if (customType == CustomMessageType.callingInvite ||
|
||||
customType == CustomMessageType.callingAccept ||
|
||||
customType == CustomMessageType.callingReject ||
|
||||
customType == CustomMessageType.callingCancel ||
|
||||
customType == CustomMessageType.callingHungup) {
|
||||
final signaling = SignalingInfo(invitation: InvitationInfo.fromJson(map['data']));
|
||||
signaling.userID = signaling.invitation?.inviterUserID;
|
||||
|
||||
switch (customType) {
|
||||
case CustomMessageType.callingInvite:
|
||||
receiveNewInvitation(signaling);
|
||||
break;
|
||||
case CustomMessageType.callingAccept:
|
||||
inviteeAccepted(signaling);
|
||||
break;
|
||||
case CustomMessageType.callingReject:
|
||||
inviteeRejected(signaling);
|
||||
break;
|
||||
case CustomMessageType.callingCancel:
|
||||
invitationCancelled(signaling);
|
||||
break;
|
||||
case CustomMessageType.callingHungup:
|
||||
beHangup(signaling);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
))
|
||||
..messageManager.setMsgSendProgressListener(OnMsgSendProgressListener(
|
||||
onProgress: progressCallback,
|
||||
))
|
||||
..messageManager.setCustomBusinessListener(OnCustomBusinessListener(
|
||||
onRecvCustomBusinessMessage: recvCustomBusinessMessage,
|
||||
))
|
||||
..friendshipManager.setFriendshipListener(OnFriendshipListener(
|
||||
onBlackAdded: blacklistAdded,
|
||||
onBlackDeleted: blacklistDeleted,
|
||||
onFriendApplicationAccepted: friendApplicationAccepted,
|
||||
onFriendApplicationAdded: friendApplicationAdded,
|
||||
onFriendApplicationDeleted: friendApplicationDeleted,
|
||||
onFriendApplicationRejected: friendApplicationRejected,
|
||||
onFriendInfoChanged: friendInfoChanged,
|
||||
onFriendAdded: friendAdded,
|
||||
onFriendDeleted: friendDeleted,
|
||||
))
|
||||
..conversationManager.setConversationListener(OnConversationListener(
|
||||
onConversationChanged: conversationChanged,
|
||||
onNewConversation: newConversation,
|
||||
onTotalUnreadMessageCountChanged: totalUnreadMsgCountChanged,
|
||||
onInputStatusChanged: inputStateChanged,
|
||||
onSyncServerFailed: (reInstall) {
|
||||
imSdkStatus(IMSdkStatus.syncFailed, reInstall: reInstall ?? false);
|
||||
},
|
||||
onSyncServerFinish: (reInstall) {
|
||||
imSdkStatus(IMSdkStatus.syncEnded, reInstall: reInstall ?? false);
|
||||
if (Platform.isAndroid) {
|
||||
Permissions.request([Permission.systemAlertWindow]);
|
||||
}
|
||||
},
|
||||
onSyncServerStart: (reInstall) {
|
||||
imSdkStatus(IMSdkStatus.syncStart, reInstall: reInstall ?? false);
|
||||
},
|
||||
onSyncServerProgress: (progress) {
|
||||
imSdkStatus(IMSdkStatus.syncProgress, progress: progress);
|
||||
}))
|
||||
..groupManager.setGroupListener(OnGroupListener(
|
||||
onGroupApplicationAccepted: groupApplicationAccepted,
|
||||
onGroupApplicationAdded: groupApplicationAdded,
|
||||
onGroupApplicationDeleted: groupApplicationDeleted,
|
||||
onGroupApplicationRejected: groupApplicationRejected,
|
||||
onGroupInfoChanged: groupInfoChanged,
|
||||
onGroupMemberAdded: groupMemberAdded,
|
||||
onGroupMemberDeleted: groupMemberDeleted,
|
||||
onGroupMemberInfoChanged: groupMemberInfoChanged,
|
||||
onJoinedGroupAdded: joinedGroupAdded,
|
||||
onJoinedGroupDeleted: joinedGroupDeleted,
|
||||
));
|
||||
|
||||
initializedSubject.sink.add(initialized);
|
||||
}
|
||||
|
||||
Future login(String userID, String token) async {
|
||||
try {
|
||||
var user = await OpenIM.iMManager.login(
|
||||
userID: userID,
|
||||
token: token,
|
||||
defaultValue: () async => UserInfo(userID: userID),
|
||||
);
|
||||
ApiService().setToken(token);
|
||||
userInfo = UserFullInfo.fromJson(user.toJson()).obs;
|
||||
_queryMyFullInfo();
|
||||
_queryAtAllTag();
|
||||
} catch (e, s) {
|
||||
Logger.print('e: $e s:$s');
|
||||
await _handleLoginRepeatError(e);
|
||||
|
||||
return Future.error(e, s);
|
||||
}
|
||||
}
|
||||
|
||||
Future logout() {
|
||||
return OpenIM.iMManager.logout();
|
||||
}
|
||||
|
||||
void _queryAtAllTag() async {
|
||||
atAllTag = OpenIM.iMManager.conversationManager.atAllTag;
|
||||
}
|
||||
|
||||
void _queryMyFullInfo() async {
|
||||
final data = await Apis.queryMyFullInfo();
|
||||
if (data is UserFullInfo) {
|
||||
userInfo.update((val) {
|
||||
val?.allowAddFriend = data.allowAddFriend;
|
||||
val?.allowBeep = data.allowBeep;
|
||||
val?.allowVibration = data.allowVibration;
|
||||
val?.nickname = data.nickname;
|
||||
val?.faceURL = data.faceURL;
|
||||
val?.phoneNumber = data.phoneNumber;
|
||||
val?.email = data.email;
|
||||
val?.birth = data.birth;
|
||||
val?.gender = data.gender;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
_handleLoginRepeatError(e) async {
|
||||
if (e is PlatformException && (e.code == "13002" || e.code == '1507')) {
|
||||
await logout();
|
||||
await DataSp.removeLoginCertificate();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user