3 changed files with 357 additions and 2 deletions
@ -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<MeetingDetailsController> { |
|||
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; |
|||
} |
|||
} |
|||
Loading…
Reference in new issue