Files
lunchpick/lib/main.dart
2025-11-19 16:36:39 +09:00

171 lines
5.4 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:hive_flutter/hive_flutter.dart';
import 'package:adaptive_theme/adaptive_theme.dart';
import 'package:go_router/go_router.dart';
import 'package:timezone/data/latest_all.dart' as tz;
import 'core/constants/app_colors.dart';
import 'core/constants/app_constants.dart';
import 'core/services/notification_service.dart';
import 'domain/entities/restaurant.dart';
import 'domain/entities/visit_record.dart';
import 'domain/entities/recommendation_record.dart';
import 'domain/entities/user_settings.dart';
import 'presentation/pages/splash/splash_screen.dart';
import 'presentation/pages/main/main_screen.dart';
import 'data/sample/sample_data_initializer.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
// Initialize timezone
tz.initializeTimeZones();
// Initialize Hive
await Hive.initFlutter();
// Register Hive Adapters
Hive.registerAdapter(RestaurantAdapter());
Hive.registerAdapter(DataSourceAdapter());
Hive.registerAdapter(VisitRecordAdapter());
Hive.registerAdapter(RecommendationRecordAdapter());
Hive.registerAdapter(UserSettingsAdapter());
// Open Hive Boxes
await Hive.openBox<Restaurant>(AppConstants.restaurantBox);
await Hive.openBox<VisitRecord>(AppConstants.visitRecordBox);
await Hive.openBox<RecommendationRecord>(AppConstants.recommendationBox);
await Hive.openBox(AppConstants.settingsBox);
await Hive.openBox<UserSettings>('user_settings');
await SampleDataInitializer.seedManualRestaurantsIfNeeded();
// Initialize Notification Service (only for non-web platforms)
if (!kIsWeb) {
final notificationService = NotificationService();
await notificationService.initialize();
await notificationService.requestPermission();
}
// Get saved theme mode
final savedThemeMode = await AdaptiveTheme.getThemeMode();
runApp(ProviderScope(child: LunchPickApp(savedThemeMode: savedThemeMode)));
}
class LunchPickApp extends StatelessWidget {
final AdaptiveThemeMode? savedThemeMode;
const LunchPickApp({super.key, this.savedThemeMode});
@override
Widget build(BuildContext context) {
return AdaptiveTheme(
light: ThemeData(
useMaterial3: true,
colorScheme: ColorScheme.fromSeed(
seedColor: AppColors.lightPrimary,
brightness: Brightness.light,
),
primaryColor: AppColors.lightPrimary,
scaffoldBackgroundColor: AppColors.lightBackground,
appBarTheme: const AppBarTheme(
backgroundColor: AppColors.lightPrimary,
foregroundColor: Colors.white,
elevation: 0,
),
elevatedButtonTheme: ElevatedButtonThemeData(
style: ElevatedButton.styleFrom(
backgroundColor: AppColors.lightPrimary,
foregroundColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
),
),
cardTheme: CardThemeData(
color: AppColors.lightSurface,
elevation: 2,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
),
),
dark: ThemeData(
useMaterial3: true,
colorScheme: ColorScheme.fromSeed(
seedColor: AppColors.darkPrimary,
brightness: Brightness.dark,
),
primaryColor: AppColors.darkPrimary,
scaffoldBackgroundColor: AppColors.darkBackground,
appBarTheme: const AppBarTheme(
backgroundColor: AppColors.darkPrimary,
foregroundColor: Colors.white,
elevation: 0,
),
elevatedButtonTheme: ElevatedButtonThemeData(
style: ElevatedButton.styleFrom(
backgroundColor: AppColors.darkPrimary,
foregroundColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
),
),
cardTheme: CardThemeData(
color: AppColors.darkSurface,
elevation: 2,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
),
),
initial: savedThemeMode ?? AdaptiveThemeMode.light,
builder: (theme, darkTheme) => MaterialApp.router(
title: AppConstants.appName,
theme: theme,
darkTheme: darkTheme,
routerConfig: _router,
debugShowCheckedModeBanner: false,
),
);
}
}
// GoRouter configuration
final _router = GoRouter(
initialLocation: '/',
routes: [
GoRoute(path: '/', builder: (context, state) => const SplashScreen()),
GoRoute(
path: '/home',
builder: (context, state) {
final tabParam = state.uri.queryParameters['tab'];
int initialTab = 2; // 기본값: 뽑기 탭
if (tabParam != null) {
switch (tabParam) {
case 'share':
initialTab = 0;
break;
case 'list':
initialTab = 1;
break;
case 'random':
initialTab = 2;
break;
case 'calendar':
initialTab = 3;
break;
case 'settings':
initialTab = 4;
break;
}
}
return MainScreen(initialTab: initialTab);
},
),
],
);