add i18n package #164
							
								
								
									
										40
									
								
								packages/wyatt_i18n/lib/src/core/utils/assets_utils.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								packages/wyatt_i18n/lib/src/core/utils/assets_utils.dart
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,40 @@
 | 
				
			|||||||
 | 
					// Copyright (C) 2023 WYATT GROUP
 | 
				
			||||||
 | 
					// Please see the AUTHORS file for details.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// This program is free software: you can redistribute it and/or modify
 | 
				
			||||||
 | 
					// it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 | 
					// the Free Software Foundation, either version 3 of the License, or
 | 
				
			||||||
 | 
					// any later version.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// This program is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					// but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 | 
				
			||||||
 | 
					// GNU General Public License for more details.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// You should have received a copy of the GNU General Public License
 | 
				
			||||||
 | 
					// along with this program. If not, see <https://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import 'dart:convert';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import 'package:flutter/services.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class AssetsUtils {
 | 
				
			||||||
 | 
					  /// Checks if the given [assetPath] is a local asset.
 | 
				
			||||||
 | 
					  ///
 | 
				
			||||||
 | 
					  /// In fact, this method loads the asset and checks if it is null.
 | 
				
			||||||
 | 
					  static Future<bool> assetExists(String assetPath) async {
 | 
				
			||||||
 | 
					    final encoded = utf8.encoder.convert(
 | 
				
			||||||
 | 
					      Uri(path: Uri.encodeFull(assetPath)).path,
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					    final asset = await ServicesBinding.instance.defaultBinaryMessenger
 | 
				
			||||||
 | 
					        .send('flutter/assets', encoded.buffer.asByteData());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return asset != null;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Cleans the given [path] by removing all the consecutive slashes.
 | 
				
			||||||
 | 
					  /// For example, `///a///b///c///` becomes `/a/b/c/`.
 | 
				
			||||||
 | 
					  /// It also removes the first slash if it exists.
 | 
				
			||||||
 | 
					  static String cleanPath(String path) =>
 | 
				
			||||||
 | 
					      path.replaceAll(RegExp(r'\/+'), '/').replaceFirst(RegExp(r'^\/'), '');
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -14,11 +14,10 @@
 | 
				
			|||||||
// You should have received a copy of the GNU General Public License
 | 
					// You should have received a copy of the GNU General Public License
 | 
				
			||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
 | 
					// along with this program. If not, see <https://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import 'dart:convert';
 | 
					import 'package:flutter/services.dart' show AssetBundle, rootBundle;
 | 
				
			||||||
 | 
					 | 
				
			||||||
import 'package:flutter/services.dart' show ServicesBinding, rootBundle;
 | 
					 | 
				
			||||||
import 'package:wyatt_i18n/src/core/enums/format.dart';
 | 
					import 'package:wyatt_i18n/src/core/enums/format.dart';
 | 
				
			||||||
import 'package:wyatt_i18n/src/core/exceptions/exceptions.dart';
 | 
					import 'package:wyatt_i18n/src/core/exceptions/exceptions.dart';
 | 
				
			||||||
 | 
					import 'package:wyatt_i18n/src/core/utils/assets_utils.dart';
 | 
				
			||||||
import 'package:wyatt_i18n/src/domain/data_sources/i18n_data_source.dart';
 | 
					import 'package:wyatt_i18n/src/domain/data_sources/i18n_data_source.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// {@template assets_file_data_source_impl}
 | 
					/// {@template assets_file_data_source_impl}
 | 
				
			||||||
@ -34,10 +33,11 @@ import 'package:wyatt_i18n/src/domain/data_sources/i18n_data_source.dart';
 | 
				
			|||||||
/// {@endtemplate}
 | 
					/// {@endtemplate}
 | 
				
			||||||
class AssetsFileDataSourceImpl extends I18nDataSource {
 | 
					class AssetsFileDataSourceImpl extends I18nDataSource {
 | 
				
			||||||
  /// {@macro assets_file_data_source_impl}
 | 
					  /// {@macro assets_file_data_source_impl}
 | 
				
			||||||
  const AssetsFileDataSourceImpl({
 | 
					  AssetsFileDataSourceImpl({
 | 
				
			||||||
    this.basePath = 'assets',
 | 
					    this.basePath = 'assets',
 | 
				
			||||||
    this.baseName = 'i18n',
 | 
					    this.baseName = 'i18n',
 | 
				
			||||||
    super.format = Format.arb,
 | 
					    super.format = Format.arb,
 | 
				
			||||||
 | 
					    super.defaultLocale = 'en',
 | 
				
			||||||
  }) : super();
 | 
					  }) : super();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /// The folder where the i18n files are located.
 | 
					  /// The folder where the i18n files are located.
 | 
				
			||||||
@ -46,29 +46,23 @@ class AssetsFileDataSourceImpl extends I18nDataSource {
 | 
				
			|||||||
  /// The name of the i18n files without the extension.
 | 
					  /// The name of the i18n files without the extension.
 | 
				
			||||||
  final String baseName;
 | 
					  final String baseName;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /// Checks if the given [assetPath] is a local asset.
 | 
					  /// The asset bundle used to load the i18n files.
 | 
				
			||||||
  ///
 | 
					  final AssetBundle assetBundle = rootBundle;
 | 
				
			||||||
  /// In fact, this method loads the asset and checks if it is null.
 | 
					 | 
				
			||||||
  Future<bool> assetExists(String assetPath) async {
 | 
					 | 
				
			||||||
    final encoded = utf8.encoder.convert(
 | 
					 | 
				
			||||||
      Uri(path: Uri.encodeFull(assetPath)).path,
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
    final asset = await ServicesBinding.instance.defaultBinaryMessenger
 | 
					 | 
				
			||||||
        .send('flutter/assets', encoded.buffer.asByteData());
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return asset != null;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /// Tries to load the i18n file from the given [locale].
 | 
					  /// Tries to load the i18n file from the given [locale].
 | 
				
			||||||
  Future<String> _tryLoad(String? locale) async {
 | 
					  Future<String> _tryLoad(String? locale) async {
 | 
				
			||||||
    String? content;
 | 
					    String? content;
 | 
				
			||||||
    final ext = format.name;
 | 
					    final ext = format.name;
 | 
				
			||||||
    final path = locale == null
 | 
					
 | 
				
			||||||
        ? '$basePath/$baseName.$ext'
 | 
					    final path = AssetsUtils.cleanPath(
 | 
				
			||||||
        : '$basePath/$baseName.$locale.$ext';
 | 
					      locale == null
 | 
				
			||||||
 | 
					          ? '$basePath/$baseName.$defaultLocale.$ext'
 | 
				
			||||||
 | 
					          : '$basePath/$baseName.$locale.$ext',
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    try {
 | 
					    try {
 | 
				
			||||||
      if (await assetExists(path)) {
 | 
					      if (await AssetsUtils.assetExists(path)) {
 | 
				
			||||||
        content = await rootBundle.loadString(path);
 | 
					        content = await assetBundle.loadString(path);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    } catch (_) {
 | 
					    } catch (_) {
 | 
				
			||||||
      content = null;
 | 
					      content = null;
 | 
				
			||||||
@ -78,7 +72,10 @@ class AssetsFileDataSourceImpl extends I18nDataSource {
 | 
				
			|||||||
    /// default i18n file.
 | 
					    /// default i18n file.
 | 
				
			||||||
    if (content == null && locale != null) {
 | 
					    if (content == null && locale != null) {
 | 
				
			||||||
      try {
 | 
					      try {
 | 
				
			||||||
        content = await rootBundle.loadString('$basePath/$baseName.$ext');
 | 
					        final fallbackPath = AssetsUtils.cleanPath(
 | 
				
			||||||
 | 
					          '$basePath/$baseName.$defaultLocale.$ext',
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					        content = await assetBundle.loadString(fallbackPath);
 | 
				
			||||||
      } catch (_) {
 | 
					      } catch (_) {
 | 
				
			||||||
        throw SourceNotFoundException(path, format: format);
 | 
					        throw SourceNotFoundException(path, format: format);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
@ -98,7 +95,7 @@ class AssetsFileDataSourceImpl extends I18nDataSource {
 | 
				
			|||||||
  Future<String> _tryLoadUri(Uri uri) async {
 | 
					  Future<String> _tryLoadUri(Uri uri) async {
 | 
				
			||||||
    String? content;
 | 
					    String? content;
 | 
				
			||||||
    try {
 | 
					    try {
 | 
				
			||||||
      content = await rootBundle.loadString(uri.toString());
 | 
					      content = await assetBundle.loadString(uri.toString());
 | 
				
			||||||
    } catch (_) {
 | 
					    } catch (_) {
 | 
				
			||||||
      throw SourceNotFoundException(uri.toString(), format: format);
 | 
					      throw SourceNotFoundException(uri.toString(), format: format);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
@ -17,16 +17,26 @@
 | 
				
			|||||||
import 'package:wyatt_architecture/wyatt_architecture.dart';
 | 
					import 'package:wyatt_architecture/wyatt_architecture.dart';
 | 
				
			||||||
import 'package:wyatt_i18n/src/core/enums/format.dart';
 | 
					import 'package:wyatt_i18n/src/core/enums/format.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// {@template i18n_data_source}
 | 
				
			||||||
/// Base class for i18n data sources.
 | 
					/// Base class for i18n data sources.
 | 
				
			||||||
///
 | 
					///
 | 
				
			||||||
/// This class is used to load i18n files from a source.
 | 
					/// This class is used to load i18n files from a source.
 | 
				
			||||||
/// It returns a [Future] that resolves to a [String] containing the i18n file
 | 
					/// It returns a [Future] that resolves to a [String] containing the i18n file
 | 
				
			||||||
/// contents.
 | 
					/// contents.
 | 
				
			||||||
 | 
					/// {@endtemplate}
 | 
				
			||||||
abstract class I18nDataSource extends BaseDataSource {
 | 
					abstract class I18nDataSource extends BaseDataSource {
 | 
				
			||||||
  const I18nDataSource({this.format = Format.arb});
 | 
					  /// {@macro i18n_data_source}
 | 
				
			||||||
 | 
					  const I18nDataSource({
 | 
				
			||||||
 | 
					    this.format = Format.arb,
 | 
				
			||||||
 | 
					    this.defaultLocale = 'en',
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// The format of the i18n file.
 | 
				
			||||||
  final Format format;
 | 
					  final Format format;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// The default locale.
 | 
				
			||||||
 | 
					  final String defaultLocale;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /// Loads the i18n file from the source.
 | 
					  /// Loads the i18n file from the source.
 | 
				
			||||||
  /// If [locale] is not `null`, it will load the file with the given [locale].
 | 
					  /// If [locale] is not `null`, it will load the file with the given [locale].
 | 
				
			||||||
  /// Otherwise, it will load the file from the default location.
 | 
					  /// Otherwise, it will load the file from the default location.
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user