123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345 |
- import 'dart:io';
- import 'dart:typed_data';
- import 'dart:ui';
- import 'package:flutter/material.dart';
- import 'package:flutter/rendering.dart';
- import 'package:flutter/services.dart';
- import 'package:image_gallery_saver/image_gallery_saver.dart';
- import 'package:path_provider/path_provider.dart';
- import 'package:permission_handler/permission_handler.dart';
- import 'package:provider/provider.dart';
- import 'package:sport/application.dart';
- import 'package:sport/bean/forum.dart';
- import 'package:sport/bean/post.dart';
- import 'package:sport/pages/social/post_page.dart';
- import 'package:sport/pages/social/post_share_page.dart';
- import 'package:sport/pages/social/share_webview.dart';
- import 'package:sport/provider/user_model.dart';
- import 'package:sport/router/navigator_util.dart';
- import 'package:sport/services/api/inject_api.dart';
- import 'package:sport/services/api/resp.dart';
- import 'package:sport/sharesdk/tencent.dart';
- import 'package:sport/sharesdk/wechat.dart';
- import 'package:sport/utils/toast.dart';
- import 'package:sport/widgets/space.dart';
- import 'package:umeng_common_sdk/umeng_common_sdk.dart';
- import 'package:wechat_kit/wechat_kit.dart';
- class MenuShareBottomContent extends StatefulWidget {
- final String? url; // 复制的那个链接
- final bool hasDownload; // 有些又download 有些没download
- final GlobalKey? poster; // 下载海报...
- final String shareType; // 什么类型 Img social Link
- final Post? post; // social 连带的 post
- final String? hash; // 分享 link 连带的hash
- final String? file; // 分享 link 连带的hash
- final bool app; // 分享 是否显示app内功能
- MenuShareBottomContent(this.shareType, {this.post, this.url = "", this.hasDownload = false, this.poster, this.hash, this.file, this.app = true});
- @override
- State<StatefulWidget> createState() {
- return _MenuShareBottomContentState();
- }
- }
- // shareType : Img / Link / Social
- class _MenuShareBottomContentState extends State<MenuShareBottomContent> with TencentMixin, WechatMixin, InjectApi {
- late List<Map<String, dynamic>> map;
- Uint8List? postInstance;
- @override
- listenWechatShareMsg(ShareMsgResp resp) {
- Navigator.pop(context);
- ToastUtil.show("分享成功");
- }
- @override
- void initState() {
- super.initState();
- map = [
- {
- "value": "微信",
- "url": "share_icon_wechat",
- "callBack": () async {
- if (widget.shareType == "Img") {
- String path = await initFile();
- wechatShareImage(path, "chat");
- } else if (widget.shareType == "Link") {
- wechatShareLink(widget.url ?? "" + "?h=${widget.hash}", "chat", Provider.of<UserModel>(context, listen: false).user.name);
- } else if (widget.shareType == "Video") {
- String path = await initFile();
- wechatShareVideo(path, "chat");
- }
- UmengCommonSdk.onEvent("share_wechat", {});
- }
- },
- {
- "value": "朋友圈",
- "url": "share_icon_wechatmonents",
- "callBack": () async {
- if (widget.shareType == "Img") {
- String path = await initFile();
- wechatShareImage(path, "friend");
- } else if (widget.shareType == "Link") {
- wechatShareLink(widget.url ?? "" + "?h=${widget.hash}", "friend", Provider.of<UserModel>(context, listen: false).user.name);
- }
- UmengCommonSdk.onEvent("share_wechatmonents", {});
- }
- },
- {
- "value": "QQ",
- "url": "share_icon_qq",
- "callBack": () async {
- if (widget.shareType == "Img") {
- String path = await initFile();
- tencentShare(path);
- } else if (widget.shareType == "Link") {
- tencentShareLink(widget.url ?? "");
- }
- UmengCommonSdk.onEvent("share_tencent", {});
- }
- },
- if(widget.app && openSocial())
- {
- "value": "社区",
- "url": "share_icon_community",
- "callBack": () async {
- UmengCommonSdk.onEvent("share_community", {});
- // if(widget.post == null)
- // return;
- List<Forum> buttonList = [];
- RespList<Forum> data = await api.getForumIndex();
- buttonList = data.results;
- if (data.results.length > 0) {
- buttonList.insert(0, new Forum(gameName: "全部"));
- }
- if (widget.shareType == "social") {
- await NavigatorUtil.goPage(
- context,
- (contxt) => PostPage(
- "",
- post: widget.post,
- forums: buttonList,
- ));
- } else if (widget.shareType == "Link") {
- await NavigatorUtil.goPage(
- context,
- (contxt) => PostPage(
- "",
- post: widget.post,
- url: widget.url,
- hash: widget.hash,
- forums: buttonList,
- ));
- } else if (widget.shareType == "Img") {
- String path = await initFile();
- print("$path---------------------------------");
- await NavigatorUtil.goPage(
- context,
- (context) => PostPage(
- "",
- image: path,
- forums: buttonList,
- ));
- }
- Navigator.pop(context, true);
- }
- },
- if(widget.app && openSocial())
- {
- "value": "社区好友",
- "url": "share_icon_friends",
- "callBack": () async {
- UmengCommonSdk.onEvent("share_friend", {});
- if (widget.shareType == "social") {
- await NavigatorUtil.goPage(
- context,
- (context) => PostShareFriendsPage(
- post: widget.post,
- ));
- } else if (widget.shareType == "Link") {
- // 这里可能得组装一手 link 的 数据 ...
- await NavigatorUtil.goPage(context, (context) => PostShareFriendsPage(hash: widget.hash));
- } else if (widget.shareType == "Img") {
- String path = await initFile();
- String url = (await api.postChatUpload(File(path))).data["url"];
- await NavigatorUtil.goPage(
- context,
- (context) => PostShareFriendsPage(
- image: url,
- ));
- }
- Navigator.pop(context, true);
- }
- },
- if (widget.url?.isNotEmpty == true)
- {
- "value": "复制链接",
- "url": "share_icon_link",
- "callBack": () {
- UmengCommonSdk.onEvent("share_copy", {});
- Clipboard.setData(ClipboardData(text: widget.url));
- ToastUtil.show("复制成功");
- }
- },
- if (widget.hasDownload == true)
- {
- "value": "下载图片",
- "url": "share_icon_download",
- "callBack": () {
- UmengCommonSdk.onEvent("share_download", {});
- _capture().then((file) async {}).whenComplete(() {
- print("Complete-------------------------------------------------");
- });
- }
- },
- ];
- // 社区暂时先把前面的隐藏掉
- if (widget.shareType == "social") {
- map = map.sublist(map.length - 2, map.length);
- }
- }
- // 封装成灵活的更通用一点...
- Future<String> initFile() async {
- if (widget.file?.isNotEmpty == true) return widget.file!;
- Uint8List pngBytes = await initFileUint8List();
- print("$pngBytes------------------------------");
- String sTempDir = (await getTemporaryDirectory()).path;
- bool isDirExist = await Directory(sTempDir).exists();
- if (!isDirExist) {
- Directory(sTempDir).create();
- }
- // QQ分享需要一个确实存在的图片
- File file = await File(sTempDir + "/poster-temp-${DateTime.now().millisecondsSinceEpoch}.png").writeAsBytes(pngBytes);
- Future.delayed(new Duration(milliseconds: 200));
- print("[file]:${file.readAsBytesSync().length}---------------${pngBytes.length}----------------");
- return file.path;
- }
- Future<Uint8List> initFileUint8List() async {
- if(widget.poster == null) return Uint8List.fromList([0]);
- try {
- RenderObject? renderObject = widget.poster!.currentContext?.findRenderObject();
- //boundary.toImage()转化为ui.Image对象,不会自动为包裹的组件添加背景,不设置可能会缺失背景
- if(renderObject is RenderRepaintBoundary) {
- RenderRepaintBoundary boundary = renderObject;
- var image = await boundary.toImage(pixelRatio: window.devicePixelRatio);
- //将image转化为byteData
- ByteData? byteData = await image.toByteData(format: ImageByteFormat.png);
- if (byteData == null) return Uint8List.fromList([0]);
- //这个对象就是图片数据
- Uint8List pngBytes = byteData.buffer.asUint8List();
- print("成功生成图片 ----------------------------------------");
- return pngBytes;
- }
- } catch (e) {
- print(e);
- }
- return Uint8List.fromList([0]);
- }
- Future<File?> _capture() async {
- var permission = await Permission.storage.request();
- if (!permission.isGranted) {
- ToastUtil.show("没有保存文件的权限");
- return null;
- }
- var result ;
- if (widget.file?.isNotEmpty == true) {
- result = await ImageGallerySaver.saveFile(widget.file!);
- }else {
- Uint8List pngBytes = await initFileUint8List();
- result = await ImageGallerySaver.saveImage(pngBytes);
- }
- if (result != null && result["isSuccess"] == true) ToastUtil.show("下载成功");
- }
- @override
- Widget build(BuildContext context) {
- return Container(
- margin: EdgeInsets.fromLTRB(12, 23, 24, 17),
- child: Column(
- mainAxisSize: MainAxisSize.min,
- children: <Widget>[
- Row(
- children: <Widget>[
- Expanded(
- child: Divider(
- endIndent: 12.0,
- ),
- ),
- Text(
- "分享至",
- style: Theme.of(context).textTheme.bodyText2!,
- ),
- Expanded(
- child: Divider(
- indent: 12.0,
- ),
- )
- ],
- ),
- SizedBox(
- height: 20.0,
- ),
- Wrap(
- children: map
- .map((e) => InkWell(
- child: FractionallySizedBox(
- widthFactor: .25,
- child: Container(
- padding: EdgeInsets.symmetric(horizontal: 5, vertical: 6),
- child: Center(
- child: Column(
- mainAxisSize: MainAxisSize.min,
- crossAxisAlignment: CrossAxisAlignment.center,
- children: <Widget>[
- Image.asset(
- "lib/assets/img/${e["url"]}.png",
- width: 44.0,
- height: 44.0,
- ),
- Space(
- height: 4.0,
- ),
- Text(
- "${e["value"]}",
- style: Theme.of(context).textTheme.subtitle2,
- ),
- // Space(height: 8.0,),
- ],
- ),
- ),
- )),
- onTap: () {
- e["callBack"]();
- },
- ))
- .toList(),
- )
- ],
- ),
- );
- }
- }
- Future<bool?> menuShareBottom(BuildContext context, String shareType, {Post? post, String? url, bool hasDownload = true, GlobalKey? poster, String? hash}) {
- return showModalBottomSheet(
- context: context,
- builder: (context) {
- return MenuShareBottomContent(shareType, post: post, url: url, hasDownload: hasDownload, poster: poster, hash: hash);
- },
- backgroundColor: Colors.white,
- elevation: 10,
- shape: RoundedRectangleBorder(
- borderRadius: BorderRadius.only(topLeft: Radius.circular(10), topRight: Radius.circular(10)),
- ),
- );
- }
|