feat(ui): add themed shell navigation

This commit is contained in:
2026-04-23 21:57:24 +02:00
parent bf67e9c2ae
commit 8cf6e95474
14 changed files with 531 additions and 122 deletions

View File

@ -587,7 +587,7 @@ class _DeviceDetailsPageState extends ConsumerState<DeviceDetailsPage> {
}
toast(toastMessage);
context.replace('/');
context.replace('/devices');
}
Future<void> _cancelReconnect() async {
@ -599,7 +599,7 @@ class _DeviceDetailsPageState extends ConsumerState<DeviceDetailsPage> {
if (!mounted) {
return;
}
context.replace('/');
context.replace('/devices');
}
void _showStatusHistory() {

View File

@ -65,7 +65,7 @@ class _ConnectDevicePageState extends ConsumerState<ConnectDevicePage>
title: const Text('Connect Device'),
leading: IconButton(
icon: const Icon(Icons.arrow_back),
onPressed: () => context.go('/'),
onPressed: () => context.go('/devices'),
),
actions: [
Padding(
@ -188,7 +188,10 @@ class _ConnectDevicePageState extends ConsumerState<ConnectDevicePage>
return;
} else {
final res = await controller.connect(device);
print('res: $res');
if (!mounted) {
return;
}
switch (res) {
case Ok():
// trigger pairing/permission prompt if needed
@ -231,6 +234,9 @@ class _ConnectDevicePageState extends ConsumerState<ConnectDevicePage>
}
break;
case Err(:final v):
if (!context.mounted) {
break;
}
ScaffoldMessenger.of(context)
.showSnackBar(SnackBar(
content: Text(
@ -239,7 +245,6 @@ class _ConnectDevicePageState extends ConsumerState<ConnectDevicePage>
break;
}
}
print('Tapped on ${device.id}');
},
child: DeviceListItem(
deviceName: deviceName,

View File

@ -0,0 +1,67 @@
import 'package:abawo_bt_app/pages/home_page.dart';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
class DevicesTabPage extends StatelessWidget {
const DevicesTabPage({super.key});
@override
Widget build(BuildContext context) {
return ListView(
padding: const EdgeInsets.fromLTRB(20, 16, 20, 24),
children: [
Row(
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Devices',
style: Theme.of(context).textTheme.headlineMedium?.copyWith(
fontWeight: FontWeight.w700,
),
),
const SizedBox(height: 6),
Text(
'Manage and connect your hardware.',
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
color: Theme.of(context)
.colorScheme
.onSurface
.withValues(alpha: 0.68),
),
),
],
),
),
IconButton.filledTonal(
tooltip: 'Connect a device',
onPressed: () => context.go('/connect_device'),
icon: const Icon(Icons.add),
),
],
),
const SizedBox(height: 20),
Card(
child: Padding(
padding: const EdgeInsets.fromLTRB(16, 16, 16, 8),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Saved devices',
style: Theme.of(context).textTheme.titleMedium?.copyWith(
fontWeight: FontWeight.w700,
),
),
const SizedBox(height: 8),
const DevicesList(),
],
),
),
),
],
);
}
}

View File

@ -181,6 +181,10 @@ class _DevicesListState extends ConsumerState<DevicesList> {
timeout: const Duration(seconds: 10),
);
if (!context.mounted) {
return;
}
if (result.isOk()) {
context.go('/device/${device.deviceAddress}');
} else {
@ -193,13 +197,18 @@ class _DevicesListState extends ConsumerState<DevicesList> {
);
}
} catch (e) {
if (!context.mounted) {
return;
}
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Error: ${e.toString()}')),
);
} finally {
setState(() {
_connectingDeviceId = null;
});
if (context.mounted) {
setState(() {
_connectingDeviceId = null;
});
}
}
},
child: DeviceListItem(

View File

@ -1,50 +1,54 @@
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
class SettingsPage extends StatelessWidget {
const SettingsPage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Settings'),
leading: IconButton(
icon: const Icon(Icons.arrow_back),
onPressed: () => context.go('/'),
return ListView(
padding: const EdgeInsets.fromLTRB(20, 16, 20, 24),
children: [
Text(
'Settings',
style: Theme.of(context).textTheme.headlineMedium?.copyWith(
fontWeight: FontWeight.w700,
),
),
),
body: ListView(
children: [
ListTile(
leading: const Icon(Icons.brightness_6),
title: const Text('Theme'),
subtitle: const Text('Change app theme'),
trailing: const Icon(Icons.chevron_right),
onTap: () {
// Theme settings functionality
},
const SizedBox(height: 6),
Text(
'Theme, Bluetooth, and app details.',
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
color: Theme.of(context)
.colorScheme
.onSurface
.withValues(alpha: 0.68),
),
),
const SizedBox(height: 20),
Card(
child: Column(
children: const [
ListTile(
leading: Icon(Icons.brightness_6),
title: Text('Theme'),
subtitle: Text('Theme controls arrive in the next phase'),
),
Divider(height: 1),
ListTile(
leading: Icon(Icons.bluetooth),
title: Text('Bluetooth Settings'),
subtitle: Text('Configure Bluetooth connections'),
),
Divider(height: 1),
ListTile(
leading: Icon(Icons.info),
title: Text('About'),
subtitle: Text('App information'),
),
],
),
ListTile(
leading: const Icon(Icons.bluetooth),
title: const Text('Bluetooth Settings'),
subtitle: const Text('Configure Bluetooth connections'),
trailing: const Icon(Icons.chevron_right),
onTap: () {
// Bluetooth settings functionality
},
),
ListTile(
leading: const Icon(Icons.info),
title: const Text('About'),
subtitle: const Text('App information'),
trailing: const Icon(Icons.chevron_right),
onTap: () {
// About screen functionality
},
),
],
),
),
],
);
}
}