import 'dart:convert'; import 'dart:ui'; import 'package:chewie/chewie.dart'; import 'package:dio/dio.dart'; import 'package:flutter/material.dart'; import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:flutter_svg/svg.dart'; import 'package:huixiang/generated/l10n.dart'; import 'package:huixiang/retrofit/data/article.dart'; import 'package:huixiang/retrofit/data/base_data.dart'; import 'package:chewie/src/chewie_progress_colors.dart' as chewie; import 'package:huixiang/retrofit/retrofit_api.dart'; import 'package:huixiang/utils/font_weight.dart'; import 'package:huixiang/view_widget/border_text.dart'; import 'package:huixiang/view_widget/custom_image.dart'; import 'package:huixiang/view_widget/round_button.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:huixiang/view_widget/share_dialog.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:sharesdk_plugin/sharesdk_defines.dart'; import 'package:sharesdk_plugin/sharesdk_interface.dart'; import 'package:sharesdk_plugin/sharesdk_map.dart'; import 'package:video_player/video_player.dart'; import '../photo_view_gallery_screen.dart'; class CommunityDynamic extends StatefulWidget { final int itemCount; final Function(double height) heightFun; final bool isDetails; final int commentType; final Function removalDynamic; final Function exitFull; final bool isList; final Article article; final String userId; CommunityDynamic( this.article, this.commentType, { Key key, this.itemCount = 9, this.heightFun, this.isDetails = false, this.removalDynamic, this.exitFull, this.userId, this.isList = false, }) : super(key: key); @override State createState() { return _CommunityDynamic(); } } class _CommunityDynamic extends State { GlobalKey globalKey = GlobalKey(); double height = 0; ApiService apiService; VideoPlayerController videoPlayerController; ChewieController chewieAudioController; Chewie chewies; @override void initState() { super.initState(); initVideo(); } String filePath; initVideo() async { if (widget?.article?.content == null) return; var cnt = jsonDecode(widget.article.content); if (cnt["type"] == "video" && cnt["video"] != null) { if (widget.isList) { videoPlayerController = VideoPlayerController.network( cnt["video"], )..initialize().then((value) {}); } else { videoPlayerController = VideoPlayerController.network( cnt["video"], )..initialize().then((value) { chewieAudioController = ChewieController( videoPlayerController: videoPlayerController, aspectRatio: videoPlayerController.value.aspectRatio, //宽高比 autoPlay: false, //自动播放 looping: true, //循环播放 allowFullScreen: true, // 拖动条样式颜色 materialProgressColors: chewie.ChewieProgressColors( playedColor: Colors.white, handleColor: Colors.white, backgroundColor: Colors.grey, bufferedColor: Colors.transparent, ), autoInitialize: true, ); chewieAudioController.addListener(_fullScreenListener); if (mounted) setState(() {}); }); } } } ///关注/取关会员 _vipFollow(followId, isFollow) async { if (apiService == null) { SharedPreferences value = await SharedPreferences.getInstance(); apiService = ApiService( Dio(), context: context, token: value.getString("token"), ); } BaseData baseData = await apiService.follow(followId ?? ""); if (baseData != null && baseData.isSuccess) { widget.exitFull(); SmartDialog.showToast(isFollow ? "关注成功" : "取关成功", alignment: Alignment.center); setState(() {}); } else { SmartDialog.showToast(baseData.msg, alignment: Alignment.center); } } ///删除动态 _deleteDynamic(id) async { if (apiService == null) { SharedPreferences value = await SharedPreferences.getInstance(); apiService = ApiService( Dio(), context: context, token: value.getString("token"), ); } BaseData baseData = await apiService.deleteTrend(id); if (baseData != null && baseData.isSuccess) { widget.exitFull(); SmartDialog.showToast("删除成功", alignment: Alignment.center); setState(() {}); } else { // SmartDialog.showToast(baseData.msg, alignment: Alignment.center); } } ///给文章/活动点赞 _queryInformationLikes(isLikes) async { if (apiService == null) { SharedPreferences value = await SharedPreferences.getInstance(); apiService = ApiService( Dio(), context: context, token: value.getString("token"), ); } BaseData baseData = await apiService .informationLikes(widget.article.id) .catchError((onError) {}); if (baseData != null && baseData.isSuccess) { widget.exitFull(); setState(() {}); } } goPersonalPage() async { await Navigator.of(context).pushNamed('/router/personal_page', arguments: { "memberId": (widget.article.author == widget.userId) ? "0" : widget.article.author, }); widget.exitFull(); } @override Widget build(BuildContext context) { return Column( children: [ Container( margin: EdgeInsets.only(top: 2.h), key: globalKey, alignment: Alignment.topCenter, padding: EdgeInsets.only(left: 16.w, top: 16.h, right: 16.w), decoration: BoxDecoration( color: Colors.white, boxShadow: [ BoxShadow( color: Color(0x08000000), offset: Offset(0, 1), blurRadius: 8, spreadRadius: 0, ), ], ), child: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.center, children: [ Container( // height: 44.h, child: Row( children: [ GestureDetector( onTap: () { // Navigator.push( // context, // MaterialPageRoute( // builder: (context) => PhotoViewGalleryScreen( // images: [(widget?.article?.authorHeadImg ?? "").isEmpty? // "https://lmg.jj20.com/up/allimg/tx30/09041130358711081.jpg":widget?.article?.authorHeadImg // ], //传入图片list // index: 0, //传入当前点击的图片的index // ), // )); goPersonalPage(); }, child: MImage( (widget?.article?.authorHeadImg ?? ""), width: 44, height: 44, isCircle: true, fit: BoxFit.cover, errorSrc: "assets/image/default_1.webp", fadeSrc: "assets/image/default_1.webp", ), ), SizedBox( width: 8.w, ), Column( mainAxisAlignment: MainAxisAlignment.spaceEvenly, crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( widget?.article?.authorName ?? "", style: TextStyle( fontSize: MediaQuery.of(context).size.width >= 650 ? 12.sp : 15.sp, fontWeight: MyFontWeight.semi_bold, color: Color(0xFF1A1A1A), ), ), Text( widget?.article?.createTime ?? "", style: TextStyle( fontSize: MediaQuery.of(context).size.width >= 650 ? 10.sp : 13.sp, fontWeight: MyFontWeight.regular, color: Color(0xFF808080), ), ), ], ), ], ), ), if (widget?.article?.author != widget.userId ?? "") GestureDetector( behavior: HitTestBehavior.opaque, onTap: () { setState(() { if (widget.commentType == 0) { widget.article.followed = !(widget.article.followed ?? false); _vipFollow(widget.article.author, widget.article.followed ?? false); } else { showDeleteDialog(); } }); }, child: (widget.commentType == 0) ? Container( width: 56.w, height: 25.h, alignment: Alignment.center, child: RoundButton( height: 25.h, backgroup: (widget?.article?.followed ?? false) ? Color(0xFFE6E6E6) : Color(0xFF32A060), textColor: (widget?.article?.followed ?? false) ? Color(0xFF808080) : Colors.white, text: (widget?.article?.followed ?? false) ? S.of(context).yiguanzhu : S.of(context).guanzhu, radius: 20, icons: Icon( (widget?.article?.followed ?? false) ? Icons.check : Icons.add, color: (widget?.article?.followed ?? false) ? Color(0xFF808080) : Colors.white, size: 15, ), )) : Padding( padding: EdgeInsets.all(20), child: Icon( Icons.close, color: Colors.black, size: 16, ), ), ), ], ), SizedBox( height: 12.h, ), widget.isList ? Text( widget?.article?.mainTitle ?? "", maxLines: 5, overflow: TextOverflow.ellipsis, style: TextStyle( color: Color(0xFF1A1A1A), fontWeight: MyFontWeight.regular, fontSize: 15.sp, ), ) : Text( widget?.article?.mainTitle ?? "", style: TextStyle( color: Color(0xFF1A1A1A), fontWeight: MyFontWeight.regular, fontSize: 15.sp, ), ), buildMedia(widget?.article?.content), SizedBox( height: 8.h, ), if (widget.article.location != "") Padding( padding: EdgeInsets.only(bottom: 7), child: Row( children: [ Icon( Icons.place, size: 16, color: Color(0xFFB3B2B2), ), SizedBox( width: 2, ), Expanded( child: Text( widget?.article?.location ?? "", overflow: TextOverflow.ellipsis, maxLines: 1, style: TextStyle( fontSize: 12.sp, fontWeight: MyFontWeight.medium, color: Color(0xFFB3B2B2), ), )), ], ), ), if (!widget.isDetails) SizedBox( height: 5.h, ), if (!widget.isDetails) Container( // padding: EdgeInsets.only(bottom: 16), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.center, children: [ Expanded( child: Container( padding: EdgeInsets.only(bottom: 16.h), child: Row( children: [ SvgPicture.asset( "assets/svg/liulanliang.svg", width: 16, height: 16, ), SizedBox( width: 5.w, ), Text( (widget.article != null) ? "${widget.article.viewers}" : "", style: TextStyle( fontSize: 14.sp, fontFamily: 'JDZhengHT', fontWeight: MyFontWeight.regular, color: Color(0xFF1A1A1A), ), ), ], )), ), Expanded( child: Container( padding: EdgeInsets.only(bottom: 16.h), child: Row( children: [ SvgPicture.asset( "assets/svg/pinglun.svg", width: 16, height: 16, ), SizedBox( width: 5.w, ), Text( "${widget.article.comments ?? 0}", style: TextStyle( fontSize: 14.sp, fontFamily: 'JDZhengHT', fontWeight: MyFontWeight.regular, color: Color(0xFF1A1A1A), ), ), ], ))), Expanded( child: GestureDetector( behavior: HitTestBehavior.opaque, onTap: () { setState(() { widget.article.liked = !(widget.article.liked ?? false); _queryInformationLikes( widget.article.liked ?? false); }); }, child: Container( padding: EdgeInsets.only(bottom: 16.h), child: Row( children: [ (widget.article.liked ?? false) ? Image.asset( "assets/image/icon_like.webp", width: 16, height: 16, ) : Image.asset( "assets/image/icon_like_h.webp", width: 16, height: 16, ), SizedBox( width: 5.w, ), Text( "${widget.article.likes ?? 0}", style: TextStyle( fontSize: 14.sp, fontFamily: 'JDZhengHT', fontWeight: MyFontWeight.regular, color: Color(0xFF1A1A1A), ), ), ], )), )), if ((widget?.article?.author != widget.userId ?? "") && widget.commentType == 0) Expanded( child: GestureDetector( behavior: HitTestBehavior.opaque, onTap: () { setState(() { choiceShowBottomSheet(); }); }, child: Container( padding: EdgeInsets.only(top: 3.h, bottom: 16.h), alignment: Alignment.center, // color: Colors.red, child: Icon( Icons.more_horiz, color: Colors.black, ), ))), ], ), ), ], ), ), Container( height: 16.h, color: Color(0xFFF7F7F7), ), ], ); } share() async { SSDKMap params = SSDKMap() ..setGeneral( widget?.article?.mainTitle ?? "", "", [ widget?.article?.content != null && widget.article.content.contains("images\":[\"") ? jsonDecode(widget.article.content)["images"][0] : "", widget?.article?.content != null && widget.article.content.contains("video\":[\"") ? jsonDecode(widget.article.content)["video"][0] : "", ], widget?.article?.content != null && widget.article.content.contains("images\":[\"") ? jsonDecode(widget.article.content)["images"][0] : "", widget?.article?.content != null && widget.article.content.contains("video\":[\"") ? jsonDecode(widget.article.content)["video"][0] : "", buildShareUrl(), "", "", "", "", SSDKContentTypes.webpage, ); showModalBottomSheet( context: context, backgroundColor: Colors.transparent, builder: (context) { return ShareDialog((platform) { if (platform == ShareSDKPlatforms.line) { params.map["type"] = SSDKContentTypes.text.value; params.map["text"] = "${widget?.article?.mainTitle ?? ""} ${buildShareUrl()}"; } SharesdkPlugin.share(platform, params, (state, userData, contentEntity, error) { print("share!$state"); }); }); }); } String buildShareUrl() { return "https://hx.lotus-wallet.com/communityShare.html?id=${widget.article.id}"; } ///动态内容 Widget buildMedia(String subjectInfo) { if (subjectInfo == null || !subjectInfo.startsWith("{")) { return Container(); } var cnt = jsonDecode(subjectInfo); Widget itemWidget = Container(); if (cnt["type"] == "image" && cnt["images"] != null && cnt["images"].length > 0) { if (cnt["images"].length == 1) { itemWidget = Container( child: InkWell( onTap: () { // ImagePickers.previewImages(subjectInfo.images,0); Navigator.push( context, MaterialPageRoute( builder: (context) => PhotoViewGalleryScreen( images: cnt["images"], //传入图片list index: 0, //传入当前点击的图片的index ), ), ); }, child: MImage( cnt["images"][0], fit: BoxFit.contain, radius: BorderRadius.circular(2), height: MediaQuery.of(context).size.width / 1.5, errorSrc: "assets/image/default_2_1.webp", fadeSrc: "assets/image/default_2_1.webp", )), ); } else { itemWidget = GridView.builder( gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: (cnt["images"].length == 2 || cnt["images"].length == 4) ? 2 : 3, crossAxisSpacing: 12.w, mainAxisSpacing: 12.w, childAspectRatio: 1, ), padding: EdgeInsets.zero, shrinkWrap: true, physics: NeverScrollableScrollPhysics(), itemBuilder: (context, position) { return Container( child: InkWell( onTap: () { // ImagePickers.previewImages(subjectInfo.images, position); Navigator.push( context, MaterialPageRoute( builder: (context) => PhotoViewGalleryScreen( images: cnt["images"], //传入图片list index: position, //传入当前点击的图片的index ), ), ); }, child: MImage( cnt["images"][position], fit: BoxFit.cover, aspectRatio: 1, radius: BorderRadius.circular(1), errorSrc: "assets/image/default_2_1.webp", fadeSrc: "assets/image/default_2_1.webp", ), ), ); }, itemCount: cnt["images"].length, ); } } else if (cnt["type"] == "video" && cnt["video"] != null && cnt["video"].isNotEmpty) { itemWidget = videoWidget( MediaQuery.of(context).size.width - 32, videoPlayerController != null ? (MediaQuery.of(context).size.width - 32) / videoPlayerController.value.aspectRatio : MediaQuery.of(context).size.width / 2, cnt["video"].replaceAll(".mp4", "_poster.jpg"), ); } return Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ SizedBox( height: 16.h, ), itemWidget, ], ); } @override void dispose() { super.dispose(); if (chewieAudioController != null) { chewieAudioController.pause(); chewieAudioController.dispose(); chewieAudioController = null; } if (videoPlayerController != null) { videoPlayerController.pause(); videoPlayerController.dispose(); } } Widget videoWidget(double width, double height, src) { return MediaQuery( data: MediaQuery.of(context).copyWith( textScaleFactor: 0.9, ), child: !widget.isList ? (chewieAudioController != null ? Container( width: width, height: height, child: chewies = Chewie( controller: chewieAudioController, ), ) : Container( width: width, height: height, )) : Container( width: width, height: width / 7 * 5, color: Colors.black, child: Stack( children: [ Container( width: double.infinity, height: double.infinity, child: MImage( src, aspectRatio: videoPlayerController != null ? videoPlayerController.value.aspectRatio : (width / 7 * 5), fit: BoxFit.cover, errorSrc: "assets/image/default_2_1.webp", fadeSrc: "assets/image/default_2_1.webp", ), ), Center( child: Icon( Icons.play_circle_outline, color: Colors.white, size: 60, ), ), ], ), ), ); } Future _fullScreenListener() async { if (!chewieAudioController.isFullScreen) { Future.delayed(Duration(seconds: 1), () { widget.exitFull(); }); } } ///删除动态弹窗 showDeleteDialog() { showDialog( context: context, builder: (context) { return AlertDialog( content: Container( width: MediaQuery.of(context).size.width - 84, height: 130.h, child: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: [ Text( S.of(context).quedingyaoshanchudongtai, style: TextStyle( fontSize: 17.sp, fontWeight: FontWeight.bold, color: Colors.black, ), ), SizedBox( height: 30.h, ), Row( children: [ Expanded( child: InkWell( child: BorderText( text: S.of(context).quxiao, textColor: Color(0xFF32A060), fontSize: 16.sp, fontWeight: FontWeight.bold, borderColor: Color(0xFF32A060), radius: 4, padding: EdgeInsets.all(12), borderWidth: 1, ), onTap: () { Navigator.of(context).pop(); }, ), flex: 1, ), SizedBox( width: 16.w, ), Expanded( child: InkWell( child: RoundButton( text: S.of(context).queding, textColor: Colors.white, radius: 4, padding: EdgeInsets.all(12), backgroup: Color(0xFF32A060), fontSize: 16.sp, fontWeight: FontWeight.bold, ), onTap: () { _deleteDynamic(widget.article.id); Navigator.of(context).pop(); }, ), flex: 1, ), ], ) ], ), ), ); }, ); } ///更多选择弹窗 choiceShowBottomSheet() { showModalBottomSheet( builder: (BuildContext context) { return buildBottomSheetWidget(context); }, backgroundColor: Colors.transparent, context: context); } Widget buildBottomSheetWidget(BuildContext context) { return Container( padding: EdgeInsets.all(16), decoration: new BoxDecoration( color: Colors.white, borderRadius: new BorderRadius.only( topLeft: const Radius.circular(25.0), topRight: const Radius.circular(25.0))), child: Container( height: 130.h, child: Column( children: [ GestureDetector( behavior: HitTestBehavior.translucent, onTap: () { setState(() { Navigator.of(context).pop(); share(); }); }, child: Container( width: double.infinity, margin: EdgeInsets.only(top: 10.h), padding: EdgeInsets.symmetric(vertical: 5.h), child: Row( children: [ SizedBox( width: 4.w, ), Image.asset( "assets/image/icon_share.webp", fit: BoxFit.cover, width: 25, height: 25, color: Color(0xff515151), ), SizedBox( width: 12.w, ), Text( S.of(context).fenxiang, style: TextStyle( fontSize: 17.sp, fontWeight: MyFontWeight.medium, color: Color(0xFF1A1A1A), ), ), ], ), )), Container( margin: EdgeInsets.symmetric(vertical: 12), height: 1.h, color: Color(0xFFF7F7F7), ), GestureDetector( behavior: HitTestBehavior.translucent, onTap: () { setState(() { Navigator.of(context) .popAndPushNamed('/router/report_page', arguments: { "userName": widget?.article?.authorName ?? "", "authorId": widget?.article?.author ?? "", }); }); }, child: Container( width: double.infinity, padding: EdgeInsets.symmetric(vertical: 5.h), child: Row( children: [ SizedBox( width: 4.w, ), SvgPicture.asset( "assets/svg/ju_b.svg", width: 20, height: 20, ), SizedBox( width: 15.w, ), Text( S.of(context).jubaogaineirong, style: TextStyle( fontSize: 17.sp, fontWeight: MyFontWeight.medium, color: Color(0xFF1A1A1A), ), ), ], ), )) ], ), )); } @override void didChangeDependencies() { if (widget.heightFun != null) WidgetsBinding.instance.addPostFrameCallback(_getContainerHeight); super.didChangeDependencies(); } _getContainerHeight(_) { if (globalKey.currentContext != null) height = globalKey.currentContext.size.height; if (widget.heightFun != null) widget.heightFun(height); print("height: $height"); } }