Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: added support quoting articles #505

Merged
merged 2 commits into from
Jan 7, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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: () =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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),
),
],
),
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
Original file line number Diff line number Diff line change
@@ -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,
Expand All @@ -28,19 +31,33 @@ 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 QuotedEntityFrame.post(
child: Post(
eventReference: eventReference,
header: UserInfo(pubkey: eventReference.pubkey),
footer: const SizedBox.shrink(),
),
);
case ArticleEntity():
return QuotedEntityFrame.article(
child: Article.quoted(
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: quoteChild,
);
}
}
24 changes: 17 additions & 7 deletions lib/app/features/feed/views/components/article/article.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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(
Expand All @@ -72,7 +83,6 @@ class Article extends ConsumerWidget {
],
),
),
SizedBox(width: 16.0.s),
],
),
),
Expand Down

This file was deleted.

76 changes: 62 additions & 14 deletions lib/app/features/feed/views/components/post/post.dart
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
// 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/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';
Expand Down Expand Up @@ -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: QuotedPostFrame(
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<void>(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<void>(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<void>(context);
},
child: AbsorbPointer(child: Article.quoted(eventReference: eventReference)),
),
);
}
}
Original file line number Diff line number Diff line change
@@ -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(top: 12.0.s, right: 16.0.s, bottom: 12.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,
),
);
}
}