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 'package:haptic_feedback/haptic_feedback.dart'; import '../../../core/theme/app_colors.dart'; import '../../../routes/app_routes.dart'; import '../controllers/meeting_controller.dart'; import '../model/meeting_model.dart'; class MeetingView extends GetView { const MeetingView({super.key}); @override Widget build(BuildContext context) { final isDarkMode = Theme.of(context).brightness == Brightness.dark; return PopScope( onPopInvokedWithResult: controller.onPopInvokedWithResult, child: Scaffold( backgroundColor: isDarkMode ? Colors.black : Colors.grey[50], appBar: _buildAppBar(context, isDarkMode), body: Stack( children: [ Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ _buildConnect(isDarkMode), Expanded( child: _buildBody(context, isDarkMode), ), ], ), _buildMicButton(context, isDarkMode), ], ), floatingActionButton: _buildFloatingButtons(), ), ); } Widget _buildConnect(bool isDarkMode) { return GestureDetector( onTap: () { Get.toNamed(Routes.meetingConnect); }, child: Container( padding: EdgeInsets.all(5.w), margin: EdgeInsets.symmetric( horizontal: 12.w, vertical: 10.w, ), decoration: BoxDecoration( color: isDarkMode ? Colors.white.withOpacity(0.05) : Colors.white, borderRadius: BorderRadius.circular(50.w), boxShadow: [ BoxShadow( color: isDarkMode ? Colors.black.withOpacity(0.2) : Colors.black.withOpacity(0.05), blurRadius: 10, offset: const Offset(0, 2), ), ], ), child: Row( mainAxisSize: MainAxisSize.min, children: [ Container( width: 32.w, height: 32.w, decoration: BoxDecoration( color: Colors.black, borderRadius: BorderRadius.circular(50.w), ), child: Icon( Icons.add, color: Colors.white, size: 20.sp, ), ), Padding( padding: EdgeInsets.symmetric(horizontal: 5.w), child: Text( '连接', style: TextStyle( color: isDarkMode ? Colors.white : Colors.black87, fontSize: 14.sp, ), ), ) ], ), ), ); } /// 构建底部中间的录音按钮 Widget _buildMicButton(BuildContext context, bool isDarkMode) { return Positioned( bottom: 20, left: 0, right: 0, child: Center( child: FloatingActionButton( heroTag: "recordAudio", onPressed: () { _showStartsRecordSheet(context, isDarkMode); }, child: const Icon(Icons.mic), ), ), ); } /// 构建右下角的悬浮按钮 Widget _buildFloatingButtons() { return Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.end, children: [ FloatingActionButton( heroTag: "addAudio", onPressed: () { controller.addAudio(); }, child: const Icon(Icons.add), ), ], ); } // 开始录音弹窗 void _showStartsRecordSheet(BuildContext context, bool isDarkMode) { showModalBottomSheet( context: context, isScrollControlled: true, backgroundColor: Colors.transparent, builder: (context) { return Container( decoration: BoxDecoration( color: isDarkMode ? Colors.grey[900] : Colors.white, borderRadius: BorderRadius.vertical(top: Radius.circular(18.w)), ), padding: EdgeInsets.only( left: 0, right: 0, top: 12.w, bottom: MediaQuery.of(context).viewInsets.bottom + 12.w, ), child: Column( mainAxisSize: MainAxisSize.min, children: [ Container( alignment: Alignment.centerLeft, padding: EdgeInsets.symmetric(horizontal: 24.w, vertical: 8.w), child: Text( '开始录音', style: TextStyle( fontSize: 18.sp, fontWeight: FontWeight.bold, color: isDarkMode ? Colors.white : Colors.black87, ), ), ), Divider( height: 1, color: isDarkMode ? Colors.white12 : Colors.grey[200]), // 选项列表 Padding( padding: EdgeInsets.symmetric(horizontal: 16.w, vertical: 8.w), child: Column( children: [ // 现场录音 - 始终可用 _importAudioItem( context, isDarkMode, icon: Image.asset('assets/images/explore.png', width: 32.w, height: 32.w), title: '现场录音', enabled: true, // 始终可用 onTap: () async { Navigator.of(context).pop(); await Get.toNamed(Routes.meetingRecord, arguments: { 'audioTypes': 0, }); controller.addMeetingAudio(); }, ), SizedBox(height: 8.w), // 音、视频录音 - 根据控制器状态禁用 _importAudioItem( context, isDarkMode, icon: Image.asset('assets/images/explore.png', width: 32.w, height: 32.w), title: '音、视频录音', enabled: controller.bleManager.isConnected, // 依赖控制器状态 onTap: controller.bleManager.isConnected ? () async { // 条件启用 Navigator.of(context).pop(); await Get.toNamed(Routes.meetingRecord, arguments: { 'audioTypes': 1, }); controller.addMeetingAudio(); } : null, // 禁用时置空onTap ), SizedBox(height: 8.w), // 通话录音 - 根据控制器状态禁用 _importAudioItem( context, isDarkMode, icon: Row( // ... 图标组合保持不变 ), title: '通话录音', enabled: controller.bleManager.isConnected, // 依赖控制器状态 onTap: controller.bleManager.isConnected ? () async { // 条件启用 Navigator.of(context).pop(); await Get.toNamed(Routes.meetingRecord, arguments: { 'audioTypes': 2, }); controller.addMeetingAudio(); } : null, // 禁用时置空onTap ), ], ), ), SizedBox(height: 8.w), Padding( padding: EdgeInsets.symmetric(horizontal: 20.w), child: Text( '支持导入单文件时长不超过5小时的音频', style: TextStyle( fontSize: 13.sp, color: isDarkMode ? Colors.white54 : Colors.grey[600], ), ), ), SizedBox(height: 16.w), GestureDetector( onTap: () => Navigator.of(context).pop(), child: Icon(Icons.close, size: 32.w, color: Colors.grey), ), SizedBox(height: 8.w), ], ), ); }, ); } // 选项框 (增加enabled参数) Widget _importAudioItem( BuildContext context, bool isDarkMode, { required Widget icon, required String title, required bool enabled, // 新增启用状态参数 required VoidCallback? onTap, // 改为可空回调 }) { return Material( color: Colors.transparent, child: InkWell( borderRadius: BorderRadius.circular(12.w), onTap: onTap, // 禁用时onTap为null child: Container( height: 52.w, padding: EdgeInsets.symmetric(horizontal: 12.w), decoration: BoxDecoration( color: isDarkMode ? Colors.white.withOpacity(enabled ? 0.03 : 0.01) // 调整禁用透明度 : Colors.grey[50]!.withOpacity(enabled ? 1 : 0.5), borderRadius: BorderRadius.circular(12.w), ), child: Row( children: [ // 图标添加透明度效果 Opacity( opacity: enabled ? 1.0 : 0.5, child: icon, ), SizedBox(width: 14.w), Expanded( child: Text( title, style: TextStyle( fontSize: 16.sp, color: isDarkMode ? Colors.white.withOpacity(enabled ? 1 : 0.5) : Colors.black87.withOpacity(enabled ? 1 : 0.5), ), ), ), Icon(Icons.arrow_forward_ios, size: 18.w, color: Colors.grey.withOpacity(enabled ? 1 : 0.5)), ], ), ), ), ); } // 新增右侧弹窗 void _showRightDrawerDialog(BuildContext context, bool isDarkMode) { showGeneralDialog( context: context, barrierDismissible: true, barrierLabel: "rightDrawer", transitionDuration: const Duration(milliseconds: 300), pageBuilder: (context, anim1, anim2) { return Align( alignment: Alignment.centerRight, child: FractionallySizedBox( widthFactor: 0.7, child: Material( color: Colors.transparent, child: Container( height: MediaQuery.of(context).size.height, decoration: BoxDecoration( color: isDarkMode ? Colors.white : Colors.white, borderRadius: BorderRadius.only( topLeft: Radius.circular(18.w), bottomLeft: Radius.circular(18.w), ), ), child: _buildDrawerContent(context, isDarkMode), ), ), ), ); }, transitionBuilder: (context, anim1, anim2, child) { final offsetAnimation = Tween( begin: const Offset(1, 0), end: Offset.zero, ).animate(CurvedAnimation(parent: anim1, curve: Curves.easeOutCubic)); return SlideTransition( position: offsetAnimation, child: child, ); }, ); } // 侧边栏内容 Widget _buildDrawerContent(BuildContext context, bool isDarkMode) { return SafeArea( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Padding( padding: EdgeInsets.all(20.w), child: TextField( decoration: InputDecoration( hintText: '在所有文件中搜索', prefixIcon: Icon(Icons.search), border: OutlineInputBorder( borderRadius: BorderRadius.circular(12.w), borderSide: BorderSide.none, ), filled: true, fillColor: Colors.grey[100], contentPadding: EdgeInsets.zero, ), ), ), ListTile( leading: Icon(Icons.folder, color: Colors.red), title: Text('全部文件(4)', style: TextStyle(fontWeight: FontWeight.bold)), onTap: () {}, ), ListTile( leading: Icon(Icons.category, color: Colors.blue), title: Text('未分类(4)'), onTap: () {}, ), ListTile( leading: Icon(Icons.delete, color: Colors.teal), title: Text('回收站'), onTap: () {}, ), Divider(), Padding( padding: EdgeInsets.symmetric(horizontal: 16.w, vertical: 8.w), child: Text('文件夹', style: TextStyle(color: Colors.grey)), ), ...['NOTE', 'CALL', 'NotePin', 'Import', 'Desktop'] .map((name) => ListTile( title: Text(name), onTap: () {}, )), Divider(), Padding( padding: EdgeInsets.symmetric(horizontal: 16.w, vertical: 8.w), child: Text('排序方式', style: TextStyle(color: Colors.grey)), ), ListTile( title: Text('创建时间'), trailing: Icon(Icons.arrow_upward), onTap: () {}, ), ListTile( title: Text('修改时间'), trailing: Icon(Icons.arrow_upward), onTap: () {}, ), ], ), ); } // 构建应用栏 PreferredSizeWidget _buildAppBar(BuildContext context, bool isDarkMode) { return AppBar( backgroundColor: isDarkMode ? Colors.black : Colors.white, surfaceTintColor: Colors.transparent, elevation: 0.5, leading: IconButton( icon: Icon( Icons.arrow_back_ios, color: isDarkMode ? Colors.white : Colors.black, size: 20.sp, ), onPressed: () => Get.back(), ), title: Text( 'conferenceAssistant'.tr, // 商务会议助手 style: TextStyle( fontSize: 17.sp, fontWeight: FontWeight.w600, color: isDarkMode ? Colors.white : Colors.black, ), ), centerTitle: true, actions: [ IconButton( icon: Icon(Icons.folder_open, color: isDarkMode ? Colors.white : Colors.black), onPressed: () { _showRightDrawerDialog(context, isDarkMode); }, ), ], ); } // 构建主体内容 Widget _buildBody(BuildContext context, bool isDarkMode) { return Obx( () => ListView.builder( controller: controller.listController, itemCount: controller.dataList.length, padding: EdgeInsets.fromLTRB(12.w, 5.w, 12.w, 90.w), itemBuilder: (BuildContext context, int index) { MeetingModel data = MeetingModel.fromJson(controller.dataList[index]); return _item(context, isDarkMode, data); }, ), ); } Widget _item(BuildContext context, bool isDarkMode, MeetingModel data) { return GestureDetector( onTap: () { controller.isDisposed = true; Get.toNamed(Routes.meetingDetails, arguments: { 'id': data.id, }); }, onLongPressStart: (LongPressStartDetails details) { _onLongPressItem(context, isDarkMode, details, data); }, child: Container( padding: EdgeInsets.symmetric(horizontal: 15.w, vertical: 10.w), margin: EdgeInsets.symmetric(vertical: 5.w), decoration: BoxDecoration( color: isDarkMode ? Colors.white.withOpacity(0.05) : Colors.white, borderRadius: BorderRadius.circular(12.w), boxShadow: [ BoxShadow( color: isDarkMode ? Colors.black.withOpacity(0.2) : Colors.black.withOpacity(0.05), blurRadius: 10, offset: const Offset(0, 2), ), ], ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( data.title, style: TextStyle( color: isDarkMode ? Colors.white : Colors.black87, fontSize: 18.sp, ), overflow: TextOverflow.ellipsis, ), Padding( padding: EdgeInsets.symmetric(vertical: 5.w), child: Row( children: [ Icon( Icons.calendar_month, size: 14.w, color: isDarkMode ? Colors.grey[400] : Colors.grey[500], ), 2.horizontalSpace, Text( DateUtil.formatDateMs( data.creationtime, format: DateFormats.y_mo_d_h_m, ), style: TextStyle( color: isDarkMode ? Colors.grey[400] : Colors.grey[500], fontSize: 12.sp, ), ), 20.horizontalSpace, Icon( Icons.access_time, size: 14.w, color: isDarkMode ? Colors.grey[400] : Colors.grey[500], ), 2.horizontalSpace, Text( '${data.seconds}s', style: TextStyle( color: isDarkMode ? Colors.grey[400] : Colors.grey[500], fontSize: 12.sp, ), ), ], ), ), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Container( padding: EdgeInsets.symmetric(horizontal: 5.w, vertical: 2.w), margin: EdgeInsets.only(top: 5.w), decoration: BoxDecoration( color: isDarkMode ? Colors.grey[900] : Colors.grey[100], borderRadius: BorderRadius.circular(4.w), ), child: Text( data.type, style: TextStyle( color: isDarkMode ? Colors.grey[400] : Colors.grey[600], fontSize: 10.sp, ), ), ), if (data.tasktype == 1) Padding( padding: EdgeInsets.only(top: 5.w), child: Text( '正在生成...', style: TextStyle( color: Colors.blue, fontSize: 10.sp, ), ), ), if (data.tasktype == 2) Padding( padding: EdgeInsets.only(top: 5.w), child: Text( '已生成', style: TextStyle( color: Colors.blue, fontSize: 10.sp, ), ), ), ], ), ], ), ), ); } void _onLongPressItem(BuildContext context, bool isDarkMode, LongPressStartDetails details, MeetingModel data) { Haptics.vibrate(HapticsType.success); RenderBox? renderBox = Overlay.of(context).context.findRenderObject() as RenderBox; final RelativeRect position = RelativeRect.fromRect( Rect.fromLTRB( details.globalPosition.dx, details.globalPosition.dy, details.globalPosition.dx + 110, // 菜单显示位置X轴坐标 details.globalPosition.dy - 40, // 菜单显示位置Y轴坐标 ), Offset.zero & renderBox.size, ); showMenu( context: context, position: position, color: isDarkMode ? AppColors.cardBackground : Colors.white, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12.r), ), items: [ _popupMenuEntry( Icon( Icons.edit_calendar, size: 20.w, color: isDarkMode ? Colors.white : Colors.black87, ), 'edit'.tr, // 编辑 isDarkMode ? Colors.white : Colors.black87, () { final dotIndex = data.title.lastIndexOf('.'); controller.titleController.text = dotIndex != -1 ? data.title.substring(0, dotIndex) : data.title; controller.titleCSuffix = data.title.substring(dotIndex, data.title.length); _bottomSheet(context, isDarkMode, data.id); }, ), _popupMenuEntry( Icon( Icons.delete_outline, size: 20.w, color: isDarkMode ? Colors.red[700] : Colors.red, ), 'delete'.tr, // 删除 isDarkMode ? Colors.red[700]! : Colors.red, () { controller.deleteMeeting(data.id, data.filepath); }, ), ], ); } PopupMenuEntry _popupMenuEntry( Icon icon, String title, Color color, Function() onTap, ) { return PopupMenuItem( onTap: onTap, child: SizedBox( width: 140.w, child: Row( children: [ icon, 8.horizontalSpace, Text( title, style: TextStyle( color: color, fontSize: 14.sp, ), ), ], ), ), ); } void _bottomSheet( BuildContext context, bool isDarkMode, int id, ) { Get.bottomSheet( Padding( padding: MediaQuery.of(context).viewInsets, child: Container( padding: EdgeInsets.symmetric(horizontal: 12.w, vertical: 20.w), color: isDarkMode ? AppColors.darkBackground : Colors.grey[50], child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ Text( 'editMeetingTitle'.tr, // 编辑会议标题 style: TextStyle( color: isDarkMode ? Colors.white : Colors.black87, fontSize: 16.sp, ), ), Container( height: 48.w, margin: EdgeInsets.only(top: 10.w, bottom: 20.w), alignment: Alignment.center, decoration: BoxDecoration( color: isDarkMode ? Colors.white.withOpacity(0.05) : Colors.white, borderRadius: BorderRadius.circular(12.w), boxShadow: [ BoxShadow( color: isDarkMode ? Colors.black.withOpacity(0.2) : Colors.black.withOpacity(0.05), blurRadius: 10, offset: const Offset(0, 2), ), ], ), child: TextField( controller: controller.titleController, style: TextStyle( color: isDarkMode ? Colors.white : Colors.black87, fontSize: 16.sp, ), decoration: InputDecoration( hintText: 'maxCharacters'.tr, hintStyle: TextStyle( color: isDarkMode ? Colors.white70 : Colors.black54, fontSize: 16.sp, ), fillColor: Colors.transparent, border: InputBorder.none, contentPadding: EdgeInsets.symmetric(horizontal: 10.w), ), ), ), Padding( padding: EdgeInsets.only(top: 30.w), child: Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ GestureDetector( onTap: () { Get.back(); }, child: Container( width: 120.w, height: 40.w, alignment: Alignment.center, decoration: BoxDecoration( border: Border.all( width: 2.w, color: isDarkMode ? AppColors.primary : Colors.blue, ), borderRadius: BorderRadius.circular(12.w), ), child: Text( 'cancel'.tr, // 取消 style: TextStyle( fontSize: 14.sp, color: isDarkMode ? AppColors.primary : Colors.blue, ), ), ), ), GestureDetector( onTap: () { String title = controller.titleController.text + controller.titleCSuffix; controller.editMeetingTitle(id, title); }, child: Container( width: 120.w, height: 40.w, alignment: Alignment.center, decoration: BoxDecoration( color: isDarkMode ? AppColors.primary : Colors.blue, borderRadius: BorderRadius.circular(12.w), ), child: Text( 'confirm'.tr, // 确认 style: TextStyle( color: Colors.white, fontSize: 14.sp, ), ), ), ), ], ), ), ], ), ), ), isScrollControlled: true, clipBehavior: Clip.hardEdge, ); } // ...existing code... // // 选项框 // Widget _importAudioItem1( // BuildContext context, // bool isDarkMode, { // required Widget icon, // required String title, // required VoidCallback onTap, // }) { // return Material( // color: Colors.transparent, // child: InkWell( // borderRadius: BorderRadius.circular(12.w), // onTap: onTap, // child: Container( // height: 52.w, // padding: EdgeInsets.symmetric(horizontal: 12.w), // decoration: BoxDecoration( // color: // isDarkMode ? Colors.white.withOpacity(0.03) : Colors.grey[50], // borderRadius: BorderRadius.circular(12.w), // ), // child: Row( // children: [ // icon, // SizedBox(width: 14.w), // Expanded( // child: Text( // title, // style: TextStyle( // fontSize: 16.sp, // color: isDarkMode ? Colors.white : Colors.black87, // ), // ), // ), // Icon(Icons.arrow_forward_ios, size: 18.w, color: Colors.grey), // ], // ), // ), // ), // ); // } // // 底部+号菜单 // void _showAddAudioMenu(BuildContext context, bool isDarkMode) { // showModalBottomSheet( // context: context, // isScrollControlled: true, // backgroundColor: Colors.transparent, // builder: (context) { // return Padding( // padding: EdgeInsets.only( // bottom: MediaQuery.of(context).viewInsets.bottom + 30.w, // left: 16.w, // right: 16.w, // ), // child: Column( // mainAxisSize: MainAxisSize.min, // children: [ // // 录音按钮 // Container( // margin: EdgeInsets.only(bottom: 12.w), // child: GestureDetector( // onTap: () { // Navigator.of(context).pop(); // // TODO: 实现开始录音逻辑 // _showStartsRecordSheet(context, isDarkMode); // }, // child: Container( // height: 56.w, // decoration: BoxDecoration( // color: isDarkMode // ? Colors.white.withOpacity(0.05) // : Colors.grey[100], // borderRadius: BorderRadius.circular(28.w), // ), // child: Row( // mainAxisAlignment: MainAxisAlignment.center, // children: [ // Container( // width: 36.w, // height: 36.w, // decoration: BoxDecoration( // color: Colors.red.withOpacity(0.15), // shape: BoxShape.circle, // ), // child: Icon(Icons.mic, color: Colors.red, size: 24.w), // ), // SizedBox(width: 12.w), // Text( // '开始录音', // style: TextStyle( // color: isDarkMode ? Colors.white70 : Colors.black87, // fontSize: 16.sp, // fontWeight: FontWeight.w500, // ), // ), // Spacer(), // Icon(Icons.arrow_forward_ios, // color: Colors.grey, size: 18.w), // SizedBox(width: 16.w), // ], // ), // ), // ), // ), // // 导入音频按钮 // Container( // margin: EdgeInsets.only(bottom: 24.w), // child: GestureDetector( // onTap: () { // Navigator.of(context).pop(); // _showImportAudioSheet(context, isDarkMode); // }, // child: Container( // height: 56.w, // decoration: BoxDecoration( // color: isDarkMode // ? Colors.white.withOpacity(0.10) // : Colors.white, // borderRadius: BorderRadius.circular(28.w), // border: Border.all( // color: Colors.blue.withOpacity(0.15), // width: 2, // ), // boxShadow: [ // BoxShadow( // color: Colors.blue.withOpacity(0.08), // blurRadius: 8, // offset: Offset(0, 2), // ), // ], // ), // child: Row( // mainAxisAlignment: MainAxisAlignment.center, // children: [ // Container( // width: 36.w, // height: 36.w, // decoration: BoxDecoration( // color: Colors.blue.withOpacity(0.15), // shape: BoxShape.circle, // ), // child: Icon(Icons.file_upload_outlined, // color: Colors.blue, size: 24.w), // ), // SizedBox(width: 12.w), // Text( // '导入音频', // style: TextStyle( // color: Colors.blue, // fontSize: 16.sp, // fontWeight: FontWeight.w500, // ), // ), // Spacer(), // Icon(Icons.arrow_forward_ios, // color: Colors.grey, size: 18.w), // SizedBox(width: 16.w), // ], // ), // ), // ), // ), // // 关闭按钮 // GestureDetector( // onTap: () => Navigator.of(context).pop(), // child: Container( // width: 56.w, // height: 56.w, // decoration: BoxDecoration( // color: isDarkMode // ? Colors.white.withOpacity(0.08) // : Colors.black.withOpacity(0.08), // shape: BoxShape.circle, // ), // child: Icon(Icons.close, // color: isDarkMode ? Colors.white : Colors.black54, // size: 32.w), // ), // ), // SizedBox(height: 10.w), // ], // ), // ); // }, // ); // } // // 新增:从opus导出选择弹窗 // void _showLocalOpusPicker(BuildContext context, bool isDarkMode) async { // // 这里以用户目录下的 Downloads 为例,可根据实际需求修改路径 // controller.loadTranslatopus(); // showModalBottomSheet( // context: context, // isScrollControlled: true, // backgroundColor: Colors.transparent, // builder: (context) { // return StatefulBuilder( // builder: (context, setState) { // return Container( // decoration: BoxDecoration( // color: isDarkMode ? Colors.grey[900] : Colors.white, // borderRadius: BorderRadius.vertical(top: Radius.circular(18.w)), // ), // padding: EdgeInsets.only( // left: 0, // right: 0, // top: 12.w, // bottom: MediaQuery.of(context).viewInsets.bottom + 12.w, // ), // child: Column( // mainAxisSize: MainAxisSize.min, // children: [ // Text( // '选择音视频文件', // style: TextStyle( // fontSize: 18.sp, // fontWeight: FontWeight.bold, // color: isDarkMode ? Colors.white : Colors.black87, // ), // ), // Divider( // height: 1, // color: isDarkMode ? Colors.white12 : Colors.grey[200]), // SizedBox(height: 8.w), // SizedBox( // height: 300.w, // child: ListView.builder( // itemCount: controller.files.length, // itemBuilder: (context, idx) { // final file = controller.files[idx]; // final fileName = file.path.split('/').last; // final isChecked = // controller.selected.contains(file.path); // return CheckboxListTile( // value: isChecked, // onChanged: (checked) { // setState(() { // if (checked == true) { // controller.selected.add(file.path); // } else { // controller.selected.remove(file.path); // } // }); // }, // title: Text( // fileName, // style: TextStyle( // color: isDarkMode ? Colors.white : Colors.black87, // fontSize: 15.sp, // ), // ), // controlAffinity: ListTileControlAffinity.leading, // activeColor: Colors.blue, // ); // }, // ), // ), // SizedBox(height: 12.w), // Row( // mainAxisAlignment: MainAxisAlignment.spaceEvenly, // children: [ // ElevatedButton( // style: ElevatedButton.styleFrom( // backgroundColor: Colors.grey, // ), // onPressed: () => Navigator.of(context).pop(), // child: // Text('取消', style: TextStyle(color: Colors.white)), // ), // ElevatedButton( // style: ElevatedButton.styleFrom( // backgroundColor: Colors.blue, // ), // onPressed: controller.selected.isEmpty // ? null // : () { // Navigator.of(context).pop(); // // TODO: 调用导入逻辑 // controller.shareAllTranslatAudio(); // }, // child: // Text('导入选中', style: TextStyle(color: Colors.white)), // ), // ], // ), // SizedBox(height: 8.w), // ], // ), // ); // }, // ); // }, // ); // } // // 新增:本地音视频文件选择弹窗 // void _showLocalAudioVideoPicker(BuildContext context, bool isDarkMode) async { // // 这里以用户目录下的 Downloads 为例,可根据实际需求修改路径 // controller.loadTranslatAudio(); // showModalBottomSheet( // context: context, // isScrollControlled: true, // backgroundColor: Colors.transparent, // builder: (context) { // return StatefulBuilder( // builder: (context, setState) { // return Container( // decoration: BoxDecoration( // color: isDarkMode ? Colors.grey[900] : Colors.white, // borderRadius: BorderRadius.vertical(top: Radius.circular(18.w)), // ), // padding: EdgeInsets.only( // left: 0, // right: 0, // top: 12.w, // bottom: MediaQuery.of(context).viewInsets.bottom + 12.w, // ), // child: Column( // mainAxisSize: MainAxisSize.min, // children: [ // Text( // '选择音视频文件', // style: TextStyle( // fontSize: 18.sp, // fontWeight: FontWeight.bold, // color: isDarkMode ? Colors.white : Colors.black87, // ), // ), // Divider( // height: 1, // color: isDarkMode ? Colors.white12 : Colors.grey[200]), // SizedBox(height: 8.w), // SizedBox( // height: 300.w, // child: ListView.builder( // itemCount: controller.files.length, // itemBuilder: (context, idx) { // final file = controller.files[idx]; // final fileName = file.path.split('/').last; // final isChecked = // controller.selected.contains(file.path); // return CheckboxListTile( // value: isChecked, // onChanged: (checked) { // setState(() { // if (checked == true) { // controller.selected.add(file.path); // } else { // controller.selected.remove(file.path); // } // }); // }, // title: Text( // fileName, // style: TextStyle( // color: isDarkMode ? Colors.white : Colors.black87, // fontSize: 15.sp, // ), // ), // controlAffinity: ListTileControlAffinity.leading, // activeColor: Colors.blue, // ); // }, // ), // ), // SizedBox(height: 12.w), // Row( // mainAxisAlignment: MainAxisAlignment.spaceEvenly, // children: [ // ElevatedButton( // style: ElevatedButton.styleFrom( // backgroundColor: Colors.grey, // ), // onPressed: () => Navigator.of(context).pop(), // child: // Text('取消', style: TextStyle(color: Colors.white)), // ), // ElevatedButton( // style: ElevatedButton.styleFrom( // backgroundColor: Colors.blue, // ), // onPressed: controller.selected.isEmpty // ? null // : () { // Navigator.of(context).pop(); // // TODO: 调用导入逻辑 // controller.addTranslatAudio(); // }, // child: // Text('导入选中', style: TextStyle(color: Colors.white)), // ), // ], // ), // SizedBox(height: 8.w), // ], // ), // ); // }, // ); // }, // ); // } // // 导入音频弹窗 // void _showImportAudioSheet(BuildContext context, bool isDarkMode) { // showModalBottomSheet( // context: context, // isScrollControlled: true, // backgroundColor: Colors.transparent, // builder: (context) { // return Container( // decoration: BoxDecoration( // color: isDarkMode ? Colors.grey[900] : Colors.white, // borderRadius: BorderRadius.vertical(top: Radius.circular(18.w)), // ), // padding: EdgeInsets.only( // left: 0, // right: 0, // top: 12.w, // bottom: MediaQuery.of(context).viewInsets.bottom + 12.w, // ), // child: Column( // mainAxisSize: MainAxisSize.min, // children: [ // Container( // alignment: Alignment.centerLeft, // padding: EdgeInsets.symmetric(horizontal: 24.w, vertical: 8.w), // child: Text( // '导入音频', // style: TextStyle( // fontSize: 18.sp, // fontWeight: FontWeight.bold, // color: isDarkMode ? Colors.white : Colors.black87, // ), // ), // ), // Divider( // height: 1, // color: isDarkMode ? Colors.white12 : Colors.grey[200]), // // 选项列表 // Padding( // padding: EdgeInsets.symmetric(horizontal: 16.w, vertical: 8.w), // child: Column( // children: [ // _importAudioItem1( // context, // isDarkMode, // icon: Image.asset('assets/images/explore.png', // width: 32.w, height: 32.w), // title: '从外部导入', // onTap: () { // Navigator.of(context).pop(); // controller.addAudio(); // // TODO: 实现从文件导入逻辑 // }, // ), // // SizedBox(height: 8.w), // // _importAudioItem1( // // context, // // isDarkMode, // // icon: Image.asset('assets/images/explore.png', // // width: 32.w, height: 32.w), // // title: '从翻译里导入', // // onTap: () { // // Navigator.of(context).pop(); // // _showLocalAudioVideoPicker(context, isDarkMode); // // // TODO: 实现从相册导入逻辑 // // }, // // ), // // SizedBox(height: 8.w), // // _importAudioItem1( // // context, // // isDarkMode, // // icon: Row( // // mainAxisSize: MainAxisSize.min, // // children: [ // // Image.asset('assets/images/explore.png', // // width: 20.w, height: 20.w), // // SizedBox(width: 4.w), // // Image.asset('assets/images/explore.png', // // width: 20.w, height: 20.w), // // SizedBox(width: 4.w), // // Image.asset('assets/images/explore.png', // // width: 20.w, height: 20.w), // // ], // // ), // // title: '从opus导出', // // onTap: () { // // Navigator.of(context).pop(); // // // TODO: 实现从其他APP导入逻辑 // // _showLocalOpusPicker(context, isDarkMode); // // }, // // ), // ], // ), // ), // SizedBox(height: 8.w), // Padding( // padding: EdgeInsets.symmetric(horizontal: 20.w), // child: Text( // '支持导入单文件时长不超过5小时的音频', // style: TextStyle( // fontSize: 13.sp, // color: isDarkMode ? Colors.white54 : Colors.grey[600], // ), // ), // ), // SizedBox(height: 16.w), // GestureDetector( // onTap: () => Navigator.of(context).pop(), // child: Icon(Icons.close, size: 32.w, color: Colors.grey), // ), // SizedBox(height: 8.w), // ], // ), // ); // }, // ); // } // void _showRecordingSheet(BuildContext context, bool isDarkMode) { // if (_recordingOverlayEntry != null) return; // 防止重复添加 // _recordingOverlayEntry = OverlayEntry( // builder: (ctx) => RecordingFloatingPanel( // onStop: () { // _recordingOverlayEntry?.remove(); // _recordingOverlayEntry = null; // // 录音完成后的逻辑 // }, // ), // ); // Overlay.of(context).insert(_recordingOverlayEntry!); // } }