petsHero-AI/lib/app.dart

132 lines
4.2 KiB
Dart

import 'package:flutter/material.dart';
import 'core/auth/auth_service.dart';
import 'core/theme/app_colors.dart';
import 'core/theme/app_theme.dart';
import 'core/user/user_state.dart';
import 'features/gallery/gallery_screen.dart';
import 'features/generate_video/generate_progress_screen.dart';
import 'features/generate_video/generate_video_screen.dart';
import 'features/gallery/models/gallery_task_item.dart';
import 'features/generate_video/generation_result_screen.dart';
import 'features/home/home_screen.dart';
import 'features/home/models/task_item.dart';
import 'features/profile/profile_screen.dart';
import 'features/recharge/recharge_screen.dart';
import 'shared/widgets/bottom_nav_bar.dart';
import 'shared/tab_selector_scope.dart';
/// Root app widget with navigation
class App extends StatefulWidget {
const App({super.key});
@override
State<App> createState() => _AppState();
}
class _AppState extends State<App> {
NavTab _currentTab = NavTab.home;
@override
Widget build(BuildContext context) {
return UserCreditsScope(
child: TabSelectorScope(
selectTab: (tab) => setState(() => _currentTab = tab),
child: MaterialApp(
title: 'AI Video App',
theme: AppTheme.light,
debugShowCheckedModeBanner: false,
initialRoute: '/',
builder: (context, child) {
return Stack(
fit: StackFit.expand,
children: [
SafeArea(
top: true,
left: false,
right: false,
bottom: false,
child: child ?? const SizedBox.shrink(),
),
FutureBuilder<void>(
future: AuthService.loginComplete,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
return const SizedBox.shrink();
}
return Positioned.fill(
child: AbsorbPointer(
child: Container(
color: Colors.black.withValues(alpha: 0.2),
child: const Center(
child: CircularProgressIndicator(
color: AppColors.primary,
),
),
),
),
);
},
),
],
);
},
routes: {
'/': (_) => _MainScaffold(
currentTab: _currentTab,
onTabSelected: (tab) => setState(() => _currentTab = tab),
),
'/recharge': (_) => const RechargeScreen(),
'/generate': (ctx) {
final task = ModalRoute.of(ctx)?.settings.arguments as TaskItem?;
return GenerateVideoScreen(task: task);
},
'/progress': (ctx) {
final args = ModalRoute.of(ctx)?.settings.arguments;
final taskId = args is Map ? args['taskId'] : args;
final imagePath = args is Map ? args['imagePath'] as String? : null;
return GenerateProgressScreen(
taskId: taskId,
imagePath: imagePath,
);
},
'/result': (ctx) {
final mediaItem =
ModalRoute.of(ctx)?.settings.arguments as GalleryMediaItem?;
return GenerationResultScreen(mediaItem: mediaItem);
},
},
),
),
);
}
}
class _MainScaffold extends StatelessWidget {
const _MainScaffold({
required this.currentTab,
required this.onTabSelected,
});
final NavTab currentTab;
final ValueChanged<NavTab> onTabSelected;
@override
Widget build(BuildContext context) {
return Scaffold(
body: IndexedStack(
index: currentTab.index,
children: [
HomeScreen(isActive: currentTab == NavTab.home),
GalleryScreen(isActive: currentTab == NavTab.gallery),
ProfileScreen(isActive: currentTab == NavTab.profile),
],
),
bottomNavigationBar: BottomNavBar(
currentTab: currentTab,
onTabSelected: onTabSelected,
),
);
}
}