From a17bd819c0ae1fb42afca52f3e974cfeb5189617 Mon Sep 17 00:00:00 2001 From: Oleksandr Prokhorenko Date: Thu, 23 Nov 2023 09:48:25 +0100 Subject: [PATCH] feat(fronted): add catalyst_voices_localization pub (#155) * feat(fronted): add catalyst_voices_localization pub * Delete l10n.dart * feat: update localization * Update project.dic * wip * feat: update localization pub * Update README.md * Update README.md --- .config/dictionaries/project.dic | 2 + catalyst_voices/README.md | 108 ------------ catalyst_voices/l10n.yaml | 4 - catalyst_voices/lib/app/view/app.dart | 16 +- catalyst_voices/lib/dummy/constants.dart | 2 + catalyst_voices/lib/dummy/home_screen.dart | 7 +- catalyst_voices/lib/dummy/login_page.dart | 28 ++-- catalyst_voices/lib/l10n/arb/app_en.arb | 7 - catalyst_voices/lib/l10n/arb/app_es.arb | 7 - catalyst_voices/lib/l10n/l10n.dart | 8 - .../catalyst_voices_localization/.gitignore | 44 +++++ .../catalyst_voices_localization/README.md | 143 ++++++++++++++++ .../catalyst_voices_localization/l10n.yaml | 9 + .../lib/catalyst_voices_localization.dart | 4 + .../catalyst_voices_localizations.dart | 156 ++++++++++++++++++ .../catalyst_voices_localizations_en.dart | 21 +++ .../catalyst_voices_localizations_es.dart | 21 +++ .../lib/l10n/intl_en.arb | 23 +++ .../lib/l10n/intl_es.arb | 8 + .../build_context_localization_extension.dart | 6 + .../lib/src/catalyst_voices_localization.dart | 2 + .../catalyst_voices_localization/pubspec.yaml | 22 +++ catalyst_voices/pubspec.yaml | 6 +- catalyst_voices/test/helpers/pump_app.dart | 11 +- cspell.json | 5 +- 25 files changed, 506 insertions(+), 164 deletions(-) delete mode 100644 catalyst_voices/l10n.yaml delete mode 100644 catalyst_voices/lib/l10n/arb/app_en.arb delete mode 100644 catalyst_voices/lib/l10n/arb/app_es.arb delete mode 100644 catalyst_voices/lib/l10n/l10n.dart create mode 100644 catalyst_voices/packages/catalyst_voices_localization/.gitignore create mode 100644 catalyst_voices/packages/catalyst_voices_localization/README.md create mode 100644 catalyst_voices/packages/catalyst_voices_localization/l10n.yaml create mode 100644 catalyst_voices/packages/catalyst_voices_localization/lib/catalyst_voices_localization.dart create mode 100644 catalyst_voices/packages/catalyst_voices_localization/lib/generated/catalyst_voices_localizations.dart create mode 100644 catalyst_voices/packages/catalyst_voices_localization/lib/generated/catalyst_voices_localizations_en.dart create mode 100644 catalyst_voices/packages/catalyst_voices_localization/lib/generated/catalyst_voices_localizations_es.dart create mode 100644 catalyst_voices/packages/catalyst_voices_localization/lib/l10n/intl_en.arb create mode 100644 catalyst_voices/packages/catalyst_voices_localization/lib/l10n/intl_es.arb create mode 100644 catalyst_voices/packages/catalyst_voices_localization/lib/src/build_context_localization_extension.dart create mode 100644 catalyst_voices/packages/catalyst_voices_localization/lib/src/catalyst_voices_localization.dart create mode 100644 catalyst_voices/packages/catalyst_voices_localization/pubspec.yaml diff --git a/.config/dictionaries/project.dic b/.config/dictionaries/project.dic index 9992a41dfcb..e946395ed50 100644 --- a/.config/dictionaries/project.dic +++ b/.config/dictionaries/project.dic @@ -8,6 +8,7 @@ auditability bluefireteam BROTLI cardano +Catalyst CEST cfbundle chromedriver @@ -17,6 +18,7 @@ COCOAPODS codepoints coti cryptoxide +Cupertino dbsync delegators dockerhub diff --git a/catalyst_voices/README.md b/catalyst_voices/README.md index 9470f4adddc..66a173c130f 100644 --- a/catalyst_voices/README.md +++ b/catalyst_voices/README.md @@ -7,10 +7,6 @@ * [Getting Started](#getting-started) * [Bootstrapping](#bootstrapping) * [Running Tests](#running-tests) - * [Working with Translations](#working-with-translations) - * [Adding Strings](#adding-strings) - * [Adding Supported Locales](#adding-supported-locales) - * [Adding Translations](#adding-translations) ## Requirements @@ -80,107 +76,3 @@ genhtml coverage/lcov.info -o coverage/ # Open Coverage Report open coverage/index.html ``` - -## Working with Translations - -This project relies on [flutter_localizations](https://github.com/flutter/flutter/tree/master/packages/flutter_localizations). -It follows the [official internationalization guide for Flutter][flutter-intl-guide]. - -### Adding Strings - -1. To add a new localizable string, open the `app_en.arb` file at `lib/l10n/arb/app_en.arb`. - -```arb -{ - "@@locale": "en", - "counterAppBarTitle": "Counter", - "@counterAppBarTitle": { - "description": "Text shown in the AppBar of the Counter Page" - } -} -``` - -2. Then add a new key/value and description - -```arb -{ - "@@locale": "en", - "counterAppBarTitle": "Counter", - "@counterAppBarTitle": { - "description": "Text shown in the AppBar of the Counter Page" - }, - "helloWorld": "Hello World", - "@helloWorld": { - "description": "Hello World Text" - } -} -``` - -3. Use the new string - -```dart -import 'package:catalyst_voices/l10n/l10n.dart'; - -@override -Widget build(BuildContext context) { - final l10n = context.l10n; - return Text(l10n.helloWorld); -} -``` - -### Adding Supported Locales - -Update the `CFBundleLocalizations` array in the `Info.plist` at `ios/Runner/Info.plist` to include the new locale. - -```xml - ... - - CFBundleLocalizations - - en - es - - - ... -``` - -### Adding Translations - -1. For each supported locale, add a new ARB file in `lib/l10n/arb`. - -```tree -├── l10n -│ ├── arb -│ │ ├── app_en.arb -│ │ └── app_es.arb -``` - -2. Add the translated strings to each `.arb` file: - -`app_en.arb` - -```arb -{ - "@@locale": "en", - "counterAppBarTitle": "Counter", - "@counterAppBarTitle": { - "description": "Text shown in the AppBar of the Counter Page" - } -} -``` - - - -`app_es.arb` - -```arb -{ - "@@locale": "es", - "counterAppBarTitle": "Contador", - "@counterAppBarTitle": { - "description": "Texto mostrado en la AppBar de la página del contador" - } -} -``` - -[flutter-intl-guide]: https://docs.flutter.dev/development/accessibility-and-localization/internationalization diff --git a/catalyst_voices/l10n.yaml b/catalyst_voices/l10n.yaml deleted file mode 100644 index 6f72a55d41f..00000000000 --- a/catalyst_voices/l10n.yaml +++ /dev/null @@ -1,4 +0,0 @@ -arb-dir: lib/l10n/arb -template-arb-file: app_en.arb -output-localization-file: app_localizations.dart -nullable-getter: false diff --git a/catalyst_voices/lib/app/view/app.dart b/catalyst_voices/lib/app/view/app.dart index 1c74787030b..1c9a879f136 100644 --- a/catalyst_voices/lib/app/view/app.dart +++ b/catalyst_voices/lib/app/view/app.dart @@ -1,16 +1,22 @@ import 'package:catalyst_voices/dummy/dummy.dart'; -import 'package:catalyst_voices/l10n/l10n.dart'; +import 'package:catalyst_voices_localization/catalyst_voices_localization.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_localized_locales/flutter_localized_locales.dart'; final class App extends StatelessWidget { const App({super.key}); @override Widget build(BuildContext context) { - return const MaterialApp( - localizationsDelegates: AppLocalizations.localizationsDelegates, - supportedLocales: AppLocalizations.supportedLocales, - home: LoginPage(), + return MaterialApp( + restorationScopeId: 'rootVoices', + localizationsDelegates: const [ + ...VoicesLocalizations.localizationsDelegates, + LocaleNamesLocalizationsDelegate(), + ], + supportedLocales: VoicesLocalizations.supportedLocales, + localeListResolutionCallback: basicLocaleListResolution, + home: isUserLoggedIn ? const HomeScreen() : const LoginPage(), ); } } diff --git a/catalyst_voices/lib/dummy/constants.dart b/catalyst_voices/lib/dummy/constants.dart index af2935d3325..a9cf3a8ed7f 100644 --- a/catalyst_voices/lib/dummy/constants.dart +++ b/catalyst_voices/lib/dummy/constants.dart @@ -1,5 +1,7 @@ import 'package:flutter/foundation.dart'; +bool isUserLoggedIn = false; + abstract class WidgetKeys { static const loginScreen = Key('loginScreen'); static const usernameTextController = Key('usernameTextController'); diff --git a/catalyst_voices/lib/dummy/home_screen.dart b/catalyst_voices/lib/dummy/home_screen.dart index 4bbc73ef5c8..84e1415ffa5 100644 --- a/catalyst_voices/lib/dummy/home_screen.dart +++ b/catalyst_voices/lib/dummy/home_screen.dart @@ -1,5 +1,6 @@ import 'package:catalyst_voices/dummy/dummy.dart'; import 'package:catalyst_voices_assets/catalyst_voices_assets.dart'; +import 'package:catalyst_voices_localization/catalyst_voices_localization.dart'; import 'package:flutter/material.dart'; final class HomeScreen extends StatelessWidget { @@ -13,9 +14,9 @@ final class HomeScreen extends StatelessWidget { child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ - const Text( - 'Catalyst Voices', - style: TextStyle( + Text( + context.l10n.homeScreenText, + style: const TextStyle( color: VoicesColors.purpleGradientStart, fontFamily: VoicesFonts.sFPro, fontSize: 32, diff --git a/catalyst_voices/lib/dummy/login_page.dart b/catalyst_voices/lib/dummy/login_page.dart index 5387bb7e77f..e80241e7e64 100644 --- a/catalyst_voices/lib/dummy/login_page.dart +++ b/catalyst_voices/lib/dummy/login_page.dart @@ -1,4 +1,5 @@ import 'package:catalyst_voices/dummy/dummy.dart'; +import 'package:catalyst_voices_localization/catalyst_voices_localization.dart'; import 'package:flutter/material.dart'; final class LoginPage extends StatefulWidget { @@ -9,12 +10,8 @@ final class LoginPage extends StatefulWidget { } abstract class _Constants { - static const usernameLabelText = 'Username'; - static const passwordLabelText = 'Password'; static const username = 'robot'; static const password = '1234'; - static const errorMessage = 'Wrong credentials'; - static const loginButtonText = 'Login'; } final class _LoginPageState extends State { @@ -23,6 +20,7 @@ final class _LoginPageState extends State { @override Widget build(BuildContext context) { + final l10n = context.l10n; return Scaffold( key: WidgetKeys.loginScreen, body: Center( @@ -39,9 +37,9 @@ final class _LoginPageState extends State { child: TextFormField( key: WidgetKeys.usernameTextController, controller: usernameTextController, - decoration: const InputDecoration( - border: OutlineInputBorder(), - labelText: _Constants.usernameLabelText, + decoration: InputDecoration( + border: const OutlineInputBorder(), + labelText: l10n.loginScreenUsernameLabelText, ), ), ), @@ -51,9 +49,9 @@ final class _LoginPageState extends State { key: WidgetKeys.passwordTextController, controller: passwordTextController, obscureText: true, - decoration: const InputDecoration( - border: OutlineInputBorder(), - labelText: _Constants.passwordLabelText, + decoration: InputDecoration( + border: const OutlineInputBorder(), + labelText: l10n.loginScreenPasswordLabelText, ), ), ), @@ -62,7 +60,7 @@ final class _LoginPageState extends State { child: ElevatedButton( key: WidgetKeys.loginButton, onPressed: () async => _loginButtonPressed(context), - child: const Text(_Constants.loginButtonText), + child: Text(l10n.loginScreenLoginButtonText), ), ), ], @@ -106,9 +104,9 @@ final class _LoginPageState extends State { void _showError(BuildContext context) { ScaffoldMessenger.of(context).showSnackBar( - const SnackBar( + SnackBar( key: WidgetKeys.loginErrorSnackbar, - content: Text(_Constants.errorMessage), + content: Text(context.l10n.loginScreenErrorMessage), ), ); } @@ -116,6 +114,8 @@ final class _LoginPageState extends State { bool _validateCredentials() { final username = usernameTextController.text; final password = passwordTextController.text; - return username == _Constants.username && password == _Constants.password; + + return isUserLoggedIn = + username == _Constants.username && password == _Constants.password; } } diff --git a/catalyst_voices/lib/l10n/arb/app_en.arb b/catalyst_voices/lib/l10n/arb/app_en.arb deleted file mode 100644 index a5484a06191..00000000000 --- a/catalyst_voices/lib/l10n/arb/app_en.arb +++ /dev/null @@ -1,7 +0,0 @@ -{ - "@@locale": "en", - "counterAppBarTitle": "Counter", - "@counterAppBarTitle": { - "description": "Text shown in the AppBar of the Counter Page" - } -} \ No newline at end of file diff --git a/catalyst_voices/lib/l10n/arb/app_es.arb b/catalyst_voices/lib/l10n/arb/app_es.arb deleted file mode 100644 index f1405f02e3c..00000000000 --- a/catalyst_voices/lib/l10n/arb/app_es.arb +++ /dev/null @@ -1,7 +0,0 @@ -{ - "@@locale": "es", - "counterAppBarTitle": "Contador", - "@counterAppBarTitle": { - "description": "Texto mostrado en la AppBar de la página del contador" - } -} \ No newline at end of file diff --git a/catalyst_voices/lib/l10n/l10n.dart b/catalyst_voices/lib/l10n/l10n.dart deleted file mode 100644 index 17c891b5c0d..00000000000 --- a/catalyst_voices/lib/l10n/l10n.dart +++ /dev/null @@ -1,8 +0,0 @@ -import 'package:flutter/widgets.dart'; -import 'package:flutter_gen/gen_l10n/app_localizations.dart'; - -export 'package:flutter_gen/gen_l10n/app_localizations.dart'; - -extension AppLocalizationsX on BuildContext { - AppLocalizations get l10n => AppLocalizations.of(this); -} diff --git a/catalyst_voices/packages/catalyst_voices_localization/.gitignore b/catalyst_voices/packages/catalyst_voices_localization/.gitignore new file mode 100644 index 00000000000..06ef8e610f7 --- /dev/null +++ b/catalyst_voices/packages/catalyst_voices_localization/.gitignore @@ -0,0 +1,44 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ +migrate_working_dir/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# VSCode related +.vscode/* + +# Flutter/Dart/Pub related +**/doc/api/ +**/ios/Flutter/.last_build_id +.dart_tool/ +.flutter-plugins +.flutter-plugins-dependencies +.packages +.pub-cache/ +.pub/ +/build/ +pubspec.lock + +# Web related +lib/generated_plugin_registrant.dart + +# Symbolication related +app.*.symbols + +# Obfuscation related +app.*.map.json + +# Test related +coverage \ No newline at end of file diff --git a/catalyst_voices/packages/catalyst_voices_localization/README.md b/catalyst_voices/packages/catalyst_voices_localization/README.md new file mode 100644 index 00000000000..e2ed408d05c --- /dev/null +++ b/catalyst_voices/packages/catalyst_voices_localization/README.md @@ -0,0 +1,143 @@ +# Catalyst Voices Localization + +This package contains the localization files for the Catalyst Voices app. + +* [Catalyst Voices Localization](#catalyst-voices-localization) + * [Working with Translations](#working-with-translations) + * [Creating New Locale Messages](#creating-new-locale-messages) + * [Adding Strings](#adding-strings) + * [Adding Translations](#adding-translations) + * [Adding Supported Locales](#adding-supported-locales) + * [Generating VoicesLocalizations](#generating-voiceslocalizations) + +## Working with Translations + +This project relies on [flutter_localizations](https://github.com/flutter/flutter/tree/master/packages/flutter_localizations). +It follows the official +[internationalization](https://docs.flutter.dev/development/accessibility-and-localization/internationalization) +guide for Flutter. + +## Creating New Locale Messages + +To add new strings for localization, modify `intl_en.arb`, +which this project uses as its template. + +New entries must adhere to the format below: + +```arb + "dartGetterVariableName": "english translation of the message", + "@dartGetterVariableName": { + "description": "description for use by the localizations delegate." + }, +``` + +Here, `dartGetterVariableName` represents the Dart method/property name utilized in your localizations delegate. + +Once you've updated `intl_en.arb` with the new message, regenerate the `VoicesLocalizations` delegate to enable +immediate use of the English message in your application code through the localizations delegate, +bypassing the need to wait for translation completion. + +### Adding Strings + +* To add a new localizable string, open the `intl_en.arb` file at `lib/l10n/`. + +```arb +{ + "@@locale": "en", + "loginScreenUsernameLabelText": "Username", + "@loginScreenUsernameLabelText": { + "description": "Text shown in the login screen for the username field" + } +} +``` + +* Then add a new key/value and description + +```arb +{ + "@@locale": "en", + "loginScreenUsernameLabelText": "Username", + "@loginScreenUsernameLabelText": { + "description": "Text shown in the login screen for the username field" + }, + "loginScreenPasswordLabelText": "Password", + "@loginScreenPasswordLabelText": { + "description": "Text shown in the login screen for the password field" + } +} +``` + +### Adding Translations + +* For each supported locale, add a new ARB file in `lib/l10n/`. + +```tree +├── l10n +│ ├── intl_en.arb +│ ├── intl_es.arb +``` + +* Add the translated strings to each `.arb` file: + +`intl_en.arb` + +```arb +{ + "@@locale": "en", + "loginScreenUsernameLabelText": "Username", + "@loginScreenUsernameLabelText": { + "description": "Text shown in the login screen for the username field" + }, + "loginScreenPasswordLabelText": "Password", + "@loginScreenPasswordLabelText": { + "description": "Text shown in the login screen for the password field" + } +} +``` + +`app_es.arb` + + + +```arb +{ + "@@locale": "es", + "loginScreenUsernameLabelText": "Nombre de usuario", + "loginScreenPasswordLabelText": "Contraseña", +} +``` + +### Adding Supported Locales + +Update the `CFBundleLocalizations` array in the `Info.plist` at +`ios/Runner/Info.plist` to include the new locale. + +```xml + ... + CFBundleLocalizations + + en + es + + ... +``` + +## Generating VoicesLocalizations + +* Run the following command in `catalyst_voices_localization` package to +generate the `VoicesLocalizations` class: + +```sh +flutter gen-l10n +``` + +* Use the new string + +```dart +import 'package:catalyst_voices_localization/catalyst_voices_localization.dart'; + +@override +Widget build(BuildContext context) { + return Text(context.l10n.loginScreenPasswordLabelText); +} +``` diff --git a/catalyst_voices/packages/catalyst_voices_localization/l10n.yaml b/catalyst_voices/packages/catalyst_voices_localization/l10n.yaml new file mode 100644 index 00000000000..7b2de8a5b54 --- /dev/null +++ b/catalyst_voices/packages/catalyst_voices_localization/l10n.yaml @@ -0,0 +1,9 @@ +arb-dir: lib/l10n +output-dir: lib/generated/ +template-arb-file: intl_en.arb +output-localization-file: catalyst_voices_localizations.dart +output-class: VoicesLocalizations +preferred-supported-locales: + - en +use-deferred-loading: true +synthetic-package: false \ No newline at end of file diff --git a/catalyst_voices/packages/catalyst_voices_localization/lib/catalyst_voices_localization.dart b/catalyst_voices/packages/catalyst_voices_localization/lib/catalyst_voices_localization.dart new file mode 100644 index 00000000000..520652bb33e --- /dev/null +++ b/catalyst_voices/packages/catalyst_voices_localization/lib/catalyst_voices_localization.dart @@ -0,0 +1,4 @@ +/// A Very Good Project created by Very Good CLI. +library catalyst_voices_localization; + +export 'src/catalyst_voices_localization.dart'; diff --git a/catalyst_voices/packages/catalyst_voices_localization/lib/generated/catalyst_voices_localizations.dart b/catalyst_voices/packages/catalyst_voices_localization/lib/generated/catalyst_voices_localizations.dart new file mode 100644 index 00000000000..c58d7449479 --- /dev/null +++ b/catalyst_voices/packages/catalyst_voices_localization/lib/generated/catalyst_voices_localizations.dart @@ -0,0 +1,156 @@ +import 'dart:async'; + +import 'package:flutter/widgets.dart'; +import 'package:flutter_localizations/flutter_localizations.dart'; +import 'package:intl/intl.dart' as intl; + +import 'catalyst_voices_localizations_en.dart' deferred as catalyst_voices_localizations_en; +import 'catalyst_voices_localizations_es.dart' deferred as catalyst_voices_localizations_es; + +/// Callers can lookup localized strings with an instance of VoicesLocalizations +/// returned by `VoicesLocalizations.of(context)`. +/// +/// Applications need to include `VoicesLocalizations.delegate()` in their app's +/// `localizationDelegates` list, and the locales they support in the app's +/// `supportedLocales` list. For example: +/// +/// ```dart +/// import 'generated/catalyst_voices_localizations.dart'; +/// +/// return MaterialApp( +/// localizationsDelegates: VoicesLocalizations.localizationsDelegates, +/// supportedLocales: VoicesLocalizations.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 VoicesLocalizations.supportedLocales +/// property. +abstract class VoicesLocalizations { + VoicesLocalizations(String locale) : localeName = intl.Intl.canonicalizedLocale(locale.toString()); + + final String localeName; + + static VoicesLocalizations? of(BuildContext context) { + return Localizations.of(context, VoicesLocalizations); + } + + static const LocalizationsDelegate delegate = _VoicesLocalizationsDelegate(); + + /// 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> localizationsDelegates = >[ + delegate, + GlobalMaterialLocalizations.delegate, + GlobalCupertinoLocalizations.delegate, + GlobalWidgetsLocalizations.delegate, + ]; + + /// A list of this localizations delegate's supported locales. + static const List supportedLocales = [ + Locale('en'), + Locale('es') + ]; + + /// Text shown in the login screen for the username field + /// + /// In en, this message translates to: + /// **'Username'** + String get loginScreenUsernameLabelText; + + /// Text shown in the login screen for the password field + /// + /// In en, this message translates to: + /// **'Password'** + String get loginScreenPasswordLabelText; + + /// Text shown in the login screen when the user enters wrong credentials + /// + /// In en, this message translates to: + /// **'Wrong credentials'** + String get loginScreenErrorMessage; + + /// Text shown in the login screen for the login button + /// + /// In en, this message translates to: + /// **'Login'** + String get loginScreenLoginButtonText; + + /// Text shown in the home screen + /// + /// In en, this message translates to: + /// **'Catalyst Voices'** + String get homeScreenText; +} + +class _VoicesLocalizationsDelegate extends LocalizationsDelegate { + const _VoicesLocalizationsDelegate(); + + @override + Future load(Locale locale) { + return lookupVoicesLocalizations(locale); + } + + @override + bool isSupported(Locale locale) => ['en', 'es'].contains(locale.languageCode); + + @override + bool shouldReload(_VoicesLocalizationsDelegate old) => false; +} + +Future lookupVoicesLocalizations(Locale locale) { + + + // Lookup logic when only language code is specified. + switch (locale.languageCode) { + case 'en': return catalyst_voices_localizations_en.loadLibrary().then((dynamic _) => catalyst_voices_localizations_en.VoicesLocalizationsEn()); + case 'es': return catalyst_voices_localizations_es.loadLibrary().then((dynamic _) => catalyst_voices_localizations_es.VoicesLocalizationsEs()); + } + + throw FlutterError( + 'VoicesLocalizations.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.' + ); +} diff --git a/catalyst_voices/packages/catalyst_voices_localization/lib/generated/catalyst_voices_localizations_en.dart b/catalyst_voices/packages/catalyst_voices_localization/lib/generated/catalyst_voices_localizations_en.dart new file mode 100644 index 00000000000..effa58a9a59 --- /dev/null +++ b/catalyst_voices/packages/catalyst_voices_localization/lib/generated/catalyst_voices_localizations_en.dart @@ -0,0 +1,21 @@ +import 'catalyst_voices_localizations.dart'; + +/// The translations for English (`en`). +class VoicesLocalizationsEn extends VoicesLocalizations { + VoicesLocalizationsEn([String locale = 'en']) : super(locale); + + @override + String get loginScreenUsernameLabelText => 'Username'; + + @override + String get loginScreenPasswordLabelText => 'Password'; + + @override + String get loginScreenErrorMessage => 'Wrong credentials'; + + @override + String get loginScreenLoginButtonText => 'Login'; + + @override + String get homeScreenText => 'Catalyst Voices'; +} diff --git a/catalyst_voices/packages/catalyst_voices_localization/lib/generated/catalyst_voices_localizations_es.dart b/catalyst_voices/packages/catalyst_voices_localization/lib/generated/catalyst_voices_localizations_es.dart new file mode 100644 index 00000000000..28b089fd89b --- /dev/null +++ b/catalyst_voices/packages/catalyst_voices_localization/lib/generated/catalyst_voices_localizations_es.dart @@ -0,0 +1,21 @@ +import 'catalyst_voices_localizations.dart'; + +/// The translations for Spanish Castilian (`es`). +class VoicesLocalizationsEs extends VoicesLocalizations { + VoicesLocalizationsEs([String locale = 'es']) : super(locale); + + @override + String get loginScreenUsernameLabelText => 'Nombre de usuario'; + + @override + String get loginScreenPasswordLabelText => 'Contraseña'; + + @override + String get loginScreenErrorMessage => 'Credenciales incorrectas'; + + @override + String get loginScreenLoginButtonText => 'Acceso'; + + @override + String get homeScreenText => 'Catalyst Voices'; +} diff --git a/catalyst_voices/packages/catalyst_voices_localization/lib/l10n/intl_en.arb b/catalyst_voices/packages/catalyst_voices_localization/lib/l10n/intl_en.arb new file mode 100644 index 00000000000..437ad23ca69 --- /dev/null +++ b/catalyst_voices/packages/catalyst_voices_localization/lib/l10n/intl_en.arb @@ -0,0 +1,23 @@ +{ + "@@locale": "en", + "loginScreenUsernameLabelText": "Username", + "@loginScreenUsernameLabelText": { + "description": "Text shown in the login screen for the username field" + }, + "loginScreenPasswordLabelText": "Password", + "@loginScreenPasswordLabelText": { + "description": "Text shown in the login screen for the password field" + }, + "loginScreenErrorMessage": "Wrong credentials", + "@loginScreenErrorMessage": { + "description": "Text shown in the login screen when the user enters wrong credentials" + }, + "loginScreenLoginButtonText": "Login", + "@loginScreenLoginButtonText": { + "description": "Text shown in the login screen for the login button" + }, + "homeScreenText": "Catalyst Voices", + "@homeScreenText": { + "description": "Text shown in the home screen" + } +} diff --git a/catalyst_voices/packages/catalyst_voices_localization/lib/l10n/intl_es.arb b/catalyst_voices/packages/catalyst_voices_localization/lib/l10n/intl_es.arb new file mode 100644 index 00000000000..e21e9246e0e --- /dev/null +++ b/catalyst_voices/packages/catalyst_voices_localization/lib/l10n/intl_es.arb @@ -0,0 +1,8 @@ +{ + "@@locale": "es", + "loginScreenUsernameLabelText": "Nombre de usuario", + "loginScreenPasswordLabelText": "Contraseña", + "loginScreenErrorMessage": "Credenciales incorrectas", + "loginScreenLoginButtonText": "Acceso", + "homeScreenLoginButtonText": "Catalyst Voices - Inicio 🇪🇸" +} diff --git a/catalyst_voices/packages/catalyst_voices_localization/lib/src/build_context_localization_extension.dart b/catalyst_voices/packages/catalyst_voices_localization/lib/src/build_context_localization_extension.dart new file mode 100644 index 00000000000..3daeda8576c --- /dev/null +++ b/catalyst_voices/packages/catalyst_voices_localization/lib/src/build_context_localization_extension.dart @@ -0,0 +1,6 @@ +import 'package:catalyst_voices_localization/generated/catalyst_voices_localizations.dart'; +import 'package:flutter/widgets.dart'; + +extension BuildContextLocalizationExtension on BuildContext { + VoicesLocalizations get l10n => VoicesLocalizations.of(this)!; +} diff --git a/catalyst_voices/packages/catalyst_voices_localization/lib/src/catalyst_voices_localization.dart b/catalyst_voices/packages/catalyst_voices_localization/lib/src/catalyst_voices_localization.dart new file mode 100644 index 00000000000..678bb60f539 --- /dev/null +++ b/catalyst_voices/packages/catalyst_voices_localization/lib/src/catalyst_voices_localization.dart @@ -0,0 +1,2 @@ +export 'package:catalyst_voices_localization/generated/catalyst_voices_localizations.dart'; +export 'package:catalyst_voices_localization/src/build_context_localization_extension.dart'; diff --git a/catalyst_voices/packages/catalyst_voices_localization/pubspec.yaml b/catalyst_voices/packages/catalyst_voices_localization/pubspec.yaml new file mode 100644 index 00000000000..0917244b2e7 --- /dev/null +++ b/catalyst_voices/packages/catalyst_voices_localization/pubspec.yaml @@ -0,0 +1,22 @@ +name: catalyst_voices_localization +description: A Catalyst Voices Localization. +version: 0.1.0+1 +publish_to: none + +environment: + sdk: ">=3.2.0 <4.0.0" + flutter: 3.16.0 + +dependencies: + flutter: + sdk: flutter + flutter_localizations: + sdk: flutter + intl: ^0.18.1 + +dev_dependencies: + flutter_test: + sdk: flutter + +flutter: + generate: true diff --git a/catalyst_voices/pubspec.yaml b/catalyst_voices/pubspec.yaml index 12dee6bdd36..547a1137486 100644 --- a/catalyst_voices/pubspec.yaml +++ b/catalyst_voices/pubspec.yaml @@ -11,12 +11,12 @@ dependencies: bloc: ^8.1.2 catalyst_voices_assets: path: ./packages/catalyst_voices_assets + catalyst_voices_localization: + path: ./packages/catalyst_voices_localization flutter: sdk: flutter flutter_bloc: ^8.1.3 - flutter_localizations: - sdk: flutter - intl: ^0.18.1 + flutter_localized_locales: ^2.0.5 dev_dependencies: bloc_test: ^9.1.4 diff --git a/catalyst_voices/test/helpers/pump_app.dart b/catalyst_voices/test/helpers/pump_app.dart index db6b04658b1..9edb76d5161 100644 --- a/catalyst_voices/test/helpers/pump_app.dart +++ b/catalyst_voices/test/helpers/pump_app.dart @@ -1,13 +1,18 @@ -import 'package:catalyst_voices/l10n/l10n.dart'; +import 'package:catalyst_voices_localization/catalyst_voices_localization.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_localized_locales/flutter_localized_locales.dart'; import 'package:flutter_test/flutter_test.dart'; extension PumpApp on WidgetTester { Future pumpApp(Widget widget) { return pumpWidget( MaterialApp( - localizationsDelegates: AppLocalizations.localizationsDelegates, - supportedLocales: AppLocalizations.supportedLocales, + localizationsDelegates: const [ + ...VoicesLocalizations.localizationsDelegates, + LocaleNamesLocalizationsDelegate(), + ], + supportedLocales: VoicesLocalizations.supportedLocales, + localeListResolutionCallback: basicLocaleListResolution, home: widget, ), ); diff --git a/cspell.json b/cspell.json index 979023996dd..363ea0cab83 100644 --- a/cspell.json +++ b/cspell.json @@ -215,7 +215,7 @@ //.config/dictionaries/cspell/sv/cspell-ext.json //.config/dictionaries/cspell/tr_TR/cspell-ext.json //.config/dictionaries/cspell/uk_UA/cspell-ext.json - //.config/dictionaries/cspell/vi_VN/cspell-ext.json + //.config/dictionaries/cspell/vi_VN/cspell-ext.json ], "ignorePaths": [ ".config/dictionaries/**", @@ -233,6 +233,7 @@ "**/historic_data/**/*.json", "**/test_data/**/*.sql", "styles.min.css", - "web-components.min.js" + "web-components.min.js", + "**/generated/**" ] } \ No newline at end of file