import 'package:flutter/material.dart'; import 'app_controller.dart'; import 'app_theme.dart'; import '../widgets/glass_dock.dart'; import '../features/timetable/timetable_page.dart'; import '../features/profile/profile_page.dart'; class HepanApp extends StatelessWidget { const HepanApp({super.key, required this.controller, this.schoolBuilder}); final AppController controller; final Widget Function()? schoolBuilder; @override Widget build(BuildContext context) => MaterialApp( debugShowCheckedModeBanner: false, title: '河畔Everyday', theme: hepanTheme(), home: _Shell(controller: controller, schoolBuilder: schoolBuilder), ); } class _Shell extends StatefulWidget { const _Shell({required this.controller, this.schoolBuilder}); final AppController controller; final Widget Function()? schoolBuilder; @override State<_Shell> createState() => _ShellState(); } class _ShellState extends State<_Shell> with WidgetsBindingObserver { int _tab = 0; @override void initState() { super.initState(); WidgetsBinding.instance.addObserver(this); } @override void dispose() { WidgetsBinding.instance.removeObserver(this); super.dispose(); } @override void didChangeAppLifecycleState(AppLifecycleState state) { if (state == AppLifecycleState.resumed) { widget.controller.refreshServices(); } } void _school() { if (widget.schoolBuilder != null) { Navigator.push( context, MaterialPageRoute(builder: (_) => widget.schoolBuilder!()), ); } else { showDialog( context: context, builder: (context) => AlertDialog( title: const Text('学校认证'), content: const Text('学校认证入口正在接入。你可以先体验示例课表或导入课表文件。'), actions: [ TextButton( onPressed: () => Navigator.pop(context), child: const Text('知道了'), ), ], ), ); } } @override Widget build(BuildContext context) => AnimatedBuilder( animation: widget.controller, builder: (context, _) => Scaffold( body: Container( decoration: const BoxDecoration( gradient: LinearGradient( begin: Alignment.topLeft, end: Alignment.bottomRight, colors: [Color(0xFFF0F7F5), Color(0xFFF7F8F5), Color(0xFFEFF5F3)], ), ), child: SafeArea( bottom: false, child: Stack( children: [ Positioned.fill( child: Column( children: [ if (widget.controller.lastError != null) Container( width: double.infinity, color: const Color(0xFFF8ECE6), padding: const EdgeInsets.all(12), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( widget.controller.lastError!, style: const TextStyle(fontSize: 12), ), if (!widget.controller.storageReady) TextButton( onPressed: widget.controller.restoreBackup, child: const Text('恢复最近备份'), ), ], ), ), Expanded( child: IndexedStack( index: _tab, children: [ TimetablePage(controller: widget.controller), ProfilePage( controller: widget.controller, onLogin: _school, ), ], ), ), ], ), ), Positioned( left: 0, right: 0, bottom: 16 + MediaQuery.paddingOf(context).bottom, child: Center( child: GlassDock( selectedIndex: _tab, onSelected: (index) => setState(() => _tab = index), ), ), ), ], ), ), ), ), ); }