Change error prompts

This commit is contained in:
problematicconsumer
2023-08-26 17:01:51 +03:30
parent f393020a31
commit 2ecb781f60
15 changed files with 88 additions and 48 deletions

View File

@@ -14,9 +14,9 @@ sealed class UpdateFailure with _$UpdateFailure, Failure {
]) = UpdateUnexpectedFailure; ]) = UpdateUnexpectedFailure;
@override @override
String present(TranslationsEn t) { ({String type, String? message}) present(TranslationsEn t) {
return switch (this) { return switch (this) {
UpdateUnexpectedFailure() => t.failure.unexpected, UpdateUnexpectedFailure() => (type: t.failure.unexpected, message: null),
}; };
} }
} }

View File

@@ -25,15 +25,20 @@ sealed class ConnectionFailure with _$ConnectionFailure, Failure {
CoreConnectionFailure; CoreConnectionFailure;
@override @override
String present(TranslationsEn t) { ({String type, String? message}) present(TranslationsEn t) {
return switch (this) { return switch (this) {
UnexpectedConnectionFailure() => t.failure.connectivity.unexpected, UnexpectedConnectionFailure() => (
MissingVpnPermission(:final message) => type: t.failure.connectivity.unexpected,
t.failure.connectivity.missingVpnPermission + message: null
(message == null ? "" : ": $message"), ),
MissingNotificationPermission(:final message) => MissingVpnPermission(:final message) => (
t.failure.connectivity.missingNotificationPermission + type: t.failure.connectivity.missingVpnPermission,
(message == null ? "" : ": $message"), message: message
),
MissingNotificationPermission(:final message) => (
type: t.failure.connectivity.missingNotificationPermission,
message: message
),
CoreConnectionFailure(:final failure) => failure.present(t), CoreConnectionFailure(:final failure) => failure.present(t),
}; };
} }

View File

@@ -42,19 +42,32 @@ sealed class CoreServiceFailure with _$CoreServiceFailure, Failure {
}; };
@override @override
String present(TranslationsEn t) { ({String type, String? message}) present(TranslationsEn t) {
return switch (this) { return switch (this) {
UnexpectedCoreServiceFailure() => t.failure.singbox.unexpected, UnexpectedCoreServiceFailure() => (
CoreServiceNotRunning(:final message) => type: t.failure.singbox.unexpected,
t.failure.singbox.serviceNotRunning + message: null
(message == null ? "" : ": $message"), ),
InvalidConfig(:final message) => CoreServiceNotRunning(:final message) => (
t.failure.singbox.invalidConfig + (message == null ? "" : ": $message"), type: t.failure.singbox.serviceNotRunning,
CoreServiceCreateFailure(:final message) => message: message
t.failure.singbox.create + (message == null ? "" : ": $message"), ),
CoreServiceStartFailure(:final message) => InvalidConfig(:final message) => (
t.failure.singbox.start + (message == null ? "" : ": $message"), type: t.failure.singbox.invalidConfig,
CoreServiceOtherFailure(:final message) => message ?? "", 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
),
}; };
} }
} }

View File

@@ -2,12 +2,20 @@ import 'package:hiddify/core/locale/locale.dart';
// TODO: rewrite // TODO: rewrite
mixin Failure { mixin Failure {
String present(TranslationsEn t); ({String type, String? message}) present(TranslationsEn t);
} }
extension ErrorPresenter on TranslationsEn { extension ErrorPresenter on TranslationsEn {
String presentError(Object error) { String printError(Object error) {
if (error case Failure()) return error.present(this); if (error case Failure()) {
final err = error.present(this);
return err.type + (err.message == null ? "" : ": ${err.message}");
}
return failure.unexpected; return failure.unexpected;
} }
({String type, String? message}) presentError(Object error) {
if (error case Failure()) return error.present(this);
return (type: failure.unexpected, message: null);
}
} }

View File

@@ -19,13 +19,20 @@ sealed class ProfileFailure with _$ProfileFailure, Failure {
ProfileInvalidConfigFailure; ProfileInvalidConfigFailure;
@override @override
String present(TranslationsEn t) { ({String type, String? message}) present(TranslationsEn t) {
return switch (this) { return switch (this) {
ProfileUnexpectedFailure() => t.failure.profiles.unexpected, ProfileUnexpectedFailure() => (
ProfileNotFoundFailure() => t.failure.profiles.notFound, type: t.failure.profiles.unexpected,
ProfileInvalidConfigFailure(:final message) => message: null
t.failure.profiles.invalidConfig + ),
(message == null ? "" : ": $message"), ProfileNotFoundFailure() => (
type: t.failure.profiles.notFound,
message: null
),
ProfileInvalidConfigFailure(:final message) => (
type: t.failure.profiles.invalidConfig,
message: message
),
}; };
} }
} }

View File

@@ -33,7 +33,7 @@ class AboutPage extends HookConsumerWidget {
if (next case AsyncData(:final value)) { if (next case AsyncData(:final value)) {
switch (value.latestVersion) { switch (value.latestVersion) {
case AsyncError(:final error): case AsyncError(:final error):
CustomToast.error(t.presentError(error)).show(context); CustomToast.error(t.printError(error)).show(context);
default: default:
if (value.newVersionAvailable) { if (value.newVersionAvailable) {
await NewVersionDialog( await NewVersionDialog(

View File

@@ -31,7 +31,7 @@ class ProfileTile extends HookConsumerWidget {
final selectActiveMutation = useMutation( final selectActiveMutation = useMutation(
initialOnFailure: (err) { 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( final updateProfileMutation = useMutation(
initialOnFailure: (err) { initialOnFailure: (err) {
CustomToast.error(t.presentError(err)).show(context); // CustomToast.error(t.printError(err)).show(context);
CustomAlertDialog.fromErr(t.presentError(err)).show(context);
}, },
initialOnSuccess: () => initialOnSuccess: () =>
CustomToast.success(t.profile.update.successMsg).show(context), CustomToast.success(t.profile.update.successMsg).show(context),
@@ -204,14 +205,14 @@ class ProfileActionsMenu extends HookConsumerWidget {
final updateProfileMutation = useMutation( final updateProfileMutation = useMutation(
initialOnFailure: (err) { initialOnFailure: (err) {
CustomToast.error(t.presentError(err)).show(context); CustomAlertDialog.fromErr(t.presentError(err)).show(context);
}, },
initialOnSuccess: () => initialOnSuccess: () =>
CustomToast.success(t.profile.update.successMsg).show(context), CustomToast.success(t.profile.update.successMsg).show(context),
); );
final deleteProfileMutation = useMutation( final deleteProfileMutation = useMutation(
initialOnFailure: (err) { initialOnFailure: (err) {
CustomToast.error(t.presentError(err)).show(context); CustomAlertDialog.fromErr(t.presentError(err)).show(context);
}, },
); );

View File

@@ -67,7 +67,7 @@ class HomePage extends HookConsumerWidget {
_ => const EmptyProfilesHomeBody(), _ => const EmptyProfilesHomeBody(),
}, },
AsyncError(:final error) => AsyncError(:final error) =>
SliverErrorBodyPlaceholder(t.presentError(error)), SliverErrorBodyPlaceholder(t.printError(error)),
_ => const SliverToBoxAdapter(), _ => const SliverToBoxAdapter(),
}, },
], ],

View File

@@ -24,13 +24,12 @@ class ConnectionButton extends HookConsumerWidget {
connectivityControllerProvider, connectivityControllerProvider,
(_, next) { (_, next) {
if (next case AsyncError(:final error)) { if (next case AsyncError(:final error)) {
CustomToast.error(t.presentError(error)).show(context); CustomAlertDialog.fromErr(t.presentError(error)).show(context);
} }
if (next if (next
case AsyncData(value: Disconnected(:final connectionFailure?))) { case AsyncData(value: Disconnected(:final connectionFailure?))) {
CustomAlertDialog( CustomAlertDialog.fromErr(t.presentError(connectionFailure))
message: connectionFailure.present(t), .show(context);
).show(context);
} }
}, },
); );

View File

@@ -138,7 +138,7 @@ class LogsPage extends HookConsumerWidget with PresLogger {
NestedTabAppBar( NestedTabAppBar(
title: Text(t.logs.pageTitle.titleCase), title: Text(t.logs.pageTitle.titleCase),
), ),
SliverErrorBodyPlaceholder(t.presentError(error)), SliverErrorBodyPlaceholder(t.printError(error)),
], ],
), ),
); );

View File

@@ -38,7 +38,7 @@ class ProfileDetailPage extends HookConsumerWidget with PresLogger {
if (asyncSave case AsyncData(value: final save)) { if (asyncSave case AsyncData(value: final save)) {
switch (save) { switch (save) {
case MutationFailure(:final failure): case MutationFailure(:final failure):
CustomToast.error(t.presentError(failure)).show(context); CustomToast.error(t.printError(failure)).show(context);
case MutationSuccess(): case MutationSuccess():
CustomToast.success(t.profile.save.successMsg.sentenceCase) CustomToast.success(t.profile.save.successMsg.sentenceCase)
.show(context); .show(context);
@@ -58,7 +58,7 @@ class ProfileDetailPage extends HookConsumerWidget with PresLogger {
if (asyncSave case AsyncData(value: final delete)) { if (asyncSave case AsyncData(value: final delete)) {
switch (delete) { switch (delete) {
case MutationFailure(:final failure): case MutationFailure(:final failure):
CustomToast.error(t.presentError(failure)).show(context); CustomToast.error(t.printError(failure)).show(context);
case MutationSuccess(): case MutationSuccess():
CustomToast.success(t.profile.delete.successMsg.sentenceCase) CustomToast.success(t.profile.delete.successMsg.sentenceCase)
.show(context); .show(context);

View File

@@ -30,7 +30,8 @@ class AddProfileModal extends HookConsumerWidget {
final addProfileMutation = useMutation( final addProfileMutation = useMutation(
initialOnFailure: (err) { initialOnFailure: (err) {
mutationTriggered.value = false; 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: () { initialOnSuccess: () {
CustomToast.success(t.profile.save.successMsg.sentenceCase) CustomToast.success(t.profile.save.successMsg.sentenceCase)

View File

@@ -38,7 +38,7 @@ class ProfilesModal extends HookConsumerWidget {
itemCount: profiles.length, itemCount: profiles.length,
), ),
AsyncError(:final error) => SliverErrorBodyPlaceholder( AsyncError(:final error) => SliverErrorBodyPlaceholder(
t.presentError(error), t.printError(error),
), ),
AsyncLoading() => const SliverLoadingBodyPlaceholder(), AsyncLoading() => const SliverLoadingBodyPlaceholder(),
_ => const SliverToBoxAdapter(), _ => const SliverToBoxAdapter(),

View File

@@ -22,7 +22,7 @@ class ProxiesPage extends HookConsumerWidget with PresLogger {
final selectActiveProxyMutation = useMutation( final selectActiveProxyMutation = useMutation(
initialOnFailure: (error) => initialOnFailure: (error) =>
CustomToast.error(t.presentError(error)).show(context), CustomToast.error(t.printError(error)).show(context),
); );
switch (asyncProxies) { switch (asyncProxies) {
@@ -148,7 +148,7 @@ class ProxiesPage extends HookConsumerWidget with PresLogger {
title: Text(t.proxies.pageTitle.titleCase), title: Text(t.proxies.pageTitle.titleCase),
), ),
SliverErrorBodyPlaceholder( SliverErrorBodyPlaceholder(
t.presentError(error), t.printError(error),
icon: null, icon: null,
), ),
], ],

View File

@@ -11,6 +11,12 @@ class CustomAlertDialog extends StatelessWidget {
final String? title; final String? title;
final String message; 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<void> show(BuildContext context) async { Future<void> show(BuildContext context) async {
await showDialog( await showDialog(
context: context, context: context,