ponshu-room-lite/lib/main.dart

133 lines
5.1 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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';
import 'services/license_service.dart';
import 'providers/license_provider.dart';
/// 店舗向けビルドかどうかを判定するビルド時フラグ
///
/// ビルドコマンド:
/// - 消費者向け: 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<UserProfile>('user_profile'),
Hive.openBox<SakeItem>('sake_items'),
Hive.openBox<MenuSettings>('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) {
final migrationSucceeded = await MigrationService.runMigration();
if (migrationSucceeded) {
await box.put('migration_version', currentMigrationVersion);
await box.put('migration_completed', true); // 旧フラグも維持(後方互換)
} else {
// バックアップ失敗などでマイグレーションが中断された場合は
// バージョンを進めない。次回起動で再試行される。
debugPrint('[main] Migration aborted — migration_version not updated');
}
}
// v1.0.33: AI 解析キャッシュをインメモリ化したため、旧 Hive ボックスをディスクから削除する
// (既存ユーザーのデータ残骸クリーンアップ。ボックスが存在しない場合は何もしない)
for (final boxName in ['analysis_cache_v1', 'brand_index_v1']) {
try {
await Hive.deleteBoxFromDisk(boxName);
} catch (_) {
// 存在しない場合は無視
}
}
// ちらつき防止: runApp の前にキャッシュ済みライセンス状態を取得し、
// licenseStatusProvider が loading を経由せず即 AsyncData になるよう override する
final cachedLicenseStatus = await LicenseService.getCachedStatusOnly();
runApp(
ProviderScope(
overrides: [
licenseInitialStatusProvider.overrideWithValue(cachedLicenseStatus),
],
child: const 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<ModalRoute<void>> routeObserver = RouteObserver<ModalRoute<void>>();