diff --git a/lib/modules/meeting/views/speaker_all_bottom_sheet.dart b/lib/modules/meeting/views/speaker_all_bottom_sheet.dart new file mode 100644 index 000000000..b2b8d553e --- /dev/null +++ b/lib/modules/meeting/views/speaker_all_bottom_sheet.dart @@ -0,0 +1,353 @@ +import 'package:common_utils/common_utils.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:get/get.dart'; + +import '../controllers/meeting_details_controller.dart'; + +class SpeakerAllBottomSheet extends GetView { + const SpeakerAllBottomSheet({super.key}); + + @override + Widget build(BuildContext context) { + List dataList = _getDataList(); + + return Padding( + padding: EdgeInsets.only( + left: 12.w, + right: 12.w, + bottom: MediaQuery.of(context).viewInsets.bottom, + ), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Container( + padding: EdgeInsets.symmetric(vertical: 10.w), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + '命名发言者', + style: TextStyle( + fontSize: 16.sp, + color: Colors.black87, + fontWeight: FontWeight.bold, + ), + ), + GestureDetector( + onTap: () => Get.back(), + child: Container( + width: 26.w, + height: 26.w, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(26.r), + ), + child: Icon( + Icons.close, + size: 18.w, + color: Colors.grey[400], + ), + ), + ) + ], + ), + ), + Divider( + height: 1, + color: Colors.grey[300], + ), + Container( + constraints: BoxConstraints( + maxHeight: + 1.sh - 240.w - MediaQuery.of(context).viewInsets.bottom, + ), + child: ListView.builder( + itemCount: dataList.length, + shrinkWrap: true, + itemBuilder: (BuildContext context, int index) { + TextEditingController textController = TextEditingController(); + Map item = dataList[index]; + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + margin: EdgeInsets.only(top: 15.w), + alignment: Alignment.center, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(12.r), + ), + child: TextField( + controller: textController, + style: TextStyle( + fontSize: 16.sp, + color: Colors.black87, + letterSpacing: 0, + height: 1.4, + ), + decoration: InputDecoration( + hintText: item['speaker'], + hintStyle: TextStyle( + fontSize: 16.sp, + color: Colors.grey[400], + letterSpacing: 0, + height: 1.4, + ), + isDense: true, + fillColor: Colors.transparent, + border: InputBorder.none, + contentPadding: EdgeInsets.symmetric( + horizontal: 10.w, + vertical: 12.w, + ), + ), + ), + ), + Padding( + padding: EdgeInsets.symmetric( + horizontal: 10.w, + vertical: 8.w, + ), + child: Row( + children: [ + Text( + '总计', + style: TextStyle( + fontSize: 12.sp, + color: Colors.grey, + ), + ), + 5.horizontalSpace, + Text( + '${item['totaltime'] / 1000}s', + style: TextStyle( + fontSize: 12.sp, + color: Colors.black87, + ), + ), + ], + ), + ), + ...List.generate( + item['list'].length, + (int idx) { + Map data = item['list'][idx]; + return Padding( + padding: EdgeInsets.symmetric(horizontal: 10.w), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Icon( + Icons.play_circle, + color: Colors.red[400], + size: 15.w, + ), + 2.horizontalSpace, + Text( + DateUtil.formatDateMs( + data['starttime'], + format: 'HH:mm:ss', + isUtc: true, + ), + style: TextStyle( + color: Colors.grey, + fontSize: 12.sp, + ), + ), + Padding( + padding: + EdgeInsets.symmetric(horizontal: 2.w), + child: Text( + '-', + style: TextStyle( + color: Colors.grey, + fontSize: 12.sp, + ), + ), + ), + Text( + DateUtil.formatDateMs( + data['endtime'], + format: 'HH:mm:ss', + isUtc: true, + ), + style: TextStyle( + color: Colors.grey, + fontSize: 12.sp, + ), + ), + 5.horizontalSpace, + Text( + '${(data['endtime'] - data['starttime']) / 1000}s', + style: TextStyle( + color: Colors.black54, + fontSize: 12.sp, + ), + ), + ], + ), + Padding( + padding: EdgeInsets.symmetric(vertical: 8.w), + child: Text( + data['content'], + overflow: TextOverflow.ellipsis, + maxLines: 2, + style: TextStyle( + color: Colors.grey[700], + fontSize: 12.sp, + ), + ), + ), + ], + ), + ); + }, + ), + if (item['isOmit']) + Padding( + padding: + EdgeInsets.only(left: 10.w, top: 5.w, bottom: 8.w), + child: Row( + children: List.generate( + 6, + (int idx) => Container( + width: 3.w, + height: 3.w, + margin: EdgeInsets.only(right: 3.w), + decoration: BoxDecoration( + color: Colors.grey[700], + borderRadius: BorderRadius.circular(3.r), + ), + ), + ), + ), + ), + Padding( + padding: EdgeInsets.only(top: 7.w), + child: _separator(), + ), + ], + ); + }, + ), + ), + Padding( + padding: EdgeInsets.symmetric(vertical: 5.w), + child: Text( + '总结的发言者将自动更新', + style: TextStyle( + fontSize: 14.sp, + color: Colors.grey[600], + ), + ), + ), + Padding( + padding: EdgeInsets.only(bottom: 20.w), + child: Row( + children: [ + Expanded( + child: GestureDetector( + onTap: () => Get.back(), + child: Container( + height: 48.w, + alignment: Alignment.center, + decoration: BoxDecoration( + color: Colors.grey[300], + borderRadius: BorderRadius.circular(12.r), + ), + child: Text( + '取消', + style: TextStyle( + fontSize: 16.sp, + color: Colors.black, + ), + ), + ), + ), + ), + 10.horizontalSpace, + Expanded( + child: GestureDetector( + onTap: () {}, + child: Container( + height: 48.w, + alignment: Alignment.center, + decoration: BoxDecoration( + color: Colors.black, + borderRadius: BorderRadius.circular(12.r), + ), + child: Text( + '确认', + style: TextStyle( + fontSize: 16.sp, + color: Colors.white, + ), + ), + ), + ), + ), + ], + ), + ), + ], + ), + ); + } + + Widget _separator() { + return LayoutBuilder( + builder: (BuildContext context, BoxConstraints constraints) { + final boxWidth = constraints.constrainWidth(); + const dashWidth = 2.0; + const dashHeight = 1.0; + final dashCount = (boxWidth / (2 * dashWidth)).floor(); + return Flex( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + direction: Axis.horizontal, + children: List.generate(dashCount, (_) { + return SizedBox( + width: dashWidth, + height: dashHeight, + child: DecoratedBox( + decoration: BoxDecoration(color: Colors.grey[300]), + ), + ); + }), + ); + }, + ); + } + + List _getDataList() { + List textList = controller.textList; + List dataList = []; + for (var item in textList) { + Map? foundElement = dataList.firstWhere( + (element) => element['speaker'] == item['speaker'], + orElse: () => null, + ); + if (foundElement != null) { + int time = item['endtime'] - item['starttime']; + foundElement['totaltime'] = foundElement['totaltime'] + time; + if (!foundElement['isOmit']) { + if (foundElement['list'].length < 2) { + foundElement['list'].add(Map.from(item)); + } else { + foundElement['isOmit'] = true; + } + } + } else { + dataList.add({ + 'speaker': item['speaker'], + 'totaltime': item['endtime'] - item['starttime'], + 'isOmit': false, + 'list': [Map.from(item)], + }); + } + } + return dataList; + } +} diff --git a/lib/modules/meeting/views/speech_tab.dart b/lib/modules/meeting/views/speech_tab.dart index 8a586f27d..f7a4bb0f3 100644 --- a/lib/modules/meeting/views/speech_tab.dart +++ b/lib/modules/meeting/views/speech_tab.dart @@ -4,6 +4,7 @@ import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; import '../controllers/meeting_details_controller.dart'; +import 'speaker_all_bottom_sheet.dart'; import 'speaker_bottom_sheet.dart'; class SpeechTab extends GetView { @@ -200,7 +201,7 @@ class SpeechTab extends GetView { ), ), builder: (BuildContext context) { - return Container(); + return const SpeakerAllBottomSheet(); }, ); }, diff --git a/lib/modules/meeting/views/summary_tab.dart b/lib/modules/meeting/views/summary_tab.dart index ed3a49437..d663ee748 100644 --- a/lib/modules/meeting/views/summary_tab.dart +++ b/lib/modules/meeting/views/summary_tab.dart @@ -5,6 +5,7 @@ import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; import '../controllers/meeting_details_controller.dart'; +import 'speaker_all_bottom_sheet.dart'; class SummaryTab extends GetView { const SummaryTab({super.key}); @@ -168,7 +169,7 @@ class SummaryTab extends GetView { ), ), builder: (BuildContext context) { - return Container(); + return const SpeakerAllBottomSheet(); }, ); },