You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

300 lines
10 KiB

import 'dart:io';
import 'package:common_utils/common_utils.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import 'package:get_storage/get_storage.dart';
import 'package:path_provider/path_provider.dart';
import 'package:share_plus/share_plus.dart';
import 'package:webview_flutter/webview_flutter.dart';
import '../../../../core/utils/synchrodata.dart';
import '../../controllers/meeting_details_controller.dart';
import '../../controllers/mind_map_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,
onTap: () async {
Get.back();
Synchrodata.uploadOperationRecords();
final GetStorage storage = GetStorage();
String token = storage.read("logintoken") ?? '';
String userId = '';
Map? userInfo = storage.read("user_info");
if (userInfo != null) {
userId = userInfo['user']['uid'];
}
String id =
'${userId}_${_controller.meetingData.value.id}';
final thumbnail = await getAssetThumbnailFile(
'assets/images/headphone_dark.png',
'share_thumb.png',
);
final result = await SharePlus.instance.share(ShareParams(
title: _controller.meetingData.value.title,
subject:
'DeepSound WEB,由DeepSound.Ai提供支持-实时记录会议纪要,多语言翻译。',
uri: Uri.parse(
'http://web.ideapsound.com/share/$id/$token',
),
previewThumbnail: thumbnail,
));
if (result.status == ShareResultStatus.success) {
EasyLoading.showToast('分享完成!');
}
},
),
]),
_box([
_shareItem(Icons.copy, '复制转写',
onTap: _controller.meetingDetails.value.tasktype >= 2
? () {
Get.back();
_copy(_getAllText());
}
: null),
_shareItem(Icons.copy, '复制总结',
isBorder: false,
onTap: _controller.meetingDetails.value.tasktype >= 3
? () {
Get.back();
_copy(_controller.meetingDetails.value.summary);
}
: null),
]),
_box([
_shareItem(Icons.multitrack_audio, '导出音频', onTap: () {
Get.back();
_share(_controller.meetingData.value.filepath, '分享会议音频');
}),
_shareItem(Icons.message, '导出转写',
onTap: _controller.meetingDetails.value.tasktype >= 2
? () async {
Get.back();
final tempDir = await getTemporaryDirectory();
final file = File(
'${tempDir.path}/${_controller.meetingData.value.title} speaker.txt');
String allText = _getAllText();
await file.writeAsString(allText);
_share(file.path, '分享会议转写');
}
: null),
_shareItem(Icons.article, '导出总结',
onTap: _controller.meetingDetails.value.tasktype >= 3
? () async {
Get.back();
final tempDir = await getTemporaryDirectory();
final file = File(
'${tempDir.path}/${_controller.meetingData.value.title} summary.txt');
await file.writeAsString(
_controller.meetingDetails.value.summary);
_share(file.path, '分享会议总结');
}
: null),
_shareItem(
Icons.lan,
'导出思维导图',
isBorder: false,
onTap: _controller.meetingDetails.value.tasktype >= 3
? () {
Get.back();
final mindMapController =
Get.find<MindMapController>();
if (mindMapController.isWebViewReady) {
mindMapController.webViewController
.runJavaScript('captureImage()');
} else {
mindMapController.webViewController
.setNavigationDelegate(
NavigationDelegate(
onPageFinished: (String url) {
mindMapController.isWebViewReady = true;
mindMapController.webViewController
.runJavaScript('captureImage()');
},
),
);
}
}
: null,
),
]),
],
),
),
],
),
);
}
Widget _box(List<Widget> children) {
return Container(
margin: EdgeInsets.only(bottom: 10.w),
clipBehavior: Clip.hardEdge,
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(
color: onTap != null ? null : Colors.grey[200],
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 _share(String filepath, String title) async {
final result = await SharePlus.instance.share(ShareParams(
text: title,
files: [XFile(filepath)],
));
if (result.status == ShareResultStatus.success) {
EasyLoading.showToast('分享完成!');
}
}
void _copy(String text) {
Clipboard.setData(ClipboardData(
text: text,
)).then(
(value) => Get.snackbar(
'success'.tr, // 成功
'复制成功',
backgroundColor: Colors.blue.withOpacity(0.8),
colorText: Colors.white,
),
);
}
String _getAllText() {
String text = '';
for (var element in _controller.textList) {
if (element['speaker'].isNotEmpty) {
text += '${element['speaker']} ';
}
text += '${DateUtil.formatDateMs(
element['starttime'],
format: 'HH:mm:ss',
isUtc: true,
)}\n';
text += '${element['content']}\n';
}
return text;
}
Future<XFile> getAssetThumbnailFile(String assetPath, String fileName) async {
final byteData = await rootBundle.load(assetPath);
final tempDir = await getTemporaryDirectory();
final file = File('${tempDir.path}/$fileName');
await file.writeAsBytes(byteData.buffer.asUint8List());
return XFile(file.path);
}
}