WGShare.Mobile.Flutter/wgshare/lib/pages/metting/meeting_main_view.dart

1716 lines
72 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import 'dart:ui';
import 'package:agora_rtc_engine/agora_rtc_engine.dart';
import 'package:flutter/material.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:get/get.dart';
import 'package:liquid_progress_indicator_v2/liquid_progress_indicator.dart';
import 'package:preload_page_view/preload_page_view.dart';
import 'package:wgshare/common/store/user_store.dart';
import 'package:wgshare/utils/toast_utils.dart';
import '../../utils/color_util.dart';
import '../../utils/cus_behavior.dart';
import '../../view/view_svg_path.dart';
import 'meeting_main_logic.dart';
import 'meeting_main_state.dart';
import 'voice/meeting_main_voice_view.dart';
class MeetingMainPage extends StatefulWidget {
const MeetingMainPage({super.key});
@override
State<MeetingMainPage> createState() => MeetingMainPageState();
}
class MeetingMainPageState extends State<MeetingMainPage> {
final MeetingMainLogic logic = Get.put(MeetingMainLogic());
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) {
state.context.value = context;
return Scaffold(
appBar: AppBar(
surfaceTintColor: ColorUtil.Color_41_41_41,
elevation: 0,
toolbarHeight: 0,
systemOverlayStyle: const SystemUiOverlayStyle(
statusBarColor: Colors.transparent,
systemNavigationBarColor: ColorUtil.Color_41_41_41,
systemNavigationBarIconBrightness: Brightness.light,
statusBarIconBrightness: Brightness.light,
statusBarBrightness: Brightness.light,
),
backgroundColor: ColorUtil.Color_41_41_41,
),
body: Obx(() => Stack(
children: [
Column(
children: [
/// 顶部布局
Container(
width: double.infinity,
height: 100.h,
alignment: Alignment.center,
color: ColorUtil.Color_41_41_41,
padding: const EdgeInsets.only(left: 16, right: 16),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Container(
width: 92.w,
child: Row(
children: [
GestureDetector(
child: Image.asset(
'assets/images/meeting_main_narrow.png',
width: 20.w,
height: 20.h,
),
onTap: () {},
),
SizedBox(width: 16.w),
GestureDetector(
child: Image.asset(
state.communicationMode.value == 1
? 'assets/images/meeting_main_receiver.png'
: 'assets/images/meeting_main_speaker.png',
width: 20.w,
height: 20.h,
),
onTap: () {
if (state.communicationMode.value == 1 ||
state.communicationMode.value == 3) {
logic.changeMeetingAudioState(true);
}
},
),
Visibility(
visible: state.isOpenCamera.value,
child: GestureDetector(
child: Row(
children: [
SizedBox(width: 16.w),
Image.asset(
'assets/images/meeting_main_rotate_camera.png',
width: 20.w,
height: 20.h,
)
],
),
onTap: () {
logic.switchCamera();
},
),
)
],
),
),
GestureDetector(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Row(
children: [
Text(
state.meetingRoomInfo.value?.roomName ??
'',
style: TextStyle(
color: Colors.white,
fontSize: 14.sp,
fontWeight: FontWeight.w500),
),
SizedBox(width: 4.w),
Image.asset(
'assets/images/meeting_main_down.png',
width: 16.w,
height: 16.h,
)
],
),
SizedBox(height: 4.h),
Text(
state.duration.value,
style: TextStyle(
color: Colors.white,
fontSize: 12.sp,
),
)
],
),
onTap: () {
logic.changeMeetingInfoState(true);
},
),
Container(
width: 92.w,
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
/// 退出会议
GestureDetector(
child: Image.asset(
'assets/images/meeting_leave.png',
width: 20.w,
height: 20.h,
),
onTap: () {
Get.bottomSheet(
isScrollControlled: true,
leaveBottomSheet(context));
},
)
],
),
)
],
),
),
/// 中间布局
Expanded(
child: Stack(
alignment: Alignment.bottomLeft,
children: [
// 语音
Visibility(
visible: state.pageState.value == 0,
child: MeetingMainVoiceComponent(
users: state.cacheUsers.value)),
// 视频-共享
Visibility(
visible: state.pageState.value == 1,
child: null != state.rctEngine.value
? Stack(
alignment: Alignment.center,
children: [
PreloadPageView.builder(
preloadPagesCount: 2,
itemCount: 2,
itemBuilder: (BuildContext context,
int position) =>
returnPage(position),
controller: PreloadPageController(
initialPage: 0),
onPageChanged: (int position) {
state.pageIndex.value = position;
if (state.isSpeak.value == true &&
state.isOpenCamera.value ==
true &&
state.remoteUid.value != "0") {
if (position == 0) {
state.floating.value
?.open(context);
} else {
state.floating.value?.close();
}
}
},
),
/// pageview 指示器
Positioned(
bottom: 16,
child: Row(
children: [
Container(
width: 8.w,
height: 8.h,
margin: const EdgeInsets.only(
right: 6),
decoration: BoxDecoration(
borderRadius:
BorderRadius.circular(
8),
color: state.pageIndex
.value ==
0
? ColorUtil
.Color_255_255_255
: ColorUtil
.Color_108_108_108),
),
Container(
width: 8.w,
height: 8.h,
margin: const EdgeInsets.only(
left: 6),
decoration: BoxDecoration(
borderRadius:
BorderRadius.circular(
8),
color: state.pageIndex
.value ==
1
? ColorUtil
.Color_255_255_255
: ColorUtil
.Color_108_108_108),
)
],
),
),
],
)
: Container()),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
GestureDetector(
child: Container(
width: 200.w,
height: 40.h,
margin:
const EdgeInsets.only(left: 20, bottom: 40),
padding: const EdgeInsets.only(left: 20),
decoration: BoxDecoration(
borderRadius: const BorderRadius.only(
bottomLeft: Radius.circular(56),
topRight: Radius.circular(50),
bottomRight: Radius.circular(50)),
color: ColorUtil.Color_35_35_35_07,
border: Border.all(
width: 1.w,
color: ColorUtil.Color_99_111_158),
),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Image.asset(
'assets/images/meeting_main_chat.png',
width: 18.w,
height: 18.h,
),
SizedBox(width: 6.w),
Text(
'说点什么...',
style: TextStyle(
fontSize: 14.sp,
color: ColorUtil.Color_156_156_156),
)
],
),
),
onTap: () {
Get.bottomSheet(
isScrollControlled: true,
chatBottomSheet(context));
Future.delayed(const Duration(milliseconds: 100),
() {
state.chatController.jumpTo(state
.chatController.position.maxScrollExtent);
});
},
),
Visibility(
visible: state.isSpeak.value,
child: GestureDetector(
child: Container(
width: 82.w,
height: 40.h,
margin: const EdgeInsets.only(left: 12, bottom: 40,right: 20),
alignment: Alignment.center,
decoration: const BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(99)),
color: ColorUtil.Color_255_69_69
),
child: Text(
'结束发言',
style: TextStyle(
fontSize: 14.sp,
color: ColorUtil.Color_255_255_255),
),
),
onTap: () {
logic.cancelSpeak();
},
),
)
],
)
],
),
),
/// 底部布局
Container(
width: double.infinity,
height: 84.h,
color: ColorUtil.Color_35_35_35,
padding: const EdgeInsets.only(left: 26, right: 26),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
/// 音频
GestureDetector(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
state.isSpeak.value == false
? Image.asset(
state.isSpeak.value == false
? 'assets/images/meeting_main_sqfy.png'
: state.isOpenMicrophone.value ==
true
? 'assets/images/meeting_main_microphone_default.png'
: 'assets/images/meeting_main_sqfy.png',
width: 20.w,
height: 20.h,
)
: state.isOpenMicrophone.value == true
? Container(
width: 20.w,
height: 20.h,
child: LiquidCustomProgressIndicator(
value: state
.microphoneVolume.value,
valueColor:
const AlwaysStoppedAnimation(
ColorUtil
.Color_2_177_136),
backgroundColor:
ColorUtil.Color_255_255_255,
direction: Axis.vertical,
shapePath: ViewSvgPath
.getMicrpphonePath()),
)
: Image.asset(
'assets/images/meeting_main_sqfy.png',
width: 20.w,
height: 20.h,
),
SizedBox(height: 4.h),
Text(
state.isSpeak.value == false
? '申请发言'
: state.isOpenMicrophone.value == true
? "手动静音"
: "解除静音",
style: TextStyle(
fontSize: 12.sp,
color: ColorUtil.Color_202_202_202),
)
],
),
onTap: () {
if (state.isSpeak.value == false) {
Get.bottomSheet(
isScrollControlled: true,
applySpeakPermissionBottomSheet(context,1));
} else {
if (state.isOpenMicrophone.value == false) {
logic.doHttpSetMicr(true);
} else {
logic.doHttpSetMicr(false);
}
}
},
),
/// 视频
GestureDetector(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
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',
width: 22.w,
height: 22.h,
),
SizedBox(height: 4.h),
Text(
/*state.isSpeak.value == false
? '申请发言'
: */state.isOpenCamera.value == true
? "关闭视频"
: "开启视频",
style: TextStyle(
fontSize: 12.sp,
color: ColorUtil.Color_202_202_202),
)
],
),
onTap: () {
if (state.isSpeak.value == false) {
Get.bottomSheet(
isScrollControlled: true,
applySpeakPermissionBottomSheet(context,2));
} else {
if (state.isOpenCamera.value == true) {
logic.doHttpSetCamer(false);
} else {
logic.doHttpSetCamer(true);
}
}
},
),
/// 共享(此版本不做)
/*GestureDetector(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
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',
width: 22.w,
height: 22.h,
),
SizedBox(height: 4.h),
Text(
'共享屏幕',
style: TextStyle(
fontSize: 12.sp,
color: ColorUtil.Color_202_202_202),
)
],
),
onTap: () {
if (state.isSpeak.value == true) {
if (state.isOpenShare.value == true) {
logic.stopScreenCapture();
} else {
logic.startScreenCapture();
}
}
},
),*/
/// 成员
GestureDetector(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.asset(
'assets/images/meeting_main_member_default.png',
width: 22.w,
height: 22.h,
),
SizedBox(height: 4.h),
Text(
' 成员 ',
style: TextStyle(
fontSize: 12.sp,
color: ColorUtil.Color_202_202_202),
)
],
),
onTap: () {
Get.bottomSheet(
isScrollControlled: true,
queryMemberFloatingLayer(context),
);
},
),
],
),
)
],
),
meetingInfoFloatingLayer(),
meetingAudioFloatingLayer(),
],
)));
}
/// 退出会议底部弹窗
Widget leaveBottomSheet(BuildContext context) {
return Container(
height: 170.h,
color: ColorUtil.Color_7_9_11,
padding: const EdgeInsets.only(top: 24, bottom: 24, left: 16, right: 16),
child: Column(
children: [
GestureDetector(
child: Container(
height: 52.h,
decoration: const BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(6)),
color: ColorUtil.Color_49_53_58,
),
alignment: Alignment.center,
child: Text(
'仅自己离开',
style: TextStyle(
fontSize: 16.sp,
color: Colors.white,
),
),
),
onTap: () {
Get.back();
Get.back();
},
),
GestureDetector(
child: Container(
height: 52.h,
margin: const EdgeInsets.only(top: 16),
decoration: const BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(6)),
color: ColorUtil.Color_16_20_24,
),
alignment: Alignment.center,
child: Text(
'取消',
style: TextStyle(
fontSize: 16.sp,
color: Colors.white,
),
),
),
onTap: () {
Get.back();
},
)
],
),
);
}
/// 会议信息浮层
Widget meetingInfoFloatingLayer() {
return Visibility(
visible: state.isShowMeetingInfoFloatingLayer.value,
child: Column(
children: [
Container(
height: 100.h,
color: ColorUtil.Color_0_0_0_0,
),
Container(
color: ColorUtil.Color_35_35_35,
padding: const EdgeInsets.only(top: 16, bottom: 6),
child: Column(
children: [
Container(
padding: const EdgeInsets.only(left: 16, right: 16),
margin: const EdgeInsets.only(bottom: 12),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
state.meetingRoomInfo.value?.roomName ?? '',
style: TextStyle(
fontSize: 14.sp,
fontWeight: FontWeight.w500,
color: ColorUtil.Color_85_117_242),
),
Row(
children: [
Image.asset(
'assets/images/meeting_main_network_normal.png',
width: 14.w,
height: 14.h,
),
SizedBox(width: 12.w),
Text(
'网络链接正常',
style: TextStyle(
fontSize: 12.sp,
color: ColorUtil.Color_202_202_202),
)
],
)
],
),
),
Container(
padding: const EdgeInsets.only(left: 16, right: 16),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'会议号',
style: TextStyle(
fontSize: 12.sp,
fontWeight: FontWeight.w500,
color: ColorUtil.Color_134_134_134),
),
Row(
children: [
Text(
state.roomNumber.value,
style: TextStyle(
fontSize: 12.sp,
color: ColorUtil.Color_202_202_202,
fontWeight: FontWeight.w500),
),
SizedBox(width: 12.w),
Image.asset(
'assets/images/meeting_main_copy.png',
width: 18.w,
height: 18.h,
)
],
)
],
),
),
Container(
width: double.infinity,
height: 1.h,
color: ColorUtil.Color_49_47_47,
margin: const EdgeInsets.only(top: 14, bottom: 14),
),
Container(
padding: const EdgeInsets.only(left: 16, right: 16),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'我的名称',
style: TextStyle(
fontSize: 12.sp,
fontWeight: FontWeight.w500,
color: ColorUtil.Color_134_134_134),
),
Text(
UserStore.to.userInfoEntity.value!.userName,
style: TextStyle(
fontSize: 12.sp,
color: ColorUtil.Color_202_202_202,
fontWeight: FontWeight.w500),
)
],
),
),
Container(
width: double.infinity,
height: 1.h,
color: ColorUtil.Color_49_47_47,
margin: const EdgeInsets.only(top: 14, bottom: 14),
),
Container(
padding: const EdgeInsets.only(left: 16, right: 16),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'参会时长',
style: TextStyle(
fontSize: 12.sp,
fontWeight: FontWeight.w500,
color: ColorUtil.Color_134_134_134),
),
Text(
state.duration.value,
style: TextStyle(
fontSize: 12.sp,
color: ColorUtil.Color_202_202_202,
fontWeight: FontWeight.w500),
)
],
),
),
SizedBox(height: 10.h),
GestureDetector(
child: Container(
padding: const EdgeInsets.only(top: 10, bottom: 10),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'收回列表',
style: TextStyle(
fontSize: 10.sp,
color: ColorUtil.Color_202_202_202,
fontWeight: FontWeight.w500),
),
SizedBox(width: 4.w),
Image.asset(
'assets/images/meeting_main_info_close.png',
width: 12.w,
height: 10.h,
)
],
),
),
onTap: () {
logic.changeMeetingInfoState(false);
},
)
],
),
),
Expanded(
child: GestureDetector(
child: Container(
color: ColorUtil.Color_57_57_57_08,
),
onTap: (){
logic.changeMeetingInfoState(false);
},
)
)
],
),
);
}
/// 选择音频输出浮层
Widget meetingAudioFloatingLayer() {
return Visibility(
visible: state.isShowMeetingAudioFloatingLayer.value,
child: Column(
children: [
Expanded(
child: GestureDetector(
child: Container(
color: ColorUtil.Color_57_57_57_08,
),
onTap: (){
logic.changeMeetingAudioState(false);
},
)),
Container(
color: ColorUtil.Color_57_57_57_08,
child: Container(
width: double.infinity,
padding: const EdgeInsets.only(top: 16, bottom: 16),
margin: const EdgeInsets.only(left: 40, right: 40),
decoration: BoxDecoration(
borderRadius: const BorderRadius.all(Radius.circular(6)),
border: Border.all(color: ColorUtil.Color_0_0_0_0),
color: ColorUtil.Color_35_35_35,
),
child: Column(
children: audioList(),
),
),
),
Expanded(
child: GestureDetector(
child:Container(
color: ColorUtil.Color_57_57_57_08,
),
onTap: (){
logic.changeMeetingAudioState(false);
},
))
],
),
);
}
/// 音频列表
List<Widget> audioList() {
List<Widget> audioList = [];
audioList.add(GestureDetector(
child: Column(children: [
Text(
'听筒',
style: TextStyle(
fontSize: 14.sp,
fontWeight: state.communicationMode.value == 1
? FontWeight.w500
: FontWeight.w400,
color: state.communicationMode.value == 1
? ColorUtil.Color_85_117_242
: ColorUtil.Color_134_134_134),
),
Container(
width: double.infinity,
height: 1.h,
color: ColorUtil.Color_49_47_47,
margin: const EdgeInsets.only(top: 14, bottom: 14),
)
]),
onTap: () {
logic.setEnableSpeakerphone(1);
logic.changeMeetingAudioState(false);
},
));
audioList.add(GestureDetector(
child: Column(
children: [
Text(
'扬声器',
style: TextStyle(
fontSize: 14.sp,
fontWeight: state.communicationMode.value == 3
? FontWeight.w500
: FontWeight.w400,
color: state.communicationMode.value == 3
? ColorUtil.Color_85_117_242
: ColorUtil.Color_134_134_134),
),
],
),
onTap: () {
logic.setEnableSpeakerphone(3);
logic.changeMeetingAudioState(false);
},
));
return audioList;
}
/// 申请发言权限底部弹窗
Widget applySpeakPermissionBottomSheet(BuildContext context, int defaulOpenState) {
return Container(
height: 240.h,
color: ColorUtil.Color_7_9_11,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
padding: const EdgeInsets.only(left: 16, right: 16),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
SizedBox(width: 12.w),
Container(
height: 50.h,
alignment: Alignment.center,
child: Text(
'提示',
style: TextStyle(
fontSize: 14.sp,
fontWeight: FontWeight.w500,
color: ColorUtil.Color_238_238_238),
),
),
GestureDetector(
child: Image.asset(
'assets/images/meeting_main_close_permission.png',
width: 12.w,
height: 12.h,
),
onTap: () {
Get.back();
},
)
],
),
),
Container(
width: double.infinity,
height: 1.h,
color: ColorUtil.Color_49_47_47,
),
Container(
margin: const EdgeInsets.only(top: 20, bottom: 80, left: 16),
child: Text(
'该操作需向管理人申请发言权限',
style: TextStyle(
fontSize: 14.sp,
fontWeight: FontWeight.w600,
color: ColorUtil.Color_238_238_238),
),
),
Container(
margin: const EdgeInsets.only(bottom: 20, left: 16, right: 16),
child: Row(
children: [
Expanded(
child: GestureDetector(
child: Container(
height: 44.h,
margin: const EdgeInsets.only(right: 6),
decoration: const BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(10)),
color: ColorUtil.Color_49_53_58,
),
alignment: Alignment.center,
child: Text(
'取消',
style: TextStyle(
fontSize: 14.sp,
color: ColorUtil.Color_238_238_238,
),
),
),
onTap: () {
Get.back();
},
),
),
Expanded(
child: GestureDetector(
child: Container(
height: 44.h,
margin: const EdgeInsets.only(left: 6),
decoration: const BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(10)),
color: ColorUtil.Color_85_117_242,
),
alignment: Alignment.center,
child: Text(
'申请',
style: TextStyle(
fontSize: 14.sp,
color: ColorUtil.Color_238_238_238,
),
),
),
onTap: () {
state.defaulOpenState.value = defaulOpenState;
logic.doHttpApplySpeak();
Get.back();
},
),
)
],
),
)
],
),
);
}
/// 查看成员浮层
Widget queryMemberFloatingLayer(BuildContext context) {
return Container(
height: 520.h,
color: ColorUtil.Color_7_9_11,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
padding: const EdgeInsets.only(left: 16, right: 16),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
SizedBox(width: 12.w),
Container(
height: 50.h,
alignment: Alignment.center,
child: Text(
'成员',
style: TextStyle(
fontSize: 14.sp,
fontWeight: FontWeight.w500,
color: ColorUtil.Color_238_238_238),
),
),
GestureDetector(
child: Image.asset(
'assets/images/meeting_main_close_permission.png',
width: 12.w,
height: 12.h,
),
onTap: () {
Get.back();
},
)
],
),
),
Container(
width: double.infinity,
height: 0.5.h,
color: ColorUtil.Color_49_47_47,
),
Container(
width: double.infinity,
height: 44.h,
margin: const EdgeInsets.only(top: 18, left: 16, right: 16),
padding: const EdgeInsets.only(left: 12, right: 12),
decoration: BoxDecoration(
borderRadius: const BorderRadius.all(Radius.circular(12)),
border: Border.all(width: 1.w, color: ColorUtil.Color_70_71_73),
),
child: Row(
children: [
Image.asset(
'assets/images/meeting_main_query_member.png',
width: 24.w,
height: 24.h,
),
SizedBox(width: 8.w),
Expanded(
child: TextField(
controller: state.memberNameSearchController,
style: TextStyle(
fontSize: 14.sp, color: ColorUtil.Color_235_235_235),
textInputAction: TextInputAction.search,
decoration: InputDecoration(
contentPadding: const EdgeInsets.all(0),
border: const OutlineInputBorder(
borderSide: BorderSide.none),
hintText: '输入用户名',
hintStyle: TextStyle(
color: ColorUtil.Color_70_71_73, fontSize: 14.sp)),
onSubmitted: (value) {
logic.searchMember(value);
},
),
)
],
),
),
Container(
margin:
const EdgeInsets.only(top: 18, left: 16, right: 16, bottom: 16),
child: Text(
'会议中(${state.users.value.length}',
style: TextStyle(
fontSize: 14.sp,
fontWeight: FontWeight.w500,
color: ColorUtil.Color_85_117_242),
),
),
Expanded(
child: ScrollConfiguration(
behavior: CusBehavior(),
child: GetBuilder<MeetingMainLogic>(builder: (controll) {
return ListView.builder(
itemBuilder: (context, index) {
return Container(
width: double.infinity,
margin: EdgeInsets.only(bottom: index == 9 ? 18 : 0),
child: Column(
children: [
Container(
padding:
const EdgeInsets.only(left: 16, right: 16),
child: Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
Container(
decoration: BoxDecoration(
borderRadius:
BorderRadius.circular(100),
color: ColorUtil.Color_85_117_242),
margin: const EdgeInsets.only(right: 8),
width: 36.w,
height: 36.h,
alignment: Alignment.center,
child: Text(
state.users.value[index].userName
.length >
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(
fontSize: 12.sp,
color:
ColorUtil.Color_244_244_244),
),
),
Text(
state.users.value[index].userName,
style: TextStyle(
fontSize: 14.sp,
fontWeight: FontWeight.w600,
color: ColorUtil.Color_243_243_243),
),
SizedBox(width: 8.w),
Visibility(
visible:
state.users.value[index].roleId ==
"1" ||
state.users.value[index]
.roleId ==
"3"
? true
: false,
child: Text(
'主持人',
style: TextStyle(
fontSize: 12.sp,
fontWeight: FontWeight.w500,
color: ColorUtil.Color_2_177_136),
),
),
Visibility(
visible:
state.users.value[index].roleId ==
"2" &&
state.users.value[index]
.isRoomManager ==
true
? true
: false,
child: Text(
'发言人',
style: TextStyle(
fontSize: 12.sp,
fontWeight: FontWeight.w500,
color: ColorUtil.Color_2_177_136),
),
)
],
),
Row(
children: [
Container(
child: Image.asset(
'assets/images/meeting_main_share_currently.png',
width: 17.w,
height: 17.h,
),
),
Container(
margin: const EdgeInsets.only(left: 12),
child: Image.asset(
state.users.value[index].enableMicr ==
true
? 'assets/images/meeting_main_microphone_default.png'
: 'assets/images/meeting_main_microphone_close.png',
width: 17.w,
height: 17.h,
),
),
Container(
margin: const EdgeInsets.only(left: 12),
child: Image.asset(
state.users.value[index]
.enableCamera ==
true
? 'assets/images/meeting_main_camera_default.png'
: 'assets/images/meeting_main_camera_close.png',
width: 17.w,
height: 17.h,
),
)
],
)
],
),
),
Container(
width: double.infinity,
height: 0.5.h,
margin:
const EdgeInsets.only(top: 12, bottom: 12),
color: ColorUtil.Color_49_47_47,
)
],
),
);
},
itemCount: state.users.value.length,
);
})),
)
],
),
);
}
/// 聊天底部弹窗
Widget chatBottomSheet(BuildContext context) {
return Container(
height: 500.h,
color: ColorUtil.Color_35_35_35,
padding:
EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
padding: const EdgeInsets.only(left: 16, right: 16),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
SizedBox(width: 12.w),
Container(
height: 50.h,
alignment: Alignment.center,
child: Text(
'聊天',
style: TextStyle(
fontSize: 14.sp,
fontWeight: FontWeight.w500,
color: ColorUtil.Color_238_238_238),
),
),
GestureDetector(
child: Image.asset(
'assets/images/meeting_main_close_permission.png',
width: 12.w,
height: 12.h,
),
onTap: () {
Get.back();
},
)
],
),
),
Container(
width: double.infinity,
height: 0.5.h,
color: ColorUtil.Color_49_47_47,
),
Expanded(
child: ScrollConfiguration(
behavior: CusBehavior(),
child: GetBuilder<MeetingMainLogic>(builder: (controll) {
return ListView.builder(
controller: state.chatController,
itemBuilder: (context, index) {
return state.meetingRoomMsgs.value[index].source == 0
? chartItemToOthers(index)
: chartItemToOwn(index);
},
itemCount: state.meetingRoomMsgs.value.length,
);
})),
),
Container(
width: double.infinity,
height: 60.h,
color: ColorUtil.Color_28_28_28,
padding: const EdgeInsets.all(6),
child: Container(
padding: const EdgeInsets.all(12),
decoration: const BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(6)),
color: ColorUtil.Color_53_53_53,
),
child: TextField(
controller: state.sendMsgController,
style: TextStyle(
fontSize: 14.sp, color: ColorUtil.Color_235_235_235),
decoration: InputDecoration(
contentPadding: const EdgeInsets.all(0),
border:
const OutlineInputBorder(borderSide: BorderSide.none),
hintText: '请输入内容...',
hintStyle: TextStyle(
color: ColorUtil.Color_235_235_235, fontSize: 14.sp)),
onSubmitted: (value) {
if (value.isNotEmpty) {
logic.sendMsg(value);
state.sendMsgController.text = "";
} else {
ToastUtils.showError("请输入内容");
}
},
),
),
)
],
),
);
}
/// 聊天浮层-其他人消息
Widget chartItemToOthers(int index) {
return Container(
width: double.infinity,
padding: const EdgeInsets.only(left: 16, right: 16),
margin: EdgeInsets.only(top: 18, bottom: index == 3 ? 18 : 6),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(99),
color: ColorUtil.Color_85_117_242),
width: 50.w,
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(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
margin: const EdgeInsets.only(left: 6),
child: Text(
state.meetingRoomMsgs.value[index].userName,
style: TextStyle(
fontSize: 10.sp, color: ColorUtil.Color_202_202_202),
),
),
Container(
margin: const EdgeInsets.only(left: 6, top: 6, right: 16),
padding: const EdgeInsets.only(
left: 18, right: 18, top: 10, bottom: 10),
decoration: const BoxDecoration(
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(99),
topRight: Radius.circular(99),
bottomRight: Radius.circular(99)),
color: ColorUtil.Color_53_53_53,
),
child: Text(
state.meetingRoomMsgs.value[index].message,
style: TextStyle(
fontSize: 12.sp, color: ColorUtil.Color_235_235_235),
),
)
],
))
],
),
);
}
/// 聊天浮层-自己消息
Widget chartItemToOwn(int index) {
return Container(
width: double.infinity,
padding: const EdgeInsets.only(left: 16, right: 16),
margin: EdgeInsets.only(top: 18, bottom: index == 3 ? 18 : 6),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Container(
margin: const EdgeInsets.only(right: 6),
child: Text(
state.meetingRoomMsgs.value[index].userName,
style: TextStyle(
fontSize: 10.sp, color: ColorUtil.Color_202_202_202),
),
),
Container(
margin: const EdgeInsets.only(left: 16, top: 6, right: 6),
padding: const EdgeInsets.only(
left: 18, right: 18, top: 10, bottom: 10),
decoration: const BoxDecoration(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(99),
bottomLeft: Radius.circular(99),
bottomRight: Radius.circular(99)),
color: ColorUtil.Color_85_117_242,
),
child: Text(
state.meetingRoomMsgs.value[index].message,
style: TextStyle(
fontSize: 12.sp, color: ColorUtil.Color_235_235_235),
),
)
],
)),
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(99),
color: ColorUtil.Color_85_117_242),
width: 50.w,
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),
),
)
],
),
);
}
/// 自己视频预览悬浮窗
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,
setupMode: VideoViewSetupMode.videoViewSetupAdd),
),
)
: 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: Text(
UserStore.to.userInfoEntity.value!.userName,
style: TextStyle(
fontSize: 10.sp, color: ColorUtil.Color_185_184_184),
),
)
],
),
)
],
);
}
/// pageview对应页数的界面
Widget returnPage(int position) {
var pageList = [];
/// 大屏
pageList.add(Stack(
alignment: Alignment.center,
children: [
state.remoteUid.value != ""
? AgoraVideoView(
controller: VideoViewController(
rtcEngine: state.rctEngine.value!,
canvas: VideoCanvas(
uid: int.tryParse(state.remoteUid.value),
setupMode: VideoViewSetupMode.videoViewSetupAdd,
renderMode: state.remoteUid.value.length == 9 ? RenderModeType.renderModeFit : RenderModeType.renderModeHidden),
),
)
: Container(
width: double.infinity,
color: ColorUtil.Color_57_57_57,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.asset(
'assets/images/metting_main_no_person.png',
width: 138.w,
height: 144.h,
),
const SizedBox(height: 20),
Text(
'主持人正在赶来的路上...',
style: TextStyle(
color: ColorUtil.Color_255_255_255, fontSize: 14.sp),
)
],
),
),
Positioned(
top: 16,
right: 16,
child: Container(
height: 30,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8),
color: ColorUtil.Color_0_0_0_96),
padding: const EdgeInsets.only(left: 12, right: 12),
child: Row(
children: [
Text(
'正在讲话:',
style: TextStyle(
fontSize: 10.sp, color: ColorUtil.Color_185_184_184),
),
SizedBox(
width: 20.w,
height: 20.h,
child: LiquidCustomProgressIndicator(
value: state.spokesmanVolume.value,
valueColor: const AlwaysStoppedAnimation(
ColorUtil.Color_2_177_136),
backgroundColor: ColorUtil.Color_255_255_255,
direction: Axis.vertical,
shapePath: ViewSvgPath.getMicrpphonePath()),
),
Text(
state.spokesman.value,
style: TextStyle(
fontSize: 10.sp, color: ColorUtil.Color_185_184_184),
)
],
),
),
),
],
));
/// gridview
pageList.add(Container(
color: ColorUtil.Color_57_57_57,
child: GridView.builder(
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2, childAspectRatio: 0.8, crossAxisSpacing: 0),
itemCount: state.cacheUsers.value.length,
itemBuilder: (BuildContext ctx, index) {
return Stack(
children: [
state.cacheUsers.value[index].enableCamera == true
? state.cacheUsers.value[index].uid ==
UserStore.to.userInfoEntity.value!.uid
? AgoraVideoView(
controller: VideoViewController(
rtcEngine: state.rctEngine.value!,
canvas: const VideoCanvas(
uid: 0,
setupMode:
VideoViewSetupMode.videoViewSetupAdd)),
)
: AgoraVideoView(
controller: VideoViewController.remote(
rtcEngine: state.rctEngine.value!,
canvas: VideoCanvas(
uid: int.tryParse(
state.cacheUsers.value[index].uid),
setupMode:
VideoViewSetupMode.videoViewSetupAdd),
connection: RtcConnection(
channelId: state.roomNumber.value),
),
)
: Container(
color: ColorUtil.Color_16_19_13,
child: SizedBox(
width: double.infinity,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.asset(
'assets/images/metting_main_no_person.png',
width: 78.w,
height: 84.h,
),
const SizedBox(height: 12),
Text(
'该用户未开启摄像头...',
style: TextStyle(
color: ColorUtil.Color_255_255_255,
fontSize: 10.sp),
)
],
),
),
),
Positioned(
left: 4,
bottom: 4,
child: Row(
children: [
Visibility(
visible: state.cacheUsers.value[index].uid ==
UserStore.to.userInfoEntity.value!.uid,
child: Image.asset(
'assets/images/meeting_main_own.png',
width: 24.w,
height: 24.h,
),
),
Container(
height: 20,
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: state.cacheUsers.value[index].enableMicr == true
? Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
SizedBox(
width: 20.w,
height: 20.h,
child: LiquidCustomProgressIndicator(
value: state.cacheUsers.value[index]
.volume ??
0.0,
valueColor:
const AlwaysStoppedAnimation(
ColorUtil.Color_2_177_136),
backgroundColor:
ColorUtil.Color_255_255_255,
direction: Axis.vertical,
shapePath:
ViewSvgPath.getMicrpphonePath()),
),
Text(
state.cacheUsers.value[index].userName,
style: TextStyle(
fontSize: 12.sp,
color: ColorUtil.Color_255_255_255),
)
],
)
: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Image.asset(
'assets/images/meeting_main_microphone_open.png',
width: 20.w,
height: 20.h,
),
Text(
state.cacheUsers.value[index].userName,
style: TextStyle(
fontSize: 12.sp,
color: ColorUtil.Color_255_255_255),
)
],
),
)
],
),
)
],
);
}),
));
return pageList[position];
}
}