Integrate email notifications into signup and login (#38)
This commit is contained in:
1 parent
326d58f705
commit
ad5a061164
55 files changed
+1859
-3464
No files matched your search
@@ -19,6 +19,7 @@ class AuthFeedback extends StatelessWidget {
|
||||
? (signUp ? l.signupPreview : l.loginPreview)
|
||||
: l.authCompleted)
|
||||
: switch (error) {
|
||||
AuthError.accountNotVerified => l.authVerifyEmail,
|
||||
AuthError.invalidCredentials => l.authInvalidCredentials,
|
||||
AuthError.emailInUse => l.authEmailInUse,
|
||||
AuthError.unavailable => l.authUnavailable,
|
||||
|
||||
@@ -104,6 +104,11 @@ class _AuthFormState extends State<AuthForm> {
|
||||
locale: locale,
|
||||
);
|
||||
if (!mounted || _signUp) return;
|
||||
if (login.state.error == AuthError.accountNotVerified) {
|
||||
_password.clear();
|
||||
context.goNamed(AppRoutes.verificationSent, extra: _email.text.trim());
|
||||
return;
|
||||
}
|
||||
final challenge = login.state.result?.challenge;
|
||||
if (challenge != null) {
|
||||
_password.clear();
|
||||
@@ -329,10 +334,11 @@ class _AuthFormState extends State<AuthForm> {
|
||||
AuthFeedback(state: state, signUp: _signUp),
|
||||
],
|
||||
const SizedBox(height: 20),
|
||||
TextButton(
|
||||
onPressed: () => context.go('/accounts'),
|
||||
child: Text(l.wEnter),
|
||||
),
|
||||
if (context.read<TwoFactorService>().isSimulated)
|
||||
TextButton(
|
||||
onPressed: () => context.go('/accounts'),
|
||||
child: Text(l.wEnter),
|
||||
),
|
||||
Wrap(
|
||||
alignment: WrapAlignment.center,
|
||||
crossAxisAlignment: WrapCrossAlignment.center,
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,860 +0,0 @@
|
||||
// ignore: unused_import
|
||||
import 'package:intl/intl.dart' as intl;
|
||||
|
||||
import 'app_localizations.dart';
|
||||
|
||||
// ignore_for_file: type=lint
|
||||
|
||||
/// The translations for English (`en`).
|
||||
class AppLocalizationsEn extends AppLocalizations {
|
||||
AppLocalizationsEn([String locale = 'en']) : super(locale);
|
||||
|
||||
@override
|
||||
String get appTitle => 'SXCHNGE · Your next move';
|
||||
|
||||
@override
|
||||
String get nextChapter => 'YOUR NEXT CHAPTER';
|
||||
|
||||
@override
|
||||
String get loginHeading => 'Hey, welcome\nback.';
|
||||
|
||||
@override
|
||||
String get signupHeading => 'Make your\nfirst move.';
|
||||
|
||||
@override
|
||||
String get loginIntro => 'Your next move is just a login away.';
|
||||
|
||||
@override
|
||||
String get signupIntro => 'A new account. A world of possibility.';
|
||||
|
||||
@override
|
||||
String get login => 'Log in';
|
||||
|
||||
@override
|
||||
String get signup => 'Sign up';
|
||||
|
||||
@override
|
||||
String get name => 'Your name';
|
||||
|
||||
@override
|
||||
String get email => 'Email address';
|
||||
|
||||
@override
|
||||
String get emailHint => 'you@example.com';
|
||||
|
||||
@override
|
||||
String get password => 'Password';
|
||||
|
||||
@override
|
||||
String get confirmPassword => 'Confirm password';
|
||||
|
||||
@override
|
||||
String get passwordHint => 'Use at least 12 characters.';
|
||||
|
||||
@override
|
||||
String get showPassword => 'Show password';
|
||||
|
||||
@override
|
||||
String get hidePassword => 'Hide password';
|
||||
|
||||
@override
|
||||
String get showConfirmation => 'Show confirmation';
|
||||
|
||||
@override
|
||||
String get hideConfirmation => 'Hide confirmation';
|
||||
|
||||
@override
|
||||
String get createAccount => 'Create account';
|
||||
|
||||
@override
|
||||
String get letsGo => 'Let’s go';
|
||||
|
||||
@override
|
||||
String get loginPreview => 'You’re signed in.';
|
||||
|
||||
@override
|
||||
String get signupPreview => 'Your account is ready.';
|
||||
|
||||
@override
|
||||
String get alreadyMember => 'Already part of sxchnge?';
|
||||
|
||||
@override
|
||||
String get newHere => 'New around here?';
|
||||
|
||||
@override
|
||||
String get loginInstead => 'Log in instead';
|
||||
|
||||
@override
|
||||
String get createAnAccount => 'Create an account';
|
||||
|
||||
@override
|
||||
String get brandEyebrow => 'A LITTLE CHANGE. A BIG NEXT STEP.';
|
||||
|
||||
@override
|
||||
String get brandHeading => 'Good moves.\nStart here.';
|
||||
|
||||
@override
|
||||
String get brandIntro => 'A fresh way forward.\nMake it yours with sxchnge.';
|
||||
|
||||
@override
|
||||
String get brandCard => 'Less friction.\nMore possibility.';
|
||||
|
||||
@override
|
||||
String get brandFooter => 'YOUR NEXT MOVE STARTS WITH YOU.';
|
||||
|
||||
@override
|
||||
String get emailRequired => 'Enter your email address.';
|
||||
|
||||
@override
|
||||
String get emailInvalid => 'Enter a valid email address.';
|
||||
|
||||
@override
|
||||
String get nameRequired => 'Enter your name.';
|
||||
|
||||
@override
|
||||
String get passwordRequired => 'Enter your password.';
|
||||
|
||||
@override
|
||||
String get confirmationRequired => 'Confirm your password.';
|
||||
|
||||
@override
|
||||
String get passwordMismatch => 'Passwords do not match.';
|
||||
|
||||
@override
|
||||
String get language => 'Language';
|
||||
|
||||
@override
|
||||
String get preferenceNotSaved =>
|
||||
'Language changed for this session. Your preference could not be saved.';
|
||||
|
||||
@override
|
||||
String get authWorking => 'Please wait…';
|
||||
|
||||
@override
|
||||
String get authCompleted => 'Request completed.';
|
||||
|
||||
@override
|
||||
String get authInvalidCredentials =>
|
||||
'Email or password is incorrect. Please try again.';
|
||||
|
||||
@override
|
||||
String get authEmailInUse =>
|
||||
'This email is already registered. Try logging in.';
|
||||
|
||||
@override
|
||||
String get authUnavailable => 'The service is unavailable. Please try again.';
|
||||
|
||||
@override
|
||||
String get authUnexpected => 'Something went wrong. Please try again.';
|
||||
|
||||
@override
|
||||
String get checkInbox => 'Check your inbox.';
|
||||
|
||||
@override
|
||||
String get verificationSent =>
|
||||
'We’ve sent you a verification email. Open the link in your inbox to confirm your email address.';
|
||||
|
||||
@override
|
||||
String get verificationSending => 'Preparing your verification email…';
|
||||
|
||||
@override
|
||||
String get verificationChecking => 'Verifying your email…';
|
||||
|
||||
@override
|
||||
String get verificationVerified => 'Your email\nis verified.';
|
||||
|
||||
@override
|
||||
String get verificationVerifiedBody =>
|
||||
'One step done. You can now return to login. Identity verification is a separate step.';
|
||||
|
||||
@override
|
||||
String get verificationExpired => 'This link has expired.';
|
||||
|
||||
@override
|
||||
String get verificationExpiredBody =>
|
||||
'Request a new verification email and use the latest link.';
|
||||
|
||||
@override
|
||||
String get verificationInvalid => 'This link isn’t valid.';
|
||||
|
||||
@override
|
||||
String get verificationInvalidBody =>
|
||||
'The confirmation link is missing or invalid. Open the complete link from your email, or request a new one.';
|
||||
|
||||
@override
|
||||
String get verificationInternal => 'Something went wrong.';
|
||||
|
||||
@override
|
||||
String get verificationInternalBody =>
|
||||
'We couldn’t complete your request because of an internal error. Please try again.';
|
||||
|
||||
@override
|
||||
String get verificationResend => 'Resend verification email';
|
||||
|
||||
@override
|
||||
String get verificationRequest => 'Send a new verification email';
|
||||
|
||||
@override
|
||||
String get verificationRetry => 'Retry verification';
|
||||
|
||||
@override
|
||||
String get verificationBack => 'Back to login';
|
||||
|
||||
@override
|
||||
String get verificationHint =>
|
||||
'No email? Check your spam folder or request another below.';
|
||||
|
||||
@override
|
||||
String get verificationDemoLink => 'Continue to confirmation';
|
||||
|
||||
@override
|
||||
String get verificationStep => 'CONFIRM YOUR EMAIL';
|
||||
|
||||
@override
|
||||
String get verificationRecipient => 'Recipient';
|
||||
|
||||
@override
|
||||
String get verificationChangeEmail => 'Change email';
|
||||
|
||||
@override
|
||||
String get kycTitle => 'Verification & limits';
|
||||
|
||||
@override
|
||||
String get kycIntro =>
|
||||
'Your account, at your pace. Verify your identity when you need higher limits.';
|
||||
|
||||
@override
|
||||
String get kycUnverified => 'Not verified';
|
||||
|
||||
@override
|
||||
String get kycPending => 'In review';
|
||||
|
||||
@override
|
||||
String get kycApproved => 'Identity verified';
|
||||
|
||||
@override
|
||||
String get kycChanges => 'New photos needed';
|
||||
|
||||
@override
|
||||
String get kycDenied => 'Verification declined';
|
||||
|
||||
@override
|
||||
String get kycUnverifiedBody =>
|
||||
'You can keep using your account with basic limits. Submit a passport photo and a selfie holding it to request an upgrade.';
|
||||
|
||||
@override
|
||||
String get kycPendingBody =>
|
||||
'Your submission is awaiting a human review. Basic limits remain active until approval. You do not need to submit again.';
|
||||
|
||||
@override
|
||||
String get kycApprovedBody =>
|
||||
'Your review is complete. Check your current limits below.';
|
||||
|
||||
@override
|
||||
String get kycChangesBody =>
|
||||
'Your account remains available with basic limits. Replace the photos and submit a new review request.';
|
||||
|
||||
@override
|
||||
String get kycDeniedBody =>
|
||||
'Basic limits remain available. If you believe this decision is incorrect, contact support for a review.';
|
||||
|
||||
@override
|
||||
String get kycPassportReason =>
|
||||
'The passport details could not be read. Retake the photo in good light, with every edge visible.';
|
||||
|
||||
@override
|
||||
String get kycSelfieReason =>
|
||||
'Your face or passport was not clear in the selfie. Keep both visible and in focus.';
|
||||
|
||||
@override
|
||||
String get kycExpiredReason =>
|
||||
'The passport has expired. Use a valid passport and take both photos again.';
|
||||
|
||||
@override
|
||||
String get kycDeniedReason =>
|
||||
'We could not verify your identity from this submission.';
|
||||
|
||||
@override
|
||||
String get kycStart => 'Verify identity';
|
||||
|
||||
@override
|
||||
String get kycResubmit => 'Replace photos';
|
||||
|
||||
@override
|
||||
String get kycRefresh => 'Refresh status & limits';
|
||||
|
||||
@override
|
||||
String get kycSupport => 'Contact support';
|
||||
|
||||
@override
|
||||
String get kycSupportBody =>
|
||||
'Support is currently unavailable. Please try again later.';
|
||||
|
||||
@override
|
||||
String get kycBasic => 'Basic';
|
||||
|
||||
@override
|
||||
String get kycVerifiedTier => 'Verified';
|
||||
|
||||
@override
|
||||
String get kycLimits => 'Your limits';
|
||||
|
||||
@override
|
||||
String get kycDay => 'Daily volume';
|
||||
|
||||
@override
|
||||
String get kycMonth => 'Monthly volume';
|
||||
|
||||
@override
|
||||
String get kycCurrent => 'Current cap';
|
||||
|
||||
@override
|
||||
String get kycRemaining => 'Available';
|
||||
|
||||
@override
|
||||
String get kycAfter => 'After approval';
|
||||
|
||||
@override
|
||||
String get kycLimitsError =>
|
||||
'Limits could not be refreshed. Any values below are out of date. Retry to see your current access.';
|
||||
|
||||
@override
|
||||
String get kycLimitsEmpty =>
|
||||
'No limits were returned. Refresh or check with support before making a transaction.';
|
||||
|
||||
@override
|
||||
String get kycLoading => 'Loading your status…';
|
||||
|
||||
@override
|
||||
String get kycPassport => 'Passport photo';
|
||||
|
||||
@override
|
||||
String get kycSelfie => 'Selfie with passport';
|
||||
|
||||
@override
|
||||
String get kycReview => 'Review your photos';
|
||||
|
||||
@override
|
||||
String get kycPassportHelp =>
|
||||
'Open your valid passport to the photo page. Show all four edges and keep text sharp. Avoid glare, blur and covered details.';
|
||||
|
||||
@override
|
||||
String get kycSelfieHelp =>
|
||||
'Hold the open passport beside your face. Show your whole face and the photo page in the same image. Keep both sharp and uncovered.';
|
||||
|
||||
@override
|
||||
String get kycFileRules =>
|
||||
'JPEG or PNG · up to 10 MB · at least 600 × 600 pixels. Take a photo with your camera, then choose it here.';
|
||||
|
||||
@override
|
||||
String get kycChoose => 'Choose photo';
|
||||
|
||||
@override
|
||||
String get kycReplace => 'Choose a different photo';
|
||||
|
||||
@override
|
||||
String get kycRemove => 'Remove photo';
|
||||
|
||||
@override
|
||||
String get kycNext => 'Continue';
|
||||
|
||||
@override
|
||||
String get kycBack => 'Back';
|
||||
|
||||
@override
|
||||
String get kycSkip => 'Keep basic limits';
|
||||
|
||||
@override
|
||||
String get kycClose => 'Back to account';
|
||||
|
||||
@override
|
||||
String get kycReviewHelp =>
|
||||
'Check that both photos are readable and show the same passport. A staff member will review them; submission does not immediately raise your limits.';
|
||||
|
||||
@override
|
||||
String get kycConfirm => 'These photos show me and my own valid passport.';
|
||||
|
||||
@override
|
||||
String get kycSubmit => 'Submit for review';
|
||||
|
||||
@override
|
||||
String get kycWorking => 'Processing… Please keep this page open.';
|
||||
|
||||
@override
|
||||
String get kycDiscardTitle => 'Discard these photos?';
|
||||
|
||||
@override
|
||||
String get kycDiscardBody =>
|
||||
'Your draft is only in memory. Leaving will remove the selected photos; you can start again later.';
|
||||
|
||||
@override
|
||||
String get kycStay => 'Keep editing';
|
||||
|
||||
@override
|
||||
String get kycDiscard => 'Discard & leave';
|
||||
|
||||
@override
|
||||
String get kycErrorUnavailable =>
|
||||
'The service is unavailable. Your selected photos are still here. Try again.';
|
||||
|
||||
@override
|
||||
String get kycErrorInternal =>
|
||||
'Something went wrong. Try again; your selected photos have been kept.';
|
||||
|
||||
@override
|
||||
String get kycErrorPermission =>
|
||||
'We could not open that photo. Check file access or choose another image.';
|
||||
|
||||
@override
|
||||
String get kycErrorFormat =>
|
||||
'Choose a JPEG or PNG image. Other formats are not supported.';
|
||||
|
||||
@override
|
||||
String get kycErrorLarge =>
|
||||
'This image is too large. Choose one under 10 MB and 40 megapixels.';
|
||||
|
||||
@override
|
||||
String get kycErrorUnreadable =>
|
||||
'This image is damaged or cannot be read. Choose another photo.';
|
||||
|
||||
@override
|
||||
String get kycErrorSmall =>
|
||||
'The photo is too small. Use an image at least 600 pixels wide and high.';
|
||||
|
||||
@override
|
||||
String get kycErrorIncomplete =>
|
||||
'Choose both photos and confirm they belong to you before submitting.';
|
||||
|
||||
@override
|
||||
String get kycErrorSession =>
|
||||
'Your session has expired. Return to login, then check your verification status.';
|
||||
|
||||
@override
|
||||
String get kycErrorRate =>
|
||||
'Too many requests. Wait a moment before trying again.';
|
||||
|
||||
@override
|
||||
String get kycErrorConflict =>
|
||||
'Your review status has changed. Refresh it before continuing.';
|
||||
|
||||
@override
|
||||
String get kycDemoControls => 'Review scenarios';
|
||||
|
||||
@override
|
||||
String get kycDemoApprove => 'Approve';
|
||||
|
||||
@override
|
||||
String get kycDemoCorrect => 'Request clearer passport';
|
||||
|
||||
@override
|
||||
String get kycDemoSelfie => 'Request clearer selfie';
|
||||
|
||||
@override
|
||||
String get kycDemoExpired => 'Passport expired';
|
||||
|
||||
@override
|
||||
String get kycDemoDeny => 'Decline';
|
||||
|
||||
@override
|
||||
String get kycPreview => 'Explore verification & limits';
|
||||
|
||||
@override
|
||||
String get kycChooseFirst => 'Choose a photo to continue.';
|
||||
|
||||
@override
|
||||
String get kycStatusStale =>
|
||||
'Status could not be refreshed. The status shown is the last known result.';
|
||||
|
||||
@override
|
||||
String get kycUsed => 'Used';
|
||||
|
||||
@override
|
||||
String get kycReserved => 'Reserved';
|
||||
|
||||
@override
|
||||
String get kycUsageHelp =>
|
||||
'Used is completed activity. Reserved is held for pending transactions. Both count toward your limit.';
|
||||
|
||||
@override
|
||||
String get kycOccupied => 'Used + reserved';
|
||||
|
||||
@override
|
||||
String get kycNoCapacity => 'No capacity available';
|
||||
|
||||
@override
|
||||
String get wAccounts => 'Accounts';
|
||||
|
||||
@override
|
||||
String get wActivity => 'Activity';
|
||||
|
||||
@override
|
||||
String get wLimits => 'Limits';
|
||||
|
||||
@override
|
||||
String get wSettings => 'Settings';
|
||||
|
||||
@override
|
||||
String get wHeadline => 'Your money.\nYour next move.';
|
||||
|
||||
@override
|
||||
String get wSubheading => 'Top up. Exchange. Go further.';
|
||||
|
||||
@override
|
||||
String get wAvailable => 'Available to you';
|
||||
|
||||
@override
|
||||
String get wTopUp => 'Top up';
|
||||
|
||||
@override
|
||||
String get wExchange => 'Exchange';
|
||||
|
||||
@override
|
||||
String get wPayout => 'Pay out';
|
||||
|
||||
@override
|
||||
String get wRecent => 'Recent activity';
|
||||
|
||||
@override
|
||||
String get wSeeAll => 'See all';
|
||||
|
||||
@override
|
||||
String get wEmptyActivity =>
|
||||
'Your next move starts here. Your transactions will appear below.';
|
||||
|
||||
@override
|
||||
String get wEmptyAccounts =>
|
||||
'Your accounts are not ready yet. Try refreshing.';
|
||||
|
||||
@override
|
||||
String get wRefresh => 'Refresh';
|
||||
|
||||
@override
|
||||
String get wSource => 'From account';
|
||||
|
||||
@override
|
||||
String get wDestination => 'To account';
|
||||
|
||||
@override
|
||||
String get wReceiveAccount => 'Receiving account';
|
||||
|
||||
@override
|
||||
String get wAmount => 'Amount';
|
||||
|
||||
@override
|
||||
String get wRecipient => 'Recipient';
|
||||
|
||||
@override
|
||||
String get wRecipientHint => 'Recipient name or reference';
|
||||
|
||||
@override
|
||||
String get wReview => 'Review';
|
||||
|
||||
@override
|
||||
String get wReviewTitle => 'One last look.';
|
||||
|
||||
@override
|
||||
String get wFee => 'Fee';
|
||||
|
||||
@override
|
||||
String get wTotalDebit => 'Leaves your account';
|
||||
|
||||
@override
|
||||
String get wCredit => 'Arrives in your account';
|
||||
|
||||
@override
|
||||
String get wRecipientGets => 'Recipient receives';
|
||||
|
||||
@override
|
||||
String get wYouPay => 'You pay';
|
||||
|
||||
@override
|
||||
String get wRate => 'Exchange rate';
|
||||
|
||||
@override
|
||||
String get wQuoteNotice =>
|
||||
'These terms are valid for 60 seconds. Confirm them before continuing.';
|
||||
|
||||
@override
|
||||
String get wExpired =>
|
||||
'This quote expired. Refresh it and review the new terms.';
|
||||
|
||||
@override
|
||||
String get wNewQuote => 'Refresh quote';
|
||||
|
||||
@override
|
||||
String get wConfirm => 'Confirm transaction';
|
||||
|
||||
@override
|
||||
String get wEdit => 'Edit details';
|
||||
|
||||
@override
|
||||
String get wClose => 'Close';
|
||||
|
||||
@override
|
||||
String get wWorking => 'Working on it…';
|
||||
|
||||
@override
|
||||
String get wPending => 'Processing';
|
||||
|
||||
@override
|
||||
String get wCompleted => 'Completed';
|
||||
|
||||
@override
|
||||
String get wFailed => 'Not completed';
|
||||
|
||||
@override
|
||||
String get wPendingTopUp =>
|
||||
'Your top-up is processing. Your available balance has not changed yet.';
|
||||
|
||||
@override
|
||||
String get wPendingExchange =>
|
||||
'The amount and fee have left your available balance. The exchanged amount will appear in the receiving account when completed.';
|
||||
|
||||
@override
|
||||
String get wPendingPayout =>
|
||||
'The amount and fee have left your available balance. The payout is still processing.';
|
||||
|
||||
@override
|
||||
String get wCompleteTopUp =>
|
||||
'Your account has been credited. The money is available to use.';
|
||||
|
||||
@override
|
||||
String get wCompleteExchange =>
|
||||
'Your exchange is complete. The money is available in the receiving account.';
|
||||
|
||||
@override
|
||||
String get wCompletePayout =>
|
||||
'Your payout is complete. The amount and fee have been deducted from your account.';
|
||||
|
||||
@override
|
||||
String get wFailedTopUp =>
|
||||
'The top-up did not complete. No money was added to your account.';
|
||||
|
||||
@override
|
||||
String get wFailedOutgoing =>
|
||||
'The transaction did not complete. The amount and fee are available in your account again.';
|
||||
|
||||
@override
|
||||
String get wUnavailable =>
|
||||
'Could not refresh. The displayed information may be out of date. Try again.';
|
||||
|
||||
@override
|
||||
String get wInvalidAmount =>
|
||||
'Enter an amount greater than zero, using the currency’s decimal precision.';
|
||||
|
||||
@override
|
||||
String get wInsufficient =>
|
||||
'Not enough available money for this amount and fee. Top up or enter a smaller amount.';
|
||||
|
||||
@override
|
||||
String get wLimitError =>
|
||||
'This amount exceeds your available limit. Check your limits before continuing.';
|
||||
|
||||
@override
|
||||
String get wRecipientError =>
|
||||
'Enter a sample recipient between 6 and 140 characters.';
|
||||
|
||||
@override
|
||||
String get wUnsupported =>
|
||||
'This combination is unavailable. Choose another account.';
|
||||
|
||||
@override
|
||||
String get wNotFound =>
|
||||
'This item could not be found. Return to your accounts.';
|
||||
|
||||
@override
|
||||
String get wUncertain =>
|
||||
'We could not confirm the outcome. Check it before trying another transaction.';
|
||||
|
||||
@override
|
||||
String get wCheckOutcome => 'Check outcome';
|
||||
|
||||
@override
|
||||
String get wNoSubmission =>
|
||||
'No transaction was found. You can review and confirm again.';
|
||||
|
||||
@override
|
||||
String get wDiscardTitle => 'Leave this transaction?';
|
||||
|
||||
@override
|
||||
String get wDiscardBody =>
|
||||
'Your entered details will be cleared. No new transaction will be submitted.';
|
||||
|
||||
@override
|
||||
String get wStay => 'Keep editing';
|
||||
|
||||
@override
|
||||
String get wAll => 'All';
|
||||
|
||||
@override
|
||||
String get wSearch => 'Search by reference';
|
||||
|
||||
@override
|
||||
String get wNoMatches => 'No matching transactions. Try another filter.';
|
||||
|
||||
@override
|
||||
String get wClearFilters => 'Clear filters';
|
||||
|
||||
@override
|
||||
String get wReference => 'Reference';
|
||||
|
||||
@override
|
||||
String get wWhen => 'Created';
|
||||
|
||||
@override
|
||||
String get wViewAccount => 'View account';
|
||||
|
||||
@override
|
||||
String get wPreferences => 'Make it yours.';
|
||||
|
||||
@override
|
||||
String get wLanguage => 'Account language';
|
||||
|
||||
@override
|
||||
String get wLanguageHelp => 'Used throughout your account.';
|
||||
|
||||
@override
|
||||
String get wLanguageSaved => 'Saved to your account.';
|
||||
|
||||
@override
|
||||
String get wLanguageFailed =>
|
||||
'Changed for this session, but not saved to your account. Retry below.';
|
||||
|
||||
@override
|
||||
String get wProfileError =>
|
||||
'Account preferences could not be loaded. Try again.';
|
||||
|
||||
@override
|
||||
String get wSecurity => 'Security';
|
||||
|
||||
@override
|
||||
String get wSecurityBody =>
|
||||
'Password and security settings are not available yet.';
|
||||
|
||||
@override
|
||||
String get wIdentity => 'Identity verification';
|
||||
|
||||
@override
|
||||
String get wIdentityHelp => 'Optional verification for higher limits.';
|
||||
|
||||
@override
|
||||
String get wBackLogin => 'Back to login';
|
||||
|
||||
@override
|
||||
String get wEnter => 'Explore your accounts';
|
||||
|
||||
@override
|
||||
String get wUsage => 'Used this period';
|
||||
|
||||
@override
|
||||
String get wLimitsScope => 'Outgoing activity · EUR equivalent';
|
||||
|
||||
@override
|
||||
String get wPendingHint =>
|
||||
'Refresh to check the latest status. You can keep using your other accounts.';
|
||||
|
||||
@override
|
||||
String get wFundsHeading => 'Where is my money?';
|
||||
|
||||
@override
|
||||
String get wAnother => 'Make another transaction';
|
||||
|
||||
@override
|
||||
String get factorTitle => 'One more check.';
|
||||
|
||||
@override
|
||||
String get factorLogin => 'Confirm it’s you to finish signing in.';
|
||||
|
||||
@override
|
||||
String get factorMoney =>
|
||||
'Confirm this transaction. No money moves before confirmation.';
|
||||
|
||||
@override
|
||||
String get factorEnableHelp =>
|
||||
'Confirm to turn on two-factor verification for sign-in and money operations.';
|
||||
|
||||
@override
|
||||
String get factorDisableHelp =>
|
||||
'Confirm to turn off two-factor verification. Sign-in and money operations will no longer ask for a second code.';
|
||||
|
||||
@override
|
||||
String get factorEmail => 'Enter the six-digit code sent to your email.';
|
||||
|
||||
@override
|
||||
String get factorAuthenticator =>
|
||||
'Enter the current six-digit code from your authenticator app.';
|
||||
|
||||
@override
|
||||
String get factorCode => 'Verification code';
|
||||
|
||||
@override
|
||||
String get factorConfirm => 'Verify and continue';
|
||||
|
||||
@override
|
||||
String get factorResend => 'Send a new code';
|
||||
|
||||
@override
|
||||
String get factorHelp =>
|
||||
'Check your inbox and spam folder. A new code replaces the previous one.';
|
||||
|
||||
@override
|
||||
String get factorAppHelp =>
|
||||
'Use the current code. If you cannot access your authenticator, cancel this action.';
|
||||
|
||||
@override
|
||||
String get factorInvalid =>
|
||||
'That code is not valid. Check all six digits and try again.';
|
||||
|
||||
@override
|
||||
String get factorExpired =>
|
||||
'This verification has expired. Request a new code or return to start again.';
|
||||
|
||||
@override
|
||||
String get factorLocked =>
|
||||
'Too many incorrect attempts. Wait five minutes, then start verification again.';
|
||||
|
||||
@override
|
||||
String get factorWait => 'Please wait before requesting another code.';
|
||||
|
||||
@override
|
||||
String get factorRequired =>
|
||||
'Verification is needed again. Please confirm this action once more.';
|
||||
|
||||
@override
|
||||
String get factorUnavailable =>
|
||||
'Could not complete verification. Try again or cancel this action.';
|
||||
|
||||
@override
|
||||
String factorCooldown(int seconds) {
|
||||
return 'Send a new code in ${seconds}s';
|
||||
}
|
||||
|
||||
@override
|
||||
String get factorSettings => 'Two-factor verification';
|
||||
|
||||
@override
|
||||
String get factorSettingsHelp =>
|
||||
'Add a verification code when you sign in, top up, exchange or pay out.';
|
||||
|
||||
@override
|
||||
String get factorOn => 'On';
|
||||
|
||||
@override
|
||||
String get factorOff => 'Off';
|
||||
|
||||
@override
|
||||
String get factorEnable => 'Turn on';
|
||||
|
||||
@override
|
||||
String get factorDisable => 'Turn off';
|
||||
|
||||
@override
|
||||
String get factorEmailMethod => 'Email code';
|
||||
|
||||
@override
|
||||
String get factorAppMethod => 'Authenticator app';
|
||||
|
||||
@override
|
||||
String get factorAppExpired =>
|
||||
'This verification has expired. Return and start again.';
|
||||
}
|
||||
@@ -1,857 +0,0 @@
|
||||
// ignore: unused_import
|
||||
import 'package:intl/intl.dart' as intl;
|
||||
|
||||
import 'app_localizations.dart';
|
||||
|
||||
// ignore_for_file: type=lint
|
||||
|
||||
/// The translations for Russian (`ru`).
|
||||
class AppLocalizationsRu extends AppLocalizations {
|
||||
AppLocalizationsRu([String locale = 'ru']) : super(locale);
|
||||
|
||||
@override
|
||||
String get appTitle => 'SXCHNGE · Ваш следующий шаг';
|
||||
|
||||
@override
|
||||
String get nextChapter => 'НОВАЯ ГЛАВА';
|
||||
|
||||
@override
|
||||
String get loginHeading => 'Рады видеть\nвас снова.';
|
||||
|
||||
@override
|
||||
String get signupHeading => 'Сделайте\nпервый шаг.';
|
||||
|
||||
@override
|
||||
String get loginIntro => 'Войдите, чтобы сделать следующий шаг.';
|
||||
|
||||
@override
|
||||
String get signupIntro => 'Новый аккаунт. Новые возможности.';
|
||||
|
||||
@override
|
||||
String get login => 'Войти';
|
||||
|
||||
@override
|
||||
String get signup => 'Регистрация';
|
||||
|
||||
@override
|
||||
String get name => 'Ваше имя';
|
||||
|
||||
@override
|
||||
String get email => 'Электронная почта';
|
||||
|
||||
@override
|
||||
String get emailHint => 'you@example.com';
|
||||
|
||||
@override
|
||||
String get password => 'Пароль';
|
||||
|
||||
@override
|
||||
String get confirmPassword => 'Повторите пароль';
|
||||
|
||||
@override
|
||||
String get passwordHint => 'Используйте не менее 12 символов.';
|
||||
|
||||
@override
|
||||
String get showPassword => 'Показать пароль';
|
||||
|
||||
@override
|
||||
String get hidePassword => 'Скрыть пароль';
|
||||
|
||||
@override
|
||||
String get showConfirmation => 'Показать повтор пароля';
|
||||
|
||||
@override
|
||||
String get hideConfirmation => 'Скрыть повтор пароля';
|
||||
|
||||
@override
|
||||
String get createAccount => 'Создать аккаунт';
|
||||
|
||||
@override
|
||||
String get letsGo => 'Продолжить';
|
||||
|
||||
@override
|
||||
String get loginPreview => 'Вы вошли в аккаунт.';
|
||||
|
||||
@override
|
||||
String get signupPreview => 'Ваш аккаунт готов.';
|
||||
|
||||
@override
|
||||
String get alreadyMember => 'Уже есть аккаунт sxchnge?';
|
||||
|
||||
@override
|
||||
String get newHere => 'Впервые здесь?';
|
||||
|
||||
@override
|
||||
String get loginInstead => 'Войти в аккаунт';
|
||||
|
||||
@override
|
||||
String get createAnAccount => 'Зарегистрироваться';
|
||||
|
||||
@override
|
||||
String get brandEyebrow => 'МАЛЕНЬКАЯ ПЕРЕМЕНА. БОЛЬШОЙ ШАГ.';
|
||||
|
||||
@override
|
||||
String get brandHeading => 'Всё начинается\nс перемен.';
|
||||
|
||||
@override
|
||||
String get brandIntro =>
|
||||
'Новый путь вперёд.\nОткройте его вместе со sxchnge.';
|
||||
|
||||
@override
|
||||
String get brandCard => 'Меньше преград.\nБольше возможностей.';
|
||||
|
||||
@override
|
||||
String get brandFooter => 'СЛЕДУЮЩИЙ ШАГ — ЗА ВАМИ.';
|
||||
|
||||
@override
|
||||
String get emailRequired => 'Введите электронную почту.';
|
||||
|
||||
@override
|
||||
String get emailInvalid => 'Введите корректный адрес почты.';
|
||||
|
||||
@override
|
||||
String get nameRequired => 'Введите ваше имя.';
|
||||
|
||||
@override
|
||||
String get passwordRequired => 'Введите пароль.';
|
||||
|
||||
@override
|
||||
String get confirmationRequired => 'Повторите пароль.';
|
||||
|
||||
@override
|
||||
String get passwordMismatch => 'Пароли не совпадают.';
|
||||
|
||||
@override
|
||||
String get language => 'Язык';
|
||||
|
||||
@override
|
||||
String get preferenceNotSaved =>
|
||||
'Язык изменён для этого сеанса. Сохранить выбор не удалось.';
|
||||
|
||||
@override
|
||||
String get authWorking => 'Подождите…';
|
||||
|
||||
@override
|
||||
String get authCompleted => 'Запрос выполнен.';
|
||||
|
||||
@override
|
||||
String get authInvalidCredentials =>
|
||||
'Неверная почта или пароль. Попробуйте ещё раз.';
|
||||
|
||||
@override
|
||||
String get authEmailInUse =>
|
||||
'Эта почта уже зарегистрирована. Попробуйте войти.';
|
||||
|
||||
@override
|
||||
String get authUnavailable => 'Сервис недоступен. Попробуйте ещё раз.';
|
||||
|
||||
@override
|
||||
String get authUnexpected => 'Что-то пошло не так. Попробуйте ещё раз.';
|
||||
|
||||
@override
|
||||
String get checkInbox => 'Проверьте почту.';
|
||||
|
||||
@override
|
||||
String get verificationSent =>
|
||||
'Мы отправили вам письмо для подтверждения. Откройте ссылку в письме, чтобы подтвердить электронную почту.';
|
||||
|
||||
@override
|
||||
String get verificationSending => 'Готовим письмо для подтверждения…';
|
||||
|
||||
@override
|
||||
String get verificationChecking => 'Подтверждаем вашу почту…';
|
||||
|
||||
@override
|
||||
String get verificationVerified => 'Ваша почта\nподтверждена.';
|
||||
|
||||
@override
|
||||
String get verificationVerifiedBody =>
|
||||
'Первый шаг пройден. Теперь можно вернуться ко входу. Подтверждение личности — отдельный этап.';
|
||||
|
||||
@override
|
||||
String get verificationExpired => 'Срок действия ссылки истёк.';
|
||||
|
||||
@override
|
||||
String get verificationExpiredBody =>
|
||||
'Запросите новое письмо и перейдите по ссылке из него.';
|
||||
|
||||
@override
|
||||
String get verificationInvalid => 'Ссылка недействительна.';
|
||||
|
||||
@override
|
||||
String get verificationInvalidBody =>
|
||||
'Ссылка подтверждения отсутствует или недействительна. Откройте полную ссылку из письма или запросите новую.';
|
||||
|
||||
@override
|
||||
String get verificationInternal => 'Что-то пошло не так.';
|
||||
|
||||
@override
|
||||
String get verificationInternalBody =>
|
||||
'Не удалось выполнить запрос из-за внутренней ошибки. Попробуйте ещё раз.';
|
||||
|
||||
@override
|
||||
String get verificationResend => 'Отправить письмо ещё раз';
|
||||
|
||||
@override
|
||||
String get verificationRequest => 'Отправить новое письмо';
|
||||
|
||||
@override
|
||||
String get verificationRetry => 'Повторить подтверждение';
|
||||
|
||||
@override
|
||||
String get verificationBack => 'Вернуться ко входу';
|
||||
|
||||
@override
|
||||
String get verificationHint =>
|
||||
'Нет письма? Проверьте папку «Спам» или запросите новое ниже.';
|
||||
|
||||
@override
|
||||
String get verificationDemoLink => 'Перейти к подтверждению';
|
||||
|
||||
@override
|
||||
String get verificationStep => 'ПОДТВЕРДИТЕ ПОЧТУ';
|
||||
|
||||
@override
|
||||
String get verificationRecipient => 'Получатель';
|
||||
|
||||
@override
|
||||
String get verificationChangeEmail => 'Изменить почту';
|
||||
|
||||
@override
|
||||
String get kycTitle => 'Верификация и лимиты';
|
||||
|
||||
@override
|
||||
String get kycIntro =>
|
||||
'Ваш аккаунт — ваш темп. Подтвердите личность, когда понадобятся более высокие лимиты.';
|
||||
|
||||
@override
|
||||
String get kycUnverified => 'Личность не подтверждена';
|
||||
|
||||
@override
|
||||
String get kycPending => 'На проверке';
|
||||
|
||||
@override
|
||||
String get kycApproved => 'Личность подтверждена';
|
||||
|
||||
@override
|
||||
String get kycChanges => 'Нужны новые фото';
|
||||
|
||||
@override
|
||||
String get kycDenied => 'Верификация отклонена';
|
||||
|
||||
@override
|
||||
String get kycUnverifiedBody =>
|
||||
'Вы можете пользоваться аккаунтом с базовыми лимитами. Для повышения отправьте фото паспорта и селфи с ним.';
|
||||
|
||||
@override
|
||||
String get kycPendingBody =>
|
||||
'Заявка ожидает проверки сотрудником. До одобрения действуют базовые лимиты. Повторная отправка не нужна.';
|
||||
|
||||
@override
|
||||
String get kycApprovedBody =>
|
||||
'Проверка завершена. Актуальные лимиты указаны ниже.';
|
||||
|
||||
@override
|
||||
String get kycChangesBody =>
|
||||
'Аккаунт доступен с базовыми лимитами. Замените фото и отправьте новую заявку.';
|
||||
|
||||
@override
|
||||
String get kycDeniedBody =>
|
||||
'Базовые лимиты остаются доступными. Если вы не согласны с решением, обратитесь в поддержку для пересмотра.';
|
||||
|
||||
@override
|
||||
String get kycPassportReason =>
|
||||
'Данные паспорта не удалось прочитать. Переснимите при хорошем освещении, чтобы все края были видны.';
|
||||
|
||||
@override
|
||||
String get kycSelfieReason =>
|
||||
'На селфи плохо видно лицо или паспорт. Оба должны быть в кадре и в фокусе.';
|
||||
|
||||
@override
|
||||
String get kycExpiredReason =>
|
||||
'Срок действия паспорта истёк. Используйте действующий паспорт и сделайте оба фото заново.';
|
||||
|
||||
@override
|
||||
String get kycDeniedReason =>
|
||||
'По этой заявке не удалось подтвердить вашу личность.';
|
||||
|
||||
@override
|
||||
String get kycStart => 'Подтвердить личность';
|
||||
|
||||
@override
|
||||
String get kycResubmit => 'Заменить фото';
|
||||
|
||||
@override
|
||||
String get kycRefresh => 'Обновить статус и лимиты';
|
||||
|
||||
@override
|
||||
String get kycSupport => 'Обратиться в поддержку';
|
||||
|
||||
@override
|
||||
String get kycSupportBody => 'Поддержка сейчас недоступна. Попробуйте позже.';
|
||||
|
||||
@override
|
||||
String get kycBasic => 'Базовый';
|
||||
|
||||
@override
|
||||
String get kycVerifiedTier => 'Подтверждённый';
|
||||
|
||||
@override
|
||||
String get kycLimits => 'Ваши лимиты';
|
||||
|
||||
@override
|
||||
String get kycDay => 'Объём за день';
|
||||
|
||||
@override
|
||||
String get kycMonth => 'Объём за месяц';
|
||||
|
||||
@override
|
||||
String get kycCurrent => 'Текущий лимит';
|
||||
|
||||
@override
|
||||
String get kycRemaining => 'Доступно';
|
||||
|
||||
@override
|
||||
String get kycAfter => 'После одобрения';
|
||||
|
||||
@override
|
||||
String get kycLimitsError =>
|
||||
'Не удалось обновить лимиты. Значения ниже могут быть устаревшими. Повторите запрос.';
|
||||
|
||||
@override
|
||||
String get kycLimitsEmpty =>
|
||||
'Сервис не вернул лимиты. Обновите данные или уточните их в поддержке перед операцией.';
|
||||
|
||||
@override
|
||||
String get kycLoading => 'Загружаем ваш статус…';
|
||||
|
||||
@override
|
||||
String get kycPassport => 'Фото паспорта';
|
||||
|
||||
@override
|
||||
String get kycSelfie => 'Селфи с паспортом';
|
||||
|
||||
@override
|
||||
String get kycReview => 'Проверьте фото';
|
||||
|
||||
@override
|
||||
String get kycPassportHelp =>
|
||||
'Откройте действующий паспорт на странице с фото. Все четыре края и текст должны быть чётко видны. Избегайте бликов и размытия, не закрывайте данные.';
|
||||
|
||||
@override
|
||||
String get kycSelfieHelp =>
|
||||
'Держите открытый паспорт рядом с лицом. Лицо целиком и страница с фото должны быть в одном кадре, чёткими и ничем не закрытыми.';
|
||||
|
||||
@override
|
||||
String get kycFileRules =>
|
||||
'JPEG или PNG · до 10 МБ · не менее 600 × 600 пикселей. Сделайте фото камерой, затем выберите его здесь.';
|
||||
|
||||
@override
|
||||
String get kycChoose => 'Выбрать фото';
|
||||
|
||||
@override
|
||||
String get kycReplace => 'Выбрать другое фото';
|
||||
|
||||
@override
|
||||
String get kycRemove => 'Удалить фото';
|
||||
|
||||
@override
|
||||
String get kycNext => 'Продолжить';
|
||||
|
||||
@override
|
||||
String get kycBack => 'Назад';
|
||||
|
||||
@override
|
||||
String get kycSkip => 'Оставить базовые лимиты';
|
||||
|
||||
@override
|
||||
String get kycClose => 'К аккаунту';
|
||||
|
||||
@override
|
||||
String get kycReviewHelp =>
|
||||
'Убедитесь, что оба фото читаемы и на них один паспорт. Их проверит сотрудник. Отправка не повышает лимиты сразу.';
|
||||
|
||||
@override
|
||||
String get kycConfirm => 'На фото я и мой действующий паспорт.';
|
||||
|
||||
@override
|
||||
String get kycSubmit => 'Отправить на проверку';
|
||||
|
||||
@override
|
||||
String get kycWorking => 'Обработка… Не закрывайте страницу.';
|
||||
|
||||
@override
|
||||
String get kycDiscardTitle => 'Удалить выбранные фото?';
|
||||
|
||||
@override
|
||||
String get kycDiscardBody =>
|
||||
'Черновик хранится только в памяти. При выходе выбранные фото будут удалены. Позже можно начать заново.';
|
||||
|
||||
@override
|
||||
String get kycStay => 'Продолжить';
|
||||
|
||||
@override
|
||||
String get kycDiscard => 'Удалить и выйти';
|
||||
|
||||
@override
|
||||
String get kycErrorUnavailable =>
|
||||
'Сервис недоступен. Выбранные фото сохранены в памяти. Повторите попытку.';
|
||||
|
||||
@override
|
||||
String get kycErrorInternal =>
|
||||
'Произошла ошибка. Повторите попытку; выбранные фото сохранены.';
|
||||
|
||||
@override
|
||||
String get kycErrorPermission =>
|
||||
'Не удалось открыть фото. Проверьте доступ к файлам или выберите другое изображение.';
|
||||
|
||||
@override
|
||||
String get kycErrorFormat =>
|
||||
'Выберите изображение JPEG или PNG. Другие форматы не поддерживаются.';
|
||||
|
||||
@override
|
||||
String get kycErrorLarge =>
|
||||
'Изображение слишком большое. Выберите файл до 10 МБ и 40 мегапикселей.';
|
||||
|
||||
@override
|
||||
String get kycErrorUnreadable =>
|
||||
'Изображение повреждено или не читается. Выберите другое фото.';
|
||||
|
||||
@override
|
||||
String get kycErrorSmall =>
|
||||
'Фото слишком маленькое. Ширина и высота должны быть не менее 600 пикселей.';
|
||||
|
||||
@override
|
||||
String get kycErrorIncomplete =>
|
||||
'Выберите оба фото и подтвердите, что на них вы и ваш паспорт.';
|
||||
|
||||
@override
|
||||
String get kycErrorSession =>
|
||||
'Сессия истекла. Войдите снова и проверьте статус верификации.';
|
||||
|
||||
@override
|
||||
String get kycErrorRate =>
|
||||
'Слишком много запросов. Немного подождите и повторите попытку.';
|
||||
|
||||
@override
|
||||
String get kycErrorConflict =>
|
||||
'Статус проверки изменился. Обновите его, прежде чем продолжить.';
|
||||
|
||||
@override
|
||||
String get kycDemoControls => 'Сценарии проверки';
|
||||
|
||||
@override
|
||||
String get kycDemoApprove => 'Одобрить';
|
||||
|
||||
@override
|
||||
String get kycDemoCorrect => 'Запросить чёткое фото паспорта';
|
||||
|
||||
@override
|
||||
String get kycDemoSelfie => 'Запросить чёткое селфи';
|
||||
|
||||
@override
|
||||
String get kycDemoExpired => 'Паспорт просрочен';
|
||||
|
||||
@override
|
||||
String get kycDemoDeny => 'Отклонить';
|
||||
|
||||
@override
|
||||
String get kycPreview => 'Посмотреть верификацию и лимиты';
|
||||
|
||||
@override
|
||||
String get kycChooseFirst => 'Выберите фото для продолжения.';
|
||||
|
||||
@override
|
||||
String get kycStatusStale =>
|
||||
'Не удалось обновить статус. Показан последний известный результат.';
|
||||
|
||||
@override
|
||||
String get kycUsed => 'Использовано';
|
||||
|
||||
@override
|
||||
String get kycReserved => 'Зарезервировано';
|
||||
|
||||
@override
|
||||
String get kycUsageHelp =>
|
||||
'Использовано — завершённые операции. Зарезервировано — суммы, удержанные для ожидающих операций. Обе суммы учитываются в лимите.';
|
||||
|
||||
@override
|
||||
String get kycOccupied => 'Использовано + зарезервировано';
|
||||
|
||||
@override
|
||||
String get kycNoCapacity => 'Доступный объём исчерпан';
|
||||
|
||||
@override
|
||||
String get wAccounts => 'Счета';
|
||||
|
||||
@override
|
||||
String get wActivity => 'История';
|
||||
|
||||
@override
|
||||
String get wLimits => 'Лимиты';
|
||||
|
||||
@override
|
||||
String get wSettings => 'Настройки';
|
||||
|
||||
@override
|
||||
String get wHeadline => 'Ваши деньги.\nВаш следующий шаг.';
|
||||
|
||||
@override
|
||||
String get wSubheading => 'Пополняйте. Обменивайте. Двигайтесь дальше.';
|
||||
|
||||
@override
|
||||
String get wAvailable => 'Вам доступно';
|
||||
|
||||
@override
|
||||
String get wTopUp => 'Пополнить';
|
||||
|
||||
@override
|
||||
String get wExchange => 'Обменять';
|
||||
|
||||
@override
|
||||
String get wPayout => 'Вывести';
|
||||
|
||||
@override
|
||||
String get wRecent => 'Последние операции';
|
||||
|
||||
@override
|
||||
String get wSeeAll => 'Смотреть все';
|
||||
|
||||
@override
|
||||
String get wEmptyActivity =>
|
||||
'Ваш следующий шаг начинается здесь. Здесь появятся ваши операции.';
|
||||
|
||||
@override
|
||||
String get wEmptyAccounts =>
|
||||
'Ваши счета ещё не готовы. Попробуйте обновить страницу.';
|
||||
|
||||
@override
|
||||
String get wRefresh => 'Обновить';
|
||||
|
||||
@override
|
||||
String get wSource => 'Со счёта';
|
||||
|
||||
@override
|
||||
String get wDestination => 'На счёт';
|
||||
|
||||
@override
|
||||
String get wReceiveAccount => 'Счёт для зачисления';
|
||||
|
||||
@override
|
||||
String get wAmount => 'Сумма';
|
||||
|
||||
@override
|
||||
String get wRecipient => 'Получатель';
|
||||
|
||||
@override
|
||||
String get wRecipientHint => 'Имя или реквизиты получателя';
|
||||
|
||||
@override
|
||||
String get wReview => 'Проверить';
|
||||
|
||||
@override
|
||||
String get wReviewTitle => 'Проверьте детали.';
|
||||
|
||||
@override
|
||||
String get wFee => 'Комиссия';
|
||||
|
||||
@override
|
||||
String get wTotalDebit => 'Спишется со счёта';
|
||||
|
||||
@override
|
||||
String get wCredit => 'Поступит на счёт';
|
||||
|
||||
@override
|
||||
String get wRecipientGets => 'Получатель получит';
|
||||
|
||||
@override
|
||||
String get wYouPay => 'Вы платите';
|
||||
|
||||
@override
|
||||
String get wRate => 'Курс обмена';
|
||||
|
||||
@override
|
||||
String get wQuoteNotice =>
|
||||
'Эти условия действуют 60 секунд. Подтвердите их, прежде чем продолжить.';
|
||||
|
||||
@override
|
||||
String get wExpired =>
|
||||
'Срок действия расчёта истёк. Обновите его и проверьте новые условия.';
|
||||
|
||||
@override
|
||||
String get wNewQuote => 'Обновить расчёт';
|
||||
|
||||
@override
|
||||
String get wConfirm => 'Подтвердить операцию';
|
||||
|
||||
@override
|
||||
String get wEdit => 'Изменить данные';
|
||||
|
||||
@override
|
||||
String get wClose => 'Закрыть';
|
||||
|
||||
@override
|
||||
String get wWorking => 'Обрабатываем…';
|
||||
|
||||
@override
|
||||
String get wPending => 'В обработке';
|
||||
|
||||
@override
|
||||
String get wCompleted => 'Завершено';
|
||||
|
||||
@override
|
||||
String get wFailed => 'Не выполнено';
|
||||
|
||||
@override
|
||||
String get wPendingTopUp =>
|
||||
'Пополнение обрабатывается. Доступный баланс пока не изменился.';
|
||||
|
||||
@override
|
||||
String get wPendingExchange =>
|
||||
'Сумма и комиссия уже вычтены из доступного баланса. После завершения обмена деньги появятся на счёте зачисления.';
|
||||
|
||||
@override
|
||||
String get wPendingPayout =>
|
||||
'Сумма и комиссия уже вычтены из доступного баланса. Вывод ещё обрабатывается.';
|
||||
|
||||
@override
|
||||
String get wCompleteTopUp => 'Счёт пополнен. Деньги доступны для операций.';
|
||||
|
||||
@override
|
||||
String get wCompleteExchange =>
|
||||
'Обмен завершён. Деньги доступны на счёте зачисления.';
|
||||
|
||||
@override
|
||||
String get wCompletePayout =>
|
||||
'Вывод завершён. Сумма и комиссия списаны с вашего счёта.';
|
||||
|
||||
@override
|
||||
String get wFailedTopUp =>
|
||||
'Пополнение не выполнено. На счёт ничего не зачислено.';
|
||||
|
||||
@override
|
||||
String get wFailedOutgoing =>
|
||||
'Операция не выполнена. Сумма и комиссия снова доступны на вашем счёте.';
|
||||
|
||||
@override
|
||||
String get wUnavailable =>
|
||||
'Не удалось обновить данные. Информация может быть устаревшей. Повторите попытку.';
|
||||
|
||||
@override
|
||||
String get wInvalidAmount =>
|
||||
'Введите сумму больше нуля с допустимым для валюты числом знаков после запятой.';
|
||||
|
||||
@override
|
||||
String get wInsufficient =>
|
||||
'Для этой суммы и комиссии недостаточно доступных средств. Пополните счёт или уменьшите сумму.';
|
||||
|
||||
@override
|
||||
String get wLimitError =>
|
||||
'Сумма превышает доступный лимит. Проверьте лимиты перед продолжением.';
|
||||
|
||||
@override
|
||||
String get wRecipientError =>
|
||||
'Введите тестового получателя длиной от 6 до 140 символов.';
|
||||
|
||||
@override
|
||||
String get wUnsupported => 'Эта комбинация недоступна. Выберите другой счёт.';
|
||||
|
||||
@override
|
||||
String get wNotFound => 'Не удалось найти запись. Вернитесь к счетам.';
|
||||
|
||||
@override
|
||||
String get wUncertain =>
|
||||
'Не удалось подтвердить результат. Проверьте его, прежде чем создавать другую операцию.';
|
||||
|
||||
@override
|
||||
String get wCheckOutcome => 'Проверить результат';
|
||||
|
||||
@override
|
||||
String get wNoSubmission =>
|
||||
'Операция не найдена. Вы можете снова проверить и подтвердить её.';
|
||||
|
||||
@override
|
||||
String get wDiscardTitle => 'Выйти из операции?';
|
||||
|
||||
@override
|
||||
String get wDiscardBody =>
|
||||
'Введённые данные будут удалены. Новая операция не будет отправлена.';
|
||||
|
||||
@override
|
||||
String get wStay => 'Продолжить';
|
||||
|
||||
@override
|
||||
String get wAll => 'Все';
|
||||
|
||||
@override
|
||||
String get wSearch => 'Поиск по номеру';
|
||||
|
||||
@override
|
||||
String get wNoMatches => 'Операции не найдены. Измените фильтр.';
|
||||
|
||||
@override
|
||||
String get wClearFilters => 'Сбросить фильтры';
|
||||
|
||||
@override
|
||||
String get wReference => 'Номер операции';
|
||||
|
||||
@override
|
||||
String get wWhen => 'Создано';
|
||||
|
||||
@override
|
||||
String get wViewAccount => 'Открыть счёт';
|
||||
|
||||
@override
|
||||
String get wPreferences => 'Настройте под себя.';
|
||||
|
||||
@override
|
||||
String get wLanguage => 'Язык аккаунта';
|
||||
|
||||
@override
|
||||
String get wLanguageHelp => 'Используется во всём аккаунте.';
|
||||
|
||||
@override
|
||||
String get wLanguageSaved => 'Сохранено в аккаунте.';
|
||||
|
||||
@override
|
||||
String get wLanguageFailed =>
|
||||
'Изменено для текущей сессии, но не сохранено в аккаунте. Повторите попытку ниже.';
|
||||
|
||||
@override
|
||||
String get wProfileError =>
|
||||
'Не удалось загрузить настройки аккаунта. Повторите попытку.';
|
||||
|
||||
@override
|
||||
String get wSecurity => 'Безопасность';
|
||||
|
||||
@override
|
||||
String get wSecurityBody =>
|
||||
'Настройки пароля и безопасности пока недоступны.';
|
||||
|
||||
@override
|
||||
String get wIdentity => 'Подтверждение личности';
|
||||
|
||||
@override
|
||||
String get wIdentityHelp => 'Необязательная проверка для повышения лимитов.';
|
||||
|
||||
@override
|
||||
String get wBackLogin => 'Вернуться ко входу';
|
||||
|
||||
@override
|
||||
String get wEnter => 'Открыть свои счета';
|
||||
|
||||
@override
|
||||
String get wUsage => 'Использовано за период';
|
||||
|
||||
@override
|
||||
String get wLimitsScope => 'Исходящие операции · эквивалент в EUR';
|
||||
|
||||
@override
|
||||
String get wPendingHint =>
|
||||
'Обновите, чтобы узнать текущий статус. Остальными счетами можно пользоваться.';
|
||||
|
||||
@override
|
||||
String get wFundsHeading => 'Где мои деньги?';
|
||||
|
||||
@override
|
||||
String get wAnother => 'Создать новую операцию';
|
||||
|
||||
@override
|
||||
String get factorTitle => 'Ещё одна проверка.';
|
||||
|
||||
@override
|
||||
String get factorLogin => 'Подтвердите, что это вы, чтобы завершить вход.';
|
||||
|
||||
@override
|
||||
String get factorMoney =>
|
||||
'Подтвердите эту операцию. До подтверждения деньги не переводятся.';
|
||||
|
||||
@override
|
||||
String get factorEnableHelp =>
|
||||
'Подтвердите включение двухфакторной проверки для входа и операций с деньгами.';
|
||||
|
||||
@override
|
||||
String get factorDisableHelp =>
|
||||
'Подтвердите отключение двухфакторной проверки. Для входа и операций больше не потребуется второй код.';
|
||||
|
||||
@override
|
||||
String get factorEmail => 'Введите шестизначный код из письма.';
|
||||
|
||||
@override
|
||||
String get factorAuthenticator =>
|
||||
'Введите текущий шестизначный код из приложения-аутентификатора.';
|
||||
|
||||
@override
|
||||
String get factorCode => 'Код подтверждения';
|
||||
|
||||
@override
|
||||
String get factorConfirm => 'Подтвердить и продолжить';
|
||||
|
||||
@override
|
||||
String get factorResend => 'Отправить новый код';
|
||||
|
||||
@override
|
||||
String get factorHelp =>
|
||||
'Проверьте входящие и папку «Спам». Новый код заменяет предыдущий.';
|
||||
|
||||
@override
|
||||
String get factorAppHelp =>
|
||||
'Используйте текущий код. Если приложение недоступно, отмените это действие.';
|
||||
|
||||
@override
|
||||
String get factorInvalid =>
|
||||
'Неверный код. Проверьте все шесть цифр и попробуйте ещё раз.';
|
||||
|
||||
@override
|
||||
String get factorExpired =>
|
||||
'Срок проверки истёк. Запросите новый код или вернитесь и начните снова.';
|
||||
|
||||
@override
|
||||
String get factorLocked =>
|
||||
'Слишком много неверных попыток. Подождите пять минут и начните проверку снова.';
|
||||
|
||||
@override
|
||||
String get factorWait => 'Подождите перед повторным запросом кода.';
|
||||
|
||||
@override
|
||||
String get factorRequired =>
|
||||
'Нужна повторная проверка. Подтвердите это действие ещё раз.';
|
||||
|
||||
@override
|
||||
String get factorUnavailable =>
|
||||
'Не удалось завершить проверку. Повторите попытку или отмените действие.';
|
||||
|
||||
@override
|
||||
String factorCooldown(int seconds) {
|
||||
return 'Новый код через $seconds с';
|
||||
}
|
||||
|
||||
@override
|
||||
String get factorSettings => 'Двухфакторная проверка';
|
||||
|
||||
@override
|
||||
String get factorSettingsHelp =>
|
||||
'Подтверждайте кодом вход, пополнение, обмен и вывод средств.';
|
||||
|
||||
@override
|
||||
String get factorOn => 'Включена';
|
||||
|
||||
@override
|
||||
String get factorOff => 'Выключена';
|
||||
|
||||
@override
|
||||
String get factorEnable => 'Включить';
|
||||
|
||||
@override
|
||||
String get factorDisable => 'Выключить';
|
||||
|
||||
@override
|
||||
String get factorEmailMethod => 'Код из письма';
|
||||
|
||||
@override
|
||||
String get factorAppMethod => 'Приложение-аутентификатор';
|
||||
|
||||
@override
|
||||
String get factorAppExpired =>
|
||||
'Срок проверки истёк. Вернитесь и начните снова.';
|
||||
}
|
||||
@@ -43,10 +43,11 @@
|
||||
"authCompleted": "Request completed.",
|
||||
"authInvalidCredentials": "Email or password is incorrect. Please try again.",
|
||||
"authEmailInUse": "This email is already registered. Try logging in.",
|
||||
"authVerifyEmail": "Confirm your email before signing in.",
|
||||
"authUnavailable": "The service is unavailable. Please try again.",
|
||||
"authUnexpected": "Something went wrong. Please try again.",
|
||||
"checkInbox": "Check your inbox.",
|
||||
"verificationSent": "We’ve sent you a verification email. Open the link in your inbox to confirm your email address.",
|
||||
"verificationSent": "If this email belongs to an unverified account, a verification email is on its way. Open the link in your inbox to confirm your address.",
|
||||
"verificationSending": "Preparing your verification email…",
|
||||
"verificationChecking": "Verifying your email…",
|
||||
"verificationVerified": "Your email\nis verified.",
|
||||
|
||||
@@ -43,10 +43,11 @@
|
||||
"authCompleted": "Запрос выполнен.",
|
||||
"authInvalidCredentials": "Неверная почта или пароль. Попробуйте ещё раз.",
|
||||
"authEmailInUse": "Эта почта уже зарегистрирована. Попробуйте войти.",
|
||||
"authVerifyEmail": "Подтвердите почту перед входом.",
|
||||
"authUnavailable": "Сервис недоступен. Попробуйте ещё раз.",
|
||||
"authUnexpected": "Что-то пошло не так. Попробуйте ещё раз.",
|
||||
"checkInbox": "Проверьте почту.",
|
||||
"verificationSent": "Мы отправили вам письмо для подтверждения. Откройте ссылку в письме, чтобы подтвердить электронную почту.",
|
||||
"verificationSent": "Если эта почта принадлежит неподтверждённому аккаунту, письмо с подтверждением уже в пути. Откройте ссылку в письме, чтобы подтвердить адрес.",
|
||||
"verificationSending": "Готовим письмо для подтверждения…",
|
||||
"verificationChecking": "Подтверждаем вашу почту…",
|
||||
"verificationVerified": "Ваша почта\nподтверждена.",
|
||||
|
||||
@@ -20,13 +20,19 @@ import 'generated/i18n/app_localizations.dart';
|
||||
Future<void> main() async {
|
||||
final binding = WidgetsFlutterBinding.ensureInitialized();
|
||||
final locale = await LocaleProvider.load(binding.platformDispatcher.locales);
|
||||
runApp(SxchngeApp(localeProvider: locale));
|
||||
const apiUrl = String.fromEnvironment('SXCHNGE_API_URL');
|
||||
const clientId = String.fromEnvironment('SXCHNGE_CLIENT_ID');
|
||||
final backend = apiUrl.isEmpty
|
||||
? null
|
||||
: BackendAuthServices(baseUri: Uri.parse(apiUrl), clientId: clientId);
|
||||
runApp(SxchngeApp(localeProvider: locale, backend: backend));
|
||||
}
|
||||
|
||||
class SxchngeApp extends StatefulWidget {
|
||||
const SxchngeApp({
|
||||
super.key,
|
||||
this.localeProvider,
|
||||
this.backend,
|
||||
this.analyticsService,
|
||||
this.identityService,
|
||||
this.limitsService,
|
||||
@@ -38,6 +44,7 @@ class SxchngeApp extends StatefulWidget {
|
||||
this.verificationService = const DummyVerificationService(),
|
||||
});
|
||||
final LocaleProvider? localeProvider;
|
||||
final BackendAuthServices? backend;
|
||||
final AnalyticsService? analyticsService;
|
||||
final IdentityService? identityService;
|
||||
final LimitsService? limitsService;
|
||||
@@ -56,7 +63,8 @@ class _SxchngeAppState extends State<SxchngeApp> {
|
||||
late final _locale = widget.localeProvider ?? LocaleProvider();
|
||||
|
||||
late final _analytics = widget.analyticsService ?? DummyAnalyticsService();
|
||||
late final _factors = widget.twoFactorService ?? DummyTwoFactorService();
|
||||
late final _factors =
|
||||
widget.backend ?? widget.twoFactorService ?? DummyTwoFactorService();
|
||||
late final _security = SecurityProvider(_factors, _analytics);
|
||||
late final _identity = widget.identityService ?? DummyIdentityService();
|
||||
late final _walletService =
|
||||
@@ -79,12 +87,18 @@ class _SxchngeAppState extends State<SxchngeApp> {
|
||||
late final _journeys = JourneyRecorder(_analytics);
|
||||
late final _services = InstrumentedAuthServices(
|
||||
recorder: _journeys,
|
||||
loginService: GuardedLoginService(widget.loginService, _factors),
|
||||
signupService: widget.signupService,
|
||||
verificationService: widget.verificationService,
|
||||
loginService: GuardedLoginService(
|
||||
widget.backend ?? widget.loginService,
|
||||
_factors,
|
||||
),
|
||||
signupService: widget.backend ?? widget.signupService,
|
||||
verificationService: widget.backend ?? widget.verificationService,
|
||||
);
|
||||
late final _router = createAppRouter()
|
||||
..routeInformationProvider.addListener(_routeChanged);
|
||||
late final _router = createAppRouter(
|
||||
authenticated: widget.backend == null
|
||||
? null
|
||||
: () => widget.backend!.session != null,
|
||||
)..routeInformationProvider.addListener(_routeChanged);
|
||||
String _previousPath = '/';
|
||||
|
||||
@override
|
||||
@@ -109,6 +123,7 @@ class _SxchngeAppState extends State<SxchngeApp> {
|
||||
_wallet.dispose();
|
||||
_security.dispose();
|
||||
_locale.dispose();
|
||||
widget.backend?.close();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
|
||||
@@ -19,12 +19,23 @@ import '../workspace/shell.dart';
|
||||
import '../workspace/transfer.dart';
|
||||
import 'routes.dart';
|
||||
|
||||
GoRouter createAppRouter() {
|
||||
GoRouter createAppRouter({bool Function()? authenticated}) {
|
||||
final topUpKey = GlobalKey<TransferPageState>();
|
||||
final exchangeKey = GlobalKey<TransferPageState>();
|
||||
final payoutKey = GlobalKey<TransferPageState>();
|
||||
final identityKey = GlobalKey<IdentityPageState>();
|
||||
return GoRouter(
|
||||
redirect: (context, state) {
|
||||
if (authenticated == null || authenticated()) return null;
|
||||
final path = state.uri.path;
|
||||
if (path == '/' ||
|
||||
path == '/verify-email' ||
|
||||
path == '/verification-sent' ||
|
||||
path == '/two-factor') {
|
||||
return null;
|
||||
}
|
||||
return '/';
|
||||
},
|
||||
// Signup email is an in-memory navigation extra, never browser-history data.
|
||||
extraCodec: const _TransientExtras(),
|
||||
routes: [
|
||||
|
||||
Reference in new issue
Block a user