From 93a456a03b4df13443e25444bc2d262d3f02eca6 Mon Sep 17 00:00:00 2001 From: Hamlet Jiang Su Date: Fri, 8 Sep 2023 11:16:48 -0700 Subject: [PATCH] refactored code to handle navigateToCommunityPage/nagivateToUserPage, and added workaround to allow iOS to handle swipe back correctly --- .../utils/post_card_action_helpers.dart | 56 +----- lib/community/widgets/community_sidebar.dart | 20 +- lib/community/widgets/post_card.dart | 5 +- lib/core/enums/fab_action.dart | 1 + lib/inbox/widgets/inbox_mentions_view.dart | 25 +-- lib/inbox/widgets/inbox_replies_view.dart | 188 +----------------- lib/post/pages/post_page.dart | 1 + lib/post/utils/comment_actions.dart | 1 + lib/post/widgets/comment_card.dart | 2 +- lib/post/widgets/post_view.dart | 41 +--- lib/routes.dart | 1 + lib/search/pages/search_page.dart | 117 +++++------ lib/settings/pages/about_settings_page.dart | 2 +- lib/shared/comment_header.dart | 19 +- lib/shared/comment_reference.dart | 1 + lib/shared/common_markdown_body.dart | 4 +- lib/shared/link_preview_card.dart | 4 +- lib/user/widgets/comment_card.dart | 36 +--- lib/user/widgets/user_sidebar.dart | 18 +- lib/utils/navigate_community.dart | 36 +++- lib/utils/navigate_user.dart | 39 ++-- 21 files changed, 149 insertions(+), 468 deletions(-) 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 86b31131c..2c11033d7 100644 --- a/lib/community/widgets/community_sidebar.dart +++ b/lib/community/widgets/community_sidebar.dart @@ -13,6 +13,8 @@ import 'package:thunder/core/auth/bloc/auth_bloc.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 '../../shared/common_markdown_body.dart'; import '../../thunder/bloc/thunder_bloc.dart'; @@ -136,6 +138,7 @@ class _CommunitySidebarState extends State with TickerProvider ThunderBloc thunderBloc = context.read(); Navigator.of(context).push( SwipeablePageRoute( + backGestureDetectionWidth: 45, builder: (context) { return MultiBlocProvider( providers: [ @@ -476,22 +479,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 4338fa4b9..451ce8a59 100644 --- a/lib/core/enums/fab_action.dart +++ b/lib/core/enums/fab_action.dart @@ -120,6 +120,7 @@ enum FeedFabAction { AccountBloc accountBloc = context.read(); Navigator.of(context).push( SwipeablePageRoute( + backGestureDetectionWidth: 45, builder: (context) { return MultiBlocProvider( providers: [ diff --git a/lib/inbox/widgets/inbox_mentions_view.dart b/lib/inbox/widgets/inbox_mentions_view.dart index a0c01c3bf..6af680f03 100644 --- a/lib/inbox/widgets/inbox_mentions_view.dart +++ b/lib/inbox/widgets/inbox_mentions_view.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'; @@ -14,6 +16,7 @@ import 'package:thunder/shared/common_markdown_body.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'; class InboxMentionsView extends StatelessWidget { @@ -45,7 +48,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: [ @@ -109,6 +113,7 @@ class InboxMentionsView extends StatelessWidget { Navigator.of(context).push( SwipeablePageRoute( + backGestureDetectionWidth: 45, builder: (context) { return MultiBlocProvider(providers: [ BlocProvider.value(value: inboxBloc), @@ -138,22 +143,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 5b44dcadf..8df3dbe31 100644 --- a/lib/inbox/widgets/inbox_replies_view.dart +++ b/lib/inbox/widgets/inbox_replies_view.dart @@ -14,6 +14,7 @@ import 'package:thunder/post/bloc/post_bloc.dart'; import 'package:thunder/shared/comment_reference.dart'; import 'package:thunder/post/pages/create_comment_page.dart'; import 'package:thunder/thunder/bloc/thunder_bloc.dart'; +import 'package:thunder/utils/navigate_community.dart'; import 'package:thunder/utils/swipe.dart'; class InboxRepliesView extends StatefulWidget { @@ -116,194 +117,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 5dfb3ba71..e186ee104 100644 --- a/lib/post/pages/post_page.dart +++ b/lib/post/pages/post_page.dart @@ -486,6 +486,7 @@ class _PostPageState extends State { } else { Navigator.of(context).push( SwipeablePageRoute( + backGestureDetectionWidth: 45, builder: (context) { return MultiBlocProvider(providers: [ BlocProvider.value(value: postBloc), diff --git a/lib/post/utils/comment_actions.dart b/lib/post/utils/comment_actions.dart index 179a964a1..432918724 100644 --- a/lib/post/utils/comment_actions.dart +++ b/lib/post/utils/comment_actions.dart @@ -37,6 +37,7 @@ void triggerCommentAction({ Navigator.of(context).push( SwipeablePageRoute( + backGestureDetectionWidth: 45, builder: (context) { return MultiBlocProvider( providers: [ diff --git a/lib/post/widgets/comment_card.dart b/lib/post/widgets/comment_card.dart index c3f2b3fbe..10c53f386 100644 --- a/lib/post/widgets/comment_card.dart +++ b/lib/post/widgets/comment_card.dart @@ -188,7 +188,7 @@ class _CommentCardState extends State with SingleTickerProviderStat behavior: HitTestBehavior.opaque, onPointerDown: (event) => {}, onPointerUp: (event) { - if (isOverridingSwipeGestureAction) { + if (isOverridingSwipeGestureAction == true) { setState(() => isOverridingSwipeGestureAction = false); } diff --git a/lib/post/widgets/post_view.dart b/lib/post/widgets/post_view.dart index 6e79c5e7c..b2dcfbf15 100644 --- a/lib/post/widgets/post_view.dart +++ b/lib/post/widgets/post_view.dart @@ -22,6 +22,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'; @@ -103,25 +105,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), @@ -189,23 +173,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, @@ -343,6 +311,7 @@ class PostSubview extends StatelessWidget { Navigator.of(context).push( SwipeablePageRoute( + backGestureDetectionWidth: 45, builder: (context) { return MultiBlocProvider( providers: [ 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/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), ), ), );