feat(mobile-next): 迁移 Android 一对一语音通话薄适配与入口

复用官方 OpenIMLive 信令与房间,换票改走账号服务 /api/rtc_token;入口仅音频,占线/超时/重复回调与销毁释放由公司层防护。

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: multica-agent <github@multica.ai>
This commit is contained in:
编码工程师
2026-08-20 07:58:24 +08:00
co-authored by Cursor multica-agent
parent 2a817e77d8
commit 3832e080c4
19 changed files with 597 additions and 81 deletions
+7 -7
View File
@@ -22,6 +22,7 @@ import 'package:wechat_assets_picker/wechat_assets_picker.dart';
import 'package:wechat_camera_picker/wechat_camera_picker.dart';
import 'package:openim_live/openim_live.dart';
import '../../company/feature_flags.dart';
import '../../core/controller/app_controller.dart';
import '../../core/controller/im_controller.dart';
import '../../core/im_callback.dart';
@@ -1622,18 +1623,17 @@ class ChatLogic extends SuperController {
}
void call() {
if (!FeatureFlags.livekitCall || !isSingleChat) return;
if (rtcIsBusy) {
IMViews.showToast(StrRes.callingBusy);
return;
}
IMViews.openIMCallSheet(nickname.value, (index) {
imLogic.call(
callObj: CallObj.single,
callType: index == 0 ? CallType.audio : CallType.video,
inviteeUserIDList: [if (isSingleChat) userID!],
);
});
imLogic.call(
callObj: CallObj.single,
callType: CallType.audio,
inviteeUserIDList: [userID!],
);
}
void onScrollToTop() {
+2 -2
View File
@@ -225,7 +225,7 @@ class ChatPage extends StatelessWidget {
onCloseMultiModel: logic.exit,
onClickMoreBtn: logic.chatSetup,
onClickCallBtn: logic.call,
showCallBtn: FeatureFlags.livekitCall,
showCallBtn: FeatureFlags.livekitCall && logic.isSingleChat,
),
body: SafeArea(
child: WaterMarkBgView(
@@ -244,7 +244,7 @@ class ChatPage extends StatelessWidget {
toolbox: ChatToolBox(
onTapAlbum: logic.onTapAlbum,
onTapCamera: logic.onTapCamera,
onTapCall: logic.call,
onTapCall: FeatureFlags.livekitCall && logic.isSingleChat ? logic.call : null,
onTapCard: logic.onTapCarte,
onTapFile: logic.onTapFile,
onTapLocation: logic.onTapLocation,
@@ -6,6 +6,7 @@ import 'package:extended_image/extended_image.dart';
import 'package:flutter/material.dart';
import 'package:flutter_openim_sdk/flutter_openim_sdk.dart';
import 'package:get/get.dart';
import 'package:openim/company/feature_flags.dart';
import 'package:openim/routes/app_navigator.dart';
import 'package:openim_common/openim_common.dart';
import 'package:sprintf/sprintf.dart';
@@ -324,13 +325,12 @@ class UserProfilePanelLogic extends GetxController {
}
void toCall() {
IMViews.openIMCallSheet(userInfo.value.showName, (index) {
imLogic.call(
callObj: CallObj.single,
callType: index == 0 ? CallType.audio : CallType.video,
inviteeUserIDList: [userInfo.value.userID!],
);
});
if (!FeatureFlags.livekitCall) return;
imLogic.call(
callObj: CallObj.single,
callType: CallType.audio,
inviteeUserIDList: [userInfo.value.userID!],
);
}
void copyID() {
@@ -7,6 +7,7 @@ import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import 'package:openim_common/openim_common.dart';
import '../../../company/feature_flags.dart';
import 'user_profile _panel_logic.dart';
class UserProfilePanelPage extends StatelessWidget {
@@ -234,12 +235,14 @@ class UserProfilePanelPage extends StatelessWidget {
height: 108.h,
child: Row(
children: [
Expanded(
child: ImageTextButton.call(
onTap: logic.toCall,
if (FeatureFlags.livekitCall) ...[
Expanded(
child: ImageTextButton.call(
onTap: logic.toCall,
),
),
),
11.horizontalSpace,
11.horizontalSpace,
],
Expanded(
child: ImageTextButton.message(
onTap: logic.toChat,