diff --git a/l10n.yaml b/l10n.yaml new file mode 100644 index 00000000..4e6692e5 --- /dev/null +++ b/l10n.yaml @@ -0,0 +1,3 @@ +arb-dir: lib/l10n +template-arb-file: app_en.arb +output-localization-file: app_localizations.dart \ No newline at end of file diff --git a/lib/app/app.dart b/lib/app/app.dart index 0c884eaf..6dea1718 100755 --- a/lib/app/app.dart +++ b/lib/app/app.dart @@ -1,4 +1,6 @@ import 'package:flutter/material.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; +import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../theme.dart'; @@ -22,6 +24,15 @@ class YubicoAuthenticatorApp extends ConsumerWidget { themeMode: ref.watch(themeModeProvider), home: page, debugShowCheckedModeBanner: false, + localizationsDelegates: const [ + AppLocalizations.delegate, + GlobalMaterialLocalizations.delegate, + GlobalWidgetsLocalizations.delegate, + GlobalCupertinoLocalizations.delegate, + ], + supportedLocales: const [ + Locale('en', ''), // English, no country code + ], ), ), ); diff --git a/lib/app/views/app_failure_page.dart b/lib/app/views/app_failure_page.dart index 281799bc..016e117e 100755 --- a/lib/app/views/app_failure_page.dart +++ b/lib/app/views/app_failure_page.dart @@ -1,6 +1,7 @@ import 'dart:io'; import 'package:flutter/material.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../../desktop/models.dart'; @@ -42,15 +43,18 @@ class AppFailurePage extends ConsumerWidget { !ref.watch(rpcStateProvider.select((state) => state.isAdmin))) { graphic = noPermission; header = null; - message = 'WebAuthn management requires elevated privileges.'; + message = AppLocalizations.of(context)!.appFailurePage_txt_info; actions = [ OutlinedButton.icon( - label: const Text('Unlock'), + label: Text(AppLocalizations.of(context)! + .appFailurePage_btn_unlock), icon: const Icon(Icons.lock_open), style: AppTheme.primaryOutlinedButtonStyle(context), onPressed: () async { final closeMessage = showMessage( - context, 'Elevating permissions...', + context, + AppLocalizations.of(context)! + .appFailurePage_msg_permission, duration: const Duration(seconds: 30)); try { if (await ref.read(rpcProvider).elevate()) { diff --git a/lib/app/views/main_drawer.dart b/lib/app/views/main_drawer.dart index af3f3d1c..e6984156 100755 --- a/lib/app/views/main_drawer.dart +++ b/lib/app/views/main_drawer.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../../management/views/management_screen.dart'; @@ -74,7 +75,8 @@ class MainPageDrawer extends ConsumerWidget { Application.management.getAvailability(data) == Availability.enabled) ...[ DrawerItem( - titleText: 'Toggle applications', + titleText: + AppLocalizations.of(context)!.mainDrawer_txt_applications, icon: Icon(Application.management._icon), onTap: () { if (shouldPop) Navigator.of(context).pop(); @@ -89,7 +91,7 @@ class MainPageDrawer extends ConsumerWidget { ], // Non-YubiKey pages DrawerItem( - titleText: 'Settings', + titleText: AppLocalizations.of(context)!.mainDrawer_txt_settings, icon: const Icon(Icons.settings), onTap: () { final nav = Navigator.of(context); @@ -102,7 +104,7 @@ class MainPageDrawer extends ConsumerWidget { }, ), DrawerItem( - titleText: 'Help and about', + titleText: AppLocalizations.of(context)!.mainDrawer_txt_help, icon: const Icon(Icons.help), onTap: () { final nav = Navigator.of(context); diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb new file mode 100644 index 00000000..ed169241 --- /dev/null +++ b/lib/l10n/app_en.arb @@ -0,0 +1,10 @@ +{ + "@@locale": "en", + "appFailurePage_btn_unlock": "Unlock", + "appFailurePage_txt_info": "WebAuthn management requires elevated privileges.", + "appFailurePage_msg_permission": "Elevating permissions...", + + "mainDrawer_txt_applications": "Toggle applications", + "mainDrawer_txt_settings": "Settings", + "mainDrawer_txt_help": "Help and about" +} \ No newline at end of file diff --git a/pubspec.lock b/pubspec.lock index db340a89..6cfcd4b6 100755 --- a/pubspec.lock +++ b/pubspec.lock @@ -221,6 +221,11 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.0.1" + flutter_localizations: + dependency: "direct main" + description: flutter + source: sdk + version: "0.0.0" flutter_riverpod: dependency: "direct main" description: @@ -297,6 +302,13 @@ packages: description: flutter source: sdk version: "0.0.0" + intl: + dependency: "direct main" + description: + name: intl + url: "https://pub.dartlang.org" + source: hosted + version: "0.17.0" io: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 0ec04ca2..ff9c17c7 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -32,6 +32,9 @@ environment: dependencies: flutter: sdk: flutter + flutter_localizations: + sdk: flutter + intl: ^0.17.0 # The following adds the Cupertino Icons font to your application. @@ -75,6 +78,7 @@ dev_dependencies: # The following section is specific to Flutter. flutter: + generate: true # The following line ensures that the Material Icons font is # included with your application, so that you can use the icons in # the material Icons class.