import 'dart:io'; import 'dart:ui'; import 'package:dio/dio.dart'; import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:huixiang/data/activity.dart'; import 'package:huixiang/data/article.dart'; import 'package:huixiang/data/base_data.dart'; import 'package:huixiang/data/examine_instance.dart'; import 'package:huixiang/generated/l10n.dart'; import 'package:huixiang/retrofit/retrofit_api.dart'; import 'package:huixiang/view_widget/my_appbar.dart'; import 'package:huixiang/view_widget/share_dialog.dart'; import 'package:huixiang/view_widget/tips_dialog.dart'; import 'package:huixiang/web/web_view/comment_list.dart'; import 'package:huixiang/web/web_view/input_comment.dart'; import 'package:huixiang/web/web_view/web_content.dart'; import 'package:huixiang/web/web_view/web_header.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:dio/dio.dart'; class WebPage extends StatefulWidget { final Map? arguments; ///富文本 文章 活动 WebPage({this.arguments}); @override State createState() { return _WebPage(); } } class _WebPage extends State with WidgetsBindingObserver { ApiService? apiService; int commentTotal = 0; String hintText = S.current.liuxianinjingcaidepinglunba; var commentFocus = FocusNode(); String parenId = "0"; Activity? activity; Article? article; final double fontSize = 16.sp; final GlobalKey commentKey = GlobalKey(); final GlobalKey inputKey = GlobalKey(); final ScrollController scrollController = ScrollController(); final TextEditingController commentTextController = TextEditingController(); bool emojiShowing = false; double keyboard = -1; bool needShowSmiley = false; bool needHideSmiley = false; @override void initState() { super.initState(); WidgetsBinding.instance.addObserver(this); commentFocus.addListener(_focusNodeListener); SharedPreferences.getInstance().then((value) => { apiService = ApiService( Dio(), context: context, token: value.getString('token'), showLoading: true ), queryHtml() }); } bool isKeyBoardShow = false; @override void didChangeMetrics() { WidgetsBinding.instance.addPostFrameCallback((_) { isKeyBoardShow = MediaQuery.of(context).viewInsets.bottom > 0; if (MediaQuery.of(context).viewInsets.bottom == 0) { if (isKeyBoardShow) { FocusScope.of(context).requestFocus(FocusNode()); if(!emojiShowing) setState(() { hintText = S.current.liuxianinjingcaidepinglunba; isKeyBoardShow = false; }); } } else { setState(() { isKeyBoardShow = true; }); } }); if (needShowSmiley && window.viewInsets.bottom <= 0.1) { needShowSmiley = false; setState(() { emojiShowing = true; }); } if(needHideSmiley && window.viewInsets.bottom > 0.1) { needHideSmiley = false; setState(() { emojiShowing = false; }); } } void _focusNodeListener() { /*if (_focusNode.hasFocus || _focusNode.consumeKeyboardToken()){ setState(() { smileyPadGone = true; }); }*/ } _onTextFieldTap() { if(emojiShowing) { needHideSmiley = true; } } _onSmileyTap() { if(!emojiShowing && commentFocus.hasFocus && isKeyBoardShow) { needShowSmiley = true; commentFocus.unfocus(); } else { setState(() { emojiShowing = !emojiShowing; isKeyBoardShow = emojiShowing; }); } } @override void dispose(){ WidgetsBinding.instance.removeObserver(this); commentFocus.removeListener(_focusNodeListener); super.dispose(); } queryHtml() async { SharedPreferences value = await SharedPreferences.getInstance(); apiService = ApiService(Dio(), // showLoading: true, context: context, token: value.getString("token")); if (widget.arguments?["activityId"] != null) { BaseData? baseData = await apiService?.activityInfo(widget.arguments!["activityId"]) .catchError((onError) { return Future.value(null); }); if (baseData?.isSuccess ?? false) { activity = baseData?.data; setState(() {}); } } if (widget.arguments?["articleId"] != null) { BaseData
? baseData = await apiService?.informationInfo(widget.arguments!["articleId"]) .catchError((onError) { return Future.value(null); }); if (baseData?.isSuccess ?? false) { article = baseData?.data; setState(() {}); } } } //发布评论 _queryMemberComment(String content) async { BaseData? baseData = await apiService?.memberComment({ "content": content, "parentId": parenId, "relationalId": widget.arguments?["activityId"] ?? widget.arguments?["articleId"], "relationalType": 1 }).catchError((error) { return Future.value(null); }); if (baseData?.isSuccess ?? false) { CommentListState _commentList = commentKey.currentState as CommentListState; _commentList.queryMemberCommentList(); commentTextController.text = ""; FocusScope.of(context).unfocus(); _toComment(); } } share() async { SSDKMap params = SSDKMap() ..setGeneral( activity?.mainTitle ?? article?.mainTitle ?? "", activity != null ? activity!.viceTitle : article != null ? article!.viceTitle : "", [ activity != null ? activity!.coverImg : article != null ? article!.coverImg : "", ], activity!.coverImg ?? article!.coverImg ?? "", "", 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"] = "${activity != null ? activity!.viceTitle : article != null ? article!.viceTitle : ""} ${buildShareUrl()}"; } SharesdkPlugin.share(platform, params, (state, userData, contentEntity, error) { print("share!$state"); }); }); }); } String buildShareUrl() { return "https://hx.lotus-wallet.com/index.html?id=${widget.arguments?["activityId"] ?? widget.arguments?["articleId"]}&type=${activity != null ? "activity" : article != null ? "article" : ""}"; } //给文章/活动点赞 _queryInformationLikes() async { BaseData? baseData = await apiService?.informationLikes(widget.arguments?["activityId"] ?? widget.arguments?["articleId"]) .catchError((onError) { return Future.value(null); }); if (baseData?.isSuccess ?? false) { if (article != null) { int likes = article!.likes ?? 0; if (article!.liked ?? false) { article!.likes = (likes - 1); } else { article!.likes = (likes + 1); } article!.liked = !(article!.liked ?? false); } commentKey.currentState?.setState(() {}); } else { // SmartDialog.showToast(baseData.msg, alignment: Alignment.center); } } @override Widget build(BuildContext context) { double h = MediaQuery.of(context).viewInsets.bottom; if(h > 0 && keyboard < h) { setState(() { keyboard = h; }); } return GestureDetector( behavior: HitTestBehavior.translucent, onTap: () { setState(() { emojiShowing = false; isKeyBoardShow = emojiShowing; FocusScope.of(context).requestFocus(FocusNode()); }); }, child:Scaffold( appBar: MyAppBar( action: Container( margin: EdgeInsets.only(right: 10), child: GestureDetector( onTap: () { share(); }, child: Icon( Icons.share, size: 24, color: Colors.black, ), ), ), background: Color(0xFFFFFFFFF), leadingColor: Colors.black, title: activity!.mainTitle ?? article!.mainTitle ?? "", titleSize: fontSize, titleColor: Colors.black, ), body: Container( child: Column( children: [ Expanded( child: GestureDetector( onTap: () { commentFocus.unfocus(); hintText = S.of(context).liuxianinjingcaidepinglunba; inputKey.currentState?.setState(() {}); parenId = "0"; }, child: SingleChildScrollView( controller: scrollController, physics: BouncingScrollPhysics(), child: Column( children: [ /// 富文本的头部 WebHeader(widget.arguments, activity, article, 16), /// 富文本的内容 WebContent( activity, article, apiService, () { setState(() {}); }, ), /// 富文本的评论 if(!ExamineInstance.instance.isExamine) CommentList( commentKey, article?.likes ?? activity?.likes ?? 0, widget.arguments?["activityId"] ?? widget.arguments?["articleId"], 1, isKeyBoardShow, _reply, _delCommentTips, 12.sp, requestApiFinish: (total) { setState(() { commentTotal = total; }); }, ), ], ), ), ), flex: 1, ), /// 富文本评论的输入框 if(!ExamineInstance.instance.isExamine) InputComment( inputKey, hintText, isKeyBoardShow, keyboard, emojiShowing, commentFocus, commentTextController, _toComment, _onSmileyTap, _onTextFieldTap, _queryMemberComment, _queryInformationLikes, activity: activity, article: article, ), ], ), ), )); } ///删除评论的提示 _delCommentTips(memberComment) { SmartDialog.show(widget: Tips(() { delComment(memberComment); })); } ///删除评论 delComment(memberComment) async { BaseData? baseData = await apiService?.delComment(memberComment.id) .catchError((onError) { return Future.value(null); }); if (baseData?.isSuccess ?? false) { CommentListState _commentList = commentKey.currentState as CommentListState; _commentList.queryMemberCommentList(); } } ///评论 回复 _reply(memberComment) { FocusScope.of(context).requestFocus(commentFocus); parenId = memberComment.id; hintText = S.of(context).huifu_("${memberComment.username}"); } ///滑动到评论列表 _toComment() { if (commentKey.currentContext == null) return; RenderBox firstRenderBox = commentKey.currentContext!.findRenderObject() as RenderBox; Offset first = firstRenderBox.localToGlobal(Offset.zero); scrollController.animateTo( first.dy + scrollController.offset - (kToolbarHeight + MediaQuery.of(context).padding.top), duration: Duration(milliseconds: 300), curve: Curves.easeIn); } }