本地预览悬浮窗
This commit is contained in:
parent
5d194ad054
commit
44c789e2f1
|
|
@ -2,11 +2,8 @@ import 'package:flutter/material.dart';
|
|||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_screenutil/flutter_screenutil.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 '../../routes/app_routes.dart';
|
||||
import '../../utils/color_util.dart';
|
||||
import 'login_logic.dart';
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'package:agora_rtc_engine/agora_rtc_engine.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:signalr_core/signalr_core.dart';
|
||||
|
|
@ -33,6 +34,7 @@ class MeetingMainLogic extends GetxController with RequestToolMixin{
|
|||
@override
|
||||
void onClose() {
|
||||
super.onClose();
|
||||
state.floating.value?.close();
|
||||
state.memberNameSearchController.dispose();
|
||||
state.sendMsgController.dispose();
|
||||
stopTime();
|
||||
|
|
@ -311,7 +313,7 @@ class MeetingMainLogic extends GetxController with RequestToolMixin{
|
|||
doHttpSetMicr();
|
||||
});
|
||||
|
||||
/// 单独用户开闭麦回调
|
||||
/// 用户单独开闭麦回调
|
||||
state.hubConnection.value?.on("OperMicr", (e){
|
||||
// var jsonStr = const Utf8Decoder().convert(json.encode(e?[0]).runes.toList());
|
||||
var jsonStr = json.encode(e?[0]);
|
||||
|
|
@ -406,7 +408,7 @@ class MeetingMainLogic extends GetxController with RequestToolMixin{
|
|||
});
|
||||
|
||||
/// ------------------------------------------------------------------------------摄像头或者屏幕相关回调
|
||||
/// 单独用户开闭摄像头回调
|
||||
/// 用户单独开闭摄像头回调
|
||||
state.hubConnection.value?.on("OperCamera", (e){
|
||||
// var jsonStr = const Utf8Decoder().convert(json.encode(e?[0]).runes.toList());
|
||||
var jsonStr = json.encode(e?[0]);
|
||||
|
|
@ -425,7 +427,8 @@ class MeetingMainLogic extends GetxController with RequestToolMixin{
|
|||
muteLocalVideoStream(false);
|
||||
// 开始本地预览
|
||||
startPreview();
|
||||
|
||||
// 打开本地预览悬浮窗
|
||||
state.floating.value?.open(state.context.value!);
|
||||
changePageState(1);
|
||||
}
|
||||
}else{
|
||||
|
|
@ -442,6 +445,8 @@ class MeetingMainLogic extends GetxController with RequestToolMixin{
|
|||
muteLocalVideoStream(true);
|
||||
// 停止本地预览
|
||||
stopPreview();
|
||||
// 关闭本地预览悬浮窗
|
||||
state.floating.value?.close();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import 'dart:async';
|
|||
|
||||
import 'package:agora_rtc_engine/agora_rtc_engine.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter_floating/floating/floating.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:get/get_rx/src/rx_types/rx_types.dart';
|
||||
import 'package:signalr_core/signalr_core.dart';
|
||||
|
|
@ -18,6 +19,8 @@ class MeetingMainState {
|
|||
|
||||
late TextEditingController memberNameSearchController = TextEditingController();
|
||||
late TextEditingController sendMsgController = TextEditingController();
|
||||
late Rx<Floating?> floating = Rx(null);
|
||||
late Rx<BuildContext?> context = Rx(null);
|
||||
|
||||
/// 是否显示会议信息浮层
|
||||
late RxBool isShowMeetingInfoFloatingLayer = false.obs;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,10 @@
|
|||
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';
|
||||
|
|
@ -15,13 +20,35 @@ import 'meeting_main_logic.dart';
|
|||
import 'meeting_main_state.dart';
|
||||
import 'voice/meeting_main_voice_view.dart';
|
||||
|
||||
class MeetingMainPage extends StatelessWidget {
|
||||
MeetingMainPage({Key? key}) : super(key: key);
|
||||
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,
|
||||
|
|
@ -54,20 +81,32 @@ class MeetingMainPage extends StatelessWidget {
|
|||
width: 92.w,
|
||||
child: Row(
|
||||
children: [
|
||||
Image.asset(
|
||||
GestureDetector(
|
||||
child: Image.asset(
|
||||
'assets/images/meeting_main_narrow.png',
|
||||
width: 20.w,
|
||||
height: 20.h,
|
||||
),
|
||||
onTap: (){
|
||||
if(state.floating.value?.isShowing == true){
|
||||
state.floating.value?.close();
|
||||
}else{
|
||||
state.floating.value?.open(context);
|
||||
}
|
||||
},
|
||||
),
|
||||
SizedBox(width: 16.w),
|
||||
GestureDetector(
|
||||
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,
|
||||
height: 20.h,
|
||||
),
|
||||
onTap: (){
|
||||
if(state.communicationMode.value == 1 || state.communicationMode.value == 3){
|
||||
onTap: () {
|
||||
if (state.communicationMode.value == 1 ||
|
||||
state.communicationMode.value == 3) {
|
||||
logic.changeMeetingAudioState(true);
|
||||
}
|
||||
},
|
||||
|
|
@ -85,7 +124,7 @@ class MeetingMainPage extends StatelessWidget {
|
|||
)
|
||||
],
|
||||
),
|
||||
onTap: (){
|
||||
onTap: () {
|
||||
logic.switchCamera();
|
||||
},
|
||||
),
|
||||
|
|
@ -100,7 +139,8 @@ class MeetingMainPage extends StatelessWidget {
|
|||
Row(
|
||||
children: [
|
||||
Text(
|
||||
state.meetingRoomInfo.value?.roomName ?? '',
|
||||
state.meetingRoomInfo.value?.roomName ??
|
||||
'',
|
||||
style: TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 14.sp,
|
||||
|
|
@ -124,7 +164,7 @@ class MeetingMainPage extends StatelessWidget {
|
|||
)
|
||||
],
|
||||
),
|
||||
onTap: (){
|
||||
onTap: () {
|
||||
logic.changeMeetingInfoState(true);
|
||||
},
|
||||
),
|
||||
|
|
@ -148,6 +188,7 @@ class MeetingMainPage extends StatelessWidget {
|
|||
),
|
||||
),
|
||||
SizedBox(width: 16.w),
|
||||
|
||||
/// 退出会议
|
||||
GestureDetector(
|
||||
child: Image.asset(
|
||||
|
|
@ -158,8 +199,7 @@ class MeetingMainPage extends StatelessWidget {
|
|||
onTap: () {
|
||||
Get.bottomSheet(
|
||||
isScrollControlled: true,
|
||||
leaveBottomSheet(context)
|
||||
);
|
||||
leaveBottomSheet(context));
|
||||
},
|
||||
)
|
||||
],
|
||||
|
|
@ -174,12 +214,11 @@ class MeetingMainPage extends StatelessWidget {
|
|||
child: Stack(
|
||||
alignment: Alignment.bottomLeft,
|
||||
children: [
|
||||
|
||||
// 语音
|
||||
Visibility(
|
||||
visible: state.pageState.value == 0,
|
||||
child: MeetingMainVoiceComponent(users: state.cacheUsers.value)
|
||||
),
|
||||
child: MeetingMainVoiceComponent(
|
||||
users: state.cacheUsers.value)),
|
||||
|
||||
// 视频
|
||||
Visibility(
|
||||
|
|
@ -190,13 +229,15 @@ class MeetingMainPage extends StatelessWidget {
|
|||
channelId: state.roomNumber.value,
|
||||
isOpenCamera: state.isOpenCamera.value,
|
||||
remoteUid: state.remoteUid.value,
|
||||
users: state.cacheUsers.value.where((user) => user.enableCamera == true).toList(),
|
||||
onHangUpTap: (){
|
||||
users: state.cacheUsers.value
|
||||
.where((user) =>
|
||||
user.enableCamera == true)
|
||||
.toList(),
|
||||
onHangUpTap: () {
|
||||
logic.hangUpVideo();
|
||||
},
|
||||
)
|
||||
: Container()
|
||||
),
|
||||
: Container()),
|
||||
|
||||
// 共享屏幕
|
||||
Visibility(
|
||||
|
|
@ -207,14 +248,14 @@ class MeetingMainPage extends StatelessWidget {
|
|||
channelId: state.roomNumber.value,
|
||||
remoteUid: state.remoteUid.value,
|
||||
)
|
||||
: Container()
|
||||
),
|
||||
: Container()),
|
||||
|
||||
GestureDetector(
|
||||
child: Container(
|
||||
width: 180.w,
|
||||
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),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: const BorderRadius.only(
|
||||
|
|
@ -224,8 +265,7 @@ class MeetingMainPage extends StatelessWidget {
|
|||
color: ColorUtil.Color_35_35_35_07,
|
||||
border: Border.all(
|
||||
width: 1.w,
|
||||
color: ColorUtil.Color_99_111_158
|
||||
),
|
||||
color: ColorUtil.Color_99_111_158),
|
||||
),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
|
|
@ -249,10 +289,11 @@ class MeetingMainPage extends StatelessWidget {
|
|||
onTap: () {
|
||||
Get.bottomSheet(
|
||||
isScrollControlled: true,
|
||||
chatBottomSheet(context)
|
||||
);
|
||||
Future.delayed(const Duration(milliseconds: 100), () {
|
||||
state.chatController.jumpTo(state.chatController.position.maxScrollExtent);
|
||||
chatBottomSheet(context));
|
||||
Future.delayed(const Duration(milliseconds: 100),
|
||||
() {
|
||||
state.chatController.jumpTo(state
|
||||
.chatController.position.maxScrollExtent);
|
||||
});
|
||||
},
|
||||
)
|
||||
|
|
@ -278,7 +319,8 @@ class MeetingMainPage extends StatelessWidget {
|
|||
? Image.asset(
|
||||
state.isSpeak.value == false
|
||||
? '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_sqfy.png',
|
||||
width: 20.w,
|
||||
|
|
@ -289,21 +331,30 @@ class MeetingMainPage extends StatelessWidget {
|
|||
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,
|
||||
value: state
|
||||
.microphoneVolume.value,
|
||||
valueColor:
|
||||
const AlwaysStoppedAnimation(
|
||||
ColorUtil
|
||||
.Color_2_177_136),
|
||||
backgroundColor:
|
||||
ColorUtil.Color_255_255_255,
|
||||
direction: Axis.vertical,
|
||||
shapePath: ViewSvgPath.getMicrpphonePath()
|
||||
),
|
||||
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 ? "手动静音" : "解除静音",
|
||||
state.isSpeak.value == false
|
||||
? '申请发言'
|
||||
: state.isOpenMicrophone.value == true
|
||||
? "手动静音"
|
||||
: "解除静音",
|
||||
style: TextStyle(
|
||||
fontSize: 12.sp,
|
||||
color: ColorUtil.Color_202_202_202),
|
||||
|
|
@ -311,16 +362,14 @@ class MeetingMainPage extends StatelessWidget {
|
|||
],
|
||||
),
|
||||
onTap: () {
|
||||
if(state.isSpeak.value == false){
|
||||
if (state.isSpeak.value == false) {
|
||||
Get.bottomSheet(
|
||||
isScrollControlled: true,
|
||||
applySpeakPermissionBottomSheet(
|
||||
context)
|
||||
);
|
||||
}else{
|
||||
if(state.isOpenMicrophone.value == false){
|
||||
applySpeakPermissionBottomSheet(context));
|
||||
} else {
|
||||
if (state.isOpenMicrophone.value == false) {
|
||||
logic.setMicrophoneOpen(true);
|
||||
}else{
|
||||
} else {
|
||||
logic.setMicrophoneOpen(false);
|
||||
}
|
||||
}
|
||||
|
|
@ -333,24 +382,30 @@ class MeetingMainPage extends StatelessWidget {
|
|||
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',
|
||||
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.isOpenCamera.value == true ? "关闭视频" : "开启视频",
|
||||
state.isOpenCamera.value == true
|
||||
? "关闭视频"
|
||||
: "开启视频",
|
||||
style: TextStyle(
|
||||
fontSize: 12.sp,
|
||||
color: ColorUtil.Color_202_202_202),
|
||||
)
|
||||
],
|
||||
),
|
||||
onTap: (){
|
||||
if(state.isSpeak.value == true){
|
||||
if(state.isOpenCamera.value == true){
|
||||
onTap: () {
|
||||
if (state.isSpeak.value == true) {
|
||||
if (state.isOpenCamera.value == true) {
|
||||
logic.setCameraOpen(false);
|
||||
}else{
|
||||
} else {
|
||||
logic.setCameraOpen(true);
|
||||
}
|
||||
}
|
||||
|
|
@ -363,7 +418,11 @@ class MeetingMainPage extends StatelessWidget {
|
|||
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',
|
||||
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,
|
||||
),
|
||||
|
|
@ -376,11 +435,11 @@ class MeetingMainPage extends StatelessWidget {
|
|||
)
|
||||
],
|
||||
),
|
||||
onTap: (){
|
||||
if(state.isSpeak.value == true){
|
||||
if(state.isOpenShare.value == true){
|
||||
onTap: () {
|
||||
if (state.isSpeak.value == true) {
|
||||
if (state.isOpenShare.value == true) {
|
||||
logic.setScreenShareOpen(false);
|
||||
}else{
|
||||
} else {
|
||||
logic.setScreenShareOpen(true);
|
||||
}
|
||||
}
|
||||
|
|
@ -448,7 +507,7 @@ class MeetingMainPage extends StatelessWidget {
|
|||
),
|
||||
),
|
||||
),
|
||||
onTap: (){
|
||||
onTap: () {
|
||||
Get.back();
|
||||
Get.back();
|
||||
},
|
||||
|
|
@ -470,7 +529,7 @@ class MeetingMainPage extends StatelessWidget {
|
|||
),
|
||||
),
|
||||
),
|
||||
onTap: (){
|
||||
onTap: () {
|
||||
Get.back();
|
||||
},
|
||||
)
|
||||
|
|
@ -617,7 +676,7 @@ class MeetingMainPage extends StatelessWidget {
|
|||
SizedBox(height: 10.h),
|
||||
GestureDetector(
|
||||
child: Container(
|
||||
padding: const EdgeInsets.only(top:10, bottom: 10),
|
||||
padding: const EdgeInsets.only(top: 10, bottom: 10),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
|
|
@ -637,7 +696,7 @@ class MeetingMainPage extends StatelessWidget {
|
|||
],
|
||||
),
|
||||
),
|
||||
onTap: (){
|
||||
onTap: () {
|
||||
logic.changeMeetingInfoState(false);
|
||||
},
|
||||
)
|
||||
|
|
@ -691,16 +750,18 @@ class MeetingMainPage extends StatelessWidget {
|
|||
/// 音频列表
|
||||
List<Widget> audioList() {
|
||||
List<Widget> audioList = [];
|
||||
audioList.add(
|
||||
GestureDetector(
|
||||
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
|
||||
),
|
||||
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,
|
||||
|
|
@ -709,32 +770,32 @@ class MeetingMainPage extends StatelessWidget {
|
|||
margin: const EdgeInsets.only(top: 14, bottom: 14),
|
||||
)
|
||||
]),
|
||||
onTap: (){
|
||||
onTap: () {
|
||||
logic.setEnableSpeakerphone(1);
|
||||
logic.changeMeetingAudioState(false);
|
||||
},
|
||||
)
|
||||
);
|
||||
audioList.add(
|
||||
GestureDetector(
|
||||
));
|
||||
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
|
||||
),
|
||||
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: (){
|
||||
onTap: () {
|
||||
logic.setEnableSpeakerphone(3);
|
||||
logic.changeMeetingAudioState(false);
|
||||
},
|
||||
)
|
||||
);
|
||||
));
|
||||
return audioList;
|
||||
}
|
||||
|
||||
|
|
@ -769,7 +830,7 @@ class MeetingMainPage extends StatelessWidget {
|
|||
width: 12.w,
|
||||
height: 12.h,
|
||||
),
|
||||
onTap: (){
|
||||
onTap: () {
|
||||
Get.back();
|
||||
},
|
||||
)
|
||||
|
|
@ -813,7 +874,7 @@ class MeetingMainPage extends StatelessWidget {
|
|||
),
|
||||
),
|
||||
),
|
||||
onTap: (){
|
||||
onTap: () {
|
||||
Get.back();
|
||||
},
|
||||
),
|
||||
|
|
@ -836,7 +897,7 @@ class MeetingMainPage extends StatelessWidget {
|
|||
),
|
||||
),
|
||||
),
|
||||
onTap: (){
|
||||
onTap: () {
|
||||
logic.doHttpApplySpeak();
|
||||
Get.back();
|
||||
},
|
||||
|
|
@ -881,7 +942,7 @@ class MeetingMainPage extends StatelessWidget {
|
|||
width: 12.w,
|
||||
height: 12.h,
|
||||
),
|
||||
onTap: (){
|
||||
onTap: () {
|
||||
Get.back();
|
||||
},
|
||||
)
|
||||
|
|
@ -900,8 +961,7 @@ class MeetingMainPage extends StatelessWidget {
|
|||
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),
|
||||
border: Border.all(width: 1.w, color: ColorUtil.Color_70_71_73),
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
|
|
@ -915,18 +975,16 @@ class MeetingMainPage extends StatelessWidget {
|
|||
child: TextField(
|
||||
controller: state.memberNameSearchController,
|
||||
style: TextStyle(
|
||||
fontSize: 14.sp,
|
||||
color: ColorUtil.Color_235_235_235
|
||||
),
|
||||
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),
|
||||
border: const OutlineInputBorder(
|
||||
borderSide: BorderSide.none),
|
||||
hintText: '输入用户名',
|
||||
hintStyle: TextStyle(
|
||||
color: ColorUtil.Color_70_71_73,
|
||||
fontSize: 14.sp)),
|
||||
onSubmitted: (value){
|
||||
color: ColorUtil.Color_70_71_73, fontSize: 14.sp)),
|
||||
onSubmitted: (value) {
|
||||
logic.searchMember(value);
|
||||
},
|
||||
),
|
||||
|
|
@ -945,11 +1003,10 @@ class MeetingMainPage extends StatelessWidget {
|
|||
color: ColorUtil.Color_85_117_242),
|
||||
),
|
||||
),
|
||||
|
||||
Expanded(
|
||||
child: ScrollConfiguration(
|
||||
behavior: CusBehavior(),
|
||||
child: GetBuilder<MeetingMainLogic>(builder: (controll){
|
||||
child: GetBuilder<MeetingMainLogic>(builder: (controll) {
|
||||
return ListView.builder(
|
||||
itemBuilder: (context, index) {
|
||||
return Container(
|
||||
|
|
@ -958,29 +1015,41 @@ class MeetingMainPage extends StatelessWidget {
|
|||
child: Column(
|
||||
children: [
|
||||
Container(
|
||||
padding: const EdgeInsets.only(left: 16, right: 16),
|
||||
padding:
|
||||
const EdgeInsets.only(left: 16, right: 16),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(100),
|
||||
color: ColorUtil.Color_85_117_242
|
||||
),
|
||||
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,
|
||||
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
|
||||
),
|
||||
color:
|
||||
ColorUtil.Color_244_244_244),
|
||||
),
|
||||
),
|
||||
Text(
|
||||
|
|
@ -992,7 +1061,14 @@ class MeetingMainPage extends StatelessWidget {
|
|||
),
|
||||
SizedBox(width: 8.w),
|
||||
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(
|
||||
'主持人',
|
||||
style: TextStyle(
|
||||
|
|
@ -1002,7 +1078,14 @@ class MeetingMainPage extends StatelessWidget {
|
|||
),
|
||||
),
|
||||
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(
|
||||
'发言人',
|
||||
style: TextStyle(
|
||||
|
|
@ -1025,7 +1108,10 @@ class MeetingMainPage extends StatelessWidget {
|
|||
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',
|
||||
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,
|
||||
),
|
||||
|
|
@ -1033,7 +1119,11 @@ class MeetingMainPage extends StatelessWidget {
|
|||
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',
|
||||
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,
|
||||
),
|
||||
|
|
@ -1046,7 +1136,8 @@ class MeetingMainPage extends StatelessWidget {
|
|||
Container(
|
||||
width: double.infinity,
|
||||
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,
|
||||
)
|
||||
],
|
||||
|
|
@ -1055,8 +1146,7 @@ class MeetingMainPage extends StatelessWidget {
|
|||
},
|
||||
itemCount: state.users.value.length,
|
||||
);
|
||||
})
|
||||
),
|
||||
})),
|
||||
)
|
||||
],
|
||||
),
|
||||
|
|
@ -1068,7 +1158,8 @@ class MeetingMainPage extends StatelessWidget {
|
|||
return Container(
|
||||
height: 500.h,
|
||||
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(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
|
|
@ -1095,7 +1186,7 @@ class MeetingMainPage extends StatelessWidget {
|
|||
width: 12.w,
|
||||
height: 12.h,
|
||||
),
|
||||
onTap: (){
|
||||
onTap: () {
|
||||
Get.back();
|
||||
},
|
||||
)
|
||||
|
|
@ -1110,16 +1201,17 @@ class MeetingMainPage extends StatelessWidget {
|
|||
Expanded(
|
||||
child: ScrollConfiguration(
|
||||
behavior: CusBehavior(),
|
||||
child: GetBuilder<MeetingMainLogic>(builder: (controll){
|
||||
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);
|
||||
return state.meetingRoomMsgs.value[index].source == 0
|
||||
? chartItemToOthers(index)
|
||||
: chartItemToOwn(index);
|
||||
},
|
||||
itemCount: state.meetingRoomMsgs.value.length,
|
||||
);
|
||||
})
|
||||
),
|
||||
})),
|
||||
),
|
||||
Container(
|
||||
width: double.infinity,
|
||||
|
|
@ -1135,22 +1227,19 @@ class MeetingMainPage extends StatelessWidget {
|
|||
child: TextField(
|
||||
controller: state.sendMsgController,
|
||||
style: TextStyle(
|
||||
fontSize: 14.sp,
|
||||
color: ColorUtil.Color_235_235_235
|
||||
),
|
||||
fontSize: 14.sp, color: ColorUtil.Color_235_235_235),
|
||||
decoration: InputDecoration(
|
||||
contentPadding: const EdgeInsets.all(0),
|
||||
border: const OutlineInputBorder(borderSide: BorderSide.none),
|
||||
border:
|
||||
const OutlineInputBorder(borderSide: BorderSide.none),
|
||||
hintText: '请输入内容...',
|
||||
hintStyle: TextStyle(
|
||||
color: ColorUtil.Color_235_235_235,
|
||||
fontSize: 14.sp)
|
||||
),
|
||||
onSubmitted: (value){
|
||||
if(value.isNotEmpty){
|
||||
color: ColorUtil.Color_235_235_235, fontSize: 14.sp)),
|
||||
onSubmitted: (value) {
|
||||
if (value.isNotEmpty) {
|
||||
logic.sendMsg(value);
|
||||
state.sendMsgController.text = "";
|
||||
}else{
|
||||
} else {
|
||||
ToastUtils.showError("请输入内容");
|
||||
}
|
||||
},
|
||||
|
|
@ -1163,7 +1252,7 @@ class MeetingMainPage extends StatelessWidget {
|
|||
}
|
||||
|
||||
/// 聊天浮层-其他人消息
|
||||
Widget chartItemToOthers(int index){
|
||||
Widget chartItemToOthers(int index) {
|
||||
return Container(
|
||||
width: double.infinity,
|
||||
padding: const EdgeInsets.only(left: 16, right: 16),
|
||||
|
|
@ -1175,19 +1264,18 @@ class MeetingMainPage extends StatelessWidget {
|
|||
Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(99),
|
||||
color: ColorUtil.Color_85_117_242
|
||||
),
|
||||
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.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
|
||||
),
|
||||
fontSize: 14.sp, color: ColorUtil.Color_244_244_244),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
|
|
@ -1199,13 +1287,11 @@ class MeetingMainPage extends StatelessWidget {
|
|||
child: Text(
|
||||
state.meetingRoomMsgs.value[index].userName,
|
||||
style: TextStyle(
|
||||
fontSize: 10.sp,
|
||||
color: ColorUtil.Color_202_202_202),
|
||||
fontSize: 10.sp, color: ColorUtil.Color_202_202_202),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
margin: const EdgeInsets.only(
|
||||
left: 6, top: 6, right: 16),
|
||||
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(
|
||||
|
|
@ -1218,20 +1304,18 @@ class MeetingMainPage extends StatelessWidget {
|
|||
child: Text(
|
||||
state.meetingRoomMsgs.value[index].message,
|
||||
style: TextStyle(
|
||||
fontSize: 12.sp,
|
||||
color: ColorUtil.Color_235_235_235),
|
||||
fontSize: 12.sp, color: ColorUtil.Color_235_235_235),
|
||||
),
|
||||
)
|
||||
],
|
||||
)
|
||||
)
|
||||
))
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/// 聊天浮层-自己消息
|
||||
Widget chartItemToOwn(int index){
|
||||
Widget chartItemToOwn(int index) {
|
||||
return Container(
|
||||
width: double.infinity,
|
||||
padding: const EdgeInsets.only(left: 16, right: 16),
|
||||
|
|
@ -1249,53 +1333,108 @@ class MeetingMainPage extends StatelessWidget {
|
|||
child: Text(
|
||||
state.meetingRoomMsgs.value[index].userName,
|
||||
style: TextStyle(
|
||||
fontSize: 10.sp,
|
||||
color: ColorUtil.Color_202_202_202),
|
||||
fontSize: 10.sp, color: ColorUtil.Color_202_202_202),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
margin: const EdgeInsets.only(
|
||||
left: 16, top: 6, right: 6),
|
||||
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)
|
||||
),
|
||||
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),
|
||||
fontSize: 12.sp, color: ColorUtil.Color_235_235_235),
|
||||
),
|
||||
)
|
||||
],
|
||||
)
|
||||
),
|
||||
)),
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(99),
|
||||
color: ColorUtil.Color_85_117_242
|
||||
),
|
||||
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.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
|
||||
),
|
||||
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),
|
||||
),
|
||||
)
|
||||
: 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),
|
||||
)
|
||||
],
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ import 'meeting_main_video_logic.dart';
|
|||
import 'meeting_main_video_state.dart';
|
||||
|
||||
class MeetingMainVideoComponent extends StatefulWidget {
|
||||
MeetingMainVideoComponent({super.key,
|
||||
const MeetingMainVideoComponent({super.key,
|
||||
required this.rtcEngine,
|
||||
required this.channelId,
|
||||
required this.isOpenCamera,
|
||||
|
|
@ -115,7 +115,7 @@ class _MeetingMainVideoComponentState extends State<MeetingMainVideoComponent> w
|
|||
),
|
||||
|
||||
/// 右上角小窗
|
||||
Visibility(
|
||||
/*Visibility(
|
||||
visible: widget.isOpenCamera,
|
||||
child: Positioned(
|
||||
top: 58,
|
||||
|
|
@ -156,12 +156,12 @@ class _MeetingMainVideoComponentState extends State<MeetingMainVideoComponent> w
|
|||
color: ColorUtil.Color_0_0_0_96),
|
||||
child: Row(
|
||||
children: [
|
||||
/*Image.asset(
|
||||
*//*Image.asset(
|
||||
'assets/images/meeting_main_microphone_open.png',
|
||||
width: 13.w,
|
||||
height: 14.h,
|
||||
),
|
||||
SizedBox(width: 4.w),*/
|
||||
SizedBox(width: 4.w),*//*
|
||||
Text(
|
||||
UserStore
|
||||
.to.userInfoEntity.value!.userName,
|
||||
|
|
@ -178,7 +178,7 @@ class _MeetingMainVideoComponentState extends State<MeetingMainVideoComponent> w
|
|||
],
|
||||
),
|
||||
),
|
||||
)
|
||||
)*/
|
||||
],
|
||||
),
|
||||
Container(
|
||||
|
|
|
|||
|
|
@ -315,6 +315,14 @@ packages:
|
|||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
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:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
|
|
|||
|
|
@ -79,6 +79,9 @@ dependencies:
|
|||
# 水波效果的进度器
|
||||
liquid_progress_indicator_v2: ^0.5.0
|
||||
|
||||
# 悬浮拖动组件
|
||||
flutter_floating: ^1.0.7
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
sdk: flutter
|
||||
|
|
|
|||
Loading…
Reference in New Issue