multiple payout page and small fixes

This commit is contained in:
Arseni
2026-02-11 02:48:30 +03:00
parent 66989ea36c
commit edb43f9909
77 changed files with 2120 additions and 1289 deletions

View File

@@ -16,6 +16,14 @@ class ErrorHandler {
'unauthorized': locs.errorLoginUnauthorized,
'verification_token_not_found': locs.errorVerificationTokenNotFound,
'internal_error': locs.errorInternalError,
'invalid_target': locs.errorInvalidTarget,
'pending_token_required': locs.errorPendingTokenRequired,
'missing_destination': locs.errorMissingDestination,
'missing_code': locs.errorMissingCode,
'missing_session': locs.errorMissingSession,
'token_expired': locs.errorTokenExpired,
'code_attempts_exceeded': locs.errorCodeAttemptsExceeded,
'too_many_requests': locs.errorTooManyRequests,
'data_conflict': locs.errorDataConflict,
'access_denied': locs.errorAccessDenied,

View File

@@ -15,18 +15,23 @@ Future<void> notifyUserOfErrorX({
int delaySeconds = 3,
}) async {
if (!context.mounted) return;
if (!_shouldShowError(errorSituation, exception)) {
return;
}
final localizedError = ErrorHandler.handleErrorLocs(appLocalizations, exception);
final technicalDetails = exception.toString();
final scaffoldMessenger = ScaffoldMessenger.maybeOf(context);
if (scaffoldMessenger != null) {
final durationSeconds = _normalizeDelaySeconds(delaySeconds);
scaffoldMessenger.clearSnackBars();
final snackBar = _buildMainErrorSnackBar(
errorSituation: errorSituation,
localizedError: localizedError,
technicalDetails: technicalDetails,
loc: appLocalizations,
scaffoldMessenger: scaffoldMessenger,
delaySeconds: delaySeconds,
delaySeconds: durationSeconds,
);
scaffoldMessenger.showSnackBar(snackBar);
return;
@@ -46,15 +51,20 @@ void showErrorSnackBar({
required AppLocalizations appLocalizations,
int delaySeconds = 3,
}) {
if (!_shouldShowError(errorSituation, exception)) {
return;
}
final localizedError = ErrorHandler.handleErrorLocs(appLocalizations, exception);
final technicalDetails = exception.toString();
final durationSeconds = _normalizeDelaySeconds(delaySeconds);
scaffoldMessenger.clearSnackBars();
final snackBar = _buildMainErrorSnackBar(
errorSituation: errorSituation,
localizedError: localizedError,
technicalDetails: technicalDetails,
loc: appLocalizations,
scaffoldMessenger: scaffoldMessenger,
delaySeconds: delaySeconds,
delaySeconds: durationSeconds,
);
scaffoldMessenger.showSnackBar(snackBar);
}
@@ -139,19 +149,22 @@ SnackBar _buildMainErrorSnackBar({
int delaySeconds = 3,
}) =>
SnackBar(
duration: Duration(seconds: delaySeconds),
duration: Duration(seconds: _normalizeDelaySeconds(delaySeconds)),
content: ErrorSnackBarContent(
situation: errorSituation,
localizedError: localizedError,
),
action: SnackBarAction(
label: loc.showDetailsAction,
onPressed: () => scaffoldMessenger.showSnackBar(
SnackBar(
content: Text(technicalDetails),
duration: const Duration(seconds: 6),
),
),
onPressed: () {
scaffoldMessenger.hideCurrentSnackBar();
scaffoldMessenger.showSnackBar(
SnackBar(
content: Text(technicalDetails),
duration: const Duration(seconds: 6),
),
);
},
),
);
@@ -176,3 +189,27 @@ Future<void> _showErrorDialog(
),
);
}
int _normalizeDelaySeconds(int delaySeconds) =>
delaySeconds <= 0 ? 3 : delaySeconds;
String? _lastErrorSignature;
DateTime? _lastErrorShownAt;
const int _errorCooldownSeconds = 60;
bool _shouldShowError(String errorSituation, Object exception) {
final signature = '$errorSituation|${exception.runtimeType}|${exception.toString()}';
final now = DateTime.now();
if (_lastErrorSignature == signature) {
final lastShownAt = _lastErrorShownAt;
if (lastShownAt != null &&
now.difference(lastShownAt).inSeconds < _errorCooldownSeconds) {
return false;
}
}
_lastErrorSignature = signature;
_lastErrorShownAt = now;
return true;
}