From d381908ff102b3e45cb551e1bb798ab7e40ef0a8 Mon Sep 17 00:00:00 2001 From: AlcalaJulian Date: Mon, 24 Nov 2025 12:55:20 +0100 Subject: [PATCH] added flutter icons files and intl packages --- .dart_tool/extension_discovery/vs_code.json | 2 +- .idea/modules.xml | 1 + apps/mobile_app/lib/main.dart | 10 + apps/mobile_app/pubspec.lock | 22 + apps/mobile_app/pubspec.yaml | 4 +- apps/mobile_app/pubspec_overrides.yaml | 4 +- .../src/login/presentation/login_screen.dart | 2 + modules/auth/pubspec.yaml | 2 + modules/auth/pubspec_overrides.yaml | 4 +- .../src/presentation/main_shell_screen.dart | 5 +- .../presentation/main_shell_view_model.dart | 10 +- .../dashboard_shell/pubspec_overrides.yaml | 4 +- modules/home/pubspec_overrides.yaml | 4 +- modules/notifications/pubspec_overrides.yaml | 4 +- modules/profile/pubspec_overrides.yaml | 4 +- packages/design_system/lib/design_system.dart | 1 + packages/design_system/lib/fonts/SFIcons.ttf | Bin 0 -> 15708 bytes packages/design_system/lib/fonts/config.json | 828 ++++++++++++++++++ .../design_system/lib/src/icons/sf_icons.dart | 326 +++++++ packages/design_system/pubspec.yaml | 5 +- packages/design_system/pubspec_overrides.yaml | 4 + packages/sf_localizations/.gitignore | 29 + packages/sf_localizations/.metadata | 10 + packages/sf_localizations/CHANGELOG.md | 3 + packages/sf_localizations/LICENSE | 1 + packages/sf_localizations/README.md | 39 + .../sf_localizations/analysis_options.yaml | 6 + packages/sf_localizations/assets/l10n/en.json | 3 + packages/sf_localizations/assets/l10n/es.json | 3 + .../lib/sf_localizations.dart | 5 + .../lib/src/asset_loaders/asset_loader.dart | 14 + .../root_bundle_asset_loader.dart | 18 + .../src/asset_loaders/test_asset_loader.dart | 20 + .../lib/src/generated/i18n.dart | 7 + .../sf_localizations/lib/src/sf_delegate.dart | 166 ++++ .../lib/src/utils/constants.dart | 1 + .../lib/src/utils/context_extension.dart | 11 + .../lib/src/utils/locale_extension.dart | 5 + .../lib/src/utils/string_extension.dart | 9 + packages/sf_localizations/pubspec.yaml | 28 + .../sf_localizations/pubspec_overrides.yaml | 4 + .../scripts/i18n_generator.dart | 58 ++ packages/sf_shared/pubspec_overrides.yaml | 4 +- packages/utils/lib/src/test.dart | 6 + packages/utils/lib/utils.dart | 1 + 45 files changed, 1679 insertions(+), 18 deletions(-) create mode 100755 packages/design_system/lib/fonts/SFIcons.ttf create mode 100755 packages/design_system/lib/fonts/config.json create mode 100644 packages/design_system/lib/src/icons/sf_icons.dart create mode 100644 packages/design_system/pubspec_overrides.yaml create mode 100755 packages/sf_localizations/.gitignore create mode 100755 packages/sf_localizations/.metadata create mode 100755 packages/sf_localizations/CHANGELOG.md create mode 100755 packages/sf_localizations/LICENSE create mode 100755 packages/sf_localizations/README.md create mode 100755 packages/sf_localizations/analysis_options.yaml create mode 100755 packages/sf_localizations/assets/l10n/en.json create mode 100644 packages/sf_localizations/assets/l10n/es.json create mode 100755 packages/sf_localizations/lib/sf_localizations.dart create mode 100755 packages/sf_localizations/lib/src/asset_loaders/asset_loader.dart create mode 100755 packages/sf_localizations/lib/src/asset_loaders/root_bundle_asset_loader.dart create mode 100755 packages/sf_localizations/lib/src/asset_loaders/test_asset_loader.dart create mode 100755 packages/sf_localizations/lib/src/generated/i18n.dart create mode 100755 packages/sf_localizations/lib/src/sf_delegate.dart create mode 100755 packages/sf_localizations/lib/src/utils/constants.dart create mode 100755 packages/sf_localizations/lib/src/utils/context_extension.dart create mode 100755 packages/sf_localizations/lib/src/utils/locale_extension.dart create mode 100755 packages/sf_localizations/lib/src/utils/string_extension.dart create mode 100755 packages/sf_localizations/pubspec.yaml create mode 100644 packages/sf_localizations/pubspec_overrides.yaml create mode 100755 packages/sf_localizations/scripts/i18n_generator.dart create mode 100755 packages/utils/lib/src/test.dart diff --git a/.dart_tool/extension_discovery/vs_code.json b/.dart_tool/extension_discovery/vs_code.json index 0951d9cb..ae1a36a6 100644 --- a/.dart_tool/extension_discovery/vs_code.json +++ b/.dart_tool/extension_discovery/vs_code.json @@ -1 +1 @@ -{"version":2,"entries":[{"package":"design_system","rootUri":"../packages/design_system/","packageUri":"lib/"},{"package":"sf_shared","rootUri":"../sf_shared/","packageUri":"lib/"},{"package":"sf_app_platform_mono_repo","rootUri":"../","packageUri":"lib/"},{"package":"navigation","rootUri":"../packages/navigation/","packageUri":"lib/"},{"package":"auth","rootUri":"../modules/auth/","packageUri":"lib/"},{"package":"home","rootUri":"../modules/home/","packageUri":"lib/"},{"package":"profile","rootUri":"../modules/profile/","packageUri":"lib/"},{"package":"notifications","rootUri":"../modules/notifications/","packageUri":"lib/"},{"package":"dashboard_shell","rootUri":"../modules/dashboard_shell/","packageUri":"lib/"}]} \ No newline at end of file +{"version":2,"entries":[{"package":"sf_app_platform_mono_repo","rootUri":"../","packageUri":"lib/"}]} \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml index e41ccc6e..48de06f6 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -10,6 +10,7 @@ + diff --git a/apps/mobile_app/lib/main.dart b/apps/mobile_app/lib/main.dart index 37384b82..34767767 100644 --- a/apps/mobile_app/lib/main.dart +++ b/apps/mobile_app/lib/main.dart @@ -1,8 +1,10 @@ +import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:design_system/design_system.dart'; import 'package:sf_app_platform/navigation/app_router.dart'; import 'package:navigation/navigation_module.dart'; +import 'package:sf_localizations/sf_localizations.dart'; Future main() async { WidgetsFlutterBinding.ensureInitialized(); @@ -25,6 +27,14 @@ class PlatformApp extends ConsumerWidget { ), routerConfig: appRouter, debugShowCheckedModeBanner: false, + + localizationsDelegates: const [ + SFLocalizations.delegate, + DefaultWidgetsLocalizations.delegate, + DefaultMaterialLocalizations.delegate, + DefaultCupertinoLocalizations.delegate, + ], + supportedLocales: [for (final lang in supportedLanguages) Locale(lang)], ); } } diff --git a/apps/mobile_app/pubspec.lock b/apps/mobile_app/pubspec.lock index eac07827..a261a5ba 100644 --- a/apps/mobile_app/pubspec.lock +++ b/apps/mobile_app/pubspec.lock @@ -388,6 +388,14 @@ packages: url: "https://pub.dev" source: hosted version: "4.1.2" + intl: + dependency: transitive + description: + name: intl + sha256: "3df61194eb431efc39c4ceba583b95633a403f46c9fd341e550ce0bfa50e9aa5" + url: "https://pub.dev" + source: hosted + version: "0.20.2" io: dependency: transitive description: @@ -577,6 +585,13 @@ packages: url: "https://pub.dev" source: hosted version: "3.0.3" + sf_localizations: + dependency: "direct main" + description: + path: "../../packages/sf_localizations" + relative: true + source: path + version: "0.0.1" sf_shared: dependency: "direct overridden" description: @@ -749,6 +764,13 @@ packages: url: "https://pub.dev" source: hosted version: "1.4.0" + utils: + dependency: "direct overridden" + description: + path: "../../packages/utils" + relative: true + source: path + version: "0.0.1" vector_graphics: dependency: transitive description: diff --git a/apps/mobile_app/pubspec.yaml b/apps/mobile_app/pubspec.yaml index 3568458c..f3c0076b 100644 --- a/apps/mobile_app/pubspec.yaml +++ b/apps/mobile_app/pubspec.yaml @@ -50,7 +50,9 @@ dependencies: navigation: path: ../../packages/navigation design_system: - path: ../../packages/design_system + path: ../../packages/design_system + sf_localizations: + path: ../../packages/sf_localizations #dependencies go here cupertino_icons: ^1.0.8 diff --git a/apps/mobile_app/pubspec_overrides.yaml b/apps/mobile_app/pubspec_overrides.yaml index 6d49b309..f502d091 100644 --- a/apps/mobile_app/pubspec_overrides.yaml +++ b/apps/mobile_app/pubspec_overrides.yaml @@ -1,4 +1,4 @@ -# melos_managed_dependency_overrides: auth,dashboard_shell,design_system,home,navigation,notifications,profile,sf_shared +# melos_managed_dependency_overrides: auth,dashboard_shell,design_system,home,navigation,notifications,profile,sf_shared,utils dependency_overrides: auth: path: ../../modules/auth @@ -16,3 +16,5 @@ dependency_overrides: path: ../../modules/profile sf_shared: path: ../../packages/sf_shared + utils: + path: ../../packages/utils diff --git a/modules/auth/lib/src/login/presentation/login_screen.dart b/modules/auth/lib/src/login/presentation/login_screen.dart index fd7899af..7b96312e 100644 --- a/modules/auth/lib/src/login/presentation/login_screen.dart +++ b/modules/auth/lib/src/login/presentation/login_screen.dart @@ -3,6 +3,7 @@ import 'package:auth/src/sign_up/signup_screen.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:navigation/navigation.dart'; +import 'package:sf_localizations/sf_localizations.dart'; class LoginScreen extends ConsumerWidget { final NavigationContract navigationContract; @@ -22,6 +23,7 @@ class LoginScreen extends ConsumerWidget { children: [ Icon(Icons.check, color: Color(0xFF329e95), size: 50), Text( + // context.translate(I18n.example) // example to use Intl package "¡Te damos la bienvenida!", style: TextStyle(fontSize: 30, fontWeight: FontWeight.bold), ), diff --git a/modules/auth/pubspec.yaml b/modules/auth/pubspec.yaml index e7f68094..53e47f0d 100644 --- a/modules/auth/pubspec.yaml +++ b/modules/auth/pubspec.yaml @@ -20,6 +20,8 @@ dependencies: path: ../../packages/design_system navigation: path: ../../packages/navigation + sf_localizations: + path: ../../packages/sf_localizations #dependencies go here flutter_svg: ^2.2.1 get_it: ^9.0.5 diff --git a/modules/auth/pubspec_overrides.yaml b/modules/auth/pubspec_overrides.yaml index 309fbed9..a635c017 100644 --- a/modules/auth/pubspec_overrides.yaml +++ b/modules/auth/pubspec_overrides.yaml @@ -1,4 +1,4 @@ -# melos_managed_dependency_overrides: dashboard_shell,design_system,home,notifications,profile,sf_shared,navigation +# melos_managed_dependency_overrides: dashboard_shell,design_system,home,notifications,profile,sf_shared,navigation,utils dependency_overrides: dashboard_shell: path: ../dashboard_shell @@ -14,3 +14,5 @@ dependency_overrides: path: ../profile sf_shared: path: ../../packages/sf_shared + utils: + path: ../../packages/utils diff --git a/modules/dashboard_shell/lib/src/presentation/main_shell_screen.dart b/modules/dashboard_shell/lib/src/presentation/main_shell_screen.dart index 57266179..6357823e 100644 --- a/modules/dashboard_shell/lib/src/presentation/main_shell_screen.dart +++ b/modules/dashboard_shell/lib/src/presentation/main_shell_screen.dart @@ -3,13 +3,12 @@ import 'package:dashboard_shell/src/presentation/main_shell_view_state.dart'; import 'package:design_system/design_system.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:flutter_riverpod/legacy.dart'; import 'package:go_router/go_router.dart'; import 'package:navigation/navigation.dart'; final mainShellViewModelProvider = - StateNotifierProvider.autoDispose( - (ref) => MainShellViewModel(ref: ref), + NotifierProvider.autoDispose( + () => MainShellViewModel(), ); class DashboardScreen extends ConsumerWidget { diff --git a/modules/dashboard_shell/lib/src/presentation/main_shell_view_model.dart b/modules/dashboard_shell/lib/src/presentation/main_shell_view_model.dart index 15e8fc4c..55892d01 100644 --- a/modules/dashboard_shell/lib/src/presentation/main_shell_view_model.dart +++ b/modules/dashboard_shell/lib/src/presentation/main_shell_view_model.dart @@ -1,11 +1,11 @@ import 'package:dashboard_shell/src/presentation/main_shell_view_state.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:flutter_riverpod/legacy.dart'; -class MainShellViewModel extends StateNotifier { - MainShellViewModel({required this.ref}) : super(MainShellViewState()); - - final Ref ref; +class MainShellViewModel extends Notifier { + @override + MainShellViewState build() { + return MainShellViewState(); + } void onTabChanged(int index) { state = state.copyWith(selectedIndex: index); diff --git a/modules/dashboard_shell/pubspec_overrides.yaml b/modules/dashboard_shell/pubspec_overrides.yaml index aaf27ccb..ebe1a3a3 100644 --- a/modules/dashboard_shell/pubspec_overrides.yaml +++ b/modules/dashboard_shell/pubspec_overrides.yaml @@ -1,4 +1,4 @@ -# melos_managed_dependency_overrides: auth,design_system,home,notifications,profile,sf_shared,navigation +# melos_managed_dependency_overrides: auth,design_system,home,notifications,profile,sf_shared,navigation,utils dependency_overrides: auth: path: ../auth @@ -14,3 +14,5 @@ dependency_overrides: path: ../profile sf_shared: path: ../../packages/sf_shared + utils: + path: ../../packages/utils diff --git a/modules/home/pubspec_overrides.yaml b/modules/home/pubspec_overrides.yaml index 11e140da..a583badb 100644 --- a/modules/home/pubspec_overrides.yaml +++ b/modules/home/pubspec_overrides.yaml @@ -1,4 +1,4 @@ -# melos_managed_dependency_overrides: auth,dashboard_shell,design_system,notifications,profile,sf_shared,navigation +# melos_managed_dependency_overrides: auth,dashboard_shell,design_system,notifications,profile,sf_shared,navigation,utils dependency_overrides: auth: path: ../auth @@ -14,3 +14,5 @@ dependency_overrides: path: ../profile sf_shared: path: ../../packages/sf_shared + utils: + path: ../../packages/utils diff --git a/modules/notifications/pubspec_overrides.yaml b/modules/notifications/pubspec_overrides.yaml index 35658845..780fb0f0 100644 --- a/modules/notifications/pubspec_overrides.yaml +++ b/modules/notifications/pubspec_overrides.yaml @@ -1,6 +1,8 @@ -# melos_managed_dependency_overrides: design_system,sf_shared +# melos_managed_dependency_overrides: design_system,sf_shared,utils dependency_overrides: design_system: path: ../../packages/design_system sf_shared: path: ../../packages/sf_shared + utils: + path: ../../packages/utils diff --git a/modules/profile/pubspec_overrides.yaml b/modules/profile/pubspec_overrides.yaml index de25ad5a..c0dcf19b 100644 --- a/modules/profile/pubspec_overrides.yaml +++ b/modules/profile/pubspec_overrides.yaml @@ -1,4 +1,4 @@ -# melos_managed_dependency_overrides: design_system,notifications,sf_shared +# melos_managed_dependency_overrides: design_system,notifications,sf_shared,utils dependency_overrides: design_system: path: ../../packages/design_system @@ -6,3 +6,5 @@ dependency_overrides: path: ../notifications sf_shared: path: ../../packages/sf_shared + utils: + path: ../../packages/utils diff --git a/packages/design_system/lib/design_system.dart b/packages/design_system/lib/design_system.dart index 11d0bc22..2c741c6a 100644 --- a/packages/design_system/lib/design_system.dart +++ b/packages/design_system/lib/design_system.dart @@ -1,2 +1,3 @@ export 'src/theme/theme_port.dart'; export 'src/theme/theme_sf_adapter.dart'; +export 'src/icons/sf_icons.dart'; diff --git a/packages/design_system/lib/fonts/SFIcons.ttf b/packages/design_system/lib/fonts/SFIcons.ttf new file mode 100755 index 0000000000000000000000000000000000000000..8c2c553fb7966bf6586a04bf5af6ed8163f4858a GIT binary patch literal 15708 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 TC#nmyL|WOVu{nMBHMIY~JX=1.17.0" @@ -11,6 +11,9 @@ environment: dependencies: flutter: sdk: flutter + + utils: + path: ../utils flutter_riverpod: ^3.0.3 get_it: ^9.0.5 diff --git a/packages/design_system/pubspec_overrides.yaml b/packages/design_system/pubspec_overrides.yaml new file mode 100644 index 00000000..d20fd735 --- /dev/null +++ b/packages/design_system/pubspec_overrides.yaml @@ -0,0 +1,4 @@ +# melos_managed_dependency_overrides: utils +dependency_overrides: + utils: + path: ../utils diff --git a/packages/sf_localizations/.gitignore b/packages/sf_localizations/.gitignore new file mode 100755 index 00000000..ac5aa989 --- /dev/null +++ b/packages/sf_localizations/.gitignore @@ -0,0 +1,29 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ +migrate_working_dir/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +# Libraries should not include pubspec.lock, per https://dart.dev/guides/libraries/private-files#pubspeclock. +/pubspec.lock +**/doc/api/ +.dart_tool/ +build/ diff --git a/packages/sf_localizations/.metadata b/packages/sf_localizations/.metadata new file mode 100755 index 00000000..24472f12 --- /dev/null +++ b/packages/sf_localizations/.metadata @@ -0,0 +1,10 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled and should not be manually edited. + +version: + revision: "2663184aa79047d0a33a14a3b607954f8fdd8730" + channel: "stable" + +project_type: package diff --git a/packages/sf_localizations/CHANGELOG.md b/packages/sf_localizations/CHANGELOG.md new file mode 100755 index 00000000..41cc7d81 --- /dev/null +++ b/packages/sf_localizations/CHANGELOG.md @@ -0,0 +1,3 @@ +## 0.0.1 + +* TODO: Describe initial release. diff --git a/packages/sf_localizations/LICENSE b/packages/sf_localizations/LICENSE new file mode 100755 index 00000000..ba75c69f --- /dev/null +++ b/packages/sf_localizations/LICENSE @@ -0,0 +1 @@ +TODO: Add your license here. diff --git a/packages/sf_localizations/README.md b/packages/sf_localizations/README.md new file mode 100755 index 00000000..4a260d8d --- /dev/null +++ b/packages/sf_localizations/README.md @@ -0,0 +1,39 @@ + + +TODO: Put a short description of the package here that helps potential users +know whether this package might be useful for them. + +## Features + +TODO: List what your package can do. Maybe include images, gifs, or videos. + +## Getting started + +TODO: List prerequisites and provide or point to information on how to +start using the package. + +## Usage + +TODO: Include short and useful examples for package users. Add longer examples +to `/example` folder. + +```dart +const like = 'sample'; +``` + +## Additional information + +TODO: Tell users more about the package: where to find more information, how to +contribute to the package, how to file issues, what response they can expect +from the package authors, and more. diff --git a/packages/sf_localizations/analysis_options.yaml b/packages/sf_localizations/analysis_options.yaml new file mode 100755 index 00000000..289609cf --- /dev/null +++ b/packages/sf_localizations/analysis_options.yaml @@ -0,0 +1,6 @@ +# include: package:utils/analysis_options.yaml + +# # Additional information about this file can be found at +# # https://dart.dev/guides/language/analysis-options + + diff --git a/packages/sf_localizations/assets/l10n/en.json b/packages/sf_localizations/assets/l10n/en.json new file mode 100755 index 00000000..9003e9e5 --- /dev/null +++ b/packages/sf_localizations/assets/l10n/en.json @@ -0,0 +1,3 @@ +{ + "example": "example" +} \ No newline at end of file diff --git a/packages/sf_localizations/assets/l10n/es.json b/packages/sf_localizations/assets/l10n/es.json new file mode 100644 index 00000000..09c9ad94 --- /dev/null +++ b/packages/sf_localizations/assets/l10n/es.json @@ -0,0 +1,3 @@ +{ + "example": "ejemplo" +} \ No newline at end of file diff --git a/packages/sf_localizations/lib/sf_localizations.dart b/packages/sf_localizations/lib/sf_localizations.dart new file mode 100755 index 00000000..085de989 --- /dev/null +++ b/packages/sf_localizations/lib/sf_localizations.dart @@ -0,0 +1,5 @@ +export 'src/sf_delegate.dart'; +export 'src/generated/i18n.dart'; +export 'src/utils/constants.dart'; +export 'src/utils/context_extension.dart'; +export 'src/utils/string_extension.dart'; diff --git a/packages/sf_localizations/lib/src/asset_loaders/asset_loader.dart b/packages/sf_localizations/lib/src/asset_loaders/asset_loader.dart new file mode 100755 index 00000000..1054529c --- /dev/null +++ b/packages/sf_localizations/lib/src/asset_loaders/asset_loader.dart @@ -0,0 +1,14 @@ +import 'dart:ui'; + +import 'package:flutter/foundation.dart'; +import '../utils/locale_extension.dart'; + +abstract class AssetLoader { + const AssetLoader(); + + Future> load(Locale locale); + + @protected + String getAssetPath(Locale locale) => + 'packages/sf_localizations/assets/l10n/${locale.fileName}.json'; +} diff --git a/packages/sf_localizations/lib/src/asset_loaders/root_bundle_asset_loader.dart b/packages/sf_localizations/lib/src/asset_loaders/root_bundle_asset_loader.dart new file mode 100755 index 00000000..5860de69 --- /dev/null +++ b/packages/sf_localizations/lib/src/asset_loaders/root_bundle_asset_loader.dart @@ -0,0 +1,18 @@ +import 'dart:convert'; +import 'dart:ui'; + +import 'package:flutter/services.dart'; +import 'asset_loader.dart'; + +class RootBundleAssetLoader extends AssetLoader { + const RootBundleAssetLoader(); + + @override + Future> load(Locale locale) async { + final assetAsString = await rootBundle.loadString(getAssetPath(locale)); + + final translations = jsonDecode(assetAsString) as Map; + + return translations; + } +} diff --git a/packages/sf_localizations/lib/src/asset_loaders/test_asset_loader.dart b/packages/sf_localizations/lib/src/asset_loaders/test_asset_loader.dart new file mode 100755 index 00000000..f61329cd --- /dev/null +++ b/packages/sf_localizations/lib/src/asset_loaders/test_asset_loader.dart @@ -0,0 +1,20 @@ +import 'dart:convert'; +import 'dart:ui'; + +import 'package:flutter/services.dart'; +import 'asset_loader.dart'; + +class TestAssetLoader extends AssetLoader { + const TestAssetLoader(); + + @override + Future> load(Locale locale) async { + final data = await rootBundle.load(getAssetPath(locale)); + final bytes = + data.buffer.asUint8List(data.offsetInBytes, data.lengthInBytes); + + final strings = utf8.decode(bytes); + + return json.decode(strings) as Map; + } +} diff --git a/packages/sf_localizations/lib/src/generated/i18n.dart b/packages/sf_localizations/lib/src/generated/i18n.dart new file mode 100755 index 00000000..5afd221a --- /dev/null +++ b/packages/sf_localizations/lib/src/generated/i18n.dart @@ -0,0 +1,7 @@ +// Generated code - do not modify by hand + +class I18n { + const I18n._(); + + static const String example = 'example'; +} diff --git a/packages/sf_localizations/lib/src/sf_delegate.dart b/packages/sf_localizations/lib/src/sf_delegate.dart new file mode 100755 index 00000000..893f4ca3 --- /dev/null +++ b/packages/sf_localizations/lib/src/sf_delegate.dart @@ -0,0 +1,166 @@ +import 'dart:async'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/widgets.dart'; +import 'package:intl/intl.dart'; +import 'package:sf_localizations/sf_localizations.dart'; +import 'package:sf_localizations/src/asset_loaders/root_bundle_asset_loader.dart'; +import 'package:sf_localizations/src/asset_loaders/test_asset_loader.dart'; +import 'asset_loaders/asset_loader.dart'; +import 'package:utils/utils.dart'; + +class SFLocalizations { + SFLocalizations._init(this._locale) { + _instance = this; + } + + @visibleForTesting + SFLocalizations.testInit() : _locale = const Locale('es') { + _instance = this; + } + + static SFLocalizations? _instance; + final _translationCache = {}; + final Locale _locale; + + Locale get locale => _locale; + + // Static getter for accessing translations without context + static SFLocalizations get current { + if (_instance == null) { + throw Exception('$SFLocalizations not initialized yet'); + } + + return _instance!; + } + + Future load(AssetLoader assetLoader) async { + _translationCache.clear(); + try { + final translations = await assetLoader.load(_locale); + _translationCache.addAll(translations); + } catch (e) { + if (kDebugMode) print('Error loading locale $_locale: $e'); + } + } + + String tr(String key, [Map? args]) => _resolve(key, args); + + String plural(String key, [Map? args, int? howMany]) => + _resolvePlural(key, args, howMany); + + static SFLocalizations of(BuildContext context) { + final translator = Localizations.of( + context, + SFLocalizations, + ); + + if (translator == null) { + throw Exception('$SFLocalizations not in the context'); + } + + return translator; + } + + // Add support for more languages by adding their respective message files + static const LocalizationsDelegate delegate = + _SFLocalizationsDelegate(); + + String _resolve(String key, [Map? args]) { + if (!_translationCache.containsKey(key)) { + return key; + } + + final translationValue = _translationCache[key] as String; + + return _format(translationValue, args); + } + + String _resolvePlural( + String key, [ + Map? args, + int? howMany, + ]) { + if (!_translationCache.containsKey(key)) { + return key; + } + + final translationValue = _translationCache[key]!; + + if (translationValue is! Map) { + return key; + } + + if (!translationValue.containsKey('other')) { + return key; + } + + if (howMany == null) { + return _format(translationValue['other'] as String, args); + } + + return _format( + Intl.withLocale( + _locale.languageCode, + () => Intl.plural( + howMany, + zero: _getPluralValue(translationValue, 'zero'), + one: _getPluralValue(translationValue, 'one'), + two: _getPluralValue(translationValue, 'two'), + few: _getPluralValue(translationValue, 'few'), + many: _getPluralValue(translationValue, 'many'), + other: translationValue['other'] as String, + ), + ) + as String, + args, + ); + } + + String _getPluralValue(Map translationValue, String key) { + if (translationValue[key] != null && + (translationValue[key] as String).isEmpty) { + return translationValue['other'] as String; + } + return translationValue[key] as String; + } + + String _format(String value, [Map? args]) { + return (args?.isNotEmpty ?? false) ? _sprintf(value, args!) : value; + } + + String _sprintf(String format, Map values) { + return format.replaceAllMapped(RegExp(r'\{(\w+)\}'), (match) { + final key = match.group(1)!; + if (!values.containsKey(key)) { + throw ArgumentError('Missing value for placeholder {$key}'); + } + return values[key].toString(); + }); + } +} + +class _SFLocalizationsDelegate extends LocalizationsDelegate { + const _SFLocalizationsDelegate(); + + static const _assetLoader = isTest + ? TestAssetLoader() + : RootBundleAssetLoader(); + + @override + bool isSupported(Locale locale) { + return supportedLanguages.contains(locale.languageCode); + } + + @override + Future load(Locale locale) async { + final localizations = SFLocalizations._init(locale); + + await localizations.load(_assetLoader); + + return localizations; + } + + @override + bool shouldReload(_SFLocalizationsDelegate old) => false; +} diff --git a/packages/sf_localizations/lib/src/utils/constants.dart b/packages/sf_localizations/lib/src/utils/constants.dart new file mode 100755 index 00000000..bcb65057 --- /dev/null +++ b/packages/sf_localizations/lib/src/utils/constants.dart @@ -0,0 +1 @@ +const supportedLanguages = ['en', 'es']; diff --git a/packages/sf_localizations/lib/src/utils/context_extension.dart b/packages/sf_localizations/lib/src/utils/context_extension.dart new file mode 100755 index 00000000..d753ddb7 --- /dev/null +++ b/packages/sf_localizations/lib/src/utils/context_extension.dart @@ -0,0 +1,11 @@ +import 'package:flutter/widgets.dart'; +import '../sf_delegate.dart'; + +extension LocalizationContextExtension on BuildContext { + Locale get locale => translator.locale; + + String translate(String key, {Map? args}) => + translator.tr(key, args); + + SFLocalizations get translator => SFLocalizations.of(this); +} diff --git a/packages/sf_localizations/lib/src/utils/locale_extension.dart b/packages/sf_localizations/lib/src/utils/locale_extension.dart new file mode 100755 index 00000000..8732ebae --- /dev/null +++ b/packages/sf_localizations/lib/src/utils/locale_extension.dart @@ -0,0 +1,5 @@ +import 'dart:ui' show Locale; + +extension ExpandLocale on Locale { + String get fileName => countryCode != null ? '$languageCode-$countryCode' : languageCode; +} diff --git a/packages/sf_localizations/lib/src/utils/string_extension.dart b/packages/sf_localizations/lib/src/utils/string_extension.dart new file mode 100755 index 00000000..e758684b --- /dev/null +++ b/packages/sf_localizations/lib/src/utils/string_extension.dart @@ -0,0 +1,9 @@ +import 'package:flutter/cupertino.dart'; +import '../sf_delegate.dart'; + +extension StringLocalizationExtension on String { + String tr({BuildContext? context, Map? args}) => + context != null + ? SFLocalizations.of(context).tr(this, args) + : SFLocalizations.current.tr(this, args); +} diff --git a/packages/sf_localizations/pubspec.yaml b/packages/sf_localizations/pubspec.yaml new file mode 100755 index 00000000..53ec7a80 --- /dev/null +++ b/packages/sf_localizations/pubspec.yaml @@ -0,0 +1,28 @@ +name: sf_localizations +description: "A new Flutter package project." +version: 0.0.1 +homepage: none +publish_to: none + +environment: + sdk: ^3.8.0 + flutter: ">=1.17.0" +# resolution: workspace + +dependencies: + flutter: + sdk: flutter + intl: ^0.20.2 + utils: + path: ../utils + build_runner: ^2.7.1 + +dev_dependencies: + flutter_test: + sdk: flutter + + +flutter: + assets: + - assets/l10n/ + diff --git a/packages/sf_localizations/pubspec_overrides.yaml b/packages/sf_localizations/pubspec_overrides.yaml new file mode 100644 index 00000000..d20fd735 --- /dev/null +++ b/packages/sf_localizations/pubspec_overrides.yaml @@ -0,0 +1,4 @@ +# melos_managed_dependency_overrides: utils +dependency_overrides: + utils: + path: ../utils diff --git a/packages/sf_localizations/scripts/i18n_generator.dart b/packages/sf_localizations/scripts/i18n_generator.dart new file mode 100755 index 00000000..5577da7a --- /dev/null +++ b/packages/sf_localizations/scripts/i18n_generator.dart @@ -0,0 +1,58 @@ +// ignore_for_file: avoid_print + +import 'dart:convert'; +import 'dart:io'; + +const inputPath = 'assets/l10n/en.json'; +const outputPath = 'lib/src/generated/i18n.dart'; + +void main() { + try { + generateI18n(); + } catch (e) { + print('Error generating I18n: $e'); + exit(1); + } +} + +void generateI18n() { + // Ensure input file exists + final inputFile = File(inputPath); + if (!inputFile.existsSync()) { + throw 'Input file not found: $inputPath'; + } + + // Create output directory if it doesn't exist + final outputDir = Directory(outputPath.substring(0, outputPath.lastIndexOf('/'))); + if (!outputDir.existsSync()) { + outputDir.createSync(recursive: true); + } + + // Read and parse JSON + final jsonString = inputFile.readAsStringSync(); + final jsonMap = json.decode(jsonString) as Map; + + // Generate Dart class + final buffer = StringBuffer(); + buffer.writeln('// Generated code - do not modify by hand'); + buffer.writeln(); + buffer.writeln('class I18n {'); + buffer.writeln(' const I18n._();'); + buffer.writeln(); + + // Process JSON and write parent keys + final parentKeys = jsonMap.keys.toList()..sort(); + for (final key in parentKeys) { + final keyName = key[0].toLowerCase() + key.substring(1); + + buffer.writeln(" static const String $keyName = '$key';"); + } + + buffer.writeln('}'); + + // Write to output file + final outputFile = File(outputPath); + outputFile.writeAsStringSync(buffer.toString()); + + print('Successfully generated I18n class at: $outputPath'); +} diff --git a/packages/sf_shared/pubspec_overrides.yaml b/packages/sf_shared/pubspec_overrides.yaml index 600b5d8d..5db6d664 100644 --- a/packages/sf_shared/pubspec_overrides.yaml +++ b/packages/sf_shared/pubspec_overrides.yaml @@ -1,4 +1,6 @@ -# melos_managed_dependency_overrides: design_system +# melos_managed_dependency_overrides: design_system,utils dependency_overrides: design_system: path: ../design_system + utils: + path: ../utils diff --git a/packages/utils/lib/src/test.dart b/packages/utils/lib/src/test.dart new file mode 100755 index 00000000..efbdbdea --- /dev/null +++ b/packages/utils/lib/src/test.dart @@ -0,0 +1,6 @@ +import 'package:flutter/foundation.dart'; + +const isTest = + !kIsWeb && + !kProfileMode && + bool.fromEnvironment('FLUTTER_TEST', defaultValue: false); diff --git a/packages/utils/lib/utils.dart b/packages/utils/lib/utils.dart index f3c74936..528c3a6c 100644 --- a/packages/utils/lib/utils.dart +++ b/packages/utils/lib/utils.dart @@ -1 +1,2 @@ export 'src/size_utils.dart'; +export 'src/test.dart';