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.
155 lines
4.2 KiB
155 lines
4.2 KiB
import 'dart:convert';
|
|
import 'dart:io';
|
|
import 'dart:typed_data';
|
|
|
|
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:path_provider/path_provider.dart';
|
|
import 'package:share_plus/share_plus.dart';
|
|
import 'package:webview_flutter/webview_flutter.dart';
|
|
|
|
import 'meeting_details_controller.dart';
|
|
|
|
class MindMapController extends GetxController {
|
|
late final WebViewController webViewController;
|
|
final _meetingDetailsController = Get.find<MeetingDetailsController>();
|
|
|
|
@override
|
|
void onInit() {
|
|
super.onInit();
|
|
String html = '''
|
|
<!DOCTYPE html>
|
|
<html lang="en">
|
|
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>MindMap</title>
|
|
<script src="https://cdn.jsdelivr.net/npm/markmap-lib"></script>
|
|
<script src="https://cdn.jsdelivr.net/npm/d3@7"></script>
|
|
<script src="https://cdn.jsdelivr.net/npm/markmap-view"></script>
|
|
<script src="https://cdn.jsdelivr.net/npm/markmap-toolbar"></script>
|
|
<script src="https://cdn.jsdelivr.net/npm/save-svg-as-png@1.4.17/lib/saveSvgAsPng.min.js"></script>
|
|
<style>
|
|
html,
|
|
body {
|
|
width: 100%;
|
|
height: 100%;
|
|
margin: 0;
|
|
padding: 0;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.mind-map {
|
|
width: 100%;
|
|
height: 100%;
|
|
position: relative;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.mind-map #markmap {
|
|
width: 100%;
|
|
height: 100%;
|
|
}
|
|
|
|
.mind-map .mm-toolbar {
|
|
height: 30px;
|
|
background: #fff;
|
|
border: 1px solid #d0d5dd;
|
|
border-radius: 8px;
|
|
display: flex;
|
|
justify-content: space-around;
|
|
align-items: center;
|
|
position: absolute;
|
|
top: 20px;
|
|
right: 20px;
|
|
}
|
|
|
|
.mind-map .mm-toolbar-item {
|
|
width: 24px;
|
|
height: 24px;
|
|
border-radius: 6px;
|
|
cursor: pointer;
|
|
color: #101828;
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
}
|
|
|
|
.mind-map .mm-toolbar-item.active {
|
|
background-color: #d4d4d8;
|
|
}
|
|
</style>
|
|
</head>
|
|
|
|
<body>
|
|
<div class="mind-map">
|
|
<svg id="markmap"></svg>
|
|
<div id="toolbar"></div>
|
|
</div>
|
|
<script>
|
|
const { Transformer, Markmap, Toolbar } = window.markmap;
|
|
const transformer = new Transformer();
|
|
const { root } = transformer.transform(`${_meetingDetailsController.meetingDetails.value.summary}`);
|
|
let mm = Markmap.create('#markmap', {
|
|
maxWidth: 300,
|
|
initialExpandLevel: 3,
|
|
}, root);
|
|
const toolbar = Toolbar.create(mm);
|
|
toolbar.showBrand = false
|
|
toolbar.render();
|
|
const el = toolbar.el;
|
|
const toolbarElement = document.getElementById('toolbar');
|
|
toolbarElement.append(el);
|
|
|
|
async function captureImage() {
|
|
const markmapElement = document.getElementById('markmap');
|
|
markmapElement.style.height = `${1.sw}px`;
|
|
await mm.fit();
|
|
const options = {
|
|
scale: 2,
|
|
backgroundColor: '#FFFFFF',
|
|
encoderOptions: 1,
|
|
};
|
|
const uri = await svgAsPngUri(markmapElement, options);
|
|
markmapElement.style.height = '100%';
|
|
mm.fit();
|
|
if (window.ImageChannel) {
|
|
window.ImageChannel.postMessage(uri);
|
|
}
|
|
}
|
|
</script>
|
|
</body>
|
|
|
|
</html>
|
|
''';
|
|
webViewController = WebViewController()
|
|
..setJavaScriptMode(JavaScriptMode.unrestricted)
|
|
..addJavaScriptChannel(
|
|
'ImageChannel',
|
|
onMessageReceived: _messageReceived,
|
|
)
|
|
..setBackgroundColor(Colors.transparent)
|
|
..loadHtmlString(html);
|
|
}
|
|
|
|
void _messageReceived(message) async {
|
|
final String dataUrl = message.message;
|
|
final String base64Str = dataUrl.split(',').last;
|
|
final Uint8List bytes = base64.decode(base64Str);
|
|
final String fileName =
|
|
'${_meetingDetailsController.meetingData.value.title} mindmap.png';
|
|
final tempDir = await getTemporaryDirectory();
|
|
final File file = File('${tempDir.path}/$fileName');
|
|
await file.writeAsBytes(bytes);
|
|
final result = await SharePlus.instance.share(ShareParams(
|
|
text: '分享思维导图',
|
|
files: [XFile(file.path)],
|
|
));
|
|
if (result.status == ShareResultStatus.success) {
|
|
EasyLoading.showToast('分享完成!');
|
|
}
|
|
}
|
|
}
|
|
|