Change error prompts
This commit is contained in:
@@ -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),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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(
|
||||||
|
|||||||
@@ -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);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -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(),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -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);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -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)),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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(),
|
||||||
|
|||||||
@@ -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,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
Reference in New Issue
Block a user