runable
This commit is contained in:
274
lib/core/utils/l10n_extensions.dart
Normal file
274
lib/core/utils/l10n_extensions.dart
Normal file
@@ -0,0 +1,274 @@
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:worker/generated/l10n/app_localizations.dart';
|
||||
|
||||
/// Extension for easy access to AppLocalizations
|
||||
///
|
||||
/// This extension provides convenient access to localization strings
|
||||
/// throughout the app without having to write `AppLocalizations.of(context)!`
|
||||
/// every time.
|
||||
///
|
||||
/// Usage:
|
||||
/// ```dart
|
||||
/// // Instead of:
|
||||
/// Text(AppLocalizations.of(context)!.login)
|
||||
///
|
||||
/// // You can use:
|
||||
/// Text(context.l10n.login)
|
||||
/// ```
|
||||
extension L10nExtension on BuildContext {
|
||||
/// Get the current AppLocalizations instance
|
||||
///
|
||||
/// This getter provides quick access to all localized strings.
|
||||
/// It will throw an error if called before the app is initialized,
|
||||
/// which helps catch localization issues during development.
|
||||
AppLocalizations get l10n => AppLocalizations.of(this)!;
|
||||
|
||||
/// Get the current locale language code (e.g., 'vi', 'en')
|
||||
String get languageCode => Localizations.localeOf(this).languageCode;
|
||||
|
||||
/// Check if the current locale is Vietnamese
|
||||
bool get isVietnamese => languageCode == 'vi';
|
||||
|
||||
/// Check if the current locale is English
|
||||
bool get isEnglish => languageCode == 'en';
|
||||
}
|
||||
|
||||
/// Helper class for common localization patterns
|
||||
///
|
||||
/// This class provides utility methods for formatting dates, times,
|
||||
/// currencies, and other locale-specific data.
|
||||
class L10nHelper {
|
||||
const L10nHelper._();
|
||||
|
||||
/// Format a DateTime to localized date string (DD/MM/YYYY for Vietnamese, MM/DD/YYYY for English)
|
||||
///
|
||||
/// Example:
|
||||
/// ```dart
|
||||
/// final dateStr = L10nHelper.formatDate(context, DateTime.now());
|
||||
/// // Vietnamese: "17/10/2025"
|
||||
/// // English: "10/17/2025"
|
||||
/// ```
|
||||
static String formatDate(BuildContext context, DateTime date) {
|
||||
final day = date.day.toString().padLeft(2, '0');
|
||||
final month = date.month.toString().padLeft(2, '0');
|
||||
final year = date.year.toString();
|
||||
|
||||
return context.l10n.formatDate(day, month, year);
|
||||
}
|
||||
|
||||
/// Format a DateTime to localized date-time string
|
||||
///
|
||||
/// Example:
|
||||
/// ```dart
|
||||
/// final dateTimeStr = L10nHelper.formatDateTime(context, DateTime.now());
|
||||
/// // Vietnamese: "17/10/2025 lúc 14:30"
|
||||
/// // English: "10/17/2025 at 14:30"
|
||||
/// ```
|
||||
static String formatDateTime(BuildContext context, DateTime dateTime) {
|
||||
final day = dateTime.day.toString().padLeft(2, '0');
|
||||
final month = dateTime.month.toString().padLeft(2, '0');
|
||||
final year = dateTime.year.toString();
|
||||
final hour = dateTime.hour.toString().padLeft(2, '0');
|
||||
final minute = dateTime.minute.toString().padLeft(2, '0');
|
||||
|
||||
return context.l10n.formatDateTime(day, month, year, hour, minute);
|
||||
}
|
||||
|
||||
/// Format a number as Vietnamese Dong currency
|
||||
///
|
||||
/// Example:
|
||||
/// ```dart
|
||||
/// final price = L10nHelper.formatCurrency(context, 1500000);
|
||||
/// // Returns: "1.500.000 ₫"
|
||||
/// ```
|
||||
static String formatCurrency(BuildContext context, double amount) {
|
||||
final formatted = context.isVietnamese
|
||||
? _formatNumberVietnamese(amount)
|
||||
: _formatNumberEnglish(amount);
|
||||
|
||||
return context.l10n.formatCurrency(formatted);
|
||||
}
|
||||
|
||||
/// Format number with Vietnamese grouping (dots)
|
||||
static String _formatNumberVietnamese(double number) {
|
||||
final parts = number.toStringAsFixed(0).split('.');
|
||||
final intPart = parts[0];
|
||||
|
||||
// Add dots every 3 digits from right
|
||||
final buffer = StringBuffer();
|
||||
for (var i = 0; i < intPart.length; i++) {
|
||||
if (i > 0 && (intPart.length - i) % 3 == 0) {
|
||||
buffer.write('.');
|
||||
}
|
||||
buffer.write(intPart[i]);
|
||||
}
|
||||
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
/// Format number with English grouping (commas)
|
||||
static String _formatNumberEnglish(double number) {
|
||||
final parts = number.toStringAsFixed(0).split('.');
|
||||
final intPart = parts[0];
|
||||
|
||||
// Add commas every 3 digits from right
|
||||
final buffer = StringBuffer();
|
||||
for (var i = 0; i < intPart.length; i++) {
|
||||
if (i > 0 && (intPart.length - i) % 3 == 0) {
|
||||
buffer.write(',');
|
||||
}
|
||||
buffer.write(intPart[i]);
|
||||
}
|
||||
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
/// Format a relative time (e.g., "5 minutes ago", "2 days ago")
|
||||
///
|
||||
/// Example:
|
||||
/// ```dart
|
||||
/// final relativeTime = L10nHelper.formatRelativeTime(
|
||||
/// context,
|
||||
/// DateTime.now().subtract(Duration(minutes: 5)),
|
||||
/// );
|
||||
/// // Returns: "5 phút trước" (Vietnamese) or "5 minutes ago" (English)
|
||||
/// ```
|
||||
static String formatRelativeTime(BuildContext context, DateTime dateTime) {
|
||||
final now = DateTime.now();
|
||||
final difference = now.difference(dateTime);
|
||||
|
||||
if (difference.inSeconds < 60) {
|
||||
return context.l10n.justNow;
|
||||
} else if (difference.inMinutes < 60) {
|
||||
return context.l10n.minutesAgo(difference.inMinutes);
|
||||
} else if (difference.inHours < 24) {
|
||||
return context.l10n.hoursAgo(difference.inHours);
|
||||
} else if (difference.inDays < 7) {
|
||||
return context.l10n.daysAgo(difference.inDays);
|
||||
} else if (difference.inDays < 30) {
|
||||
return context.l10n.weeksAgo((difference.inDays / 7).floor());
|
||||
} else if (difference.inDays < 365) {
|
||||
return context.l10n.monthsAgo((difference.inDays / 30).floor());
|
||||
} else {
|
||||
return context.l10n.yearsAgo((difference.inDays / 365).floor());
|
||||
}
|
||||
}
|
||||
|
||||
/// Get localized order status string
|
||||
static String getOrderStatus(BuildContext context, String status) {
|
||||
switch (status.toLowerCase()) {
|
||||
case 'pending':
|
||||
return context.l10n.pending;
|
||||
case 'processing':
|
||||
return context.l10n.processing;
|
||||
case 'shipping':
|
||||
return context.l10n.shipping;
|
||||
case 'completed':
|
||||
return context.l10n.completed;
|
||||
case 'cancelled':
|
||||
return context.l10n.cancelled;
|
||||
default:
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
/// Get localized project status string
|
||||
static String getProjectStatus(BuildContext context, String status) {
|
||||
switch (status.toLowerCase()) {
|
||||
case 'planning':
|
||||
return context.l10n.planningProjects;
|
||||
case 'in_progress':
|
||||
case 'inprogress':
|
||||
return context.l10n.inProgressProjects;
|
||||
case 'completed':
|
||||
return context.l10n.completedProjects;
|
||||
default:
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
/// Get localized member tier string
|
||||
static String getMemberTier(BuildContext context, String tier) {
|
||||
switch (tier.toLowerCase()) {
|
||||
case 'diamond':
|
||||
return context.l10n.diamond;
|
||||
case 'platinum':
|
||||
return context.l10n.platinum;
|
||||
case 'gold':
|
||||
return context.l10n.gold;
|
||||
default:
|
||||
return tier;
|
||||
}
|
||||
}
|
||||
|
||||
/// Get localized user type string
|
||||
static String getUserType(BuildContext context, String userType) {
|
||||
switch (userType.toLowerCase()) {
|
||||
case 'contractor':
|
||||
return context.l10n.contractor;
|
||||
case 'architect':
|
||||
return context.l10n.architect;
|
||||
case 'distributor':
|
||||
return context.l10n.distributor;
|
||||
case 'broker':
|
||||
return context.l10n.broker;
|
||||
default:
|
||||
return userType;
|
||||
}
|
||||
}
|
||||
|
||||
/// Get localized password strength string
|
||||
static String getPasswordStrength(BuildContext context, String strength) {
|
||||
switch (strength.toLowerCase()) {
|
||||
case 'weak':
|
||||
return context.l10n.weak;
|
||||
case 'medium':
|
||||
return context.l10n.medium;
|
||||
case 'strong':
|
||||
return context.l10n.strong;
|
||||
case 'very_strong':
|
||||
case 'verystrong':
|
||||
return context.l10n.veryStrong;
|
||||
default:
|
||||
return strength;
|
||||
}
|
||||
}
|
||||
|
||||
/// Format points with proper pluralization
|
||||
///
|
||||
/// Example:
|
||||
/// ```dart
|
||||
/// final pointsText = L10nHelper.formatPoints(context, 100);
|
||||
/// // Returns: "+100 điểm" (Vietnamese) or "+100 points" (English)
|
||||
/// ```
|
||||
static String formatPoints(BuildContext context, int points,
|
||||
{bool showSign = true}) {
|
||||
if (showSign && points > 0) {
|
||||
return context.l10n.earnedPoints(points);
|
||||
} else if (showSign && points < 0) {
|
||||
return context.l10n.spentPoints(points.abs());
|
||||
} else {
|
||||
return context.l10n.pointsBalance(points);
|
||||
}
|
||||
}
|
||||
|
||||
/// Format item count with pluralization
|
||||
static String formatItemCount(BuildContext context, int count) {
|
||||
return context.l10n.itemsInCart(count);
|
||||
}
|
||||
|
||||
/// Format order count with pluralization
|
||||
static String formatOrderCount(BuildContext context, int count) {
|
||||
return context.l10n.ordersCount(count);
|
||||
}
|
||||
|
||||
/// Format project count with pluralization
|
||||
static String formatProjectCount(BuildContext context, int count) {
|
||||
return context.l10n.projectsCount(count);
|
||||
}
|
||||
|
||||
/// Format days remaining with pluralization
|
||||
static String formatDaysRemaining(BuildContext context, int days) {
|
||||
return context.l10n.daysRemaining(days);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user