💄 Optimize post comments
This commit is contained in:
		| @@ -103,7 +103,7 @@ class OpenablePostItem extends StatelessWidget { | |||||||
|           transitionType: ContainerTransitionType.fade, |           transitionType: ContainerTransitionType.fade, | ||||||
|           closedElevation: 0, |           closedElevation: 0, | ||||||
|           closedColor: Theme.of(context).colorScheme.surface.withOpacity( |           closedColor: Theme.of(context).colorScheme.surface.withOpacity( | ||||||
|                 cfg.prefs.getBool(kAppBackgroundStoreKey) == true ? 0.75 : 1, |                 cfg.prefs.getBool(kAppBackgroundStoreKey) == true ? 0 : 1, | ||||||
|               ), |               ), | ||||||
|           closedShape: const RoundedRectangleBorder( |           closedShape: const RoundedRectangleBorder( | ||||||
|             borderRadius: BorderRadius.all(Radius.circular(16)), |             borderRadius: BorderRadius.all(Radius.circular(16)), | ||||||
| @@ -122,6 +122,7 @@ class PostItem extends StatefulWidget { | |||||||
|   final bool showMenu; |   final bool showMenu; | ||||||
|   final bool showFullPost; |   final bool showFullPost; | ||||||
|   final bool showAvatar; |   final bool showAvatar; | ||||||
|  |   final bool showCompactAvatar; | ||||||
|   final bool showExpandableComments; |   final bool showExpandableComments; | ||||||
|   final double? maxWidth; |   final double? maxWidth; | ||||||
|   final Function(SnPost data)? onChanged; |   final Function(SnPost data)? onChanged; | ||||||
| @@ -137,6 +138,7 @@ class PostItem extends StatefulWidget { | |||||||
|     this.showMenu = true, |     this.showMenu = true, | ||||||
|     this.showFullPost = false, |     this.showFullPost = false, | ||||||
|     this.showAvatar = true, |     this.showAvatar = true, | ||||||
|  |     this.showCompactAvatar = false, | ||||||
|     this.showExpandableComments = false, |     this.showExpandableComments = false, | ||||||
|     this.maxWidth, |     this.maxWidth, | ||||||
|     this.onChanged, |     this.onChanged, | ||||||
| @@ -297,185 +299,180 @@ class _PostItemState extends State<PostItem> { | |||||||
|         crossAxisAlignment: CrossAxisAlignment.center, |         crossAxisAlignment: CrossAxisAlignment.center, | ||||||
|         children: [ |         children: [ | ||||||
|           Container( |           Container( | ||||||
|             constraints: |             constraints: BoxConstraints( | ||||||
|                 BoxConstraints(maxWidth: widget.maxWidth ?? double.infinity), |               maxWidth: widget.maxWidth ?? double.infinity, | ||||||
|  |             ), | ||||||
|             child: Column( |             child: Column( | ||||||
|               crossAxisAlignment: CrossAxisAlignment.start, |               crossAxisAlignment: CrossAxisAlignment.start, | ||||||
|               children: [ |               children: [ | ||||||
|                 Expanded( |                 Row( | ||||||
|                   child: Column( |                   children: [ | ||||||
|                     crossAxisAlignment: CrossAxisAlignment.start, |                     if (widget.showAvatar) | ||||||
|                     children: [ |                       _PostAvatar( | ||||||
|                       Row( |                         data: widget.data, | ||||||
|  |                         isCompact: false, | ||||||
|  |                       ), | ||||||
|  |                     if (widget.showAvatar) const Gap(12), | ||||||
|  |                     Expanded( | ||||||
|  |                       child: Row( | ||||||
|                         children: [ |                         children: [ | ||||||
|                           if (widget.showAvatar) |                           if (widget.showCompactAvatar) | ||||||
|                             _PostAvatar( |                             _PostAvatar( | ||||||
|                               data: widget.data, |                               data: widget.data, | ||||||
|                               isCompact: false, |                               isCompact: true, | ||||||
|                             ), |                             ), | ||||||
|                           if (widget.showAvatar) const Gap(12), |                           if (widget.showAvatar) const Gap(8), | ||||||
|                           Expanded( |                           _PostContentHeader( | ||||||
|                             child: _PostContentHeader( |                             isRelativeDate: !widget.showFullPost, | ||||||
|                               isRelativeDate: !widget.showFullPost, |                             isCompact: false, | ||||||
|                               isCompact: false, |  | ||||||
|                               data: widget.data, |  | ||||||
|                             ), |  | ||||||
|                           ), |  | ||||||
|                           _PostActionPopup( |  | ||||||
|                             data: widget.data, |                             data: widget.data, | ||||||
|                             isAuthor: isAuthor, |  | ||||||
|                             onShare: () => _doShare(context), |  | ||||||
|                             onShareImage: () => _doShareViaPicture(context), |  | ||||||
|                             onSelectAnswer: widget.onSelectAnswer, |  | ||||||
|                             onDeleted: () { |  | ||||||
|                               widget.onDeleted?.call(); |  | ||||||
|                             }, |  | ||||||
|                             onTranslate: () { |  | ||||||
|                               _translateText(); |  | ||||||
|                             }, |  | ||||||
|                           ), |                           ), | ||||||
|                         ], |                         ], | ||||||
|                       ), |                       ), | ||||||
|                       const Gap(8), |                     ), | ||||||
|                       if (widget.data.preload?.thumbnail != null) |                     _PostActionPopup( | ||||||
|                         Container( |                       data: widget.data, | ||||||
|                           margin: const EdgeInsets.only(bottom: 8), |                       isAuthor: isAuthor, | ||||||
|                           decoration: BoxDecoration( |                       onShare: () => _doShare(context), | ||||||
|                             borderRadius: const BorderRadius.all( |                       onShareImage: () => _doShareViaPicture(context), | ||||||
|                               Radius.circular(8), |                       onSelectAnswer: widget.onSelectAnswer, | ||||||
|                             ), |                       onDeleted: () { | ||||||
|                             border: Border.all( |                         widget.onDeleted?.call(); | ||||||
|                               color: Theme.of(context).dividerColor, |                       }, | ||||||
|                               width: 1, |                       onTranslate: () { | ||||||
|                             ), |                         _translateText(); | ||||||
|                           ), |                       }, | ||||||
|                           child: AspectRatio( |                     ), | ||||||
|                             aspectRatio: 16 / 9, |                   ], | ||||||
|                             child: ClipRRect( |                 ), | ||||||
|                               borderRadius: const BorderRadius.all( |                 const Gap(8), | ||||||
|                                 Radius.circular(8), |                 if (widget.data.preload?.thumbnail != null) | ||||||
|                               ), |                   Container( | ||||||
|                               child: AutoResizeUniversalImage( |                     margin: const EdgeInsets.only(bottom: 8), | ||||||
|                                 sn.getAttachmentUrl( |                     decoration: BoxDecoration( | ||||||
|                                   widget.data.preload!.thumbnail!.rid, |                       borderRadius: const BorderRadius.all( | ||||||
|                                 ), |                         Radius.circular(8), | ||||||
|                                 fit: BoxFit.cover, |  | ||||||
|                               ), |  | ||||||
|                             ), |  | ||||||
|                           ), |  | ||||||
|                         ), |  | ||||||
|                       if (widget.data.preload?.video != null) |  | ||||||
|                         _PostVideoPlayer(data: widget.data).padding(bottom: 8), |  | ||||||
|                       if (widget.data.type == 'question') |  | ||||||
|                         _PostQuestionHint(data: widget.data).padding(bottom: 8), |  | ||||||
|                       if (_displayDescription.isNotEmpty || |  | ||||||
|                           _displayTitle.isNotEmpty) |  | ||||||
|                         _PostHeadline( |  | ||||||
|                           title: _displayTitle, |  | ||||||
|                           description: _displayDescription, |  | ||||||
|                           data: widget.data, |  | ||||||
|                           isEnlarge: widget.data.type == 'article' && |  | ||||||
|                               widget.showFullPost, |  | ||||||
|                         ).padding(bottom: 8), |  | ||||||
|                       if (widget.data.type == 'article' && !widget.showFullPost) |  | ||||||
|                         Text('postArticle') |  | ||||||
|                             .tr() |  | ||||||
|                             .fontSize(13) |  | ||||||
|                             .opacity(0.75) |  | ||||||
|                             .padding(bottom: 8), |  | ||||||
|                       if ((_displayText.isNotEmpty) && |  | ||||||
|                           (widget.showFullPost || |  | ||||||
|                               widget.data.type != 'article')) |  | ||||||
|                         _PostContentBody( |  | ||||||
|                           text: _displayText, |  | ||||||
|                           data: widget.data, |  | ||||||
|                           isSelectable: widget.showFullPost, |  | ||||||
|                           isEnlarge: widget.data.type == 'article' && |  | ||||||
|                               widget.showFullPost, |  | ||||||
|                         ).padding(bottom: 6), |  | ||||||
|                       if (widget.data.visibility > 0) |  | ||||||
|                         _PostVisibilityHint(data: widget.data).padding( |  | ||||||
|                           vertical: 4, |  | ||||||
|                         ), |  | ||||||
|                       if (widget.data.body['content_truncated'] == true) |  | ||||||
|                         _PostTruncatedHint(data: widget.data).padding( |  | ||||||
|                           vertical: 4, |  | ||||||
|                         ), |  | ||||||
|                       if (widget.data.tags.isNotEmpty) |  | ||||||
|                         _PostTagsList(data: widget.data) |  | ||||||
|                             .padding(top: 4, bottom: 6), |  | ||||||
|                       Column( |  | ||||||
|                         crossAxisAlignment: CrossAxisAlignment.start, |  | ||||||
|                         spacing: 4, |  | ||||||
|                         children: [ |  | ||||||
|                           if (widget.showViews) |  | ||||||
|                             Row( |  | ||||||
|                               children: [ |  | ||||||
|                                 Icon(Symbols.play_circle, size: 20), |  | ||||||
|                                 const Gap(4), |  | ||||||
|                                 Text('postViews') |  | ||||||
|                                     .plural(widget.data.totalViews), |  | ||||||
|                               ], |  | ||||||
|                             ).opacity(0.75), |  | ||||||
|                           if (_isTranslating) |  | ||||||
|                             AnimateWidgetExtensions(Row( |  | ||||||
|                               children: [ |  | ||||||
|                                 Icon(Symbols.translate, size: 20), |  | ||||||
|                                 const Gap(4), |  | ||||||
|                                 Text('translating').tr(), |  | ||||||
|                               ], |  | ||||||
|                             )) |  | ||||||
|                                 .animate(onPlay: (e) => e.repeat()) |  | ||||||
|                                 .fadeIn(duration: 500.ms, curve: Curves.easeOut) |  | ||||||
|                                 .then() |  | ||||||
|                                 .fadeOut( |  | ||||||
|                                   duration: 500.ms, |  | ||||||
|                                   delay: 1000.ms, |  | ||||||
|                                   curve: Curves.easeIn, |  | ||||||
|                                 ), |  | ||||||
|                           if (_isTranslated) |  | ||||||
|                             InkWell( |  | ||||||
|                               child: Row( |  | ||||||
|                                 children: [ |  | ||||||
|                                   Icon(Symbols.translate, size: 20), |  | ||||||
|                                   const Gap(4), |  | ||||||
|                                   Text('translated').tr(), |  | ||||||
|                                 ], |  | ||||||
|                               ).opacity(0.75), |  | ||||||
|                               onTap: () { |  | ||||||
|                                 setState(() { |  | ||||||
|                                   _displayText = |  | ||||||
|                                       widget.data.body['content'] ?? ''; |  | ||||||
|                                   _displayTitle = |  | ||||||
|                                       widget.data.body['title'] ?? ''; |  | ||||||
|                                   _displayDescription = |  | ||||||
|                                       widget.data.body['description'] ?? ''; |  | ||||||
|                                   _isTranslated = false; |  | ||||||
|                                 }); |  | ||||||
|                               }, |  | ||||||
|                             ), |  | ||||||
|                           if (widget.data.repostTo != null) |  | ||||||
|                             _PostQuoteContent(child: widget.data.repostTo!) |  | ||||||
|                                 .padding( |  | ||||||
|                               top: 4, |  | ||||||
|                               bottom: widget.data.preload?.attachments |  | ||||||
|                                           ?.isNotEmpty ?? |  | ||||||
|                                       false |  | ||||||
|                                   ? 12 |  | ||||||
|                                   : 0, |  | ||||||
|                             ), |  | ||||||
|                         ], |  | ||||||
|                       ).padding( |  | ||||||
|                         bottom: |  | ||||||
|                             widget.showViews || _isTranslated || _isTranslating |  | ||||||
|                                 ? 8 |  | ||||||
|                                 : 0, |  | ||||||
|                       ), |                       ), | ||||||
|                     ], |                       border: Border.all( | ||||||
|  |                         color: Theme.of(context).dividerColor, | ||||||
|  |                         width: 1, | ||||||
|  |                       ), | ||||||
|  |                     ), | ||||||
|  |                     child: AspectRatio( | ||||||
|  |                       aspectRatio: 16 / 9, | ||||||
|  |                       child: ClipRRect( | ||||||
|  |                         borderRadius: const BorderRadius.all( | ||||||
|  |                           Radius.circular(8), | ||||||
|  |                         ), | ||||||
|  |                         child: AutoResizeUniversalImage( | ||||||
|  |                           sn.getAttachmentUrl( | ||||||
|  |                             widget.data.preload!.thumbnail!.rid, | ||||||
|  |                           ), | ||||||
|  |                           fit: BoxFit.cover, | ||||||
|  |                         ), | ||||||
|  |                       ), | ||||||
|  |                     ), | ||||||
|                   ), |                   ), | ||||||
|                 ).padding(horizontal: 12, top: 8), |                 if (widget.data.preload?.video != null) | ||||||
|  |                   _PostVideoPlayer(data: widget.data).padding(bottom: 8), | ||||||
|  |                 if (widget.data.type == 'question') | ||||||
|  |                   _PostQuestionHint(data: widget.data).padding(bottom: 8), | ||||||
|  |                 if (_displayDescription.isNotEmpty || _displayTitle.isNotEmpty) | ||||||
|  |                   _PostHeadline( | ||||||
|  |                     title: _displayTitle, | ||||||
|  |                     description: _displayDescription, | ||||||
|  |                     data: widget.data, | ||||||
|  |                     isEnlarge: | ||||||
|  |                         widget.data.type == 'article' && widget.showFullPost, | ||||||
|  |                   ).padding(bottom: 8), | ||||||
|  |                 if (widget.data.type == 'article' && !widget.showFullPost) | ||||||
|  |                   Text('postArticle') | ||||||
|  |                       .tr() | ||||||
|  |                       .fontSize(13) | ||||||
|  |                       .opacity(0.75) | ||||||
|  |                       .padding(bottom: 8), | ||||||
|  |                 if ((_displayText.isNotEmpty) && | ||||||
|  |                     (widget.showFullPost || widget.data.type != 'article')) | ||||||
|  |                   _PostContentBody( | ||||||
|  |                     text: _displayText, | ||||||
|  |                     data: widget.data, | ||||||
|  |                     isSelectable: widget.showFullPost, | ||||||
|  |                     isEnlarge: | ||||||
|  |                         widget.data.type == 'article' && widget.showFullPost, | ||||||
|  |                   ).padding(bottom: 6), | ||||||
|  |                 if (widget.data.visibility > 0) | ||||||
|  |                   _PostVisibilityHint(data: widget.data).padding( | ||||||
|  |                     vertical: 4, | ||||||
|  |                   ), | ||||||
|  |                 if (widget.data.body['content_truncated'] == true) | ||||||
|  |                   _PostTruncatedHint(data: widget.data).padding( | ||||||
|  |                     vertical: 4, | ||||||
|  |                   ), | ||||||
|  |                 if (widget.data.tags.isNotEmpty) | ||||||
|  |                   _PostTagsList(data: widget.data).padding(top: 4, bottom: 6), | ||||||
|  |                 Column( | ||||||
|  |                   crossAxisAlignment: CrossAxisAlignment.start, | ||||||
|  |                   spacing: 4, | ||||||
|  |                   children: [ | ||||||
|  |                     if (widget.showViews) | ||||||
|  |                       Row( | ||||||
|  |                         children: [ | ||||||
|  |                           Icon(Symbols.play_circle, size: 20), | ||||||
|  |                           const Gap(4), | ||||||
|  |                           Text('postViews').plural(widget.data.totalViews), | ||||||
|  |                         ], | ||||||
|  |                       ).opacity(0.75), | ||||||
|  |                     if (_isTranslating) | ||||||
|  |                       AnimateWidgetExtensions(Row( | ||||||
|  |                         children: [ | ||||||
|  |                           Icon(Symbols.translate, size: 20), | ||||||
|  |                           const Gap(4), | ||||||
|  |                           Text('translating').tr(), | ||||||
|  |                         ], | ||||||
|  |                       )) | ||||||
|  |                           .animate(onPlay: (e) => e.repeat()) | ||||||
|  |                           .fadeIn(duration: 500.ms, curve: Curves.easeOut) | ||||||
|  |                           .then() | ||||||
|  |                           .fadeOut( | ||||||
|  |                             duration: 500.ms, | ||||||
|  |                             delay: 1000.ms, | ||||||
|  |                             curve: Curves.easeIn, | ||||||
|  |                           ), | ||||||
|  |                     if (_isTranslated) | ||||||
|  |                       InkWell( | ||||||
|  |                         child: Row( | ||||||
|  |                           children: [ | ||||||
|  |                             Icon(Symbols.translate, size: 20), | ||||||
|  |                             const Gap(4), | ||||||
|  |                             Text('translated').tr(), | ||||||
|  |                           ], | ||||||
|  |                         ).opacity(0.75), | ||||||
|  |                         onTap: () { | ||||||
|  |                           setState(() { | ||||||
|  |                             _displayText = widget.data.body['content'] ?? ''; | ||||||
|  |                             _displayTitle = widget.data.body['title'] ?? ''; | ||||||
|  |                             _displayDescription = | ||||||
|  |                                 widget.data.body['description'] ?? ''; | ||||||
|  |                             _isTranslated = false; | ||||||
|  |                           }); | ||||||
|  |                         }, | ||||||
|  |                       ), | ||||||
|  |                     if (widget.data.repostTo != null) | ||||||
|  |                       _PostQuoteContent(child: widget.data.repostTo!).padding( | ||||||
|  |                         top: 4, | ||||||
|  |                         bottom: widget.data.preload?.attachments?.isNotEmpty ?? | ||||||
|  |                                 false | ||||||
|  |                             ? 12 | ||||||
|  |                             : 0, | ||||||
|  |                       ), | ||||||
|  |                   ], | ||||||
|  |                 ).padding( | ||||||
|  |                   bottom: widget.showViews || _isTranslated || _isTranslating | ||||||
|  |                       ? 8 | ||||||
|  |                       : 0, | ||||||
|  |                 ), | ||||||
|               ], |               ], | ||||||
|             ), |             ).padding(horizontal: 12, top: 8), | ||||||
|           ), |           ), | ||||||
|           if (displayableAttachments?.isNotEmpty ?? false) |           if (displayableAttachments?.isNotEmpty ?? false) | ||||||
|             AttachmentList( |             AttachmentList( | ||||||
| @@ -509,6 +506,7 @@ class _PostItemState extends State<PostItem> { | |||||||
|             _PostCommentIntent( |             _PostCommentIntent( | ||||||
|               data: widget.data, |               data: widget.data, | ||||||
|               showAvatar: widget.showAvatar, |               showAvatar: widget.showAvatar, | ||||||
|  |               maxWidth: widget.maxWidth ?? double.infinity, | ||||||
|             ).padding(left: 12, right: 12) |             ).padding(left: 12, right: 12) | ||||||
|           else |           else | ||||||
|             _PostFeaturedComment(data: widget.data, maxWidth: widget.maxWidth) |             _PostFeaturedComment(data: widget.data, maxWidth: widget.maxWidth) | ||||||
| @@ -558,10 +556,22 @@ class _PostItemState extends State<PostItem> { | |||||||
|                         Row( |                         Row( | ||||||
|                           children: [ |                           children: [ | ||||||
|                             Expanded( |                             Expanded( | ||||||
|                               child: _PostContentHeader( |                               child: Row( | ||||||
|                                 isRelativeDate: !widget.showFullPost, |                                 children: [ | ||||||
|                                 isCompact: true, |                                   if (widget.showCompactAvatar) | ||||||
|                                 data: widget.data, |                                     _PostAvatar( | ||||||
|  |                                       data: widget.data, | ||||||
|  |                                       isCompact: true, | ||||||
|  |                                     ), | ||||||
|  |                                   if (widget.showCompactAvatar) const Gap(8), | ||||||
|  |                                   Expanded( | ||||||
|  |                                     child: _PostContentHeader( | ||||||
|  |                                       isRelativeDate: !widget.showFullPost, | ||||||
|  |                                       isCompact: true, | ||||||
|  |                                       data: widget.data, | ||||||
|  |                                     ), | ||||||
|  |                                   ), | ||||||
|  |                                 ], | ||||||
|                               ), |                               ), | ||||||
|                             ), |                             ), | ||||||
|                             _PostActionPopup( |                             _PostActionPopup( | ||||||
| @@ -578,7 +588,7 @@ class _PostItemState extends State<PostItem> { | |||||||
|                               }, |                               }, | ||||||
|                             ), |                             ), | ||||||
|                           ], |                           ], | ||||||
|                         ), |                         ).padding(bottom: widget.showCompactAvatar ? 4 : 0), | ||||||
|                         if (widget.data.preload?.thumbnail != null) |                         if (widget.data.preload?.thumbnail != null) | ||||||
|                           Container( |                           Container( | ||||||
|                             margin: const EdgeInsets.only(bottom: 8), |                             margin: const EdgeInsets.only(bottom: 8), | ||||||
| @@ -755,19 +765,28 @@ class _PostItemState extends State<PostItem> { | |||||||
|         if (widget.showExpandableComments) |         if (widget.showExpandableComments) | ||||||
|           _PostCommentIntent( |           _PostCommentIntent( | ||||||
|             data: widget.data, |             data: widget.data, | ||||||
|  |             maxWidth: (widget.maxWidth ?? double.infinity) - | ||||||
|  |                 (widget.showAvatar ? 72 : 24), | ||||||
|             showAvatar: widget.showAvatar, |             showAvatar: widget.showAvatar, | ||||||
|           ).padding(left: widget.showAvatar ? 60 : 12, right: 12) |           ).padding(left: widget.showAvatar ? 60 : 12, right: 12) | ||||||
|         else if (widget.showComments) |         else if (widget.showComments) | ||||||
|           _PostFeaturedComment(data: widget.data, maxWidth: widget.maxWidth) |           _PostFeaturedComment(data: widget.data, maxWidth: widget.maxWidth) | ||||||
|               .padding(left: widget.showAvatar ? 60 : 12, right: 12), |               .padding(left: widget.showAvatar ? 60 : 12, right: 12), | ||||||
|         if (widget.showReactions) |         if (widget.showReactions) | ||||||
|           Padding( |           Container( | ||||||
|             padding: const EdgeInsets.only(top: 4), |             constraints: BoxConstraints( | ||||||
|             child: _PostReactionList( |               maxWidth: widget.maxWidth ?? double.infinity, | ||||||
|               data: widget.data, |             ), | ||||||
|               padding: |             child: Padding( | ||||||
|                   EdgeInsets.only(left: widget.showAvatar ? 60 : 12, right: 12), |               padding: const EdgeInsets.only(top: 4), | ||||||
|               onChanged: _onChanged, |               child: _PostReactionList( | ||||||
|  |                 data: widget.data, | ||||||
|  |                 padding: EdgeInsets.only( | ||||||
|  |                   left: widget.showAvatar ? 60 : 12, | ||||||
|  |                   right: 12, | ||||||
|  |                 ), | ||||||
|  |                 onChanged: _onChanged, | ||||||
|  |               ), | ||||||
|             ), |             ), | ||||||
|           ), |           ), | ||||||
|       ], |       ], | ||||||
| @@ -1552,19 +1571,24 @@ class _PostContentHeader extends StatelessWidget { | |||||||
|     if (isCompact) { |     if (isCompact) { | ||||||
|       return Row( |       return Row( | ||||||
|         children: [ |         children: [ | ||||||
|           Text(data.publisher.nick).bold(), |           Flexible( | ||||||
|  |             child: Text( | ||||||
|  |               data.publisher.nick, | ||||||
|  |               maxLines: 1, | ||||||
|  |             ).bold(), | ||||||
|  |           ), | ||||||
|           const Gap(4), |           const Gap(4), | ||||||
|           Row( |           Flexible( | ||||||
|             children: [ |             child: Text( | ||||||
|               Text( |               isRelativeDate | ||||||
|                 isRelativeDate |                   ? RelativeTime(context) | ||||||
|                     ? RelativeTime(context) |                       .format((data.publishedAt ?? data.createdAt).toLocal()) | ||||||
|                         .format((data.publishedAt ?? data.createdAt).toLocal()) |                   : DateFormat('y/M/d HH:mm') | ||||||
|                     : DateFormat('y/M/d HH:mm') |                       .format((data.publishedAt ?? data.createdAt).toLocal()), | ||||||
|                         .format((data.publishedAt ?? data.createdAt).toLocal()), |               maxLines: 1, | ||||||
|               ).fontSize(13), |               overflow: TextOverflow.fade, | ||||||
|             ], |             ).fontSize(13).opacity(0.8), | ||||||
|           ).opacity(0.8), |           ), | ||||||
|         ], |         ], | ||||||
|       ); |       ); | ||||||
|     } else { |     } else { | ||||||
| @@ -1573,25 +1597,39 @@ class _PostContentHeader extends StatelessWidget { | |||||||
|         children: [ |         children: [ | ||||||
|           Row( |           Row( | ||||||
|             children: [ |             children: [ | ||||||
|               Text(data.publisher.nick).bold(), |               Flexible( | ||||||
|  |                 child: Text(data.publisher.nick).bold(), | ||||||
|  |               ), | ||||||
|               if (data.preload?.realm != null) |               if (data.preload?.realm != null) | ||||||
|                 const Icon(Symbols.arrow_right, size: 16) |                 const Icon(Symbols.arrow_right, size: 16) | ||||||
|                     .padding(horizontal: 2) |                     .padding(horizontal: 2) | ||||||
|                     .opacity(0.5), |                     .opacity(0.5), | ||||||
|               if (data.preload?.realm != null) Text(data.preload!.realm!.name), |               if (data.preload?.realm != null) | ||||||
|  |                 Flexible( | ||||||
|  |                   child: Text(data.preload!.realm!.name), | ||||||
|  |                 ), | ||||||
|             ], |             ], | ||||||
|           ), |           ), | ||||||
|           Row( |           Row( | ||||||
|             children: [ |             children: [ | ||||||
|               Text('@${data.publisher.name}').fontSize(13), |               Flexible( | ||||||
|  |                 child: Text( | ||||||
|  |                   '@${data.publisher.name}', | ||||||
|  |                   maxLines: 1, | ||||||
|  |                 ).fontSize(13), | ||||||
|  |               ), | ||||||
|               const Gap(4), |               const Gap(4), | ||||||
|               Text( |               Flexible( | ||||||
|                 isRelativeDate |                 child: Text( | ||||||
|                     ? RelativeTime(context) |                   isRelativeDate | ||||||
|                         .format((data.publishedAt ?? data.createdAt).toLocal()) |                       ? RelativeTime(context).format( | ||||||
|                     : DateFormat('y/M/d HH:mm') |                           (data.publishedAt ?? data.createdAt).toLocal()) | ||||||
|                         .format((data.publishedAt ?? data.createdAt).toLocal()), |                       : DateFormat('y/M/d HH:mm').format( | ||||||
|               ).fontSize(13), |                           (data.publishedAt ?? data.createdAt).toLocal()), | ||||||
|  |                   maxLines: 1, | ||||||
|  |                   overflow: TextOverflow.fade, | ||||||
|  |                 ).fontSize(13), | ||||||
|  |               ), | ||||||
|             ], |             ], | ||||||
|           ).opacity(0.8), |           ).opacity(0.8), | ||||||
|         ], |         ], | ||||||
| @@ -1856,7 +1894,12 @@ class _PostTruncatedHint extends StatelessWidget { | |||||||
| class _PostCommentIntent extends StatefulWidget { | class _PostCommentIntent extends StatefulWidget { | ||||||
|   final SnPost data; |   final SnPost data; | ||||||
|   final bool showAvatar; |   final bool showAvatar; | ||||||
|   const _PostCommentIntent({required this.data, this.showAvatar = false}); |   final double maxWidth; | ||||||
|  |   const _PostCommentIntent({ | ||||||
|  |     required this.data, | ||||||
|  |     this.showAvatar = false, | ||||||
|  |     required this.maxWidth, | ||||||
|  |   }); | ||||||
|  |  | ||||||
|   @override |   @override | ||||||
|   State<_PostCommentIntent> createState() => _PostCommentIntentState(); |   State<_PostCommentIntent> createState() => _PostCommentIntentState(); | ||||||
| @@ -1895,54 +1938,69 @@ class _PostCommentIntentState extends State<_PostCommentIntent> { | |||||||
|  |  | ||||||
|   @override |   @override | ||||||
|   Widget build(BuildContext context) { |   Widget build(BuildContext context) { | ||||||
|     return Column( |     return Container( | ||||||
|       children: [ |       constraints: BoxConstraints(maxWidth: widget.maxWidth), | ||||||
|         if (_comments.isNotEmpty) |       child: Column( | ||||||
|           Card( |         children: [ | ||||||
|             elevation: 4, |           if (_comments.isNotEmpty) | ||||||
|             margin: EdgeInsets.zero, |             Card( | ||||||
|             child: Column( |               elevation: 4, | ||||||
|               spacing: 8, |               margin: EdgeInsets.zero, | ||||||
|               children: [ |               child: Column( | ||||||
|                 for (final ele in _comments) |                 spacing: 8, | ||||||
|                   PostItem( |                 children: [ | ||||||
|                     data: ele, |                   for (final ele in _comments) | ||||||
|                     showAvatar: false, |                     InkWell( | ||||||
|                     showExpandableComments: true, |                       borderRadius: const BorderRadius.all(Radius.circular(8)), | ||||||
|                     showReactions: false, |                       child: PostItem( | ||||||
|                     showViews: false, |                         data: ele, | ||||||
|                     maxWidth: double.infinity, |                         showAvatar: false, | ||||||
|                   ).padding(vertical: 8, left: 6), |                         showCompactAvatar: true, | ||||||
|               ], |                         showExpandableComments: true, | ||||||
|             ), |                         showReactions: false, | ||||||
|           ).padding(vertical: 8), |                         showViews: false, | ||||||
|         Row( |                         maxWidth: double.infinity, | ||||||
|           children: [ |                       ).padding(vertical: 8, left: 6), | ||||||
|             Transform.flip( |                       onTap: () { | ||||||
|               flipX: true, |                         GoRouter.of(context).pushNamed( | ||||||
|               child: const Icon(Symbols.comment, size: 20), |                           'postDetail', | ||||||
|             ), |                           pathParameters: {'slug': ele.id.toString()}, | ||||||
|             const Gap(4), |                           extra: ele, | ||||||
|             Text('postCommentsDetailed'.plural(widget.data.metric.replyCount)), |                         ); | ||||||
|             if (widget.data.metric.replyCount > 0 && !_isAllLoaded) |                       }, | ||||||
|               SizedBox( |                     ), | ||||||
|                 width: 20, |                 ], | ||||||
|                 height: 20, |               ), | ||||||
|                 child: IconButton( |             ).padding(vertical: 8), | ||||||
|                   visualDensity: VisualDensity(horizontal: -4, vertical: -4), |           Row( | ||||||
|                   constraints: const BoxConstraints(), |             children: [ | ||||||
|                   padding: EdgeInsets.zero, |               Transform.flip( | ||||||
|                   icon: const Icon(Symbols.expand_more, size: 18), |                 flipX: true, | ||||||
|                   onPressed: _isBusy |                 child: const Icon(Symbols.comment, size: 20), | ||||||
|                       ? null |               ), | ||||||
|                       : () { |               const Gap(4), | ||||||
|                           _fetchComments(); |               Text( | ||||||
|                         }, |                   'postCommentsDetailed'.plural(widget.data.metric.replyCount)), | ||||||
|                 ), |               if (widget.data.metric.replyCount > 0 && !_isAllLoaded) | ||||||
|               ).padding(left: 8), |                 SizedBox( | ||||||
|           ], |                   width: 20, | ||||||
|         ).opacity(0.75).padding(horizontal: widget.showAvatar ? 4 : 0), |                   height: 20, | ||||||
|       ], |                   child: IconButton( | ||||||
|  |                     visualDensity: VisualDensity(horizontal: -4, vertical: -4), | ||||||
|  |                     constraints: const BoxConstraints(), | ||||||
|  |                     padding: EdgeInsets.zero, | ||||||
|  |                     icon: const Icon(Symbols.expand_more, size: 18), | ||||||
|  |                     onPressed: _isBusy | ||||||
|  |                         ? null | ||||||
|  |                         : () { | ||||||
|  |                             _fetchComments(); | ||||||
|  |                           }, | ||||||
|  |                   ), | ||||||
|  |                 ).padding(left: 8), | ||||||
|  |             ], | ||||||
|  |           ).opacity(0.75).padding(horizontal: widget.showAvatar ? 4 : 0), | ||||||
|  |         ], | ||||||
|  |       ), | ||||||
|     ); |     ); | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -16,7 +16,7 @@ publish_to: "none" # Remove this line if you wish to publish to pub.dev | |||||||
| # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html | # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html | ||||||
| # In Windows, build-name is used as the major, minor, and patch parts | # In Windows, build-name is used as the major, minor, and patch parts | ||||||
| # of the product and file versions while build-number is used as the build suffix. | # of the product and file versions while build-number is used as the build suffix. | ||||||
| version: 2.4.2+81 | version: 2.4.2+82 | ||||||
|  |  | ||||||
| environment: | environment: | ||||||
|   sdk: ^3.5.4 |   sdk: ^3.5.4 | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user