Files
citypulse/lib/l10n/locale_provider.dart
Zahar 6518df8ac1 feat: introduce FixMate Flutter app and React dashboard
- Add Flutter app shell (FixMateApp/MainScreen) with tabs: Report, Map,
  My Reports, Settings
- Implement capture and review flow (image_picker, geolocator, deterministic
  mock AI), and local storage (SharedPreferences + photo files on mobile)
- Build Map screen with flutter_map, marker clustering, filters, legend,
  marker details, and external maps deeplink
- Add My Reports list (view details, cycle status, delete) and Settings
  (language toggle via Provider, diagnostics, clear all data)
- Introduce JSON i18n loader and LocaleProvider; add EN/BM assets
- Define models (Report, enums) and UI badges (severity, status)

- Add static React dashboard (Leaflet map with clustering, heatmap toggle,
  filters incl. date range, queue, detail drawer), i18n (EN/BM), and
  demo data

- Update build/config and platform setup:
  - Extend pubspec with required packages and register i18n assets
  - Android: add CAMERA and location permissions; pin NDK version
  - iOS: add usage descriptions for camera, photo library, location
  - Gradle properties tuned for Windows/UNC stability
  - Register desktop plugins (Linux/macOS/Windows)
  - .gitignore: ignore .kilocode
  - Overhaul README and replace sample widget test
2025-09-25 18:38:18 +08:00

101 lines
2.7 KiB
Dart

import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
/// Provider for managing app locale and language switching
class LocaleProvider extends ChangeNotifier {
static const String _languageKey = 'lang';
static const String _defaultLanguage = 'en';
Locale _locale = const Locale('en');
late SharedPreferences _prefs;
/// Get the current locale
Locale get locale => _locale;
/// Get the current language code
String get languageCode => _locale.languageCode;
/// Initialize the locale provider
Future<void> init() async {
_prefs = await SharedPreferences.getInstance();
final savedLanguage = _prefs.getString(_languageKey) ?? _defaultLanguage;
_locale = Locale(savedLanguage);
notifyListeners();
}
/// Set the locale and persist the change
Future<void> setLocale(Locale locale) async {
if (_locale == locale) return;
_locale = locale;
await _prefs.setString(_languageKey, locale.languageCode);
notifyListeners();
}
/// Toggle between English and Bahasa Malaysia
Future<void> toggleLanguage() async {
final newLanguage = _locale.languageCode == 'en' ? 'ms' : 'en';
await setLocale(Locale(newLanguage));
}
/// Set language to English
Future<void> setEnglish() async {
await setLocale(const Locale('en'));
}
/// Set language to Bahasa Malaysia
Future<void> setMalay() async {
await setLocale(const Locale('ms'));
}
/// Check if current language is English
bool get isEnglish => _locale.languageCode == 'en';
/// Check if current language is Bahasa Malaysia
bool get isMalay => _locale.languageCode == 'ms';
/// Get the display name for the current language
String get currentLanguageDisplayName {
switch (_locale.languageCode) {
case 'en':
return 'English';
case 'ms':
return 'Bahasa Malaysia';
default:
return 'English';
}
}
/// Get the native display name for the current language
String get currentLanguageNativeName {
switch (_locale.languageCode) {
case 'en':
return 'English';
case 'ms':
return 'Bahasa Malaysia';
default:
return 'English';
}
}
/// Get available locales
List<Locale> get availableLocales => const [
Locale('en'),
Locale('ms'),
];
/// Get available language codes
List<String> get availableLanguageCodes => ['en', 'ms'];
/// Clear saved language preference
Future<void> clearSavedLanguage() async {
await _prefs.remove(_languageKey);
_locale = const Locale(_defaultLanguage);
notifyListeners();
}
/// Reset to default language
Future<void> resetToDefault() async {
await setLocale(const Locale(_defaultLanguage));
}
}