Deliver localized auth app with verification and go_router
Integrate themed login/signup, EN/RU localization, shared dummy providers, verification recovery screens and named URL routes. Store frontend guidelines, workflow skills, validation and delivery documentation. Related to #2, #3, #5 and #6.
This commit is contained in:
1 parent
27424ed886
commit
10a278c65a
44 files changed
+4128
-28
No files matched your search
@@ -0,0 +1,530 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_localizations/flutter_localizations.dart';
|
||||
import 'package:intl/intl.dart' as intl;
|
||||
|
||||
import 'app_localizations_en.dart';
|
||||
import 'app_localizations_ru.dart';
|
||||
|
||||
// ignore_for_file: type=lint
|
||||
|
||||
/// Callers can lookup localized strings with an instance of AppLocalizations
|
||||
/// returned by `AppLocalizations.of(context)`.
|
||||
///
|
||||
/// Applications need to include `AppLocalizations.delegate()` in their app's
|
||||
/// `localizationDelegates` list, and the locales they support in the app's
|
||||
/// `supportedLocales` list. For example:
|
||||
///
|
||||
/// ```dart
|
||||
/// import 'i18n/app_localizations.dart';
|
||||
///
|
||||
/// return MaterialApp(
|
||||
/// localizationsDelegates: AppLocalizations.localizationsDelegates,
|
||||
/// supportedLocales: AppLocalizations.supportedLocales,
|
||||
/// home: MyApplicationHome(),
|
||||
/// );
|
||||
/// ```
|
||||
///
|
||||
/// ## Update pubspec.yaml
|
||||
///
|
||||
/// Please make sure to update your pubspec.yaml to include the following
|
||||
/// packages:
|
||||
///
|
||||
/// ```yaml
|
||||
/// dependencies:
|
||||
/// # Internationalization support.
|
||||
/// flutter_localizations:
|
||||
/// sdk: flutter
|
||||
/// intl: any # Use the pinned version from flutter_localizations
|
||||
///
|
||||
/// # Rest of dependencies
|
||||
/// ```
|
||||
///
|
||||
/// ## iOS Applications
|
||||
///
|
||||
/// iOS applications define key application metadata, including supported
|
||||
/// locales, in an Info.plist file that is built into the application bundle.
|
||||
/// To configure the locales supported by your app, you’ll need to edit this
|
||||
/// file.
|
||||
///
|
||||
/// First, open your project’s ios/Runner.xcworkspace Xcode workspace file.
|
||||
/// Then, in the Project Navigator, open the Info.plist file under the Runner
|
||||
/// project’s Runner folder.
|
||||
///
|
||||
/// Next, select the Information Property List item, select Add Item from the
|
||||
/// Editor menu, then select Localizations from the pop-up menu.
|
||||
///
|
||||
/// Select and expand the newly-created Localizations item then, for each
|
||||
/// locale your application supports, add a new item and select the locale
|
||||
/// you wish to add from the pop-up menu in the Value field. This list should
|
||||
/// be consistent with the languages listed in the AppLocalizations.supportedLocales
|
||||
/// property.
|
||||
abstract class AppLocalizations {
|
||||
AppLocalizations(String locale)
|
||||
: localeName = intl.Intl.canonicalizedLocale(locale.toString());
|
||||
|
||||
final String localeName;
|
||||
|
||||
static AppLocalizations? of(BuildContext context) {
|
||||
return Localizations.of<AppLocalizations>(context, AppLocalizations);
|
||||
}
|
||||
|
||||
static const LocalizationsDelegate<AppLocalizations> delegate =
|
||||
_AppLocalizationsDelegate();
|
||||
|
||||
/// A list of this localizations delegate along with the default localizations
|
||||
/// delegates.
|
||||
///
|
||||
/// Returns a list of localizations delegates containing this delegate along with
|
||||
/// GlobalMaterialLocalizations.delegate, GlobalCupertinoLocalizations.delegate,
|
||||
/// and GlobalWidgetsLocalizations.delegate.
|
||||
///
|
||||
/// Additional delegates can be added by appending to this list in
|
||||
/// MaterialApp. This list does not have to be used at all if a custom list
|
||||
/// of delegates is preferred or required.
|
||||
static const List<LocalizationsDelegate<dynamic>> localizationsDelegates =
|
||||
<LocalizationsDelegate<dynamic>>[
|
||||
delegate,
|
||||
GlobalMaterialLocalizations.delegate,
|
||||
GlobalCupertinoLocalizations.delegate,
|
||||
GlobalWidgetsLocalizations.delegate,
|
||||
];
|
||||
|
||||
/// A list of this localizations delegate's supported locales.
|
||||
static const List<Locale> supportedLocales = <Locale>[
|
||||
Locale('en'),
|
||||
Locale('ru'),
|
||||
];
|
||||
|
||||
/// No description provided for @appTitle.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'SXCHNGE · Your next move'**
|
||||
String get appTitle;
|
||||
|
||||
/// No description provided for @nextChapter.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'YOUR NEXT CHAPTER'**
|
||||
String get nextChapter;
|
||||
|
||||
/// No description provided for @loginHeading.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Hey, welcome\nback.'**
|
||||
String get loginHeading;
|
||||
|
||||
/// No description provided for @signupHeading.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Make your\nfirst move.'**
|
||||
String get signupHeading;
|
||||
|
||||
/// No description provided for @loginIntro.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Your next move is just a login away.'**
|
||||
String get loginIntro;
|
||||
|
||||
/// No description provided for @signupIntro.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'A new account. A world of possibility.'**
|
||||
String get signupIntro;
|
||||
|
||||
/// No description provided for @login.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Log in'**
|
||||
String get login;
|
||||
|
||||
/// No description provided for @signup.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Sign up'**
|
||||
String get signup;
|
||||
|
||||
/// No description provided for @name.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Your name'**
|
||||
String get name;
|
||||
|
||||
/// No description provided for @email.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Email address'**
|
||||
String get email;
|
||||
|
||||
/// No description provided for @emailHint.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'you@example.com'**
|
||||
String get emailHint;
|
||||
|
||||
/// No description provided for @password.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Password'**
|
||||
String get password;
|
||||
|
||||
/// No description provided for @confirmPassword.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Confirm password'**
|
||||
String get confirmPassword;
|
||||
|
||||
/// No description provided for @passwordHint.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Use at least 12 characters.'**
|
||||
String get passwordHint;
|
||||
|
||||
/// No description provided for @showPassword.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Show password'**
|
||||
String get showPassword;
|
||||
|
||||
/// No description provided for @hidePassword.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Hide password'**
|
||||
String get hidePassword;
|
||||
|
||||
/// No description provided for @showConfirmation.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Show confirmation'**
|
||||
String get showConfirmation;
|
||||
|
||||
/// No description provided for @hideConfirmation.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Hide confirmation'**
|
||||
String get hideConfirmation;
|
||||
|
||||
/// No description provided for @createAccount.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Create account'**
|
||||
String get createAccount;
|
||||
|
||||
/// No description provided for @letsGo.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Let’s go'**
|
||||
String get letsGo;
|
||||
|
||||
/// No description provided for @loginPreview.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Demo login completed. No real session was created. Your credentials have not been sent or saved.'**
|
||||
String get loginPreview;
|
||||
|
||||
/// No description provided for @signupPreview.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Demo sign-up completed. No real account was created. Your credentials have not been sent or saved.'**
|
||||
String get signupPreview;
|
||||
|
||||
/// No description provided for @alreadyMember.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Already part of sxchnge?'**
|
||||
String get alreadyMember;
|
||||
|
||||
/// No description provided for @newHere.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'New around here?'**
|
||||
String get newHere;
|
||||
|
||||
/// No description provided for @loginInstead.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Log in instead'**
|
||||
String get loginInstead;
|
||||
|
||||
/// No description provided for @createAnAccount.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Create an account'**
|
||||
String get createAnAccount;
|
||||
|
||||
/// No description provided for @earlyPreview.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'EARLY PREVIEW · Login and sign-up are not live yet.'**
|
||||
String get earlyPreview;
|
||||
|
||||
/// No description provided for @brandEyebrow.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'A LITTLE CHANGE. A BIG NEXT STEP.'**
|
||||
String get brandEyebrow;
|
||||
|
||||
/// No description provided for @brandHeading.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Good moves.\nStart here.'**
|
||||
String get brandHeading;
|
||||
|
||||
/// No description provided for @brandIntro.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'A fresh way forward.\nMake it yours with sxchnge.'**
|
||||
String get brandIntro;
|
||||
|
||||
/// No description provided for @brandCard.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Less friction.\nMore possibility.'**
|
||||
String get brandCard;
|
||||
|
||||
/// No description provided for @brandFooter.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'YOUR NEXT MOVE STARTS WITH YOU.'**
|
||||
String get brandFooter;
|
||||
|
||||
/// No description provided for @emailRequired.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Enter your email address.'**
|
||||
String get emailRequired;
|
||||
|
||||
/// No description provided for @emailInvalid.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Enter a valid email address.'**
|
||||
String get emailInvalid;
|
||||
|
||||
/// No description provided for @nameRequired.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Enter your name.'**
|
||||
String get nameRequired;
|
||||
|
||||
/// No description provided for @passwordRequired.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Enter your password.'**
|
||||
String get passwordRequired;
|
||||
|
||||
/// No description provided for @confirmationRequired.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Confirm your password.'**
|
||||
String get confirmationRequired;
|
||||
|
||||
/// No description provided for @passwordMismatch.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Passwords do not match.'**
|
||||
String get passwordMismatch;
|
||||
|
||||
/// No description provided for @language.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Language'**
|
||||
String get language;
|
||||
|
||||
/// No description provided for @preferenceNotSaved.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Language changed for this session. Your preference could not be saved.'**
|
||||
String get preferenceNotSaved;
|
||||
|
||||
/// No description provided for @authWorking.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Please wait…'**
|
||||
String get authWorking;
|
||||
|
||||
/// No description provided for @authCompleted.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Request completed.'**
|
||||
String get authCompleted;
|
||||
|
||||
/// No description provided for @authInvalidCredentials.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Email or password is incorrect. Please try again.'**
|
||||
String get authInvalidCredentials;
|
||||
|
||||
/// No description provided for @authEmailInUse.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'This email is already registered. Try logging in.'**
|
||||
String get authEmailInUse;
|
||||
|
||||
/// No description provided for @authUnavailable.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'The service is unavailable. Please try again.'**
|
||||
String get authUnavailable;
|
||||
|
||||
/// No description provided for @authUnexpected.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Something went wrong. Please try again.'**
|
||||
String get authUnexpected;
|
||||
|
||||
/// No description provided for @checkInbox.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Check your inbox.'**
|
||||
String get checkInbox;
|
||||
|
||||
/// No description provided for @verificationSent.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'We’ve sent you a verification email. Open the link in your inbox to confirm your email address.'**
|
||||
String get verificationSent;
|
||||
|
||||
/// No description provided for @verificationSending.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Preparing your verification email…'**
|
||||
String get verificationSending;
|
||||
|
||||
/// No description provided for @verificationChecking.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Verifying your email…'**
|
||||
String get verificationChecking;
|
||||
|
||||
/// No description provided for @verificationVerified.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Your email\nis verified.'**
|
||||
String get verificationVerified;
|
||||
|
||||
/// No description provided for @verificationVerifiedBody.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'One step done. You can now return to login. Identity verification is a separate step.'**
|
||||
String get verificationVerifiedBody;
|
||||
|
||||
/// No description provided for @verificationExpired.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'This link has expired.'**
|
||||
String get verificationExpired;
|
||||
|
||||
/// No description provided for @verificationExpiredBody.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Request a new verification email and use the latest link.'**
|
||||
String get verificationExpiredBody;
|
||||
|
||||
/// No description provided for @verificationInvalid.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'This link isn’t valid.'**
|
||||
String get verificationInvalid;
|
||||
|
||||
/// No description provided for @verificationInvalidBody.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'The confirmation link is missing or invalid. Open the complete link from your email, or request a new one.'**
|
||||
String get verificationInvalidBody;
|
||||
|
||||
/// No description provided for @verificationInternal.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Something went wrong.'**
|
||||
String get verificationInternal;
|
||||
|
||||
/// No description provided for @verificationInternalBody.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'We couldn’t complete your request because of an internal error. Please try again.'**
|
||||
String get verificationInternalBody;
|
||||
|
||||
/// No description provided for @verificationResend.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Resend verification email'**
|
||||
String get verificationResend;
|
||||
|
||||
/// No description provided for @verificationRequest.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Send a new verification email'**
|
||||
String get verificationRequest;
|
||||
|
||||
/// No description provided for @verificationRetry.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Try again'**
|
||||
String get verificationRetry;
|
||||
|
||||
/// No description provided for @verificationBack.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Back to login'**
|
||||
String get verificationBack;
|
||||
|
||||
/// No description provided for @verificationHint.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'No email? Check your spam folder or request another below.'**
|
||||
String get verificationHint;
|
||||
|
||||
/// No description provided for @verificationDemo.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'DEMO · No real email is sent and no account is verified.'**
|
||||
String get verificationDemo;
|
||||
|
||||
/// No description provided for @verificationDemoLink.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Open demo confirmation link'**
|
||||
String get verificationDemoLink;
|
||||
|
||||
/// No description provided for @verificationStep.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'CONFIRM YOUR EMAIL'**
|
||||
String get verificationStep;
|
||||
}
|
||||
|
||||
class _AppLocalizationsDelegate
|
||||
extends LocalizationsDelegate<AppLocalizations> {
|
||||
const _AppLocalizationsDelegate();
|
||||
|
||||
@override
|
||||
Future<AppLocalizations> load(Locale locale) {
|
||||
return SynchronousFuture<AppLocalizations>(lookupAppLocalizations(locale));
|
||||
}
|
||||
|
||||
@override
|
||||
bool isSupported(Locale locale) =>
|
||||
<String>['en', 'ru'].contains(locale.languageCode);
|
||||
|
||||
@override
|
||||
bool shouldReload(_AppLocalizationsDelegate old) => false;
|
||||
}
|
||||
|
||||
AppLocalizations lookupAppLocalizations(Locale locale) {
|
||||
// Lookup logic when only language code is specified.
|
||||
switch (locale.languageCode) {
|
||||
case 'en':
|
||||
return AppLocalizationsEn();
|
||||
case 'ru':
|
||||
return AppLocalizationsRu();
|
||||
}
|
||||
|
||||
throw FlutterError(
|
||||
'AppLocalizations.delegate failed to load unsupported locale "$locale". This is likely '
|
||||
'an issue with the localizations generation tool. Please file an issue '
|
||||
'on GitHub with a reproducible sample app and the gen-l10n configuration '
|
||||
'that was used.',
|
||||
);
|
||||
}
|
||||
Reference in new issue
Block a user