123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340 |
- import 'dart:math';
- import 'package:dartin/dartin.dart';
- import 'package:flutter/material.dart';
- import 'package:flutter/services.dart';
- import 'package:flutter_easyrefresh/easy_refresh.dart';
- import 'package:sport/bean/comment.dart';
- import 'package:sport/bean/post_user.dart';
- import 'package:sport/pages/social/notification.dart';
- import 'package:sport/provider/comment_sub_list_model.dart';
- import 'package:sport/provider/lib/provider_widget.dart';
- import 'package:sport/provider/lib/view_state_lifecycle.dart';
- import 'package:sport/router/navigator_util.dart';
- import 'package:sport/services/api/inject_api.dart';
- import 'package:sport/services/api/rest_client.dart';
- import 'package:sport/services/userid.dart';
- import 'package:sport/utils/DateFormat.dart';
- import 'package:sport/utils/toast.dart';
- import 'package:sport/widgets/dialog/alert_dialog.dart';
- import 'package:sport/widgets/dialog/modal_bottom_action.dart';
- import 'package:sport/widgets/dialog/request_dialog.dart';
- import 'package:sport/widgets/error.dart';
- import 'package:sport/widgets/image.dart';
- import 'package:sport/widgets/loading.dart';
- import 'package:sport/widgets/misc.dart';
- import 'package:sport/widgets/space.dart';
- import 'package:sport/widgets/text_input.dart' as input;
- class CommentDialog extends StatefulWidget {
- final String postId;
- final Comment comment;
- final bool showInput;
- CommentDialog(this.postId, this.comment, {this.showInput = false});
- @override
- State<StatefulWidget> createState() => _PageState();
- }
- var _padding = Space(
- width: 5,
- );
- class _PageState extends ViewStateLifecycle<CommentDialog, CommentSubListModel> with UserId, InjectApi {
- FocusNode _focusNode;
- Comment _toComment;
- PostUser _toUser;
- @override
- void initState() {
- _focusNode = FocusNode();
- super.initState();
- }
- @override
- void dispose() {
- _focusNode?.dispose();
- super.dispose();
- }
- @override
- Widget build(BuildContext context) {
- return Column(
- children: <Widget>[
- Container(
- width: double.infinity,
- height: 50,
- child: Stack(
- alignment: Alignment.center,
- children: <Widget>[
- Text(
- "回复详情",
- style: TextStyle(fontSize: 16),
- ),
- Positioned(
- left: 0,
- child: IconButton(
- icon: arrowBack(),
- onPressed: () {
- Navigator.of(context).pop();
- },
- ))
- ],
- ),
- ),
- Expanded(child: _buildCommentListWidget(model, widget.comment)),
- input.TextInput(
- widget.postId,
- focusNode: _focusNode,
- parentCommentId: widget.comment.id,
- comment: widget.showInput,
- toCommentId: _toComment == null ? null : _toComment.id,
- user: _toUser,
- callback: () {
- _toComment = null;
- _toUser = null;
- model.initData();
- widget.comment.commentCount += 1;
- },
- )
- ],
- );
- }
- @override
- CommentSubListModel createModel() => CommentSubListModel(widget.comment);
- Widget _buildCommentListWidget(CommentSubListModel subModel, Comment parent) {
- return ProviderWidget<CommentSubListModel>(
- model: subModel,
- onModelReady: (model) => model.initData(),
- builder: (_, model, __) => EasyRefresh.custom(
- controller: model.refreshController,
- enableControlFinishRefresh: true,
- enableControlFinishLoad: true,
- onLoad: model.isIdle ? () => model.loadMore() : null,
- footer: buildClassicalFooter(),
- slivers: <Widget>[
- SliverToBoxAdapter(
- child: _buildCommentListHeaderWidget(parent),
- ),
- if (model.isBusy)
- SliverToBoxAdapter(
- child: RequestLoadingWidget(),
- ),
- if (model.isEmpty)
- SliverToBoxAdapter(
- child: RequestErrorWidget(
- null,
- msg: "暂无评论~",
- assets: RequestErrorWidget.ASSETS_NO_COMMENT,
- ),
- ),
- if (model.isIdle)
- SliverList(
- delegate: SliverChildBuilderDelegate(
- (context, index) {
- return _buildCommentListItemWidget(model.list[index]);
- },
- childCount: model.list.length,
- ),
- ),
- SliverToBoxAdapter(
- child: SizedBox(
- height: 30,
- ),
- ),
- ]),
- );
- }
- Widget _buildCommentListHeaderWidget(Comment item) {
- return Column(
- children: <Widget>[
- Padding(
- padding: EdgeInsets.fromLTRB(12.0, 6.0, 12.0, 0.0),
- child: buildCommentWidget(
- context,
- item,
- () {
- setState(() {
- _toComment = item;
- _toUser = null;
- _focusNode?.requestFocus();
- });
- },
- selfId == item.userId,
- onLiked: () {
- setState(() {
- item.toggleLike();
- });
- }),
- ),
- Divider(
- height: 1,
- ),
- SizedBox(height: 20.0,)
- ],
- );
- }
- Widget _buildCommentListItemWidget(Comment item) {
- return Padding(
- padding: EdgeInsets.fromLTRB(50.0, 0.0, 12.0, 0.0),
- child: buildCommentWidget(
- context,
- item,
- () {
- setState(() {
- _toComment = item;
- _toUser = item.socialInfo;
- _focusNode?.requestFocus();
- });
- },
- selfId == item.userId,
- width: 25,
- onLiked: () {
- setState(() {
- item.toggleLike();
- });
- }),
- );
- }
- }
- Future showCommentList(BuildContext context, Comment currentItem, {bool comment = false}) async {
- return await showModalBottomSheet(
- context: context,
- isScrollControlled: true,
- backgroundColor: Colors.white,
- shape: RoundedRectangleBorder(borderRadius: BorderRadius.vertical(top: Radius.circular(10))),
- builder: (BuildContext context) {
- return Container(
- height: max(520, MediaQuery.of(context).size.height / 3 * 2),
- padding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom), // !important
- child: CommentDialog(currentItem.subjectId, currentItem, showInput: comment),
- );
- },
- );
- }
- Widget buildCommentWidget(BuildContext context, Comment item, Function onTap, bool isSelf, {int width = 30, Function onLiked}) {
- return Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: <Widget>[
- item.socialInfo == null
- ? Container()
- : Row(
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
- children: <Widget>[
- GestureDetector(
- behavior: HitTestBehavior.opaque,
- onTap: () => NavigatorUtil.goSocialUserDetail(context, item.socialInfo),
- child: Row(
- children: <Widget>[
- CircleAvatar(backgroundImage: userAvatarProvider(item.socialInfo?.avatar), radius: width / 2),
- Space(
- width: 8,
- ),
- Text(
- item.socialInfo?.name,
- style: Theme.of(context).textTheme.subtitle1.copyWith(fontWeight: FontWeight.w600),
- ),
- ],
- )),
- GestureDetector(
- behavior: HitTestBehavior.opaque,
- onTap: () async {
- await inject<RestClient>().postForumLike(item.id, "comment_id");
- onLiked?.call();
- },
- child: Row(
- children: <Widget>[
- Image.asset("lib/assets/img/bbslist_icon_like${item.isLiked ?? false ? 'd' : ''}.png"),
- _padding,
- Text(item.likeCount == 0 ? "" : "${item.likeCount}", style: Theme.of(context).textTheme.bodyText1, strutStyle: fixedLine),
- ],
- ),
- ),
- ],
- ),
- Padding(
- padding: EdgeInsets.fromLTRB(width + 8.0, 6.0, 12.0, 20.0),
- child: Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: <Widget>[
- GestureDetector(
- onTap: onTap,
- onLongPress: () async {
- await showActionDialog(context, {
- if (isSelf == false)
- "举报评论": () {
- request(context, () async {
- await inject<RestClient>().postForumReport(commentId: item.id).catchError((onError) {});
- ToastUtil.show("举报成功");
- });
- },
- if (isSelf == false)
- "屏蔽此条": () {
- request(context, () async {
- await inject<RestClient>().postForumBlockObject(item.id, "comment").catchError((onError) {});
- ToastUtil.show("屏蔽成功");
- CommentNotification(item, CommentNotification.TYPE_DEL).dispatch(context);
- });
- },
- if (isSelf == true)
- "删除此条": () async {
- if (await showDialog(
- context: context,
- builder: (context) => CustomAlertDialog(title: '确定删除此条?', ok: () => Navigator.of(context).pop(true)),
- ) ==
- true) {
- request(context, () async {
- await inject<RestClient>().postDelComment(item.id);
- ToastUtil.show("删除成功");
- CommentNotification(item, CommentNotification.TYPE_DEL).dispatch(context);
- });
- }
- },
- "复制文字": () {
- Clipboard.setData(ClipboardData(text: item.content));
- ToastUtil.show("已复制到粘贴板");
- },
- });
- },
- child: Padding(
- padding: const EdgeInsets.only(bottom: 8.0),
- child: RichText(
- text: TextSpan(style: DefaultTextStyle.of(context).style, children: <InlineSpan>[
- if (item.toUserName?.isNotEmpty == true)
- TextSpan(
- text: '@${item.toUserName} ',
- style: Theme.of(context).textTheme.subtitle1.copyWith(color: Theme.of(context).accentColor),
- // recognizer: TapGestureRecognizer()..onTap = () {
- // print("111111111111");
- // setState(() {
- // _toUser = PostUser(id: item.toUserId, name: item.toUserName);
- // });
- // }
- ),
- TextSpan(text: item.content, style: Theme.of(context).textTheme.subtitle1),
- ]),
- )),
- ),
- Row(
- children: <Widget>[
- Text(DateFormat.formatTime(item.createTime), style: Theme.of(context).textTheme.bodyText1, strutStyle: fixedLine),
- dot,
- InkWell(
- onTap: onTap,
- child: Text("回复", style: Theme.of(context).textTheme.subtitle1.copyWith(fontSize: 12.0), strutStyle: fixedLine),
- )
- ],
- )
- ],
- ),
- ),
- ],
- );
- }
|