diff --git a/lib/domain/app/update_failure.dart b/lib/domain/app/update_failure.dart index 7fc77027..4b695405 100644 --- a/lib/domain/app/update_failure.dart +++ b/lib/domain/app/update_failure.dart @@ -14,9 +14,9 @@ sealed class UpdateFailure with _$UpdateFailure, Failure { ]) = UpdateUnexpectedFailure; @override - String present(TranslationsEn t) { + ({String type, String? message}) present(TranslationsEn t) { return switch (this) { - UpdateUnexpectedFailure() => t.failure.unexpected, + UpdateUnexpectedFailure() => (type: t.failure.unexpected, message: null), }; } } diff --git a/lib/domain/connectivity/connection_failure.dart b/lib/domain/connectivity/connection_failure.dart index 37a0e105..a623ba37 100644 --- a/lib/domain/connectivity/connection_failure.dart +++ b/lib/domain/connectivity/connection_failure.dart @@ -25,15 +25,20 @@ sealed class ConnectionFailure with _$ConnectionFailure, Failure { CoreConnectionFailure; @override - String present(TranslationsEn t) { + ({String type, String? message}) present(TranslationsEn t) { return switch (this) { - UnexpectedConnectionFailure() => t.failure.connectivity.unexpected, - MissingVpnPermission(:final message) => - t.failure.connectivity.missingVpnPermission + - (message == null ? "" : ": $message"), - MissingNotificationPermission(:final message) => - t.failure.connectivity.missingNotificationPermission + - (message == null ? "" : ": $message"), + UnexpectedConnectionFailure() => ( + type: t.failure.connectivity.unexpected, + message: null + ), + MissingVpnPermission(:final message) => ( + type: t.failure.connectivity.missingVpnPermission, + message: message + ), + MissingNotificationPermission(:final message) => ( + type: t.failure.connectivity.missingNotificationPermission, + message: message + ), CoreConnectionFailure(:final failure) => failure.present(t), }; } diff --git a/lib/domain/core_service_failure.dart b/lib/domain/core_service_failure.dart index e27d15d6..bb0f4fce 100644 --- a/lib/domain/core_service_failure.dart +++ b/lib/domain/core_service_failure.dart @@ -42,19 +42,32 @@ sealed class CoreServiceFailure with _$CoreServiceFailure, Failure { }; @override - String present(TranslationsEn t) { + ({String type, String? message}) present(TranslationsEn t) { return switch (this) { - UnexpectedCoreServiceFailure() => t.failure.singbox.unexpected, - CoreServiceNotRunning(:final message) => - t.failure.singbox.serviceNotRunning + - (message == null ? "" : ": $message"), - InvalidConfig(:final message) => - t.failure.singbox.invalidConfig + (message == null ? "" : ": $message"), - CoreServiceCreateFailure(:final message) => - t.failure.singbox.create + (message == null ? "" : ": $message"), - CoreServiceStartFailure(:final message) => - t.failure.singbox.start + (message == null ? "" : ": $message"), - CoreServiceOtherFailure(:final message) => message ?? "", + UnexpectedCoreServiceFailure() => ( + type: t.failure.singbox.unexpected, + message: null + ), + CoreServiceNotRunning(:final message) => ( + type: t.failure.singbox.serviceNotRunning, + message: message + ), + InvalidConfig(:final message) => ( + type: t.failure.singbox.invalidConfig, + message: message + ), + CoreServiceCreateFailure(:final message) => ( + type: t.failure.singbox.create, + message: message + ), + CoreServiceStartFailure(:final message) => ( + type: t.failure.singbox.start, + message: message + ), + CoreServiceOtherFailure(:final message) => ( + type: t.failure.singbox.unexpected, + message: message + ), }; } } diff --git a/lib/domain/failures.dart b/lib/domain/failures.dart index 3b0b9458..f730faf6 100644 --- a/lib/domain/failures.dart +++ b/lib/domain/failures.dart @@ -2,12 +2,20 @@ import 'package:hiddify/core/locale/locale.dart'; // TODO: rewrite mixin Failure { - String present(TranslationsEn t); + ({String type, String? message}) present(TranslationsEn t); } extension ErrorPresenter on TranslationsEn { - String presentError(Object error) { - if (error case Failure()) return error.present(this); + String printError(Object error) { + if (error case Failure()) { + final err = error.present(this); + return err.type + (err.message == null ? "" : ": ${err.message}"); + } return failure.unexpected; } + + ({String type, String? message}) presentError(Object error) { + if (error case Failure()) return error.present(this); + return (type: failure.unexpected, message: null); + } } diff --git a/lib/domain/profiles/profiles_failure.dart b/lib/domain/profiles/profiles_failure.dart index 8dcba0e5..cc0c1c66 100644 --- a/lib/domain/profiles/profiles_failure.dart +++ b/lib/domain/profiles/profiles_failure.dart @@ -19,13 +19,20 @@ sealed class ProfileFailure with _$ProfileFailure, Failure { ProfileInvalidConfigFailure; @override - String present(TranslationsEn t) { + ({String type, String? message}) present(TranslationsEn t) { return switch (this) { - ProfileUnexpectedFailure() => t.failure.profiles.unexpected, - ProfileNotFoundFailure() => t.failure.profiles.notFound, - ProfileInvalidConfigFailure(:final message) => - t.failure.profiles.invalidConfig + - (message == null ? "" : ": $message"), + ProfileUnexpectedFailure() => ( + type: t.failure.profiles.unexpected, + message: null + ), + ProfileNotFoundFailure() => ( + type: t.failure.profiles.notFound, + message: null + ), + ProfileInvalidConfigFailure(:final message) => ( + type: t.failure.profiles.invalidConfig, + message: message + ), }; } } diff --git a/lib/features/about/view/about_page.dart b/lib/features/about/view/about_page.dart index a156f8fb..52a8d1e6 100644 --- a/lib/features/about/view/about_page.dart +++ b/lib/features/about/view/about_page.dart @@ -33,7 +33,7 @@ class AboutPage extends HookConsumerWidget { if (next case AsyncData(:final value)) { switch (value.latestVersion) { case AsyncError(:final error): - CustomToast.error(t.presentError(error)).show(context); + CustomToast.error(t.printError(error)).show(context); default: if (value.newVersionAvailable) { await NewVersionDialog( diff --git a/lib/features/common/profile_tile.dart b/lib/features/common/profile_tile.dart index a63d70da..70c6b038 100644 --- a/lib/features/common/profile_tile.dart +++ b/lib/features/common/profile_tile.dart @@ -31,7 +31,7 @@ class ProfileTile extends HookConsumerWidget { final selectActiveMutation = useMutation( initialOnFailure: (err) { - CustomToast.error(t.presentError(err)).show(context); + CustomToast.error(t.printError(err)).show(context); }, ); @@ -146,7 +146,8 @@ class ProfileActionButton extends HookConsumerWidget { final updateProfileMutation = useMutation( initialOnFailure: (err) { - CustomToast.error(t.presentError(err)).show(context); + // CustomToast.error(t.printError(err)).show(context); + CustomAlertDialog.fromErr(t.presentError(err)).show(context); }, initialOnSuccess: () => CustomToast.success(t.profile.update.successMsg).show(context), @@ -204,14 +205,14 @@ class ProfileActionsMenu extends HookConsumerWidget { final updateProfileMutation = useMutation( initialOnFailure: (err) { - CustomToast.error(t.presentError(err)).show(context); + CustomAlertDialog.fromErr(t.presentError(err)).show(context); }, initialOnSuccess: () => CustomToast.success(t.profile.update.successMsg).show(context), ); final deleteProfileMutation = useMutation( initialOnFailure: (err) { - CustomToast.error(t.presentError(err)).show(context); + CustomAlertDialog.fromErr(t.presentError(err)).show(context); }, ); diff --git a/lib/features/home/view/home_page.dart b/lib/features/home/view/home_page.dart index 669cd1ad..08086493 100644 --- a/lib/features/home/view/home_page.dart +++ b/lib/features/home/view/home_page.dart @@ -67,7 +67,7 @@ class HomePage extends HookConsumerWidget { _ => const EmptyProfilesHomeBody(), }, AsyncError(:final error) => - SliverErrorBodyPlaceholder(t.presentError(error)), + SliverErrorBodyPlaceholder(t.printError(error)), _ => const SliverToBoxAdapter(), }, ], diff --git a/lib/features/home/widgets/connection_button.dart b/lib/features/home/widgets/connection_button.dart index ba242018..7154a333 100644 --- a/lib/features/home/widgets/connection_button.dart +++ b/lib/features/home/widgets/connection_button.dart @@ -24,13 +24,12 @@ class ConnectionButton extends HookConsumerWidget { connectivityControllerProvider, (_, next) { if (next case AsyncError(:final error)) { - CustomToast.error(t.presentError(error)).show(context); + CustomAlertDialog.fromErr(t.presentError(error)).show(context); } if (next case AsyncData(value: Disconnected(:final connectionFailure?))) { - CustomAlertDialog( - message: connectionFailure.present(t), - ).show(context); + CustomAlertDialog.fromErr(t.presentError(connectionFailure)) + .show(context); } }, ); diff --git a/lib/features/logs/view/logs_page.dart b/lib/features/logs/view/logs_page.dart index 48e4f1d2..e97a2f07 100644 --- a/lib/features/logs/view/logs_page.dart +++ b/lib/features/logs/view/logs_page.dart @@ -138,7 +138,7 @@ class LogsPage extends HookConsumerWidget with PresLogger { NestedTabAppBar( title: Text(t.logs.pageTitle.titleCase), ), - SliverErrorBodyPlaceholder(t.presentError(error)), + SliverErrorBodyPlaceholder(t.printError(error)), ], ), ); diff --git a/lib/features/profile_detail/view/profile_detail_page.dart b/lib/features/profile_detail/view/profile_detail_page.dart index 7e402b21..713b8838 100644 --- a/lib/features/profile_detail/view/profile_detail_page.dart +++ b/lib/features/profile_detail/view/profile_detail_page.dart @@ -38,7 +38,7 @@ class ProfileDetailPage extends HookConsumerWidget with PresLogger { if (asyncSave case AsyncData(value: final save)) { switch (save) { case MutationFailure(:final failure): - CustomToast.error(t.presentError(failure)).show(context); + CustomToast.error(t.printError(failure)).show(context); case MutationSuccess(): CustomToast.success(t.profile.save.successMsg.sentenceCase) .show(context); @@ -58,7 +58,7 @@ class ProfileDetailPage extends HookConsumerWidget with PresLogger { if (asyncSave case AsyncData(value: final delete)) { switch (delete) { case MutationFailure(:final failure): - CustomToast.error(t.presentError(failure)).show(context); + CustomToast.error(t.printError(failure)).show(context); case MutationSuccess(): CustomToast.success(t.profile.delete.successMsg.sentenceCase) .show(context); diff --git a/lib/features/profiles/view/add_profile_modal.dart b/lib/features/profiles/view/add_profile_modal.dart index c0f36d33..0f39ec38 100644 --- a/lib/features/profiles/view/add_profile_modal.dart +++ b/lib/features/profiles/view/add_profile_modal.dart @@ -30,7 +30,8 @@ class AddProfileModal extends HookConsumerWidget { final addProfileMutation = useMutation( initialOnFailure: (err) { mutationTriggered.value = false; - CustomToast.error(t.presentError(err)).show(context); + // CustomToast.error(t.presentError(err)).show(context); + CustomAlertDialog.fromErr(t.presentError(err)).show(context); }, initialOnSuccess: () { CustomToast.success(t.profile.save.successMsg.sentenceCase) diff --git a/lib/features/profiles/view/profiles_modal.dart b/lib/features/profiles/view/profiles_modal.dart index abc43b7b..975bbc87 100644 --- a/lib/features/profiles/view/profiles_modal.dart +++ b/lib/features/profiles/view/profiles_modal.dart @@ -38,7 +38,7 @@ class ProfilesModal extends HookConsumerWidget { itemCount: profiles.length, ), AsyncError(:final error) => SliverErrorBodyPlaceholder( - t.presentError(error), + t.printError(error), ), AsyncLoading() => const SliverLoadingBodyPlaceholder(), _ => const SliverToBoxAdapter(), diff --git a/lib/features/proxies/view/proxies_page.dart b/lib/features/proxies/view/proxies_page.dart index fad1472b..45a55e61 100644 --- a/lib/features/proxies/view/proxies_page.dart +++ b/lib/features/proxies/view/proxies_page.dart @@ -22,7 +22,7 @@ class ProxiesPage extends HookConsumerWidget with PresLogger { final selectActiveProxyMutation = useMutation( initialOnFailure: (error) => - CustomToast.error(t.presentError(error)).show(context), + CustomToast.error(t.printError(error)).show(context), ); switch (asyncProxies) { @@ -148,7 +148,7 @@ class ProxiesPage extends HookConsumerWidget with PresLogger { title: Text(t.proxies.pageTitle.titleCase), ), SliverErrorBodyPlaceholder( - t.presentError(error), + t.printError(error), icon: null, ), ], diff --git a/lib/utils/alerts.dart b/lib/utils/alerts.dart index 7239d8c4..8edc0913 100644 --- a/lib/utils/alerts.dart +++ b/lib/utils/alerts.dart @@ -11,6 +11,12 @@ class CustomAlertDialog extends StatelessWidget { final String? title; final String message; + factory CustomAlertDialog.fromErr(({String type, String? message}) err) => + CustomAlertDialog( + title: err.message == null ? null : err.type, + message: err.message ?? err.type, + ); + Future show(BuildContext context) async { await showDialog( context: context,