diff --git a/packages/clima_ui/l10n.yaml b/packages/clima_ui/l10n.yaml new file mode 100644 index 00000000..15338f2d --- /dev/null +++ b/packages/clima_ui/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/packages/clima_ui/lib/l10n/app_en.arb b/packages/clima_ui/lib/l10n/app_en.arb new file mode 100644 index 00000000..d39fd30f --- /dev/null +++ b/packages/clima_ui/lib/l10n/app_en.arb @@ -0,0 +1,43 @@ +{ + "aboutClima": "About Clima", + + "information": "Information", + + "changelog": "Changelog", + + "donate": "Donate", + + "donateTileSubtitle": "Support the development of Clima", + + "libraries": "Libraries", + "librariesTileSubtitle": "Open-source libraries used in the app", + + "feedback": "Feedback", + "feedbackTileSubtitle": "Bugs and feature requests", + + "submitIssue": "Submit issue", + + "contactDeveloper": "Contact developer", + + "sourceCode": "Source code", + "sourceCodeTileSubtitle": "Clima is free software licensed under the MPL 2.0", + + "settings": "Settings", + + "interface": "Interface", + + "theme": "Theme", + "light": "Light", + "dark": "Dark", + + "darkTheme": "Dark theme", + "defaultTheme": "Default", + "black": "Black", + + "about": "About", + + "windSpeedLowercase": "wind speed", + "sunriseLowercase": "sunrise", + "sunsetLowercase": "sunset", + "humidityLowercase": "humdity" +} diff --git a/packages/clima_ui/lib/main.dart b/packages/clima_ui/lib/main.dart index 9f881127..44511824 100644 --- a/packages/clima_ui/lib/main.dart +++ b/packages/clima_ui/lib/main.dart @@ -21,6 +21,7 @@ import 'package:clima_ui/themes/black_theme.dart'; import 'package:clima_ui/themes/dark_theme.dart'; import 'package:clima_ui/themes/light_theme.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:shared_preferences/shared_preferences.dart'; @@ -91,6 +92,8 @@ class _App extends HookConsumerWidget { builder: (context, orientation, screenType) { return MaterialApp( locale: getLocale?.call(context), + localizationsDelegates: AppLocalizations.localizationsDelegates, + supportedLocales: AppLocalizations.supportedLocales, builder: (context, child) { final ClimaThemeData climaTheme; diff --git a/packages/clima_ui/lib/screens/about_screen.dart b/packages/clima_ui/lib/screens/about_screen.dart index 2729112d..f4159de7 100644 --- a/packages/clima_ui/lib/screens/about_screen.dart +++ b/packages/clima_ui/lib/screens/about_screen.dart @@ -11,6 +11,7 @@ import 'package:clima_ui/widgets/settings/settings_divider.dart'; import 'package:clima_ui/widgets/settings/settings_header.dart'; import 'package:clima_ui/widgets/settings/settings_tile.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:package_info_plus/package_info_plus.dart'; import 'package:url_launcher/url_launcher.dart'; @@ -18,11 +19,13 @@ import 'package:url_launcher/url_launcher.dart'; class AboutScreen extends StatelessWidget { @override Widget build(BuildContext context) { + final appLocalizations = AppLocalizations.of(context)!; + return Scaffold( resizeToAvoidBottomInset: false, appBar: AppBar( title: Text( - 'About Clima', + appLocalizations.aboutClima, style: TextStyle( color: Theme.of(context).appBarTheme.titleTextStyle!.color, fontSize: Theme.of(context).textTheme.headline6!.fontSize, @@ -39,11 +42,11 @@ class AboutScreen extends StatelessWidget { child: Column( mainAxisSize: MainAxisSize.min, children: [ - const SettingsHeader( - title: 'Information', + SettingsHeader( + title: appLocalizations.information, ), SettingsTile( - title: 'Changelog', + title: appLocalizations.changelog, subtitle: 'Version 2.0.1', leading: Icon( Icons.new_releases_outlined, @@ -59,8 +62,8 @@ class AboutScreen extends StatelessWidget { // Example: https://github.com/streetcomplete/StreetComplete/issues/3768 if (buildFlavor != BuildFlavor.googlePlay) SettingsTile( - title: 'Donate', - subtitle: 'Support the development of Clima', + title: appLocalizations.donate, + subtitle: appLocalizations.donateTileSubtitle, leading: Icon( Icons.local_library_outlined, color: Theme.of(context).iconTheme.color, @@ -70,8 +73,8 @@ class AboutScreen extends StatelessWidget { ), ), SettingsTile( - title: 'Libraries', - subtitle: 'Open-source libraries used in the app', + title: appLocalizations.libraries, + subtitle: appLocalizations.librariesTileSubtitle, leading: Icon( Icons.source_outlined, color: Theme.of(context).iconTheme.color, @@ -87,8 +90,8 @@ class AboutScreen extends StatelessWidget { }, ), SettingsTile( - title: 'Feedback', - subtitle: 'Bugs and feature requests', + title: appLocalizations.feedback, + subtitle: appLocalizations.feedbackTileSubtitle, leading: Icon( Icons.help_outline, color: Theme.of(context).iconTheme.color, @@ -101,8 +104,8 @@ class AboutScreen extends StatelessWidget { }, ), SettingsTile( - title: 'Source code', - subtitle: 'Clima is free software licensed under the MPL 2.0', + title: appLocalizations.sourceCode, + subtitle: appLocalizations.sourceCodeTileSubtitle, isThreeLine: true, leading: FaIcon( FontAwesomeIcons.github, diff --git a/packages/clima_ui/lib/screens/settings_screen.dart b/packages/clima_ui/lib/screens/settings_screen.dart index 2ba09be8..682ae481 100644 --- a/packages/clima_ui/lib/screens/settings_screen.dart +++ b/packages/clima_ui/lib/screens/settings_screen.dart @@ -22,11 +22,13 @@ import 'package:clima_ui/widgets/settings/settings_divider.dart'; import 'package:clima_ui/widgets/settings/settings_header.dart'; import 'package:clima_ui/widgets/settings/settings_tile.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; class SettingScreen extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { + final appLocalizations = AppLocalizations.of(context)!; final theme = ref.watch(themeStateNotifierProvider.select((state) => state.theme)); final darkTheme = ref.watch( @@ -49,7 +51,7 @@ class SettingScreen extends ConsumerWidget { }, ), title: Text( - 'Settings', + appLocalizations.settings, style: TextStyle( color: Theme.of(context).appBarTheme.titleTextStyle!.color, fontSize: Theme.of(context).textTheme.headline6!.fontSize, @@ -84,18 +86,18 @@ class SettingScreen extends ConsumerWidget { ), ), const SettingsDivider(), - const SettingsHeader( - title: 'Interface', + SettingsHeader( + title: appLocalizations.interface, ), SettingsTile( - title: 'Theme', + title: appLocalizations.theme, subtitle: () { switch (theme) { case ThemeModel.light: - return 'Light'; + return appLocalizations.light; case ThemeModel.dark: - return 'Dark'; + return appLocalizations.dark; case ThemeModel.systemDefault: return 'System default'; @@ -111,14 +113,14 @@ class SettingScreen extends ConsumerWidget { ), ), SettingsTile( - title: 'Dark theme', + title: appLocalizations.darkTheme, subtitle: () { switch (darkTheme) { case DarkThemeModel.darkGrey: - return 'Default'; + return appLocalizations.defaultTheme; case DarkThemeModel.black: - return 'Black'; + return appLocalizations.black; default: throw Error(); @@ -175,11 +177,11 @@ class SettingScreen extends ConsumerWidget { }, ), const SettingsDivider(), - const SettingsHeader( - title: 'About', + SettingsHeader( + title: appLocalizations.about, ), SettingsTile( - title: 'About Clima', + title: appLocalizations.aboutClima, leading: Icon( Icons.info_outline, color: Theme.of(context).iconTheme.color, diff --git a/packages/clima_ui/lib/widgets/dialogs/dark_theme_dialog.dart b/packages/clima_ui/lib/widgets/dialogs/dark_theme_dialog.dart index ecaf130e..fab8b319 100644 --- a/packages/clima_ui/lib/widgets/dialogs/dark_theme_dialog.dart +++ b/packages/clima_ui/lib/widgets/dialogs/dark_theme_dialog.dart @@ -7,7 +7,9 @@ import 'package:clima_data/models/dark_theme_model.dart'; import 'package:clima_ui/state_notifiers/theme_state_notifier.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:hooks_riverpod/hooks_riverpod.dart'; class DarkThemeDialog extends ConsumerWidget { static const _dialogOptions = { @@ -22,6 +24,8 @@ class DarkThemeDialog extends ConsumerWidget { themeStateNotifierProvider.select((state) => state.darkTheme), ); + final localizations = AppLocalizations.of(context)!; + final radios = [ for (final entry in _dialogOptions.entries) RadioListTile( @@ -42,7 +46,7 @@ class DarkThemeDialog extends ConsumerWidget { return SimpleDialog( title: Text( - 'Dark theme', + localizations.darkTheme, style: TextStyle( color: Theme.of(context).textTheme.subtitle1!.color, ), diff --git a/packages/clima_ui/lib/widgets/dialogs/theme_dialog.dart b/packages/clima_ui/lib/widgets/dialogs/theme_dialog.dart index e5b848a0..54016fbb 100644 --- a/packages/clima_ui/lib/widgets/dialogs/theme_dialog.dart +++ b/packages/clima_ui/lib/widgets/dialogs/theme_dialog.dart @@ -7,6 +7,7 @@ import 'package:clima_data/models/theme_model.dart'; import 'package:clima_ui/state_notifiers/theme_state_notifier.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; class ThemeDialog extends ConsumerWidget { @@ -22,6 +23,8 @@ class ThemeDialog extends ConsumerWidget { final theme = ref.watch(themeStateNotifierProvider.select((state) => state.theme)); + final localizations = AppLocalizations.of(context)!; + final radios = [ for (final entry in _dialogOptions.entries) RadioListTile( @@ -42,7 +45,7 @@ class ThemeDialog extends ConsumerWidget { return SimpleDialog( title: Text( - 'Theme', + localizations.theme, style: TextStyle( color: Theme.of(context).textTheme.subtitle1!.color, ), diff --git a/packages/clima_ui/pubspec.lock b/packages/clima_ui/pubspec.lock index 1eba9a12..1f34e32e 100644 --- a/packages/clima_ui/pubspec.lock +++ b/packages/clima_ui/pubspec.lock @@ -161,7 +161,7 @@ packages: source: hosted version: "0.18.4" flutter_localizations: - dependency: transitive + dependency: "direct main" description: flutter source: sdk version: "0.0.0" diff --git a/packages/clima_ui/pubspec.yaml b/packages/clima_ui/pubspec.yaml index 0cebb004..299b0ca1 100644 --- a/packages/clima_ui/pubspec.yaml +++ b/packages/clima_ui/pubspec.yaml @@ -12,6 +12,9 @@ dependencies: flutter: sdk: flutter + flutter_localizations: + sdk: flutter + clima_core: path: ../clima_core clima_domain: @@ -46,3 +49,4 @@ flutter: assets: - assets/ uses-material-design: true + generate: true