1.聊天接口接入

2.聊天和成员底部弹窗刷新优化
This commit is contained in:
fuenmao 2024-11-28 11:22:50 +08:00
parent 3a1dde6e19
commit 06a9eb44d0
5 changed files with 217 additions and 136 deletions

View File

@ -0,0 +1,23 @@
import 'package:json_annotation/json_annotation.dart';
part 'meeting_room_msg.g.dart';
@JsonSerializable()
class MeetingRoomMsg extends Object{
String uid;
String userName;
String message;
// 01
int source;
MeetingRoomMsg(this.uid,this.userName,this.message,this.source);
factory MeetingRoomMsg.fromJson(Map<String, dynamic> srcJson) => _$MeetingRoomMsgFromJson(srcJson);
}

View File

@ -90,7 +90,7 @@ class HomePageState extends State<HomePage> with AutomaticKeepAliveClientMixin {
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
Text( Text(
state.meetingRooms[index].roomName, state.meetingRooms.value[index].roomName,
style: TextStyle( style: TextStyle(
fontSize: 14.sp, fontSize: 14.sp,
color: ColorUtil.Color_89_88_88, color: ColorUtil.Color_89_88_88,
@ -105,7 +105,7 @@ class HomePageState extends State<HomePage> with AutomaticKeepAliveClientMixin {
height: 16.h, height: 16.h,
), ),
Text( Text(
'${state.meetingRooms[index].onlineUserCount}', '${state.meetingRooms.value[index].onlineUserCount}',
style: TextStyle( style: TextStyle(
fontSize: 12.sp, fontSize: 12.sp,
color: ColorUtil.Color_177_177_177, color: ColorUtil.Color_177_177_177,
@ -122,7 +122,7 @@ class HomePageState extends State<HomePage> with AutomaticKeepAliveClientMixin {
Row( Row(
children: [ children: [
Text( Text(
state.meetingRooms[index].roomNum, state.meetingRooms.value[index].roomNum,
style: TextStyle( style: TextStyle(
fontSize: 12.sp, fontSize: 12.sp,
color: ColorUtil.Color_177_177_177, color: ColorUtil.Color_177_177_177,
@ -136,7 +136,7 @@ class HomePageState extends State<HomePage> with AutomaticKeepAliveClientMixin {
height: 16.h, height: 16.h,
), ),
onTap: (){ onTap: (){
Clipboard.setData(ClipboardData(text: state.meetingRooms[index].roomNum)); Clipboard.setData(ClipboardData(text: state.meetingRooms.value[index].roomNum));
ToastUtils.showSuccess("复制成功"); ToastUtils.showSuccess("复制成功");
}, },
) )
@ -169,7 +169,7 @@ class HomePageState extends State<HomePage> with AutomaticKeepAliveClientMixin {
), ),
), ),
onTap: (){ onTap: (){
Get.toNamed(Routes.meetingMainPage, arguments: {"roomNumber": state.meetingRooms[index].roomNum}); Get.toNamed(Routes.meetingMainPage, arguments: {"roomNumber": state.meetingRooms.value[index].roomNum});
}, },
) )
], ],
@ -178,7 +178,7 @@ class HomePageState extends State<HomePage> with AutomaticKeepAliveClientMixin {
), ),
); );
}, },
itemCount: state.meetingRooms.length, itemCount: state.meetingRooms.value.length,
), ),
), ),
), ),

View File

@ -1,6 +1,5 @@
import 'dart:async'; import 'dart:async';
import 'dart:convert'; import 'dart:convert';
import 'package:agora_rtc_engine/agora_rtc_engine.dart'; import 'package:agora_rtc_engine/agora_rtc_engine.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
@ -10,6 +9,7 @@ import '../../common/config/request_config.dart';
import '../../common/mixins/request_tool_mixin.dart'; import '../../common/mixins/request_tool_mixin.dart';
import '../../common/models/common/base_structure_result.dart'; import '../../common/models/common/base_structure_result.dart';
import '../../common/models/meeting_room_info.dart'; import '../../common/models/meeting_room_info.dart';
import '../../common/models/meeting_room_msg.dart';
import '../../common/models/meeting_room_user.dart'; import '../../common/models/meeting_room_user.dart';
import '../../utils/permission_handler.dart'; import '../../utils/permission_handler.dart';
import '../../utils/toast_utils.dart'; import '../../utils/toast_utils.dart';
@ -33,6 +33,7 @@ class MeetingMainLogic extends GetxController with RequestToolMixin{
void onClose() { void onClose() {
super.onClose(); super.onClose();
state.memberNameSearchController.dispose(); state.memberNameSearchController.dispose();
state.sendMsgController.dispose();
stopTime(); stopTime();
leaveMeetingToRtc(); leaveMeetingToRtc();
leaveMeetingToSocket(); leaveMeetingToSocket();
@ -154,7 +155,7 @@ class MeetingMainLogic extends GetxController with RequestToolMixin{
/// ///
state.hubConnection.value?.on("UserJoined", (user){ state.hubConnection.value?.on("UserJoined", (user){
var jsonStr = json.encode(user); var jsonStr = const Utf8Decoder().convert(json.encode(user).runes.toList());
var listDynamic = jsonDecode(jsonStr); var listDynamic = jsonDecode(jsonStr);
List<MeetingRoomUser> meetingRoomUsers = (listDynamic as List<dynamic>).map((e) => MeetingRoomUser.fromJson((e as Map<String,dynamic>))).toList(); List<MeetingRoomUser> meetingRoomUsers = (listDynamic as List<dynamic>).map((e) => MeetingRoomUser.fromJson((e as Map<String,dynamic>))).toList();
state.cacheUsers.value.addAll(meetingRoomUsers); state.cacheUsers.value.addAll(meetingRoomUsers);
@ -164,7 +165,7 @@ class MeetingMainLogic extends GetxController with RequestToolMixin{
/// ///
state.hubConnection.value?.on("UserLeave", (uid){ state.hubConnection.value?.on("UserLeave", (uid){
var jsonStr = json.encode(uid); var jsonStr = const Utf8Decoder().convert(json.encode(uid).runes.toList());
List listDynamic = jsonDecode(jsonStr); List listDynamic = jsonDecode(jsonStr);
for(String uidStr in listDynamic){ for(String uidStr in listDynamic){
for(var j = 0; j < state.cacheUsers.value.length; j++){ for(var j = 0; j < state.cacheUsers.value.length; j++){
@ -179,7 +180,7 @@ class MeetingMainLogic extends GetxController with RequestToolMixin{
/// /- /// /-
state.hubConnection.value?.on("ManagerRefresh", (e){ state.hubConnection.value?.on("ManagerRefresh", (e){
var jsonStr = json.encode(e?[0]); var jsonStr = const Utf8Decoder().convert(json.encode(e?[0]).runes.toList());
var listDynamic = jsonDecode(jsonStr); var listDynamic = jsonDecode(jsonStr);
MeetingRoomUser meetingRoomUser = MeetingRoomUser.fromJson(listDynamic); MeetingRoomUser meetingRoomUser = MeetingRoomUser.fromJson(listDynamic);
if(meetingRoomUser.isRoomManager == true){ if(meetingRoomUser.isRoomManager == true){
@ -205,7 +206,20 @@ class MeetingMainLogic extends GetxController with RequestToolMixin{
state.isSpeak.value = false; state.isSpeak.value = false;
setEnableLocalAudio(false); setEnableLocalAudio(false);
} }
update();
});
///
state.hubConnection.value?.on("ReceiveMessage", (e){
var jsonStr = const Utf8Decoder().convert(json.encode(e).runes.toList());
List list = json.decode(jsonStr);
MeetingRoomMsg meetingRoomMsg = MeetingRoomMsg(list[0],list[1],list[2],0);
state.meetingRoomMsgs.value.add(meetingRoomMsg);
update();
Future.delayed(const Duration(milliseconds: 100), () {
state.chatController.jumpTo(state.chatController.position.maxScrollExtent);
});
debugPrint("wgs输出===Socket-会议室接收消息:$jsonStr");
}); });
} }
@ -220,6 +234,20 @@ class MeetingMainLogic extends GetxController with RequestToolMixin{
await state.hubConnection.value?.invoke("levelChannel", args: [state.roomNumber.value]); await state.hubConnection.value?.invoke("levelChannel", args: [state.roomNumber.value]);
} }
///
Future<void> sendMsg(String msg) async {
MeetingRoomMsg meetingRoomMsg = MeetingRoomMsg(
UserStore.to.userInfoEntity.value!.uid,
UserStore.to.userInfoEntity.value!.userName,
msg,1);
state.meetingRoomMsgs.value.add(meetingRoomMsg);
update();
Future.delayed(const Duration(milliseconds: 100), () {
state.chatController.jumpTo(state.chatController.position.maxScrollExtent);
});
await state.hubConnection.value?.invoke("sendChannelMsg", args: [state.roomNumber.value, msg]);
}
/// --------------------------SDK相关 /// --------------------------SDK相关
/// SDK /// SDK
Future<void> initRtc() async { Future<void> initRtc() async {

View File

@ -7,6 +7,7 @@ import 'package:get/get_rx/src/rx_types/rx_types.dart';
import 'package:signalr_core/signalr_core.dart'; import 'package:signalr_core/signalr_core.dart';
import '../../common/models/meeting_room_info.dart'; import '../../common/models/meeting_room_info.dart';
import '../../common/models/meeting_room_msg.dart';
import '../../common/models/meeting_room_user.dart'; import '../../common/models/meeting_room_user.dart';
class MeetingMainState { class MeetingMainState {
@ -16,6 +17,7 @@ class MeetingMainState {
} }
late TextEditingController memberNameSearchController = TextEditingController(); late TextEditingController memberNameSearchController = TextEditingController();
late TextEditingController sendMsgController = TextEditingController();
/// ///
late RxBool isShowMeetingInfoFloatingLayer = false.obs; late RxBool isShowMeetingInfoFloatingLayer = false.obs;
@ -52,6 +54,9 @@ class MeetingMainState {
/// ///
late RxBool isSpeak = false.obs; late RxBool isSpeak = false.obs;
///
late RxList<MeetingRoomMsg> meetingRoomMsgs = RxList([]);
/// signalR /// signalR
late RxString serviceUrl = "http://192.168.2.9:5192/session-manage".obs; late RxString serviceUrl = "http://192.168.2.9:5192/session-manage".obs;
late Rx<HubConnection?> hubConnection = Rx(null); late Rx<HubConnection?> hubConnection = Rx(null);

View File

@ -148,7 +148,7 @@ class MeetingMainPage extends StatelessWidget {
// //
Visibility( Visibility(
visible: true, visible: true,
child: MeetingMainVoiceComponent(users: state.cacheUsers) child: MeetingMainVoiceComponent(users: state.cacheUsers.value)
), ),
// //
@ -324,7 +324,7 @@ class MeetingMainPage extends StatelessWidget {
onTap: () { onTap: () {
Get.bottomSheet( Get.bottomSheet(
isScrollControlled: true, isScrollControlled: true,
Obx(() => queryMemberFloatingLayer(context)), queryMemberFloatingLayer(context),
); );
}, },
), ),
@ -880,17 +880,19 @@ class MeetingMainPage extends StatelessWidget {
margin: margin:
const EdgeInsets.only(top: 18, left: 16, right: 16, bottom: 16), const EdgeInsets.only(top: 18, left: 16, right: 16, bottom: 16),
child: Text( child: Text(
'会议中(${state.users.length}', '会议中(${state.users.value.length}',
style: TextStyle( style: TextStyle(
fontSize: 14.sp, fontSize: 14.sp,
fontWeight: FontWeight.w500, fontWeight: FontWeight.w500,
color: ColorUtil.Color_85_117_242), color: ColorUtil.Color_85_117_242),
), ),
), ),
Expanded( Expanded(
child: ScrollConfiguration( child: ScrollConfiguration(
behavior: CusBehavior(), behavior: CusBehavior(),
child: ListView.builder( child: GetBuilder<MeetingMainLogic>(builder: (controll){
return ListView.builder(
itemBuilder: (context, index) { itemBuilder: (context, index) {
return Container( return Container(
width: double.infinity, width: double.infinity,
@ -914,9 +916,9 @@ class MeetingMainPage extends StatelessWidget {
height: 36.h, height: 36.h,
alignment: Alignment.center, alignment: Alignment.center,
child: Text( child: Text(
state.users[index].userName.length > 3 state.users.value[index].userName.length > 3
? state.users[index].userName.substring(state.users[index].userName.length - 2,state.users[index].userName.length) ? state.users.value[index].userName.substring(state.users.value[index].userName.length - 2,state.users.value[index].userName.length)
: state.users[index].userName, : state.users.value[index].userName,
style: TextStyle( style: TextStyle(
fontSize: 12.sp, fontSize: 12.sp,
color: ColorUtil.Color_244_244_244 color: ColorUtil.Color_244_244_244
@ -924,7 +926,7 @@ class MeetingMainPage extends StatelessWidget {
), ),
), ),
Text( Text(
state.users[index].userName, state.users.value[index].userName,
style: TextStyle( style: TextStyle(
fontSize: 14.sp, fontSize: 14.sp,
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
@ -932,7 +934,7 @@ class MeetingMainPage extends StatelessWidget {
), ),
SizedBox(width: 8.w), SizedBox(width: 8.w),
Visibility( Visibility(
visible: state.users[index].roleId == "1" || state.users[index].roleId == "3" ? true : false, visible: state.users.value[index].roleId == "1" || state.users.value[index].roleId == "3" ? true : false,
child: Text( child: Text(
'主持人', '主持人',
style: TextStyle( style: TextStyle(
@ -942,7 +944,7 @@ class MeetingMainPage extends StatelessWidget {
), ),
), ),
Visibility( Visibility(
visible: state.users[index].roleId == "2" && state.users[index].isRoomManager == true ? true : false, visible: state.users.value[index].roleId == "2" && state.users.value[index].isRoomManager == true ? true : false,
child: Text( child: Text(
'发言人', '发言人',
style: TextStyle( style: TextStyle(
@ -965,7 +967,7 @@ class MeetingMainPage extends StatelessWidget {
Container( Container(
margin: const EdgeInsets.only(left: 12), margin: const EdgeInsets.only(left: 12),
child: Image.asset( child: Image.asset(
state.users[index].enableMicr == true ? 'assets/images/meeting_main_microphone_default.png' : 'assets/images/meeting_main_microphone_close.png', state.users.value[index].enableMicr == true ? 'assets/images/meeting_main_microphone_default.png' : 'assets/images/meeting_main_microphone_close.png',
width: 17.w, width: 17.w,
height: 17.h, height: 17.h,
), ),
@ -973,7 +975,7 @@ class MeetingMainPage extends StatelessWidget {
Container( Container(
margin: const EdgeInsets.only(left: 12), margin: const EdgeInsets.only(left: 12),
child: Image.asset( child: Image.asset(
state.users[index].enableCamera == true ? 'assets/images/meeting_main_camera_default.png' : 'assets/images/meeting_main_camera_close.png', state.users.value[index].enableCamera == true ? 'assets/images/meeting_main_camera_default.png' : 'assets/images/meeting_main_camera_close.png',
width: 17.w, width: 17.w,
height: 17.h, height: 17.h,
), ),
@ -993,8 +995,9 @@ class MeetingMainPage extends StatelessWidget {
), ),
); );
}, },
itemCount: state.users.length, itemCount: state.users.value.length,
) );
})
), ),
) )
], ],
@ -1049,13 +1052,15 @@ class MeetingMainPage extends StatelessWidget {
Expanded( Expanded(
child: ScrollConfiguration( child: ScrollConfiguration(
behavior: CusBehavior(), behavior: CusBehavior(),
child: ListView.builder( child: GetBuilder<MeetingMainLogic>(builder: (controll){
return ListView.builder(
controller: state.chatController, controller: state.chatController,
itemBuilder: (context, index) { itemBuilder: (context, index) {
return index == 0 || index == 2 ? chartItemToOthers(index) : chartItemToOwn(index); return state.meetingRoomMsgs.value[index].source == 0 ? chartItemToOthers(index) : chartItemToOwn(index);
}, },
itemCount: 6, itemCount: state.meetingRoomMsgs.value.length,
) );
})
), ),
), ),
Container( Container(
@ -1070,17 +1075,27 @@ class MeetingMainPage extends StatelessWidget {
color: ColorUtil.Color_53_53_53, color: ColorUtil.Color_53_53_53,
), ),
child: TextField( child: TextField(
controller: state.sendMsgController,
style: TextStyle( style: TextStyle(
fontSize: 14.sp, fontSize: 14.sp,
color: ColorUtil.Color_235_235_235 color: ColorUtil.Color_235_235_235
), ),
decoration: InputDecoration( decoration: InputDecoration(
contentPadding: EdgeInsets.all(0), contentPadding: const EdgeInsets.all(0),
border: OutlineInputBorder(borderSide: BorderSide.none), border: const OutlineInputBorder(borderSide: BorderSide.none),
hintText: '请输入内容...', hintText: '请输入内容...',
hintStyle: TextStyle( hintStyle: TextStyle(
color: ColorUtil.Color_235_235_235, color: ColorUtil.Color_235_235_235,
fontSize: 14.sp)), fontSize: 14.sp)
),
onSubmitted: (value){
if(value.isNotEmpty){
logic.sendMsg(value);
state.sendMsgController.text = "";
}else{
ToastUtils.showError("请输入内容");
}
},
), ),
), ),
) )
@ -1102,15 +1117,20 @@ class MeetingMainPage extends StatelessWidget {
Container( Container(
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: BorderRadius.circular(99), borderRadius: BorderRadius.circular(99),
image: DecorationImage( color: ColorUtil.Color_85_117_242
fit: BoxFit.cover,
image: NetworkImage(
"https://ts4.cn.mm.bing.net/th?id=OIP-C.QDl_Z7HdQWX_XbVYgBLJLQAAAA&w=250&h=250&c=8&rs=1&qlt=90&o=6&pid=3.1&rm=2",
),
),
), ),
width: 50.w, width: 50.w,
height: 50.h, height: 50.h,
alignment: Alignment.center,
child: Text(
state.meetingRoomMsgs.value[index].userName.length > 3
? state.meetingRoomMsgs.value[index].userName.substring(state.meetingRoomMsgs.value[index].userName.length - 2,state.meetingRoomMsgs.value[index].userName.length)
: state.meetingRoomMsgs.value[index].userName,
style: TextStyle(
fontSize: 14.sp,
color: ColorUtil.Color_244_244_244
),
),
), ),
Expanded( Expanded(
child: Column( child: Column(
@ -1119,7 +1139,7 @@ class MeetingMainPage extends StatelessWidget {
Container( Container(
margin: const EdgeInsets.only(left: 6), margin: const EdgeInsets.only(left: 6),
child: Text( child: Text(
'晓晓', state.meetingRoomMsgs.value[index].userName,
style: TextStyle( style: TextStyle(
fontSize: 10.sp, fontSize: 10.sp,
color: ColorUtil.Color_202_202_202), color: ColorUtil.Color_202_202_202),
@ -1138,7 +1158,7 @@ class MeetingMainPage extends StatelessWidget {
color: ColorUtil.Color_53_53_53, color: ColorUtil.Color_53_53_53,
), ),
child: Text( child: Text(
'你好啊...............你好啊...............', state.meetingRoomMsgs.value[index].message,
style: TextStyle( style: TextStyle(
fontSize: 12.sp, fontSize: 12.sp,
color: ColorUtil.Color_235_235_235), color: ColorUtil.Color_235_235_235),
@ -1169,7 +1189,7 @@ class MeetingMainPage extends StatelessWidget {
Container( Container(
margin: const EdgeInsets.only(right: 6), margin: const EdgeInsets.only(right: 6),
child: Text( child: Text(
'晓晓', state.meetingRoomMsgs.value[index].userName,
style: TextStyle( style: TextStyle(
fontSize: 10.sp, fontSize: 10.sp,
color: ColorUtil.Color_202_202_202), color: ColorUtil.Color_202_202_202),
@ -1189,7 +1209,7 @@ class MeetingMainPage extends StatelessWidget {
color: ColorUtil.Color_85_117_242, color: ColorUtil.Color_85_117_242,
), ),
child: Text( child: Text(
'你好啊...............你好啊...............', state.meetingRoomMsgs.value[index].message,
style: TextStyle( style: TextStyle(
fontSize: 12.sp, fontSize: 12.sp,
color: ColorUtil.Color_235_235_235), color: ColorUtil.Color_235_235_235),
@ -1201,15 +1221,20 @@ class MeetingMainPage extends StatelessWidget {
Container( Container(
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: BorderRadius.circular(99), borderRadius: BorderRadius.circular(99),
image: DecorationImage( color: ColorUtil.Color_85_117_242
fit: BoxFit.cover,
image: NetworkImage(
"https://ts4.cn.mm.bing.net/th?id=OIP-C.QDl_Z7HdQWX_XbVYgBLJLQAAAA&w=250&h=250&c=8&rs=1&qlt=90&o=6&pid=3.1&rm=2",
),
),
), ),
width: 50.w, width: 50.w,
height: 50.h, height: 50.h,
alignment: Alignment.center,
child: Text(
state.meetingRoomMsgs.value[index].userName.length > 3
? state.meetingRoomMsgs.value[index].userName.substring(state.meetingRoomMsgs.value[index].userName.length - 2,state.meetingRoomMsgs.value[index].userName.length)
: state.meetingRoomMsgs.value[index].userName,
style: TextStyle(
fontSize: 14.sp,
color: ColorUtil.Color_244_244_244
),
),
) )
], ],
), ),