diff --git a/lib/modules/meeting/controllers/meeting_details_controller.dart b/lib/modules/meeting/controllers/meeting_details_controller.dart index dbf05cccf..8200c349c 100644 --- a/lib/modules/meeting/controllers/meeting_details_controller.dart +++ b/lib/modules/meeting/controllers/meeting_details_controller.dart @@ -176,12 +176,6 @@ class MeetingDetailsController extends GetxController } } - void speakerCreate() async { - EasyLoading.show(); - await _audioSpeaker(); - EasyLoading.dismiss(); - } - void summaryCreate() async { EasyLoading.show(); if (meetingDetails.value.tasktype != 1) { diff --git a/lib/modules/meeting/views/generate_bottom_sheet.dart b/lib/modules/meeting/views/generate_bottom_sheet.dart new file mode 100644 index 000000000..c23066b17 --- /dev/null +++ b/lib/modules/meeting/views/generate_bottom_sheet.dart @@ -0,0 +1,392 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:get/get.dart'; + +import '../controllers/meeting_details_controller.dart'; +import 'record_language_bottom_sheet.dart'; + +class GenerateBottomSheet extends StatefulWidget { + const GenerateBottomSheet({super.key}); + + @override + State createState() => _GenerateBottomSheetState(); +} + +class _GenerateBottomSheetState extends State { + final _controller = Get.find(); + + bool _isSpeaker = true; + String _languageText = '中文普通话(简体)'; + String _language = 'zh-CN'; + + int _templateId = 0; + + @override + Widget build(BuildContext context) { + return Column( + mainAxisSize: MainAxisSize.min, + children: [ + Container( + padding: EdgeInsets.symmetric(horizontal: 12.w, vertical: 10.w), + child: Row( + children: [ + Icon( + Icons.audio_file_outlined, + color: Colors.grey, + size: 32.w, + ), + 5.horizontalSpace, + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + _controller.meetingData.value.title, + style: TextStyle( + fontSize: 16.sp, + color: Colors.black87, + ), + ), + Text( + '${_controller.meetingData.value.seconds}s', + style: TextStyle( + fontSize: 12.sp, + color: Colors.grey, + ), + ), + ], + ), + ), + 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], + ), + ), + ) + ], + ), + ), + Container( + padding: EdgeInsets.symmetric(horizontal: 12.w), + margin: EdgeInsets.only(bottom: 10.w), + child: Divider( + height: 1, + color: Colors.grey[300], + ), + ), + Padding( + padding: EdgeInsets.symmetric(horizontal: 12.w, vertical: 10.w), + child: Row( + children: [ + Expanded( + child: Text( + '选择总结模版', + style: TextStyle( + fontSize: 14.sp, + color: Colors.black87, + ), + ), + ), + Row( + children: [ + Text( + '查看全部', + style: TextStyle( + fontSize: 12.sp, + color: Colors.grey, + ), + ), + const Icon( + Icons.keyboard_arrow_right, + color: Colors.grey, + ) + ], + ), + ], + ), + ), + Container( + height: 130.w, + margin: EdgeInsets.only(bottom: 16.w), + child: ListView.builder( + itemCount: 10, + scrollDirection: Axis.horizontal, + padding: EdgeInsets.symmetric(horizontal: 4.w), + itemBuilder: (BuildContext context, int index) { + return _item(); + }, + ), + ), + Container( + margin: EdgeInsets.symmetric(horizontal: 12.w), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8.r), + ), + child: Column( + children: [ + _row( + '区分说话人', + widget: Transform.scale( + scale: 0.8, + alignment: Alignment.centerRight, + child: Switch( + value: _isSpeaker, + onChanged: (bool value) { + setState(() { + _isSpeaker = value; + }); + }, + ), + ), + ), + _row( + '录音语言', + value: _languageText, + isBorder: false, + onTap: () { + showModalBottomSheet( + context: context, + isScrollControlled: true, + backgroundColor: Colors.grey[100], + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.vertical( + top: Radius.circular(12.r), + ), + ), + builder: (BuildContext context) { + return RecordLanguageBottomSheet(_language); + }, + ).then((value) { + if (value != null) { + setState(() { + _languageText = value['name']; + _language = value['value']; + }); + } + }); + }, + ), + ], + ), + ), + Padding( + padding: EdgeInsets.symmetric(horizontal: 12.w, vertical: 20.w), + child: GestureDetector( + onTap: () { + Get.back(); + // _controller.summaryCreate(); + }, + 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 _item() { + return Container( + width: 200.w, + margin: EdgeInsets.symmetric(horizontal: 8.w), + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(14.w), + ), + child: Stack( + children: [ + Container( + padding: EdgeInsets.all(5.w), + decoration: const BoxDecoration( + gradient: LinearGradient( + colors: [Colors.blue, Colors.pinkAccent], + begin: Alignment.centerLeft, + end: Alignment.centerRight, + ), + ), + child: Container( + width: double.infinity, + padding: EdgeInsets.all(10.w), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(10.w), + color: Colors.white, + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: EdgeInsets.only(top: 5.w), + child: Icon( + Icons.perm_phone_msg, + color: Colors.orange, + size: 30.w, + ), + ), + Padding( + padding: EdgeInsets.symmetric(vertical: 10.w), + child: Text( + '会议纪要', + style: TextStyle( + fontSize: 16.sp, + color: Colors.black87, + fontWeight: FontWeight.bold, + ), + ), + ), + Wrap( + children: [ + Container( + padding: EdgeInsets.symmetric( + horizontal: 5.w, vertical: 2.w), + decoration: BoxDecoration( + color: Colors.grey[200], + borderRadius: BorderRadius.circular(4.r), + ), + child: Text( + '主题', + style: TextStyle( + fontSize: 10.sp, + color: Colors.grey[600], + ), + ), + ), + ], + ), + // Text( + // '主题主题主题主题主题主题主题主题主题主题', + // overflow: TextOverflow.ellipsis, + // style: TextStyle( + // fontSize: 12.sp, + // color: Colors.grey[600], + // ), + // ), + ], + ), + ), + ), + Positioned( + top: 0, + left: 0, + child: Container( + padding: EdgeInsets.symmetric(horizontal: 5.w, vertical: 1.w), + decoration: BoxDecoration( + color: Colors.blue, + borderRadius: BorderRadius.only( + topLeft: Radius.circular(12.w), + bottomRight: Radius.circular(4.w), + ), + ), + child: Text( + '上次使用', + style: TextStyle( + color: Colors.white, + fontSize: 12.sp, + fontWeight: FontWeight.bold, + ), + ), + ), + ), + Positioned( + right: -18.w, + bottom: -18.w, + child: Container( + width: 40.w, + height: 40.w, + padding: EdgeInsets.all(2.w), + alignment: Alignment.topLeft, + decoration: BoxDecoration( + color: Colors.pinkAccent, + borderRadius: BorderRadius.circular(40.r), + ), + child: Icon( + Icons.check, + color: Colors.white, + size: 18.w, + ), + ), + ), + ], + ), + ); + } + + Widget _row( + String title, { + String? value, + Widget? widget, + bool isBorder = true, + Function()? onTap, + }) { + return GestureDetector( + onTap: onTap, + child: Padding( + padding: EdgeInsets.only(left: 15.w), + child: Container( + height: 46.w, + padding: EdgeInsets.only(right: 10.w), + decoration: BoxDecoration( + border: isBorder + ? Border( + bottom: BorderSide( + color: Colors.grey[300]!, + ), + ) + : null, + ), + child: Row( + children: [ + Expanded( + child: Text( + title, + style: TextStyle( + fontSize: 14.sp, + color: Colors.black87, + ), + ), + ), + widget ?? + Row( + children: [ + Text( + value ?? '', + style: TextStyle( + fontSize: 12.sp, + color: Colors.grey, + ), + ), + const Icon( + Icons.keyboard_arrow_right, + color: Colors.grey, + ) + ], + ), + ], + ), + ), + ), + ); + } +} diff --git a/lib/modules/meeting/views/record_language_bottom_sheet.dart b/lib/modules/meeting/views/record_language_bottom_sheet.dart new file mode 100644 index 000000000..217613373 --- /dev/null +++ b/lib/modules/meeting/views/record_language_bottom_sheet.dart @@ -0,0 +1,137 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:get/get.dart'; + +class RecordLanguageBottomSheet extends StatefulWidget { + final String language; + + const RecordLanguageBottomSheet(this.language, {super.key}); + + @override + State createState() => + _RecordLanguageBottomSheetState(); +} + +class _RecordLanguageBottomSheetState extends State { + final List _languages = [ + {'name': '中文普通话(简体)', 'value': 'zh-CN'}, + {'name': '粤语', 'value': 'cant'}, + {'name': '四川话', 'value': 'sc'}, + {'name': '上海话', 'value': 'zh_shanghai'}, + {'name': '英文', 'value': 'en-US'}, + {'name': '日语', 'value': 'ja-JP'}, + {'name': '韩语', 'value': 'ko-KR'}, + {'name': '法语', 'value': 'fr-FR'}, + {'name': '西班牙语', 'value': 'es-MX'}, + {'name': '葡萄牙语', 'value': 'pt-BR'}, + {'name': '印尼语', 'value': 'id-ID'}, + ]; + + @override + Widget build(BuildContext context) { + return Padding( + padding: EdgeInsets.symmetric(horizontal: 12.w), + 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( + margin: EdgeInsets.symmetric(vertical: 20.w), + constraints: BoxConstraints( + maxHeight: 1.sh - 180.w, + ), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8.r), + ), + child: ListView.builder( + itemCount: _languages.length, + shrinkWrap: true, + itemBuilder: (BuildContext context, int index) { + Map data = _languages[index]; + return _item(index, data); + }, + ), + ), + ], + ), + ); + } + + Widget _item(int index, Map data) { + return GestureDetector( + onTap: () { + Get.back(result: data); + }, + child: Padding( + padding: EdgeInsets.only(left: 15.w), + child: Container( + height: 46.w, + padding: EdgeInsets.only(right: 10.w), + decoration: BoxDecoration( + border: index != 0 + ? Border( + top: BorderSide( + color: Colors.grey[300]!, + ), + ) + : null, + ), + child: Row( + children: [ + Expanded( + child: Text( + data['name'], + style: TextStyle( + fontSize: 14.sp, + color: Colors.black87, + ), + ), + ), + if (widget.language == data['value']) + const Icon( + Icons.check, + color: Colors.black87, + ), + ], + ), + ), + ), + ); + } +} diff --git a/lib/modules/meeting/views/speech_tab.dart b/lib/modules/meeting/views/speech_tab.dart index 1d14f57ef..0e65a49c8 100644 --- a/lib/modules/meeting/views/speech_tab.dart +++ b/lib/modules/meeting/views/speech_tab.dart @@ -5,6 +5,7 @@ import 'package:get/get.dart'; import 'package:lottie/lottie.dart'; import '../controllers/meeting_details_controller.dart'; +import 'generate_bottom_sheet.dart'; import 'speaker_all_bottom_sheet.dart'; import 'speaker_bottom_sheet.dart'; @@ -290,7 +291,21 @@ class SpeechTab extends GetView { child: _button( Icons.auto_awesome, '生成', - controller.speakerCreate, + () { + showModalBottomSheet( + context: context, + isScrollControlled: true, + backgroundColor: Colors.grey[100], + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.vertical( + top: Radius.circular(12.r), + ), + ), + builder: (BuildContext context) { + return const GenerateBottomSheet(); + }, + ); + }, ), ), ], diff --git a/lib/modules/meeting/views/summary_tab.dart b/lib/modules/meeting/views/summary_tab.dart index b4eb594d2..4da336ef9 100644 --- a/lib/modules/meeting/views/summary_tab.dart +++ b/lib/modules/meeting/views/summary_tab.dart @@ -6,6 +6,7 @@ import 'package:get/get.dart'; import '../../../data/services/db/sqflite_api.dart'; import '../controllers/meeting_details_controller.dart'; +import 'generate_bottom_sheet.dart'; import 'speaker_all_bottom_sheet.dart'; class SummaryTab extends StatefulWidget { @@ -318,7 +319,21 @@ class _SummaryTabState extends State { child: _button( Icons.auto_awesome, '生成', - _controller.summaryCreate, + () { + showModalBottomSheet( + context: context, + isScrollControlled: true, + backgroundColor: Colors.grey[100], + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.vertical( + top: Radius.circular(12.r), + ), + ), + builder: (BuildContext context) { + return const GenerateBottomSheet(); + }, + ); + }, ), ), ],