cb_prestige_qr/lib/app/navigation/main_shell.dart

173 lines
5.7 KiB
Dart
Raw Normal View History

2026-04-09 06:47:03 +00:00
import 'dart:async';
import 'dart:ui';
import 'package:cb_prestige_qr/core/presentation/widgets/global_loading_overlay.dart';
2026-04-27 09:08:26 +00:00
import 'package:cb_prestige_qr/core/widgets/center_nav_button.dart';
import 'package:cb_prestige_qr/core/widgets/nav_item.dart';
import 'package:cb_prestige_qr/features/analysis/presentation/views/analysis_view.dart';
import 'package:cb_prestige_qr/features/history/presentation/views/history_view.dart';
import 'package:cb_prestige_qr/features/home/presentation/views/home_view.dart';
import 'package:cb_prestige_qr/features/scan/presentation/views/scan_flow.dart';
import 'package:cb_prestige_qr/features/settings/presentation/views/settings_view.dart';
2026-04-09 06:47:03 +00:00
import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
2026-04-27 09:08:26 +00:00
final navIndexProvider = NotifierProvider<NavIndexNotifier, int>(
2026-04-09 06:47:03 +00:00
NavIndexNotifier.new,
);
class NavIndexNotifier extends Notifier<int> {
@override
int build() => 0;
void setIndex(int index) {
if (state == index) return;
state = index;
}
}
class MainShell extends ConsumerStatefulWidget {
const MainShell({super.key});
@override
ConsumerState<MainShell> createState() => _MainShellState();
}
class _MainShellState extends ConsumerState<MainShell> {
Timer? _timer;
var _isLoading = false;
void _startLoading([Duration duration = const Duration(seconds: 1)]) {
_timer?.cancel();
2026-04-27 09:08:26 +00:00
if (!_isLoading) {
setState(() => _isLoading = true);
}
2026-04-09 06:47:03 +00:00
_timer = Timer(duration, () {
if (!mounted) return;
setState(() => _isLoading = false);
});
}
@override
void initState() {
super.initState();
2026-04-27 09:08:26 +00:00
final initialIndex = ref.read(navIndexProvider);
if (initialIndex != 0) {
_startLoading();
}
2026-04-09 06:47:03 +00:00
}
@override
void dispose() {
_timer?.cancel();
super.dispose();
}
@override
Widget build(BuildContext context) {
2026-04-27 09:08:26 +00:00
final selectedIndex = ref.watch(navIndexProvider);
2026-04-09 06:47:03 +00:00
final theme = Theme.of(context);
2026-04-27 09:08:26 +00:00
ref.listen<int>(navIndexProvider, (previous, next) {
if (previous == null || previous == next || next == 0) return;
2026-04-09 06:47:03 +00:00
_startLoading();
});
2026-04-27 09:08:26 +00:00
const pages = <Widget>[
HomeView(),
AnalysisView(),
SizedBox(),
HistoryView(),
SettingsView(),
2026-04-09 06:47:03 +00:00
];
return Stack(
children: [
Scaffold(
extendBody: true,
body: IndexedStack(index: selectedIndex, children: pages),
bottomNavigationBar: Padding(
padding: const EdgeInsets.symmetric(horizontal: 0),
child: ClipRRect(
borderRadius: BorderRadius.circular(16),
child: BackdropFilter(
filter: ImageFilter.blur(sigmaX: 20, sigmaY: 20),
child: Container(
height: 70 + MediaQuery.of(context).padding.bottom,
decoration: BoxDecoration(
color: theme.scaffoldBackgroundColor,
borderRadius: BorderRadius.circular(16),
border: Border.all(color: Colors.white.withAlpha(31)),
boxShadow: [
BoxShadow(
color: Colors.black.withAlpha(31),
blurRadius: 25,
offset: const Offset(0, 10),
),
],
),
child: Padding(
padding: EdgeInsets.only(
bottom: MediaQuery.of(context).padding.bottom,
),
child: Row(
children: [
Expanded(
child: NavItem(
icon: Icons.home_rounded,
isActive: selectedIndex == 0,
2026-04-27 09:08:26 +00:00
onTap: () =>
ref.read(navIndexProvider.notifier).setIndex(0),
2026-04-09 06:47:03 +00:00
),
),
Expanded(
child: NavItem(
icon: Icons.analytics,
isActive: selectedIndex == 1,
2026-04-27 09:08:26 +00:00
onTap: () =>
ref.read(navIndexProvider.notifier).setIndex(1),
2026-04-09 06:47:03 +00:00
),
),
Expanded(
child: CenterNavButton(
isActive: false,
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (_) => const ScanFlow(),
),
);
},
),
),
Expanded(
child: NavItem(
icon: Icons.history_rounded,
isActive: selectedIndex == 3,
2026-04-27 09:08:26 +00:00
onTap: () =>
ref.read(navIndexProvider.notifier).setIndex(3),
2026-04-09 06:47:03 +00:00
),
),
Expanded(
child: NavItem(
icon: Icons.person_rounded,
isActive: selectedIndex == 4,
2026-04-27 09:08:26 +00:00
onTap: () =>
ref.read(navIndexProvider.notifier).setIndex(4),
2026-04-09 06:47:03 +00:00
),
),
],
),
),
),
),
),
),
),
GlobalLoadingOverlay(isLoading: _isLoading),
],
);
}
}