import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; // Localization import 'package:hive_flutter/hive_flutter.dart'; import 'models/sake_item.dart'; import 'models/user_profile.dart'; import 'models/menu_settings.dart'; import 'providers/theme_provider.dart'; import 'screens/main_screen.dart'; import 'screens/license_screen.dart'; import 'services/migration_service.dart'; /// ビルド時Pro解放フラグ(現在未使用 — 実行時ライセンスはisProProviderで管理) /// 将来的に削除予定。isProProvider (license_provider.dart) を使うこと。 const bool isProVersion = bool.fromEnvironment('IS_PRO_VERSION', defaultValue: false); /// 店舗向けビルドかどうかを判定するビルド時フラグ /// /// ビルドコマンド: /// - 消費者向け: flutter build apk --release --dart-define=IS_BUSINESS_APP=false /// - 店舗向け: flutter build apk --release --dart-define=IS_BUSINESS_APP=true /// /// デフォルトはfalse(消費者向け) const bool isBusinessApp = bool.fromEnvironment('IS_BUSINESS_APP', defaultValue: false); void main() async { WidgetsFlutterBinding.ensureInitialized(); await Hive.initFlutter(); Hive.registerAdapter(SakeItemAdapter()); Hive.registerAdapter(UserProfileAdapter()); Hive.registerAdapter(MenuSettingsAdapter()); Hive.registerAdapter(DisplayDataAdapter()); Hive.registerAdapter(HiddenSpecsAdapter()); Hive.registerAdapter(UserDataAdapter()); Hive.registerAdapter(GamificationAdapter()); Hive.registerAdapter(MetadataAdapter()); Hive.registerAdapter(ItemTypeAdapter()); // Restored missing adapter // Open all boxes first (faster to open them together) // Reverted to synchronous wait to ensure Providers have data immediately // Open all boxes in parallel (Much faster than sequential) await Future.wait([ Hive.openBox('settings'), Hive.openBox('user_profile'), Hive.openBox('sake_items'), Hive.openBox('menu_settings'), ]); // Migration — バージョン番号で管理(単一フラグだと将来の追加マイグレーションが走らないため) // migration_completed=true の旧ユーザーはバージョン 1 扱いとして互換性を維持する const int currentMigrationVersion = 1; final box = Hive.box('settings'); final legacyCompleted = box.get('migration_completed', defaultValue: false) as bool; final storedVersion = legacyCompleted ? box.get('migration_version', defaultValue: 1) as int // 旧ユーザー: 既に完了済み=v1 : box.get('migration_version', defaultValue: 0) as int; // 新規ユーザー: 未実行=v0 if (storedVersion < currentMigrationVersion) { debugPrint('🚀 Running MigrationService (v$storedVersion → v$currentMigrationVersion)...'); await MigrationService.runMigration(); await box.put('migration_version', currentMigrationVersion); await box.put('migration_completed', true); // 旧フラグも維持(後方互換) } else { debugPrint('✅ Migration up to date (v$storedVersion). Skipping.'); } // ✅ AI解析キャッシュは使うときに初期化する(Lazy initialization) // AnalysisCacheService.init()はサービス内でLazy実装されているため、 // ここで呼び出すと起動が遅くなる。必要なときに自動初期化される。 runApp( const ProviderScope( child: MyApp(), ), ); } class MyApp extends ConsumerWidget { const MyApp({super.key}); @override Widget build(BuildContext context, WidgetRef ref) { final lightTheme = ref.watch(lightThemeProvider); final darkTheme = ref.watch(darkThemeProvider); final themeMode = ref.watch(themeModeProvider); final locale = ref.watch(localeProvider); // NEW: User-selected locale return MaterialApp( debugShowCheckedModeBanner: false, title: 'Ponshu Room Lite', theme: lightTheme, darkTheme: darkTheme, themeMode: themeMode, locale: locale, // NEW: Apply user's locale choice // Localization (UPDATED) localizationsDelegates: const [ GlobalMaterialLocalizations.delegate, GlobalWidgetsLocalizations.delegate, GlobalCupertinoLocalizations.delegate, ], supportedLocales: const [ Locale('ja'), Locale('en'), ], navigatorObservers: [routeObserver], home: const MainScreen(), routes: { '/upgrade': (context) => const LicenseScreen(), }, ); } } // Global RouteObserver final RouteObserver> routeObserver = RouteObserver>();