diff --git a/lib/article/hot_article_item.dart b/lib/article/hot_article_item.dart index bf9a17e8..da2e7b54 100644 --- a/lib/article/hot_article_item.dart +++ b/lib/article/hot_article_item.dart @@ -108,11 +108,12 @@ class _HotArticlePage extends State { scrollDirection: Axis.vertical, itemBuilder: (context, position) { return AspectRatio( - aspectRatio: position == 0 ? 1.38 : 3.56, + aspectRatio: position == 0 ? 1.38 : 2.56, child: Container( height: position == 0 ? 247.h : 96.h, - margin: EdgeInsets.symmetric(vertical: 6.h, horizontal: 16.w), - child: HotArticleItem(article: articles[position], isHot: position == 0), + margin: EdgeInsets.symmetric(vertical:6.h, horizontal: 16.w), + child: + HotArticleItem(article: articles[position], isHot: position == 0), ), ); }, diff --git a/lib/community/community_child_page.dart b/lib/community/community_child_page.dart index 0f0660a5..db8e8666 100644 --- a/lib/community/community_child_page.dart +++ b/lib/community/community_child_page.dart @@ -11,6 +11,10 @@ import 'package:pull_to_refresh/pull_to_refresh.dart'; import 'package:shared_preferences/shared_preferences.dart'; class CommunityChildPage extends StatefulWidget { + final String typeStr; + + CommunityChildPage(this.typeStr); + @override State createState() { return _CommunityChildPage(); @@ -47,7 +51,7 @@ class _CommunityChildPage extends State { } BaseData> baseData = await apiService.trendList({ - "onlyFollow": false, + "onlyFollow": widget.typeStr == "关注" ? true:false, "onlyMe": false, "pageNum": pageNum, "pageSize": 10, @@ -95,7 +99,7 @@ class _CommunityChildPage extends State { physics: NeverScrollableScrollPhysics(), itemBuilder: (context, position) { return InkWell( - child: CommunityDynamic(comments[position]), + child: CommunityDynamic(comments[position],0), onTap: () { Navigator.of(context).pushNamed( '/router/community_details', diff --git a/lib/community/community_details.dart b/lib/community/community_details.dart index ade0e947..705705d0 100644 --- a/lib/community/community_details.dart +++ b/lib/community/community_details.dart @@ -8,6 +8,7 @@ import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:huixiang/retrofit/data/base_data.dart'; import 'package:huixiang/retrofit/data/comunity_comment.dart'; import 'package:huixiang/retrofit/data/member_comment_list.dart'; +import 'package:huixiang/retrofit/data/page.dart'; import 'package:huixiang/retrofit/retrofit_api.dart'; import 'package:huixiang/utils/font_weight.dart'; import 'package:huixiang/view_widget/comment_menu.dart'; @@ -17,22 +18,24 @@ import 'package:huixiang/web/web_view/input_comment.dart'; import 'package:shared_preferences/shared_preferences.dart'; class CommunityDetails extends StatefulWidget { - - // final ComunityComment arguments; final Map arguments; CommunityDetails({this.arguments}); - @override State createState() { return _CommunityDetails(); } } -class _CommunityDetails extends State { +class _CommunityDetails extends State + with WidgetsBindingObserver { double height = 0; double commentHeight = 60.h; + ComunityComment comunity; + String parenId = "0"; + final GlobalKey commentKey = GlobalKey(); + final ScrollController scrollController = ScrollController(); List memberList = []; ApiService apiService; @@ -41,9 +44,12 @@ class _CommunityDetails extends State { String hintText = S.current.liuxianinjingcaidepinglunba; bool isKeyBoardShow = false; + int commentTotal = 0; + @override void didChangeMetrics() { WidgetsBinding.instance.addPostFrameCallback((_) { + if (!mounted) return; if (MediaQuery.of(context).viewInsets.bottom == 0) { if (isKeyBoardShow) { FocusScope.of(context).requestFocus(FocusNode()); @@ -63,7 +69,10 @@ class _CommunityDetails extends State { @override void initState() { super.initState(); + comunity = widget.arguments["comment"]; + WidgetsBinding.instance.addObserver(this); + _queryMemberCommentList(); SharedPreferences.getInstance().then((value) { apiService = ApiService( Dio(), @@ -75,14 +84,17 @@ class _CommunityDetails extends State { @override Widget build(BuildContext context) { - return Column( + return Scaffold( + body: Container( + child: Column( children: [ Expanded( child: NestedScrollView( headerSliverBuilder: (context, position) { return [ SliverOverlapAbsorber( - handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context), + handle: + NestedScrollView.sliverOverlapAbsorberHandleFor(context), sliver: SliverAppBar( expandedHeight: (height == 0) ? 614 : height, pinned: true, @@ -120,7 +132,7 @@ class _CommunityDetails extends State { ), color: Colors.white, child: CommunityDynamic( - widget.arguments["comment"], + comunity,0, itemCount: 3, isDetails: true, heightFun: (height) { @@ -146,7 +158,7 @@ class _CommunityDetails extends State { child: Row( children: [ Text( - S.of(context).pinglun_("1"), + S.of(context).pinglun_(commentTotal.toString()), style: TextStyle( fontSize: 14, fontWeight: FontWeight.bold, @@ -157,7 +169,8 @@ class _CommunityDetails extends State { width: 16.w, ), Text( - S.of(context).xihuan_("0"), + S.of(context).xihuan_( + "${comunity?.likes ?? comunity?.likes ?? "0"}"), style: TextStyle( fontSize: 14, fontWeight: FontWeight.bold, @@ -177,11 +190,11 @@ class _CommunityDetails extends State { MediaQuery.of(context).padding.top + kToolbarHeight - 68, - margin: EdgeInsets.only(top: 68 + 50 + kToolbarHeight), + margin: EdgeInsets.only(top: 50 + kToolbarHeight), child: Column( children: [ if (memberList != null && memberList.length > 0) - ListView.builder( + Expanded(child: ListView.builder( shrinkWrap: true, physics: NeverScrollableScrollPhysics(), itemCount: memberList != null ? memberList.length : 0, @@ -197,35 +210,12 @@ class _CommunityDetails extends State { child: CommunityComment( memberList[position], _queryCommentLike, + (memberList.length-1 == position)?1:0 ), ), ); }, - ), - if (memberList != null && memberList.length > 0) - Container( - height: commentHeight, - decoration: BoxDecoration( - color: Color(0xFFF2F2F2), - boxShadow: [ - BoxShadow( - color: Colors.black.withAlpha(12), - offset: Offset(0, 2), - blurRadius: 14, - spreadRadius: 0, - ), - ], - ), - alignment: Alignment.topCenter, - padding: EdgeInsets.only(top: 22.h), - child: Text( - S.of(context).yixiansquanbupinglun, - style: TextStyle( - fontSize: 12, - color: Color(0xff353535), - ), - ), - ), + )), if (memberList == null || memberList.length == 0) Container( width: double.infinity, @@ -257,46 +247,54 @@ class _CommunityDetails extends State { _toComment, _queryMemberComment, _queryInformationLikes, + isLike: comunity.selfLike, ), ], - ); + ))); } - //给文章/活动点赞 + ///给文章/活动点赞 _queryInformationLikes() async { - BaseData baseData = await apiService.informationLikes(""); + BaseData baseData = await apiService.informationLikes(comunity.id); if (baseData != null && baseData.isSuccess) { // commentKey.currentState.setState(() {}); + setState(() { + if(comunity.selfLike??false) + comunity.likes -= 1; + else comunity.likes += 1; + comunity.selfLike = !comunity.selfLike??false; + }); } else { SmartDialog.showToast(baseData.msg, alignment: Alignment.center); } } - //发布评论 + ///发布评论 _queryMemberComment(String content) async { - // BaseData baseData = await apiService.memberComment({ - // "content": content, - // "parentId": parenId, - // "relationalId": - // widget.arguments["activityId"] ?? widget.arguments["articleId"], - // "relationalType": 1 - // }).catchError((error) {}); - // if (baseData != null && baseData.isSuccess) { - // commentKey.currentState.initState(); - // commentTextController.text = ""; - // _toComment(); - // } + BaseData baseData = await apiService.memberComment({ + "content": content, + "parentId": parenId, + "relationalId": comunity.id, + "relationalType": 1 + }).catchError((error) {}); + if (baseData != null && baseData.isSuccess) { + // commentKey.currentState.initState(); + commentTextController.text = ""; + _toComment(); + } } ///滑动到评论列表 _toComment() { - // if (commentKey.currentContext == null) return; - // RenderBox firstRenderBox = commentKey.currentContext.findRenderObject(); - // 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); + if (commentKey.currentContext == null) return; + RenderBox firstRenderBox = commentKey.currentContext.findRenderObject(); + 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); } final GlobalKey inputKey = GlobalKey(); @@ -355,11 +353,11 @@ class _CommunityDetails extends State { ///评论 回复 _reply(memberComment) { FocusScope.of(context).requestFocus(commentFocus); - // parenId = memberComment.id; + parenId = memberComment.id; hintText = S.of(context).huifu_("${memberComment.username}"); } - //评论点赞 + ///评论点赞 _queryCommentLike(String id) async { SharedPreferences sharedPreferences = await SharedPreferences.getInstance(); String token = sharedPreferences.getString("token"); @@ -382,4 +380,29 @@ class _CommunityDetails extends State { }); } } + + ///评论列表 + _queryMemberCommentList() async { + SharedPreferences sharedPreferences = await SharedPreferences.getInstance(); + if (apiService == null) + apiService = ApiService( + Dio(), + context: context, + token: sharedPreferences.getString("token"), + showLoading: false, + ); + BaseData> baseData = + await apiService.memberCommentList({ + "pageNum": 1, + "pageSize": 100, + "relationalId": comunity.id, + "relationalType": 1, + }).catchError((error) {}); + if (baseData != null && baseData.isSuccess) { + commentTotal = baseData.data.size; + memberList = baseData.data.list; + contentHeight(); + setState(() {}); + } + } } diff --git a/lib/community/community_page.dart b/lib/community/community_page.dart index 0afd229b..b6c679e0 100644 --- a/lib/community/community_page.dart +++ b/lib/community/community_page.dart @@ -2,7 +2,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:huixiang/article/hot_article_item.dart'; import 'package:huixiang/community/community_child_page.dart'; -import 'package:huixiang/home/home_view/hot_article.dart'; import 'package:huixiang/home/huixiang_brand_page.dart'; import 'package:huixiang/view_widget/my_appbar.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; @@ -94,7 +93,7 @@ class _CommunityPage extends State }else if(e == "头条"){ return HotArticlePage(); } else { - return CommunityChildPage(); + return CommunityChildPage(e); } }).toList(), controller: tabcontroller, diff --git a/lib/community/community_view/community_comment.dart b/lib/community/community_view/community_comment.dart index 1110a120..123a9c3c 100644 --- a/lib/community/community_view/community_comment.dart +++ b/lib/community/community_view/community_comment.dart @@ -1,19 +1,17 @@ import 'package:flutter/material.dart'; import 'package:huixiang/generated/l10n.dart'; -import 'package:huixiang/retrofit/data/base_data.dart'; import 'package:huixiang/retrofit/data/member_comment_list.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:huixiang/view_widget/custom_image.dart'; -import 'package:huixiang/view_widget/login_tips_dialog.dart'; import 'package:like_button/like_button.dart'; -import 'package:shared_preferences/shared_preferences.dart'; class CommunityComment extends StatefulWidget { - MemberCommentList memberList; - Function(String id) queryCommentLike; - CommunityComment(this.memberList, this.queryCommentLike); + final MemberCommentList memberList; + final Function(String id) queryCommentLike; + final int footType; + CommunityComment(this.memberList, this.queryCommentLike,this.footType); @override State createState() { @@ -194,6 +192,29 @@ class _CommunityComment extends State { ), ), ), + if (widget.footType == 1) + Container( + decoration: BoxDecoration( + color: Color(0xFFF2F2F2), + boxShadow: [ + BoxShadow( + color: Colors.black.withAlpha(12), + offset: Offset(0, 2), + blurRadius: 14, + spreadRadius: 0, + ), + ], + ), + alignment: Alignment.topCenter, + padding: EdgeInsets.only(top: 22.h), + child: Text( + S.of(context).yixiansquanbupinglun, + style: TextStyle( + fontSize: 12, + color: Color(0xff353535), + ), + ), + ), ], ), ); diff --git a/lib/community/community_view/community_dynamic.dart b/lib/community/community_view/community_dynamic.dart index d922f0d7..4aa3aa15 100644 --- a/lib/community/community_view/community_dynamic.dart +++ b/lib/community/community_view/community_dynamic.dart @@ -1,21 +1,27 @@ +import 'package:dio/dio.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_svg/flutter_svg.dart'; +import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; +import 'package:huixiang/retrofit/data/base_data.dart'; import 'package:huixiang/retrofit/data/comunity_comment.dart'; +import 'package:huixiang/retrofit/retrofit_api.dart'; import 'package:huixiang/utils/font_weight.dart'; import 'package:huixiang/view_widget/custom_image.dart'; import 'package:huixiang/view_widget/icon_text.dart'; import 'package:huixiang/view_widget/round_button.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:shared_preferences/shared_preferences.dart'; class CommunityDynamic extends StatefulWidget { final int itemCount; final Function(double height) heightFun; final bool isDetails; + final int commentType; final ComunityComment comment; CommunityDynamic( - this.comment, { + this.comment, + this.commentType,{ Key key, this.itemCount = 9, this.heightFun, @@ -27,10 +33,27 @@ class CommunityDynamic extends StatefulWidget { return _CommunityDynamic(); } } - class _CommunityDynamic extends State { GlobalKey globalKey = GlobalKey(); double height = 0; + ApiService apiService; + + @override + void initState() { + super.initState(); + SharedPreferences.getInstance().then((value) => { + apiService = ApiService(Dio(), + context: context, token: value.getString('token')), + }); + } + + ///关注/取关会员 + _vipFollow(followId) async { + BaseData baseData = await apiService.follow(followId); + if (baseData != null && baseData.isSuccess) { + SmartDialog.showToast("关注成功"); + } + } @override Widget build(BuildContext context) { @@ -64,13 +87,14 @@ class _CommunityDynamic extends State { height: 44, child: Row( children: [ - ClipRRect( - child: Image.asset( - "assets/image/default_user.png", - width: 44, - height: 44, - ), - borderRadius: BorderRadius.circular(22), + MImage( + widget.comment != null ? widget.comment.memberInfo.avatar : "", + width: 44, + height: 44, + isCircle: true, + fit: BoxFit.cover, + errorSrc: "assets/image/default_1.png", + fadeSrc: "assets/image/default_1.png", ), SizedBox( width: 8, @@ -80,7 +104,7 @@ class _CommunityDynamic extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - "百花谷", + widget.comment != null ? widget.comment.memberInfo.nickname : "", style: TextStyle( fontSize: 14.sp, fontWeight: MyFontWeight.medium, @@ -88,7 +112,7 @@ class _CommunityDynamic extends State { ), ), Text( - "2021.04.12", + widget.comment != null ? widget.comment.createTime : "", style: TextStyle( fontSize: 12.sp, fontWeight: MyFontWeight.regular, @@ -100,21 +124,35 @@ class _CommunityDynamic extends State { ], ), ), - RoundButton( - padding: EdgeInsets.symmetric( - horizontal: 8, - vertical: 3, - ), - backgroup: Color(0xFF32A060), - textColor: Colors.white, - text: "关注", - radius: 20, - icons: SvgPicture.asset( - "assets/svg/shequ_fabu.svg", - fit: BoxFit.contain, - color: Colors.white, - width: 14, - height: 14, + GestureDetector( + onTap: (){ + setState(() { + if(widget.commentType == 0){ + widget.comment.selfFollow = !(widget.comment.selfFollow??false); + _vipFollow(widget.comment.memberInfo.mid); + }else{ + SmartDialog.showToast("删除成功", alignment: Alignment.center); + } + }); + }, + child: (widget.commentType == 0)?RoundButton( + padding: EdgeInsets.symmetric( + horizontal: 8, + vertical: 3, + ), + backgroup: (widget.comment.selfFollow??false) ? Color(0xFFE6E6E6) : Color(0xFF32A060), + textColor: (widget.comment.selfFollow??false) ? Color(0xFF808080):Colors.white , + text:(widget.comment.selfFollow??false) ? "已关注":"关注", + radius: 20, + icons: Icon( + (widget.comment.selfFollow??false) ? Icons.check: Icons.add, + color:(widget.comment.selfFollow??false) ? Color(0xFF808080):Colors.white , + size: 14, + ), + ):Icon( + Icons.close, + color:Colors.black, + size: 16, ), ), ], @@ -173,6 +211,7 @@ class _CommunityDynamic extends State { ); } + ///动态内容 Widget buildMedia(SubjectInfo subjectInfo) { if (subjectInfo == null) { return Container(); diff --git a/lib/mine/fans_page.dart b/lib/mine/fans_page.dart index 72362b2a..7c3ee5d8 100644 --- a/lib/mine/fans_page.dart +++ b/lib/mine/fans_page.dart @@ -1,15 +1,14 @@ import 'package:dio/dio.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -import 'package:huixiang/generated/l10n.dart'; import 'package:huixiang/retrofit/data/base_data.dart'; -import 'package:huixiang/retrofit/data/vip_card.dart'; +import 'package:huixiang/retrofit/data/follow_list.dart'; +import 'package:huixiang/retrofit/data/page.dart'; import 'package:huixiang/retrofit/retrofit_api.dart'; import 'package:huixiang/utils/font_weight.dart'; import 'package:huixiang/view_widget/classic_header.dart'; import 'package:huixiang/view_widget/custom_image.dart'; import 'package:huixiang/view_widget/my_footer.dart'; -import 'package:huixiang/view_widget/no_data_view.dart'; import 'package:pull_to_refresh/pull_to_refresh.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; @@ -23,7 +22,8 @@ class FansPage extends StatefulWidget { class _FansPage extends State { RefreshController _refreshController; - + int pageNum = 1; + List list = []; ApiService apiService; @override @@ -34,16 +34,50 @@ class _FansPage extends State { SharedPreferences.getInstance().then((value) { apiService = ApiService(Dio(), context: context, token: value.getString("token")); - + _queryFollowList(); }); } + ///我的关注列表 + _queryFollowList() async { + SharedPreferences sharedPreferences = await SharedPreferences.getInstance(); + if (apiService == null) + apiService = ApiService( + Dio(), + context: context, + token: sharedPreferences.getString("token"), + showLoading: false, + ); + BaseData> baseData = await apiService.followList({ + "isMyFans": true, + "pageNum": 1, + "pageSize": 100, + }).catchError((error) { + _refreshController.refreshFailed(); + _refreshController.loadFailed(); + }); + _refreshController.refreshCompleted(); + _refreshController.loadComplete(); + if (baseData != null && baseData.isSuccess) { + if (pageNum == 1) { + list.clear(); + } + list.addAll(baseData.data.list); + print("list: ${list.length}"); + if (int.tryParse(baseData.data.total) < (pageNum * 10)) { + _refreshController.loadNoData(); + } + setState(() {}); + } + } @override Widget build(BuildContext context) { return Scaffold( body: Container( + margin: EdgeInsets.only(top: 2), + color:Colors.white, child: SmartRefresher( enablePullDown: true, enablePullUp: false, @@ -57,16 +91,18 @@ class _FansPage extends State { // onRefresh: , physics: BouncingScrollPhysics(), child: ListView.builder( + itemCount: list == null ? 0 : list.length, padding: EdgeInsets.symmetric(vertical: 8.h), + shrinkWrap: true, + physics: NeverScrollableScrollPhysics(), + scrollDirection: Axis.vertical, itemBuilder: (context, position) { return GestureDetector( onTap: () { - }, - child: fansItem(), + child: fansItem(list[position]), ); }, - itemCount:5, ) // NoDataView( // isShowBtn: false, @@ -80,7 +116,7 @@ class _FansPage extends State { } - Widget fansItem() { + Widget fansItem(ListData list) { return Container( margin: EdgeInsets.symmetric(horizontal: 16.w, vertical: 16.h), child:Row( @@ -88,7 +124,7 @@ class _FansPage extends State { crossAxisAlignment:CrossAxisAlignment.center, children: [ MImage( - "assets/image/default_1.png", + list != null ? (list.avatar ?? "") : "", width: 44, height: 44, isCircle: true, @@ -100,7 +136,7 @@ class _FansPage extends State { width:8, ), Expanded(child:Text( - "百花谷", + list != null ? (list.nickname ?? "") : "", style: TextStyle( color: Color(0xFF1A1A1A), fontSize: 14.sp, diff --git a/lib/mine/follow_page.dart b/lib/mine/follow_page.dart index 633d8309..cf0f71f0 100644 --- a/lib/mine/follow_page.dart +++ b/lib/mine/follow_page.dart @@ -3,6 +3,8 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:huixiang/generated/l10n.dart'; import 'package:huixiang/retrofit/data/base_data.dart'; +import 'package:huixiang/retrofit/data/follow_list.dart'; +import 'package:huixiang/retrofit/data/page.dart'; import 'package:huixiang/retrofit/data/vip_card.dart'; import 'package:huixiang/retrofit/retrofit_api.dart'; import 'package:huixiang/utils/font_weight.dart'; @@ -23,8 +25,9 @@ class FollowPage extends StatefulWidget { class _FollowPage extends State { RefreshController _refreshController; - ApiService apiService; + int pageNum = 1; + List list = []; @override void initState() { @@ -34,16 +37,50 @@ class _FollowPage extends State { SharedPreferences.getInstance().then((value) { apiService = ApiService(Dio(), context: context, token: value.getString("token")); - + _queryFollowList(); }); } + ///我的关注列表 + _queryFollowList() async { + SharedPreferences sharedPreferences = await SharedPreferences.getInstance(); + if (apiService == null) + apiService = ApiService( + Dio(), + context: context, + token: sharedPreferences.getString("token"), + showLoading: false, + ); + BaseData> baseData = await apiService.followList({ + "isMyFans": false, + "pageNum": 1, + "pageSize": 100, + }).catchError((error) { + _refreshController.refreshFailed(); + _refreshController.loadFailed(); + }); + _refreshController.refreshCompleted(); + _refreshController.loadComplete(); + if (baseData != null && baseData.isSuccess) { + if (pageNum == 1) { + list.clear(); + } + list.addAll(baseData.data.list); + print("list: ${list.length}"); + if (int.tryParse(baseData.data.total) < (pageNum * 10)) { + _refreshController.loadNoData(); + } + setState(() {}); + } + } @override Widget build(BuildContext context) { return Scaffold( body: Container( + margin: EdgeInsets.only(top: 2), + color:Colors.white, child: SmartRefresher( enablePullDown: true, enablePullUp: false, @@ -56,18 +93,18 @@ class _FollowPage extends State { controller: _refreshController, // onRefresh: , physics: BouncingScrollPhysics(), - child: ListView.builder( + child: ListView.builder( + itemCount: list == null ? 0 : list.length, + shrinkWrap: true, + physics: NeverScrollableScrollPhysics(), + scrollDirection: Axis.vertical, padding: EdgeInsets.symmetric(vertical: 8.h), itemBuilder: (context, position) { - return GestureDetector( - onTap: () { - - }, - child: followItem(), + return Container( + child: followItem(list[position]), ); }, - itemCount:5, - ) + ), // NoDataView( // isShowBtn: false, // text: "共关注0人", @@ -75,12 +112,13 @@ class _FollowPage extends State { // margin: EdgeInsets.only(top: 120.h), // ), ), + ), ); } - Widget followItem() { + Widget followItem(ListData list) { return Container( margin: EdgeInsets.symmetric(horizontal: 16.w, vertical: 16.h), child:Row( @@ -88,7 +126,7 @@ class _FollowPage extends State { crossAxisAlignment:CrossAxisAlignment.center, children: [ MImage( - "assets/image/default_1.png", + list != null ? (list.avatar ?? "") : "", width: 44, height: 44, isCircle: true, @@ -100,7 +138,7 @@ class _FollowPage extends State { width:8, ), Expanded(child:Text( - "百花谷", + list != null ? (list.nickname ?? "") : "", style: TextStyle( color: Color(0xFF1A1A1A), fontSize: 14.sp, diff --git a/lib/mine/mine_view/community_follow.dart b/lib/mine/mine_view/community_follow.dart index 3ea67a39..81844dd5 100644 --- a/lib/mine/mine_view/community_follow.dart +++ b/lib/mine/mine_view/community_follow.dart @@ -1,9 +1,7 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -import 'package:huixiang/generated/l10n.dart'; import 'package:huixiang/mine/follow_page.dart'; import 'package:huixiang/mine/release_page.dart'; -import 'package:huixiang/mine/vip_card_page.dart'; import 'package:huixiang/utils/font_weight.dart'; import 'package:huixiang/view_widget/my_appbar.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; @@ -21,6 +19,15 @@ class CommunityFollow extends StatefulWidget { class _CommunityFollow extends State with SingleTickerProviderStateMixin { + + + @override + void initState() { + super.initState(); + + } + + @override Widget build(BuildContext context) { return DefaultTabController( @@ -50,9 +57,9 @@ class _CommunityFollow extends State indicatorSize: TabBarIndicatorSize.label, //指示器与文字等宽 tabs: [ - MyTab(text:"关注(23)"), - MyTab(text: "粉丝(55)"), - MyTab(text: "发布(26)"), + MyTab(text:"关注(0)",), + MyTab(text: "粉丝(0)"), + MyTab(text: "发布(0)"), ], ), ), diff --git a/lib/mine/release_page.dart b/lib/mine/release_page.dart index e621ce45..3a1ec9b1 100644 --- a/lib/mine/release_page.dart +++ b/lib/mine/release_page.dart @@ -1,18 +1,15 @@ import 'package:dio/dio.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -import 'package:huixiang/generated/l10n.dart'; +import 'package:huixiang/community/community_view/community_dynamic.dart'; import 'package:huixiang/retrofit/data/base_data.dart'; -import 'package:huixiang/retrofit/data/vip_card.dart'; +import 'package:huixiang/retrofit/data/comunity_comment.dart'; +import 'package:huixiang/retrofit/data/page.dart'; import 'package:huixiang/retrofit/retrofit_api.dart'; -import 'package:huixiang/utils/font_weight.dart'; import 'package:huixiang/view_widget/classic_header.dart'; -import 'package:huixiang/view_widget/custom_image.dart'; import 'package:huixiang/view_widget/my_footer.dart'; -import 'package:huixiang/view_widget/no_data_view.dart'; import 'package:pull_to_refresh/pull_to_refresh.dart'; import 'package:shared_preferences/shared_preferences.dart'; -import 'package:flutter_screenutil/flutter_screenutil.dart'; class ReleasePage extends StatefulWidget { @override @@ -22,251 +19,97 @@ class ReleasePage extends StatefulWidget { } class _ReleasePage extends State { - RefreshController _refreshController; - var isShowShrink = false; + RefreshController refreshController = RefreshController(); ApiService apiService; + int pageNum = 1; + + List comments = []; @override void initState() { super.initState(); - _refreshController = RefreshController(); - SharedPreferences.getInstance().then((value) { - apiService = - ApiService(Dio(), context: context, token: value.getString("token")); + _onRefresh(); + } - }); + _onRefresh() async { + pageNum = 1; + setState(() {}); } + queryCommunity() async { + if (apiService == null) { + SharedPreferences value = await SharedPreferences.getInstance(); + apiService = ApiService( + Dio(), + context: context, + token: value.getString("token"), + ); + } + BaseData> baseData = await apiService.trendList({ + "onlyFollow": false, + "onlyMe": true, + "pageNum": pageNum, + "pageSize": 10, + "searchKey": "" + }).catchError((error) { + refreshController.refreshFailed(); + refreshController.loadFailed(); + }); + + refreshController.refreshCompleted(); + refreshController.loadComplete(); + if (baseData.isSuccess) { + if (pageNum == 1) { + comments.clear(); + } + comments.addAll(baseData.data.list); + print("comments: ${comments.length}"); + if (int.tryParse(baseData.data.total) < (pageNum * 10)) { + refreshController.loadNoData(); + } + } + } @override Widget build(BuildContext context) { - return Scaffold( - body: Container( - child: SmartRefresher( + return FutureBuilder( + future: queryCommunity(), + builder: (context, position) { + return SmartRefresher( + controller: refreshController, enablePullDown: true, - enablePullUp: false, + enablePullUp: true, + physics: BouncingScrollPhysics(), header: MyHeader(), footer: CustomFooter( builder: (context, mode) { return MyFooter(mode); }, ), - controller: _refreshController, - // onRefresh: , - physics: BouncingScrollPhysics(), - child: ListView.builder( - padding: EdgeInsets.symmetric(vertical: 8.h), + onRefresh: _onRefresh, + onLoading: () { + setState(() {}); + }, + child: ListView.builder( + physics: NeverScrollableScrollPhysics(), itemBuilder: (context, position) { - return GestureDetector( + return InkWell( + child: CommunityDynamic(comments[position],1), onTap: () { - + Navigator.of(context).pushNamed( + '/router/community_details', + arguments: { + "comment": comments[position], + }, + ); }, - child: releaseItem(), ); }, - itemCount:5, - ) - // NoDataView( - // isShowBtn: false, - // text: "共关注0人", - // fontSize: 16.sp, - // margin: EdgeInsets.only(top: 120.h), - // ), - ), - ), - ); - } - - - Widget releaseItem() { - return Container( - color: Colors.white, - padding: EdgeInsets.symmetric(horizontal: 16.w), - margin: EdgeInsets.symmetric(vertical: 16.w), - child:Column( - mainAxisAlignment: MainAxisAlignment.spaceAround, - crossAxisAlignment:CrossAxisAlignment.start, - children: [ - Row( - children: [ - ClipOval( - child: Image.network( - "https://t7.baidu.com/it/u=2841334870,333581502&fm=193&f=GIF", - fit: BoxFit.cover, - width: 44.w, - height: 44.h, - ), - clipBehavior: Clip.hardEdge, - ), - SizedBox( - width: 8.w, - ), - Expanded( - child: Container( - height: 60.h, - child: Column( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - children: [ - Expanded(child: Text( - "百花谷", - style: TextStyle( - fontSize: 14.sp, - fontWeight: MyFontWeight.medium, - color: Color(0xff808080), - ), - ), ), - InkWell( - onTap: () { - }, - child: Icon( - Icons.close, - color: Colors.black, - size: 16, - ), - ), - ], - ), - Text( - "2021.04.12 12:12", - overflow: TextOverflow.ellipsis, - maxLines: 2, - style: TextStyle( - fontSize: 12.sp, - color: Color(0xff808080), - ), - ), - ], - ), - ), - flex: 1, - ), - ], - ), - SizedBox(height: 12), - Text( - "文本,是指书面语言的表现形式,从文学角度说,通常是具有完整、系统含义(Message)的一个句子或多个句子的组合。" - "一个文本可以是一个句子(Sentence)、一个段落(Paragraph)或者一个篇章(Discourse)。广义“文本”:" - "任何由书写所固定下来的任何话语。(利科尔) 狭义“文本”:由语言文字组成的文学实体,代指“作品”,相对于作者、世界构成一个独立、自足的系统。", - overflow: isShowShrink - ? TextOverflow.visible - : TextOverflow.ellipsis, - maxLines: isShowShrink ? 10 :5, - style: TextStyle( - fontSize: 14.sp, - color:Color(0xFF1A1A1A), - fontWeight: MyFontWeight.regular, - ), - ), - SizedBox(height: 4.h), - GestureDetector( - onTap: () { - setState(() { - isShowShrink = !isShowShrink; - }); - }, - child: Row( - // mainAxisAlignment: MainAxisAlignment.end, - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisSize: MainAxisSize.max, - children: [ - Text( - (isShowShrink != null && !isShowShrink) - ?"查看全文":"收起", - style: TextStyle( - fontSize: 14.sp, - color: Color(0xFF32A060), - fontWeight: MyFontWeight.medium, - ), - ), - ], - ), - ), - SizedBox(height:16.h), - Image.asset( - "assets/image/laoban.png", - height: 310.h, - ), - SizedBox(height: 17.h), - Padding(padding: EdgeInsets.only(bottom: 16), - child:Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - children: [ - InkWell( - onTap: () { - }, - child: Image.asset( - "assets/image/browse.png", - height: 16.h, - width: 16.w, - ), - ), - SizedBox(width:4), - Text( - "15", - style: TextStyle( - fontSize: 12.sp, - color:Color(0xFF1A1A1A), - fontWeight: MyFontWeight.regular, - ), - ), - ], - ), - Row( - children: [ - InkWell( - onTap: () { - }, - child: Image.asset( - "assets/image/leaving_message.png", - height: 16.h, - width: 16.w, - ), - ), - SizedBox(width:4), - Text( - "52", - style: TextStyle( - fontSize: 12.sp, - color:Color(0xFF1A1A1A), - fontWeight: MyFontWeight.regular, - ), - ), - ], - ), - Row( - children: [ - InkWell( - onTap: () { - }, - child: Image.asset( - "assets/image/follow.png", - height: 16.h, - width: 16.w, - ), - ), - SizedBox(width:4), - Text( - "25", - style: TextStyle( - fontSize: 12.sp, - color:Color(0xFF1A1A1A), - fontWeight: MyFontWeight.regular, - ), - ), - ], - ), - ], - ),), - ], - ), + itemCount: comments.length, + )); + }, ); } } diff --git a/lib/retrofit/data/article.dart b/lib/retrofit/data/article.dart index 0085a6ed..620b84a6 100644 --- a/lib/retrofit/data/article.dart +++ b/lib/retrofit/data/article.dart @@ -24,6 +24,7 @@ class Article { bool _isHot; bool _liked; int _viewers; + bool isFollow; dynamic _storeName; String get id => _id; diff --git a/lib/retrofit/data/comunity_comment.dart b/lib/retrofit/data/comunity_comment.dart index 45ef149b..a9fe7bc2 100644 --- a/lib/retrofit/data/comunity_comment.dart +++ b/lib/retrofit/data/comunity_comment.dart @@ -10,7 +10,6 @@ /// createTime : "2021-10-19 09:55:16" class ComunityComment { - ComunityComment({ String id, String subject, @@ -20,7 +19,7 @@ class ComunityComment { int viewers, int comments, bool selfLike, - bool selfFollow, + bool selfFollow, String createTime,}){ this.id = id; this.subject = subject; diff --git a/lib/retrofit/data/follow_list.dart b/lib/retrofit/data/follow_list.dart new file mode 100644 index 00000000..27691608 --- /dev/null +++ b/lib/retrofit/data/follow_list.dart @@ -0,0 +1,159 @@ +/// pageNum : 1 +/// pageSize : 100 +/// size : 1 +/// pages : 1 +/// hasPreviousPage : false +/// hasNextPage : false +/// total : "1" +/// list : [{"mid":"1406879717390286848","nickname":"flutter无敌","avatar":"https://pos.upload.gznl.top/admin/2021/10/fb4dadec-a836-49bd-a4c9-c35fc9fd5008.jpeg"}] + +class FollowList { + FollowList({ + int pageNum, + int pageSize, + int size, + int pages, + bool hasPreviousPage, + bool hasNextPage, + String total, + List list,}){ + _pageNum = pageNum; + _pageSize = pageSize; + _size = size; + _pages = pages; + _hasPreviousPage = hasPreviousPage; + _hasNextPage = hasNextPage; + _total = total; + _list = list; +} + + FollowList.fromJson(dynamic json) { + _pageNum = json['pageNum']; + _pageSize = json['pageSize']; + _size = json['size']; + _pages = json['pages']; + _hasPreviousPage = json['hasPreviousPage']; + _hasNextPage = json['hasNextPage']; + _total = json['total']; + if (json['list'] != null) { + _list = []; + json['list'].forEach((v) { + _list.add(ListData.fromJson(v)); + }); + } + } + int _pageNum; + int _pageSize; + int _size; + int _pages; + bool _hasPreviousPage; + bool _hasNextPage; + String _total; + List _list; + + int get pageNum => _pageNum; + int get pageSize => _pageSize; + int get size => _size; + int get pages => _pages; + bool get hasPreviousPage => _hasPreviousPage; + bool get hasNextPage => _hasNextPage; + String get total => _total; + List get list => _list; + + + set pageNum(int value) { + _pageNum = value; + } + + Map toJson() { + final map = {}; + map['pageNum'] = _pageNum; + map['pageSize'] = _pageSize; + map['size'] = _size; + map['pages'] = _pages; + map['hasPreviousPage'] = _hasPreviousPage; + map['hasNextPage'] = _hasNextPage; + map['total'] = _total; + if (_list != null) { + map['list'] = _list.map((v) => v.toJson()).toList(); + } + return map; + } + + set pageSize(int value) { + _pageSize = value; + } + + set size(int value) { + _size = value; + } + + set pages(int value) { + _pages = value; + } + + set hasPreviousPage(bool value) { + _hasPreviousPage = value; + } + + set hasNextPage(bool value) { + _hasNextPage = value; + } + + set total(String value) { + _total = value; + } + + set list(List value) { + _list = value; + } +} + +/// mid : "1406879717390286848" +/// nickname : "flutter无敌" +/// avatar : "https://pos.upload.gznl.top/admin/2021/10/fb4dadec-a836-49bd-a4c9-c35fc9fd5008.jpeg" + +class ListData { + ListData({ + String mid, + String nickname, + String avatar,}){ + _mid = mid; + _nickname = nickname; + _avatar = avatar; +} + + ListData.fromJson(dynamic json) { + _mid = json['mid']; + _nickname = json['nickname']; + _avatar = json['avatar']; + } + String _mid; + String _nickname; + String _avatar; + + String get mid => _mid; + String get nickname => _nickname; + String get avatar => _avatar; + + + set mid(String value) { + _mid = value; + } + + Map toJson() { + final map = {}; + map['mid'] = _mid; + map['nickname'] = _nickname; + map['avatar'] = _avatar; + return map; + } + + set nickname(String value) { + _nickname = value; + } + + set avatar(String value) { + _avatar = value; + } +} \ No newline at end of file diff --git a/lib/retrofit/data/page.dart b/lib/retrofit/data/page.dart index 257ac7e0..c92e8278 100644 --- a/lib/retrofit/data/page.dart +++ b/lib/retrofit/data/page.dart @@ -22,7 +22,7 @@ class PageInfo { List list; List records; - factory PageInfo.fromJson(Map json, D Function(dynamic d) fromJsonD) => _$PageInfoFromJson(json, fromJsonD); + factory PageInfo.fromJson(Map json, D Function(dynamic d) fromJsonD) => _$PageInfoFromJson(json, fromJsonD); Map toJson(Object Function(D value) toJsonD) => _$PageInfoToJson(this, toJsonD); } diff --git a/lib/retrofit/min_api.dart b/lib/retrofit/min_api.dart index 53d6ccc9..e6b33d1f 100644 --- a/lib/retrofit/min_api.dart +++ b/lib/retrofit/min_api.dart @@ -154,8 +154,8 @@ abstract class MinApiService { @POST("order/placeOrderFirst") Future placeOrderFirst(@Body() Map param); - /// 结算 @POST("order/settlement") Future settlementApi(@Body() Map param); + } diff --git a/lib/retrofit/retrofit_api.dart b/lib/retrofit/retrofit_api.dart index d9f4f607..16bd62b3 100644 --- a/lib/retrofit/retrofit_api.dart +++ b/lib/retrofit/retrofit_api.dart @@ -21,6 +21,7 @@ import 'data/address.dart'; import 'data/banner.dart'; import 'data/brand_data.dart'; import 'data/exchange_order.dart'; +import 'data/follow_list.dart'; import 'data/goods.dart'; import 'data/goods_category.dart'; import 'data/logistics.dart'; @@ -372,5 +373,13 @@ abstract class ApiService { @POST("/information/trend-list") Future>> trendList(@Body() Map map); + /// 我关注/粉丝的会员列表 + @POST("/member/follow/list") + Future>> followList(@Body() Map map); + + + ///关注/取关会员 + @PUT("/member/follow/{followId}") + Future follow(@Path("followId") String followId); } diff --git a/lib/retrofit/retrofit_api.g.dart b/lib/retrofit/retrofit_api.g.dart index 9fc29cfd..0e5e21d1 100644 --- a/lib/retrofit/retrofit_api.g.dart +++ b/lib/retrofit/retrofit_api.g.dart @@ -1254,4 +1254,53 @@ class _ApiService implements ApiService { ); return value; } + + @override + Future>> followList(map) async { + ArgumentError.checkNotNull(map, 'map'); + const _extra = {}; + final queryParameters = {}; + final _data = {}; + _data.addAll(map ?? {}); + final _result = await _dio.request>( + '/member/follow/list', + queryParameters: queryParameters, + options: RequestOptions( + method: 'POST', + headers: {}, + extra: _extra, + baseUrl: baseUrl), + data: _data); + final value = BaseData>.fromJson( + _result.data, + (json) => PageInfo.fromJson( + json, + (json) => ListData.fromJson(json), + ), + ); + return value; + } + + + @override + Future> follow(followId) async { + ArgumentError.checkNotNull(followId, 'followId'); + const _extra = {}; + final queryParameters = {}; + final _data = {}; + final _result = await _dio.request>( + '/member/follow/$followId', + queryParameters: queryParameters, + options: RequestOptions( + method: 'PUT', + headers: {}, + extra: _extra, + baseUrl: baseUrl), + data: _data); + final value = BaseData.fromJson( + _result.data, + (json) => json as dynamic, + ); + return value; + } } diff --git a/lib/view_widget/coupon_widget.dart b/lib/view_widget/coupon_widget.dart index d1a5bbf1..17f0f21d 100644 --- a/lib/view_widget/coupon_widget.dart +++ b/lib/view_widget/coupon_widget.dart @@ -80,7 +80,6 @@ class CouponWidget extends StatelessWidget { : coupon.couponImg, ) // Image.network( - // width: 60, // height: 60, // fit: BoxFit.cover, diff --git a/lib/view_widget/hot_item.dart b/lib/view_widget/hot_item.dart index 3f8db488..a4523ea7 100644 --- a/lib/view_widget/hot_item.dart +++ b/lib/view_widget/hot_item.dart @@ -1,19 +1,23 @@ +import 'package:dio/dio.dart'; import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:huixiang/retrofit/data/article.dart'; +import 'package:huixiang/retrofit/data/base_data.dart'; +import 'package:huixiang/retrofit/retrofit_api.dart'; import 'package:huixiang/utils/flutter_utils.dart'; import 'package:huixiang/utils/font_weight.dart'; import 'package:huixiang/view_widget/custom_image.dart'; import 'package:huixiang/view_widget/icon_text.dart'; import 'package:huixiang/view_widget/round_button.dart'; +import 'package:shared_preferences/shared_preferences.dart'; class HotArticleItem extends StatefulWidget { final Article article; final bool isHot; HotArticleItem({this.article, this.isHot}); - @override State createState() { return _HotArticleItem(); @@ -21,7 +25,24 @@ class HotArticleItem extends StatefulWidget { } class _HotArticleItem extends State { + ApiService apiService; + + @override + void initState() { + super.initState(); + SharedPreferences.getInstance().then((value) => { + apiService = ApiService(Dio(), context: context, token: value.getString("token")), + }); + } + + ///关注/取关会员 + _vipFollow(followId) async { + BaseData baseData = await apiService.follow(followId); + if (baseData != null && baseData.isSuccess) { + SmartDialog.showToast("关注成功"); + } + } @override Widget build(BuildContext context) { @@ -63,7 +84,7 @@ class _HotArticleItem extends State { crossAxisAlignment: CrossAxisAlignment.center, children: [ Container( - height: 44, + margin: EdgeInsets.only(left: 5), child: Row( children: [ MImage( @@ -113,19 +134,23 @@ class _HotArticleItem extends State { ), GestureDetector( onTap: (){ + setState(() { + widget.article.isFollow = !(widget.article.isFollow??false); + _vipFollow(widget.article.updateUser); + }); }, child: RoundButton( padding: EdgeInsets.symmetric( horizontal: 8, vertical: 3, ), - backgroup: Color(0xFF32A060), - textColor: Colors.white , - text: "关注", + backgroup: (widget.article.isFollow??false) ? Color(0xFFE6E6E6) : Color(0xFF32A060), + textColor: (widget.article.isFollow??false) ? Color(0xFF808080):Colors.white , + text:(widget.article.isFollow??false) ? "已关注":"关注", radius: 20, icons: Icon( - Icons.check, - color: Color(0xFF808080), + (widget.article.isFollow??false) ? Icons.check: Icons.add, + color:(widget.article.isFollow??false) ? Color(0xFF808080):Colors.white , size: 14, ), ), @@ -133,6 +158,7 @@ class _HotArticleItem extends State { ], ), Expanded(child:Row( + crossAxisAlignment: CrossAxisAlignment.center, children: [ Expanded( child: Container( @@ -140,6 +166,7 @@ class _HotArticleItem extends State { child: articleTextTow(context), ), ), + SizedBox(width: 12.w,), Visibility( visible: widget.article != null && widget.article.coverImg != null && @@ -147,13 +174,10 @@ class _HotArticleItem extends State { child:Stack( alignment: Alignment.center, children: [ - MImage( + Image.network( widget.article != null ? widget.article.coverImg : "", - fit: BoxFit.cover, - radius: BorderRadius.circular(2), - aspectRatio: 1, - errorSrc: "assets/image/default_1.png", - fadeSrc: "assets/image/default_1.png", + fit: BoxFit.fill, + height: double.infinity, ), Visibility( visible: (widget.article != null && @@ -170,6 +194,7 @@ class _HotArticleItem extends State { ), ], )), + SizedBox(height: 10.h,) ], ) : Column( diff --git a/lib/web/web_view/input_comment.dart b/lib/web/web_view/input_comment.dart index 337aece4..41e696a3 100644 --- a/lib/web/web_view/input_comment.dart +++ b/lib/web/web_view/input_comment.dart @@ -15,6 +15,7 @@ class InputComment extends StatefulWidget { final Function(String text) queryMemberComment; final Function() queryInformationLikes; final TextEditingController commentTextController; + final bool isLike; InputComment( Key key, @@ -26,9 +27,10 @@ class InputComment extends StatefulWidget { this.queryMemberComment, this.queryInformationLikes, { - this.activity, this.article, + this.isLike + } ) : super(key: key); @@ -156,14 +158,14 @@ class _InputComment extends State { ? widget.activity.liked : widget.article != null ? widget.article.liked - : false), + : widget.isLike??false), onTap: (isLiked) async { await widget.queryInformationLikes(); return (widget.activity != null ? widget.activity.liked : widget.article != null ? widget.article.liked - : false); + : widget.isLike??false); }, countBuilder: (int count, bool isLiked, String text) { return Text(