本地预览悬浮窗

This commit is contained in:
fuenmao 2024-12-06 10:19:47 +08:00
parent 5d194ad054
commit 44c789e2f1
7 changed files with 717 additions and 562 deletions

View File

@ -2,11 +2,8 @@ import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:wgshare/main.dart';
import 'package:wgshare/utils/my_text.dart';
import 'package:wgshare/utils/utils.dart'; import 'package:wgshare/utils/utils.dart';
import '../../routes/app_routes.dart';
import '../../utils/color_util.dart'; import '../../utils/color_util.dart';
import 'login_logic.dart'; import 'login_logic.dart';

View File

@ -1,6 +1,7 @@
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/cupertino.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:signalr_core/signalr_core.dart'; import 'package:signalr_core/signalr_core.dart';
@ -33,6 +34,7 @@ class MeetingMainLogic extends GetxController with RequestToolMixin{
@override @override
void onClose() { void onClose() {
super.onClose(); super.onClose();
state.floating.value?.close();
state.memberNameSearchController.dispose(); state.memberNameSearchController.dispose();
state.sendMsgController.dispose(); state.sendMsgController.dispose();
stopTime(); stopTime();
@ -311,7 +313,7 @@ class MeetingMainLogic extends GetxController with RequestToolMixin{
doHttpSetMicr(); doHttpSetMicr();
}); });
/// ///
state.hubConnection.value?.on("OperMicr", (e){ state.hubConnection.value?.on("OperMicr", (e){
// var jsonStr = const Utf8Decoder().convert(json.encode(e?[0]).runes.toList()); // var jsonStr = const Utf8Decoder().convert(json.encode(e?[0]).runes.toList());
var jsonStr = json.encode(e?[0]); var jsonStr = json.encode(e?[0]);
@ -406,7 +408,7 @@ class MeetingMainLogic extends GetxController with RequestToolMixin{
}); });
/// ------------------------------------------------------------------------------ /// ------------------------------------------------------------------------------
/// ///
state.hubConnection.value?.on("OperCamera", (e){ state.hubConnection.value?.on("OperCamera", (e){
// var jsonStr = const Utf8Decoder().convert(json.encode(e?[0]).runes.toList()); // var jsonStr = const Utf8Decoder().convert(json.encode(e?[0]).runes.toList());
var jsonStr = json.encode(e?[0]); var jsonStr = json.encode(e?[0]);
@ -425,7 +427,8 @@ class MeetingMainLogic extends GetxController with RequestToolMixin{
muteLocalVideoStream(false); muteLocalVideoStream(false);
// //
startPreview(); startPreview();
//
state.floating.value?.open(state.context.value!);
changePageState(1); changePageState(1);
} }
}else{ }else{
@ -442,6 +445,8 @@ class MeetingMainLogic extends GetxController with RequestToolMixin{
muteLocalVideoStream(true); muteLocalVideoStream(true);
// //
stopPreview(); stopPreview();
//
state.floating.value?.close();
} }
} }
}); });

View File

@ -2,6 +2,7 @@ import 'dart:async';
import 'package:agora_rtc_engine/agora_rtc_engine.dart'; import 'package:agora_rtc_engine/agora_rtc_engine.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter_floating/floating/floating.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:get/get_rx/src/rx_types/rx_types.dart'; 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';
@ -18,6 +19,8 @@ class MeetingMainState {
late TextEditingController memberNameSearchController = TextEditingController(); late TextEditingController memberNameSearchController = TextEditingController();
late TextEditingController sendMsgController = TextEditingController(); late TextEditingController sendMsgController = TextEditingController();
late Rx<Floating?> floating = Rx(null);
late Rx<BuildContext?> context = Rx(null);
/// ///
late RxBool isShowMeetingInfoFloatingLayer = false.obs; late RxBool isShowMeetingInfoFloatingLayer = false.obs;

View File

@ -1,5 +1,10 @@
import 'dart:ui';
import 'package:agora_rtc_engine/agora_rtc_engine.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_floating/floating/assist/floating_slide_type.dart';
import 'package:flutter_floating/floating/floating.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:liquid_progress_indicator_v2/liquid_progress_indicator.dart'; import 'package:liquid_progress_indicator_v2/liquid_progress_indicator.dart';
@ -15,13 +20,35 @@ import 'meeting_main_logic.dart';
import 'meeting_main_state.dart'; import 'meeting_main_state.dart';
import 'voice/meeting_main_voice_view.dart'; import 'voice/meeting_main_voice_view.dart';
class MeetingMainPage extends StatelessWidget { class MeetingMainPage extends StatefulWidget {
MeetingMainPage({Key? key}) : super(key: key); const MeetingMainPage({super.key});
@override
State<MeetingMainPage> createState() => MeetingMainPageState();
}
class MeetingMainPageState extends State<MeetingMainPage> {
final MeetingMainLogic logic = Get.put(MeetingMainLogic()); final MeetingMainLogic logic = Get.put(MeetingMainLogic());
final MeetingMainState state = Get.find<MeetingMainLogic>().state; final MeetingMainState state = Get.find<MeetingMainLogic>().state;
@override
void initState() {
super.initState();
state.floating.value = Floating(
previewFloatingWidget(),
slideType: FloatingSlideType.onRightAndTop,
moveOpacity: 1,
isShowLog: false,
isSnapToEdge: false,
isPosCache: false,
top: MediaQueryData.fromView(window).padding.top + 100 + 58,
right: 13);
}
@override
Widget build(BuildContext context) { Widget build(BuildContext context) {
state.context.value = context;
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
surfaceTintColor: ColorUtil.Color_41_41_41, surfaceTintColor: ColorUtil.Color_41_41_41,
@ -54,20 +81,32 @@ class MeetingMainPage extends StatelessWidget {
width: 92.w, width: 92.w,
child: Row( child: Row(
children: [ children: [
Image.asset( GestureDetector(
child: Image.asset(
'assets/images/meeting_main_narrow.png', 'assets/images/meeting_main_narrow.png',
width: 20.w, width: 20.w,
height: 20.h, height: 20.h,
), ),
onTap: (){
if(state.floating.value?.isShowing == true){
state.floating.value?.close();
}else{
state.floating.value?.open(context);
}
},
),
SizedBox(width: 16.w), SizedBox(width: 16.w),
GestureDetector( GestureDetector(
child: Image.asset( child: Image.asset(
state.communicationMode.value == 1 ? 'assets/images/meeting_main_receiver.png' : 'assets/images/meeting_main_speaker.png', state.communicationMode.value == 1
? 'assets/images/meeting_main_receiver.png'
: 'assets/images/meeting_main_speaker.png',
width: 20.w, width: 20.w,
height: 20.h, height: 20.h,
), ),
onTap: () { onTap: () {
if(state.communicationMode.value == 1 || state.communicationMode.value == 3){ if (state.communicationMode.value == 1 ||
state.communicationMode.value == 3) {
logic.changeMeetingAudioState(true); logic.changeMeetingAudioState(true);
} }
}, },
@ -100,7 +139,8 @@ class MeetingMainPage extends StatelessWidget {
Row( Row(
children: [ children: [
Text( Text(
state.meetingRoomInfo.value?.roomName ?? '', state.meetingRoomInfo.value?.roomName ??
'',
style: TextStyle( style: TextStyle(
color: Colors.white, color: Colors.white,
fontSize: 14.sp, fontSize: 14.sp,
@ -148,6 +188,7 @@ class MeetingMainPage extends StatelessWidget {
), ),
), ),
SizedBox(width: 16.w), SizedBox(width: 16.w),
/// 退 /// 退
GestureDetector( GestureDetector(
child: Image.asset( child: Image.asset(
@ -158,8 +199,7 @@ class MeetingMainPage extends StatelessWidget {
onTap: () { onTap: () {
Get.bottomSheet( Get.bottomSheet(
isScrollControlled: true, isScrollControlled: true,
leaveBottomSheet(context) leaveBottomSheet(context));
);
}, },
) )
], ],
@ -174,12 +214,11 @@ class MeetingMainPage extends StatelessWidget {
child: Stack( child: Stack(
alignment: Alignment.bottomLeft, alignment: Alignment.bottomLeft,
children: [ children: [
// //
Visibility( Visibility(
visible: state.pageState.value == 0, visible: state.pageState.value == 0,
child: MeetingMainVoiceComponent(users: state.cacheUsers.value) child: MeetingMainVoiceComponent(
), users: state.cacheUsers.value)),
// //
Visibility( Visibility(
@ -190,13 +229,15 @@ class MeetingMainPage extends StatelessWidget {
channelId: state.roomNumber.value, channelId: state.roomNumber.value,
isOpenCamera: state.isOpenCamera.value, isOpenCamera: state.isOpenCamera.value,
remoteUid: state.remoteUid.value, remoteUid: state.remoteUid.value,
users: state.cacheUsers.value.where((user) => user.enableCamera == true).toList(), users: state.cacheUsers.value
.where((user) =>
user.enableCamera == true)
.toList(),
onHangUpTap: () { onHangUpTap: () {
logic.hangUpVideo(); logic.hangUpVideo();
}, },
) )
: Container() : Container()),
),
// //
Visibility( Visibility(
@ -207,14 +248,14 @@ class MeetingMainPage extends StatelessWidget {
channelId: state.roomNumber.value, channelId: state.roomNumber.value,
remoteUid: state.remoteUid.value, remoteUid: state.remoteUid.value,
) )
: Container() : Container()),
),
GestureDetector( GestureDetector(
child: Container( child: Container(
width: 180.w, width: 180.w,
height: 40.h, height: 40.h,
margin: const EdgeInsets.only(left: 20, bottom: 40), margin:
const EdgeInsets.only(left: 20, bottom: 40),
padding: const EdgeInsets.only(left: 20), padding: const EdgeInsets.only(left: 20),
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: const BorderRadius.only( borderRadius: const BorderRadius.only(
@ -224,8 +265,7 @@ class MeetingMainPage extends StatelessWidget {
color: ColorUtil.Color_35_35_35_07, color: ColorUtil.Color_35_35_35_07,
border: Border.all( border: Border.all(
width: 1.w, width: 1.w,
color: ColorUtil.Color_99_111_158 color: ColorUtil.Color_99_111_158),
),
), ),
child: Row( child: Row(
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
@ -249,10 +289,11 @@ class MeetingMainPage extends StatelessWidget {
onTap: () { onTap: () {
Get.bottomSheet( Get.bottomSheet(
isScrollControlled: true, isScrollControlled: true,
chatBottomSheet(context) chatBottomSheet(context));
); Future.delayed(const Duration(milliseconds: 100),
Future.delayed(const Duration(milliseconds: 100), () { () {
state.chatController.jumpTo(state.chatController.position.maxScrollExtent); state.chatController.jumpTo(state
.chatController.position.maxScrollExtent);
}); });
}, },
) )
@ -278,7 +319,8 @@ class MeetingMainPage extends StatelessWidget {
? Image.asset( ? Image.asset(
state.isSpeak.value == false state.isSpeak.value == false
? 'assets/images/meeting_main_sqfy.png' ? 'assets/images/meeting_main_sqfy.png'
: state.isOpenMicrophone.value == true : state.isOpenMicrophone.value ==
true
? 'assets/images/meeting_main_microphone_default.png' ? 'assets/images/meeting_main_microphone_default.png'
: 'assets/images/meeting_main_sqfy.png', : 'assets/images/meeting_main_sqfy.png',
width: 20.w, width: 20.w,
@ -289,12 +331,17 @@ class MeetingMainPage extends StatelessWidget {
width: 20.w, width: 20.w,
height: 20.h, height: 20.h,
child: LiquidCustomProgressIndicator( child: LiquidCustomProgressIndicator(
value: state.microphoneVolume.value, value: state
valueColor: const AlwaysStoppedAnimation(ColorUtil.Color_2_177_136), .microphoneVolume.value,
backgroundColor: ColorUtil.Color_255_255_255, valueColor:
const AlwaysStoppedAnimation(
ColorUtil
.Color_2_177_136),
backgroundColor:
ColorUtil.Color_255_255_255,
direction: Axis.vertical, direction: Axis.vertical,
shapePath: ViewSvgPath.getMicrpphonePath() shapePath: ViewSvgPath
), .getMicrpphonePath()),
) )
: Image.asset( : Image.asset(
'assets/images/meeting_main_sqfy.png', 'assets/images/meeting_main_sqfy.png',
@ -303,7 +350,11 @@ class MeetingMainPage extends StatelessWidget {
), ),
SizedBox(height: 4.h), SizedBox(height: 4.h),
Text( Text(
state.isSpeak.value == false ? '申请发言' : state.isOpenMicrophone.value == true ? "手动静音" : "解除静音", state.isSpeak.value == false
? '申请发言'
: state.isOpenMicrophone.value == true
? "手动静音"
: "解除静音",
style: TextStyle( style: TextStyle(
fontSize: 12.sp, fontSize: 12.sp,
color: ColorUtil.Color_202_202_202), color: ColorUtil.Color_202_202_202),
@ -314,9 +365,7 @@ class MeetingMainPage extends StatelessWidget {
if (state.isSpeak.value == false) { if (state.isSpeak.value == false) {
Get.bottomSheet( Get.bottomSheet(
isScrollControlled: true, isScrollControlled: true,
applySpeakPermissionBottomSheet( applySpeakPermissionBottomSheet(context));
context)
);
} else { } else {
if (state.isOpenMicrophone.value == false) { if (state.isOpenMicrophone.value == false) {
logic.setMicrophoneOpen(true); logic.setMicrophoneOpen(true);
@ -333,13 +382,19 @@ class MeetingMainPage extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
Image.asset( Image.asset(
state.isSpeak.value == true ? state.isOpenCamera.value == true ? 'assets/images/meeting_main_camera_open.png' : 'assets/images/meeting_main_camera_default.png' : 'assets/images/meeting_main_sp.png', state.isSpeak.value == true
? state.isOpenCamera.value == true
? 'assets/images/meeting_main_camera_open.png'
: 'assets/images/meeting_main_camera_default.png'
: 'assets/images/meeting_main_sp.png',
width: 22.w, width: 22.w,
height: 22.h, height: 22.h,
), ),
SizedBox(height: 4.h), SizedBox(height: 4.h),
Text( Text(
state.isOpenCamera.value == true ? "关闭视频" : "开启视频", state.isOpenCamera.value == true
? "关闭视频"
: "开启视频",
style: TextStyle( style: TextStyle(
fontSize: 12.sp, fontSize: 12.sp,
color: ColorUtil.Color_202_202_202), color: ColorUtil.Color_202_202_202),
@ -363,7 +418,11 @@ class MeetingMainPage extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
Image.asset( Image.asset(
state.isSpeak.value == true ? state.isOpenShare.value == true ? 'assets/images/meeting_main_share_open.png' : 'assets/images/meeting_main_share_default.png' : 'assets/images/meeting_main_share_close.png', state.isSpeak.value == true
? state.isOpenShare.value == true
? 'assets/images/meeting_main_share_open.png'
: 'assets/images/meeting_main_share_default.png'
: 'assets/images/meeting_main_share_close.png',
width: 22.w, width: 22.w,
height: 22.h, height: 22.h,
), ),
@ -691,16 +750,18 @@ class MeetingMainPage extends StatelessWidget {
/// ///
List<Widget> audioList() { List<Widget> audioList() {
List<Widget> audioList = []; List<Widget> audioList = [];
audioList.add( audioList.add(GestureDetector(
GestureDetector(
child: Column(children: [ child: Column(children: [
Text( Text(
'听筒', '听筒',
style: TextStyle( style: TextStyle(
fontSize: 14.sp, fontSize: 14.sp,
fontWeight: state.communicationMode.value == 1 ? FontWeight.w500 : FontWeight.w400, fontWeight: state.communicationMode.value == 1
color: state.communicationMode.value == 1 ? ColorUtil.Color_85_117_242 : ColorUtil.Color_134_134_134 ? FontWeight.w500
), : FontWeight.w400,
color: state.communicationMode.value == 1
? ColorUtil.Color_85_117_242
: ColorUtil.Color_134_134_134),
), ),
Container( Container(
width: double.infinity, width: double.infinity,
@ -713,19 +774,20 @@ class MeetingMainPage extends StatelessWidget {
logic.setEnableSpeakerphone(1); logic.setEnableSpeakerphone(1);
logic.changeMeetingAudioState(false); logic.changeMeetingAudioState(false);
}, },
) ));
); audioList.add(GestureDetector(
audioList.add(
GestureDetector(
child: Column( child: Column(
children: [ children: [
Text( Text(
'扬声器', '扬声器',
style: TextStyle( style: TextStyle(
fontSize: 14.sp, fontSize: 14.sp,
fontWeight: state.communicationMode.value == 3 ? FontWeight.w500 : FontWeight.w400, fontWeight: state.communicationMode.value == 3
color: state.communicationMode.value == 3 ? ColorUtil.Color_85_117_242 : ColorUtil.Color_134_134_134 ? FontWeight.w500
), : FontWeight.w400,
color: state.communicationMode.value == 3
? ColorUtil.Color_85_117_242
: ColorUtil.Color_134_134_134),
), ),
], ],
), ),
@ -733,8 +795,7 @@ class MeetingMainPage extends StatelessWidget {
logic.setEnableSpeakerphone(3); logic.setEnableSpeakerphone(3);
logic.changeMeetingAudioState(false); logic.changeMeetingAudioState(false);
}, },
) ));
);
return audioList; return audioList;
} }
@ -900,8 +961,7 @@ class MeetingMainPage extends StatelessWidget {
padding: const EdgeInsets.only(left: 12, right: 12), padding: const EdgeInsets.only(left: 12, right: 12),
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: const BorderRadius.all(Radius.circular(12)), borderRadius: const BorderRadius.all(Radius.circular(12)),
border: Border.all( border: Border.all(width: 1.w, color: ColorUtil.Color_70_71_73),
width: 1.w, color: ColorUtil.Color_70_71_73),
), ),
child: Row( child: Row(
children: [ children: [
@ -915,17 +975,15 @@ class MeetingMainPage extends StatelessWidget {
child: TextField( child: TextField(
controller: state.memberNameSearchController, controller: state.memberNameSearchController,
style: TextStyle( style: TextStyle(
fontSize: 14.sp, fontSize: 14.sp, color: ColorUtil.Color_235_235_235),
color: ColorUtil.Color_235_235_235
),
textInputAction: TextInputAction.search, textInputAction: TextInputAction.search,
decoration: InputDecoration( decoration: InputDecoration(
contentPadding: const EdgeInsets.all(0), contentPadding: const EdgeInsets.all(0),
border: const OutlineInputBorder(borderSide: BorderSide.none), border: const OutlineInputBorder(
borderSide: BorderSide.none),
hintText: '输入用户名', hintText: '输入用户名',
hintStyle: TextStyle( hintStyle: TextStyle(
color: ColorUtil.Color_70_71_73, color: ColorUtil.Color_70_71_73, fontSize: 14.sp)),
fontSize: 14.sp)),
onSubmitted: (value) { onSubmitted: (value) {
logic.searchMember(value); logic.searchMember(value);
}, },
@ -945,7 +1003,6 @@ class MeetingMainPage extends StatelessWidget {
color: ColorUtil.Color_85_117_242), color: ColorUtil.Color_85_117_242),
), ),
), ),
Expanded( Expanded(
child: ScrollConfiguration( child: ScrollConfiguration(
behavior: CusBehavior(), behavior: CusBehavior(),
@ -958,29 +1015,41 @@ class MeetingMainPage extends StatelessWidget {
child: Column( child: Column(
children: [ children: [
Container( Container(
padding: const EdgeInsets.only(left: 16, right: 16), padding:
const EdgeInsets.only(left: 16, right: 16),
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [ children: [
Row( Row(
children: [ children: [
Container( Container(
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: BorderRadius.circular(100), borderRadius:
color: ColorUtil.Color_85_117_242 BorderRadius.circular(100),
), color: ColorUtil.Color_85_117_242),
margin: const EdgeInsets.only(right: 8), margin: const EdgeInsets.only(right: 8),
width: 36.w, width: 36.w,
height: 36.h, height: 36.h,
alignment: Alignment.center, alignment: Alignment.center,
child: Text( child: Text(
state.users.value[index].userName.length > 3 state.users.value[index].userName
? state.users.value[index].userName.substring(state.users.value[index].userName.length - 2,state.users.value[index].userName.length) .length >
: state.users.value[index].userName, 3
? state
.users.value[index].userName
.substring(
state.users.value[index]
.userName.length -
2,
state.users.value[index]
.userName.length)
: 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),
), ),
), ),
Text( Text(
@ -992,7 +1061,14 @@ class MeetingMainPage extends StatelessWidget {
), ),
SizedBox(width: 8.w), SizedBox(width: 8.w),
Visibility( Visibility(
visible: state.users.value[index].roleId == "1" || state.users.value[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(
@ -1002,7 +1078,14 @@ class MeetingMainPage extends StatelessWidget {
), ),
), ),
Visibility( Visibility(
visible: state.users.value[index].roleId == "2" && state.users.value[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(
@ -1025,7 +1108,10 @@ 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.value[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,
), ),
@ -1033,7 +1119,11 @@ 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.value[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,
), ),
@ -1046,7 +1136,8 @@ class MeetingMainPage extends StatelessWidget {
Container( Container(
width: double.infinity, width: double.infinity,
height: 0.5.h, height: 0.5.h,
margin: const EdgeInsets.only(top: 12, bottom: 12), margin:
const EdgeInsets.only(top: 12, bottom: 12),
color: ColorUtil.Color_49_47_47, color: ColorUtil.Color_49_47_47,
) )
], ],
@ -1055,8 +1146,7 @@ class MeetingMainPage extends StatelessWidget {
}, },
itemCount: state.users.value.length, itemCount: state.users.value.length,
); );
}) })),
),
) )
], ],
), ),
@ -1068,7 +1158,8 @@ class MeetingMainPage extends StatelessWidget {
return Container( return Container(
height: 500.h, height: 500.h,
color: ColorUtil.Color_35_35_35, color: ColorUtil.Color_35_35_35,
padding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom), padding:
EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
@ -1114,12 +1205,13 @@ class MeetingMainPage extends StatelessWidget {
return ListView.builder( return ListView.builder(
controller: state.chatController, controller: state.chatController,
itemBuilder: (context, index) { itemBuilder: (context, index) {
return state.meetingRoomMsgs.value[index].source == 0 ? chartItemToOthers(index) : chartItemToOwn(index); return state.meetingRoomMsgs.value[index].source == 0
? chartItemToOthers(index)
: chartItemToOwn(index);
}, },
itemCount: state.meetingRoomMsgs.value.length, itemCount: state.meetingRoomMsgs.value.length,
); );
}) })),
),
), ),
Container( Container(
width: double.infinity, width: double.infinity,
@ -1135,17 +1227,14 @@ class MeetingMainPage extends StatelessWidget {
child: TextField( child: TextField(
controller: state.sendMsgController, 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: const EdgeInsets.all(0), contentPadding: const EdgeInsets.all(0),
border: const 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) { onSubmitted: (value) {
if (value.isNotEmpty) { if (value.isNotEmpty) {
logic.sendMsg(value); logic.sendMsg(value);
@ -1175,19 +1264,18 @@ class MeetingMainPage extends StatelessWidget {
Container( Container(
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: BorderRadius.circular(99), borderRadius: BorderRadius.circular(99),
color: ColorUtil.Color_85_117_242 color: ColorUtil.Color_85_117_242),
),
width: 50.w, width: 50.w,
height: 50.h, height: 50.h,
alignment: Alignment.center, alignment: Alignment.center,
child: Text( child: Text(
state.meetingRoomMsgs.value[index].userName.length > 3 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.substring(
state.meetingRoomMsgs.value[index].userName.length - 2,
state.meetingRoomMsgs.value[index].userName.length)
: state.meetingRoomMsgs.value[index].userName, : state.meetingRoomMsgs.value[index].userName,
style: TextStyle( style: TextStyle(
fontSize: 14.sp, fontSize: 14.sp, color: ColorUtil.Color_244_244_244),
color: ColorUtil.Color_244_244_244
),
), ),
), ),
Expanded( Expanded(
@ -1199,13 +1287,11 @@ class MeetingMainPage extends StatelessWidget {
child: Text( child: Text(
state.meetingRoomMsgs.value[index].userName, 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),
), ),
), ),
Container( Container(
margin: const EdgeInsets.only( margin: const EdgeInsets.only(left: 6, top: 6, right: 16),
left: 6, top: 6, right: 16),
padding: const EdgeInsets.only( padding: const EdgeInsets.only(
left: 18, right: 18, top: 10, bottom: 10), left: 18, right: 18, top: 10, bottom: 10),
decoration: const BoxDecoration( decoration: const BoxDecoration(
@ -1218,13 +1304,11 @@ class MeetingMainPage extends StatelessWidget {
child: Text( child: Text(
state.meetingRoomMsgs.value[index].message, 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),
), ),
) )
], ],
) ))
)
], ],
), ),
); );
@ -1249,53 +1333,108 @@ class MeetingMainPage extends StatelessWidget {
child: Text( child: Text(
state.meetingRoomMsgs.value[index].userName, 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),
), ),
), ),
Container( Container(
margin: const EdgeInsets.only( margin: const EdgeInsets.only(left: 16, top: 6, right: 6),
left: 16, top: 6, right: 6),
padding: const EdgeInsets.only( padding: const EdgeInsets.only(
left: 18, right: 18, top: 10, bottom: 10), left: 18, right: 18, top: 10, bottom: 10),
decoration: const BoxDecoration( decoration: const BoxDecoration(
borderRadius: BorderRadius.only( borderRadius: BorderRadius.only(
topLeft: Radius.circular(99), topLeft: Radius.circular(99),
bottomLeft: Radius.circular(99), bottomLeft: Radius.circular(99),
bottomRight: Radius.circular(99) bottomRight: Radius.circular(99)),
),
color: ColorUtil.Color_85_117_242, color: ColorUtil.Color_85_117_242,
), ),
child: Text( child: Text(
state.meetingRoomMsgs.value[index].message, 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),
), ),
) )
], ],
) )),
),
Container( Container(
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: BorderRadius.circular(99), borderRadius: BorderRadius.circular(99),
color: ColorUtil.Color_85_117_242 color: ColorUtil.Color_85_117_242),
),
width: 50.w, width: 50.w,
height: 50.h, height: 50.h,
alignment: Alignment.center, alignment: Alignment.center,
child: Text( child: Text(
state.meetingRoomMsgs.value[index].userName.length > 3 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.substring(
state.meetingRoomMsgs.value[index].userName.length - 2,
state.meetingRoomMsgs.value[index].userName.length)
: state.meetingRoomMsgs.value[index].userName, : state.meetingRoomMsgs.value[index].userName,
style: TextStyle( style: TextStyle(
fontSize: 14.sp, fontSize: 14.sp, color: ColorUtil.Color_244_244_244),
color: ColorUtil.Color_244_244_244
),
), ),
) )
], ],
), ),
); );
} }
///
Widget previewFloatingWidget(){
return Stack(
children: [
SizedBox(
width: 120,
height: 150,
child: Obx(() => Center(
child: state.isOpenCamera.value == true
? AgoraVideoView(
controller: VideoViewController(
rtcEngine: state.rctEngine.value!,
canvas: const VideoCanvas(uid: 0),
),
)
: const CircularProgressIndicator(),
)),
),
Positioned(
left: 4,
bottom: 4,
child: Row(
children: [
Image.asset(
'assets/images/meeting_main_own.png',
width: 20.w,
height: 15.h,
),
Container(
height: 15,
margin: const EdgeInsets.only(left: 4),
padding:
const EdgeInsets.only(left: 4, right: 4),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(2),
color: ColorUtil.Color_0_0_0_96),
child: Row(
children: [
/*Image.asset(
'assets/images/meeting_main_microphone_open.png',
width: 13.w,
height: 14.h,
),
SizedBox(width: 4.w),*/
Text(
UserStore
.to.userInfoEntity.value!.userName,
style: TextStyle(
fontSize: 10.sp,
color: ColorUtil.Color_185_184_184),
)
],
),
)
],
),
)
],
);
}
} }

View File

@ -12,7 +12,7 @@ import 'meeting_main_video_logic.dart';
import 'meeting_main_video_state.dart'; import 'meeting_main_video_state.dart';
class MeetingMainVideoComponent extends StatefulWidget { class MeetingMainVideoComponent extends StatefulWidget {
MeetingMainVideoComponent({super.key, const MeetingMainVideoComponent({super.key,
required this.rtcEngine, required this.rtcEngine,
required this.channelId, required this.channelId,
required this.isOpenCamera, required this.isOpenCamera,
@ -115,7 +115,7 @@ class _MeetingMainVideoComponentState extends State<MeetingMainVideoComponent> w
), ),
/// ///
Visibility( /*Visibility(
visible: widget.isOpenCamera, visible: widget.isOpenCamera,
child: Positioned( child: Positioned(
top: 58, top: 58,
@ -156,12 +156,12 @@ class _MeetingMainVideoComponentState extends State<MeetingMainVideoComponent> w
color: ColorUtil.Color_0_0_0_96), color: ColorUtil.Color_0_0_0_96),
child: Row( child: Row(
children: [ children: [
/*Image.asset( *//*Image.asset(
'assets/images/meeting_main_microphone_open.png', 'assets/images/meeting_main_microphone_open.png',
width: 13.w, width: 13.w,
height: 14.h, height: 14.h,
), ),
SizedBox(width: 4.w),*/ SizedBox(width: 4.w),*//*
Text( Text(
UserStore UserStore
.to.userInfoEntity.value!.userName, .to.userInfoEntity.value!.userName,
@ -178,7 +178,7 @@ class _MeetingMainVideoComponentState extends State<MeetingMainVideoComponent> w
], ],
), ),
), ),
) )*/
], ],
), ),
Container( Container(

View File

@ -315,6 +315,14 @@ packages:
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "3.0.5" version: "3.0.5"
flutter_floating:
dependency: "direct main"
description:
name: flutter_floating
sha256: "0ff6a47c29a213c426005d248c6afe93fa76e308abbbbd6c8a35689daf11a997"
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.0.8"
flutter_hooks: flutter_hooks:
dependency: "direct main" dependency: "direct main"
description: description:

View File

@ -79,6 +79,9 @@ dependencies:
# 水波效果的进度器 # 水波效果的进度器
liquid_progress_indicator_v2: ^0.5.0 liquid_progress_indicator_v2: ^0.5.0
# 悬浮拖动组件
flutter_floating: ^1.0.7
dev_dependencies: dev_dependencies:
flutter_test: flutter_test:
sdk: flutter sdk: flutter