From aff21cec407188e4f781f608e48e0f61dd78b22a Mon Sep 17 00:00:00 2001 From: ice-kreios <180917405+ice-kreios@users.noreply.github.com> Date: Fri, 3 Jan 2025 09:58:56 +0200 Subject: [PATCH 1/2] fix: render article entity in quote box --- .../components/quoted_entity.dart | 35 +++++++++---- .../quoted_post_frame/quoted_post_frame.dart | 24 --------- .../feed/views/components/post/post.dart | 4 +- .../quoted_entity_frame.dart | 51 +++++++++++++++++++ 4 files changed, 77 insertions(+), 37 deletions(-) delete mode 100644 lib/app/features/feed/views/components/post/components/quoted_post_frame/quoted_post_frame.dart create mode 100644 lib/app/features/feed/views/components/quoted_entity_frame/quoted_entity_frame.dart diff --git a/lib/app/features/feed/create_post/views/pages/create_post_modal/components/quoted_entity.dart b/lib/app/features/feed/create_post/views/pages/create_post_modal/components/quoted_entity.dart index 12c14f877..bd947733e 100644 --- a/lib/app/features/feed/create_post/views/pages/create_post_modal/components/quoted_entity.dart +++ b/lib/app/features/feed/create_post/views/pages/create_post_modal/components/quoted_entity.dart @@ -1,18 +1,21 @@ // SPDX-License-Identifier: ice License 1.0 import 'package:flutter/material.dart'; +import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:ion/app/components/skeleton/skeleton.dart'; import 'package:ion/app/extensions/extensions.dart'; +import 'package:ion/app/features/feed/data/models/entities/article_data.c.dart'; import 'package:ion/app/features/feed/data/models/entities/post_data.c.dart'; -import 'package:ion/app/features/feed/views/components/post/components/quoted_post_frame/quoted_post_frame.dart'; +import 'package:ion/app/features/feed/views/components/article/article.dart'; import 'package:ion/app/features/feed/views/components/post/post.dart'; import 'package:ion/app/features/feed/views/components/post/post_skeleton.dart'; +import 'package:ion/app/features/feed/views/components/quoted_entity_frame/quoted_entity_frame.dart'; import 'package:ion/app/features/feed/views/components/user_info/user_info.dart'; import 'package:ion/app/features/nostr/model/event_reference.c.dart'; import 'package:ion/app/features/nostr/providers/nostr_entity_provider.c.dart'; -class QuotedEntity extends ConsumerWidget { +class QuotedEntity extends HookConsumerWidget { const QuotedEntity({ required this.eventReference, super.key, @@ -28,18 +31,28 @@ class QuotedEntity extends ConsumerWidget { return const Skeleton(child: PostSkeleton()); } - if (nostrEntity is! PostEntity) { - return Text('Quoting events ${nostrEntity.runtimeType} is not supported yet'); - } + final quoteChild = useMemoized( + () { + switch (nostrEntity) { + case PostEntity(): + return Post( + eventReference: eventReference, + header: UserInfo(pubkey: eventReference.pubkey), + footer: const SizedBox.shrink(), + ); + case ArticleEntity(): + return Article(eventReference: eventReference); + default: + return const SizedBox.shrink(); + } + }, + [nostrEntity], + ); return Padding( padding: EdgeInsets.only(left: 40.0.s, top: 16.0.s), - child: QuotedPostFrame( - child: Post( - eventReference: eventReference, - header: UserInfo(pubkey: eventReference.pubkey), - footer: const SizedBox.shrink(), - ), + child: QuotedEntityFrame.post( + child: quoteChild, ), ); } diff --git a/lib/app/features/feed/views/components/post/components/quoted_post_frame/quoted_post_frame.dart b/lib/app/features/feed/views/components/post/components/quoted_post_frame/quoted_post_frame.dart deleted file mode 100644 index 9b64a4762..000000000 --- a/lib/app/features/feed/views/components/post/components/quoted_post_frame/quoted_post_frame.dart +++ /dev/null @@ -1,24 +0,0 @@ -// SPDX-License-Identifier: ice License 1.0 - -import 'package:flutter/material.dart'; -import 'package:ion/app/extensions/extensions.dart'; - -class QuotedPostFrame extends StatelessWidget { - const QuotedPostFrame({required this.child, super.key}); - - final Widget child; - - @override - Widget build(BuildContext context) { - return DecoratedBox( - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(16.0.s), - border: Border.all(color: context.theme.appColors.onTerararyFill, width: 1.0.s), - ), - child: Padding( - padding: EdgeInsets.only(left: 16.0.s, right: 16.0.s, bottom: 10.0.s), - child: child, - ), - ); - } -} diff --git a/lib/app/features/feed/views/components/post/post.dart b/lib/app/features/feed/views/components/post/post.dart index 37a8cc24d..f5904f9e6 100644 --- a/lib/app/features/feed/views/components/post/post.dart +++ b/lib/app/features/feed/views/components/post/post.dart @@ -7,8 +7,8 @@ import 'package:ion/app/components/skeleton/skeleton.dart'; import 'package:ion/app/extensions/extensions.dart'; import 'package:ion/app/features/feed/data/models/entities/post_data.c.dart'; import 'package:ion/app/features/feed/views/components/post/components/post_body/post_body.dart'; -import 'package:ion/app/features/feed/views/components/post/components/quoted_post_frame/quoted_post_frame.dart'; import 'package:ion/app/features/feed/views/components/post/post_skeleton.dart'; +import 'package:ion/app/features/feed/views/components/quoted_entity_frame/quoted_entity_frame.dart'; import 'package:ion/app/features/feed/views/components/user_info/user_info.dart'; import 'package:ion/app/features/feed/views/components/user_info_menu/user_info_menu.dart'; import 'package:ion/app/features/nostr/model/event_reference.c.dart'; @@ -82,7 +82,7 @@ class _FramedEvent extends StatelessWidget { Widget build(BuildContext context) { return Padding( padding: EdgeInsets.only(top: 6.0.s), - child: QuotedPostFrame( + child: QuotedEntityFrame.post( child: GestureDetector( // Open a post by clicking on any part of the widget, including the author's avatar or name. onTap: () => diff --git a/lib/app/features/feed/views/components/quoted_entity_frame/quoted_entity_frame.dart b/lib/app/features/feed/views/components/quoted_entity_frame/quoted_entity_frame.dart new file mode 100644 index 000000000..8b555249e --- /dev/null +++ b/lib/app/features/feed/views/components/quoted_entity_frame/quoted_entity_frame.dart @@ -0,0 +1,51 @@ +// SPDX-License-Identifier: ice License 1.0 + +import 'package:flutter/material.dart'; +import 'package:ion/app/extensions/extensions.dart'; + +class QuotedEntityFrame extends StatelessWidget { + const QuotedEntityFrame._({ + required this.child, + required this.padding, + super.key, + }); + + factory QuotedEntityFrame.post({ + required Widget child, + Key? key, + }) { + return QuotedEntityFrame._( + padding: EdgeInsets.only(left: 16.0.s, right: 16.0.s, bottom: 10.0.s), + key: key, + child: child, + ); + } + + factory QuotedEntityFrame.article({ + required Widget child, + Key? key, + }) { + return QuotedEntityFrame._( + padding: EdgeInsets.only(left: 0.0.s, right: 16.0.s, bottom: 10.0.s), + key: key, + child: child, + ); + } + + final Widget child; + final EdgeInsets padding; + + @override + Widget build(BuildContext context) { + return DecoratedBox( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(16.0.s), + border: Border.all(color: context.theme.appColors.onTerararyFill, width: 1.0.s), + ), + child: Padding( + padding: padding, + child: child, + ), + ); + } +} From 286e0782e0f799cf231bf81d6289f7d460f74447 Mon Sep 17 00:00:00 2001 From: ice-kreios <180917405+ice-kreios@users.noreply.github.com> Date: Fri, 3 Jan 2025 16:19:58 +0200 Subject: [PATCH 2/2] feat: added support quoting articles --- .../components/article_list_item.dart | 2 +- .../components/generic_repost_list_item.dart | 5 +- .../create_post/model/create_post_option.dart | 2 +- .../components/quoted_entity.dart | 20 +++-- .../views/components/article/article.dart | 24 ++++-- .../feed/views/components/post/post.dart | 74 +++++++++++++++---- .../quoted_entity_frame.dart | 2 +- 7 files changed, 97 insertions(+), 32 deletions(-) diff --git a/lib/app/features/components/entities_list/components/article_list_item.dart b/lib/app/features/components/entities_list/components/article_list_item.dart index 33d5a4866..1c0c4bb9c 100644 --- a/lib/app/features/components/entities_list/components/article_list_item.dart +++ b/lib/app/features/components/entities_list/components/article_list_item.dart @@ -18,7 +18,7 @@ class ArticleListItem extends ConsumerWidget { final eventReference = EventReference.fromNostrEntity(article); return Padding( - padding: EdgeInsets.symmetric(vertical: 12.0.s), + padding: EdgeInsets.only(top: 12.0.s, bottom: 12.0.s, right: 16.0.s), child: GestureDetector( behavior: HitTestBehavior.opaque, onTap: () => diff --git a/lib/app/features/components/entities_list/components/generic_repost_list_item.dart b/lib/app/features/components/entities_list/components/generic_repost_list_item.dart index d333e9dc2..e150203cd 100644 --- a/lib/app/features/components/entities_list/components/generic_repost_list_item.dart +++ b/lib/app/features/components/entities_list/components/generic_repost_list_item.dart @@ -32,7 +32,10 @@ class GenericRepostListItem extends StatelessWidget { children: [ RepostAuthorHeader(pubkey: repost.masterPubkey), SizedBox(height: 6.0.s), - Article(eventReference: eventReference), + Padding( + padding: EdgeInsets.only(right: 16.0.s), + child: Article(eventReference: eventReference), + ), ], ), ), diff --git a/lib/app/features/feed/create_post/model/create_post_option.dart b/lib/app/features/feed/create_post/model/create_post_option.dart index 3a8b44852..48cbfbba0 100644 --- a/lib/app/features/feed/create_post/model/create_post_option.dart +++ b/lib/app/features/feed/create_post/model/create_post_option.dart @@ -13,7 +13,7 @@ enum CreatePostOption { String getTitle(BuildContext context) { return switch (this) { CreatePostOption.reply => context.i18n.button_reply, - CreatePostOption.quote => context.i18n.feed_write_comment, + CreatePostOption.quote => context.i18n.feed_quote_post, CreatePostOption.plain => context.i18n.create_post_modal_title, CreatePostOption.video => context.i18n.create_video_new_video, _ => throw ArgumentError() diff --git a/lib/app/features/feed/create_post/views/pages/create_post_modal/components/quoted_entity.dart b/lib/app/features/feed/create_post/views/pages/create_post_modal/components/quoted_entity.dart index bd947733e..48d54a519 100644 --- a/lib/app/features/feed/create_post/views/pages/create_post_modal/components/quoted_entity.dart +++ b/lib/app/features/feed/create_post/views/pages/create_post_modal/components/quoted_entity.dart @@ -35,13 +35,19 @@ class QuotedEntity extends HookConsumerWidget { () { switch (nostrEntity) { case PostEntity(): - return Post( - eventReference: eventReference, - header: UserInfo(pubkey: eventReference.pubkey), - footer: const SizedBox.shrink(), + return QuotedEntityFrame.post( + child: Post( + eventReference: eventReference, + header: UserInfo(pubkey: eventReference.pubkey), + footer: const SizedBox.shrink(), + ), ); case ArticleEntity(): - return Article(eventReference: eventReference); + return QuotedEntityFrame.article( + child: Article.quoted( + eventReference: eventReference, + ), + ); default: return const SizedBox.shrink(); } @@ -51,9 +57,7 @@ class QuotedEntity extends HookConsumerWidget { return Padding( padding: EdgeInsets.only(left: 40.0.s, top: 16.0.s), - child: QuotedEntityFrame.post( - child: quoteChild, - ), + child: quoteChild, ); } } diff --git a/lib/app/features/feed/views/components/article/article.dart b/lib/app/features/feed/views/components/article/article.dart index a6e6200db..853c63705 100644 --- a/lib/app/features/feed/views/components/article/article.dart +++ b/lib/app/features/feed/views/components/article/article.dart @@ -18,9 +18,18 @@ import 'package:ion/app/utils/algorithm.dart'; class Article extends ConsumerWidget { const Article({ required this.eventReference, + this.showActionButtons = true, super.key, }); + factory Article.quoted({ + required EventReference eventReference, + }) { + return Article(eventReference: eventReference, showActionButtons: false); + } + + final bool showActionButtons; + final EventReference eventReference; @override @@ -55,12 +64,14 @@ class Article extends ConsumerWidget { children: [ UserInfo( pubkey: eventReference.pubkey, - trailing: Row( - children: [ - BookmarkButton.article(eventReference: eventReference), - UserInfoMenu(pubkey: eventReference.pubkey), - ], - ), + trailing: showActionButtons + ? Row( + children: [ + BookmarkButton.article(eventReference: eventReference), + UserInfoMenu(pubkey: eventReference.pubkey), + ], + ) + : null, ), SizedBox(height: 10.0.s), ArticleImage( @@ -72,7 +83,6 @@ class Article extends ConsumerWidget { ], ), ), - SizedBox(width: 16.0.s), ], ), ), diff --git a/lib/app/features/feed/views/components/post/post.dart b/lib/app/features/feed/views/components/post/post.dart index f5904f9e6..7906c000b 100644 --- a/lib/app/features/feed/views/components/post/post.dart +++ b/lib/app/features/feed/views/components/post/post.dart @@ -1,11 +1,14 @@ // SPDX-License-Identifier: ice License 1.0 import 'package:flutter/material.dart'; +import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:ion/app/components/counter_items_footer/counter_items_footer.dart'; import 'package:ion/app/components/skeleton/skeleton.dart'; import 'package:ion/app/extensions/extensions.dart'; +import 'package:ion/app/features/feed/data/models/entities/article_data.c.dart'; import 'package:ion/app/features/feed/data/models/entities/post_data.c.dart'; +import 'package:ion/app/features/feed/views/components/article/article.dart'; import 'package:ion/app/features/feed/views/components/post/components/post_body/post_body.dart'; import 'package:ion/app/features/feed/views/components/post/post_skeleton.dart'; import 'package:ion/app/features/feed/views/components/quoted_entity_frame/quoted_entity_frame.dart'; @@ -73,29 +76,74 @@ class Post extends ConsumerWidget { } } -class _FramedEvent extends StatelessWidget { +class _FramedEvent extends HookConsumerWidget { const _FramedEvent({required this.eventReference}); final EventReference eventReference; @override - Widget build(BuildContext context) { + Widget build(BuildContext context, WidgetRef ref) { + final nostrEntity = ref.watch(nostrEntityProvider(eventReference: eventReference)).valueOrNull; + + final quotedEntity = useMemoized( + () { + switch (nostrEntity) { + case PostEntity(): + return _QuotedPost(eventReference: eventReference); + case ArticleEntity(): + return _QuotedArticle(eventReference: eventReference); + default: + return const SizedBox.shrink(); + } + }, + [nostrEntity], + ); + return Padding( padding: EdgeInsets.only(top: 6.0.s), - child: QuotedEntityFrame.post( - child: GestureDetector( - // Open a post by clicking on any part of the widget, including the author's avatar or name. - onTap: () => - PostDetailsRoute(eventReference: eventReference.toString()).push(context), - child: AbsorbPointer( - child: Post( - eventReference: eventReference, - header: UserInfo(pubkey: eventReference.pubkey), - footer: const SizedBox.shrink(), - ), + child: quotedEntity, + ); + } +} + +final class _QuotedPost extends ConsumerWidget { + const _QuotedPost({required this.eventReference}); + + final EventReference eventReference; + + @override + Widget build(BuildContext context, WidgetRef ref) { + return QuotedEntityFrame.post( + child: GestureDetector( + onTap: () { + PostDetailsRoute(eventReference: eventReference.toString()).push(context); + }, + child: AbsorbPointer( + child: Post( + eventReference: eventReference, + header: UserInfo(pubkey: eventReference.pubkey), + footer: const SizedBox.shrink(), ), ), ), ); } } + +final class _QuotedArticle extends ConsumerWidget { + const _QuotedArticle({required this.eventReference}); + + final EventReference eventReference; + + @override + Widget build(BuildContext context, WidgetRef ref) { + return QuotedEntityFrame.article( + child: GestureDetector( + onTap: () { + ArticleDetailsRoute(eventReference: eventReference.toString()).push(context); + }, + child: AbsorbPointer(child: Article.quoted(eventReference: eventReference)), + ), + ); + } +} diff --git a/lib/app/features/feed/views/components/quoted_entity_frame/quoted_entity_frame.dart b/lib/app/features/feed/views/components/quoted_entity_frame/quoted_entity_frame.dart index 8b555249e..680f4b15d 100644 --- a/lib/app/features/feed/views/components/quoted_entity_frame/quoted_entity_frame.dart +++ b/lib/app/features/feed/views/components/quoted_entity_frame/quoted_entity_frame.dart @@ -26,7 +26,7 @@ class QuotedEntityFrame extends StatelessWidget { Key? key, }) { return QuotedEntityFrame._( - padding: EdgeInsets.only(left: 0.0.s, right: 16.0.s, bottom: 10.0.s), + padding: EdgeInsets.only(top: 12.0.s, right: 16.0.s, bottom: 12.0.s), key: key, child: child, );