Browse Source

Merge branch 'new_dev' of https://github.com/deepcloud2048/deep_voice into new_dev

newdev_shunjiawei
lxm 1 year ago
parent
commit
7efc8a9f78
  1. 23
      lib/modules/meeting/controllers/meeting_details_controller.dart
  2. 108
      lib/modules/meeting/views/meeting_details_view.dart
  3. 162
      lib/modules/meeting/views/share_bottom_sheet.dart

23
lib/modules/meeting/controllers/meeting_details_controller.dart

@ -17,7 +17,6 @@ import '../../../data/services/deapsound_ai_service.dart';
import '../model/meeting_details_model.dart'; import '../model/meeting_details_model.dart';
import '../model/meeting_model.dart'; import '../model/meeting_model.dart';
import 'meeting_controller.dart'; import 'meeting_controller.dart';
import 'package:share_plus/share_plus.dart';
class MeetingDetailsController extends GetxController class MeetingDetailsController extends GetxController
with GetTickerProviderStateMixin { with GetTickerProviderStateMixin {
@ -423,26 +422,4 @@ class MeetingDetailsController extends GetxController
} }
allText = text; allText = text;
} }
// 导入音频文件
Future<void> shareAllTranslatAudio() async {
// 确保 filepath 是字符串列表类型
if (meetingData.value.filepath.isEmpty) {
EasyLoading.showToast('没有可分享的音频文件');
return;
}
try {
// 直接使用文件路径列表创建 XFile 列表
await Share.shareXFiles(
[XFile(meetingData.value.filepath)], // 注意:这里用方括号创建包含单个文件的列表
text: '分享会议音频',
);
EasyLoading.showToast('分享完成!');
} catch (e) {
EasyLoading.showToast('分享失败: ${e.toString()}');
}
}
} }

108
lib/modules/meeting/views/meeting_details_view.dart

@ -9,6 +9,7 @@ import '../../../core/theme/app_colors.dart';
import '../controllers/meeting_details_controller.dart'; import '../controllers/meeting_details_controller.dart';
import 'mind_map_tab.dart'; import 'mind_map_tab.dart';
import 'overview_tab.dart'; import 'overview_tab.dart';
import 'share_bottom_sheet.dart';
import 'speech_tab.dart'; import 'speech_tab.dart';
import 'summary_tab.dart'; import 'summary_tab.dart';
@ -143,7 +144,16 @@ class MeetingDetailsView extends GetView<MeetingDetailsController> {
size: 22.sp, size: 22.sp,
), ),
onPressed: () { onPressed: () {
_showShareSheet(context, isDarkMode); Get.bottomSheet(
const ShareBottomSheet(),
isScrollControlled: true,
backgroundColor: Colors.grey[100],
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(
top: Radius.circular(12.r),
),
),
);
}, },
), ),
if (!controller.isSpeakerText.value) if (!controller.isSpeakerText.value)
@ -276,102 +286,6 @@ class MeetingDetailsView extends GetView<MeetingDetailsController> {
); );
} }
// 2. 新增底部分享弹窗方法
void _showShareSheet(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: [
// 文件名和关闭按钮
Row(
children: [
SizedBox(width: 16.w),
Icon(Icons.insert_drive_file, color: Colors.grey, size: 22.w),
SizedBox(width: 8.w),
Expanded(
child: Text(
controller.meetingData.value.title ?? '会议文件',
style: TextStyle(
fontWeight: FontWeight.w600,
fontSize: 16.sp,
color: isDarkMode ? Colors.white : Colors.black87,
),
),
),
IconButton(
icon: Icon(Icons.close,
color: isDarkMode ? Colors.white : Colors.black54,
size: 24.w),
onPressed: () => Navigator.of(context).pop(),
),
],
),
SizedBox(height: 8.w),
Divider(
height: 1,
color: isDarkMode ? Colors.white12 : Colors.grey[200]),
// 分享选项
_shareItem(Icons.link, '分享链接', onTap: () {/* TODO */}),
_shareItem(Icons.copy, '复制转写', onTap: () {/* TODO */}),
_shareItem(Icons.copy, '复制总结', onTap: () {/* TODO */}),
// ...existing code...
_shareItem(Icons.multitrack_audio, '导出音频', onTap: () {
controller.shareAllTranslatAudio();
}),
// ...existing code...
_shareItem(Icons.description, '导出转写', onTap: () {/* TODO */}),
_shareItem(Icons.description, '导出总结', onTap: () {/* TODO */}),
_shareItem(Icons.account_tree, '导出思维导图', onTap: () {/* TODO */}),
SizedBox(height: 8.w),
],
),
);
},
);
}
// 3. 分享选项组件
Widget _shareItem(IconData icon, String title, {VoidCallback? onTap}) {
return InkWell(
onTap: () {
Navigator.of(Get.context!).pop();
if (onTap != null) onTap();
},
child: Container(
height: 52.w,
padding: EdgeInsets.symmetric(horizontal: 20.w),
child: Row(
children: [
Icon(icon, color: Colors.grey[700], size: 22.w),
SizedBox(width: 16.w),
Text(
title,
style: TextStyle(
fontSize: 16.sp,
color: Colors.black87,
),
),
],
),
),
);
}
Widget _meetingWait(String title) { Widget _meetingWait(String title) {
return Stack( return Stack(
alignment: Alignment.topCenter, alignment: Alignment.topCenter,

162
lib/modules/meeting/views/share_bottom_sheet.dart

@ -0,0 +1,162 @@
import 'package:flutter/material.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import 'package:share_plus/share_plus.dart';
import '../controllers/meeting_details_controller.dart';
class ShareBottomSheet extends StatefulWidget {
const ShareBottomSheet({super.key});
@override
State<ShareBottomSheet> createState() => _ShareBottomSheetState();
}
class _ShareBottomSheetState extends State<ShareBottomSheet> {
final _controller = Get.find<MeetingDetailsController>();
@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(
children: [
Icon(
Icons.audio_file_outlined,
color: Colors.grey,
size: 32.w,
),
5.horizontalSpace,
Expanded(
child: Text(
_controller.meetingData.value.title,
style: TextStyle(
fontSize: 16.sp,
color: Colors.black87,
),
),
),
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],
),
),
)
],
),
),
Padding(
padding: EdgeInsets.symmetric(vertical: 10.w),
child: Column(
children: [
_box([
_shareItem(Icons.link, '分享链接', isBorder: false),
]),
_box([
_shareItem(Icons.copy, '复制转写'),
_shareItem(Icons.copy, '复制总结', isBorder: false),
]),
_box([
_shareItem(
Icons.multitrack_audio,
'导出音频',
onTap: shareAllTranslatAudio,
),
_shareItem(Icons.message, '导出转写'),
_shareItem(Icons.article, '导出总结'),
_shareItem(Icons.lan, '导出思维导图', isBorder: false),
]),
],
),
),
],
),
);
}
Widget _box(List<Widget> children) {
return Container(
margin: EdgeInsets.only(bottom: 10.w),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(12.r),
),
child: Column(
children: children,
),
);
}
Widget _shareItem(
IconData icon,
String title, {
bool isBorder = true,
VoidCallback? onTap,
}) {
return InkWell(
onTap: onTap,
child: Container(
padding: EdgeInsets.symmetric(horizontal: 12.w, vertical: 15.w),
decoration: BoxDecoration(
border: isBorder
? Border(
bottom: BorderSide(
color: Colors.grey[300]!,
),
)
: null,
),
child: Row(
children: [
Icon(
icon,
color: Colors.black87,
),
10.horizontalSpace,
Expanded(
child: Text(
title,
style: TextStyle(
fontSize: 14.sp,
color: Colors.black87,
),
),
),
],
),
),
);
}
void shareAllTranslatAudio() async {
if (_controller.meetingData.value.filepath.isEmpty) {
EasyLoading.showToast('没有可分享的音频文件');
return;
}
try {
await Share.shareXFiles(
[XFile(_controller.meetingData.value.filepath)],
text: '分享会议音频',
);
EasyLoading.showToast('分享完成!');
} catch (e) {
EasyLoading.showToast('分享失败: ${e.toString()}');
}
}
}
Loading…
Cancel
Save