diff --git a/lib/community/community_child_page.dart b/lib/community/community_child_page.dart index 95746b4f..acbcf93d 100644 --- a/lib/community/community_child_page.dart +++ b/lib/community/community_child_page.dart @@ -1,8 +1,14 @@ +import 'package:dio/dio.dart'; import 'package:flutter/material.dart'; import 'package:huixiang/community/community_view/community_dynamic.dart'; +import 'package:huixiang/retrofit/data/base_data.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/view_widget/classic_header.dart'; import 'package:huixiang/view_widget/my_footer.dart'; import 'package:pull_to_refresh/pull_to_refresh.dart'; +import 'package:shared_preferences/shared_preferences.dart'; class CommunityChildPage extends StatefulWidget { @override @@ -12,56 +18,95 @@ class CommunityChildPage extends StatefulWidget { } class _CommunityChildPage extends State { - RefreshController refreshController = RefreshController(); + ApiService apiService; + int pageNum = 1; + + List comments = []; @override void initState() { super.initState(); + + _onRefresh(); } - _onRefresh() { - Future.delayed(Duration(seconds: 1), () { - refreshController.refreshCompleted(); - refreshController.loadComplete(); - }); + _onRefresh() async { + pageNum = 1; + queryCommunity(); } - queryCommunity() { - Future.delayed(Duration(seconds: 1), () { - refreshController.refreshCompleted(); - refreshController.loadComplete(); + 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": false, + "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 SmartRefresher( - controller: refreshController, - enablePullDown: true, - enablePullUp: true, - physics: BouncingScrollPhysics(), - header: MyHeader(), - footer: CustomFooter( - builder: (context, mode) { - return MyFooter(mode); - }, - ), - onRefresh: _onRefresh, - onLoading: queryCommunity, - child: ListView.builder( - physics: NeverScrollableScrollPhysics(), - itemBuilder: (context, position) { - return InkWell( - child: CommunityDynamic(), - onTap: () { - Navigator.of(context).pushNamed('/router/community_details'); - }, - ); - }, - itemCount: 13, - ), + return FutureBuilder( + future: _onRefresh(), + builder: (context, position) { + return SmartRefresher( + controller: refreshController, + enablePullDown: true, + enablePullUp: true, + physics: BouncingScrollPhysics(), + header: MyHeader(), + footer: CustomFooter( + builder: (context, mode) { + return MyFooter(mode); + }, + ), + onRefresh: _onRefresh, + onLoading: queryCommunity, + child: ListView.builder( + physics: NeverScrollableScrollPhysics(), + itemBuilder: (context, position) { + return InkWell( + child: CommunityDynamic(comments[position]), + onTap: () { + Navigator.of(context).pushNamed( + '/router/community_details', + arguments: { + "comment": comments[position], + }, + ); + }, + ); + }, + itemCount: comments.length, + )); + }, ); } - } diff --git a/lib/community/community_details.dart b/lib/community/community_details.dart index 77e881f6..ade0e947 100644 --- a/lib/community/community_details.dart +++ b/lib/community/community_details.dart @@ -6,6 +6,7 @@ import 'package:huixiang/community/community_view/community_dynamic.dart'; import 'package:huixiang/generated/l10n.dart'; 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/retrofit_api.dart'; import 'package:huixiang/utils/font_weight.dart'; @@ -16,6 +17,13 @@ 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(); @@ -112,6 +120,7 @@ class _CommunityDetails extends State { ), color: Colors.white, child: CommunityDynamic( + widget.arguments["comment"], itemCount: 3, isDetails: true, heightFun: (height) { diff --git a/lib/community/community_page.dart b/lib/community/community_page.dart index 84e22d9d..03a696d9 100644 --- a/lib/community/community_page.dart +++ b/lib/community/community_page.dart @@ -34,6 +34,13 @@ class _CommunityPage extends State tabcontroller = TabController(length: lables.length, vsync: this); } + _toRelease() async { + var result = await Navigator.of(context).pushNamed('/router/release_dynamic'); + if (result != null && result) { + setState(() {}); + } + } + @override Widget build(BuildContext context) { return Scaffold( @@ -66,7 +73,7 @@ class _CommunityPage extends State ), ), onTap: () { - Navigator.of(context).pushNamed('/router/release_dynamic'); + _toRelease(); }, action: SvgPicture.asset( "assets/svg/shequ_fabu.svg", diff --git a/lib/community/community_view/community_dynamic.dart b/lib/community/community_view/community_dynamic.dart index d453eac2..d922f0d7 100644 --- a/lib/community/community_view/community_dynamic.dart +++ b/lib/community/community_view/community_dynamic.dart @@ -1,17 +1,21 @@ import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; +import 'package:huixiang/retrofit/data/comunity_comment.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'; class CommunityDynamic extends StatefulWidget { - final int itemCount; final Function(double height) heightFun; - final bool isDetails ; + final bool isDetails; + + final ComunityComment comment; - CommunityDynamic({ + CommunityDynamic( + this.comment, { Key key, this.itemCount = 9, this.heightFun, @@ -25,7 +29,6 @@ class CommunityDynamic extends StatefulWidget { } class _CommunityDynamic extends State { - GlobalKey globalKey = GlobalKey(); double height = 0; @@ -34,6 +37,7 @@ class _CommunityDynamic extends State { return Column( children: [ Container( + key: globalKey, alignment: Alignment.topCenter, padding: EdgeInsets.all(16), decoration: BoxDecoration( @@ -48,7 +52,6 @@ class _CommunityDynamic extends State { ], ), child: Column( - key: globalKey, mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, @@ -120,7 +123,7 @@ class _CommunityDynamic extends State { height: 12.h, ), Text( - "文本,是指书面语言的表现形式,从文学角度说,通常是具有完整、系统含义(Message)的一个句子或多个句子的组说,通常是具有完整、系统含义(Message)的一个句子或多个句子的组或多个句子的组说。", + widget.comment.subject ?? "", maxLines: 5, overflow: TextOverflow.ellipsis, style: TextStyle( @@ -129,34 +132,7 @@ class _CommunityDynamic extends State { fontSize: 14.sp, ), ), - SizedBox( - height: 16.h, - ), - if (widget.itemCount == 1) - Container( - width: MediaQuery.of(context).size.width / 2, - height: MediaQuery.of(context).size.width, - color: Colors.blue.withAlpha(123), - ) - else - GridView.builder( - gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( - crossAxisCount: - (widget.itemCount == 2 || widget.itemCount == 4) ? 2 : 3, - crossAxisSpacing: 12.w, - mainAxisSpacing: 12.w, - childAspectRatio: 1, - ), - padding: EdgeInsets.zero, - shrinkWrap: true, - physics: NeverScrollableScrollPhysics(), - itemBuilder: (context, position) { - return Container( - color: Colors.blue.withAlpha(123), - ); - }, - itemCount: widget.itemCount, - ), + buildMedia(widget.comment.subjectInfo), if (!widget.isDetails) SizedBox( height: 12.h, @@ -167,19 +143,19 @@ class _CommunityDynamic extends State { crossAxisAlignment: CrossAxisAlignment.center, children: [ IconText( - "58", + "${widget.comment.viewers ?? 0}", space: 4.w, leftImage: "assets/svg/liulanliang.svg", iconSize: 16, ), IconText( - "58", + "${widget.comment.comments ?? 0}", space: 4.w, leftImage: "assets/svg/pinglun.svg", iconSize: 16, ), IconText( - "58", + "${widget.comment.likes ?? 0}", space: 4.w, leftImage: "assets/svg/xihuan.svg", iconSize: 16, @@ -197,17 +173,85 @@ class _CommunityDynamic extends State { ); } + Widget buildMedia(SubjectInfo subjectInfo) { + if (subjectInfo == null) { + return Container(); + } + Widget widget = Container(); + if (subjectInfo.type == "image" && subjectInfo.images.length > 0) { + if (subjectInfo.images.length == 1) { + widget = Container( + child: MImage( + subjectInfo.images[0], + fit: BoxFit.cover, + width: MediaQuery.of(context).size.width / 2, + height: MediaQuery.of(context).size.width / 2, + errorSrc: "assets/image/default_2_1.png", + fadeSrc: "assets/image/default_2_1.png", + ), + ); + } else { + widget = GridView.builder( + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: (subjectInfo.images.length == 2 || + subjectInfo.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: MImage( + subjectInfo.images[0], + fit: BoxFit.cover, + aspectRatio: 1, + errorSrc: "assets/image/default_2_1.png", + fadeSrc: "assets/image/default_2_1.png", + ), + ); + }, + itemCount: subjectInfo.images.length, + ); + } + } else if (subjectInfo.type == "video" && + subjectInfo.video != null && + subjectInfo.video != "") { + widget = Container( + width: MediaQuery.of(context).size.width - 32, + height: MediaQuery.of(context).size.width / 2, + color: Colors.blue.withAlpha(123), + ); + } + + return Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + SizedBox( + height: 16.h, + ), + widget, + ], + ); + } @override void didChangeDependencies() { - WidgetsBinding.instance.addPostFrameCallback(_getContainerHeight); + if (widget.heightFun != null) + WidgetsBinding.instance.addPostFrameCallback(_getContainerHeight); super.didChangeDependencies(); } _getContainerHeight(_) { - height = globalKey.currentContext.size.height; - widget.heightFun(height); + if (globalKey.currentContext != null) + height = globalKey.currentContext.size.height; + if (widget.heightFun != null) widget.heightFun(height); print("height: $height"); } - } diff --git a/lib/community/release_dynamic.dart b/lib/community/release_dynamic.dart index badda948..c2415051 100644 --- a/lib/community/release_dynamic.dart +++ b/lib/community/release_dynamic.dart @@ -143,7 +143,7 @@ class _ReleaseDynamic extends State { } } - BaseData baseData = await apiService.trend({ + BaseData baseData = await apiService.trend({ "images": remoteImageUrls, "subject": dynamicText, "subjectType": subjectType, @@ -151,7 +151,12 @@ class _ReleaseDynamic extends State { }).catchError((onError) { EasyLoading.dismiss(); }); - if (baseData.isSuccess) {} + if (baseData.isSuccess) { + SmartDialog.showToast("发布成功!~"); + Future.delayed(Duration(seconds: 1), () { + Navigator.of(context).pop(true); + }); + } EasyLoading.dismiss(); }); } diff --git a/lib/main.dart b/lib/main.dart index 74911cb3..c8cf3cd4 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -286,7 +286,7 @@ Map routers = { '/router/address_map_page': (context, {arguments}) => AddressMapPage(), '/router/roll_center_page': (context, {arguments}) => RollCenterPage(), '/router/release_dynamic': (context, {arguments}) => ReleaseDynamic(), - '/router/community_details': (context, {arguments}) => CommunityDetails(), + '/router/community_details': (context, {arguments}) => CommunityDetails(arguments: arguments), '/router/user_info_page': (context, {arguments}) => UserInfoPage(), '/router/recharge_page': (context, {arguments}) => RechargePage(), '/router/mine_wallet': (context, {arguments}) => MineWalletPage(), diff --git a/lib/retrofit/data/comunity_comment.dart b/lib/retrofit/data/comunity_comment.dart new file mode 100644 index 00000000..45ef149b --- /dev/null +++ b/lib/retrofit/data/comunity_comment.dart @@ -0,0 +1,145 @@ +/// id : "1450279348069203968" +/// subject : "哈哈哈哈哈哈😃😃😃😃" +/// subjectInfo : {"type":"image","images":["https://pos.upload.gznl.top/admin/2021/10/9a15049b-9828-4056-84d7-21b9055d2cb0.jpeg"],"video":""} +/// memberInfo : {"mid":null,"nickname":null,"avatar":""} +/// likes : 0 +/// viewers : 0 +/// comments : 0 +/// selfLike : false +/// selfFollow : false +/// createTime : "2021-10-19 09:55:16" + +class ComunityComment { + + ComunityComment({ + String id, + String subject, + SubjectInfo subjectInfo, + MemberInfo memberInfo, + int likes, + int viewers, + int comments, + bool selfLike, + bool selfFollow, + String createTime,}){ + this.id = id; + this.subject = subject; + this.subjectInfo = subjectInfo; + this.memberInfo = memberInfo; + this.likes = likes; + this.viewers = viewers; + this.comments = comments; + this.selfLike = selfLike; + this.selfFollow = selfFollow; + this.createTime = createTime; +} + + ComunityComment.fromJson(dynamic json) { + this.id = json['id']; + this.subject = json['subject']; + this.subjectInfo = json['subjectInfo'] != null ? SubjectInfo.fromJson(json['subjectInfo']) : null; + this.memberInfo = json['memberInfo'] != null ? MemberInfo.fromJson(json['memberInfo']) : null; + this.likes = json['likes']; + this.viewers = json['viewers']; + this.comments = json['comments']; + this.selfLike = json['selfLike']; + this.selfFollow = json['selfFollow']; + this.createTime = json['createTime']; + } + String id; + String subject; + SubjectInfo subjectInfo; + MemberInfo memberInfo; + int likes; + int viewers; + int comments; + bool selfLike; + bool selfFollow; + String createTime; + + Map toJson() { + final map = {}; + map['id'] = this.id; + map['subject'] = this.subject; + if (this.subjectInfo != null) { + map['subjectInfo'] = this.subjectInfo.toJson(); + } + if (this.memberInfo != null) { + map['memberInfo'] = this.memberInfo.toJson(); + } + map['likes'] = this.likes; + map['viewers'] = this.viewers; + map['comments'] = this.comments; + map['selfLike'] = this.selfLike; + map['selfFollow'] = this.selfFollow; + map['createTime'] = this.createTime; + return map; + } + +} + +/// mid : null +/// nickname : null +/// avatar : "" + +class MemberInfo { + MemberInfo({ + dynamic mid, + dynamic nickname, + String avatar,}){ + this.mid = mid; + this.nickname = nickname; + this.avatar = avatar; +} + + MemberInfo.fromJson(dynamic json) { + this.mid = json['mid']; + this.nickname = json['nickname']; + this.avatar = json['avatar']; + } + dynamic mid; + dynamic nickname; + String avatar; + + Map toJson() { + final map = {}; + map['mid'] = this.mid; + map['nickname'] = this.nickname; + map['avatar'] = this.avatar; + return map; + } + +} + +/// type : "image" +/// images : ["https://pos.upload.gznl.top/admin/2021/10/9a15049b-9828-4056-84d7-21b9055d2cb0.jpeg"] +/// video : "" + +class SubjectInfo { + SubjectInfo({ + String type, + List images, + String video,}){ + this.type = type; + this.images = images; + this.video = video; +} + + SubjectInfo.fromJson(dynamic json) { + this.type = json['type']; + this.images = json['images'] != null ? json['images'].cast() : []; + this.video = json['video']; + } + String type; + List images; + String video; + + Map toJson() { + final map = {}; + map['type'] = this.type; + map['images'] = this.images; + map['video'] = this.video; + return map; + } + +} \ No newline at end of file diff --git a/lib/retrofit/retrofit_api.dart b/lib/retrofit/retrofit_api.dart index 05491851..d9f4f607 100644 --- a/lib/retrofit/retrofit_api.dart +++ b/lib/retrofit/retrofit_api.dart @@ -11,6 +11,7 @@ import 'package:huixiang/generated/l10n.dart'; import 'package:huixiang/retrofit/data/activity.dart'; import 'package:huixiang/retrofit/data/article.dart'; import 'package:huixiang/retrofit/data/base_data.dart'; +import 'package:huixiang/retrofit/data/comunity_comment.dart'; import 'package:huixiang/retrofit/data/coupon.dart'; import 'package:huixiang/retrofit/data/order_info.dart'; import 'package:huixiang/view_widget/login_tips_dialog.dart'; @@ -365,7 +366,11 @@ abstract class ApiService { /// 发表动态 @POST("/information/trend") - Future> trend(@Body() Map map); + Future> trend(@Body() Map map); + + /// 动态列表 + @POST("/information/trend-list") + Future>> trendList(@Body() Map map); } diff --git a/lib/retrofit/retrofit_api.g.dart b/lib/retrofit/retrofit_api.g.dart index 7bba57a6..9fc29cfd 100644 --- a/lib/retrofit/retrofit_api.g.dart +++ b/lib/retrofit/retrofit_api.g.dart @@ -1207,7 +1207,7 @@ class _ApiService implements ApiService { } @override - Future> trend(map) async { + Future> trend(map) async { ArgumentError.checkNotNull(map, 'map'); const _extra = {}; final queryParameters = {}; @@ -1222,9 +1222,35 @@ class _ApiService implements ApiService { extra: _extra, baseUrl: baseUrl), data: _data); - final value = BaseData.fromJson( + final value = BaseData.fromJson( _result.data, - (json) => json as String, + (json) => json as bool, + ); + return value; + } + + @override + Future>> trendList(map) async { + ArgumentError.checkNotNull(map, 'map'); + const _extra = {}; + final queryParameters = {}; + final _data = {}; + _data.addAll(map ?? {}); + final _result = await _dio.request>( + '/information/trend-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) => ComunityComment.fromJson(json), + ), ); return value; } diff --git a/lib/view_widget/custom_image.dart b/lib/view_widget/custom_image.dart index 6fbd838b..6fdcff22 100644 --- a/lib/view_widget/custom_image.dart +++ b/lib/view_widget/custom_image.dart @@ -8,8 +8,8 @@ class MImage extends StatelessWidget { final String fadeSrc; final BorderRadius radius; final double aspectRatio; - final double width; - final double height; + double width; + double height; final BoxFit fit; final bool isCircle; @@ -32,16 +32,18 @@ class MImage extends StatelessWidget { Widget image = LayoutBuilder(builder: (context, constraints) { String imageUrl = ""; if (src != null && src != "") { - imageUrl = "$src?imageMogr2/thumbnail/${constraints.constrainWidth() * scaleIndex}" + imageUrl = + "$src?imageMogr2/thumbnail/${constraints.constrainWidth() * scaleIndex}" "x${constraints.constrainHeight() * scaleIndex}/format/webp/quality/100"; } + if (imageUrl == null || imageUrl == "") { return Image.asset( "assets/image/default_2_1.png", fit: fit, ); } - return CachedNetworkImage( + CachedNetworkImage cachedNetworkImage = CachedNetworkImage( imageUrl: imageUrl, cacheManager: DefaultCacheManager(), fadeInDuration: Duration(milliseconds: 300), @@ -65,6 +67,7 @@ class MImage extends StatelessWidget { ); }, ); + return cachedNetworkImage; }); var clipRRect;