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; } }