fix navbar freezing fix
Some checks failed
Release / meta (push) Failing after 9s
Release / android-build (push) Has been skipped
Release / linux-build (push) Has been skipped
Release / release-dev (push) Has been skipped
Release / release-master (push) Has been skipped

This commit is contained in:
2025-12-17 17:41:09 +00:00
parent a9e0cdbe1b
commit 587933fa50
7 changed files with 182 additions and 63 deletions

View File

@@ -1,5 +1,6 @@
import 'package:dynamic_color/dynamic_color.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:go_router/go_router.dart';
import 'package:mileograph_flutter/components/login/login.dart';
import 'package:mileograph_flutter/components/pages/calculator.dart';
@@ -17,6 +18,28 @@ import 'package:mileograph_flutter/services/data_service.dart';
import 'package:mileograph_flutter/services/navigation_guard.dart';
import 'package:provider/provider.dart';
final GlobalKey<NavigatorState> _shellNavigatorKey = GlobalKey<NavigatorState>();
const List<String> _contentPages = [
"/",
"/calculator",
"/legs",
"/traction",
"/trips",
"/add",
];
const int _addTabIndex = 5;
int tabIndexForPath(String path) {
final newIndex = _contentPages.indexWhere((routePath) {
if (path == routePath) return true;
if (routePath == '/') return path == '/';
return path.startsWith('$routePath/');
});
return newIndex < 0 ? 0 : newIndex;
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
@@ -52,6 +75,7 @@ class _MyAppState extends State<MyApp> {
},
routes: [
ShellRoute(
navigatorKey: _shellNavigatorKey,
builder: (context, state, child) => MyHomePage(child: child),
routes: [
GoRoute(path: '/', builder: (context, state) => const Dashboard()),
@@ -153,26 +177,7 @@ class MyHomePage extends StatefulWidget {
}
class _MyHomePageState extends State<MyHomePage> {
final List<String> contentPages = [
"/",
"/calculator",
"/legs",
"/traction",
"/trips",
"/add",
];
int _getIndexFromLocation(String location) {
int newIndex = contentPages.indexWhere((path) {
if (location == path) return true;
if (path == '/') return location == '/';
return location.startsWith('$path/');
});
if (newIndex < 0) {
return 0;
}
return newIndex;
}
List<String> get contentPages => _contentPages;
Future<void> _onItemTapped(int index, int currentIndex) async {
if (index < 0 || index >= contentPages.length || index == currentIndex) {
@@ -184,6 +189,10 @@ class _MyHomePageState extends State<MyHomePage> {
});
}
int? _lastTabIndex;
final List<int> _tabHistory = [];
bool _handlingBackNavigation = false;
bool _fetched = false;
@override
@@ -221,8 +230,12 @@ class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
final location = GoRouterState.of(context).uri.toString();
final pageIndex = _getIndexFromLocation(location);
final uri = GoRouterState.of(context).uri;
final pageIndex = tabIndexForPath(uri.path);
_recordTabChange(pageIndex);
if (pageIndex != _addTabIndex) {
NavigationGuard.unregister();
}
final homepageReady = context.select<DataService, bool>(
(data) => data.homepageStats != null || !data.isHomepageLoading,
);
@@ -232,42 +245,90 @@ class _MyHomePageState extends State<MyHomePage> {
? widget.child
: const Center(child: CircularProgressIndicator());
return Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
title: Text.rich(
TextSpan(
children: const [
TextSpan(text: "Mile"),
TextSpan(text: "O", style: TextStyle(color: Colors.red)),
TextSpan(text: "graph"),
],
style: const TextStyle(
decoration: TextDecoration.none,
color: Colors.white,
fontFamily: "Tomatoes",
return PopScope(
canPop: false,
onPopInvokedWithResult: (didPop, _) async {
if (didPop) return;
final shellNav = _shellNavigatorKey.currentState;
if (shellNav != null && shellNav.canPop()) {
shellNav.pop();
return;
}
if (_tabHistory.isNotEmpty) {
final previousTab = _tabHistory.removeLast();
if (!mounted) return;
_handlingBackNavigation = true;
context.go(contentPages[previousTab]);
return;
}
if (pageIndex != 0) {
if (!mounted) return;
_handlingBackNavigation = true;
context.go(contentPages[0]);
return;
}
SystemNavigator.pop();
},
child: Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
title: Text.rich(
TextSpan(
children: const [
TextSpan(text: "Mile"),
TextSpan(text: "O", style: TextStyle(color: Colors.red)),
TextSpan(text: "graph"),
],
style: const TextStyle(
decoration: TextDecoration.none,
color: Colors.white,
fontFamily: "Tomatoes",
),
),
),
actions: [
const IconButton(onPressed: null, icon: Icon(Icons.account_circle)),
IconButton(onPressed: auth.logout, icon: const Icon(Icons.logout)),
],
),
actions: [
const IconButton(onPressed: null, icon: Icon(Icons.account_circle)),
IconButton(onPressed: auth.logout, icon: const Icon(Icons.logout)),
],
bottomNavigationBar: NavigationBar(
selectedIndex: pageIndex,
onDestinationSelected: (int index) => _onItemTapped(index, pageIndex),
destinations: const [
NavigationDestination(icon: Icon(Icons.home), label: "Home"),
NavigationDestination(icon: Icon(Icons.route), label: "Calculator"),
NavigationDestination(icon: Icon(Icons.list), label: "Entries"),
NavigationDestination(icon: Icon(Icons.train), label: "Traction"),
NavigationDestination(icon: Icon(Icons.book), label: "Trips"),
NavigationDestination(icon: Icon(Icons.add), label: "Add"),
],
),
body: currentPage,
),
bottomNavigationBar: NavigationBar(
selectedIndex: pageIndex,
onDestinationSelected: (int index) => _onItemTapped(index, pageIndex),
destinations: const [
NavigationDestination(icon: Icon(Icons.home), label: "Home"),
NavigationDestination(icon: Icon(Icons.route), label: "Calculator"),
NavigationDestination(icon: Icon(Icons.list), label: "Entries"),
NavigationDestination(icon: Icon(Icons.train), label: "Traction"),
NavigationDestination(icon: Icon(Icons.book), label: "Trips"),
NavigationDestination(icon: Icon(Icons.add), label: "Add"),
],
),
body: currentPage,
);
}
}
void _recordTabChange(int pageIndex) {
final last = _lastTabIndex;
if (last == null) {
_lastTabIndex = pageIndex;
return;
}
if (last == pageIndex) return;
if (_handlingBackNavigation) {
_handlingBackNavigation = false;
_lastTabIndex = pageIndex;
return;
}
if (_tabHistory.isEmpty || _tabHistory.last != last) {
_tabHistory.add(last);
}
_lastTabIndex = pageIndex;
}
}