From 77a647d17daeeb8377d6f5bbfdeec5c6ad09ff7a Mon Sep 17 00:00:00 2001 From: marco Date: Wed, 21 Jan 2026 13:50:24 +0100 Subject: [PATCH] [fix] Added basic locatlization --- l10n.yaml | 3 + lib/l10n/app_de.arb | 16 +++ lib/l10n/app_en.arb | 16 +++ lib/l10n/app_localizations.dart | 170 +++++++++++++++++++++++++++ lib/l10n/app_localizations_de.dart | 30 +++++ lib/l10n/app_localizations_en.dart | 31 +++++ lib/main.dart | 9 ++ lib/pages/collection_page.dart | 7 +- lib/pages/collections_list_page.dart | 11 +- lib/pages/search_page.dart | 3 +- pubspec.lock | 13 ++ pubspec.yaml | 7 +- 12 files changed, 307 insertions(+), 9 deletions(-) create mode 100644 l10n.yaml create mode 100644 lib/l10n/app_de.arb create mode 100644 lib/l10n/app_en.arb create mode 100644 lib/l10n/app_localizations.dart create mode 100644 lib/l10n/app_localizations_de.dart create mode 100644 lib/l10n/app_localizations_en.dart diff --git a/l10n.yaml b/l10n.yaml new file mode 100644 index 0000000..15338f2 --- /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 diff --git a/lib/l10n/app_de.arb b/lib/l10n/app_de.arb new file mode 100644 index 0000000..3cae173 --- /dev/null +++ b/lib/l10n/app_de.arb @@ -0,0 +1,16 @@ +{ + "@@locale": "de", + "addToCollection": "Speichern in {collection_name}", + "@addToCollection": { + "placeholders": { + "collection_name" : { + "type": "String" + } + } + }, + "cancel": "Abbrechen", + "chooseCollection": "Sammlung auswählen", + "collections": "Sammlungen", + "tipCreateCollections": "Erstelle deine erste Sammlung!", + "search": "Suche" +} \ No newline at end of file diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb new file mode 100644 index 0000000..d5694f7 --- /dev/null +++ b/lib/l10n/app_en.arb @@ -0,0 +1,16 @@ +{ + "@@locale": "en", + "addToCollection": "Add to {collection_name}", + "@addToCollection": { + "placeholders": { + "collection_name" : { + "type": "String" + } + } + }, + "cancel": "Cancel", + "chooseCollection": "Choose Collection", + "collections": "Collections", + "tipCreateCollections": "Create your first Collection to get started!", + "search": "Search" +} \ No newline at end of file diff --git a/lib/l10n/app_localizations.dart b/lib/l10n/app_localizations.dart new file mode 100644 index 0000000..bd46a86 --- /dev/null +++ b/lib/l10n/app_localizations.dart @@ -0,0 +1,170 @@ +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_de.dart'; +import 'app_localizations_en.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('de'), + Locale('en'), + ]; + + /// No description provided for @addToCollection. + /// + /// In en, this message translates to: + /// **'Add to {collection_name}'** + String addToCollection(String collection_name); + + /// No description provided for @cancel. + /// + /// In en, this message translates to: + /// **'Cancel'** + String get cancel; + + /// No description provided for @chooseCollection. + /// + /// In en, this message translates to: + /// **'Choose Collection'** + String get chooseCollection; + + /// No description provided for @collections. + /// + /// In en, this message translates to: + /// **'Collections'** + String get collections; + + /// No description provided for @tipCreateCollections. + /// + /// In en, this message translates to: + /// **'Create your first Collection to get started!'** + String get tipCreateCollections; + + /// No description provided for @search. + /// + /// In en, this message translates to: + /// **'Search'** + String get search; +} + +class _AppLocalizationsDelegate + extends LocalizationsDelegate { + const _AppLocalizationsDelegate(); + + @override + Future load(Locale locale) { + return SynchronousFuture(lookupAppLocalizations(locale)); + } + + @override + bool isSupported(Locale locale) => + ['de', 'en'].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 'de': + return AppLocalizationsDe(); + case 'en': + return AppLocalizationsEn(); + } + + 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_de.dart b/lib/l10n/app_localizations_de.dart new file mode 100644 index 0000000..1148525 --- /dev/null +++ b/lib/l10n/app_localizations_de.dart @@ -0,0 +1,30 @@ +// ignore: unused_import +import 'package:intl/intl.dart' as intl; +import 'app_localizations.dart'; + +// ignore_for_file: type=lint + +/// The translations for German (`de`). +class AppLocalizationsDe extends AppLocalizations { + AppLocalizationsDe([String locale = 'de']) : super(locale); + + @override + String addToCollection(String collection_name) { + return 'Speichern in $collection_name'; + } + + @override + String get cancel => 'Abbrechen'; + + @override + String get chooseCollection => 'Sammlung auswählen'; + + @override + String get collections => 'Sammlungen'; + + @override + String get tipCreateCollections => 'Erstelle deine erste Sammlung!'; + + @override + String get search => 'Suche'; +} diff --git a/lib/l10n/app_localizations_en.dart b/lib/l10n/app_localizations_en.dart new file mode 100644 index 0000000..b3318c8 --- /dev/null +++ b/lib/l10n/app_localizations_en.dart @@ -0,0 +1,31 @@ +// 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 addToCollection(String collection_name) { + return 'Add to $collection_name'; + } + + @override + String get cancel => 'Cancel'; + + @override + String get chooseCollection => 'Choose Collection'; + + @override + String get collections => 'Collections'; + + @override + String get tipCreateCollections => + 'Create your first Collection to get started!'; + + @override + String get search => 'Search'; +} diff --git a/lib/main.dart b/lib/main.dart index 75858ce..d09aad1 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,5 +1,7 @@ import 'package:flutter/material.dart'; +import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:provider/provider.dart'; +import 'l10n/app_localizations.dart'; import 'pages/collection_page.dart'; import 'pages/collections_list_page.dart'; import 'pages/search_page.dart'; @@ -66,6 +68,13 @@ class _MapsBookmarksState extends State @override Widget build(BuildContext context) { return MaterialApp( + localizationsDelegates: [ + AppLocalizations.delegate, + GlobalMaterialLocalizations.delegate, + GlobalWidgetsLocalizations.delegate, + GlobalCupertinoLocalizations.delegate, + ], + supportedLocales: [Locale('en'), Locale('de')], navigatorKey: _navigatorKey, theme: lightTheme, darkTheme: darkTheme, diff --git a/lib/pages/collection_page.dart b/lib/pages/collection_page.dart index cf8432a..5a0b66c 100644 --- a/lib/pages/collection_page.dart +++ b/lib/pages/collection_page.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; +import '../l10n/app_localizations.dart'; import '../model/bookmark.dart'; import '../model/maps_link_metadata.dart'; import '../service/bookmarks_provider.dart'; @@ -89,13 +90,15 @@ class _CollectionPageState extends State { return Scaffold( appBar: AppBar( title: selectedMapsLink != null - ? Text('Add to ${collection.name}') + ? Text( + AppLocalizations.of(context)!.addToCollection(collection.name), + ) : Text(collection.name), actions: [ if (selectedMapsLink != null) TextButton( onPressed: () => provider.removeCurrentMapsLink(), - child: Text('Cancel'), + child: Text(AppLocalizations.of(context)!.cancel), ), ], ), diff --git a/lib/pages/collections_list_page.dart b/lib/pages/collections_list_page.dart index 10d731e..7834f16 100644 --- a/lib/pages/collections_list_page.dart +++ b/lib/pages/collections_list_page.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; +import '../l10n/app_localizations.dart'; import '../model/collection.dart'; import '../service/bookmarks_provider.dart'; import '../service/shared_link_provider.dart'; @@ -88,13 +89,13 @@ class _CollectionsListPageState extends State { return Scaffold( appBar: AppBar( title: addingNewBookmark - ? Text('Choose Collection') - : Text('Collections'), + ? Text(AppLocalizations.of(context)!.chooseCollection) + : Text(AppLocalizations.of(context)!.collections), actions: [ if (addingNewBookmark) TextButton( onPressed: () => provider.removeCurrentMapsLink(), - child: Text('Cancel'), + child: Text(AppLocalizations.of(context)!.cancel), ) else IconButton( @@ -116,7 +117,9 @@ class _CollectionsListPageState extends State { ), itemCount: collections.length, ) - : Center(child: Text('Create your first Collection to get started!')), + : Center( + child: Text(AppLocalizations.of(context)!.tipCreateCollections), + ), ); } } diff --git a/lib/pages/search_page.dart b/lib/pages/search_page.dart index 10eda73..d77ac66 100644 --- a/lib/pages/search_page.dart +++ b/lib/pages/search_page.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; +import '../l10n/app_localizations.dart'; import '../service/search_provider.dart'; import '../widgets/search_widgets/search_bar_widget.dart'; import '../widgets/search_widgets/search_results_widget.dart'; @@ -12,7 +13,7 @@ class SearchPage extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( - appBar: AppBar(title: Text('Search')), + appBar: AppBar(title: Text(AppLocalizations.of(context)!.search)), body: Column( children: [ SearchBarWidget( diff --git a/pubspec.lock b/pubspec.lock index 2931415..a69ba4a 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -102,6 +102,11 @@ packages: url: "https://pub.dev" source: hosted version: "6.0.0" + flutter_localizations: + dependency: "direct main" + description: flutter + source: sdk + version: "0.0.0" flutter_test: dependency: "direct dev" description: flutter @@ -136,6 +141,14 @@ packages: url: "https://pub.dev" source: hosted version: "4.1.2" + intl: + dependency: "direct main" + description: + name: intl + sha256: "3df61194eb431efc39c4ceba583b95633a403f46c9fd341e550ce0bfa50e9aa5" + url: "https://pub.dev" + source: hosted + version: "0.20.2" leak_tracker: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index db8ca29..fd4ae02 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -3,7 +3,7 @@ description: "A new way to save google maps bookmarks" publish_to: 'none' -version: 0.0.0 +version: 0.0.18 environment: sdk: ^3.9.2 @@ -18,6 +18,9 @@ dependencies: provider: ^6.1.5+1 metadata_fetch: ^0.4.2 url_launcher: ^6.3.2 + flutter_localizations: + sdk: flutter + intl: any dev_dependencies: flutter_test: @@ -26,5 +29,5 @@ dev_dependencies: flutter_lints: ^6.0.0 flutter: - + generate: true uses-material-design: true \ No newline at end of file