From b2d96e466ebf8a19bc85d74d1b2a3240025cd576 Mon Sep 17 00:00:00 2001 From: insleker Date: Sat, 30 Aug 2025 03:28:05 +0800 Subject: [PATCH] chore: improve i18n development experience --- .gitignore | 2 + .vscode/extensions.json | 8 +- README.md | 1 + l10n.yaml | 1 - lib/l10n/app_en.arb | 122 ++++-- lib/l10n/app_es.arb | 78 ++-- lib/l10n/app_localizations.dart | 373 ------------------ lib/l10n/app_localizations_en.dart | 127 ------ lib/l10n/app_localizations_es.dart | 127 ------ lib/l10n/app_localizations_zh.dart | 249 ------------ lib/l10n/app_zh.arb | 75 ++-- lib/l10n/app_zh_TW.arb | 75 ++-- .../features/pdf/widgets/pdf_page_area.dart | 16 +- lib/ui/features/pdf/widgets/pdf_screen.dart | 6 +- lib/ui/features/pdf/widgets/pdf_toolbar.dart | 2 +- test/features/step/_tokens.dart | 1 + 16 files changed, 221 insertions(+), 1042 deletions(-) delete mode 100644 lib/l10n/app_localizations.dart delete mode 100644 lib/l10n/app_localizations_en.dart delete mode 100644 lib/l10n/app_localizations_es.dart delete mode 100644 lib/l10n/app_localizations_zh.dart diff --git a/.gitignore b/.gitignore index dd0d9fa..69ada61 100644 --- a/.gitignore +++ b/.gitignore @@ -123,3 +123,5 @@ docs/.* .vscode/launch.json devtools_options.yaml test/features/*_test.dart +**/app_localizations*.dart +.env diff --git a/.vscode/extensions.json b/.vscode/extensions.json index 8874b30..62d5411 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -1,6 +1,12 @@ { "recommendations": [ "yzhang.markdown-all-in-one", - "alexkrechik.cucumberautocomplete" + "alexkrechik.cucumberautocomplete", + "google.arb-editor", + "dart-code.flutter", + "lsaudon.l10nization", // quick translation gen + "oke331.flutter-l10n-helper", // show arb string + "gabbygreat.flutter-l10n-checker", // detect hard-coded strings + // "joaopinacio.translate-me" ] } \ No newline at end of file diff --git a/README.md b/README.md index 5655df5..11acfd6 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,7 @@ checkout [`docs/FRs.md`](docs/FRs.md) ```bash # flutter clean +# arb_translate flutter pub get # generate gherkin test flutter pub run build_runner build --delete-conflicting-outputs diff --git a/l10n.yaml b/l10n.yaml index 5fc505f..efc1f95 100644 --- a/l10n.yaml +++ b/l10n.yaml @@ -3,4 +3,3 @@ template-arb-file: app_en.arb output-class: AppLocalizations output-localization-file: app_localizations.dart nullable-getter: false -untranslated-messages-file: build/l10n_missing.txt diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index ec4f68a..59c9ca2 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -1,59 +1,107 @@ { "@@locale": "en", "appTitle": "PDF Signature", + "@appTitle": {}, + "backgroundRemoval": "Background removal", + "@backgroundRemoval": {}, + "brightness": "Brightness", + "@brightness": {}, + "clear": "Clear", + "@clear": {}, + "confirm": "Confirm", + "@confirm": {}, + "contrast": "Contrast", + "@contrast": {}, + "createNewSignature": "Create new signature", + "@createNewSignature": {}, + "delete": "Delete", + "@delete": {}, + "downloadStarted": "Download started", + "@downloadStarted": {}, + "dpi": "DPI:", + "@dpi": {}, + "drawSignature": "Draw Signature", + "@drawSignature": {}, "errorWithMessage": "Error: {message}", "@errorWithMessage": { "description": "Generic error text with message", - "placeholders": {"message": {"type": "String"}} + "placeholders": { + "message": { + "type": "String" + } + } }, - - "settings": "Settings", - "theme": "Theme", - "themeLight": "Light", - "themeDark": "Dark", - "themeSystem": "System", + "exportingPleaseWait": "Exporting... Please wait", + "@exportingPleaseWait": {}, + "failedToGeneratePdf": "Failed to generate PDF", + "@failedToGeneratePdf": {}, + "failedToSavePdf": "Failed to save PDF", + "@failedToSavePdf": {}, + "goTo": "Go to:", + "@goTo": {}, + "invalidOrUnsupportedFile": "Invalid or unsupported file", + "@invalidOrUnsupportedFile": {}, "language": "Language", - "languageEnglish": "English", + "@language": {}, "languageChineseTraditional": "Traditional Chinese", + "@languageChineseTraditional": {}, + "languageEnglish": "English", + "@languageEnglish": {}, "languageSpanish": "Spanish", - "resetToDefaults": "Reset to defaults", - - "openPdf": "Open PDF...", - "prev": "Prev", + "@languageSpanish": {}, + "loadSignatureFromFile": "Load Signature from file", + "@loadSignatureFromFile": {}, + "lockAspectRatio": "Lock aspect ratio", + "@lockAspectRatio": {}, + "longPressOrRightClickTheSignatureToConfirmOrDelete": "Long-press or right-click the signature to Confirm or Delete.", + "@longPressOrRightClickTheSignatureToConfirmOrDelete": {}, "next": "Next", + "@next": {}, + "noPdfLoaded": "No PDF loaded", + "@noPdfLoaded": {}, + "nothingToSaveYet": "Nothing to save yet", + "@nothingToSaveYet": {}, + "openPdf": "Open PDF...", + "@openPdf": {}, "pageInfo": "Page {current}/{total}", "@pageInfo": { "description": "Label showing current page and total", "placeholders": { - "current": {"type": "int"}, - "total": {"type": "int"} + "current": { + "type": "int" + }, + "total": { + "type": "int" + } } }, - "goTo": "Go to:", - "dpi": "DPI:", - "saveSignedPdf": "Save Signed PDF", - "loadSignatureFromFile": "Load Signature from file", - "drawSignature": "Draw Signature", - "noPdfLoaded": "No PDF loaded", - "signature": "Signature", - "lockAspectRatio": "Lock aspect ratio", - "backgroundRemoval": "Background removal", - "contrast": "Contrast", - "brightness": "Brightness", - "exportingPleaseWait": "Exporting... Please wait", - - "nothingToSaveYet": "Nothing to save yet", + "prev": "Prev", + "@prev": {}, + "resetToDefaults": "Reset to defaults", + "@resetToDefaults": {}, "savedWithPath": "Saved: {path}", "@savedWithPath": { "description": "Snackbar text showing where file saved", - "placeholders": {"path": {"type": "String"}} + "placeholders": { + "path": { + "type": "String" + } + } }, - "failedToSavePdf": "Failed to save PDF", - "downloadStarted": "Download started", - "failedToGeneratePdf": "Failed to generate PDF", - "invalidOrUnsupportedFile": "Invalid or unsupported file", - - "confirm": "Confirm", + "saveSignedPdf": "Save Signed PDF", + "@saveSignedPdf": {}, + "settings": "Settings", + "@settings": {}, + "signature": "Signature", + "@signature": {}, + "theme": "Theme", + "@theme": {}, + "themeDark": "Dark", + "@themeDark": {}, + "themeLight": "Light", + "@themeLight": {}, + "themeSystem": "System", + "@themeSystem": {}, "undo": "Undo", - "clear": "Clear" -} + "@undo": {} +} \ No newline at end of file diff --git a/lib/l10n/app_es.arb b/lib/l10n/app_es.arb index 60926e0..d300743 100644 --- a/lib/l10n/app_es.arb +++ b/lib/l10n/app_es.arb @@ -1,44 +1,42 @@ { - "@@locale": "es", "appTitle": "Firma PDF", - "errorWithMessage": "Error: {message}", - - "settings": "Ajustes", - "theme": "Tema", - "themeLight": "Claro", - "themeDark": "Oscuro", - "themeSystem": "Del sistema", - "language": "Idioma", - "languageEnglish": "Inglés", - "languageChineseTraditional": "Chino tradicional", - "languageSpanish": "Español", - "resetToDefaults": "Restablecer valores", - - "openPdf": "Abrir PDF…", - "prev": "Anterior", - "next": "Siguiente", - "pageInfo": "Página {current}/{total}", - "goTo": "Ir a:", - "dpi": "DPI:", - "saveSignedPdf": "Guardar PDF firmado", - "loadSignatureFromFile": "Cargar firma desde archivo", - "drawSignature": "Dibujar firma", - "noPdfLoaded": "No hay PDF cargado", - "signature": "Firma", - "lockAspectRatio": "Bloquear relación de aspecto", - "backgroundRemoval": "Eliminación de fondo", - "contrast": "Contraste", + "backgroundRemoval": "Eliminar fondo", "brightness": "Brillo", - "exportingPleaseWait": "Exportando... Por favor espera", - - "nothingToSaveYet": "Nada que guardar todavía", - "savedWithPath": "Guardado: {path}", - "failedToSavePdf": "Error al guardar el PDF", - "downloadStarted": "Descarga iniciada", - "failedToGeneratePdf": "Error al generar el PDF", - "invalidOrUnsupportedFile": "Archivo no válido o no compatible", - + "clear": "Limpiar", "confirm": "Confirmar", - "undo": "Deshacer", - "clear": "Limpiar" -} + "contrast": "Contraste", + "createNewSignature": "Crear nueva firma", + "delete": "Eliminar", + "downloadStarted": "Descarga iniciada", + "dpi": "DPI:", + "drawSignature": "Dibujar firma", + "errorWithMessage": "Error: {message}", + "exportingPleaseWait": "Exportando... Por favor, espere", + "failedToGeneratePdf": "No se pudo generar el PDF", + "failedToSavePdf": "No se pudo guardar el PDF", + "goTo": "Ir a:", + "invalidOrUnsupportedFile": "Archivo inválido o no compatible", + "language": "Idioma", + "languageChineseTraditional": "Chino tradicional", + "languageEnglish": "Inglés", + "languageSpanish": "Español", + "loadSignatureFromFile": "Cargar firma desde archivo", + "lockAspectRatio": "Bloquear relación de aspecto", + "longPressOrRightClickTheSignatureToConfirmOrDelete": "Pulse prolongadamente o haga clic derecho en la firma para confirmar o eliminar.", + "next": "Siguiente", + "noPdfLoaded": "No se ha cargado ningún PDF", + "nothingToSaveYet": "Aún no hay nada que guardar", + "openPdf": "Abrir PDF...", + "pageInfo": "Página {current}/{total}", + "prev": "Anterior", + "resetToDefaults": "Restablecer valores predeterminados", + "savedWithPath": "Guardado: {path}", + "saveSignedPdf": "Guardar PDF firmado", + "settings": "Ajustes", + "signature": "Firma", + "theme": "Tema", + "themeDark": "Oscuro", + "themeLight": "Claro", + "themeSystem": "Sistema", + "undo": "Deshacer" +} \ No newline at end of file diff --git a/lib/l10n/app_localizations.dart b/lib/l10n/app_localizations.dart deleted file mode 100644 index c787c64..0000000 --- a/lib/l10n/app_localizations.dart +++ /dev/null @@ -1,373 +0,0 @@ -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_es.dart'; -import 'app_localizations_zh.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 'l10n/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(context, AppLocalizations)!; - } - - static const LocalizationsDelegate 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> 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'), - Locale('zh'), - Locale('zh', 'TW'), - ]; - - /// No description provided for @appTitle. - /// - /// In en, this message translates to: - /// **'PDF Signature'** - String get appTitle; - - /// Generic error text with message - /// - /// In en, this message translates to: - /// **'Error: {message}'** - String errorWithMessage(String message); - - /// No description provided for @settings. - /// - /// In en, this message translates to: - /// **'Settings'** - String get settings; - - /// No description provided for @theme. - /// - /// In en, this message translates to: - /// **'Theme'** - String get theme; - - /// No description provided for @themeLight. - /// - /// In en, this message translates to: - /// **'Light'** - String get themeLight; - - /// No description provided for @themeDark. - /// - /// In en, this message translates to: - /// **'Dark'** - String get themeDark; - - /// No description provided for @themeSystem. - /// - /// In en, this message translates to: - /// **'System'** - String get themeSystem; - - /// No description provided for @language. - /// - /// In en, this message translates to: - /// **'Language'** - String get language; - - /// No description provided for @languageEnglish. - /// - /// In en, this message translates to: - /// **'English'** - String get languageEnglish; - - /// No description provided for @languageChineseTraditional. - /// - /// In en, this message translates to: - /// **'Traditional Chinese'** - String get languageChineseTraditional; - - /// No description provided for @languageSpanish. - /// - /// In en, this message translates to: - /// **'Spanish'** - String get languageSpanish; - - /// No description provided for @resetToDefaults. - /// - /// In en, this message translates to: - /// **'Reset to defaults'** - String get resetToDefaults; - - /// No description provided for @openPdf. - /// - /// In en, this message translates to: - /// **'Open PDF...'** - String get openPdf; - - /// No description provided for @prev. - /// - /// In en, this message translates to: - /// **'Prev'** - String get prev; - - /// No description provided for @next. - /// - /// In en, this message translates to: - /// **'Next'** - String get next; - - /// Label showing current page and total - /// - /// In en, this message translates to: - /// **'Page {current}/{total}'** - String pageInfo(int current, int total); - - /// No description provided for @goTo. - /// - /// In en, this message translates to: - /// **'Go to:'** - String get goTo; - - /// No description provided for @dpi. - /// - /// In en, this message translates to: - /// **'DPI:'** - String get dpi; - - /// No description provided for @saveSignedPdf. - /// - /// In en, this message translates to: - /// **'Save Signed PDF'** - String get saveSignedPdf; - - /// No description provided for @loadSignatureFromFile. - /// - /// In en, this message translates to: - /// **'Load Signature from file'** - String get loadSignatureFromFile; - - /// No description provided for @drawSignature. - /// - /// In en, this message translates to: - /// **'Draw Signature'** - String get drawSignature; - - /// No description provided for @noPdfLoaded. - /// - /// In en, this message translates to: - /// **'No PDF loaded'** - String get noPdfLoaded; - - /// No description provided for @signature. - /// - /// In en, this message translates to: - /// **'Signature'** - String get signature; - - /// No description provided for @lockAspectRatio. - /// - /// In en, this message translates to: - /// **'Lock aspect ratio'** - String get lockAspectRatio; - - /// No description provided for @backgroundRemoval. - /// - /// In en, this message translates to: - /// **'Background removal'** - String get backgroundRemoval; - - /// No description provided for @contrast. - /// - /// In en, this message translates to: - /// **'Contrast'** - String get contrast; - - /// No description provided for @brightness. - /// - /// In en, this message translates to: - /// **'Brightness'** - String get brightness; - - /// No description provided for @exportingPleaseWait. - /// - /// In en, this message translates to: - /// **'Exporting... Please wait'** - String get exportingPleaseWait; - - /// No description provided for @nothingToSaveYet. - /// - /// In en, this message translates to: - /// **'Nothing to save yet'** - String get nothingToSaveYet; - - /// Snackbar text showing where file saved - /// - /// In en, this message translates to: - /// **'Saved: {path}'** - String savedWithPath(String path); - - /// No description provided for @failedToSavePdf. - /// - /// In en, this message translates to: - /// **'Failed to save PDF'** - String get failedToSavePdf; - - /// No description provided for @downloadStarted. - /// - /// In en, this message translates to: - /// **'Download started'** - String get downloadStarted; - - /// No description provided for @failedToGeneratePdf. - /// - /// In en, this message translates to: - /// **'Failed to generate PDF'** - String get failedToGeneratePdf; - - /// No description provided for @invalidOrUnsupportedFile. - /// - /// In en, this message translates to: - /// **'Invalid or unsupported file'** - String get invalidOrUnsupportedFile; - - /// No description provided for @confirm. - /// - /// In en, this message translates to: - /// **'Confirm'** - String get confirm; - - /// No description provided for @undo. - /// - /// In en, this message translates to: - /// **'Undo'** - String get undo; - - /// No description provided for @clear. - /// - /// In en, this message translates to: - /// **'Clear'** - String get clear; -} - -class _AppLocalizationsDelegate - extends LocalizationsDelegate { - const _AppLocalizationsDelegate(); - - @override - Future load(Locale locale) { - return SynchronousFuture(lookupAppLocalizations(locale)); - } - - @override - bool isSupported(Locale locale) => - ['en', 'es', 'zh'].contains(locale.languageCode); - - @override - bool shouldReload(_AppLocalizationsDelegate old) => false; -} - -AppLocalizations lookupAppLocalizations(Locale locale) { - // Lookup logic when language+country codes are specified. - switch (locale.languageCode) { - case 'zh': - { - switch (locale.countryCode) { - case 'TW': - return AppLocalizationsZhTw(); - } - break; - } - } - - // Lookup logic when only language code is specified. - switch (locale.languageCode) { - case 'en': - return AppLocalizationsEn(); - case 'es': - return AppLocalizationsEs(); - case 'zh': - return AppLocalizationsZh(); - } - - 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.', - ); -} diff --git a/lib/l10n/app_localizations_en.dart b/lib/l10n/app_localizations_en.dart deleted file mode 100644 index b86589c..0000000 --- a/lib/l10n/app_localizations_en.dart +++ /dev/null @@ -1,127 +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 => 'PDF Signature'; - - @override - String errorWithMessage(String message) { - return 'Error: $message'; - } - - @override - String get settings => 'Settings'; - - @override - String get theme => 'Theme'; - - @override - String get themeLight => 'Light'; - - @override - String get themeDark => 'Dark'; - - @override - String get themeSystem => 'System'; - - @override - String get language => 'Language'; - - @override - String get languageEnglish => 'English'; - - @override - String get languageChineseTraditional => 'Traditional Chinese'; - - @override - String get languageSpanish => 'Spanish'; - - @override - String get resetToDefaults => 'Reset to defaults'; - - @override - String get openPdf => 'Open PDF...'; - - @override - String get prev => 'Prev'; - - @override - String get next => 'Next'; - - @override - String pageInfo(int current, int total) { - return 'Page $current/$total'; - } - - @override - String get goTo => 'Go to:'; - - @override - String get dpi => 'DPI:'; - - @override - String get saveSignedPdf => 'Save Signed PDF'; - - @override - String get loadSignatureFromFile => 'Load Signature from file'; - - @override - String get drawSignature => 'Draw Signature'; - - @override - String get noPdfLoaded => 'No PDF loaded'; - - @override - String get signature => 'Signature'; - - @override - String get lockAspectRatio => 'Lock aspect ratio'; - - @override - String get backgroundRemoval => 'Background removal'; - - @override - String get contrast => 'Contrast'; - - @override - String get brightness => 'Brightness'; - - @override - String get exportingPleaseWait => 'Exporting... Please wait'; - - @override - String get nothingToSaveYet => 'Nothing to save yet'; - - @override - String savedWithPath(String path) { - return 'Saved: $path'; - } - - @override - String get failedToSavePdf => 'Failed to save PDF'; - - @override - String get downloadStarted => 'Download started'; - - @override - String get failedToGeneratePdf => 'Failed to generate PDF'; - - @override - String get invalidOrUnsupportedFile => 'Invalid or unsupported file'; - - @override - String get confirm => 'Confirm'; - - @override - String get undo => 'Undo'; - - @override - String get clear => 'Clear'; -} diff --git a/lib/l10n/app_localizations_es.dart b/lib/l10n/app_localizations_es.dart deleted file mode 100644 index 3dfbb6c..0000000 --- a/lib/l10n/app_localizations_es.dart +++ /dev/null @@ -1,127 +0,0 @@ -// ignore: unused_import -import 'package:intl/intl.dart' as intl; -import 'app_localizations.dart'; - -// ignore_for_file: type=lint - -/// The translations for Spanish Castilian (`es`). -class AppLocalizationsEs extends AppLocalizations { - AppLocalizationsEs([String locale = 'es']) : super(locale); - - @override - String get appTitle => 'Firma PDF'; - - @override - String errorWithMessage(String message) { - return 'Error: $message'; - } - - @override - String get settings => 'Ajustes'; - - @override - String get theme => 'Tema'; - - @override - String get themeLight => 'Claro'; - - @override - String get themeDark => 'Oscuro'; - - @override - String get themeSystem => 'Del sistema'; - - @override - String get language => 'Idioma'; - - @override - String get languageEnglish => 'Inglés'; - - @override - String get languageChineseTraditional => 'Chino tradicional'; - - @override - String get languageSpanish => 'Español'; - - @override - String get resetToDefaults => 'Restablecer valores'; - - @override - String get openPdf => 'Abrir PDF…'; - - @override - String get prev => 'Anterior'; - - @override - String get next => 'Siguiente'; - - @override - String pageInfo(int current, int total) { - return 'Página $current/$total'; - } - - @override - String get goTo => 'Ir a:'; - - @override - String get dpi => 'DPI:'; - - @override - String get saveSignedPdf => 'Guardar PDF firmado'; - - @override - String get loadSignatureFromFile => 'Cargar firma desde archivo'; - - @override - String get drawSignature => 'Dibujar firma'; - - @override - String get noPdfLoaded => 'No hay PDF cargado'; - - @override - String get signature => 'Firma'; - - @override - String get lockAspectRatio => 'Bloquear relación de aspecto'; - - @override - String get backgroundRemoval => 'Eliminación de fondo'; - - @override - String get contrast => 'Contraste'; - - @override - String get brightness => 'Brillo'; - - @override - String get exportingPleaseWait => 'Exportando... Por favor espera'; - - @override - String get nothingToSaveYet => 'Nada que guardar todavía'; - - @override - String savedWithPath(String path) { - return 'Guardado: $path'; - } - - @override - String get failedToSavePdf => 'Error al guardar el PDF'; - - @override - String get downloadStarted => 'Descarga iniciada'; - - @override - String get failedToGeneratePdf => 'Error al generar el PDF'; - - @override - String get invalidOrUnsupportedFile => 'Archivo no válido o no compatible'; - - @override - String get confirm => 'Confirmar'; - - @override - String get undo => 'Deshacer'; - - @override - String get clear => 'Limpiar'; -} diff --git a/lib/l10n/app_localizations_zh.dart b/lib/l10n/app_localizations_zh.dart deleted file mode 100644 index 1da3962..0000000 --- a/lib/l10n/app_localizations_zh.dart +++ /dev/null @@ -1,249 +0,0 @@ -// ignore: unused_import -import 'package:intl/intl.dart' as intl; -import 'app_localizations.dart'; - -// ignore_for_file: type=lint - -/// The translations for Chinese (`zh`). -class AppLocalizationsZh extends AppLocalizations { - AppLocalizationsZh([String locale = 'zh']) : super(locale); - - @override - String get appTitle => 'PDF 簽名'; - - @override - String errorWithMessage(String message) { - return '錯誤:$message'; - } - - @override - String get settings => '設定'; - - @override - String get theme => '主題'; - - @override - String get themeLight => '淺色'; - - @override - String get themeDark => '深色'; - - @override - String get themeSystem => '系統'; - - @override - String get language => '語言'; - - @override - String get languageEnglish => '英文'; - - @override - String get languageChineseTraditional => '繁體中文'; - - @override - String get languageSpanish => '西班牙文'; - - @override - String get resetToDefaults => '重設為預設值'; - - @override - String get openPdf => '開啟 PDF…'; - - @override - String get prev => '上一頁'; - - @override - String get next => '下一頁'; - - @override - String pageInfo(int current, int total) { - return '第 $current/$total 頁'; - } - - @override - String get goTo => '前往:'; - - @override - String get dpi => 'DPI:'; - - @override - String get saveSignedPdf => '儲存已簽名 PDF'; - - @override - String get loadSignatureFromFile => '從檔案載入簽名'; - - @override - String get drawSignature => '手寫簽名'; - - @override - String get noPdfLoaded => '尚未載入 PDF'; - - @override - String get signature => '簽名'; - - @override - String get lockAspectRatio => '鎖定長寬比'; - - @override - String get backgroundRemoval => '去除背景'; - - @override - String get contrast => '對比'; - - @override - String get brightness => '亮度'; - - @override - String get exportingPleaseWait => '匯出中…請稍候'; - - @override - String get nothingToSaveYet => '尚無可儲存的內容'; - - @override - String savedWithPath(String path) { - return '已儲存:$path'; - } - - @override - String get failedToSavePdf => '儲存 PDF 失敗'; - - @override - String get downloadStarted => '已開始下載'; - - @override - String get failedToGeneratePdf => '產生 PDF 失敗'; - - @override - String get invalidOrUnsupportedFile => '無效或不支援的檔案'; - - @override - String get confirm => '確認'; - - @override - String get undo => '復原'; - - @override - String get clear => '清除'; -} - -/// The translations for Chinese, as used in Taiwan (`zh_TW`). -class AppLocalizationsZhTw extends AppLocalizationsZh { - AppLocalizationsZhTw() : super('zh_TW'); - - @override - String get appTitle => 'PDF 簽名'; - - @override - String errorWithMessage(String message) { - return '錯誤:$message'; - } - - @override - String get settings => '設定'; - - @override - String get theme => '主題'; - - @override - String get themeLight => '淺色'; - - @override - String get themeDark => '深色'; - - @override - String get themeSystem => '系統'; - - @override - String get language => '語言'; - - @override - String get languageEnglish => '英文'; - - @override - String get languageChineseTraditional => '繁體中文'; - - @override - String get languageSpanish => '西班牙文'; - - @override - String get resetToDefaults => '重設為預設值'; - - @override - String get openPdf => '開啟 PDF…'; - - @override - String get prev => '上一頁'; - - @override - String get next => '下一頁'; - - @override - String pageInfo(int current, int total) { - return '第 $current/$total 頁'; - } - - @override - String get goTo => '前往:'; - - @override - String get dpi => 'DPI:'; - - @override - String get saveSignedPdf => '儲存已簽名 PDF'; - - @override - String get loadSignatureFromFile => '從檔案載入簽名'; - - @override - String get drawSignature => '手寫簽名'; - - @override - String get noPdfLoaded => '尚未載入 PDF'; - - @override - String get signature => '簽名'; - - @override - String get lockAspectRatio => '鎖定長寬比'; - - @override - String get backgroundRemoval => '去除背景'; - - @override - String get contrast => '對比'; - - @override - String get brightness => '亮度'; - - @override - String get exportingPleaseWait => '匯出中…請稍候'; - - @override - String get nothingToSaveYet => '尚無可儲存的內容'; - - @override - String savedWithPath(String path) { - return '已儲存:$path'; - } - - @override - String get failedToSavePdf => '儲存 PDF 失敗'; - - @override - String get downloadStarted => '已開始下載'; - - @override - String get failedToGeneratePdf => '產生 PDF 失敗'; - - @override - String get invalidOrUnsupportedFile => '無效或不支援的檔案'; - - @override - String get confirm => '確認'; - - @override - String get undo => '復原'; - - @override - String get clear => '清除'; -} diff --git a/lib/l10n/app_zh.arb b/lib/l10n/app_zh.arb index 303e370..92cdeb6 100644 --- a/lib/l10n/app_zh.arb +++ b/lib/l10n/app_zh.arb @@ -1,44 +1,43 @@ { "@@locale": "zh", "appTitle": "PDF 簽名", - "errorWithMessage": "錯誤:{message}", - - "settings": "設定", - "theme": "主題", - "themeLight": "淺色", - "themeDark": "深色", - "themeSystem": "系統", - "language": "語言", - "languageEnglish": "英文", - "languageChineseTraditional": "繁體中文", - "languageSpanish": "西班牙文", - "resetToDefaults": "重設為預設值", - - "openPdf": "開啟 PDF…", - "prev": "上一頁", - "next": "下一頁", - "pageInfo": "第 {current}/{total} 頁", - "goTo": "前往:", - "dpi": "DPI:", - "saveSignedPdf": "儲存已簽名 PDF", - "loadSignatureFromFile": "從檔案載入簽名", - "drawSignature": "手寫簽名", - "noPdfLoaded": "尚未載入 PDF", - "signature": "簽名", - "lockAspectRatio": "鎖定長寬比", "backgroundRemoval": "去除背景", - "contrast": "對比", "brightness": "亮度", - "exportingPleaseWait": "匯出中…請稍候", - - "nothingToSaveYet": "尚無可儲存的內容", - "savedWithPath": "已儲存:{path}", - "failedToSavePdf": "儲存 PDF 失敗", - "downloadStarted": "已開始下載", - "failedToGeneratePdf": "產生 PDF 失敗", - "invalidOrUnsupportedFile": "無效或不支援的檔案", - + "clear": "清除", "confirm": "確認", - "undo": "復原", - "clear": "清除" -} + "contrast": "對比", + "createNewSignature": "建立新簽名", + "delete": "刪除", + "downloadStarted": "已開始下載", + "dpi": "DPI:", + "drawSignature": "手寫簽名", + "errorWithMessage": "錯誤:{message}", + "exportingPleaseWait": "匯出中…請稍候", + "failedToGeneratePdf": "產生 PDF 失敗", + "failedToSavePdf": "儲存 PDF 失敗", + "goTo": "前往:", + "invalidOrUnsupportedFile": "無效或不支援的檔案", + "language": "語言", + "languageChineseTraditional": "繁體中文", + "languageEnglish": "英文", + "languageSpanish": "西班牙文", + "loadSignatureFromFile": "從檔案載入簽名", + "lockAspectRatio": "鎖定長寬比", + "longPressOrRightClickTheSignatureToConfirmOrDelete": "長按或右鍵點擊簽名以確認或刪除。", + "next": "下一頁", + "noPdfLoaded": "尚未載入 PDF", + "nothingToSaveYet": "尚無可儲存的內容", + "openPdf": "開啟 PDF…", + "pageInfo": "第 {current}/{total} 頁", + "prev": "上一頁", + "resetToDefaults": "重設為預設值", + "savedWithPath": "已儲存:{path}", + "saveSignedPdf": "儲存已簽名 PDF", + "settings": "設定", + "signature": "簽名", + "theme": "主題", + "themeDark": "深色", + "themeLight": "淺色", + "themeSystem": "系統", + "undo": "復原" +} \ No newline at end of file diff --git a/lib/l10n/app_zh_TW.arb b/lib/l10n/app_zh_TW.arb index 8153474..103c01f 100644 --- a/lib/l10n/app_zh_TW.arb +++ b/lib/l10n/app_zh_TW.arb @@ -1,44 +1,43 @@ { "@@locale": "zh_TW", "appTitle": "PDF 簽名", - "errorWithMessage": "錯誤:{message}", - - "settings": "設定", - "theme": "主題", - "themeLight": "淺色", - "themeDark": "深色", - "themeSystem": "系統", - "language": "語言", - "languageEnglish": "英文", - "languageChineseTraditional": "繁體中文", - "languageSpanish": "西班牙文", - "resetToDefaults": "重設為預設值", - - "openPdf": "開啟 PDF…", - "prev": "上一頁", - "next": "下一頁", - "pageInfo": "第 {current}/{total} 頁", - "goTo": "前往:", - "dpi": "DPI:", - "saveSignedPdf": "儲存已簽名 PDF", - "loadSignatureFromFile": "從檔案載入簽名", - "drawSignature": "手寫簽名", - "noPdfLoaded": "尚未載入 PDF", - "signature": "簽名", - "lockAspectRatio": "鎖定長寬比", "backgroundRemoval": "去除背景", - "contrast": "對比", "brightness": "亮度", - "exportingPleaseWait": "匯出中…請稍候", - - "nothingToSaveYet": "尚無可儲存的內容", - "savedWithPath": "已儲存:{path}", - "failedToSavePdf": "儲存 PDF 失敗", - "downloadStarted": "已開始下載", - "failedToGeneratePdf": "產生 PDF 失敗", - "invalidOrUnsupportedFile": "無效或不支援的檔案", - + "clear": "清除", "confirm": "確認", - "undo": "復原", - "clear": "清除" -} + "contrast": "對比", + "createNewSignature": "建立新簽名", + "delete": "刪除", + "downloadStarted": "已開始下載", + "dpi": "DPI:", + "drawSignature": "手寫簽名", + "errorWithMessage": "錯誤:{message}", + "exportingPleaseWait": "匯出中…請稍候", + "failedToGeneratePdf": "產生 PDF 失敗", + "failedToSavePdf": "儲存 PDF 失敗", + "goTo": "前往:", + "invalidOrUnsupportedFile": "無效或不支援的檔案", + "language": "語言", + "languageChineseTraditional": "繁體中文", + "languageEnglish": "英文", + "languageSpanish": "西班牙文", + "loadSignatureFromFile": "從檔案載入簽名", + "lockAspectRatio": "鎖定長寬比", + "longPressOrRightClickTheSignatureToConfirmOrDelete": "長按或右鍵點擊簽名以確認或刪除。", + "next": "下一頁", + "noPdfLoaded": "尚未載入 PDF", + "nothingToSaveYet": "尚無可儲存的內容", + "openPdf": "開啟 PDF…", + "pageInfo": "第 {current}/{total} 頁", + "prev": "上一頁", + "resetToDefaults": "重設為預設值", + "savedWithPath": "已儲存:{path}", + "saveSignedPdf": "儲存已簽名 PDF", + "settings": "設定", + "signature": "簽名", + "theme": "主題", + "themeDark": "深色", + "themeLight": "淺色", + "themeSystem": "系統", + "undo": "復原" +} \ No newline at end of file diff --git a/lib/ui/features/pdf/widgets/pdf_page_area.dart b/lib/ui/features/pdf/widgets/pdf_page_area.dart index 0749905..4c0cddf 100644 --- a/lib/ui/features/pdf/widgets/pdf_page_area.dart +++ b/lib/ui/features/pdf/widgets/pdf_page_area.dart @@ -41,11 +41,11 @@ class PdfPageArea extends ConsumerWidget { globalPos.dx, globalPos.dy, ), - items: const [ + items: [ PopupMenuItem( key: Key('ctx_delete_signature'), value: 'delete', - child: Text('Delete'), + child: Text(AppLocalizations.of(context).delete), ), ], ); @@ -281,16 +281,16 @@ class PdfPageArea extends ConsumerWidget { pos.dx, pos.dy, ), - items: const [ + items: [ PopupMenuItem( key: Key('ctx_active_confirm'), value: 'confirm', - child: Text('Confirm'), + child: Text(AppLocalizations.of(context).confirm), ), PopupMenuItem( key: Key('ctx_active_delete'), value: 'delete', - child: Text('Delete'), + child: Text(AppLocalizations.of(context).delete), ), ], ).then((choice) { @@ -311,16 +311,16 @@ class PdfPageArea extends ConsumerWidget { pos.dx, pos.dy, ), - items: const [ + items: [ PopupMenuItem( key: Key('ctx_active_confirm_lp'), value: 'confirm', - child: Text('Confirm'), + child: Text(AppLocalizations.of(context).confirm), ), PopupMenuItem( key: Key('ctx_active_delete_lp'), value: 'delete', - child: Text('Delete'), + child: Text(AppLocalizations.of(context).delete), ), ], ).then((choice) { diff --git a/lib/ui/features/pdf/widgets/pdf_screen.dart b/lib/ui/features/pdf/widgets/pdf_screen.dart index 0dc027d..459a1ec 100644 --- a/lib/ui/features/pdf/widgets/pdf_screen.dart +++ b/lib/ui/features/pdf/widgets/pdf_screen.dart @@ -79,9 +79,11 @@ class _PdfSignatureHomePageState extends ConsumerState { .setSignedPage(ref.read(pdfProvider).currentPage); // Hint: how to confirm/delete via context menu ScaffoldMessenger.of(context).showSnackBar( - const SnackBar( + SnackBar( content: Text( - 'Long-press or right-click the signature to Confirm or Delete.', + AppLocalizations.of( + context, + ).longPressOrRightClickTheSignatureToConfirmOrDelete, ), duration: Duration(seconds: 3), ), diff --git a/lib/ui/features/pdf/widgets/pdf_toolbar.dart b/lib/ui/features/pdf/widgets/pdf_toolbar.dart index 2c39479..e8c420d 100644 --- a/lib/ui/features/pdf/widgets/pdf_toolbar.dart +++ b/lib/ui/features/pdf/widgets/pdf_toolbar.dart @@ -129,7 +129,7 @@ class PdfToolbar extends ConsumerWidget { OutlinedButton( key: const Key('btn_create_signature'), onPressed: disabled || !pdf.loaded ? null : onCreateSignature, - child: const Text('Create new signature'), + child: Text(l.createNewSignature), ), ElevatedButton( key: const Key('btn_draw_signature'), diff --git a/test/features/step/_tokens.dart b/test/features/step/_tokens.dart index 20daf92..d443f63 100644 --- a/test/features/step/_tokens.dart +++ b/test/features/step/_tokens.dart @@ -30,6 +30,7 @@ const system = _Token('system'); const en = _Token('en'); const es = _Token('es'); const zh = _Token('zh'); +// ignore: constant_identifier_names const TW = _Token('TW'); const theme = _Token('theme'); const language = _Token('language');