diff --git a/lib/account/widgets/account_page_app_bar.dart b/lib/account/widgets/account_page_app_bar.dart index 6f2463318..61e686501 100644 --- a/lib/account/widgets/account_page_app_bar.dart +++ b/lib/account/widgets/account_page_app_bar.dart @@ -1,15 +1,12 @@ -import 'dart:io'; - import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; -import 'package:swipeable_page_route/swipeable_page_route.dart'; -import 'package:thunder/account/bloc/account_bloc.dart'; import 'package:thunder/account/utils/profiles.dart'; import 'package:thunder/core/enums/full_name.dart'; +import 'package:thunder/core/enums/local_settings.dart'; import 'package:thunder/core/singletons/lemmy_client.dart'; import 'package:thunder/feed/bloc/feed_bloc.dart'; import 'package:thunder/feed/utils/user_share.dart'; @@ -17,9 +14,8 @@ import 'package:thunder/feed/utils/utils.dart'; import 'package:thunder/shared/sort_picker.dart'; import 'package:thunder/shared/thunder_popup_menu_item.dart'; import 'package:thunder/thunder/bloc/thunder_bloc.dart'; -import 'package:thunder/user/bloc/user_settings_bloc.dart'; -import 'package:thunder/user/pages/user_settings_page.dart'; import 'package:thunder/utils/instance.dart'; +import 'package:thunder/utils/navigation.dart'; /// Holds the app bar for the account page class AccountPageAppBar extends StatefulWidget { @@ -153,26 +149,7 @@ class AccountAppBarUserActions extends StatelessWidget { tooltip: l10n.accountSettings, onPressed: () { HapticFeedback.mediumImpact(); - - final AccountBloc accountBloc = context.read(); - final ThunderBloc thunderBloc = context.read(); - final UserSettingsBloc userSettingsBloc = UserSettingsBloc(); - - Navigator.of(context).push( - SwipeablePageRoute( - transitionDuration: thunderBloc.state.reduceAnimations ? const Duration(milliseconds: 100) : null, - canSwipe: Platform.isIOS || thunderBloc.state.enableFullScreenSwipeNavigationGesture, - canOnlySwipeFromEdge: !thunderBloc.state.enableFullScreenSwipeNavigationGesture, - builder: (context) => MultiBlocProvider( - providers: [ - BlocProvider.value(value: accountBloc), - BlocProvider.value(value: thunderBloc), - BlocProvider.value(value: userSettingsBloc), - ], - child: const UserSettingsPage(), - ), - ), - ); + navigateToSettingPage(context, LocalSettings.settingsPageAccount); }, ), Semantics( diff --git a/lib/comment/utils/navigate_comment.dart b/lib/comment/utils/navigate_comment.dart deleted file mode 100644 index 4bf98b9ae..000000000 --- a/lib/comment/utils/navigate_comment.dart +++ /dev/null @@ -1,101 +0,0 @@ -// Flutter imports -import 'dart:io'; - -import 'package:flutter/material.dart'; - -// Package imports -import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:flutter_gen/gen_l10n/app_localizations.dart'; -import 'package:lemmy_api_client/v3.dart'; -import 'package:swipeable_page_route/swipeable_page_route.dart'; - -// Project imports -import 'package:thunder/account/bloc/account_bloc.dart'; -import 'package:thunder/comment/view/create_comment_page.dart'; -import 'package:thunder/core/auth/bloc/auth_bloc.dart'; -import 'package:thunder/core/models/post_view_media.dart'; -import 'package:thunder/post/bloc/post_bloc.dart'; -import 'package:thunder/post/pages/legacy_post_page.dart'; -import 'package:thunder/shared/pages/loading_page.dart'; -import 'package:thunder/shared/snackbar.dart'; -import 'package:thunder/thunder/bloc/thunder_bloc.dart'; -import 'package:thunder/utils/swipe.dart'; - -Future navigateToComment(BuildContext context, CommentView commentView) async { - AccountBloc accountBloc = context.read(); - AuthBloc authBloc = context.read(); - ThunderBloc thunderBloc = context.read(); - - final ThunderState state = context.read().state; - final bool reduceAnimations = state.reduceAnimations; - - final SwipeablePageRoute route = SwipeablePageRoute( - transitionDuration: isLoadingPageShown - ? Duration.zero - : reduceAnimations - ? const Duration(milliseconds: 100) - : null, - reverseTransitionDuration: reduceAnimations ? const Duration(milliseconds: 100) : const Duration(milliseconds: 500), - backGestureDetectionWidth: 45, - canSwipe: Platform.isIOS || state.enableFullScreenSwipeNavigationGesture, - canOnlySwipeFromEdge: disableFullPageSwipe(isUserLoggedIn: authBloc.state.isLoggedIn, state: thunderBloc.state, isPostPage: true) || !state.enableFullScreenSwipeNavigationGesture, - builder: (context) => MultiBlocProvider( - providers: [ - BlocProvider.value(value: accountBloc), - BlocProvider.value(value: authBloc), - BlocProvider.value(value: thunderBloc), - BlocProvider(create: (context) => PostBloc()), - ], - child: PostPage( - selectedCommentId: commentView.comment.id, - selectedCommentPath: commentView.comment.path, - postId: commentView.post.id, - onPostUpdated: (PostViewMedia postViewMedia) => {}, - ), - ), - ); - - pushOnTopOfLoadingPage(context, route); -} - -Future navigateToCreateCommentPage( - BuildContext context, { - PostViewMedia? postViewMedia, - CommentView? commentView, - CommentView? parentCommentView, - Function(CommentView commentView, bool userChanged)? onCommentSuccess, -}) async { - assert(!(postViewMedia == null && parentCommentView == null && commentView == null)); - assert(!(postViewMedia != null && (parentCommentView != null || commentView != null))); - - final l10n = AppLocalizations.of(context)!; - - try { - ThunderBloc thunderBloc = context.read(); - AccountBloc accountBloc = context.read(); - - final bool reduceAnimations = thunderBloc.state.reduceAnimations; - - Navigator.of(context).push(SwipeablePageRoute( - transitionDuration: reduceAnimations ? const Duration(milliseconds: 100) : null, - canOnlySwipeFromEdge: true, - backGestureDetectionWidth: 45, - builder: (navigatorContext) { - return MultiBlocProvider( - providers: [ - BlocProvider.value(value: thunderBloc), - BlocProvider.value(value: accountBloc), - ], - child: CreateCommentPage( - postViewMedia: postViewMedia, - commentView: commentView, - parentCommentView: parentCommentView, - onCommentSuccess: onCommentSuccess, - ), - ); - }, - )); - } catch (e) { - if (context.mounted) showSnackbar(l10n.unexpectedError); - } -} diff --git a/lib/comment/widgets/comment_card.dart b/lib/comment/widgets/comment_card.dart index ce74b120e..c5d6d70e7 100644 --- a/lib/comment/widgets/comment_card.dart +++ b/lib/comment/widgets/comment_card.dart @@ -6,7 +6,7 @@ import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:lemmy_api_client/v3.dart'; import 'package:thunder/comment/enums/comment_action.dart'; -import 'package:thunder/comment/utils/navigate_comment.dart'; +import 'package:thunder/utils/navigation.dart'; import 'package:thunder/comment/widgets/comment_action_bottom_sheet.dart'; import 'package:thunder/core/auth/bloc/auth_bloc.dart'; import 'package:thunder/core/enums/nested_comment_indicator.dart'; diff --git a/lib/comment/widgets/comment_comment_action_bottom_sheet.dart b/lib/comment/widgets/comment_comment_action_bottom_sheet.dart index 2557a6713..25c86c4d5 100644 --- a/lib/comment/widgets/comment_comment_action_bottom_sheet.dart +++ b/lib/comment/widgets/comment_comment_action_bottom_sheet.dart @@ -5,7 +5,7 @@ import 'package:lemmy_api_client/v3.dart'; import 'package:thunder/comment/enums/comment_action.dart'; import 'package:thunder/core/auth/bloc/auth_bloc.dart'; -import 'package:thunder/modlog/utils/navigate_modlog.dart'; +import 'package:thunder/utils/navigation.dart'; import 'package:thunder/post/enums/post_action.dart'; import 'package:thunder/shared/bottom_sheet_action.dart'; import 'package:thunder/shared/dialogs.dart'; diff --git a/lib/comment/widgets/comment_list_entry.dart b/lib/comment/widgets/comment_list_entry.dart index 8966f0d86..9dfd862d9 100644 --- a/lib/comment/widgets/comment_list_entry.dart +++ b/lib/comment/widgets/comment_list_entry.dart @@ -6,7 +6,7 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:lemmy_api_client/v3.dart'; // Project imports -import 'package:thunder/comment/utils/navigate_comment.dart'; +import 'package:thunder/utils/navigation.dart'; import 'package:thunder/core/auth/bloc/auth_bloc.dart'; import 'package:thunder/post/bloc/post_bloc.dart' as post_bloc; import 'package:thunder/shared/comment_reference.dart'; diff --git a/lib/community/widgets/community_drawer.dart b/lib/community/widgets/community_drawer.dart index edb1d7975..1e00d3f21 100644 --- a/lib/community/widgets/community_drawer.dart +++ b/lib/community/widgets/community_drawer.dart @@ -1,7 +1,5 @@ -import 'dart:io'; import 'dart:math'; -import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; @@ -9,14 +7,12 @@ import 'package:lemmy_api_client/v3.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:sliver_tools/sliver_tools.dart'; -import 'package:swipeable_page_route/swipeable_page_route.dart'; import 'package:thunder/account/bloc/account_bloc.dart'; import 'package:thunder/account/utils/profiles.dart'; import 'package:thunder/community/bloc/anonymous_subscriptions_bloc.dart'; import 'package:thunder/core/auth/bloc/auth_bloc.dart'; import 'package:thunder/feed/feed.dart'; -import 'package:thunder/moderator/view/report_page.dart'; import 'package:thunder/shared/avatars/community_avatar.dart'; import 'package:thunder/shared/avatars/user_avatar.dart'; import 'package:thunder/thunder/bloc/thunder_bloc.dart'; @@ -24,6 +20,7 @@ import 'package:thunder/utils/instance.dart'; import 'package:thunder/utils/global_context.dart'; import 'package:thunder/core/enums/full_name.dart'; import 'package:thunder/feed/utils/community.dart'; +import 'package:thunder/utils/navigation.dart'; class CommunityDrawer extends StatefulWidget { const CommunityDrawer({super.key, this.navigateToAccount}); @@ -254,27 +251,9 @@ class FeedDrawerItems extends StatelessWidget { if (accountState.moderates.isNotEmpty || accountState.personView?.isAdmin == true) DrawerItem( label: l10n.report(2), - onTap: () async { + onTap: () { HapticFeedback.mediumImpact(); - ThunderBloc thunderBloc = context.read(); - - await Navigator.of(context).push( - SwipeablePageRoute( - transitionDuration: thunderBloc.state.reduceAnimations ? const Duration(milliseconds: 100) : null, - backGestureDetectionStartOffset: !kIsWeb && Platform.isAndroid ? 45 : 0, - backGestureDetectionWidth: 45, - canOnlySwipeFromEdge: true, - builder: (otherContext) { - return MultiBlocProvider( - providers: [ - BlocProvider.value(value: feedBloc), - BlocProvider.value(value: thunderBloc), - ], - child: const ReportFeedPage(), - ); - }, - ), - ); + navigateToReportPage(context); }, icon: Icons.report_rounded, trailing: const Icon(Icons.arrow_forward_rounded), diff --git a/lib/community/widgets/community_list_entry.dart b/lib/community/widgets/community_list_entry.dart index b22dae990..860c21ca8 100644 --- a/lib/community/widgets/community_list_entry.dart +++ b/lib/community/widgets/community_list_entry.dart @@ -5,12 +5,12 @@ import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:thunder/account/bloc/account_bloc.dart'; import 'package:thunder/core/enums/full_name.dart'; import 'package:thunder/core/singletons/lemmy_client.dart'; -import 'package:thunder/feed/utils/utils.dart'; import 'package:thunder/feed/view/feed_page.dart'; import 'package:thunder/shared/avatars/community_avatar.dart'; import 'package:thunder/shared/full_name_widgets.dart'; import 'package:thunder/shared/snackbar.dart'; import 'package:thunder/utils/instance.dart'; +import 'package:thunder/utils/navigation.dart'; import 'package:thunder/utils/numbers.dart'; class CommunityListEntry extends StatelessWidget { diff --git a/lib/community/widgets/community_sidebar.dart b/lib/community/widgets/community_sidebar.dart index 4185e27e5..d46f1d9ac 100644 --- a/lib/community/widgets/community_sidebar.dart +++ b/lib/community/widgets/community_sidebar.dart @@ -11,10 +11,9 @@ import 'package:thunder/community/enums/community_action.dart'; import 'package:thunder/core/auth/bloc/auth_bloc.dart'; import 'package:thunder/core/singletons/lemmy_client.dart'; import 'package:thunder/feed/bloc/feed_bloc.dart'; -import 'package:thunder/feed/utils/utils.dart'; import 'package:thunder/feed/view/feed_page.dart'; import 'package:thunder/instance/widgets/instance_view.dart'; -import 'package:thunder/post/utils/navigate_create_post.dart'; +import 'package:thunder/utils/navigation.dart'; import 'package:thunder/shared/common_markdown_body.dart'; import 'package:thunder/shared/avatars/user_avatar.dart'; import 'package:thunder/shared/full_name_widgets.dart'; diff --git a/lib/community/widgets/post_card.dart b/lib/community/widgets/post_card.dart index 3a4920358..ae82d4793 100644 --- a/lib/community/widgets/post_card.dart +++ b/lib/community/widgets/post_card.dart @@ -18,7 +18,7 @@ import 'package:thunder/feed/view/feed_page.dart'; import 'package:thunder/feed/widgets/widgets.dart'; import 'package:thunder/post/enums/post_action.dart'; import 'package:thunder/thunder/bloc/thunder_bloc.dart'; -import 'package:thunder/post/utils/navigate_post.dart'; +import 'package:thunder/utils/navigation.dart'; import 'package:thunder/user/enums/user_action.dart'; class PostCard extends StatefulWidget { diff --git a/lib/community/widgets/post_card_metadata.dart b/lib/community/widgets/post_card_metadata.dart index f27deec40..38f31011e 100644 --- a/lib/community/widgets/post_card_metadata.dart +++ b/lib/community/widgets/post_card_metadata.dart @@ -16,6 +16,7 @@ import 'package:thunder/shared/text/scalable_text.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/navigation.dart'; import 'package:thunder/utils/numbers.dart'; /// Contains metadata related to a given post. This is generally displayed as part of the post card. diff --git a/lib/core/enums/local_settings.dart b/lib/core/enums/local_settings.dart index 77e1e12c6..79aa04721 100644 --- a/lib/core/enums/local_settings.dart +++ b/lib/core/enums/local_settings.dart @@ -9,6 +9,9 @@ enum LocalSettingsCategories { floatingActionButton('floatingActionButton'), accessibility('Accessibility'), account('Account'), + accountLanguages('Discussion Languages'), + accountBlocklist('Blocklists'), + accountMediaManagement('Media Management'), userLabels('User Labels'), about('About'), debug('Debug'), @@ -74,6 +77,27 @@ enum LocalSettings { settingsPageGeneral(name: 'settings_page_general', key: 'settingsPageGeneral', category: LocalSettingsCategories.general, subCategory: LocalSettingsSubCategories.general, isPage: true), settingsPageFilters(name: 'settings_page_filters', key: 'settingsPageFilters', category: LocalSettingsCategories.filters, subCategory: LocalSettingsSubCategories.general, isPage: true), settingsPageAppearance(name: 'settings_page_appearance', key: 'settingsPageAppearance', category: LocalSettingsCategories.appearance, subCategory: LocalSettingsSubCategories.general, isPage: true), + settingsPageAppearanceTheming( + name: 'settings_page_appearance_theming', + key: 'settingsPageAppearanceTheming', + category: LocalSettingsCategories.theming, + subCategory: LocalSettingsSubCategories.general, + isPage: true, + ), + settingsPageAppearancePosts( + name: 'settings_page_appearance_posts', + key: 'settingsPageAppearancePosts', + category: LocalSettingsCategories.posts, + subCategory: LocalSettingsSubCategories.general, + isPage: true, + ), + settingsPageAppearanceComments( + name: 'settings_page_appearance_comments', + key: 'settingsPageAppearanceComments', + category: LocalSettingsCategories.comments, + subCategory: LocalSettingsSubCategories.general, + isPage: true, + ), settingsPageGestures(name: 'settings_page_gestures', key: 'settingsPageGestures', category: LocalSettingsCategories.gestures, subCategory: LocalSettingsSubCategories.general, isPage: true), settingsPageVideo(name: 'settings_page_video', key: 'settingsPageVideo', category: LocalSettingsCategories.videoPlayer, subCategory: LocalSettingsSubCategories.general, isPage: true), settingsPageFloatingActionButton( @@ -85,6 +109,27 @@ enum LocalSettings { settingsPageAccessibility( name: 'settings_page_accessibility', key: 'settingsPageAccessibility', category: LocalSettingsCategories.accessibility, subCategory: LocalSettingsSubCategories.general, isPage: true), settingsPageAccount(name: 'settings_page_account', key: 'settingsPageAccount', category: LocalSettingsCategories.account, subCategory: LocalSettingsSubCategories.general, isPage: true), + settingsPageAccountLanguages( + name: 'settings_page_account_languages', + key: 'settingsPageAccountLanguages', + category: LocalSettingsCategories.accountLanguages, + subCategory: LocalSettingsSubCategories.contentManagement, + isPage: true, + ), + settingsPageAccountBlocks( + name: 'settings_page_account_blocks', + key: 'settingsPageAccountBlocks', + category: LocalSettingsCategories.accountBlocklist, + subCategory: LocalSettingsSubCategories.contentManagement, + isPage: true, + ), + settingsPageAccountMedia( + name: 'settings_page_account_media', + key: 'settingsPageAccountMedia', + category: LocalSettingsCategories.accountMediaManagement, + subCategory: LocalSettingsSubCategories.contentManagement, + isPage: true, + ), settingsPageUserLabels(name: 'settings_page_user_labels', key: 'settingsPageUserLabels', category: LocalSettingsCategories.userLabels, subCategory: LocalSettingsSubCategories.general, isPage: true), settingsPageAbout(name: 'settings_page_about', key: 'settingsPageAbout', category: LocalSettingsCategories.about, subCategory: LocalSettingsSubCategories.general, isPage: true), settingsPageDebug(name: 'settings_page_debug', key: 'settingsPageDebug', category: LocalSettingsCategories.debug, subCategory: LocalSettingsSubCategories.general, isPage: true), @@ -436,11 +481,17 @@ extension LocalizationExt on AppLocalizations { 'settingsPageAbout': settingsPageAbout, 'settingsPageUserLabels': settingsPageUserLabels, 'settingsPageAccount': settingsPageAccount, + 'settingsPageAccountLanguages': settingsPageAccountLanguages, + 'settingsPageAccountBlocks': settingsPageAccountBlocks, + 'settingsPageAccountMedia': settingsPageAccountMedia, 'settingsPageAccessibility': settingsPageAccessibility, 'settingsPageFloatingActionButton': settingsPageFloatingActionButton, 'settingsPageVideo': settingsPageVideo, 'settingsPageGestures': settingsPageGestures, 'settingsPageAppearance': settingsPageAppearance, + 'settingsPageAppearanceTheming': settingsPageAppearanceTheming, + 'settingsPageAppearancePosts': settingsPageAppearancePosts, + 'settingsPageAppearanceComments': settingsPageAppearanceComments, 'settingsPageFilters': settingsPageFilters, 'settingsPageGeneral': settingsPageGeneral, 'defaultFeedType': defaultFeedType, diff --git a/lib/core/theme/bloc/theme_bloc.dart b/lib/core/theme/bloc/theme_bloc.dart index 84c651148..3c32ec5ca 100644 --- a/lib/core/theme/bloc/theme_bloc.dart +++ b/lib/core/theme/bloc/theme_bloc.dart @@ -43,7 +43,7 @@ class ThemeBloc extends Bloc { bool usePureBlackTheme = prefs.getBool(LocalSettings.usePureBlackTheme.name) ?? false; if (usePureBlackTheme && (themeType == ThemeType.dark || (themeType == ThemeType.system && brightness == Brightness.dark))) themeType = ThemeType.pureBlack; - bool useDarkTheme = themeType == ThemeType.dark || themeType == ThemeType.pureBlack; + bool useDarkTheme = themeType == ThemeType.dark || themeType == ThemeType.pureBlack || (themeType == ThemeType.system && brightness == Brightness.dark); CustomThemeType selectedTheme = CustomThemeType.values.byName(prefs.getString(LocalSettings.appThemeAccentColor.name) ?? CustomThemeType.deepBlue.name); diff --git a/lib/feed/utils/utils.dart b/lib/feed/utils/utils.dart index 050a21006..d3b772bbe 100644 --- a/lib/feed/utils/utils.dart +++ b/lib/feed/utils/utils.dart @@ -1,21 +1,9 @@ -import 'dart:io'; - import 'package:flutter/material.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/bloc/account_bloc.dart'; -import 'package:thunder/community/bloc/anonymous_subscriptions_bloc.dart'; -import 'package:thunder/community/bloc/community_bloc.dart'; -import 'package:thunder/core/auth/bloc/auth_bloc.dart'; import 'package:thunder/feed/feed.dart'; -import 'package:thunder/instance/bloc/instance_bloc.dart'; -import 'package:thunder/shared/pages/loading_page.dart'; import 'package:thunder/shared/sort_picker.dart'; import 'package:thunder/community/widgets/community_drawer.dart'; -import 'package:thunder/thunder/bloc/thunder_bloc.dart'; -import 'package:thunder/utils/swipe.dart'; String getAppBarTitle(FeedState state) { if (state.status == FeedStatus.initial) { @@ -55,88 +43,6 @@ IconData? getSortIcon(FeedState state) { return sortTypeItem?.icon; } -/// Navigates to a [FeedPage] with the given parameters -/// -/// [feedType] must be provided. -/// If [feedType] is [FeedType.general], [postListingType] must be provided -/// If [feedType] is [FeedType.community], one of [communityId] or [communityName] must be provided -/// If [feedType] is [FeedType.user], one of [userId] or [username] must be provided -/// -/// The [context] parameter should contain the following blocs within its widget tree: [AccountBloc], [AuthBloc], [ThunderBloc] -Future navigateToFeedPage( - BuildContext context, { - required FeedType feedType, - ListingType? postListingType, - SortType? sortType, - String? communityName, - int? communityId, - String? username, - int? userId, -}) async { - // Push navigation - AccountBloc accountBloc = context.read(); - AuthBloc authBloc = context.read(); - ThunderBloc thunderBloc = context.read(); - CommunityBloc communityBloc = context.read(); - InstanceBloc instanceBloc = context.read(); - AnonymousSubscriptionsBloc anonymousSubscriptionsBloc = context.read(); - - ThunderState thunderState = thunderBloc.state; - final bool reduceAnimations = thunderState.reduceAnimations; - - if (feedType == FeedType.general) { - return context.read().add( - FeedFetchedEvent( - feedType: feedType, - postListingType: postListingType, - sortType: sortType ?? authBloc.state.getSiteResponse?.myUser?.localUserView.localUser.defaultSortType ?? thunderBloc.state.sortTypeForInstance, - communityId: communityId, - communityName: communityName, - userId: userId, - username: username, - reset: true, - showHidden: thunderBloc.state.showHiddenPosts, - ), - ); - } - - SwipeablePageRoute route = SwipeablePageRoute( - transitionDuration: isLoadingPageShown - ? Duration.zero - : reduceAnimations - ? const Duration(milliseconds: 100) - : null, - reverseTransitionDuration: reduceAnimations ? const Duration(milliseconds: 100) : const Duration(milliseconds: 500), - backGestureDetectionWidth: 45, - canSwipe: Platform.isIOS || thunderState.enableFullScreenSwipeNavigationGesture, - canOnlySwipeFromEdge: disableFullPageSwipe(isUserLoggedIn: authBloc.state.isLoggedIn, state: thunderBloc.state, isFeedPage: true) || !thunderState.enableFullScreenSwipeNavigationGesture, - builder: (context) => MultiBlocProvider( - providers: [ - BlocProvider.value(value: accountBloc), - BlocProvider.value(value: authBloc), - BlocProvider.value(value: thunderBloc), - BlocProvider.value(value: instanceBloc), - BlocProvider.value(value: anonymousSubscriptionsBloc), - BlocProvider.value(value: communityBloc), - ], - child: Material( - child: FeedPage( - feedType: feedType, - sortType: sortType ?? authBloc.state.getSiteResponse?.myUser?.localUserView.localUser.defaultSortType ?? thunderBloc.state.sortTypeForInstance, - communityName: communityName, - communityId: communityId, - userId: userId, - username: username, - postListingType: postListingType, - showHidden: thunderBloc.state.showHiddenPosts, - ), - ), - ), - ); - - pushOnTopOfLoadingPage(context, route); -} - Future triggerRefresh(BuildContext context) async { FeedState state = context.read().state; diff --git a/lib/feed/view/feed_page.dart b/lib/feed/view/feed_page.dart index 9f581cb76..ab0650f8f 100644 --- a/lib/feed/view/feed_page.dart +++ b/lib/feed/view/feed_page.dart @@ -1,5 +1,4 @@ import 'dart:async'; -import 'dart:io'; import 'dart:math'; import 'package:back_button_interceptor/back_button_interceptor.dart'; @@ -10,7 +9,6 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:lemmy_api_client/v3.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:sliver_tools/sliver_tools.dart'; -import 'package:swipeable_page_route/swipeable_page_route.dart'; import 'package:thunder/account/widgets/account_page_app_bar.dart'; import 'package:thunder/community/bloc/community_bloc.dart'; @@ -28,7 +26,6 @@ import 'package:thunder/feed/widgets/feed_post_card_list.dart'; import 'package:thunder/feed/widgets/feed_fab.dart'; import 'package:thunder/feed/widgets/feed_page_app_bar.dart'; import 'package:thunder/instance/bloc/instance_bloc.dart'; -import 'package:thunder/settings/pages/filter_settings_page.dart'; import 'package:thunder/shared/common_markdown_body.dart'; import 'package:thunder/shared/snackbar.dart'; import 'package:thunder/shared/text/scalable_text.dart'; @@ -38,6 +35,7 @@ import 'package:thunder/user/widgets/user_header.dart'; import 'package:thunder/user/widgets/user_sidebar.dart'; import 'package:thunder/utils/colors.dart'; import 'package:thunder/utils/global_context.dart'; +import 'package:thunder/utils/navigation.dart'; enum FeedType { community, user, general, account } @@ -344,21 +342,7 @@ class _FeedViewState extends State { showSnackbar( l10n.excessiveApiCallsWarning, trailingIcon: Icons.settings_rounded, - trailingAction: () { - final ThunderBloc thunderBloc = context.read(); - - Navigator.of(context).push( - SwipeablePageRoute( - transitionDuration: thunderBloc.state.reduceAnimations ? const Duration(milliseconds: 100) : null, - canSwipe: Platform.isIOS || thunderBloc.state.enableFullScreenSwipeNavigationGesture, - canOnlySwipeFromEdge: !thunderBloc.state.enableFullScreenSwipeNavigationGesture, - builder: (context) => MultiBlocProvider( - providers: [BlocProvider.value(value: thunderBloc)], - child: const FilterSettingsPage(settingToHighlight: LocalSettings.keywordFilters), - ), - ), - ); - }, + trailingAction: () => navigateToSettingPage(context, LocalSettings.settingsPageFilters, settingToHighlight: LocalSettings.keywordFilters), ); } return true; diff --git a/lib/feed/widgets/feed_fab.dart b/lib/feed/widgets/feed_fab.dart index 2aee105e5..3f89d62fd 100644 --- a/lib/feed/widgets/feed_fab.dart +++ b/lib/feed/widgets/feed_fab.dart @@ -14,7 +14,7 @@ import 'package:thunder/core/singletons/lemmy_client.dart'; import 'package:thunder/feed/bloc/feed_bloc.dart'; import 'package:thunder/feed/utils/utils.dart'; import 'package:thunder/feed/view/feed_page.dart'; -import 'package:thunder/post/utils/navigate_create_post.dart'; +import 'package:thunder/utils/navigation.dart'; import 'package:thunder/shared/gesture_fab.dart'; import 'package:thunder/shared/snackbar.dart'; import 'package:thunder/shared/sort_picker.dart'; diff --git a/lib/feed/widgets/feed_page_app_bar.dart b/lib/feed/widgets/feed_page_app_bar.dart index 2a3eef121..71a948853 100644 --- a/lib/feed/widgets/feed_page_app_bar.dart +++ b/lib/feed/widgets/feed_page_app_bar.dart @@ -6,7 +6,6 @@ import 'package:flutter/services.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:lemmy_api_client/v3.dart'; -import 'package:swipeable_page_route/swipeable_page_route.dart'; import 'package:thunder/account/bloc/account_bloc.dart'; import 'package:thunder/community/bloc/anonymous_subscriptions_bloc.dart'; @@ -20,9 +19,7 @@ import 'package:thunder/feed/utils/community_share.dart'; import 'package:thunder/feed/utils/user_share.dart'; import 'package:thunder/feed/utils/utils.dart'; import 'package:thunder/feed/view/feed_page.dart'; -import 'package:thunder/modlog/utils/navigate_modlog.dart'; -import 'package:thunder/search/bloc/search_bloc.dart'; -import 'package:thunder/search/pages/search_page.dart'; +import 'package:thunder/utils/navigation.dart'; import 'package:thunder/shared/avatars/user_avatar.dart'; import 'package:thunder/shared/dialogs.dart'; import 'package:thunder/shared/snackbar.dart'; @@ -242,35 +239,14 @@ class FeedAppBarCommunityActions extends StatelessWidget { ), if (feedBloc.state.fullCommunityView?.communityView != null) ThunderPopupMenuItem( - onTap: () async { - final ThunderState state = context.read().state; - final bool reduceAnimations = state.reduceAnimations; - final SearchBloc searchBloc = SearchBloc(); - - await Navigator.of(context).push( - SwipeablePageRoute( - transitionDuration: reduceAnimations ? const Duration(milliseconds: 100) : null, - backGestureDetectionWidth: 45, - canOnlySwipeFromEdge: true, - builder: (context) => MultiBlocProvider( - providers: [ - // Create a new SearchBloc so it doesn't conflict with the main one - BlocProvider.value(value: searchBloc), - BlocProvider.value(value: thunderBloc), - ], - child: SearchPage(communityToSearch: feedBloc.state.fullCommunityView!.communityView, isInitiallyFocused: true), - ), - ), - ); - }, + onTap: () => navigateToSearchPage(context), icon: Icons.search_rounded, title: l10n.search, ), ThunderPopupMenuItem( - onTap: () async { - await navigateToModlogPage( + onTap: () { + navigateToModlogPage( context, - feedBloc: feedBloc, communityId: feedBloc.state.fullCommunityView!.communityView.community.id, ); }, @@ -381,7 +357,7 @@ class FeedAppBarGeneralActions extends StatelessWidget { ThunderPopupMenuItem( onTap: () async { HapticFeedback.mediumImpact(); - await navigateToModlogPage(context, feedBloc: feedBloc); + await navigateToModlogPage(context); }, icon: Icons.shield_rounded, title: l10n.modlog, diff --git a/lib/inbox/widgets/inbox_replies_view.dart b/lib/inbox/widgets/inbox_replies_view.dart index 375100e4c..df24ee156 100644 --- a/lib/inbox/widgets/inbox_replies_view.dart +++ b/lib/inbox/widgets/inbox_replies_view.dart @@ -8,7 +8,7 @@ import 'package:flutter_gen/gen_l10n/app_localizations.dart'; // Project imports import 'package:thunder/comment/enums/comment_action.dart'; -import 'package:thunder/comment/utils/navigate_comment.dart'; +import 'package:thunder/utils/navigation.dart'; import 'package:thunder/core/auth/bloc/auth_bloc.dart'; import 'package:thunder/feed/view/feed_page.dart'; import 'package:thunder/inbox/bloc/inbox_bloc.dart'; diff --git a/lib/instance/pages/instance_page.dart b/lib/instance/pages/instance_page.dart index 593c43d2e..8a17af98d 100644 --- a/lib/instance/pages/instance_page.dart +++ b/lib/instance/pages/instance_page.dart @@ -12,7 +12,7 @@ import 'package:thunder/instance/bloc/instance_bloc.dart'; import 'package:thunder/instance/cubit/instance_page_cubit.dart'; import 'package:thunder/instance/enums/instance_action.dart'; import 'package:thunder/instance/widgets/instance_view.dart'; -import 'package:thunder/modlog/utils/navigate_modlog.dart'; +import 'package:thunder/utils/navigation.dart'; import 'package:thunder/search/widgets/search_action_chip.dart'; import 'package:thunder/shared/error_message.dart'; import 'package:thunder/shared/persistent_header.dart'; @@ -191,7 +191,6 @@ class _InstancePageState extends State { FeedBloc feedBloc = context.read(); navigateToModlogPage( context, - feedBloc: feedBloc, lemmyClient: feedBloc.lemmyClient, ); }, diff --git a/lib/instance/utils/navigate_instance.dart b/lib/instance/utils/navigate_instance.dart deleted file mode 100644 index 94464b77d..000000000 --- a/lib/instance/utils/navigate_instance.dart +++ /dev/null @@ -1,75 +0,0 @@ -import 'dart:io'; - -import 'package:flutter/material.dart'; - -import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:lemmy_api_client/v3.dart'; -import 'package:swipeable_page_route/swipeable_page_route.dart'; -import 'package:flutter_gen/gen_l10n/app_localizations.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'; -import 'package:thunder/instance/pages/instance_page.dart'; -import 'package:thunder/shared/pages/loading_page.dart'; -import 'package:thunder/shared/snackbar.dart'; -import 'package:thunder/thunder/bloc/thunder_bloc.dart'; -import 'package:thunder/utils/links.dart'; - -Future navigateToInstancePage(BuildContext context, {required String instanceHost, required int? instanceId}) async { - showLoadingPage(context); - - final AppLocalizations l10n = AppLocalizations.of(context)!; - final ThunderBloc thunderBloc = context.read(); - final bool reduceAnimations = thunderBloc.state.reduceAnimations; - final Account? account = await fetchActiveProfileAccount(); - - GetSiteResponse? getSiteResponse; - bool? isBlocked; - - try { - getSiteResponse = await LemmyApiV3(instanceHost).run(const GetSite()).timeout(const Duration(seconds: 5)); - - // Check whether this instance is blocked (we have to get our user from our current site first). - final GetSiteResponse localSite = await LemmyClient.instance.lemmyApiV3.run(GetSite(auth: account?.jwt)).timeout(const Duration(seconds: 5)); - isBlocked = localSite.myUser?.instanceBlocks?.any((i) => i.instance.domain == instanceHost) == true; - } catch (e) { - // Continue if we can't get the site - } - - if (context.mounted) { - if (getSiteResponse?.siteView.site != null) { - pushOnTopOfLoadingPage( - context, - SwipeablePageRoute( - transitionDuration: isLoadingPageShown - ? Duration.zero - : reduceAnimations - ? const Duration(milliseconds: 100) - : null, - reverseTransitionDuration: reduceAnimations ? const Duration(milliseconds: 100) : const Duration(milliseconds: 500), - backGestureDetectionWidth: 45, - canSwipe: Platform.isIOS || thunderBloc.state.enableFullScreenSwipeNavigationGesture, - canOnlySwipeFromEdge: !thunderBloc.state.enableFullScreenSwipeNavigationGesture, - builder: (context) => MultiBlocProvider( - providers: [ - BlocProvider.value(value: thunderBloc), - ], - child: InstancePage( - getSiteResponse: getSiteResponse!, - isBlocked: isBlocked, - instanceId: instanceId, - ), - ), - ), - ); - } else { - showSnackbar( - l10n.unableToNavigateToInstance(instanceHost), - trailingAction: () => handleLink(context, url: "https://$instanceHost", forceOpenInBrowser: true), - trailingIcon: Icons.open_in_browser_rounded, - ); - hideLoadingPage(context); - } - } -} diff --git a/lib/instance/widgets/instance_action_bottom_sheet.dart b/lib/instance/widgets/instance_action_bottom_sheet.dart index 42deebe68..fd6f6b684 100644 --- a/lib/instance/widgets/instance_action_bottom_sheet.dart +++ b/lib/instance/widgets/instance_action_bottom_sheet.dart @@ -5,7 +5,7 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:thunder/core/auth/bloc/auth_bloc.dart'; import 'package:thunder/instance/bloc/instance_bloc.dart'; import 'package:thunder/instance/enums/instance_action.dart'; -import 'package:thunder/instance/utils/navigate_instance.dart'; +import 'package:thunder/utils/navigation.dart'; import 'package:thunder/post/enums/post_action.dart'; import 'package:thunder/shared/bottom_sheet_action.dart'; import 'package:thunder/utils/global_context.dart'; diff --git a/lib/instance/widgets/instance_list_entry.dart b/lib/instance/widgets/instance_list_entry.dart index cc59ca0b5..5432d037b 100644 --- a/lib/instance/widgets/instance_list_entry.dart +++ b/lib/instance/widgets/instance_list_entry.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:thunder/instance/utils/navigate_instance.dart'; +import 'package:thunder/utils/navigation.dart'; import 'package:thunder/shared/avatars/instance_avatar.dart'; import 'package:thunder/utils/instance.dart'; import 'package:thunder/utils/numbers.dart'; diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index fb94439d0..4cd46f972 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -2157,10 +2157,34 @@ "@settingsPageAccount": { "description": "Account settings page" }, + "settingsPageAccountBlocks": "Blocklists", + "@settingsPageAccountBlocks": { + "description": "Account blocklist (user/community/instance) page" + }, + "settingsPageAccountLanguages": "Discussion Languages", + "@settingsPageAccountLanguages": { + "description": "Account discussion languages page" + }, + "settingsPageAccountMedia": "Manage Media", + "@settingsPageAccountMedia": { + "description": "Account manage media page" + }, "settingsPageAppearance": "Appearance", "@settingsPageAppearance": { "description": "Appearance settings page" }, + "settingsPageAppearanceComments": "Comments", + "@settingsPageAppearanceComments": { + "description": "Theming comments page" + }, + "settingsPageAppearancePosts": "Posts", + "@settingsPageAppearancePosts": { + "description": "Theming posts page" + }, + "settingsPageAppearanceTheming": "Theming", + "@settingsPageAppearanceTheming": { + "description": "Theming settings page" + }, "settingsPageDebug": "Debug", "@settingsPageDebug": { "description": "Debug settings page" diff --git a/lib/moderator/view/report_page.dart b/lib/moderator/view/report_page.dart index 38d921e22..f4c03a2e3 100644 --- a/lib/moderator/view/report_page.dart +++ b/lib/moderator/view/report_page.dart @@ -18,7 +18,7 @@ import 'package:thunder/feed/feed.dart'; import 'package:thunder/moderator/bloc/report_bloc.dart'; import 'package:thunder/moderator/enums/report_action.dart'; import 'package:thunder/moderator/widgets/report_page_filter_bottom_sheet.dart'; -import 'package:thunder/post/utils/navigate_post.dart'; +import 'package:thunder/utils/navigation.dart'; import 'package:thunder/shared/comment_reference.dart'; import 'package:thunder/shared/full_name_widgets.dart'; import 'package:thunder/shared/snackbar.dart'; diff --git a/lib/modlog/utils/navigate_modlog.dart b/lib/modlog/utils/navigate_modlog.dart deleted file mode 100644 index 9ef903151..000000000 --- a/lib/modlog/utils/navigate_modlog.dart +++ /dev/null @@ -1,62 +0,0 @@ -import 'dart:io'; - -import 'package:flutter/foundation.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:lemmy_api_client/v3.dart'; -import 'package:swipeable_page_route/swipeable_page_route.dart'; -import 'package:thunder/core/auth/bloc/auth_bloc.dart'; -import 'package:thunder/core/singletons/lemmy_client.dart'; -import 'package:thunder/feed/bloc/feed_bloc.dart'; -import 'package:thunder/modlog/view/modlog_page.dart'; -import 'package:thunder/thunder/bloc/thunder_bloc.dart'; -import 'package:thunder/utils/swipe.dart'; - -Future navigateToModlogPage( - BuildContext context, { - FeedBloc? feedBloc, - ModlogActionType? modlogActionType, - int? communityId, - int? userId, - int? moderatorId, - int? commentId, - LemmyClient? lemmyClient, - Widget? subtitle, -}) async { - final ThunderBloc thunderBloc = context.read(); - final bool reduceAnimations = thunderBloc.state.reduceAnimations; - - bool canSwipe = true; - bool canOnlySwipeFromEdge = true; - try { - AuthBloc authBloc = context.read(); - canSwipe = Platform.isIOS || thunderBloc.state.enableFullScreenSwipeNavigationGesture; - canOnlySwipeFromEdge = disableFullPageSwipe(isUserLoggedIn: authBloc.state.isLoggedIn, state: thunderBloc.state, isPostPage: false) || !thunderBloc.state.enableFullScreenSwipeNavigationGesture; - } catch (e) { - // Continue with default values - } - - await Navigator.of(context).push( - SwipeablePageRoute( - transitionDuration: reduceAnimations ? const Duration(milliseconds: 100) : null, - backGestureDetectionStartOffset: !kIsWeb && Platform.isAndroid ? 45 : 0, - canSwipe: canSwipe, - canOnlySwipeFromEdge: canOnlySwipeFromEdge, - builder: (context) => MultiBlocProvider( - providers: [ - if (feedBloc != null) BlocProvider.value(value: feedBloc), - BlocProvider.value(value: thunderBloc), - ], - child: ModlogFeedPage( - modlogActionType: modlogActionType, - communityId: communityId, - userId: userId, - moderatorId: moderatorId, - commentId: commentId, - lemmyClient: lemmyClient, - subtitle: subtitle, - ), - ), - ), - ); -} diff --git a/lib/modlog/widgets/modlog_item_context_card.dart b/lib/modlog/widgets/modlog_item_context_card.dart index 88f00c42e..44a3f299a 100644 --- a/lib/modlog/widgets/modlog_item_context_card.dart +++ b/lib/modlog/widgets/modlog_item_context_card.dart @@ -6,9 +6,8 @@ import 'package:html_unescape/html_unescape_small.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:thunder/core/enums/font_scale.dart'; -import 'package:thunder/feed/utils/utils.dart'; import 'package:thunder/feed/view/feed_page.dart'; -import 'package:thunder/post/utils/navigate_post.dart'; +import 'package:thunder/utils/navigation.dart'; import 'package:thunder/shared/avatars/community_avatar.dart'; import 'package:thunder/shared/avatars/user_avatar.dart'; import 'package:thunder/shared/common_markdown_body.dart'; diff --git a/lib/notification/utils/navigate_notification.dart b/lib/notification/utils/navigate_notification.dart deleted file mode 100644 index 53146fd25..000000000 --- a/lib/notification/utils/navigate_notification.dart +++ /dev/null @@ -1,110 +0,0 @@ -// Flutter imports -import 'dart:io'; - -import 'package:flutter/material.dart'; - -// Package imports -import 'package:collection/collection.dart'; -import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:lemmy_api_client/v3.dart'; -import 'package:swipeable_page_route/swipeable_page_route.dart'; - -// Project imports -import 'package:thunder/account/models/account.dart'; -import 'package:thunder/core/auth/bloc/auth_bloc.dart'; -import 'package:thunder/core/auth/helpers/fetch_account.dart'; -import 'package:thunder/core/singletons/lemmy_client.dart'; -import 'package:thunder/inbox/bloc/inbox_bloc.dart'; -import 'package:thunder/inbox/enums/inbox_type.dart'; -import 'package:thunder/shared/pages/loading_page.dart'; -import 'package:thunder/thunder/bloc/thunder_bloc.dart'; -import 'package:thunder/thunder/pages/notifications_pages.dart'; - -void navigateToNotificationReplyPage(BuildContext context, {required int? replyId, required String? accountId}) async { - // It can take a little while to set up notifications, so show a loading page - showLoadingPage(context); - - final ThunderBloc thunderBloc = context.read(); - final bool reduceAnimations = thunderBloc.state.reduceAnimations; - Account? account = await fetchActiveProfileAccount(); - - bool switchedAccount = false; - String? originalAccount = account?.id; - String? originalAnonymousInstance = context.mounted ? context.read().state.currentAnonymousInstance : null; - - if (account?.id != accountId && accountId != null && context.mounted) { - // Switch to the notification's account without reloading the app - context.read().add(SwitchAccount(accountId: accountId, reload: false)); - - // Set the account locally here so we don't have to wait for the event to complete - account = await Account.fetchAccount(accountId); - - // Note that we switched so we can switch back - switchedAccount = true; - } - - // If account is still null, we can't do anything. - if (account == null) return; - - List allReplies = []; - CommentReplyView? specificReply; - - bool doneFetching = false; - int currentPage = 1; - - // Load the notifications - while (!doneFetching) { - final GetRepliesResponse getRepliesResponse = await (LemmyClient()..changeBaseUrl(account.instance)).lemmyApiV3.run(GetReplies( - sort: CommentSortType.new_, - page: currentPage, - limit: 50, - unreadOnly: replyId == null, - auth: account.jwt, - )); - - allReplies.addAll(getRepliesResponse.replies); - specificReply ??= getRepliesResponse.replies.firstWhereOrNull((crv) => crv.commentReply.id == replyId); - - doneFetching = specificReply != null || getRepliesResponse.replies.isEmpty; - ++currentPage; - } - - if (context.mounted) { - final NotificationsReplyPage notificationsReplyPage = NotificationsReplyPage(replies: specificReply == null ? allReplies : [specificReply]); - - final SwipeablePageRoute route = SwipeablePageRoute( - transitionDuration: isLoadingPageShown - ? Duration.zero - : reduceAnimations - ? const Duration(milliseconds: 100) - : null, - reverseTransitionDuration: reduceAnimations ? const Duration(milliseconds: 100) : const Duration(milliseconds: 500), - backGestureDetectionWidth: 45, - canSwipe: Platform.isIOS || thunderBloc.state.enableFullScreenSwipeNavigationGesture, - canOnlySwipeFromEdge: !thunderBloc.state.enableFullScreenSwipeNavigationGesture, - builder: (context) => MultiBlocProvider( - providers: [ - BlocProvider.value(value: thunderBloc), - ], - child: notificationsReplyPage, - ), - ); - - pushOnTopOfLoadingPage(context, route).then((_) { - // If needed, switch back to the original account or anonymous instance - if (switchedAccount) { - if (originalAccount != null) { - // We switched from an account, so switch back - context.read().add(SwitchAccount(accountId: originalAccount, reload: false)); - } else if (originalAnonymousInstance != null) { - // We switched from anonymous, so switch back - context.read().add(const LogOutOfAllAccounts()); - context.read().add(OnSetCurrentAnonymousInstance(originalAnonymousInstance)); - context.read().add(InstanceChanged(instance: originalAnonymousInstance)); - } - } - - context.read().add(const GetInboxEvent(reset: true, inboxType: InboxType.all)); - }); - } -} diff --git a/lib/post/pages/legacy_post_page.dart b/lib/post/pages/legacy_post_page.dart index 5546c3d60..269815399 100644 --- a/lib/post/pages/legacy_post_page.dart +++ b/lib/post/pages/legacy_post_page.dart @@ -13,7 +13,7 @@ import 'package:lemmy_api_client/v3.dart'; import 'package:super_sliver_list/super_sliver_list.dart'; // Project imports -import 'package:thunder/comment/utils/navigate_comment.dart'; +import 'package:thunder/utils/navigation.dart'; import 'package:thunder/core/auth/bloc/auth_bloc.dart'; import 'package:thunder/core/enums/fab_action.dart'; import 'package:thunder/core/enums/media_type.dart'; diff --git a/lib/post/pages/post_page.dart b/lib/post/pages/post_page.dart index 56f9fe74e..b990e727d 100644 --- a/lib/post/pages/post_page.dart +++ b/lib/post/pages/post_page.dart @@ -9,7 +9,7 @@ import 'package:super_sliver_list/super_sliver_list.dart'; import 'package:thunder/account/models/account.dart'; import 'package:thunder/comment/enums/comment_action.dart'; import 'package:thunder/comment/models/comment_node.dart'; -import 'package:thunder/comment/utils/navigate_comment.dart'; +import 'package:thunder/utils/navigation.dart'; import 'package:thunder/comment/widgets/comment_card.dart'; import 'package:thunder/core/auth/bloc/auth_bloc.dart'; import 'package:thunder/core/models/post_view_media.dart'; diff --git a/lib/post/pages/post_page_success.dart b/lib/post/pages/post_page_success.dart index 08b121ebf..31c376ca4 100644 --- a/lib/post/pages/post_page_success.dart +++ b/lib/post/pages/post_page_success.dart @@ -7,7 +7,7 @@ import 'package:lemmy_api_client/v3.dart'; import 'package:super_sliver_list/super_sliver_list.dart'; // Project imports -import 'package:thunder/comment/utils/navigate_comment.dart'; +import 'package:thunder/utils/navigation.dart'; import 'package:thunder/core/models/comment_view_tree.dart'; import 'package:thunder/core/models/post_view_media.dart'; import 'package:thunder/post/bloc/post_bloc.dart'; diff --git a/lib/post/utils/comment_actions.dart b/lib/post/utils/comment_actions.dart index 96451f5cc..1a64fce89 100644 --- a/lib/post/utils/comment_actions.dart +++ b/lib/post/utils/comment_actions.dart @@ -7,7 +7,7 @@ import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:lemmy_api_client/v3.dart'; // Project imports -import 'package:thunder/comment/utils/navigate_comment.dart'; +import 'package:thunder/utils/navigation.dart'; import 'package:thunder/core/auth/bloc/auth_bloc.dart'; import 'package:thunder/core/enums/swipe_action.dart'; import 'package:thunder/shared/snackbar.dart'; diff --git a/lib/post/utils/navigate_create_post.dart b/lib/post/utils/navigate_create_post.dart deleted file mode 100644 index 2a0808435..000000000 --- a/lib/post/utils/navigate_create_post.dart +++ /dev/null @@ -1,88 +0,0 @@ -import 'dart:io'; - -import 'package:flutter/material.dart'; -import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:lemmy_api_client/v3.dart'; -import 'package:swipeable_page_route/swipeable_page_route.dart'; -import 'package:thunder/account/bloc/account_bloc.dart'; -import 'package:thunder/community/pages/create_post_page.dart'; -import 'package:thunder/core/models/post_view_media.dart'; -import 'package:thunder/core/singletons/lemmy_client.dart'; -import 'package:thunder/feed/feed.dart'; -import 'package:thunder/post/cubit/create_post_cubit.dart'; -import 'package:thunder/post/utils/navigate_post.dart'; -import 'package:thunder/shared/snackbar.dart'; -import 'package:thunder/thunder/thunder.dart'; -import 'package:flutter_gen/gen_l10n/app_localizations.dart'; - -Future navigateToCreatePostPage( - BuildContext context, { - String? title, - String? text, - File? image, - String? url, - bool? prePopulated, - int? communityId, - CommunityView? communityView, -}) async { - try { - final l10n = AppLocalizations.of(context)!; - - FeedBloc? feedBloc; - ThunderBloc thunderBloc = context.read(); - AccountBloc accountBloc = context.read(); - CreatePostCubit createPostCubit = CreatePostCubit(); - - try { - feedBloc = context.read(); - } catch (e) { - // Don't need feed block if we're not opening post in the context of a feed. - } - - final bool reduceAnimations = thunderBloc.state.reduceAnimations; - - await Navigator.of(context).push(SwipeablePageRoute( - transitionDuration: reduceAnimations ? const Duration(milliseconds: 100) : null, - canOnlySwipeFromEdge: true, - backGestureDetectionWidth: 45, - builder: (navigatorContext) { - return MultiBlocProvider( - providers: [ - feedBloc != null ? BlocProvider.value(value: feedBloc) : BlocProvider(create: (context) => FeedBloc(lemmyClient: LemmyClient.instance)), - BlocProvider.value(value: thunderBloc), - BlocProvider.value(value: accountBloc), - BlocProvider.value(value: createPostCubit), - ], - child: CreatePostPage( - title: title, - text: text, - image: image, - url: url, - prePopulated: prePopulated, - communityId: communityId, - communityView: communityView, - onPostSuccess: (PostViewMedia postViewMedia, bool userChanged) { - if (!userChanged) { - try { - showSnackbar( - l10n.postCreatedSuccessfully, - trailingIcon: Icons.remove_red_eye_rounded, - trailingAction: () { - navigateToPost(context, postViewMedia: postViewMedia); - }, - ); - - if (feedBloc != null) feedBloc.add(FeedItemUpdatedEvent(postViewMedia: postViewMedia)); - } catch (e) { - if (context.mounted) showSnackbar("${AppLocalizations.of(context)!.unexpectedError}: $e"); - } - } - }, - ), - ); - }, - )); - } catch (e) { - if (context.mounted) showSnackbar(AppLocalizations.of(context)!.unexpectedError); - } -} diff --git a/lib/post/utils/navigate_post.dart b/lib/post/utils/navigate_post.dart deleted file mode 100644 index b75a31626..000000000 --- a/lib/post/utils/navigate_post.dart +++ /dev/null @@ -1,119 +0,0 @@ -import 'dart:io'; - -import 'package:flutter/foundation.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:shared_preferences/shared_preferences.dart'; -import 'package:swipeable_page_route/swipeable_page_route.dart'; -import 'package:thunder/account/bloc/account_bloc.dart'; -import 'package:thunder/community/bloc/anonymous_subscriptions_bloc.dart'; -import 'package:thunder/community/bloc/community_bloc.dart'; -import 'package:thunder/core/auth/bloc/auth_bloc.dart'; -import 'package:thunder/core/enums/local_settings.dart'; -import 'package:thunder/core/models/post_view_media.dart'; -import 'package:thunder/core/singletons/preferences.dart'; -import 'package:thunder/feed/bloc/feed_bloc.dart'; -import 'package:thunder/instance/bloc/instance_bloc.dart'; -import 'package:thunder/post/enums/post_action.dart'; -import 'package:thunder/post/pages/legacy_post_page.dart' as legacy_post_page; -import 'package:thunder/post/pages/post_page.dart'; -import 'package:thunder/shared/pages/loading_page.dart'; -import 'package:thunder/thunder/bloc/thunder_bloc.dart'; -import 'package:thunder/utils/swipe.dart'; -import 'package:thunder/post/bloc/post_bloc.dart' as post_bloc; - -Future navigateToPost(BuildContext context, {PostViewMedia? postViewMedia, int? selectedCommentId, String? selectedCommentPath, int? postId, Function(PostViewMedia)? onPostUpdated}) async { - SharedPreferences prefs = (await UserPreferences.instance).sharedPreferences; - - AccountBloc accountBloc = context.read(); - AuthBloc authBloc = context.read(); - ThunderBloc thunderBloc = context.read(); - InstanceBloc instanceBloc = context.read(); - - CommunityBloc? communityBloc; - try { - communityBloc = context.read(); - } catch (e) { - // Ignore exceptions - } - - AnonymousSubscriptionsBloc? anonymousSubscriptionsBloc; - try { - anonymousSubscriptionsBloc = context.read(); - } catch (e) { - // Ignore exceptions - } - - FeedBloc? feedBloc; - try { - feedBloc = context.read(); - } catch (e) { - // Don't need feed block if we're not opening post in the context of a feed. - } - - final ThunderState state = context.read().state; - final bool reduceAnimations = state.reduceAnimations; - - // Mark post as read when tapped - if (authBloc.state.isLoggedIn) { - feedBloc?.add(FeedItemActionedEvent(postId: postViewMedia?.postView.post.id ?? postId, postAction: PostAction.read, value: true)); - } - - bool enableExperimentalFeatures = prefs.getBool(LocalSettings.enableExperimentalFeatures.name) ?? false; - - final SwipeablePageRoute route = SwipeablePageRoute( - transitionDuration: isLoadingPageShown - ? Duration.zero - : reduceAnimations - ? const Duration(milliseconds: 100) - : null, - reverseTransitionDuration: reduceAnimations ? const Duration(milliseconds: 100) : const Duration(milliseconds: 500), - backGestureDetectionStartOffset: !kIsWeb && Platform.isAndroid ? 45 : 0, - backGestureDetectionWidth: 45, - canSwipe: Platform.isIOS || thunderBloc.state.enableFullScreenSwipeNavigationGesture, - canOnlySwipeFromEdge: disableFullPageSwipe(isUserLoggedIn: authBloc.state.isLoggedIn, state: thunderBloc.state, isPostPage: true) || !thunderBloc.state.enableFullScreenSwipeNavigationGesture, - builder: (otherContext) { - return MultiBlocProvider( - providers: [ - BlocProvider.value(value: accountBloc), - BlocProvider.value(value: authBloc), - BlocProvider.value(value: thunderBloc), - BlocProvider.value(value: instanceBloc), - BlocProvider(create: (context) => post_bloc.PostBloc()), - if (communityBloc != null) BlocProvider.value(value: communityBloc), - if (anonymousSubscriptionsBloc != null) BlocProvider.value(value: anonymousSubscriptionsBloc), - ], - child: enableExperimentalFeatures - ? PostPage( - initialPostViewMedia: postViewMedia!, - onPostUpdated: (PostViewMedia postViewMedia) { - FeedBloc? feedBloc; - try { - feedBloc = context.read(); - } catch (e) { - // Don't need feed block if we're not opening post in the context of a feed. - } - // Manually marking the read attribute as true when navigating to post since there is a case where the API call to mark the post as read from the feed page is not completed in time - feedBloc?.add(FeedItemUpdatedEvent(postViewMedia: PostViewMedia(postView: postViewMedia.postView.copyWith(read: true), media: postViewMedia.media))); - }, - ) - : legacy_post_page.PostPage( - postView: postViewMedia, - postId: postId, - selectedCommentId: selectedCommentId, - selectedCommentPath: selectedCommentPath, - onPostUpdated: (PostViewMedia postViewMedia) { - FeedBloc? feedBloc; - try { - feedBloc = context.read(); - } catch (e) {} - // Manually marking the read attribute as true when navigating to post since there is a case where the API call to mark the post as read from the feed page is not completed in time - feedBloc?.add(FeedItemUpdatedEvent(postViewMedia: PostViewMedia(postView: postViewMedia.postView.copyWith(read: true), media: postViewMedia.media))); - }, - ), - ); - }, - ); - - pushOnTopOfLoadingPage(context, route); -} diff --git a/lib/post/widgets/community_post_action_bottom_sheet.dart b/lib/post/widgets/community_post_action_bottom_sheet.dart index ca1156831..5284dcaad 100644 --- a/lib/post/widgets/community_post_action_bottom_sheet.dart +++ b/lib/post/widgets/community_post_action_bottom_sheet.dart @@ -13,6 +13,7 @@ import 'package:thunder/post/widgets/post_action_bottom_sheet.dart'; import 'package:thunder/shared/bottom_sheet_action.dart'; import 'package:thunder/shared/divider.dart'; import 'package:thunder/thunder/thunder_icons.dart'; +import 'package:thunder/utils/navigation.dart'; /// Defines the actions that can be taken on a community enum CommunityPostAction { diff --git a/lib/post/widgets/post_post_action_bottom_sheet.dart b/lib/post/widgets/post_post_action_bottom_sheet.dart index fe6bbfea9..fb7e285a5 100644 --- a/lib/post/widgets/post_post_action_bottom_sheet.dart +++ b/lib/post/widgets/post_post_action_bottom_sheet.dart @@ -1,22 +1,17 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:lemmy_api_client/v3.dart'; -import 'package:swipeable_page_route/swipeable_page_route.dart'; -import 'package:thunder/account/bloc/account_bloc.dart'; -import 'package:thunder/community/pages/create_post_page.dart'; import 'package:thunder/core/auth/bloc/auth_bloc.dart'; import 'package:thunder/core/models/post_view_media.dart'; import 'package:thunder/feed/bloc/feed_bloc.dart'; -import 'package:thunder/post/cubit/create_post_cubit.dart'; import 'package:thunder/post/enums/post_action.dart'; import 'package:thunder/shared/bottom_sheet_action.dart'; import 'package:thunder/shared/dialogs.dart'; import 'package:thunder/shared/divider.dart'; -import 'package:thunder/thunder/bloc/thunder_bloc.dart'; import 'package:thunder/thunder/thunder_icons.dart'; import 'package:thunder/utils/global_context.dart'; +import 'package:thunder/utils/navigation.dart'; /// Defines the actions that can be taken on a user /// TODO: Implement admin-level actions @@ -92,53 +87,7 @@ class _PostPostActionBottomSheetState extends State { return; case PostPostAction.editPost: Navigator.of(context).pop(); - - ThunderBloc thunderBloc = context.read(); - AccountBloc accountBloc = context.read(); - CreatePostCubit createPostCubit = CreatePostCubit(); - - final ThunderState thunderState = context.read().state; - final bool reduceAnimations = thunderState.reduceAnimations; - - Navigator.of(widget.context).push( - SwipeablePageRoute( - transitionDuration: reduceAnimations ? const Duration(milliseconds: 100) : null, - canOnlySwipeFromEdge: true, - backGestureDetectionWidth: 45, - builder: (context) { - return MultiBlocProvider( - providers: [ - BlocProvider.value(value: thunderBloc), - BlocProvider.value(value: accountBloc), - BlocProvider.value(value: createPostCubit), - ], - child: CreatePostPage( - communityId: postViewMedia.postView.community.id, - // Create a stub for the community view. - communityView: CommunityView( - community: postViewMedia.postView.community, - subscribed: postViewMedia.postView.subscribed, - blocked: false, - counts: CommunityAggregates( - communityId: postViewMedia.postView.community.id, - subscribers: 0, - posts: 0, - comments: 0, - published: DateTime.now(), - usersActiveDay: 0, - usersActiveWeek: 0, - usersActiveMonth: 0, - usersActiveHalfYear: 0, - ), - ), - postView: postViewMedia.postView, - onPostSuccess: (PostViewMedia pvm, _) {}, - ), - ); - }, - ), - ); - + navigateToCreatePostPage(context, communityId: postViewMedia.postView.community.id, postViewMedia: postViewMedia); return; case PostPostAction.deletePost: Navigator.of(context).pop(); diff --git a/lib/post/widgets/post_view.dart b/lib/post/widgets/post_view.dart index 3211d19e9..48ebcf1c9 100644 --- a/lib/post/widgets/post_view.dart +++ b/lib/post/widgets/post_view.dart @@ -11,14 +11,11 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:html_unescape/html_unescape_small.dart'; import 'package:lemmy_api_client/v3.dart'; -import 'package:swipeable_page_route/swipeable_page_route.dart'; // Project imports -import 'package:thunder/account/bloc/account_bloc.dart'; import 'package:thunder/account/models/account.dart'; -import 'package:thunder/comment/utils/navigate_comment.dart'; +import 'package:thunder/utils/navigation.dart'; import 'package:thunder/community/enums/community_action.dart'; -import 'package:thunder/community/pages/create_post_page.dart'; import 'package:thunder/feed/bloc/feed_bloc.dart'; import 'package:thunder/post/enums/post_action.dart'; import 'package:thunder/post/widgets/general_post_action_bottom_sheet.dart'; @@ -33,7 +30,6 @@ import 'package:thunder/core/enums/view_mode.dart'; import 'package:thunder/core/models/post_view_media.dart'; import 'package:thunder/core/singletons/lemmy_client.dart'; import 'package:thunder/post/bloc/post_bloc.dart'; -import 'package:thunder/post/cubit/create_post_cubit.dart'; import 'package:thunder/post/widgets/post_metadata.dart'; import 'package:thunder/post/widgets/post_quick_actions_bar.dart'; import 'package:thunder/shared/avatars/community_avatar.dart'; @@ -346,45 +342,21 @@ class _PostSubviewState extends State with SingleTickerProviderStat ); }, onEdit: () async { - ThunderBloc thunderBloc = context.read(); - AccountBloc accountBloc = context.read(); - CreatePostCubit createPostCubit = CreatePostCubit(); - - final ThunderState thunderState = context.read().state; - final bool reduceAnimations = thunderState.reduceAnimations; - final Account? account = await fetchActiveProfileAccount(); final GetCommunityResponse getCommunityResponse = await LemmyClient.instance.lemmyApiV3.run(GetCommunity( auth: account?.jwt, id: postViewMedia.postView.community.id, )); - if (context.mounted) { - Navigator.of(context).push( - SwipeablePageRoute( - transitionDuration: reduceAnimations ? const Duration(milliseconds: 100) : null, - canOnlySwipeFromEdge: true, - backGestureDetectionWidth: 45, - builder: (context) { - return MultiBlocProvider( - providers: [ - BlocProvider.value(value: thunderBloc), - BlocProvider.value(value: accountBloc), - BlocProvider.value(value: createPostCubit), - ], - child: CreatePostPage( - communityId: postViewMedia.postView.community.id, - communityView: getCommunityResponse.communityView, - postView: postViewMedia.postView, - onPostSuccess: (PostViewMedia pvm, _) { - setState(() => postViewMedia = pvm); - }, - ), - ); - }, - ), - ); - } + navigateToCreatePostPage( + context, + communityId: postView.community.id, + communityView: getCommunityResponse.communityView, + postViewMedia: postViewMedia, + onPostSuccess: (PostViewMedia pvm, _) { + setState(() => postViewMedia = pvm); + }, + ); }, onReply: () async => navigateToCreateCommentPage( context, diff --git a/lib/search/pages/search_page.dart b/lib/search/pages/search_page.dart index 4689a42c7..9e1b43e76 100644 --- a/lib/search/pages/search_page.dart +++ b/lib/search/pages/search_page.dart @@ -25,7 +25,7 @@ import 'package:thunder/core/singletons/lemmy_client.dart'; import 'package:thunder/core/singletons/preferences.dart'; import 'package:thunder/feed/bloc/feed_bloc.dart'; import 'package:thunder/feed/widgets/feed_post_card_list.dart'; -import 'package:thunder/instance/utils/navigate_instance.dart'; +import 'package:thunder/utils/navigation.dart'; import 'package:thunder/instance/widgets/instance_list_entry.dart'; import 'package:thunder/search/bloc/search_bloc.dart'; import 'package:thunder/search/widgets/search_action_chip.dart'; diff --git a/lib/settings/pages/about_settings_page.dart b/lib/settings/pages/about_settings_page.dart index 166a56b59..8210d2096 100644 --- a/lib/settings/pages/about_settings_page.dart +++ b/lib/settings/pages/about_settings_page.dart @@ -1,11 +1,11 @@ import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; -import 'package:thunder/feed/utils/utils.dart'; import 'package:thunder/feed/view/feed_page.dart'; import 'package:thunder/utils/links.dart'; import 'package:thunder/core/enums/local_settings.dart'; import 'package:thunder/core/update/check_github_update.dart'; +import 'package:thunder/utils/navigation.dart'; class AboutSettingsPage extends StatelessWidget { final LocalSettings? settingToHighlight; diff --git a/lib/settings/pages/appearance_settings_page.dart b/lib/settings/pages/appearance_settings_page.dart index 9d690af8c..1a7daa124 100644 --- a/lib/settings/pages/appearance_settings_page.dart +++ b/lib/settings/pages/appearance_settings_page.dart @@ -1,17 +1,10 @@ -import 'dart:io'; - import 'package:flutter/material.dart'; -import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; -import 'package:swipeable_page_route/swipeable_page_route.dart'; + import 'package:thunder/core/enums/local_settings.dart'; -import 'package:thunder/settings/pages/comment_appearance_settings_page.dart'; -import 'package:thunder/settings/pages/post_appearance_settings_page.dart'; -import 'package:thunder/settings/pages/theme_settings_page.dart'; import 'package:thunder/shared/divider.dart'; - -import 'package:thunder/thunder/bloc/thunder_bloc.dart'; +import 'package:thunder/utils/navigation.dart'; class AppearanceSettingsPage extends StatelessWidget { final LocalSettings? settingToHighlight; @@ -39,21 +32,7 @@ class AppearanceSettingsPage extends StatelessWidget { title: Text(l10n.theming), leading: const Icon(Icons.text_fields), trailing: const Icon(Icons.chevron_right_rounded), - onTap: () { - final ThunderBloc thunderBloc = context.read(); - - Navigator.of(context).push( - SwipeablePageRoute( - transitionDuration: thunderBloc.state.reduceAnimations ? const Duration(milliseconds: 100) : null, - canSwipe: Platform.isIOS || thunderBloc.state.enableFullScreenSwipeNavigationGesture, - canOnlySwipeFromEdge: !thunderBloc.state.enableFullScreenSwipeNavigationGesture, - builder: (context) => MultiBlocProvider( - providers: [BlocProvider.value(value: thunderBloc)], - child: const ThemeSettingsPage(), - ), - ), - ); - }, + onTap: () => navigateToSettingPage(context, LocalSettings.settingsPageAppearanceTheming), ), ], ), @@ -66,41 +45,13 @@ class AppearanceSettingsPage extends StatelessWidget { title: Text(l10n.posts), leading: const Icon(Icons.splitscreen_rounded), trailing: const Icon(Icons.chevron_right_rounded), - onTap: () { - final ThunderBloc thunderBloc = context.read(); - - Navigator.of(context).push( - SwipeablePageRoute( - transitionDuration: thunderBloc.state.reduceAnimations ? const Duration(milliseconds: 100) : null, - canSwipe: Platform.isIOS || thunderBloc.state.enableFullScreenSwipeNavigationGesture, - canOnlySwipeFromEdge: !thunderBloc.state.enableFullScreenSwipeNavigationGesture, - builder: (context) => MultiBlocProvider( - providers: [BlocProvider.value(value: thunderBloc)], - child: const PostAppearanceSettingsPage(), - ), - ), - ); - }, + onTap: () => navigateToSettingPage(context, LocalSettings.settingsPageAppearancePosts), ), ListTile( title: Text(l10n.comments), leading: const Icon(Icons.comment_rounded), trailing: const Icon(Icons.chevron_right_rounded), - onTap: () { - final ThunderBloc thunderBloc = context.read(); - - Navigator.of(context).push( - SwipeablePageRoute( - transitionDuration: thunderBloc.state.reduceAnimations ? const Duration(milliseconds: 100) : null, - canSwipe: Platform.isIOS || thunderBloc.state.enableFullScreenSwipeNavigationGesture, - canOnlySwipeFromEdge: !thunderBloc.state.enableFullScreenSwipeNavigationGesture, - builder: (context) => MultiBlocProvider( - providers: [BlocProvider.value(value: thunderBloc)], - child: const CommentAppearanceSettingsPage(), - ), - ), - ); - }, + onTap: () => navigateToSettingPage(context, LocalSettings.settingsPageAppearanceComments), ), ], ), diff --git a/lib/settings/pages/comment_appearance_settings_page.dart b/lib/settings/pages/comment_appearance_settings_page.dart index b1fbaa1e5..5756d684a 100644 --- a/lib/settings/pages/comment_appearance_settings_page.dart +++ b/lib/settings/pages/comment_appearance_settings_page.dart @@ -1,5 +1,4 @@ import 'dart:async'; -import 'dart:io'; import 'package:flutter/material.dart'; @@ -7,7 +6,6 @@ import 'package:expandable/expandable.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:lemmy_api_client/v3.dart'; -import 'package:swipeable_page_route/swipeable_page_route.dart'; import 'package:thunder/core/enums/local_settings.dart'; import 'package:thunder/core/enums/nested_comment_indicator.dart'; @@ -15,7 +13,6 @@ import 'package:thunder/core/models/comment_view_tree.dart'; import 'package:thunder/core/singletons/preferences.dart'; import 'package:thunder/post/bloc/post_bloc.dart'; import 'package:thunder/post/widgets/comment_card.dart'; -import 'package:thunder/settings/pages/theme_settings_page.dart'; import 'package:thunder/settings/widgets/list_option.dart'; import 'package:thunder/settings/widgets/settings_list_tile.dart'; import 'package:thunder/settings/widgets/toggle_option.dart'; @@ -24,6 +21,7 @@ import 'package:thunder/thunder/bloc/thunder_bloc.dart'; import 'package:thunder/utils/bottom_sheet_list_picker.dart'; import 'package:thunder/comment/utils/comment.dart'; import 'package:thunder/utils/constants.dart'; +import 'package:thunder/utils/navigation.dart'; class CommentAppearanceSettingsPage extends StatefulWidget { final LocalSettings? settingToHighlight; @@ -411,21 +409,7 @@ class _CommentAppearanceSettingsPageState extends State(); - - Navigator.of(context).push( - SwipeablePageRoute( - transitionDuration: thunderBloc.state.reduceAnimations ? const Duration(milliseconds: 100) : null, - canSwipe: Platform.isIOS || thunderBloc.state.enableFullScreenSwipeNavigationGesture, - canOnlySwipeFromEdge: !thunderBloc.state.enableFullScreenSwipeNavigationGesture, - builder: (context) => MultiBlocProvider( - providers: [BlocProvider.value(value: thunderBloc)], - child: const ThemeSettingsPage(settingToHighlight: LocalSettings.userStyle), - ), - ), - ); - }, + onTap: () => navigateToSettingPage(context, LocalSettings.settingsPageAppearanceTheming, settingToHighlight: LocalSettings.userStyle), highlightKey: settingToHighlightKey, setting: null, highlightedSetting: settingToHighlight, diff --git a/lib/settings/pages/debug_settings_page.dart b/lib/settings/pages/debug_settings_page.dart index 56c11b56d..4fe8baa13 100644 --- a/lib/settings/pages/debug_settings_page.dart +++ b/lib/settings/pages/debug_settings_page.dart @@ -14,14 +14,12 @@ import 'package:path_provider/path_provider.dart'; import 'package:sqflite/sqflite.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; -import 'package:swipeable_page_route/swipeable_page_route.dart'; import 'package:thunder/core/enums/local_settings.dart'; import 'package:thunder/core/singletons/preferences.dart'; import 'package:thunder/notification/enums/notification_type.dart'; import 'package:thunder/notification/shared/android_notification.dart'; import 'package:thunder/notification/shared/notification_server.dart'; import 'package:thunder/notification/utils/local_notifications.dart'; -import 'package:thunder/settings/pages/general_settings_page.dart'; import 'package:thunder/settings/widgets/list_option.dart'; import 'package:thunder/settings/widgets/toggle_option.dart'; @@ -33,6 +31,7 @@ import 'package:thunder/settings/widgets/settings_list_tile.dart'; import 'package:thunder/utils/bottom_sheet_list_picker.dart'; import 'package:thunder/utils/cache.dart'; import 'package:thunder/utils/constants.dart'; +import 'package:thunder/utils/navigation.dart'; import 'package:unifiedpush/unifiedpush.dart'; class DebugSettingsPage extends StatefulWidget { @@ -538,21 +537,7 @@ class _DebugSettingsPageState extends State { height: 42.0, child: Icon(Icons.chevron_right_rounded), ), - onTap: () { - final ThunderBloc thunderBloc = context.read(); - - Navigator.of(context).push( - SwipeablePageRoute( - transitionDuration: thunderBloc.state.reduceAnimations ? const Duration(milliseconds: 100) : null, - canSwipe: Platform.isIOS || thunderBloc.state.enableFullScreenSwipeNavigationGesture, - canOnlySwipeFromEdge: !thunderBloc.state.enableFullScreenSwipeNavigationGesture, - builder: (context) => MultiBlocProvider( - providers: [BlocProvider.value(value: thunderBloc)], - child: const GeneralSettingsPage(settingToHighlight: LocalSettings.inboxNotificationType), - ), - ), - ); - }, + onTap: () => navigateToSettingPage(context, LocalSettings.inboxNotificationType), highlightKey: settingToHighlightKey, setting: null, highlightedSetting: settingToHighlight, diff --git a/lib/settings/pages/filter_settings_page.dart b/lib/settings/pages/filter_settings_page.dart index bd754e3ae..8b9173655 100644 --- a/lib/settings/pages/filter_settings_page.dart +++ b/lib/settings/pages/filter_settings_page.dart @@ -1,12 +1,10 @@ import 'dart:async'; -import 'dart:io'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:smooth_highlight/smooth_highlight.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'; @@ -16,8 +14,7 @@ import 'package:thunder/settings/widgets/settings_list_tile.dart'; import 'package:thunder/shared/dialogs.dart'; import 'package:thunder/shared/input_dialogs.dart'; import 'package:thunder/thunder/bloc/thunder_bloc.dart'; -import 'package:thunder/user/bloc/user_settings_bloc.dart'; -import 'package:thunder/user/pages/user_settings_page.dart'; +import 'package:thunder/utils/navigation.dart'; class FilterSettingsPage extends StatefulWidget { final LocalSettings? settingToHighlight; @@ -201,25 +198,7 @@ class _FilterSettingsPageState extends State with SingleTick onTap: () { // Can only set discussion language if user is logged in if (authState.isLoggedIn && accountState.status == AccountStatus.success && accountState.personView != null) { - final AccountBloc accountBloc = context.read(); - final ThunderBloc thunderBloc = context.read(); - final UserSettingsBloc userSettingsBloc = UserSettingsBloc(); - - Navigator.of(context).push( - SwipeablePageRoute( - transitionDuration: thunderBloc.state.reduceAnimations ? const Duration(milliseconds: 100) : null, - canSwipe: Platform.isIOS || thunderBloc.state.enableFullScreenSwipeNavigationGesture, - canOnlySwipeFromEdge: !thunderBloc.state.enableFullScreenSwipeNavigationGesture, - builder: (context) => MultiBlocProvider( - providers: [ - BlocProvider.value(value: thunderBloc), - BlocProvider.value(value: accountBloc), - BlocProvider.value(value: userSettingsBloc), - ], - child: const UserSettingsPage(settingToHighlight: LocalSettings.discussionLanguages), - ), - ), - ); + navigateToSettingPage(context, LocalSettings.settingsPageAccountLanguages); } else { showThunderDialog( context: context, diff --git a/lib/settings/pages/general_settings_page.dart b/lib/settings/pages/general_settings_page.dart index dac80a31e..1d84b1220 100644 --- a/lib/settings/pages/general_settings_page.dart +++ b/lib/settings/pages/general_settings_page.dart @@ -11,8 +11,6 @@ import 'package:android_intent_plus/android_intent.dart'; import 'package:permission_handler/permission_handler.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; -import 'package:swipeable_page_route/swipeable_page_route.dart'; -import 'package:thunder/account/bloc/account_bloc.dart'; import 'package:thunder/account/models/account.dart'; import 'package:thunder/core/database/database.dart' hide Account; import 'package:thunder/core/enums/browser_mode.dart'; @@ -23,7 +21,6 @@ import 'package:thunder/notification/enums/notification_type.dart'; import 'package:thunder/core/singletons/lemmy_client.dart'; import 'package:thunder/core/singletons/preferences.dart'; import 'package:thunder/notification/utils/notification_settings.dart'; -import 'package:thunder/settings/pages/debug_settings_page.dart'; import 'package:thunder/settings/widgets/list_option.dart'; import 'package:thunder/settings/widgets/settings_list_tile.dart'; import 'package:thunder/settings/widgets/toggle_option.dart'; @@ -34,13 +31,12 @@ import 'package:thunder/shared/divider.dart'; import 'package:thunder/shared/snackbar.dart'; import 'package:thunder/shared/sort_picker.dart'; import 'package:thunder/thunder/bloc/thunder_bloc.dart'; -import 'package:thunder/user/bloc/user_settings_bloc.dart'; -import 'package:thunder/user/pages/user_settings_page.dart'; import 'package:thunder/utils/bottom_sheet_list_picker.dart'; import 'package:thunder/utils/constants.dart'; import 'package:thunder/utils/global_context.dart'; import 'package:thunder/utils/language/language.dart'; import 'package:thunder/utils/links.dart'; +import 'package:thunder/utils/navigation.dart'; import 'package:unifiedpush/unifiedpush.dart'; import 'package:version/version.dart'; @@ -446,27 +442,7 @@ class _GeneralSettingsPageState extends State with SingleTi height: 42.0, child: Icon(Icons.chevron_right_rounded), ), - onTap: () { - final AccountBloc accountBloc = context.read(); - final ThunderBloc thunderBloc = context.read(); - final UserSettingsBloc userSettingsBloc = UserSettingsBloc(); - - Navigator.of(context).push( - SwipeablePageRoute( - transitionDuration: thunderBloc.state.reduceAnimations ? const Duration(milliseconds: 100) : null, - canSwipe: Platform.isIOS || thunderBloc.state.enableFullScreenSwipeNavigationGesture, - canOnlySwipeFromEdge: !thunderBloc.state.enableFullScreenSwipeNavigationGesture, - builder: (context) => MultiBlocProvider( - providers: [ - BlocProvider.value(value: thunderBloc), - BlocProvider.value(value: accountBloc), - BlocProvider.value(value: userSettingsBloc), - ], - child: const UserSettingsPage(), - ), - ), - ); - }, + onTap: () => navigateToSettingPage(context, LocalSettings.settingsPageAccount), highlightKey: settingToHighlightKey, setting: null, highlightedSetting: settingToHighlight, @@ -1071,21 +1047,7 @@ class _GeneralSettingsPageState extends State with SingleTi height: 42.0, child: Icon(Icons.chevron_right_rounded), ), - onTap: () { - final ThunderBloc thunderBloc = context.read(); - - Navigator.of(context).push( - SwipeablePageRoute( - transitionDuration: thunderBloc.state.reduceAnimations ? const Duration(milliseconds: 100) : null, - canSwipe: Platform.isIOS || thunderBloc.state.enableFullScreenSwipeNavigationGesture, - canOnlySwipeFromEdge: !thunderBloc.state.enableFullScreenSwipeNavigationGesture, - builder: (context) => MultiBlocProvider( - providers: [BlocProvider.value(value: thunderBloc)], - child: const DebugSettingsPage(), - ), - ), - ); - }, + onTap: () => navigateToSettingPage(context, LocalSettings.settingsPageDebug), highlightKey: settingToHighlightKey, setting: null, highlightedSetting: settingToHighlight, diff --git a/lib/settings/pages/gesture_settings_page.dart b/lib/settings/pages/gesture_settings_page.dart index 82017a7a8..9d0c2e672 100644 --- a/lib/settings/pages/gesture_settings_page.dart +++ b/lib/settings/pages/gesture_settings_page.dart @@ -1,18 +1,16 @@ import 'dart:async'; -import 'dart:io'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; -import 'package:swipeable_page_route/swipeable_page_route.dart'; import 'package:thunder/core/enums/local_settings.dart'; import 'package:thunder/core/enums/swipe_action.dart'; import 'package:thunder/core/singletons/preferences.dart'; -import 'package:thunder/settings/pages/theme_settings_page.dart'; import 'package:thunder/settings/widgets/settings_list_tile.dart'; import 'package:thunder/settings/widgets/swipe_picker.dart'; import 'package:thunder/settings/widgets/toggle_option.dart'; import 'package:thunder/thunder/bloc/thunder_bloc.dart'; import 'package:thunder/utils/bottom_sheet_list_picker.dart'; +import 'package:thunder/utils/navigation.dart'; class GestureSettingsPage extends StatefulWidget { final LocalSettings? settingToHighlight; @@ -505,21 +503,7 @@ class _GestureSettingsPageState extends State with TickerPr height: 42.0, child: Icon(Icons.chevron_right_rounded), ), - onTap: () { - final ThunderBloc thunderBloc = context.read(); - - Navigator.of(context).push( - SwipeablePageRoute( - transitionDuration: thunderBloc.state.reduceAnimations ? const Duration(milliseconds: 100) : null, - canSwipe: Platform.isIOS || thunderBloc.state.enableFullScreenSwipeNavigationGesture, - canOnlySwipeFromEdge: !thunderBloc.state.enableFullScreenSwipeNavigationGesture, - builder: (context) => MultiBlocProvider( - providers: [BlocProvider.value(value: thunderBloc)], - child: const ThemeSettingsPage(settingToHighlight: LocalSettings.actionColors), - ), - ), - ); - }, + onTap: () => navigateToSettingPage(context, LocalSettings.actionColors), highlightKey: settingToHighlightKey, setting: null, highlightedSetting: settingToHighlight, diff --git a/lib/settings/pages/settings_page.dart b/lib/settings/pages/settings_page.dart index 4ab56b667..131813e02 100644 --- a/lib/settings/pages/settings_page.dart +++ b/lib/settings/pages/settings_page.dart @@ -1,31 +1,12 @@ -import 'dart:io'; - import 'package:collection/collection.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.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'; import 'package:thunder/core/enums/local_settings.dart'; import 'package:thunder/core/update/check_github_update.dart'; -import 'package:thunder/settings/pages/about_settings_page.dart'; -import 'package:thunder/settings/pages/accessibility_settings_page.dart'; -import 'package:thunder/settings/pages/appearance_settings_page.dart'; -import 'package:thunder/settings/pages/debug_settings_page.dart'; -import 'package:thunder/settings/pages/fab_settings_page.dart'; -import 'package:thunder/settings/pages/filter_settings_page.dart'; -import 'package:thunder/settings/pages/general_settings_page.dart'; -import 'package:thunder/settings/pages/gesture_settings_page.dart'; -import 'package:thunder/settings/pages/user_labels_settings_page.dart'; -import 'package:thunder/settings/pages/video_player_settings.dart'; -import 'package:thunder/thunder/bloc/thunder_bloc.dart'; -import 'package:thunder/user/bloc/user_settings_bloc.dart'; -import 'package:thunder/user/pages/user_settings_page.dart'; import 'package:thunder/utils/constants.dart'; -import 'package:thunder/utils/settings_utils.dart'; +import 'package:thunder/utils/navigation.dart'; class SettingTopic { final String title; @@ -108,7 +89,7 @@ class _SettingsPageState extends State { onTap: () { controller.closeView(null); controller.clear(); - navigateToSetting(context, localSettings[index]); + navigateToSettingPage(context, localSettings[index]); }, title: Text( l10n.getLocalSettingLocalization(localSettings[index].key), @@ -134,71 +115,39 @@ class _SettingsPageState extends State { trailing: const Icon(Icons.chevron_right_rounded), onTap: () { if (topic.path == SETTINGS_ABOUT_PAGE) { - final AccountBloc accountBloc = context.read(); - final ThunderBloc thunderBloc = context.read(); - final AuthBloc authBloc = context.read(); - - Navigator.of(context).push( - SwipeablePageRoute( - transitionDuration: thunderBloc.state.reduceAnimations ? const Duration(milliseconds: 100) : null, - canSwipe: Platform.isIOS || thunderBloc.state.enableFullScreenSwipeNavigationGesture, - canOnlySwipeFromEdge: !thunderBloc.state.enableFullScreenSwipeNavigationGesture, - builder: (context) => MultiBlocProvider( - providers: [ - BlocProvider.value(value: accountBloc), - BlocProvider.value(value: thunderBloc), - BlocProvider.value(value: authBloc), - ], - child: const AboutSettingsPage(), - ), - ), - ); + navigateToSettingPage(context, LocalSettings.settingsPageAbout); } else if (topic.path == SETTINGS_ACCOUNT_PAGE) { - final AccountBloc accountBloc = context.read(); - final ThunderBloc thunderBloc = context.read(); - final UserSettingsBloc userSettingsBloc = UserSettingsBloc(); - - Navigator.of(context).push( - SwipeablePageRoute( - transitionDuration: thunderBloc.state.reduceAnimations ? const Duration(milliseconds: 100) : null, - canSwipe: Platform.isIOS || thunderBloc.state.enableFullScreenSwipeNavigationGesture, - canOnlySwipeFromEdge: !thunderBloc.state.enableFullScreenSwipeNavigationGesture, - builder: (context) => MultiBlocProvider( - providers: [ - BlocProvider.value(value: thunderBloc), - BlocProvider.value(value: accountBloc), - BlocProvider.value(value: userSettingsBloc), - ], - child: const UserSettingsPage(), - ), - ), - ); + navigateToSettingPage(context, LocalSettings.settingsPageAccount); } else { - final ThunderBloc thunderBloc = context.read(); - - Navigator.of(context).push( - SwipeablePageRoute( - transitionDuration: thunderBloc.state.reduceAnimations ? const Duration(milliseconds: 100) : null, - canSwipe: Platform.isIOS || thunderBloc.state.enableFullScreenSwipeNavigationGesture, - canOnlySwipeFromEdge: !thunderBloc.state.enableFullScreenSwipeNavigationGesture, - builder: (context) => MultiBlocProvider( - providers: [BlocProvider.value(value: thunderBloc)], - child: switch (topic.path) { - SETTINGS_GENERAL_PAGE => const GeneralSettingsPage(), - SETTINGS_FILTERS_PAGE => const FilterSettingsPage(), - SETTINGS_APPEARANCE_PAGE => const AppearanceSettingsPage(), - SETTINGS_GESTURES_PAGE => const GestureSettingsPage(), - SETTINGS_VIDEO_PAGE => const VideoPlayerSettingsPage(), - SETTINGS_FAB_PAGE => const FabSettingsPage(), - SETTINGS_ACCESSIBILITY_PAGE => const AccessibilitySettingsPage(), - SETTINGS_USER_LABELS_PAGE => const UserLabelSettingsPage(), - SETTINGS_ABOUT_PAGE => const AboutSettingsPage(), - SETTINGS_DEBUG_PAGE => const DebugSettingsPage(), - _ => Container(), - }, - ), - ), - ); + switch (topic.path) { + case SETTINGS_GENERAL_PAGE: + navigateToSettingPage(context, LocalSettings.settingsPageGeneral); + break; + case SETTINGS_FILTERS_PAGE: + navigateToSettingPage(context, LocalSettings.settingsPageFilters); + break; + case SETTINGS_APPEARANCE_PAGE: + navigateToSettingPage(context, LocalSettings.settingsPageAppearance); + break; + case SETTINGS_GESTURES_PAGE: + navigateToSettingPage(context, LocalSettings.settingsPageGestures); + break; + case SETTINGS_VIDEO_PAGE: + navigateToSettingPage(context, LocalSettings.settingsPageVideo); + break; + case SETTINGS_FAB_PAGE: + navigateToSettingPage(context, LocalSettings.settingsPageFloatingActionButton); + break; + case SETTINGS_ACCESSIBILITY_PAGE: + navigateToSettingPage(context, LocalSettings.settingsPageAccessibility); + break; + case SETTINGS_USER_LABELS_PAGE: + navigateToSettingPage(context, LocalSettings.settingsPageUserLabels); + break; + case SETTINGS_DEBUG_PAGE: + navigateToSettingPage(context, LocalSettings.settingsPageDebug); + break; + } } }, ), diff --git a/lib/shared/chips/community_chip.dart b/lib/shared/chips/community_chip.dart index a495129aa..07d72f21f 100644 --- a/lib/shared/chips/community_chip.dart +++ b/lib/shared/chips/community_chip.dart @@ -2,12 +2,12 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:thunder/core/enums/full_name.dart'; -import 'package:thunder/feed/utils/utils.dart'; import 'package:thunder/feed/view/feed_page.dart'; import 'package:thunder/shared/avatars/community_avatar.dart'; import 'package:thunder/shared/full_name_widgets.dart'; import 'package:thunder/thunder/bloc/thunder_bloc.dart'; import 'package:thunder/utils/instance.dart'; +import 'package:thunder/utils/navigation.dart'; /// A chip which displays the given community and instance information. /// diff --git a/lib/shared/chips/user_chip.dart b/lib/shared/chips/user_chip.dart index c50fc9a9b..48d63e4f8 100644 --- a/lib/shared/chips/user_chip.dart +++ b/lib/shared/chips/user_chip.dart @@ -5,7 +5,6 @@ import 'package:lemmy_api_client/v3.dart'; import 'package:thunder/core/enums/font_scale.dart'; import 'package:thunder/core/enums/full_name.dart'; import 'package:thunder/core/enums/user_type.dart'; -import 'package:thunder/feed/utils/utils.dart'; import 'package:thunder/feed/view/feed_page.dart'; import 'package:thunder/shared/avatars/user_avatar.dart'; import 'package:thunder/shared/full_name_widgets.dart'; @@ -13,6 +12,7 @@ import 'package:thunder/thunder/bloc/thunder_bloc.dart'; import 'package:thunder/thunder/thunder_icons.dart'; import 'package:thunder/user/utils/user_groups.dart'; import 'package:thunder/utils/instance.dart'; +import 'package:thunder/utils/navigation.dart'; /// A chip which displays the given user and instance information. Additionally, it renders special chips for special users. /// diff --git a/lib/shared/comment_reference.dart b/lib/shared/comment_reference.dart index bfad4043b..915fd47dc 100644 --- a/lib/shared/comment_reference.dart +++ b/lib/shared/comment_reference.dart @@ -15,7 +15,7 @@ import 'package:thunder/shared/text/scalable_text.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/comment/utils/navigate_comment.dart'; +import 'package:thunder/utils/navigation.dart'; import 'package:thunder/utils/numbers.dart'; class CommentReference extends StatefulWidget { diff --git a/lib/shared/cross_posts.dart b/lib/shared/cross_posts.dart index 74f5dd34e..de9fcb476 100644 --- a/lib/shared/cross_posts.dart +++ b/lib/shared/cross_posts.dart @@ -6,8 +6,7 @@ import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:thunder/post/utils/post.dart'; import 'package:thunder/shared/full_name_widgets.dart'; import 'package:thunder/utils/instance.dart'; -import 'package:thunder/post/utils/navigate_create_post.dart'; -import 'package:thunder/post/utils/navigate_post.dart'; +import 'package:thunder/utils/navigation.dart'; import 'package:thunder/community/widgets/post_card_metadata.dart'; diff --git a/lib/shared/preview_image.dart b/lib/shared/preview_image.dart deleted file mode 100644 index e5edff122..000000000 --- a/lib/shared/preview_image.dart +++ /dev/null @@ -1,133 +0,0 @@ -import 'package:flutter/material.dart'; - -import 'package:extended_image/extended_image.dart'; -import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:thunder/core/enums/image_caching_mode.dart'; -import 'package:thunder/core/enums/theme_type.dart'; - -import 'package:thunder/core/enums/view_mode.dart'; -import 'package:thunder/thunder/bloc/thunder_bloc.dart'; -import 'package:thunder/utils/links.dart'; - -class PreviewImage extends StatefulWidget { - final ViewMode viewMode; - final bool showFullHeightImages; - final String mediaUrl; - final double? height; - - const PreviewImage({ - super.key, - required this.viewMode, - required this.showFullHeightImages, - required this.mediaUrl, - this.height, - }); - - @override - State createState() => _PreviewImageState(); -} - -class _PreviewImageState extends State with SingleTickerProviderStateMixin { - late AnimationController _controller; - - @override - void initState() { - _controller = AnimationController(vsync: this, duration: const Duration(milliseconds: 130), lowerBound: 0.0, upperBound: 1.0); - super.initState(); - } - - @override - void dispose() { - _controller.dispose(); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - final theme = Theme.of(context); - final ThunderState state = context.read().state; - final useDarkTheme = state.themeType == ThemeType.dark || state.themeType == ThemeType.pureBlack; - - double? height = widget.viewMode == ViewMode.compact ? ViewMode.compact.height : (widget.showFullHeightImages ? widget.height : ViewMode.comfortable.height); - double width = widget.viewMode == ViewMode.compact ? ViewMode.compact.height : MediaQuery.of(context).size.width - 24; - - return ExtendedImage.network( - widget.mediaUrl, - height: height, - width: width, - fit: widget.viewMode == ViewMode.compact ? BoxFit.cover : BoxFit.fitWidth, - cache: true, - clearMemoryCacheWhenDispose: state.imageCachingMode == ImageCachingMode.relaxed, - cacheWidth: widget.viewMode == ViewMode.compact - ? (ViewMode.compact.height * View.of(context).devicePixelRatio.ceil()).toInt() - : ((MediaQuery.of(context).size.width - 24) * View.of(context).devicePixelRatio.ceil()).toInt(), - loadStateChanged: (ExtendedImageState state) { - switch (state.extendedImageLoadState) { - case LoadState.loading: - _controller.reset(); - return Container(); - case LoadState.completed: - if (state.wasSynchronouslyLoaded) { - return state.completedWidget; - } - _controller.forward(); - - return FadeTransition( - opacity: _controller, - child: state.completedWidget, - ); - case LoadState.failed: - _controller.reset(); - - state.imageProvider.evict(); - - return Container( - color: useDarkTheme ? Colors.grey.shade900 : Colors.grey.shade300, - child: Padding( - padding: const EdgeInsets.only(top: 4.0, bottom: 8.0), - child: InkWell( - child: Container( - clipBehavior: Clip.hardEdge, - decoration: BoxDecoration(borderRadius: BorderRadius.circular(12)), - child: Stack( - alignment: Alignment.bottomRight, - fit: StackFit.passthrough, - children: [ - Container( - color: Colors.grey.shade900, - padding: const EdgeInsets.symmetric(horizontal: 8.0, vertical: 12.0), - child: Row( - children: [ - const Padding( - padding: EdgeInsets.symmetric(horizontal: 8.0), - child: Icon( - Icons.link, - color: Colors.white60, - ), - ), - Expanded( - child: Text( - widget.mediaUrl, - overflow: TextOverflow.ellipsis, - style: theme.textTheme.bodyMedium!.copyWith( - color: Colors.white60, - ), - ), - ), - ], - ), - ), - ], - ), - ), - onTap: () { - handleLink(context, url: widget.mediaUrl); - }, - ), - ), - ); - } - }, - ); - } -} diff --git a/lib/thunder/cubits/deep_links_cubit/deep_links_cubit.dart b/lib/thunder/cubits/deep_links_cubit/deep_links_cubit.dart index 0d67621ef..96eb2f948 100644 --- a/lib/thunder/cubits/deep_links_cubit/deep_links_cubit.dart +++ b/lib/thunder/cubits/deep_links_cubit/deep_links_cubit.dart @@ -1,5 +1,4 @@ import 'dart:async'; -import 'dart:math'; import 'package:app_links/app_links.dart'; import 'package:bloc/bloc.dart'; diff --git a/lib/thunder/pages/thunder_page.dart b/lib/thunder/pages/thunder_page.dart index 3f01410c7..b1ed49625 100644 --- a/lib/thunder/pages/thunder_page.dart +++ b/lib/thunder/pages/thunder_page.dart @@ -31,7 +31,7 @@ import 'package:thunder/core/singletons/lemmy_client.dart'; import 'package:thunder/core/singletons/preferences.dart'; import 'package:thunder/core/update/check_github_update.dart'; import 'package:thunder/feed/feed.dart'; -import 'package:thunder/modlog/utils/navigate_modlog.dart'; +import 'package:thunder/utils/navigation.dart'; import 'package:thunder/post/utils/post.dart'; import 'package:thunder/shared/common_markdown_body.dart'; import 'package:thunder/shared/snackbar.dart'; @@ -53,12 +53,6 @@ import 'package:thunder/search/pages/search_page.dart'; import 'package:thunder/settings/pages/settings_page.dart'; import 'package:thunder/shared/error_message.dart'; import 'package:thunder/thunder/bloc/thunder_bloc.dart'; -import 'package:thunder/comment/utils/navigate_comment.dart'; -import 'package:thunder/post/utils/navigate_create_post.dart'; -import 'package:thunder/instance/utils/navigate_instance.dart'; -import 'package:thunder/post/utils/navigate_post.dart'; -import 'package:thunder/notification/utils/navigate_notification.dart'; -import 'package:thunder/utils/settings_utils.dart'; String? currentIntent; @@ -320,7 +314,6 @@ class _ThunderState extends State { FeedBloc feedBloc = FeedBloc(lemmyClient: lemmyClient); await navigateToModlogPage( context, - feedBloc: feedBloc, modlogActionType: ModlogActionType.fromJson(uri.queryParameters['actionType'] ?? ModlogActionType.all.value), communityId: int.tryParse(uri.queryParameters['communityId'] ?? ''), userId: int.tryParse(uri.queryParameters['userId'] ?? ''), @@ -388,7 +381,7 @@ class _ThunderState extends State { link = link.replaceFirst('https://', ''); if (link.startsWith('setting-')) { String setting = link.replaceFirst('setting-', ''); - navigateToSetting(context, LocalSettings.values.firstWhere((localSetting) => localSetting.name == setting)); + navigateToSettingPage(context, LocalSettings.values.firstWhere((localSetting) => localSetting.name == setting)); } } diff --git a/lib/user/pages/user_settings_block_page.dart b/lib/user/pages/user_settings_block_page.dart index 4acd49175..c7a014399 100644 --- a/lib/user/pages/user_settings_block_page.dart +++ b/lib/user/pages/user_settings_block_page.dart @@ -5,9 +5,8 @@ import "package:flutter_gen/gen_l10n/app_localizations.dart"; import 'package:lemmy_api_client/v3.dart'; import 'package:thunder/core/enums/full_name.dart'; -import 'package:thunder/feed/utils/utils.dart'; import 'package:thunder/feed/view/feed_page.dart'; -import 'package:thunder/instance/utils/navigate_instance.dart'; +import 'package:thunder/utils/navigation.dart'; import 'package:thunder/shared/avatars/community_avatar.dart'; import 'package:thunder/shared/avatars/user_avatar.dart'; import 'package:thunder/shared/full_name_widgets.dart'; diff --git a/lib/user/pages/user_settings_page.dart b/lib/user/pages/user_settings_page.dart index 7517a423a..8dc7969e2 100644 --- a/lib/user/pages/user_settings_page.dart +++ b/lib/user/pages/user_settings_page.dart @@ -2,7 +2,6 @@ import "dart:async"; import "dart:convert"; import "dart:io"; -import "package:flutter/foundation.dart"; import "package:flutter/material.dart"; import "package:flutter/services.dart"; @@ -12,7 +11,6 @@ import "package:html/parser.dart"; import "package:lemmy_api_client/v3.dart"; import "package:flutter_gen/gen_l10n/app_localizations.dart"; import "package:path_provider/path_provider.dart"; -import "package:swipeable_page_route/swipeable_page_route.dart"; import 'package:markdown/markdown.dart' hide Text; import "package:thunder/account/bloc/account_bloc.dart"; @@ -22,23 +20,20 @@ import "package:thunder/core/auth/bloc/auth_bloc.dart"; import "package:thunder/core/auth/helpers/fetch_account.dart"; import "package:thunder/core/enums/local_settings.dart"; import "package:thunder/core/singletons/lemmy_client.dart"; -import "package:thunder/settings/widgets/discussion_language_selector.dart"; import "package:thunder/settings/widgets/list_option.dart"; import "package:thunder/settings/widgets/settings_list_tile.dart"; import "package:thunder/settings/widgets/toggle_option.dart"; import "package:thunder/shared/dialogs.dart"; import "package:thunder/shared/snackbar.dart"; import "package:thunder/shared/sort_picker.dart"; -import "package:thunder/thunder/bloc/thunder_bloc.dart"; import "package:thunder/thunder/thunder_icons.dart"; import "package:thunder/user/bloc/user_settings_bloc.dart"; -import "package:thunder/user/pages/media_management_page.dart"; -import "package:thunder/user/pages/user_settings_block_page.dart"; import "package:thunder/user/widgets/user_indicator.dart"; import "package:thunder/utils/bottom_sheet_list_picker.dart"; import "package:thunder/utils/error_messages.dart"; import "package:thunder/utils/links.dart"; import "package:thunder/account/utils/profiles.dart"; +import "package:thunder/utils/navigation.dart"; import "package:version/version.dart"; /// A widget that displays the user's account settings. These settings are synchronized with the instance and should be preferred over the app settings. @@ -417,22 +412,7 @@ class _UserSettingsPageState extends State { icon: Icons.language_rounded, description: l10n.discussionLanguages, widget: const SizedBox(height: 42.0, child: Icon(Icons.chevron_right_rounded)), - onTap: () async { - final state = context.read().state; - await Navigator.of(context).push( - SwipeablePageRoute( - transitionDuration: state.reduceAnimations ? const Duration(milliseconds: 100) : null, - canOnlySwipeFromEdge: true, - backGestureDetectionWidth: 45, - builder: (navigatorContext) { - return MultiBlocProvider( - providers: [BlocProvider.value(value: context.read())], - child: const DiscussionLanguageSelector(), - ); - }, - ), - ); - }, + onTap: () => navigateToSettingPage(context, LocalSettings.settingsPageAccountLanguages), highlightKey: settingToHighlightKey, setting: LocalSettings.discussionLanguages, highlightedSetting: settingToHighlight, @@ -441,22 +421,7 @@ class _UserSettingsPageState extends State { icon: Icons.block_rounded, description: l10n.blockSettingLabel, widget: const SizedBox(height: 42.0, child: Icon(Icons.chevron_right_rounded)), - onTap: () async { - final state = context.read().state; - await Navigator.of(context).push( - SwipeablePageRoute( - transitionDuration: state.reduceAnimations ? const Duration(milliseconds: 100) : null, - canOnlySwipeFromEdge: true, - backGestureDetectionWidth: 45, - builder: (navigatorContext) { - return MultiBlocProvider( - providers: [BlocProvider.value(value: context.read())], - child: const UserSettingsBlockPage(), - ); - }, - ), - ); - }, + onTap: () => navigateToSettingPage(context, LocalSettings.settingsPageAccountBlocks), highlightKey: settingToHighlightKey, setting: LocalSettings.accountBlocks, highlightedSetting: settingToHighlight, @@ -630,32 +595,7 @@ class _UserSettingsPageState extends State { height: 42.0, child: Icon(Icons.chevron_right_rounded), ), - onTap: () async { - final ThunderBloc thunderBloc = context.read(); - final UserSettingsBloc userSettingsBloc = context.read(); - final AuthBloc authBloc = context.read(); - - userSettingsBloc.add(const ListMediaEvent()); - - await Navigator.of(context).push( - SwipeablePageRoute( - transitionDuration: thunderBloc.state.reduceAnimations ? const Duration(milliseconds: 100) : null, - backGestureDetectionStartOffset: !kIsWeb && Platform.isAndroid ? 45 : 0, - backGestureDetectionWidth: 45, - canOnlySwipeFromEdge: true, - builder: (otherContext) { - return MultiBlocProvider( - providers: [ - BlocProvider.value(value: userSettingsBloc), - BlocProvider.value(value: thunderBloc), - BlocProvider.value(value: authBloc), - ], - child: const MediaManagementPage(), - ); - }, - ), - ); - }, + onTap: () => navigateToSettingPage(context, LocalSettings.settingsPageAccountMedia), highlightKey: settingToHighlightKey, setting: LocalSettings.accountManageMedia, highlightedSetting: settingToHighlight, diff --git a/lib/user/widgets/user_action_bottom_sheet.dart b/lib/user/widgets/user_action_bottom_sheet.dart index 93bad4295..5553c8eb3 100644 --- a/lib/user/widgets/user_action_bottom_sheet.dart +++ b/lib/user/widgets/user_action_bottom_sheet.dart @@ -6,7 +6,6 @@ import 'package:lemmy_api_client/v3.dart'; import 'package:thunder/account/models/user_label.dart'; import 'package:thunder/core/auth/bloc/auth_bloc.dart'; import 'package:thunder/core/enums/user_type.dart'; -import 'package:thunder/feed/utils/utils.dart'; import 'package:thunder/feed/view/feed_page.dart'; import 'package:thunder/post/enums/post_action.dart'; import 'package:thunder/post/utils/user_label_utils.dart'; @@ -19,6 +18,7 @@ import 'package:thunder/thunder/thunder_icons.dart'; import 'package:thunder/user/bloc/user_bloc.dart'; import 'package:thunder/user/enums/user_action.dart'; import 'package:thunder/utils/global_context.dart'; +import 'package:thunder/utils/navigation.dart'; /// Defines the actions that can be taken on a user /// TODO: Implement admin-level actions diff --git a/lib/user/widgets/user_list_entry.dart b/lib/user/widgets/user_list_entry.dart index 61c010829..154312977 100644 --- a/lib/user/widgets/user_list_entry.dart +++ b/lib/user/widgets/user_list_entry.dart @@ -2,11 +2,11 @@ import 'package:flutter/material.dart'; import 'package:lemmy_api_client/v3.dart'; import 'package:thunder/core/enums/full_name.dart'; import 'package:thunder/core/singletons/lemmy_client.dart'; -import 'package:thunder/feed/utils/utils.dart'; import 'package:thunder/feed/view/feed_page.dart'; import 'package:thunder/shared/avatars/user_avatar.dart'; import 'package:thunder/shared/full_name_widgets.dart'; import 'package:thunder/utils/instance.dart'; +import 'package:thunder/utils/navigation.dart'; /// A widget that can display a single user entry for use within a list (e.g., search page, instance explorer) class UserListEntry extends StatelessWidget { diff --git a/lib/user/widgets/user_sidebar.dart b/lib/user/widgets/user_sidebar.dart index c64e783b0..606e4cf73 100644 --- a/lib/user/widgets/user_sidebar.dart +++ b/lib/user/widgets/user_sidebar.dart @@ -7,7 +7,6 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:thunder/core/auth/bloc/auth_bloc.dart'; import 'package:thunder/core/singletons/lemmy_client.dart'; -import 'package:thunder/feed/utils/utils.dart'; import 'package:thunder/feed/view/feed_page.dart'; import 'package:thunder/shared/avatars/community_avatar.dart'; import 'package:thunder/shared/common_markdown_body.dart'; @@ -16,6 +15,7 @@ import 'package:thunder/user/bloc/user_bloc.dart'; import 'package:thunder/user/enums/user_action.dart'; import 'package:thunder/utils/date_time.dart'; import 'package:thunder/utils/instance.dart'; +import 'package:thunder/utils/navigation.dart'; const kSidebarWidthFactor = 0.8; diff --git a/lib/utils/constants.dart b/lib/utils/constants.dart index 8b1cc4c44..ab5f9df43 100644 --- a/lib/utils/constants.dart +++ b/lib/utils/constants.dart @@ -49,6 +49,9 @@ const String SETTINGS_GESTURES_PAGE = '/settings/gestures'; const String SETTINGS_FAB_PAGE = '/settings/fab'; const String SETTINGS_ACCESSIBILITY_PAGE = '/settings/accessibility'; const String SETTINGS_ACCOUNT_PAGE = '/settings/account'; +const String SETTINGS_ACCOUNT_LANGUAGES_PAGE = '/settings/account/languages'; +const String SETTINGS_ACCOUNT_BLOCKLIST_PAGE = '/settings/account/blocklist'; +const String SETTINGS_ACCOUNT_MEDIA_PAGE = '/settings/account/media'; const String SETTINGS_USER_LABELS_PAGE = '/settings/user_labels'; const String SETTINGS_ABOUT_PAGE = '/settings/about'; const String SETTINGS_DEBUG_PAGE = '/settings/debug'; diff --git a/lib/utils/links.dart b/lib/utils/links.dart index 0bb4f13d8..2dfdb0228 100644 --- a/lib/utils/links.dart +++ b/lib/utils/links.dart @@ -10,19 +10,16 @@ import 'package:intl/message_format.dart'; import 'package:lemmy_api_client/v3.dart'; import 'package:link_preview_generator/link_preview_generator.dart'; import 'package:share_plus/share_plus.dart'; -import 'package:swipeable_page_route/swipeable_page_route.dart'; import 'package:thunder/core/enums/browser_mode.dart'; import 'package:thunder/core/enums/local_settings.dart'; import 'package:thunder/core/enums/video_player_mode.dart'; import 'package:thunder/feed/bloc/feed_bloc.dart'; import 'package:thunder/instances.dart'; -import 'package:thunder/modlog/utils/navigate_modlog.dart'; +import 'package:thunder/utils/navigation.dart'; import 'package:thunder/shared/pages/loading_page.dart'; import 'package:thunder/shared/picker_item.dart'; -import 'package:thunder/shared/webview.dart'; import 'package:thunder/utils/media/image.dart'; import 'package:thunder/utils/media/video.dart'; -import 'package:thunder/utils/settings_utils.dart'; import 'package:url_launcher/url_launcher.dart' as url_launcher; import 'package:flutter_custom_tabs/flutter_custom_tabs.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; @@ -31,12 +28,9 @@ import 'package:thunder/thunder/bloc/thunder_bloc.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'; -import 'package:thunder/feed/utils/utils.dart'; import 'package:thunder/feed/view/feed_page.dart'; import 'package:thunder/post/utils/post.dart'; import 'package:thunder/utils/instance.dart'; -import 'package:thunder/comment/utils/navigate_comment.dart'; -import 'package:thunder/post/utils/navigate_post.dart'; class LinkInfo { String? imageURL; @@ -135,21 +129,7 @@ void _openLink(BuildContext context, {required String url, bool isVideo = false} hideLoadingPage(context, delay: true); url_launcher.launchUrl(uri, mode: url_launcher.LaunchMode.externalApplication); } else { - final bool reduceAnimations = state.reduceAnimations; - - SwipeablePageRoute route = SwipeablePageRoute( - transitionDuration: isLoadingPageShown - ? Duration.zero - : reduceAnimations - ? const Duration(milliseconds: 100) - : null, - reverseTransitionDuration: reduceAnimations ? const Duration(milliseconds: 100) : const Duration(milliseconds: 500), - backGestureDetectionWidth: 45, - canOnlySwipeFromEdge: true, - builder: (context) => WebView(url: url), - ); - - pushOnTopOfLoadingPage(context, route); + navigateToWebView(context, url); } } } @@ -237,7 +217,6 @@ void handleLink(BuildContext context, {required String url, bool forceOpenInBrow FeedBloc feedBloc = FeedBloc(lemmyClient: lemmyClient); await navigateToModlogPage( context, - feedBloc: feedBloc, modlogActionType: ModlogActionType.fromJson(uri.queryParameters['actionType'] ?? ModlogActionType.all.value), communityId: int.tryParse(uri.queryParameters['communityId'] ?? ''), userId: int.tryParse(uri.queryParameters['userId'] ?? ''), @@ -277,7 +256,7 @@ void handleLink(BuildContext context, {required String url, bool forceOpenInBrow if (link.startsWith('setting-')) { String setting = link.replaceFirst('setting-', ''); - navigateToSetting(context, LocalSettings.values.firstWhere((localSetting) => localSetting.name == setting)); + navigateToSettingPage(context, LocalSettings.values.firstWhere((localSetting) => localSetting.name == setting)); return; } } diff --git a/lib/utils/navigation.dart b/lib/utils/navigation.dart new file mode 100644 index 000000000..adcb55f1a --- /dev/null +++ b/lib/utils/navigation.dart @@ -0,0 +1,820 @@ +import 'dart:io'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; + +import 'package:collection/collection.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:lemmy_api_client/v3.dart'; +import 'package:swipeable_page_route/swipeable_page_route.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; + +import 'package:thunder/account/bloc/account_bloc.dart'; +import 'package:thunder/account/models/account.dart'; +import 'package:thunder/comment/view/create_comment_page.dart'; +import 'package:thunder/community/bloc/anonymous_subscriptions_bloc.dart'; +import 'package:thunder/community/bloc/community_bloc.dart'; +import 'package:thunder/community/pages/create_post_page.dart'; +import 'package:thunder/core/auth/bloc/auth_bloc.dart'; +import 'package:thunder/core/auth/helpers/fetch_account.dart'; +import 'package:thunder/core/enums/local_settings.dart'; +import 'package:thunder/core/models/post_view_media.dart'; +import 'package:thunder/core/singletons/lemmy_client.dart'; +import 'package:thunder/core/singletons/preferences.dart'; +import 'package:thunder/feed/bloc/feed_bloc.dart'; +import 'package:thunder/feed/view/feed_page.dart'; +import 'package:thunder/inbox/bloc/inbox_bloc.dart'; +import 'package:thunder/inbox/enums/inbox_type.dart'; +import 'package:thunder/instance/bloc/instance_bloc.dart'; +import 'package:thunder/instance/pages/instance_page.dart'; +import 'package:thunder/moderator/view/report_page.dart'; +import 'package:thunder/modlog/view/modlog_page.dart'; +import 'package:thunder/post/bloc/post_bloc.dart'; +import 'package:thunder/post/cubit/create_post_cubit.dart'; +import 'package:thunder/post/enums/post_action.dart'; +import 'package:thunder/post/pages/post_page.dart'; +import 'package:thunder/search/bloc/search_bloc.dart'; +import 'package:thunder/search/pages/search_page.dart'; +import 'package:thunder/settings/pages/about_settings_page.dart'; +import 'package:thunder/settings/pages/accessibility_settings_page.dart'; +import 'package:thunder/settings/pages/appearance_settings_page.dart'; +import 'package:thunder/settings/pages/comment_appearance_settings_page.dart'; +import 'package:thunder/settings/pages/debug_settings_page.dart'; +import 'package:thunder/settings/pages/filter_settings_page.dart'; +import 'package:thunder/settings/pages/general_settings_page.dart'; +import 'package:thunder/settings/pages/gesture_settings_page.dart'; +import 'package:thunder/settings/pages/post_appearance_settings_page.dart'; +import 'package:thunder/settings/pages/theme_settings_page.dart'; +import 'package:thunder/settings/pages/user_labels_settings_page.dart'; +import 'package:thunder/settings/pages/video_player_settings.dart'; +import 'package:thunder/settings/widgets/discussion_language_selector.dart'; +import 'package:thunder/shared/pages/loading_page.dart'; +import 'package:thunder/shared/snackbar.dart'; +import 'package:thunder/shared/webview.dart'; +import 'package:thunder/thunder/bloc/thunder_bloc.dart'; +import 'package:thunder/thunder/pages/notifications_pages.dart'; +import 'package:thunder/user/bloc/user_settings_bloc.dart'; +import 'package:thunder/user/pages/media_management_page.dart'; +import 'package:thunder/user/pages/user_settings_block_page.dart'; +import 'package:thunder/user/pages/user_settings_page.dart'; +import 'package:thunder/utils/constants.dart'; +import 'package:thunder/utils/links.dart'; +import 'package:thunder/utils/swipe.dart'; +import 'package:thunder/post/pages/legacy_post_page.dart' as legacy_post_page; +import 'package:thunder/post/bloc/post_bloc.dart' as post_bloc; + +/// Navigates to the instance page for the given [instanceHost]. +/// +/// When [instanceId] is provided, the instance page will allow the option to block that given instance. This value represents +/// the id of the navigated instance from the original instance (e.g., lemmy.ml's instance id from lemmy.world). +Future navigateToInstancePage( + BuildContext context, { + required String instanceHost, + required int? instanceId, +}) async { + assert(instanceHost.isNotEmpty); + + showLoadingPage(context); + + final l10n = AppLocalizations.of(context)!; + + final authBloc = context.read(); + final thunderBloc = context.read(); + final state = thunderBloc.state; + + final reduceAnimations = state.reduceAnimations; + final enableFullScreenSwipeNavigationGesture = state.enableFullScreenSwipeNavigationGesture; + + GetSiteResponse? getSiteResponse; + bool? isBlocked; + + try { + // Get the site information by connecting to the given instance + getSiteResponse = await LemmyApiV3(instanceHost).run(const GetSite()).timeout(const Duration(seconds: 5)); + + // Check whether this instance is blocked (we have to get our user from our current site first). + isBlocked = authBloc.state.getSiteResponse?.myUser?.instanceBlocks?.any((i) => i.instance.domain == instanceHost); + } catch (e) { + // Continue if we can't get the site + } + + final SwipeablePageRoute route = SwipeablePageRoute( + transitionDuration: isLoadingPageShown + ? Duration.zero + : reduceAnimations + ? const Duration(milliseconds: 100) + : null, + reverseTransitionDuration: reduceAnimations ? const Duration(milliseconds: 100) : const Duration(milliseconds: 500), + canSwipe: Platform.isIOS || enableFullScreenSwipeNavigationGesture, + canOnlySwipeFromEdge: true, + builder: (context) => BlocProvider.value( + value: thunderBloc, + child: InstancePage( + getSiteResponse: getSiteResponse!, + isBlocked: isBlocked, + instanceId: instanceId, + ), + ), + ); + + if (getSiteResponse != null) { + pushOnTopOfLoadingPage(context, route); + } else { + showSnackbar( + l10n.unableToNavigateToInstance(instanceHost), + trailingAction: () => handleLink(context, url: "https://$instanceHost", forceOpenInBrowser: true), + trailingIcon: Icons.open_in_browser_rounded, + ); + hideLoadingPage(context); + } +} + +/// Navigates to the post page with the given [postViewMedia] or [postId]. +/// +/// One of [postViewMedia] or [postId] must be provided. If [postViewMedia] is provided, the post page will use that data to display the post. +/// Otherwise, the post page will fetch the post with the given [postId]. +Future navigateToPost( + BuildContext context, { + int? postId, + PostViewMedia? postViewMedia, + int? selectedCommentId, + String? selectedCommentPath, + Function(PostViewMedia)? onPostUpdated, +}) async { + assert((postId != null || postViewMedia != null), 'One of the parameters must be provided'); + + // Required blocs + final accountBloc = context.read(); + final authBloc = context.read(); + final thunderBloc = context.read(); + + // Optional blocs + final hasFeedBloc = context.findAncestorWidgetOfExactType>(); + final feedBloc = hasFeedBloc != null ? context.read() : null; + + // Mark post as read when tapped + if (authBloc.state.isLoggedIn) { + feedBloc?.add(FeedItemActionedEvent(postId: postViewMedia?.postView.post.id ?? postId, postAction: PostAction.read, value: true)); + } + + final prefs = (await UserPreferences.instance).sharedPreferences; + final enableExperimentalFeatures = prefs.getBool(LocalSettings.enableExperimentalFeatures.name) ?? false; + + final state = thunderBloc.state; + final reduceAnimations = state.reduceAnimations; + final enableFullScreenSwipeNavigationGesture = state.enableFullScreenSwipeNavigationGesture; + + final route = SwipeablePageRoute( + transitionDuration: isLoadingPageShown + ? Duration.zero + : reduceAnimations + ? const Duration(milliseconds: 100) + : null, + reverseTransitionDuration: reduceAnimations ? const Duration(milliseconds: 100) : const Duration(milliseconds: 500), + backGestureDetectionStartOffset: !kIsWeb && Platform.isAndroid ? 45 : 0, + backGestureDetectionWidth: 45, + canSwipe: Platform.isIOS || enableFullScreenSwipeNavigationGesture, + canOnlySwipeFromEdge: disableFullPageSwipe(isUserLoggedIn: authBloc.state.isLoggedIn, state: state, isPostPage: true) || !enableFullScreenSwipeNavigationGesture, + builder: (_) { + return MultiBlocProvider( + providers: [ + BlocProvider.value(value: accountBloc), + BlocProvider.value(value: authBloc), + BlocProvider.value(value: thunderBloc), + BlocProvider(create: (context) => post_bloc.PostBloc()), + BlocProvider(create: (context) => InstanceBloc(lemmyClient: LemmyClient.instance)), + BlocProvider(create: (context) => CommunityBloc(lemmyClient: LemmyClient.instance)), + BlocProvider(create: (context) => AnonymousSubscriptionsBloc()), + ], + child: enableExperimentalFeatures + ? PostPage( + initialPostViewMedia: postViewMedia!, + onPostUpdated: (PostViewMedia postViewMedia) { + // Manually marking the read attribute as true when navigating to post since there is a case where the API call to mark the post as read from the feed page is not completed in time + feedBloc?.add(FeedItemUpdatedEvent( + postViewMedia: PostViewMedia( + postView: postViewMedia.postView.copyWith(read: true), + media: postViewMedia.media, + ), + )); + }, + ) + : legacy_post_page.PostPage( + postView: postViewMedia, + postId: postId, + selectedCommentId: selectedCommentId, + selectedCommentPath: selectedCommentPath, + onPostUpdated: (PostViewMedia postViewMedia) { + // Manually marking the read attribute as true when navigating to post since there is a case where the API call to mark the post as read from the feed page is not completed in time + feedBloc?.add(FeedItemUpdatedEvent( + postViewMedia: PostViewMedia( + postView: postViewMedia.postView.copyWith(read: true), + media: postViewMedia.media, + ), + )); + }, + ), + ); + }, + ); + + pushOnTopOfLoadingPage(context, route); +} + +/// Navigates to the modlog page with the given parameters. +Future navigateToModlogPage( + BuildContext context, { + ModlogActionType? modlogActionType, + int? communityId, + int? userId, + int? moderatorId, + int? commentId, + LemmyClient? lemmyClient, + Widget? subtitle, +}) async { + final thunderBloc = context.read(); + + // Optional blocs + final hasFeedBloc = context.findAncestorWidgetOfExactType>(); + final feedBloc = hasFeedBloc != null ? context.read() : FeedBloc(lemmyClient: lemmyClient ?? LemmyClient.instance); + + final state = thunderBloc.state; + final reduceAnimations = state.reduceAnimations; + final enableFullScreenSwipeNavigationGesture = state.enableFullScreenSwipeNavigationGesture; + + final SwipeablePageRoute route = SwipeablePageRoute( + transitionDuration: isLoadingPageShown + ? Duration.zero + : reduceAnimations + ? const Duration(milliseconds: 100) + : null, + reverseTransitionDuration: reduceAnimations ? const Duration(milliseconds: 100) : const Duration(milliseconds: 500), + canSwipe: Platform.isIOS || enableFullScreenSwipeNavigationGesture, + canOnlySwipeFromEdge: true, + builder: (context) => MultiBlocProvider( + providers: [ + BlocProvider.value(value: feedBloc), + BlocProvider.value(value: thunderBloc), + ], + child: ModlogFeedPage( + modlogActionType: modlogActionType, + communityId: communityId, + userId: userId, + moderatorId: moderatorId, + commentId: commentId, + lemmyClient: lemmyClient, + subtitle: subtitle, + ), + ), + ); + + pushOnTopOfLoadingPage(context, route); +} + +Future navigateToComment(BuildContext context, CommentView commentView) async { + AccountBloc accountBloc = context.read(); + AuthBloc authBloc = context.read(); + ThunderBloc thunderBloc = context.read(); + + final ThunderState state = context.read().state; + final bool reduceAnimations = state.reduceAnimations; + + final SwipeablePageRoute route = SwipeablePageRoute( + transitionDuration: isLoadingPageShown + ? Duration.zero + : reduceAnimations + ? const Duration(milliseconds: 100) + : null, + reverseTransitionDuration: reduceAnimations ? const Duration(milliseconds: 100) : const Duration(milliseconds: 500), + backGestureDetectionWidth: 45, + canSwipe: Platform.isIOS || state.enableFullScreenSwipeNavigationGesture, + canOnlySwipeFromEdge: disableFullPageSwipe(isUserLoggedIn: authBloc.state.isLoggedIn, state: thunderBloc.state, isPostPage: true) || !state.enableFullScreenSwipeNavigationGesture, + builder: (context) => MultiBlocProvider( + providers: [ + BlocProvider.value(value: accountBloc), + BlocProvider.value(value: authBloc), + BlocProvider.value(value: thunderBloc), + BlocProvider(create: (context) => PostBloc()), + ], + child: legacy_post_page.PostPage( + selectedCommentId: commentView.comment.id, + selectedCommentPath: commentView.comment.path, + postId: commentView.post.id, + onPostUpdated: (PostViewMedia postViewMedia) => {}, + ), + ), + ); + + pushOnTopOfLoadingPage(context, route); +} + +Future navigateToCreateCommentPage( + BuildContext context, { + PostViewMedia? postViewMedia, + CommentView? commentView, + CommentView? parentCommentView, + Function(CommentView commentView, bool userChanged)? onCommentSuccess, +}) async { + assert(!(postViewMedia == null && parentCommentView == null && commentView == null)); + assert(!(postViewMedia != null && (parentCommentView != null || commentView != null))); + + final accountBloc = context.read(); + final thunderBloc = context.read(); + + final state = thunderBloc.state; + final reduceAnimations = state.reduceAnimations; + final enableFullScreenSwipeNavigationGesture = state.enableFullScreenSwipeNavigationGesture; + + final SwipeablePageRoute route = SwipeablePageRoute( + transitionDuration: isLoadingPageShown + ? Duration.zero + : reduceAnimations + ? const Duration(milliseconds: 100) + : null, + reverseTransitionDuration: reduceAnimations ? const Duration(milliseconds: 100) : const Duration(milliseconds: 500), + canSwipe: Platform.isIOS || enableFullScreenSwipeNavigationGesture, + canOnlySwipeFromEdge: true, + builder: (context) => MultiBlocProvider( + providers: [ + BlocProvider.value(value: thunderBloc), + BlocProvider.value(value: accountBloc), + ], + child: CreateCommentPage( + postViewMedia: postViewMedia, + commentView: commentView, + parentCommentView: parentCommentView, + onCommentSuccess: onCommentSuccess, + ), + ), + ); + + pushOnTopOfLoadingPage(context, route); +} + +Future navigateToCreatePostPage( + BuildContext context, { + String? title, + String? text, + File? image, + String? url, + bool? prePopulated, + int? communityId, + CommunityView? communityView, + PostViewMedia? postViewMedia, + Function(PostViewMedia, bool)? onPostSuccess, +}) async { + try { + final l10n = AppLocalizations.of(context)!; + + FeedBloc? feedBloc; + ThunderBloc thunderBloc = context.read(); + AccountBloc accountBloc = context.read(); + CreatePostCubit createPostCubit = CreatePostCubit(); + + final ThunderState thunderState = context.read().state; + final bool reduceAnimations = thunderState.reduceAnimations; + final bool enableFullScreenSwipeNavigationGesture = thunderState.enableFullScreenSwipeNavigationGesture; + + try { + feedBloc = context.read(); + } catch (e) { + // Don't need feed block if we're not opening post in the context of a feed. + } + + await Navigator.of(context).push(SwipeablePageRoute( + transitionDuration: reduceAnimations ? const Duration(milliseconds: 100) : null, + canSwipe: Platform.isIOS || enableFullScreenSwipeNavigationGesture, + canOnlySwipeFromEdge: true, + backGestureDetectionWidth: 45, + builder: (navigatorContext) { + return MultiBlocProvider( + providers: [ + feedBloc != null ? BlocProvider.value(value: feedBloc) : BlocProvider(create: (context) => FeedBloc(lemmyClient: LemmyClient.instance)), + BlocProvider.value(value: thunderBloc), + BlocProvider.value(value: accountBloc), + BlocProvider.value(value: createPostCubit), + ], + child: CreatePostPage( + title: title, + text: text, + image: image, + url: url, + prePopulated: prePopulated, + communityId: communityId ?? postViewMedia?.postView.community.id, + communityView: communityView ?? + (postViewMedia != null + ? CommunityView( + community: postViewMedia.postView.community, + subscribed: postViewMedia.postView.subscribed, + blocked: false, + counts: CommunityAggregates( + communityId: postViewMedia.postView.community.id, + subscribers: 0, + posts: 0, + comments: 0, + published: DateTime.now(), + usersActiveDay: 0, + usersActiveWeek: 0, + usersActiveMonth: 0, + usersActiveHalfYear: 0, + ), + ) + : null), + postView: postViewMedia?.postView, + onPostSuccess: (PostViewMedia pvm, bool userChanged) { + // Update the existing post view media if it exists + if (feedBloc != null && postViewMedia != null) feedBloc.add(FeedItemUpdatedEvent(postViewMedia: pvm)); + + // Show snackbar message if the post was just created + if (!userChanged && postViewMedia == null) { + try { + showSnackbar( + l10n.postCreatedSuccessfully, + trailingIcon: Icons.remove_red_eye_rounded, + trailingAction: () { + navigateToPost(navigatorContext, postViewMedia: pvm); + }, + ); + } catch (e) { + if (context.mounted) showSnackbar("${AppLocalizations.of(context)!.unexpectedError}: $e"); + } + } + + if (onPostSuccess != null) onPostSuccess(pvm, userChanged); + }, + ), + ); + }, + )); + } catch (e) { + if (context.mounted) showSnackbar(AppLocalizations.of(context)!.unexpectedError); + } +} + +void navigateToNotificationReplyPage(BuildContext context, {required int? replyId, required String? accountId}) async { + // It can take a little while to set up notifications, so show a loading page + showLoadingPage(context); + + final ThunderBloc thunderBloc = context.read(); + final bool reduceAnimations = thunderBloc.state.reduceAnimations; + Account? account = await fetchActiveProfileAccount(); + + bool switchedAccount = false; + String? originalAccount = account?.id; + String? originalAnonymousInstance = context.mounted ? context.read().state.currentAnonymousInstance : null; + + if (account?.id != accountId && accountId != null && context.mounted) { + // Switch to the notification's account without reloading the app + context.read().add(SwitchAccount(accountId: accountId, reload: false)); + + // Set the account locally here so we don't have to wait for the event to complete + account = await Account.fetchAccount(accountId); + + // Note that we switched so we can switch back + switchedAccount = true; + } + + // If account is still null, we can't do anything. + if (account == null) return; + + List allReplies = []; + CommentReplyView? specificReply; + + bool doneFetching = false; + int currentPage = 1; + + // Load the notifications + while (!doneFetching) { + final GetRepliesResponse getRepliesResponse = await (LemmyClient()..changeBaseUrl(account.instance)).lemmyApiV3.run(GetReplies( + sort: CommentSortType.new_, + page: currentPage, + limit: 50, + unreadOnly: replyId == null, + auth: account.jwt, + )); + + allReplies.addAll(getRepliesResponse.replies); + specificReply ??= getRepliesResponse.replies.firstWhereOrNull((crv) => crv.commentReply.id == replyId); + + doneFetching = specificReply != null || getRepliesResponse.replies.isEmpty; + ++currentPage; + } + + if (context.mounted) { + final NotificationsReplyPage notificationsReplyPage = NotificationsReplyPage(replies: specificReply == null ? allReplies : [specificReply]); + + final SwipeablePageRoute route = SwipeablePageRoute( + transitionDuration: isLoadingPageShown + ? Duration.zero + : reduceAnimations + ? const Duration(milliseconds: 100) + : null, + reverseTransitionDuration: reduceAnimations ? const Duration(milliseconds: 100) : const Duration(milliseconds: 500), + backGestureDetectionWidth: 45, + canSwipe: Platform.isIOS || thunderBloc.state.enableFullScreenSwipeNavigationGesture, + canOnlySwipeFromEdge: !thunderBloc.state.enableFullScreenSwipeNavigationGesture, + builder: (context) => MultiBlocProvider( + providers: [ + BlocProvider.value(value: thunderBloc), + ], + child: notificationsReplyPage, + ), + ); + + pushOnTopOfLoadingPage(context, route).then((_) { + // If needed, switch back to the original account or anonymous instance + if (switchedAccount) { + if (originalAccount != null) { + // We switched from an account, so switch back + context.read().add(SwitchAccount(accountId: originalAccount, reload: false)); + } else if (originalAnonymousInstance != null) { + // We switched from anonymous, so switch back + context.read().add(const LogOutOfAllAccounts()); + context.read().add(OnSetCurrentAnonymousInstance(originalAnonymousInstance)); + context.read().add(InstanceChanged(instance: originalAnonymousInstance)); + } + } + + context.read().add(const GetInboxEvent(reset: true, inboxType: InboxType.all)); + }); + } +} + +/// Navigates to the [ReportFeedPage] page. +/// +/// The [context] parameter should contain the following blocs within its widget tree: [FeedBloc], [ThunderBloc] +void navigateToReportPage(BuildContext context) { + final hasFeedBloc = context.findAncestorWidgetOfExactType>() != null; + assert(hasFeedBloc == true); + + final feedBloc = context.read(); + final thunderBloc = context.read(); + + final state = thunderBloc.state; + final reduceAnimations = state.reduceAnimations; + final enableFullScreenSwipeNavigationGesture = state.enableFullScreenSwipeNavigationGesture; + + Navigator.of(context).push( + SwipeablePageRoute( + transitionDuration: reduceAnimations ? const Duration(milliseconds: 100) : null, + canSwipe: Platform.isIOS || enableFullScreenSwipeNavigationGesture, + canOnlySwipeFromEdge: true, + builder: (_) { + return MultiBlocProvider( + providers: [ + BlocProvider.value(value: feedBloc), + BlocProvider.value(value: thunderBloc), + ], + child: const ReportFeedPage(), + ); + }, + ), + ); +} + +/// Navigates to a [FeedPage] with the given parameters +/// +/// [feedType] must be provided. +/// If [feedType] is [FeedType.general], [postListingType] must be provided +/// If [feedType] is [FeedType.community], one of [communityId] or [communityName] must be provided +/// If [feedType] is [FeedType.user], one of [userId] or [username] must be provided +/// +/// The [context] parameter should contain the following blocs within its widget tree: [AccountBloc], [AuthBloc], [ThunderBloc] +Future navigateToFeedPage( + BuildContext context, { + required FeedType feedType, + ListingType? postListingType, + SortType? sortType, + String? communityName, + int? communityId, + String? username, + int? userId, +}) async { + // Push navigation + AccountBloc accountBloc = context.read(); + AuthBloc authBloc = context.read(); + ThunderBloc thunderBloc = context.read(); + CommunityBloc communityBloc = context.read(); + InstanceBloc instanceBloc = context.read(); + AnonymousSubscriptionsBloc anonymousSubscriptionsBloc = context.read(); + + ThunderState thunderState = thunderBloc.state; + final bool reduceAnimations = thunderState.reduceAnimations; + + if (feedType == FeedType.general) { + return context.read().add( + FeedFetchedEvent( + feedType: feedType, + postListingType: postListingType, + sortType: sortType ?? authBloc.state.getSiteResponse?.myUser?.localUserView.localUser.defaultSortType ?? thunderBloc.state.sortTypeForInstance, + communityId: communityId, + communityName: communityName, + userId: userId, + username: username, + reset: true, + showHidden: thunderBloc.state.showHiddenPosts, + ), + ); + } + + SwipeablePageRoute route = SwipeablePageRoute( + transitionDuration: isLoadingPageShown + ? Duration.zero + : reduceAnimations + ? const Duration(milliseconds: 100) + : null, + reverseTransitionDuration: reduceAnimations ? const Duration(milliseconds: 100) : const Duration(milliseconds: 500), + backGestureDetectionWidth: 45, + canSwipe: Platform.isIOS || thunderState.enableFullScreenSwipeNavigationGesture, + canOnlySwipeFromEdge: disableFullPageSwipe(isUserLoggedIn: authBloc.state.isLoggedIn, state: thunderBloc.state, isFeedPage: true) || !thunderState.enableFullScreenSwipeNavigationGesture, + builder: (context) => MultiBlocProvider( + providers: [ + BlocProvider.value(value: accountBloc), + BlocProvider.value(value: authBloc), + BlocProvider.value(value: thunderBloc), + BlocProvider.value(value: instanceBloc), + BlocProvider.value(value: anonymousSubscriptionsBloc), + BlocProvider.value(value: communityBloc), + ], + child: Material( + child: FeedPage( + feedType: feedType, + sortType: sortType ?? authBloc.state.getSiteResponse?.myUser?.localUserView.localUser.defaultSortType ?? thunderBloc.state.sortTypeForInstance, + communityName: communityName, + communityId: communityId, + userId: userId, + username: username, + postListingType: postListingType, + showHidden: thunderBloc.state.showHiddenPosts, + ), + ), + ), + ); + + pushOnTopOfLoadingPage(context, route); +} + +/// Navigates to the search page +/// +/// The [context] parameter should contain the following blocs within its widget tree: [FeedBloc], [ThunderBloc] +void navigateToSearchPage(BuildContext context) { + final hasFeedBloc = context.findAncestorWidgetOfExactType>() != null; + assert(hasFeedBloc == true); + + final feedBloc = context.read(); + final thunderBloc = context.read(); + + final state = thunderBloc.state; + final reduceAnimations = state.reduceAnimations; + final enableFullScreenSwipeNavigationGesture = state.enableFullScreenSwipeNavigationGesture; + + Navigator.of(context).push( + SwipeablePageRoute( + transitionDuration: reduceAnimations ? const Duration(milliseconds: 100) : null, + canSwipe: Platform.isIOS || enableFullScreenSwipeNavigationGesture, + canOnlySwipeFromEdge: true, + builder: (context) => MultiBlocProvider( + providers: [ + BlocProvider(create: (context) => SearchBloc()), + BlocProvider.value(value: thunderBloc), + ], + child: SearchPage(communityToSearch: feedBloc.state.fullCommunityView!.communityView, isInitiallyFocused: true), + ), + ), + ); +} + +/// Navigates to a given Setting page. This includes sub-pages (e.g., Account -> Blocklist, Appearance -> Posts, etc.) +/// +/// Additionally, the [settingToHighlight] parameter can be used to highlight a specific setting when the page is opened. +void navigateToSettingPage(BuildContext context, LocalSettings setting, {LocalSettings? settingToHighlight}) { + final thunderBloc = context.read(); + final accountBloc = context.read(); + + final state = thunderBloc.state; + final reduceAnimations = state.reduceAnimations; + final enableFullScreenSwipeNavigationGesture = state.enableFullScreenSwipeNavigationGesture; + + String pageToNav = { + LocalSettingsCategories.posts: SETTINGS_APPEARANCE_POSTS_PAGE, + LocalSettingsCategories.comments: SETTINGS_APPEARANCE_COMMENTS_PAGE, + LocalSettingsCategories.general: SETTINGS_GENERAL_PAGE, + LocalSettingsCategories.gestures: SETTINGS_GESTURES_PAGE, + LocalSettingsCategories.floatingActionButton: SETTINGS_FAB_PAGE, + LocalSettingsCategories.filters: SETTINGS_FILTERS_PAGE, + LocalSettingsCategories.accessibility: SETTINGS_ACCESSIBILITY_PAGE, + LocalSettingsCategories.account: SETTINGS_ACCOUNT_PAGE, + LocalSettingsCategories.accountBlocklist: SETTINGS_ACCOUNT_BLOCKLIST_PAGE, + LocalSettingsCategories.accountLanguages: SETTINGS_ACCOUNT_LANGUAGES_PAGE, + LocalSettingsCategories.accountMediaManagement: SETTINGS_ACCOUNT_MEDIA_PAGE, + LocalSettingsCategories.userLabels: SETTINGS_USER_LABELS_PAGE, + LocalSettingsCategories.theming: SETTINGS_APPEARANCE_THEMES_PAGE, + LocalSettingsCategories.debug: SETTINGS_DEBUG_PAGE, + LocalSettingsCategories.about: SETTINGS_ABOUT_PAGE, + LocalSettingsCategories.videoPlayer: SETTINGS_VIDEO_PAGE, + LocalSettingsCategories.appearance: SETTINGS_APPEARANCE_PAGE, + }[setting.category] ?? + SETTINGS_GENERAL_PAGE; + + if (pageToNav == SETTINGS_ABOUT_PAGE) { + final authBloc = context.read(); + + Navigator.of(context).push( + SwipeablePageRoute( + transitionDuration: reduceAnimations ? const Duration(milliseconds: 100) : null, + canSwipe: Platform.isIOS || enableFullScreenSwipeNavigationGesture, + canOnlySwipeFromEdge: true, + builder: (context) => MultiBlocProvider( + providers: [ + BlocProvider.value(value: accountBloc), + BlocProvider.value(value: thunderBloc), + BlocProvider.value(value: authBloc), + ], + child: AboutSettingsPage(settingToHighlight: settingToHighlight ?? setting), + ), + ), + ); + } else if (pageToNav == SETTINGS_ACCOUNT_MEDIA_PAGE) { + final hasUserSettingsBloc = context.findAncestorWidgetOfExactType>() != null; + + final userSettingsBloc = hasUserSettingsBloc ? context.read() : UserSettingsBloc(); + final authBloc = context.read(); + + userSettingsBloc.add(const ListMediaEvent()); + + Navigator.of(context).push( + SwipeablePageRoute( + transitionDuration: reduceAnimations ? const Duration(milliseconds: 100) : null, + canSwipe: Platform.isIOS || enableFullScreenSwipeNavigationGesture, + canOnlySwipeFromEdge: true, + builder: (context) => MultiBlocProvider( + providers: [ + BlocProvider.value(value: thunderBloc), + BlocProvider.value(value: authBloc), + BlocProvider.value(value: userSettingsBloc), + ], + child: MediaManagementPage(), + ), + ), + ); + } else { + final hasUserSettingsBloc = context.findAncestorWidgetOfExactType>() != null; + final userSettingsBloc = hasUserSettingsBloc ? context.read() : UserSettingsBloc(); + + Navigator.of(context).push( + SwipeablePageRoute( + transitionDuration: reduceAnimations ? const Duration(milliseconds: 100) : null, + canSwipe: Platform.isIOS || enableFullScreenSwipeNavigationGesture, + canOnlySwipeFromEdge: true, + builder: (context) => MultiBlocProvider( + providers: [ + BlocProvider.value(value: accountBloc), + BlocProvider.value(value: thunderBloc), + BlocProvider.value(value: userSettingsBloc), + ], + child: switch (pageToNav) { + SETTINGS_GENERAL_PAGE => GeneralSettingsPage(settingToHighlight: settingToHighlight ?? setting), + SETTINGS_APPEARANCE_POSTS_PAGE => PostAppearanceSettingsPage(settingToHighlight: settingToHighlight ?? setting), + SETTINGS_APPEARANCE_COMMENTS_PAGE => CommentAppearanceSettingsPage(settingToHighlight: settingToHighlight ?? setting), + SETTINGS_GESTURES_PAGE => GestureSettingsPage(settingToHighlight: settingToHighlight ?? setting), + SETTINGS_FAB_PAGE => GestureSettingsPage(settingToHighlight: settingToHighlight ?? setting), + SETTINGS_FILTERS_PAGE => FilterSettingsPage(settingToHighlight: settingToHighlight ?? setting), + SETTINGS_ACCOUNT_PAGE => UserSettingsPage(settingToHighlight: settingToHighlight ?? setting), + SETTINGS_ACCOUNT_LANGUAGES_PAGE => DiscussionLanguageSelector(), + SETTINGS_ACCOUNT_BLOCKLIST_PAGE => UserSettingsBlockPage(), + SETTINGS_APPEARANCE_THEMES_PAGE => ThemeSettingsPage(settingToHighlight: settingToHighlight ?? setting), + SETTINGS_DEBUG_PAGE => DebugSettingsPage(settingToHighlight: settingToHighlight ?? setting), + SETTINGS_VIDEO_PAGE => VideoPlayerSettingsPage(settingToHighlight: settingToHighlight ?? setting), + SETTINGS_USER_LABELS_PAGE => UserLabelSettingsPage(settingToHighlight: settingToHighlight ?? setting), + SETTINGS_ACCESSIBILITY_PAGE => AccessibilitySettingsPage(settingToHighlight: settingToHighlight ?? setting), + SETTINGS_APPEARANCE_PAGE => AppearanceSettingsPage(settingToHighlight: settingToHighlight ?? setting), + _ => Container(), + }, + ), + ), + ); + } +} + +/// Navigates to the given [url] in a webview. +void navigateToWebView(BuildContext context, String url) { + final thunderBloc = context.read(); + + final state = thunderBloc.state; + final reduceAnimations = state.reduceAnimations; + final enableFullScreenSwipeNavigationGesture = state.enableFullScreenSwipeNavigationGesture; + + SwipeablePageRoute route = SwipeablePageRoute( + transitionDuration: isLoadingPageShown + ? Duration.zero + : reduceAnimations + ? const Duration(milliseconds: 100) + : null, + reverseTransitionDuration: reduceAnimations ? const Duration(milliseconds: 100) : const Duration(milliseconds: 500), + canSwipe: Platform.isIOS || enableFullScreenSwipeNavigationGesture, + canOnlySwipeFromEdge: true, + builder: (context) => WebView(url: url), + ); + + pushOnTopOfLoadingPage(context, route); +} diff --git a/lib/utils/settings_utils.dart b/lib/utils/settings_utils.dart index 20adc0544..1e083ae21 100644 --- a/lib/utils/settings_utils.dart +++ b/lib/utils/settings_utils.dart @@ -1,105 +1,10 @@ -import 'dart:io'; - import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; -import 'package:flutter_bloc/flutter_bloc.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'; -import 'package:thunder/core/enums/local_settings.dart'; -import 'package:thunder/settings/pages/about_settings_page.dart'; -import 'package:thunder/settings/pages/accessibility_settings_page.dart'; -import 'package:thunder/settings/pages/appearance_settings_page.dart'; -import 'package:thunder/settings/pages/comment_appearance_settings_page.dart'; -import 'package:thunder/settings/pages/debug_settings_page.dart'; -import 'package:thunder/settings/pages/filter_settings_page.dart'; -import 'package:thunder/settings/pages/general_settings_page.dart'; -import 'package:thunder/settings/pages/gesture_settings_page.dart'; -import 'package:thunder/settings/pages/post_appearance_settings_page.dart'; -import 'package:thunder/settings/pages/theme_settings_page.dart'; -import 'package:thunder/settings/pages/user_labels_settings_page.dart'; -import 'package:thunder/settings/pages/video_player_settings.dart'; -import 'package:thunder/shared/snackbar.dart'; -import 'package:thunder/thunder/bloc/thunder_bloc.dart'; -import 'package:thunder/user/bloc/user_settings_bloc.dart'; -import 'package:thunder/user/pages/user_settings_page.dart'; -import 'package:thunder/utils/constants.dart'; -import 'package:flutter_gen/gen_l10n/app_localizations.dart'; - -void navigateToSetting(BuildContext context, LocalSettings setting) { - String pageToNav = { - LocalSettingsCategories.posts: SETTINGS_APPEARANCE_POSTS_PAGE, - LocalSettingsCategories.comments: SETTINGS_APPEARANCE_COMMENTS_PAGE, - LocalSettingsCategories.general: SETTINGS_GENERAL_PAGE, - LocalSettingsCategories.gestures: SETTINGS_GESTURES_PAGE, - LocalSettingsCategories.floatingActionButton: SETTINGS_FAB_PAGE, - LocalSettingsCategories.filters: SETTINGS_FILTERS_PAGE, - LocalSettingsCategories.accessibility: SETTINGS_ACCESSIBILITY_PAGE, - LocalSettingsCategories.account: SETTINGS_ACCOUNT_PAGE, - LocalSettingsCategories.userLabels: SETTINGS_USER_LABELS_PAGE, - LocalSettingsCategories.theming: SETTINGS_APPEARANCE_THEMES_PAGE, - LocalSettingsCategories.debug: SETTINGS_DEBUG_PAGE, - LocalSettingsCategories.about: SETTINGS_ABOUT_PAGE, - LocalSettingsCategories.videoPlayer: SETTINGS_VIDEO_PAGE, - LocalSettingsCategories.appearance: SETTINGS_APPEARANCE_PAGE, - }[setting.category] ?? - SETTINGS_GENERAL_PAGE; - if (pageToNav == SETTINGS_ABOUT_PAGE) { - final AccountBloc accountBloc = context.read(); - final ThunderBloc thunderBloc = context.read(); - final AuthBloc authBloc = context.read(); - - Navigator.of(context).push( - SwipeablePageRoute( - transitionDuration: thunderBloc.state.reduceAnimations ? const Duration(milliseconds: 100) : null, - canSwipe: Platform.isIOS || thunderBloc.state.enableFullScreenSwipeNavigationGesture, - canOnlySwipeFromEdge: !thunderBloc.state.enableFullScreenSwipeNavigationGesture, - builder: (context) => MultiBlocProvider( - providers: [ - BlocProvider.value(value: accountBloc), - BlocProvider.value(value: thunderBloc), - BlocProvider.value(value: authBloc), - ], - child: AboutSettingsPage(settingToHighlight: setting), - ), - ), - ); - } else { - final ThunderBloc thunderBloc = context.read(); - final UserSettingsBloc userSettingsBloc = UserSettingsBloc(); +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; - Navigator.of(context).push( - SwipeablePageRoute( - transitionDuration: thunderBloc.state.reduceAnimations ? const Duration(milliseconds: 100) : null, - canSwipe: Platform.isIOS || thunderBloc.state.enableFullScreenSwipeNavigationGesture, - canOnlySwipeFromEdge: !thunderBloc.state.enableFullScreenSwipeNavigationGesture, - builder: (context) => MultiBlocProvider( - providers: [ - BlocProvider.value(value: thunderBloc), - BlocProvider.value(value: userSettingsBloc), - ], - child: switch (pageToNav) { - SETTINGS_GENERAL_PAGE => GeneralSettingsPage(settingToHighlight: setting), - SETTINGS_APPEARANCE_POSTS_PAGE => PostAppearanceSettingsPage(settingToHighlight: setting), - SETTINGS_APPEARANCE_COMMENTS_PAGE => CommentAppearanceSettingsPage(settingToHighlight: setting), - SETTINGS_GESTURES_PAGE => GestureSettingsPage(settingToHighlight: setting), - SETTINGS_FAB_PAGE => GestureSettingsPage(settingToHighlight: setting), - SETTINGS_FILTERS_PAGE => FilterSettingsPage(settingToHighlight: setting), - SETTINGS_ACCOUNT_PAGE => UserSettingsPage(settingToHighlight: setting), - SETTINGS_APPEARANCE_THEMES_PAGE => ThemeSettingsPage(settingToHighlight: setting), - SETTINGS_DEBUG_PAGE => DebugSettingsPage(settingToHighlight: setting), - SETTINGS_VIDEO_PAGE => VideoPlayerSettingsPage(settingToHighlight: setting), - SETTINGS_USER_LABELS_PAGE => UserLabelSettingsPage(settingToHighlight: setting), - SETTINGS_ACCESSIBILITY_PAGE => AccessibilitySettingsPage(settingToHighlight: setting), - SETTINGS_APPEARANCE_PAGE => AppearanceSettingsPage(settingToHighlight: setting), - _ => Container(), - }, - ), - ), - ); - } -} +import 'package:thunder/core/enums/local_settings.dart'; +import 'package:thunder/shared/snackbar.dart'; void shareSetting(BuildContext context, LocalSettings? setting, String description) { if (setting == null) return; diff --git a/pubspec.lock b/pubspec.lock index fe656aae3..cc55e2d59 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -530,10 +530,10 @@ packages: dependency: "direct main" description: name: flex_color_scheme - sha256: "09bea5d776f694c5a67f2229f2aa500cc7cce369322dc6500ab01cf9ad1b4e1a" + sha256: ae638050fceb35b6040a43cf67892f9b956022068e736284919d93322fdd4ba2 url: "https://pub.dev" source: hosted - version: "8.1.0" + version: "8.1.1" flex_seed_scheme: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 435174c95..eb1ff2078 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -46,7 +46,7 @@ dependencies: expandable: "^5.0.1" extended_image: ^9.0.7 fading_edge_scrollview: "^4.1.1" - flex_color_scheme: "^8.0.0" + flex_color_scheme: "^8.1.1" flutter_bloc: "^8.1.3" flutter_cache_manager: "^3.3.0" flutter_custom_tabs: "^2.0.0-beta.1"