diff --git a/lib/screens/post/post_detail.dart b/lib/screens/post/post_detail.dart index be7dacd..0aec245 100644 --- a/lib/screens/post/post_detail.dart +++ b/lib/screens/post/post_detail.dart @@ -64,7 +64,8 @@ class _PostDetailScreenState extends State { @override Widget build(BuildContext context) { final ua = context.watch(); - final devicePixelRatio = MediaQuery.of(context).devicePixelRatio; + + final double maxWidth = _data?.type == 'video' ? double.infinity : 640; return AppBackground( isRoot: widget.onBack != null, @@ -114,7 +115,7 @@ class _PostDetailScreenState extends State { SliverToBoxAdapter( child: PostItem( data: _data!, - maxWidth: 640, + maxWidth: maxWidth, showComments: false, showFullPost: true, onChanged: (data) { @@ -125,11 +126,11 @@ class _PostDetailScreenState extends State { }, ), ), - const SliverToBoxAdapter(child: Divider(height: 1)), - if (_data != null) + if (_data != null && _data!.type != 'video') const SliverToBoxAdapter(child: Divider(height: 1)), + if (_data != null && _data!.type != 'video') SliverToBoxAdapter( child: Container( - constraints: const BoxConstraints(maxWidth: 640), + constraints: BoxConstraints(maxWidth: maxWidth), child: Row( crossAxisAlignment: CrossAxisAlignment.center, children: [ @@ -142,51 +143,30 @@ class _PostDetailScreenState extends State { ).padding(horizontal: 20, vertical: 12).center(), ), ), - if (_data != null && ua.isAuthorized) + if (_data != null && ua.isAuthorized && _data!.type != 'video') SliverToBoxAdapter( - child: Container( - height: 240, - constraints: const BoxConstraints(maxWidth: 640), - margin: - ResponsiveBreakpoints.of(context).largerThan(MOBILE) ? const EdgeInsets.all(8) : EdgeInsets.zero, - decoration: BoxDecoration( - borderRadius: ResponsiveBreakpoints.of(context).largerThan(MOBILE) - ? const BorderRadius.all(Radius.circular(8)) - : BorderRadius.zero, - border: ResponsiveBreakpoints.of(context).largerThan(MOBILE) - ? Border.all( - color: Theme.of(context).dividerColor, - width: 1 / devicePixelRatio, - ) - : Border.symmetric( - horizontal: BorderSide( - color: Theme.of(context).dividerColor, - width: 1 / devicePixelRatio, - ), - ), - ), - child: PostMiniEditor( - postReplyId: _data!.id, - onPost: () { - setState(() { - _data = _data!.copyWith( - metric: _data!.metric.copyWith( - replyCount: _data!.metric.replyCount + 1, - ), - ); - }); - _childListKey.currentState!.refresh(); - }, - ), - ).center(), + child: PostCommentQuickAction( + parentPost: _data!, + maxWidth: maxWidth, + onPosted: () { + setState(() { + _data = _data!.copyWith( + metric: _data!.metric.copyWith( + replyCount: _data!.metric.replyCount + 1, + ), + ); + }); + _childListKey.currentState!.refresh(); + }, + ), ), - if (_data != null) + if (_data != null && _data!.type != 'video') PostCommentSliverList( key: _childListKey, parentPost: _data!, - maxWidth: 640, + maxWidth: maxWidth, ), - SliverGap(math.max(MediaQuery.of(context).padding.bottom, 16)), + if (_data != null && _data!.type == 'video') SliverGap(math.max(MediaQuery.of(context).padding.bottom, 16)), ], ), ), diff --git a/lib/widgets/post/post_comment_list.dart b/lib/widgets/post/post_comment_list.dart index 6ca8340..cb883ea 100644 --- a/lib/widgets/post/post_comment_list.dart +++ b/lib/widgets/post/post_comment_list.dart @@ -4,6 +4,7 @@ import 'package:gap/gap.dart'; import 'package:go_router/go_router.dart'; import 'package:material_symbols_icons/symbols.dart'; import 'package:provider/provider.dart'; +import 'package:responsive_framework/responsive_framework.dart'; import 'package:styled_widget/styled_widget.dart'; import 'package:surface/providers/post.dart'; import 'package:surface/providers/userinfo.dart'; @@ -15,6 +16,47 @@ import 'package:very_good_infinite_list/very_good_infinite_list.dart'; import '../../providers/sn_network.dart'; +class PostCommentQuickAction extends StatelessWidget { + final double? maxWidth; + final SnPost parentPost; + final Function? onPosted; + + const PostCommentQuickAction({super.key, this.maxWidth, required this.parentPost, this.onPosted}); + + @override + Widget build(BuildContext context) { + final devicePixelRatio = MediaQuery.of(context).devicePixelRatio; + + return Container( + height: 240, + constraints: BoxConstraints(maxWidth: maxWidth ?? double.infinity), + margin: ResponsiveBreakpoints.of(context).largerThan(MOBILE) ? const EdgeInsets.symmetric(vertical: 8) : EdgeInsets.zero, + decoration: BoxDecoration( + borderRadius: ResponsiveBreakpoints.of(context).largerThan(MOBILE) + ? const BorderRadius.all(Radius.circular(8)) + : BorderRadius.zero, + border: ResponsiveBreakpoints.of(context).largerThan(MOBILE) + ? Border.all( + color: Theme.of(context).dividerColor, + width: 1 / devicePixelRatio, + ) + : Border.symmetric( + horizontal: BorderSide( + color: Theme.of(context).dividerColor, + width: 1 / devicePixelRatio, + ), + ), + ), + child: PostMiniEditor( + postReplyId: parentPost.id, + onPost: () { + onPosted?.call(); + }, + ), + ); + } +} + class PostCommentSliverList extends StatefulWidget { final SnPost parentPost; final double? maxWidth; @@ -71,6 +113,7 @@ class PostCommentSliverListState extends State { Future refresh() async { _posts.clear(); + _postCount = null; _fetchPosts(); } diff --git a/lib/widgets/post/post_item.dart b/lib/widgets/post/post_item.dart index 770f36e..2c86316 100644 --- a/lib/widgets/post/post_item.dart +++ b/lib/widgets/post/post_item.dart @@ -195,6 +195,57 @@ class PostItem extends StatelessWidget { final ua = context.read(); final isAuthor = ua.isAuthorized && data.publisher.accountId == ua.user?.id; + // Video full view + if (showFullPost && data.type == 'video' && ResponsiveBreakpoints.of(context).largerThan(TABLET)) { + return Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const Gap(16), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + _PostContentHeader( + data: data, + isAuthor: isAuthor, + isRelativeDate: !showFullPost, + onShare: () => _doShare(context), + onShareImage: () => _doShareViaPicture(context), + onSelectAnswer: onSelectAnswer, + onDeleted: () { + if (onDeleted != null) {} + }, + ).padding(bottom: 8), + if (data.preload?.video != null) _PostVideoPlayer(data: data).padding(bottom: 8), + _PostHeadline(data: data).padding(horizontal: 4, bottom: 8), + _PostFeaturedComment(data: data).padding(), + _PostBottomAction( + data: data, + showComments: true, + showReactions: showReactions, + onShare: () => _doShare(context), + onShareImage: () => _doShareViaPicture(context), + onChanged: _onChanged, + ), + ], + ), + ), + const Gap(4), + SizedBox( + width: 340, + child: CustomScrollView( + shrinkWrap: true, + slivers: [ + PostCommentSliverList( + parentPost: data, + ), + ], + ), + ), + ], + ); + } + // Article headline preview if (!showFullPost && data.type == 'article') { return Container(