From 89b35d7852746e6e25c11933ff4ffc853a418db3 Mon Sep 17 00:00:00 2001 From: John Wesley Date: Thu, 11 Jan 2024 11:29:40 -0500 Subject: [PATCH] Redesign comment views to make it cleaner and easier to follow --- lib/src/api/post_comments.dart | 2 +- lib/src/screens/entries/entries_list.dart | 56 ++-- lib/src/screens/entries/entry_comment.dart | 243 ++++++++++-------- lib/src/screens/entries/entry_page.dart | 7 +- lib/src/screens/explore/domains_screen.dart | 4 +- lib/src/screens/explore/magazines_screen.dart | 4 +- lib/src/screens/explore/users_screen.dart | 2 +- lib/src/screens/posts/post_comment.dart | 243 ++++++++++-------- lib/src/screens/posts/post_page.dart | 7 +- lib/src/screens/posts/posts_list.dart | 56 ++-- lib/src/widgets/content_item.dart | 76 +++--- lib/src/widgets/wrapper.dart | 19 ++ 12 files changed, 388 insertions(+), 331 deletions(-) create mode 100644 lib/src/widgets/wrapper.dart diff --git a/lib/src/api/post_comments.dart b/lib/src/api/post_comments.dart index 65ebe66..a224006 100644 --- a/lib/src/api/post_comments.dart +++ b/lib/src/api/post_comments.dart @@ -16,7 +16,7 @@ Future fetchComments( final response = await client.get(Uri.https( instanceHost, '/api/posts/$postId/comments', - removeNulls({'p': page?.toString(), 'sortBy': sort?.name}))); + removeNulls({'p': page?.toString(), 'sort': sort?.name}))); httpErrorHandler(response, message: 'Failed to load comments'); diff --git a/lib/src/screens/entries/entries_list.dart b/lib/src/screens/entries/entries_list.dart index 4bafc7c..c877039 100644 --- a/lib/src/screens/entries/entries_list.dart +++ b/lib/src/screens/entries/entries_list.dart @@ -75,7 +75,7 @@ class _EntriesListViewState extends State { ), SliverToBoxAdapter( child: Padding( - padding: const EdgeInsets.all(8.0), + padding: const EdgeInsets.all(12), child: Row( children: [ DropdownButton( @@ -122,35 +122,33 @@ class _EntriesListViewState extends State { PagedSliverList( pagingController: _pagingController, builderDelegate: PagedChildBuilderDelegate( - itemBuilder: (context, item, index) => Padding( - padding: const EdgeInsets.all(8.0), - child: Card( - clipBehavior: Clip.antiAlias, - child: InkWell( - onTap: () { - Navigator.of(context).push( - MaterialPageRoute( - builder: (context) => EntryPage(item, (newValue) { - var newList = _pagingController.itemList; - newList![index] = newValue; - setState(() { - _pagingController.itemList = newList; - }); - }), - ), - ); + itemBuilder: (context, item, index) => Card( + margin: const EdgeInsets.all(12), + clipBehavior: Clip.antiAlias, + child: InkWell( + onTap: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => EntryPage(item, (newValue) { + var newList = _pagingController.itemList; + newList![index] = newValue; + setState(() { + _pagingController.itemList = newList; + }); + }), + ), + ); + }, + child: EntryItem( + item, + (newValue) { + var newList = _pagingController.itemList; + newList![index] = newValue; + setState(() { + _pagingController.itemList = newList; + }); }, - child: EntryItem( - item, - (newValue) { - var newList = _pagingController.itemList; - newList![index] = newValue; - setState(() { - _pagingController.itemList = newList; - }); - }, - isPreview: true, - ), + isPreview: true, ), ), ), diff --git a/lib/src/screens/entries/entry_comment.dart b/lib/src/screens/entries/entry_comment.dart index b757b85..c5f0143 100644 --- a/lib/src/screens/entries/entry_comment.dart +++ b/lib/src/screens/entries/entry_comment.dart @@ -17,119 +17,142 @@ class EntryComment extends StatefulWidget { } class _EntryCommentState extends State { + bool _isCollapsed = false; + @override Widget build(BuildContext context) { - return Card( - child: ContentItem( - body: widget.comment.body ?? '_comment deleted_', - createdAt: widget.comment.createdAt, - user: widget.comment.user.username, - userIcon: widget.comment.user.avatar?.storageUrl, - userIdOnClick: widget.comment.user.userId, - boosts: widget.comment.uv, - isBoosted: widget.comment.userVote == 1, - onBoost: whenLoggedIn(context, () async { - var newValue = await api_comments.putVote( - context.read().httpClient, - context.read().instanceHost, - widget.comment.commentId, - 1, - ); - widget.onUpdate(newValue.copyWith( - childCount: widget.comment.childCount, - children: widget.comment.children, - )); - }), - upVotes: widget.comment.favourites, - isUpVoted: widget.comment.isFavourited == true, - onUpVote: whenLoggedIn(context, () async { - var newValue = await api_comments.putFavorite( - context.read().httpClient, - context.read().instanceHost, - widget.comment.commentId, - ); - widget.onUpdate(newValue.copyWith( - childCount: widget.comment.childCount, - children: widget.comment.children, - )); - }), - downVotes: widget.comment.dv, - isDownVoted: widget.comment.userVote == -1, - onDownVote: whenLoggedIn(context, () async { - var newValue = await api_comments.putVote( - context.read().httpClient, - context.read().instanceHost, - widget.comment.commentId, - -1, - ); - widget.onUpdate(newValue.copyWith( - childCount: widget.comment.childCount, - children: widget.comment.children, - )); - }), - showCollapse: true, - onReply: (body) async { - var newSubComment = await api_comments.postComment( - context.read().httpClient, - context.read().instanceHost, - body, - widget.comment.entryId, - parentCommentId: widget.comment.commentId, - ); + return Column( + children: [ + Card( + margin: const EdgeInsets.only(top: 8), + child: ContentItem( + body: widget.comment.body ?? '_comment deleted_', + createdAt: widget.comment.createdAt, + user: widget.comment.user.username, + userIcon: widget.comment.user.avatar?.storageUrl, + userIdOnClick: widget.comment.user.userId, + boosts: widget.comment.uv, + isBoosted: widget.comment.userVote == 1, + onBoost: whenLoggedIn(context, () async { + var newValue = await api_comments.putVote( + context.read().httpClient, + context.read().instanceHost, + widget.comment.commentId, + 1, + ); + widget.onUpdate(newValue.copyWith( + childCount: widget.comment.childCount, + children: widget.comment.children, + )); + }), + upVotes: widget.comment.favourites, + isUpVoted: widget.comment.isFavourited == true, + onUpVote: whenLoggedIn(context, () async { + var newValue = await api_comments.putFavorite( + context.read().httpClient, + context.read().instanceHost, + widget.comment.commentId, + ); + widget.onUpdate(newValue.copyWith( + childCount: widget.comment.childCount, + children: widget.comment.children, + )); + }), + downVotes: widget.comment.dv, + isDownVoted: widget.comment.userVote == -1, + onDownVote: whenLoggedIn(context, () async { + var newValue = await api_comments.putVote( + context.read().httpClient, + context.read().instanceHost, + widget.comment.commentId, + -1, + ); + widget.onUpdate(newValue.copyWith( + childCount: widget.comment.childCount, + children: widget.comment.children, + )); + }), + onReply: (body) async { + var newSubComment = await api_comments.postComment( + context.read().httpClient, + context.read().instanceHost, + body, + widget.comment.entryId, + parentCommentId: widget.comment.commentId, + ); - widget.onUpdate(widget.comment.copyWith( - childCount: widget.comment.childCount + 1, - children: [newSubComment, ...widget.comment.children!], - )); - }, - onEdit: widget.comment.visibility != 'soft_deleted' - ? whenLoggedIn(context, (body) async { - var newValue = await api_comments.editComment( - context.read().httpClient, - context.read().instanceHost, - widget.comment.commentId, - body, - widget.comment.lang, - widget.comment.isAdult); - widget.onUpdate(newValue.copyWith( - childCount: widget.comment.childCount, - children: widget.comment.children, - )); - }, matchesUsername: widget.comment.user.username) - : null, - onDelete: widget.comment.visibility != 'soft_deleted' - ? whenLoggedIn(context, () async { - await api_comments.deleteComment( - context.read().httpClient, - context.read().instanceHost, - widget.comment.commentId, - ); - widget.onUpdate(widget.comment.copyWith( - body: '_comment deleted_', - uv: null, - dv: null, - favourites: null, - visibility: 'soft_deleted', - )); - }, matchesUsername: widget.comment.user.username) - : null, - child: widget.comment.childCount > 0 - ? Column( - children: widget.comment.children! - .asMap() - .entries - .map((item) => EntryComment(item.value, (newValue) { - var newChildren = [...widget.comment.children!]; - newChildren[item.key] = newValue; - widget.onUpdate(widget.comment.copyWith( - childCount: widget.comment.childCount + 1, - children: newChildren, - )); - })) - .toList(), - ) - : null, - ), + widget.onUpdate(widget.comment.copyWith( + childCount: widget.comment.childCount + 1, + children: [newSubComment, ...widget.comment.children!], + )); + }, + onEdit: widget.comment.visibility != 'soft_deleted' + ? whenLoggedIn(context, (body) async { + var newValue = await api_comments.editComment( + context.read().httpClient, + context.read().instanceHost, + widget.comment.commentId, + body, + widget.comment.lang, + widget.comment.isAdult); + widget.onUpdate(newValue.copyWith( + childCount: widget.comment.childCount, + children: widget.comment.children, + )); + }, matchesUsername: widget.comment.user.username) + : null, + onDelete: widget.comment.visibility != 'soft_deleted' + ? whenLoggedIn(context, () async { + await api_comments.deleteComment( + context.read().httpClient, + context.read().instanceHost, + widget.comment.commentId, + ); + widget.onUpdate(widget.comment.copyWith( + body: '_comment deleted_', + uv: null, + dv: null, + favourites: null, + visibility: 'soft_deleted', + )); + }, matchesUsername: widget.comment.user.username) + : null, + isCollapsed: _isCollapsed, + onCollapse: widget.comment.childCount > 0 + ? () => setState(() { + _isCollapsed = !_isCollapsed; + }) + : null, + ), + ), + if (widget.comment.childCount > 0 && !_isCollapsed) + Container( + margin: const EdgeInsets.only(left: 1), + padding: const EdgeInsets.only(left: 10), + decoration: BoxDecoration( + border: Border( + left: BorderSide( + color: Theme.of(context).colorScheme.outlineVariant, + width: 1, + ), + ), + ), + child: Column( + children: widget.comment.children! + .asMap() + .entries + .map((item) => EntryComment(item.value, (newValue) { + var newChildren = [...widget.comment.children!]; + newChildren[item.key] = newValue; + widget.onUpdate(widget.comment.copyWith( + childCount: widget.comment.childCount + 1, + children: newChildren, + )); + })) + .toList(), + ), + ), + ], ); } } diff --git a/lib/src/screens/entries/entry_page.dart b/lib/src/screens/entries/entry_page.dart index 8690851..b3d52cd 100644 --- a/lib/src/screens/entries/entry_page.dart +++ b/lib/src/screens/entries/entry_page.dart @@ -148,7 +148,7 @@ class _EntryPageState extends State { ), SliverToBoxAdapter( child: Padding( - padding: const EdgeInsets.all(8.0), + padding: const EdgeInsets.all(12), child: Row( children: [ DropdownButton( @@ -192,7 +192,10 @@ class _EntryPageState extends State { pagingController: _pagingController, builderDelegate: PagedChildBuilderDelegate( itemBuilder: (context, item, index) => Padding( - padding: const EdgeInsets.all(8), + padding: const EdgeInsets.symmetric( + horizontal: 12, + vertical: 4, + ), child: EntryComment(item, (newValue) { var newList = _pagingController.itemList; newList![index] = newValue; diff --git a/lib/src/screens/explore/domains_screen.dart b/lib/src/screens/explore/domains_screen.dart index 9bbf7f2..3d9f26a 100644 --- a/lib/src/screens/explore/domains_screen.dart +++ b/lib/src/screens/explore/domains_screen.dart @@ -63,7 +63,7 @@ class _DomainsScreenState extends State { slivers: [ SliverToBoxAdapter( child: Padding( - padding: const EdgeInsets.all(12.0), + padding: const EdgeInsets.all(12), child: Row( children: [ SizedBox( @@ -106,7 +106,7 @@ class _DomainsScreenState extends State { ); }, child: Padding( - padding: const EdgeInsets.all(12.0), + padding: const EdgeInsets.all(12), child: Row(children: [ Expanded( child: diff --git a/lib/src/screens/explore/magazines_screen.dart b/lib/src/screens/explore/magazines_screen.dart index e076634..2e3142c 100644 --- a/lib/src/screens/explore/magazines_screen.dart +++ b/lib/src/screens/explore/magazines_screen.dart @@ -66,7 +66,7 @@ class _MagazinesScreenState extends State { slivers: [ SliverToBoxAdapter( child: Padding( - padding: const EdgeInsets.all(12.0), + padding: const EdgeInsets.all(12), child: Row( children: [ DropdownButton( @@ -135,7 +135,7 @@ class _MagazinesScreenState extends State { ); }, child: Padding( - padding: const EdgeInsets.all(12.0), + padding: const EdgeInsets.all(12), child: Row(children: [ if (item.icon?.storageUrl != null) Avatar(item.icon!.storageUrl, radius: 16), diff --git a/lib/src/screens/explore/users_screen.dart b/lib/src/screens/explore/users_screen.dart index 3f074d5..7015089 100644 --- a/lib/src/screens/explore/users_screen.dart +++ b/lib/src/screens/explore/users_screen.dart @@ -82,7 +82,7 @@ class _UsersScreenState extends State { ); }, child: Padding( - padding: const EdgeInsets.all(12.0), + padding: const EdgeInsets.all(12), child: Row(children: [ if (item.avatar?.storageUrl != null) Avatar( diff --git a/lib/src/screens/posts/post_comment.dart b/lib/src/screens/posts/post_comment.dart index 79d38ba..2d3fbab 100644 --- a/lib/src/screens/posts/post_comment.dart +++ b/lib/src/screens/posts/post_comment.dart @@ -17,119 +17,142 @@ class PostComment extends StatefulWidget { } class _EntryCommentState extends State { + bool _isCollapsed = false; + @override Widget build(BuildContext context) { - return Card( - child: ContentItem( - body: widget.comment.body ?? '_comment deleted_', - createdAt: widget.comment.createdAt, - user: widget.comment.user.username, - userIcon: widget.comment.user.avatar?.storageUrl, - userIdOnClick: widget.comment.user.userId, - boosts: widget.comment.uv, - isBoosted: widget.comment.userVote == 1, - onBoost: whenLoggedIn(context, () async { - var newValue = await api_comments.putVote( - context.read().httpClient, - context.read().instanceHost, - widget.comment.commentId, - 1, - ); - widget.onUpdate(newValue.copyWith( - childCount: widget.comment.childCount, - children: widget.comment.children, - )); - }), - upVotes: widget.comment.favourites, - onUpVote: whenLoggedIn(context, () async { - var newValue = await api_comments.putFavorite( - context.read().httpClient, - context.read().instanceHost, - widget.comment.commentId, - ); - widget.onUpdate(newValue.copyWith( - childCount: widget.comment.childCount, - children: widget.comment.children, - )); - }), - isUpVoted: widget.comment.isFavourited == true, - downVotes: widget.comment.dv, - isDownVoted: widget.comment.userVote == -1, - onDownVote: whenLoggedIn(context, () async { - var newValue = await api_comments.putVote( - context.read().httpClient, - context.read().instanceHost, - widget.comment.commentId, - -1, - ); - widget.onUpdate(newValue.copyWith( - childCount: widget.comment.childCount, - children: widget.comment.children, - )); - }), - showCollapse: true, - onReply: (body) async { - var newSubComment = await api_comments.postComment( - context.read().httpClient, - context.read().instanceHost, - body, - widget.comment.postId, - parentCommentId: widget.comment.commentId, - ); + return Column( + children: [ + Card( + margin: const EdgeInsets.only(top: 8), + child: ContentItem( + body: widget.comment.body ?? '_comment deleted_', + createdAt: widget.comment.createdAt, + user: widget.comment.user.username, + userIcon: widget.comment.user.avatar?.storageUrl, + userIdOnClick: widget.comment.user.userId, + boosts: widget.comment.uv, + isBoosted: widget.comment.userVote == 1, + onBoost: whenLoggedIn(context, () async { + var newValue = await api_comments.putVote( + context.read().httpClient, + context.read().instanceHost, + widget.comment.commentId, + 1, + ); + widget.onUpdate(newValue.copyWith( + childCount: widget.comment.childCount, + children: widget.comment.children, + )); + }), + upVotes: widget.comment.favourites, + onUpVote: whenLoggedIn(context, () async { + var newValue = await api_comments.putFavorite( + context.read().httpClient, + context.read().instanceHost, + widget.comment.commentId, + ); + widget.onUpdate(newValue.copyWith( + childCount: widget.comment.childCount, + children: widget.comment.children, + )); + }), + isUpVoted: widget.comment.isFavourited == true, + downVotes: widget.comment.dv, + isDownVoted: widget.comment.userVote == -1, + onDownVote: whenLoggedIn(context, () async { + var newValue = await api_comments.putVote( + context.read().httpClient, + context.read().instanceHost, + widget.comment.commentId, + -1, + ); + widget.onUpdate(newValue.copyWith( + childCount: widget.comment.childCount, + children: widget.comment.children, + )); + }), + onReply: (body) async { + var newSubComment = await api_comments.postComment( + context.read().httpClient, + context.read().instanceHost, + body, + widget.comment.postId, + parentCommentId: widget.comment.commentId, + ); - widget.onUpdate(widget.comment.copyWith( - childCount: widget.comment.childCount + 1, - children: [newSubComment, ...widget.comment.children!], - )); - }, - onEdit: widget.comment.visibility != 'soft_deleted' - ? whenLoggedIn(context, (body) async { - var newValue = await api_comments.editComment( - context.read().httpClient, - context.read().instanceHost, - widget.comment.commentId, - body, - widget.comment.lang, - widget.comment.isAdult); - widget.onUpdate(newValue.copyWith( - childCount: widget.comment.childCount, - children: widget.comment.children, - )); - }) - : null, - onDelete: widget.comment.visibility != 'soft_deleted' - ? whenLoggedIn(context, () async { - await api_comments.deleteComment( - context.read().httpClient, - context.read().instanceHost, - widget.comment.commentId, - ); - widget.onUpdate(widget.comment.copyWith( - body: '_comment deleted_', - uv: null, - dv: null, - favourites: null, - visibility: 'soft_deleted', - )); - }) - : null, - child: widget.comment.childCount > 0 - ? Column( - children: widget.comment.children! - .asMap() - .entries - .map((item) => PostComment(item.value, (newValue) { - var newChildren = [...widget.comment.children!]; - newChildren[item.key] = newValue; - widget.onUpdate(widget.comment.copyWith( - childCount: widget.comment.childCount + 1, - children: newChildren, - )); - })) - .toList(), - ) - : null, - ), + widget.onUpdate(widget.comment.copyWith( + childCount: widget.comment.childCount + 1, + children: [newSubComment, ...widget.comment.children!], + )); + }, + onEdit: widget.comment.visibility != 'soft_deleted' + ? whenLoggedIn(context, (body) async { + var newValue = await api_comments.editComment( + context.read().httpClient, + context.read().instanceHost, + widget.comment.commentId, + body, + widget.comment.lang, + widget.comment.isAdult); + widget.onUpdate(newValue.copyWith( + childCount: widget.comment.childCount, + children: widget.comment.children, + )); + }) + : null, + onDelete: widget.comment.visibility != 'soft_deleted' + ? whenLoggedIn(context, () async { + await api_comments.deleteComment( + context.read().httpClient, + context.read().instanceHost, + widget.comment.commentId, + ); + widget.onUpdate(widget.comment.copyWith( + body: '_comment deleted_', + uv: null, + dv: null, + favourites: null, + visibility: 'soft_deleted', + )); + }) + : null, + isCollapsed: _isCollapsed, + onCollapse: widget.comment.childCount > 0 + ? () => setState(() { + _isCollapsed = !_isCollapsed; + }) + : null, + ), + ), + if (widget.comment.childCount > 0 && !_isCollapsed) + Container( + margin: const EdgeInsets.only(left: 1), + padding: const EdgeInsets.only(left: 10), + decoration: BoxDecoration( + border: Border( + left: BorderSide( + color: Theme.of(context).colorScheme.outlineVariant, + width: 1, + ), + ), + ), + child: Column( + children: widget.comment.children! + .asMap() + .entries + .map((item) => PostComment(item.value, (newValue) { + var newChildren = [...widget.comment.children!]; + newChildren[item.key] = newValue; + widget.onUpdate(widget.comment.copyWith( + childCount: widget.comment.childCount + 1, + children: newChildren, + )); + })) + .toList(), + ), + ), + ], ); } } diff --git a/lib/src/screens/posts/post_page.dart b/lib/src/screens/posts/post_page.dart index 4c511d7..381196a 100644 --- a/lib/src/screens/posts/post_page.dart +++ b/lib/src/screens/posts/post_page.dart @@ -144,7 +144,7 @@ class _PostPageState extends State { ), SliverToBoxAdapter( child: Padding( - padding: const EdgeInsets.all(8.0), + padding: const EdgeInsets.all(12), child: Row( children: [ DropdownButton( @@ -188,7 +188,10 @@ class _PostPageState extends State { pagingController: _pagingController, builderDelegate: PagedChildBuilderDelegate( itemBuilder: (context, item, index) => Padding( - padding: const EdgeInsets.all(8), + padding: const EdgeInsets.symmetric( + horizontal: 12, + vertical: 4, + ), child: PostComment(item, (newValue) { var newList = _pagingController.itemList; newList![index] = newValue; diff --git a/lib/src/screens/posts/posts_list.dart b/lib/src/screens/posts/posts_list.dart index 880557f..d324de8 100644 --- a/lib/src/screens/posts/posts_list.dart +++ b/lib/src/screens/posts/posts_list.dart @@ -75,7 +75,7 @@ class _PostsListViewState extends State { ), SliverToBoxAdapter( child: Padding( - padding: const EdgeInsets.all(8.0), + padding: const EdgeInsets.all(12), child: Row( children: [ DropdownButton( @@ -122,35 +122,33 @@ class _PostsListViewState extends State { PagedSliverList( pagingController: _pagingController, builderDelegate: PagedChildBuilderDelegate( - itemBuilder: (context, item, index) => Padding( - padding: const EdgeInsets.all(8.0), - child: Card( - clipBehavior: Clip.antiAlias, - child: InkWell( - onTap: () { - Navigator.of(context).push( - MaterialPageRoute( - builder: (context) => PostPage(item, (newValue) { - var newList = _pagingController.itemList; - newList![index] = newValue; - setState(() { - _pagingController.itemList = newList; - }); - }), - ), - ); + itemBuilder: (context, item, index) => Card( + margin: const EdgeInsets.all(12), + clipBehavior: Clip.antiAlias, + child: InkWell( + onTap: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => PostPage(item, (newValue) { + var newList = _pagingController.itemList; + newList![index] = newValue; + setState(() { + _pagingController.itemList = newList; + }); + }), + ), + ); + }, + child: PostItem( + item, + (newValue) { + var newList = _pagingController.itemList; + newList![index] = newValue; + setState(() { + _pagingController.itemList = newList; + }); }, - child: PostItem( - item, - (newValue) { - var newList = _pagingController.itemList; - newList![index] = newValue; - setState(() { - _pagingController.itemList = newList; - }); - }, - isPreview: true, - ), + isPreview: true, ), ), ), diff --git a/lib/src/widgets/content_item.dart b/lib/src/widgets/content_item.dart index a26d6a0..41bb532 100644 --- a/lib/src/widgets/content_item.dart +++ b/lib/src/widgets/content_item.dart @@ -8,6 +8,7 @@ import 'package:interstellar/src/widgets/markdown.dart'; import 'package:interstellar/src/widgets/markdown_editor.dart'; import 'package:interstellar/src/widgets/open_webpage.dart'; import 'package:interstellar/src/widgets/video.dart'; +import 'package:interstellar/src/widgets/wrapper.dart'; class ContentItem extends StatefulWidget { final String? title; @@ -18,7 +19,6 @@ class ContentItem extends StatefulWidget { final DateTime? createdAt; final bool isPreview; - final bool showCollapse; final bool showMagazineFirst; final String? user; @@ -49,7 +49,8 @@ class ContentItem extends StatefulWidget { final Future Function(String)? onEdit; final Future Function()? onDelete; - final Widget? child; + final bool isCollapsed; + final void Function()? onCollapse; const ContentItem( {this.title, @@ -59,7 +60,6 @@ class ContentItem extends StatefulWidget { this.body, this.createdAt, this.isPreview = false, - this.showCollapse = false, this.showMagazineFirst = false, this.user, this.userIcon, @@ -82,7 +82,8 @@ class ContentItem extends StatefulWidget { this.onReply, this.onEdit, this.onDelete, - this.child, + this.isCollapsed = false, + this.onCollapse, super.key}); @override @@ -90,7 +91,6 @@ class ContentItem extends StatefulWidget { } class _ContentItemState extends State { - bool _isCollapsed = false; TextEditingController? _replyTextController; TextEditingController? _editTextController; final MenuController _menuController = MenuController(); @@ -161,35 +161,32 @@ class _ContentItemState extends State { return Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ - if (!widget.isPreview && widget.video != null) - VideoPlayer(widget.video!), - if (widget.image != null && - !(!widget.isPreview && widget.video != null)) - widget.isPreview - ? (widget.video != null - ? Image.network( - widget.image!, - height: 160, - width: double.infinity, - fit: BoxFit.cover, - ) - : InkWell( + if (widget.image != null || (!widget.isPreview && widget.video != null)) + Wrapper( + shouldWrap: !widget.isPreview, + parentBuilder: (child) => Container( + constraints: BoxConstraints( + maxHeight: MediaQuery.of(context).size.height / 2, + ), + child: child), + child: (!widget.isPreview && widget.video != null) + ? VideoPlayer(widget.video!) + : Wrapper( + shouldWrap: widget.video == null, + parentBuilder: (child) => InkWell( onTap: () => _onImageClick(context), - child: Image.network( - widget.image!, - height: 160, - width: double.infinity, - fit: BoxFit.cover, - ), - )) - : Container( - constraints: BoxConstraints( - maxHeight: MediaQuery.of(context).size.height / 2, + child: child, + ), + child: widget.isPreview + ? Image.network( + widget.image!, + height: 160, + width: double.infinity, + fit: BoxFit.cover, + ) + : Image.network(widget.image!), ), - child: InkWell( - onTap: () => _onImageClick(context), - child: Image.network(widget.image!), - )), + ), Container( padding: const EdgeInsets.all(12), child: Column( @@ -290,13 +287,11 @@ class _ContentItemState extends State { }), ), ), - if (widget.showCollapse && widget.child != null) + if (widget.onCollapse != null) IconButton( - tooltip: _isCollapsed ? 'Expand' : 'Collapse', - onPressed: () => setState(() { - _isCollapsed = !_isCollapsed; - }), - icon: _isCollapsed + tooltip: widget.isCollapsed ? 'Expand' : 'Collapse', + onPressed: widget.onCollapse, + icon: widget.isCollapsed ? const Icon(Icons.expand_more) : const Icon(Icons.expand_less)), const Spacer(), @@ -450,11 +445,6 @@ class _ContentItemState extends State { ], ), ), - if (widget.child != null && !_isCollapsed) - Padding( - padding: const EdgeInsets.only(top: 10), - child: widget.child, - ) ], ), ), diff --git a/lib/src/widgets/wrapper.dart b/lib/src/widgets/wrapper.dart new file mode 100644 index 0000000..83810ca --- /dev/null +++ b/lib/src/widgets/wrapper.dart @@ -0,0 +1,19 @@ +import 'package:flutter/material.dart'; + +class Wrapper extends StatelessWidget { + final bool shouldWrap; + final Widget Function(Widget child) parentBuilder; + final Widget child; + + const Wrapper({ + super.key, + required this.shouldWrap, + required this.parentBuilder, + required this.child, + }); + + @override + Widget build(BuildContext context) { + return shouldWrap ? parentBuilder(child) : child; + } +}