diff --git a/lib/community/utils/post_card_action_helpers.dart b/lib/community/utils/post_card_action_helpers.dart index 49c91b877..a64b9379d 100644 --- a/lib/community/utils/post_card_action_helpers.dart +++ b/lib/community/utils/post_card_action_helpers.dart @@ -19,6 +19,8 @@ import 'package:thunder/shared/picker_item.dart'; import 'package:thunder/shared/snackbar.dart'; import 'package:thunder/thunder/bloc/thunder_bloc.dart'; import 'package:thunder/user/pages/user_page.dart'; +import 'package:thunder/utils/navigate_community.dart'; +import 'package:thunder/utils/navigate_user.dart'; import 'package:thunder/utils/swipe.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; @@ -116,23 +118,7 @@ void showPostActionBottomModalSheet(BuildContext context, PostViewMedia postView onTapCommunityName(context, postViewMedia.postView.community.id); break; case PostCardAction.visitProfile: - AccountBloc accountBloc = context.read(); - AuthBloc authBloc = context.read(); - ThunderBloc thunderBloc = context.read(); - - Navigator.of(context).push( - SwipeablePageRoute( - canOnlySwipeFromEdge: disableFullPageSwipe(isUserLoggedIn: authBloc.state.isLoggedIn, state: thunderBloc.state, isFeedPage: true), - builder: (context) => MultiBlocProvider( - providers: [ - BlocProvider.value(value: accountBloc), - BlocProvider.value(value: authBloc), - BlocProvider.value(value: thunderBloc), - ], - child: UserPage(userId: postViewMedia.postView.post.creatorId), - ), - ), - ); + navigateToUserPage(context, userId: postViewMedia.postView.post.creatorId); break; case PostCardAction.sharePost: Share.share(postViewMedia.postView.post.apId); @@ -183,41 +169,9 @@ void showPostActionBottomModalSheet(BuildContext context, PostViewMedia postView } void onTapCommunityName(BuildContext context, int communityId) { - AccountBloc accountBloc = context.read(); - AuthBloc authBloc = context.read(); - ThunderBloc thunderBloc = context.read(); - - Navigator.of(context).push( - SwipeablePageRoute( - canOnlySwipeFromEdge: disableFullPageSwipe(isUserLoggedIn: authBloc.state.isLoggedIn, state: thunderBloc.state, isFeedPage: true), - builder: (context) => MultiBlocProvider( - providers: [ - BlocProvider.value(value: accountBloc), - BlocProvider.value(value: authBloc), - BlocProvider.value(value: thunderBloc), - ], - child: CommunityPage(communityId: communityId), - ), - ), - ); + navigateToCommunityPage(context, communityId: communityId); } void onTapUserName(BuildContext context, int userId) { - AccountBloc accountBloc = context.read(); - AuthBloc authBloc = context.read(); - ThunderBloc thunderBloc = context.read(); - - Navigator.of(context).push( - SwipeablePageRoute( - canOnlySwipeFromEdge: disableFullPageSwipe(isUserLoggedIn: authBloc.state.isLoggedIn, state: thunderBloc.state, isFeedPage: true), - builder: (context) => MultiBlocProvider( - providers: [ - BlocProvider.value(value: accountBloc), - BlocProvider.value(value: authBloc), - BlocProvider.value(value: thunderBloc), - ], - child: UserPage(userId: userId), - ), - ), - ); + navigateToUserPage(context, userId: userId); } diff --git a/lib/community/widgets/community_sidebar.dart b/lib/community/widgets/community_sidebar.dart index 65a1ac968..509dc8b1a 100644 --- a/lib/community/widgets/community_sidebar.dart +++ b/lib/community/widgets/community_sidebar.dart @@ -19,6 +19,8 @@ import 'package:thunder/core/singletons/preferences.dart'; import 'package:thunder/shared/snackbar.dart'; import 'package:thunder/shared/user_avatar.dart'; import 'package:thunder/utils/instance.dart'; +import 'package:thunder/utils/navigate_user.dart'; +import 'package:thunder/utils/swipe.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import '../../shared/common_markdown_body.dart'; @@ -156,8 +158,11 @@ class _CommunitySidebarState extends State with TickerProvider } }); - Navigator.of(context).push( + Navigator.of(context) + .push( SwipeablePageRoute( + canOnlySwipeFromEdge: true, + backGestureDetectionWidth: 45, builder: (context) { return MultiBlocProvider( providers: [ @@ -174,7 +179,8 @@ class _CommunitySidebarState extends State with TickerProvider ); }, ), - ).whenComplete(() async { + ) + .whenComplete(() async { timer.cancel(); if (newDraftPost?.saveAsDraft == true && newDraftPost?.isNotEmpty == true) { @@ -513,22 +519,7 @@ class _CommunitySidebarState extends State with TickerProvider for (var mods in widget.communityInfo!.moderators) GestureDetector( onTap: () { - AccountBloc accountBloc = context.read(); - AuthBloc authBloc = context.read(); - ThunderBloc thunderBloc = context.read(); - - Navigator.of(context).push( - SwipeablePageRoute( - builder: (context) => MultiBlocProvider( - providers: [ - BlocProvider.value(value: accountBloc), - BlocProvider.value(value: authBloc), - BlocProvider.value(value: thunderBloc), - ], - child: UserPage(userId: mods.moderator!.id), - ), - ), - ); + navigateToUserPage(context, userId: mods.moderator!.id); }, child: Padding( padding: const EdgeInsets.only(bottom: 8.0), diff --git a/lib/community/widgets/post_card.dart b/lib/community/widgets/post_card.dart index 517e2798f..ff236d959 100644 --- a/lib/community/widgets/post_card.dart +++ b/lib/community/widgets/post_card.dart @@ -1,3 +1,5 @@ +import 'dart:io'; + import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; @@ -269,7 +271,8 @@ class _PostCardState extends State { await Navigator.of(context).push( SwipeablePageRoute( - backGestureDetectionStartOffset: 45, + backGestureDetectionStartOffset: Platform.isAndroid ? 45 : 0, + backGestureDetectionWidth: 45, canOnlySwipeFromEdge: disableFullPageSwipe(isUserLoggedIn: authBloc.state.isLoggedIn, state: thunderBloc.state, isPostPage: true), builder: (context) { return MultiBlocProvider( diff --git a/lib/core/enums/fab_action.dart b/lib/core/enums/fab_action.dart index b9eb35faa..d0a7cae7f 100644 --- a/lib/core/enums/fab_action.dart +++ b/lib/core/enums/fab_action.dart @@ -139,8 +139,11 @@ enum FeedFabAction { } }); - Navigator.of(context).push( + Navigator.of(context) + .push( SwipeablePageRoute( + canOnlySwipeFromEdge: true, + backGestureDetectionWidth: 45, builder: (context) { return MultiBlocProvider( providers: [ @@ -157,7 +160,8 @@ enum FeedFabAction { ); }, ), - ).whenComplete(() async { + ) + .whenComplete(() async { timer.cancel(); if (newDraftPost?.saveAsDraft == true && newDraftPost?.isNotEmpty == true) { diff --git a/lib/inbox/widgets/inbox_mentions_view.dart b/lib/inbox/widgets/inbox_mentions_view.dart index ac7d948ce..1feb6634a 100644 --- a/lib/inbox/widgets/inbox_mentions_view.dart +++ b/lib/inbox/widgets/inbox_mentions_view.dart @@ -1,3 +1,4 @@ +import 'dart:io'; import 'dart:async'; import 'dart:convert'; @@ -21,6 +22,7 @@ import 'package:thunder/shared/snackbar.dart'; import 'package:thunder/thunder/bloc/thunder_bloc.dart'; import 'package:thunder/utils/date_time.dart'; import 'package:thunder/utils/instance.dart'; +import 'package:thunder/utils/navigate_community.dart'; import 'package:thunder/utils/swipe.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; @@ -53,7 +55,8 @@ class InboxMentionsView extends StatelessWidget { // To to specific post for now, in the future, will be best to scroll to the position of the comment await Navigator.of(context).push( SwipeablePageRoute( - backGestureDetectionStartOffset: 45, + backGestureDetectionStartOffset: Platform.isAndroid ? 45 : 0, + backGestureDetectionWidth: 45, canOnlySwipeFromEdge: disableFullPageSwipe(isUserLoggedIn: authBloc.state.isLoggedIn, state: thunderBloc.state, isPostPage: true), builder: (context) => MultiBlocProvider( providers: [ @@ -129,8 +132,11 @@ class InboxMentionsView extends StatelessWidget { } }); - Navigator.of(context).push( + Navigator.of(context) + .push( SwipeablePageRoute( + canOnlySwipeFromEdge: true, + backGestureDetectionWidth: 45, builder: (context) { return MultiBlocProvider( providers: [ @@ -147,7 +153,8 @@ class InboxMentionsView extends StatelessWidget { )); }, ), - ).whenComplete(() async { + ) + .whenComplete(() async { timer.cancel(); if (newDraftComment?.saveAsDraft == true && newDraftComment?.isNotEmpty == true) { @@ -177,22 +184,6 @@ class InboxMentionsView extends StatelessWidget { } void onTapCommunityName(BuildContext context, int communityId) { - AccountBloc accountBloc = context.read(); - AuthBloc authBloc = context.read(); - ThunderBloc thunderBloc = context.read(); - - Navigator.of(context).push( - SwipeablePageRoute( - canOnlySwipeFromEdge: disableFullPageSwipe(isUserLoggedIn: authBloc.state.isLoggedIn, state: thunderBloc.state, isFeedPage: true), - builder: (context) => MultiBlocProvider( - providers: [ - BlocProvider.value(value: accountBloc), - BlocProvider.value(value: authBloc), - BlocProvider.value(value: thunderBloc), - ], - child: CommunityPage(communityId: communityId), - ), - ), - ); + navigateToCommunityPage(context, communityId: communityId); } } diff --git a/lib/inbox/widgets/inbox_replies_view.dart b/lib/inbox/widgets/inbox_replies_view.dart index 3218a4d23..62ee49657 100644 --- a/lib/inbox/widgets/inbox_replies_view.dart +++ b/lib/inbox/widgets/inbox_replies_view.dart @@ -21,6 +21,7 @@ import 'package:thunder/shared/comment_reference.dart'; import 'package:thunder/post/pages/create_comment_page.dart'; import 'package:thunder/shared/snackbar.dart'; import 'package:thunder/thunder/bloc/thunder_bloc.dart'; +import 'package:thunder/utils/navigate_community.dart'; import 'package:thunder/utils/swipe.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; @@ -93,8 +94,11 @@ class _InboxRepliesViewState extends State { } }); - Navigator.of(context).push( + Navigator.of(context) + .push( SwipeablePageRoute( + canOnlySwipeFromEdge: true, + backGestureDetectionWidth: 45, builder: (context) { return MultiBlocProvider( providers: [ @@ -111,7 +115,8 @@ class _InboxRepliesViewState extends State { )); }, ), - ).whenComplete(() async { + ) + .whenComplete(() async { timer.cancel(); if (newDraftComment?.saveAsDraft == true && newDraftComment?.isNotEmpty == true && (!isEdit || commentView.comment.content != newDraftComment?.text)) { @@ -147,194 +152,9 @@ class _InboxRepliesViewState extends State { ); }, ); - - /*Card( - clipBehavior: Clip.hardEdge, - child: InkWell( - onTap: () async { - AccountBloc accountBloc = context.read(); - AuthBloc authBloc = context.read(); - ThunderBloc thunderBloc = context.read(); - - // To to specific post for now, in the future, will be best to scroll to the position of the comment - await Navigator.of(context).push( - SwipeablePageRoute( - backGestureDetectionStartOffset: 45, - canOnlySwipeFromEdge: disableFullPageSwipe( - isUserLoggedIn: authBloc.state.isLoggedIn, - state: thunderBloc.state, - isPostPage: true), - builder: (context) => MultiBlocProvider( - providers: [ - BlocProvider.value(value: accountBloc), - BlocProvider.value(value: authBloc), - BlocProvider.value(value: thunderBloc), - BlocProvider(create: (context) => PostBloc()), - ], - child: PostPage( - selectedCommentId: widget.replies[index].comment.id, - selectedCommentPath: widget.replies[index].comment.path, - postId: widget.replies[index].post.id, - onPostUpdated: () => {}, - ), - ), - ), - ); - }, - child: Padding( - padding: - const EdgeInsets.symmetric(horizontal: 12.0, vertical: 12.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - widget.replies[index].creator.name, - style: theme.textTheme.titleSmall - ?.copyWith(color: Colors.greenAccent), - ), - Text(formatTimeToString( - dateTime: widget.replies[index].comment.published - .toIso8601String())) - ], - ), - GestureDetector( - child: Text( - '${widget.replies[index].community.name}${' · ${fetchInstanceNameFromUrl(widget.replies[index].community.actorId)}'}', - style: theme.textTheme.bodyMedium?.copyWith( - color: theme.textTheme.bodyMedium?.color - ?.withOpacity(0.75), - ), - ), - onTap: () => onTapCommunityName( - context, widget.replies[index].community.id), - ), - const SizedBox(height: 10), - CommonMarkdownBody( - body: widget.replies[index].comment.content), - const Divider(height: 20), - Row( - mainAxisAlignment: MainAxisAlignment.end, - children: [ - Divider( - height: 1.0, - thickness: 1.0, - color: ElevationOverlay.applySurfaceTint( - Theme.of(context).colorScheme.surface, - Theme.of(context).colorScheme.surfaceTint, - 10, - ), - ), - CommentReference( - comment: widget.replies[index], - now: now, - onVoteAction: (int commentId, VoteType voteType) => - context.read().add(VoteCommentEvent( - commentId: commentId, score: voteType)), - onSaveAction: (int commentId, bool save) => context - .read() - .add(SaveCommentEvent( - commentId: commentId, save: save)), - onDeleteAction: (int commentId, bool deleted) => context - .read() - .add(DeleteCommentEvent( - deleted: deleted, commentId: commentId)), - onReplyEditAction: - (CommentView commentView, bool isEdit) { - HapticFeedback.mediumImpact(); - InboxBloc inboxBloc = context.read(); - PostBloc postBloc = context.read(); - ThunderBloc thunderBloc = context.read(); - AccountBloc accountBloc = context.read(); - - Navigator.of(context).push( - SwipeablePageRoute( - builder: (context) { - return MultiBlocProvider( - providers: [ - BlocProvider.value( - value: inboxBloc), - BlocProvider.value( - value: postBloc), - BlocProvider.value( - value: thunderBloc), - BlocProvider.value( - value: accountBloc), - ], - child: CreateCommentPage( - commentView: commentView, - isEdit: isEdit)); - }, - ), - ); - }, - isOwnComment: widget.replies[index].creator.id == - context.read().state.account?.userId, - child: Row( - mainAxisAlignment: MainAxisAlignment.end, - children: [ - if (widget.replies[index].commentReply?.read == - false) - inboxReplyMarkedAsRead != - widget.replies[index].commentReply?.id - ? IconButton( - onPressed: () { - setState(() => inboxReplyMarkedAsRead = - widget.replies[index].commentReply - ?.id); - context.read().add( - MarkReplyAsReadEvent( - commentReplyId: widget - .replies[index] - .commentReply! - .id, - read: true)); - }, - icon: const Icon( - Icons.check, - semanticLabel: 'Mark as read', - ), - visualDensity: VisualDensity.compact, - ) - : const Padding( - padding: - EdgeInsets.symmetric(horizontal: 8.0), - child: SizedBox( - width: 20, - height: 20, - child: CircularProgressIndicator()), - ), - ], - ), - ), - ], - ), - ], - ), - ), - ), - );*/ } void onTapCommunityName(BuildContext context, int communityId) { - AccountBloc accountBloc = context.read(); - AuthBloc authBloc = context.read(); - ThunderBloc thunderBloc = context.read(); - - Navigator.of(context).push( - SwipeablePageRoute( - canOnlySwipeFromEdge: disableFullPageSwipe(isUserLoggedIn: authBloc.state.isLoggedIn, state: thunderBloc.state, isFeedPage: true), - builder: (context) => MultiBlocProvider( - providers: [ - BlocProvider.value(value: accountBloc), - BlocProvider.value(value: authBloc), - BlocProvider.value(value: thunderBloc), - ], - child: CommunityPage(communityId: communityId), - ), - ), - ); + navigateToCommunityPage(context, communityId: communityId); } } diff --git a/lib/post/pages/post_page.dart b/lib/post/pages/post_page.dart index 588ea43c9..6de914fac 100644 --- a/lib/post/pages/post_page.dart +++ b/lib/post/pages/post_page.dart @@ -502,8 +502,11 @@ class _PostPageState extends State { } }); - Navigator.of(context).push( + Navigator.of(context) + .push( SwipeablePageRoute( + canOnlySwipeFromEdge: true, + backGestureDetectionWidth: 45, builder: (context) { return MultiBlocProvider( providers: [ @@ -518,7 +521,8 @@ class _PostPageState extends State { )); }, ), - ).whenComplete(() async { + ) + .whenComplete(() async { timer.cancel(); if (newDraftComment?.saveAsDraft == true && newDraftComment?.isNotEmpty == true) { diff --git a/lib/post/pages/post_page_success.dart b/lib/post/pages/post_page_success.dart index e15cef879..ee6c858ce 100644 --- a/lib/post/pages/post_page_success.dart +++ b/lib/post/pages/post_page_success.dart @@ -113,8 +113,11 @@ class _PostPageSuccessState extends State { } }); - Navigator.of(context).push( + Navigator.of(context) + .push( SwipeablePageRoute( + canOnlySwipeFromEdge: true, + backGestureDetectionWidth: 45, builder: (context) { return MultiBlocProvider( providers: [ @@ -130,7 +133,8 @@ class _PostPageSuccessState extends State { )); }, ), - ).whenComplete(() async { + ) + .whenComplete(() async { timer.cancel(); if (newDraftComment?.saveAsDraft == true && newDraftComment?.isNotEmpty == true && (!isEdit || commentView.comment.content != newDraftComment?.text)) { diff --git a/lib/post/utils/comment_actions.dart b/lib/post/utils/comment_actions.dart index 24e171a2e..030a1d6ab 100644 --- a/lib/post/utils/comment_actions.dart +++ b/lib/post/utils/comment_actions.dart @@ -63,8 +63,11 @@ void triggerCommentAction({ } }); - Navigator.of(context).push( + Navigator.of(context) + .push( SwipeablePageRoute( + canOnlySwipeFromEdge: true, + backGestureDetectionWidth: 45, builder: (context) { return MultiBlocProvider( providers: [ @@ -83,7 +86,8 @@ void triggerCommentAction({ ); }, ), - ).whenComplete(() async { + ) + .whenComplete(() async { timer.cancel(); if (newDraftComment?.saveAsDraft == true && newDraftComment?.isNotEmpty == true && (swipeAction != SwipeAction.edit || commentView.comment.content != newDraftComment?.text)) { diff --git a/lib/post/widgets/post_view.dart b/lib/post/widgets/post_view.dart index 8a26d6d7c..e6d724980 100644 --- a/lib/post/widgets/post_view.dart +++ b/lib/post/widgets/post_view.dart @@ -28,6 +28,8 @@ import 'package:thunder/thunder/thunder_icons.dart'; import 'package:thunder/user/pages/user_page.dart'; import 'package:thunder/user/utils/special_user_checks.dart'; import 'package:thunder/utils/instance.dart'; +import 'package:thunder/utils/navigate_community.dart'; +import 'package:thunder/utils/navigate_user.dart'; import 'package:thunder/utils/numbers.dart'; import 'package:thunder/utils/swipe.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; @@ -110,25 +112,7 @@ class PostSubview extends StatelessWidget { child: InkWell( borderRadius: BorderRadius.circular(5), onTap: () { - account_bloc.AccountBloc accountBloc = context.read(); - AuthBloc authBloc = context.read(); - ThunderBloc thunderBloc = context.read(); - - Navigator.of(context).push( - SwipeablePageRoute( - canOnlySwipeFromEdge: disableFullPageSwipe(isUserLoggedIn: authBloc.state.isLoggedIn, state: thunderBloc.state, isFeedPage: true), - builder: (context) => MultiBlocProvider( - providers: [ - BlocProvider.value(value: accountBloc), - BlocProvider.value(value: authBloc), - BlocProvider.value(value: thunderBloc), - ], - child: UserPage( - userId: postView.creator.id, - ), - ), - ), - ); + navigateToUserPage(context, userId: postView.creator.id); }, child: Padding( padding: const EdgeInsets.only(left: 5, right: 5), @@ -196,23 +180,7 @@ class PostSubview extends StatelessWidget { InkWell( borderRadius: BorderRadius.circular(5), onTap: () { - account_bloc.AccountBloc accountBloc = context.read(); - AuthBloc authBloc = context.read(); - ThunderBloc thunderBloc = context.read(); - - Navigator.of(context).push( - SwipeablePageRoute( - canOnlySwipeFromEdge: disableFullPageSwipe(isUserLoggedIn: authBloc.state.isLoggedIn, state: thunderBloc.state, isFeedPage: true), - builder: (context) => MultiBlocProvider( - providers: [ - BlocProvider.value(value: accountBloc), - BlocProvider.value(value: authBloc), - BlocProvider.value(value: thunderBloc), - ], - child: CommunityPage(communityId: postView.community.id), - ), - ), - ); + navigateToCommunityPage(context, communityId: postView.community.id); }, child: Tooltip( excludeFromSemantics: true, @@ -362,8 +330,11 @@ class PostSubview extends StatelessWidget { } }); - Navigator.of(context).push( + Navigator.of(context) + .push( SwipeablePageRoute( + canOnlySwipeFromEdge: true, + backGestureDetectionWidth: 45, builder: (context) { return MultiBlocProvider( providers: [ @@ -379,7 +350,8 @@ class PostSubview extends StatelessWidget { ); }, ), - ).whenComplete(() async { + ) + .whenComplete(() async { timer.cancel(); if (newDraftComment?.saveAsDraft == true && newDraftComment?.isNotEmpty == true) { diff --git a/lib/routes.dart b/lib/routes.dart index 6d85abcce..ebe68f3e8 100644 --- a/lib/routes.dart +++ b/lib/routes.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:go_router/go_router.dart'; +import 'package:swipeable_page_route/swipeable_page_route.dart'; import 'package:thunder/account/bloc/account_bloc.dart'; import 'package:thunder/core/auth/bloc/auth_bloc.dart'; diff --git a/lib/search/pages/search_page.dart b/lib/search/pages/search_page.dart index 3c7494af6..8c107fb4d 100644 --- a/lib/search/pages/search_page.dart +++ b/lib/search/pages/search_page.dart @@ -26,6 +26,7 @@ import 'package:thunder/thunder/bloc/thunder_bloc.dart'; import 'package:thunder/utils/constants.dart'; import 'package:thunder/utils/debounce.dart'; import 'package:thunder/utils/instance.dart'; +import 'package:thunder/utils/navigate_community.dart'; import 'package:thunder/utils/swipe.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; @@ -261,73 +262,59 @@ class _SearchPageState extends State with AutomaticKeepAliveClientMi CommunityView communityView = state.communities![index]; final Set currentSubscriptions = context.read().state.ids; return Tooltip( - excludeFromSemantics: true, - message: '${communityView.community.title}\n${communityView.community.name} · ${fetchInstanceNameFromUrl(communityView.community.actorId)}', - preferBelow: false, - child: ListTile( - leading: CommunityIcon(community: communityView.community, radius: 25), - title: Text( - communityView.community.title, + excludeFromSemantics: true, + message: '${communityView.community.title}\n${communityView.community.name} · ${fetchInstanceNameFromUrl(communityView.community.actorId)}', + preferBelow: false, + child: ListTile( + leading: CommunityIcon(community: communityView.community, radius: 25), + title: Text( + communityView.community.title, + overflow: TextOverflow.ellipsis, + ), + subtitle: Row(children: [ + Flexible( + child: Text( + '${communityView.community.name} · ${fetchInstanceNameFromUrl(communityView.community.actorId)}', overflow: TextOverflow.ellipsis, ), - subtitle: Row(children: [ - Flexible( - child: Text( - '${communityView.community.name} · ${fetchInstanceNameFromUrl(communityView.community.actorId)}', - overflow: TextOverflow.ellipsis, - ), - ), - Text( - ' · ${communityView.counts.subscribers}', - semanticsLabel: '${communityView.counts.subscribers} subscribers', - ), - const SizedBox(width: 4), - const Icon(Icons.people_rounded, size: 16.0), - ]), - trailing: IconButton( - onPressed: () { - SubscribedType subscriptionStatus = _getCurrentSubscriptionStatus(isUserLoggedIn, communityView, currentSubscriptions); - _onSubscribeIconPressed(isUserLoggedIn, context, communityView); - showSnackbar( - context, - subscriptionStatus == SubscribedType.notSubscribed - ? AppLocalizations.of(context)!.addedCommunityToSubscriptions - : AppLocalizations.of(context)!.removedCommunityFromSubscriptions); - context.read().add(GetAccountInformation()); - }, - icon: Icon( - switch (_getCurrentSubscriptionStatus(isUserLoggedIn, communityView, currentSubscriptions)) { - SubscribedType.notSubscribed => Icons.add_circle_outline_rounded, - SubscribedType.pending => Icons.pending_outlined, - SubscribedType.subscribed => Icons.remove_circle_outline_rounded, - }, - ), - tooltip: switch (_getCurrentSubscriptionStatus(isUserLoggedIn, communityView, currentSubscriptions)) { - SubscribedType.notSubscribed => 'Subscribe', - SubscribedType.pending => 'Unsubscribe (subscription pending)', - SubscribedType.subscribed => 'Unsubscribe', - }, - visualDensity: VisualDensity.compact, - ), - onTap: () { - AccountBloc accountBloc = context.read(); - AuthBloc authBloc = context.read(); - ThunderBloc thunderBloc = context.read(); - - Navigator.of(context).push( - SwipeablePageRoute( - canOnlySwipeFromEdge: disableFullPageSwipe(isUserLoggedIn: authBloc.state.isLoggedIn, state: thunderBloc.state, isFeedPage: true), - builder: (context) => MultiBlocProvider( - providers: [ - BlocProvider.value(value: accountBloc), - BlocProvider.value(value: authBloc), - BlocProvider.value(value: thunderBloc), - ], - child: CommunityPage(communityId: communityView.community.id), - ), - ), - ); - })); + ), + Text( + ' · ${communityView.counts.subscribers}', + semanticsLabel: '${communityView.counts.subscribers} subscribers', + ), + const SizedBox(width: 4), + const Icon(Icons.people_rounded, size: 16.0), + ]), + trailing: IconButton( + onPressed: () { + SubscribedType subscriptionStatus = _getCurrentSubscriptionStatus(isUserLoggedIn, communityView, currentSubscriptions); + _onSubscribeIconPressed(isUserLoggedIn, context, communityView); + showSnackbar( + context, + subscriptionStatus == SubscribedType.notSubscribed + ? AppLocalizations.of(context)!.addedCommunityToSubscriptions + : AppLocalizations.of(context)!.removedCommunityFromSubscriptions); + context.read().add(GetAccountInformation()); + }, + icon: Icon( + switch (_getCurrentSubscriptionStatus(isUserLoggedIn, communityView, currentSubscriptions)) { + SubscribedType.notSubscribed => Icons.add_circle_outline_rounded, + SubscribedType.pending => Icons.pending_outlined, + SubscribedType.subscribed => Icons.remove_circle_outline_rounded, + }, + ), + tooltip: switch (_getCurrentSubscriptionStatus(isUserLoggedIn, communityView, currentSubscriptions)) { + SubscribedType.notSubscribed => 'Subscribe', + SubscribedType.pending => 'Unsubscribe (subscription pending)', + SubscribedType.subscribed => 'Unsubscribe', + }, + visualDensity: VisualDensity.compact, + ), + onTap: () { + navigateToCommunityPage(context, communityId: communityView.community.id); + }, + ), + ); } }, ); diff --git a/lib/settings/pages/about_settings_page.dart b/lib/settings/pages/about_settings_page.dart index 680073679..f264fb235 100644 --- a/lib/settings/pages/about_settings_page.dart +++ b/lib/settings/pages/about_settings_page.dart @@ -60,7 +60,7 @@ class AboutSettingsPage extends StatelessWidget { subtitle: const Text('lemmy.world/c/thunder_app'), trailing: const Icon(Icons.chevron_right_rounded), onTap: () { - navigateToCommunityByName(context, 'thunder_app@lemmy.world'); + navigateToCommunityPage(context, communityName: 'thunder_app@lemmy.world'); }, ), ListTile( diff --git a/lib/shared/comment_header.dart b/lib/shared/comment_header.dart index 7dce074ed..ac343ef0a 100644 --- a/lib/shared/comment_header.dart +++ b/lib/shared/comment_header.dart @@ -10,6 +10,7 @@ import 'package:thunder/thunder/bloc/thunder_bloc.dart'; import 'package:thunder/thunder/thunder_icons.dart'; import 'package:thunder/user/utils/special_user_checks.dart'; import 'package:thunder/utils/instance.dart'; +import 'package:thunder/utils/navigate_user.dart'; import 'package:thunder/utils/numbers.dart'; import 'package:thunder/user/pages/user_page.dart'; import 'package:thunder/utils/swipe.dart'; @@ -71,23 +72,7 @@ class CommentHeader extends StatelessWidget { child: InkWell( borderRadius: const BorderRadius.all(Radius.elliptical(5, 5)), onTap: () { - account_bloc.AccountBloc accountBloc = context.read(); - AuthBloc authBloc = context.read(); - ThunderBloc thunderBloc = context.read(); - - Navigator.of(context).push( - SwipeablePageRoute( - canOnlySwipeFromEdge: disableFullPageSwipe(isUserLoggedIn: authBloc.state.isLoggedIn, state: thunderBloc.state, isFeedPage: true), - builder: (context) => MultiBlocProvider( - providers: [ - BlocProvider.value(value: accountBloc), - BlocProvider.value(value: authBloc), - BlocProvider.value(value: thunderBloc), - ], - child: UserPage(userId: comment.creator.id), - ), - ), - ); + navigateToUserPage(context, userId: comment.creator.id); }, child: Padding( padding: const EdgeInsets.only(left: 5, right: 5), diff --git a/lib/shared/comment_reference.dart b/lib/shared/comment_reference.dart index fa37bd2a2..cead3e4a4 100644 --- a/lib/shared/comment_reference.dart +++ b/lib/shared/comment_reference.dart @@ -89,6 +89,7 @@ class _CommentReferenceState extends State { // To to specific post for now, in the future, will be best to scroll to the position of the comment await Navigator.of(context).push( SwipeablePageRoute( + backGestureDetectionWidth: 45, canOnlySwipeFromEdge: disableFullPageSwipe(isUserLoggedIn: authBloc.state.isLoggedIn, state: thunderBloc.state, isPostPage: true), builder: (context) => MultiBlocProvider( providers: [ diff --git a/lib/shared/common_markdown_body.dart b/lib/shared/common_markdown_body.dart index c576b344a..878c895cc 100644 --- a/lib/shared/common_markdown_body.dart +++ b/lib/shared/common_markdown_body.dart @@ -70,7 +70,7 @@ class CommonMarkdownBody extends StatelessWidget { if (communityName != null) { try { - await navigateToCommunityByName(context, communityName); + await navigateToCommunityPage(context, communityName: communityName); return; } catch (e) { // Ignore exception, if it's not a valid community we'll perform the next fallback @@ -81,7 +81,7 @@ class CommonMarkdownBody extends StatelessWidget { if (username != null) { try { - await navigateToUserByName(context, username); + await navigateToUserPage(context, username: username); return; } catch (e) { // Ignore exception, if it's not a valid user, we'll perform the next fallback diff --git a/lib/shared/link_preview_card.dart b/lib/shared/link_preview_card.dart index 176791d9b..f5b174f6c 100644 --- a/lib/shared/link_preview_card.dart +++ b/lib/shared/link_preview_card.dart @@ -254,7 +254,7 @@ class LinkPreviewCard extends StatelessWidget { if (communityName != null) { try { - await navigateToCommunityByName(context, communityName); + await navigateToCommunityPage(context, communityName: communityName); return; } catch (e) { // Ignore exception, if it's not a valid community we'll perform the next fallback @@ -265,7 +265,7 @@ class LinkPreviewCard extends StatelessWidget { if (username != null) { try { - await navigateToUserByName(context, username); + await navigateToUserPage(context, username: username); return; } catch (e) { // Ignore exception, if it's not a valid user, we'll perform the next fallback diff --git a/lib/user/pages/user_page_success.dart b/lib/user/pages/user_page_success.dart index 4dc2d7862..1268c1be6 100644 --- a/lib/user/pages/user_page_success.dart +++ b/lib/user/pages/user_page_success.dart @@ -304,8 +304,11 @@ class _UserPageSuccessState extends State with TickerProviderSt } }); - Navigator.of(context).push( + Navigator.of(context) + .push( SwipeablePageRoute( + canOnlySwipeFromEdge: true, + backGestureDetectionWidth: 45, builder: (context) { return MultiBlocProvider( providers: [ @@ -322,7 +325,8 @@ class _UserPageSuccessState extends State with TickerProviderSt )); }, ), - ).whenComplete( + ) + .whenComplete( () async { timer.cancel(); @@ -395,8 +399,11 @@ class _UserPageSuccessState extends State with TickerProviderSt } }); - Navigator.of(context).push( + Navigator.of(context) + .push( SwipeablePageRoute( + canOnlySwipeFromEdge: true, + backGestureDetectionWidth: 45, builder: (context) { return MultiBlocProvider( providers: [ @@ -411,7 +418,8 @@ class _UserPageSuccessState extends State with TickerProviderSt )); }, ), - ).whenComplete( + ) + .whenComplete( () async { timer.cancel(); diff --git a/lib/user/widgets/comment_card.dart b/lib/user/widgets/comment_card.dart index aae2b75b0..17f48f589 100644 --- a/lib/user/widgets/comment_card.dart +++ b/lib/user/widgets/comment_card.dart @@ -1,3 +1,5 @@ +import 'dart:io'; + import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:lemmy_api_client/v3.dart'; @@ -41,7 +43,8 @@ class CommentCard extends StatelessWidget { // To to specific post for now, in the future, will be best to scroll to the position of the comment await Navigator.of(context).push( SwipeablePageRoute( - backGestureDetectionStartOffset: 45, + backGestureDetectionStartOffset: Platform.isAndroid ? 45 : 0, + backGestureDetectionWidth: 45, canOnlySwipeFromEdge: disableFullPageSwipe(isUserLoggedIn: authBloc.state.isLoggedIn, state: thunderBloc.state, isPostPage: true), builder: (context) => MultiBlocProvider( providers: [ @@ -115,36 +118,7 @@ class CommentCard extends StatelessWidget { const Divider(height: 20), const Row( mainAxisAlignment: MainAxisAlignment.end, - children: [ - // IconButton( - // onPressed: () { - // InboxBloc inboxBloc = context.read(); - - // showModalBottomSheet( - // isScrollControlled: true, - // context: context, - // showDragHandle: true, - // builder: (context) { - // return Padding( - // padding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom + 40), - // child: FractionallySizedBox( - // heightFactor: 0.8, - // child: BlocProvider.value( - // value: inboxBloc, - // child: CreateCommentModal(comment: comment.comment, parentCommentAuthor: comment.creator.name), - // ), - // ), - // ); - // }, - // ); - // }, - // icon: const Icon( - // Icons.reply_rounded, - // semanticLabel: 'Reply', - // ), - // visualDensity: VisualDensity.compact, - // ), - ], + children: [], ) ], ), diff --git a/lib/user/widgets/user_sidebar.dart b/lib/user/widgets/user_sidebar.dart index d5de239d3..95d6aba35 100644 --- a/lib/user/widgets/user_sidebar.dart +++ b/lib/user/widgets/user_sidebar.dart @@ -13,6 +13,7 @@ import 'package:thunder/shared/snackbar.dart'; import 'package:thunder/user/widgets/user_sidebar_activity.dart'; import 'package:thunder/user/widgets/user_sidebar_stats.dart'; import 'package:thunder/utils/instance.dart'; +import 'package:thunder/utils/navigate_community.dart'; import '../../community/pages/community_page.dart'; import '../../shared/common_markdown_body.dart'; @@ -378,22 +379,7 @@ class _UserSidebarState extends State { for (var mods in widget.moderates!) GestureDetector( onTap: () { - account_bloc.AccountBloc accountBloc = context.read(); - AuthBloc authBloc = context.read(); - ThunderBloc thunderBloc = context.read(); - - Navigator.of(context).push( - SwipeablePageRoute( - builder: (context) => MultiBlocProvider( - providers: [ - BlocProvider.value(value: accountBloc), - BlocProvider.value(value: authBloc), - BlocProvider.value(value: thunderBloc), - ], - child: CommunityPage(communityId: mods.community.id), - ), - ), - ); + navigateToCommunityPage(context, communityId: mods.community.id); }, child: Padding( padding: const EdgeInsets.only(bottom: 8.0), diff --git a/lib/utils/navigate_community.dart b/lib/utils/navigate_community.dart index ef974cf20..755469b9b 100644 --- a/lib/utils/navigate_community.dart +++ b/lib/utils/navigate_community.dart @@ -1,27 +1,40 @@ import 'package:flutter/material.dart'; -import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:lemmy_api_client/v3.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:swipeable_page_route/swipeable_page_route.dart'; + import 'package:thunder/account/models/account.dart'; +import 'package:thunder/community/pages/community_page.dart'; import 'package:thunder/core/auth/helpers/fetch_account.dart'; import 'package:thunder/core/singletons/lemmy_client.dart'; import 'package:thunder/account/bloc/account_bloc.dart'; -import 'package:thunder/community/pages/community_page.dart'; import 'package:thunder/core/auth/bloc/auth_bloc.dart'; import 'package:thunder/thunder/bloc/thunder_bloc.dart'; import 'package:thunder/utils/swipe.dart'; -Future navigateToCommunityByName(BuildContext context, String communityName) async { - // Get the id from the name - int? communityId; - Account? account = await fetchActiveProfileAccount(); - final getCommunityResponse = await LemmyClient.instance.lemmyApiV3.run(GetCommunity( - auth: account?.jwt, - name: communityName, - )); +/// Navigates to a [CommunityPage] with a given [communityName] or [communityId] +/// +/// Note: only one of [communityName] or [communityId] should be provided +/// If both are provided, the [communityId] will take precedence +/// +/// The [context] parameter should contain the following blocs within its widget tree: [AccountBloc], [AuthBloc], [ThunderBloc] +Future navigateToCommunityPage(BuildContext context, {String? communityName, int? communityId}) async { + if (communityName == null && communityId == null) return; // Return early since there's nothing to do + + int? _communityId = communityId; + + if (_communityId == null) { + // Get the id from the name + Account? account = await fetchActiveProfileAccount(); + + final getCommunityResponse = await LemmyClient.instance.lemmyApiV3.run(GetCommunity( + auth: account?.jwt, + name: communityName, + )); - communityId = getCommunityResponse.communityView.community.id; + _communityId = getCommunityResponse.communityView.community.id; + } // Push navigation AccountBloc accountBloc = context.read(); @@ -30,6 +43,7 @@ Future navigateToCommunityByName(BuildContext context, String communityNam Navigator.of(context).push( SwipeablePageRoute( + backGestureDetectionWidth: 45, canOnlySwipeFromEdge: disableFullPageSwipe(isUserLoggedIn: authBloc.state.isLoggedIn, state: thunderBloc.state, isFeedPage: true), builder: (context) => MultiBlocProvider( providers: [ diff --git a/lib/utils/navigate_user.dart b/lib/utils/navigate_user.dart index a6e5408e6..883bff2f9 100644 --- a/lib/utils/navigate_user.dart +++ b/lib/utils/navigate_user.dart @@ -1,8 +1,9 @@ import 'package:flutter/material.dart'; -import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:lemmy_api_client/v3.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:swipeable_page_route/swipeable_page_route.dart'; + import 'package:thunder/account/models/account.dart'; import 'package:thunder/core/auth/helpers/fetch_account.dart'; import 'package:thunder/core/singletons/lemmy_client.dart'; @@ -12,16 +13,28 @@ import 'package:thunder/thunder/bloc/thunder_bloc.dart'; import 'package:thunder/user/pages/user_page.dart'; import 'package:thunder/utils/swipe.dart'; -Future navigateToUserByName(BuildContext context, String username) async { - // Get the id from the name - int? userId; - Account? account = await fetchActiveProfileAccount(); - final fullPersonView = await LemmyClient.instance.lemmyApiV3.run(GetPersonDetails( - auth: account?.jwt, - username: username, - )); +/// Navigates to a [UserPage] with a given [username] or [userId] +/// +/// Note: only one of [username] or [userId] should be provided +/// If both are provided, the [userId] will take precedence +/// +/// The [context] parameter should contain the following blocs within its widget tree: [AccountBloc], [AuthBloc], [ThunderBloc] +Future navigateToUserPage(BuildContext context, {String? username, int? userId}) async { + if (username == null && userId == null) return; // Return early since there's nothing to do + + int? _userId = userId; + + if (_userId == null) { + // Get the id from the name + Account? account = await fetchActiveProfileAccount(); + + final FullPersonView fullPersonView = await LemmyClient.instance.lemmyApiV3.run(GetPersonDetails( + auth: account?.jwt, + username: username, + )); - userId = fullPersonView.personView.person.id; + _userId = fullPersonView.personView.person.id; + } // Push navigation AccountBloc accountBloc = context.read(); @@ -30,6 +43,7 @@ Future navigateToUserByName(BuildContext context, String username) async { Navigator.of(context).push( SwipeablePageRoute( + backGestureDetectionWidth: 45, canOnlySwipeFromEdge: disableFullPageSwipe(isUserLoggedIn: authBloc.state.isLoggedIn, state: thunderBloc.state, isFeedPage: true), builder: (context) => MultiBlocProvider( providers: [ @@ -37,10 +51,7 @@ Future navigateToUserByName(BuildContext context, String username) async { BlocProvider.value(value: authBloc), BlocProvider.value(value: thunderBloc), ], - child: UserPage( - userId: userId, - username: username, - ), + child: UserPage(userId: userId, username: username), ), ), );