a bunch of flutter updates
This commit is contained in:
@@ -1,137 +1 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import '../../core/services/voice_command_handler.dart';
|
||||
import '../../core/services/stt_service.dart';
|
||||
import '../../core/services/tts_service.dart';
|
||||
import '../../injection_container.dart';
|
||||
|
||||
class UserShell extends StatefulWidget {
|
||||
final Widget child;
|
||||
const UserShell({super.key, required this.child});
|
||||
@override
|
||||
State<UserShell> createState() => _UserShellState();
|
||||
}
|
||||
|
||||
class _UserShellState extends State<UserShell> {
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_startVoiceListening();
|
||||
_setupVoiceCommands();
|
||||
}
|
||||
|
||||
void _startVoiceListening() {
|
||||
sl<SttService>().startListening();
|
||||
}
|
||||
|
||||
void _setupVoiceCommands() {
|
||||
sl<VoiceCommandHandler>().onCommand = (key) {
|
||||
if (!mounted) return;
|
||||
switch (key) {
|
||||
case VoiceCommandKey.openWalkguide:
|
||||
context.go('/user/walkguide');
|
||||
sl<TtsService>().speak('Walkguide menu opened');
|
||||
break;
|
||||
case VoiceCommandKey.openNotification:
|
||||
context.go('/user/notifications');
|
||||
sl<TtsService>().speak('Notifications opened');
|
||||
break;
|
||||
case VoiceCommandKey.openSos:
|
||||
context.go('/user/sos');
|
||||
sl<TtsService>().speak('SOS menu opened');
|
||||
break;
|
||||
case VoiceCommandKey.openActivity:
|
||||
context.go('/user/activity');
|
||||
sl<TtsService>().speak('Activity log opened');
|
||||
break;
|
||||
case VoiceCommandKey.openNavigation:
|
||||
context.go('/user/navigation');
|
||||
sl<TtsService>().speak('Navigation mode opened');
|
||||
break;
|
||||
case VoiceCommandKey.openSettings:
|
||||
context.go('/user/settings');
|
||||
sl<TtsService>().speak('Settings opened');
|
||||
break;
|
||||
case VoiceCommandKey.callGuardian:
|
||||
context.go('/user/call');
|
||||
break;
|
||||
case VoiceCommandKey.sendSos:
|
||||
case VoiceCommandKey.whereAmI:
|
||||
case VoiceCommandKey.startWalkguide:
|
||||
case VoiceCommandKey.stopWalkguide:
|
||||
case VoiceCommandKey.readAllNotif:
|
||||
// These are handled by individual screens
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
int _tabFromLocation(String location) {
|
||||
if (location.startsWith('/user/walkguide')) return 0;
|
||||
if (location.startsWith('/user/sos')) return 1;
|
||||
if (location.startsWith('/user/activity')) return 2;
|
||||
if (location.startsWith('/user/notifications')) return 3;
|
||||
if (location.startsWith('/user/navigation')) return 4;
|
||||
return 5;
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final location = GoRouterState.of(context).matchedLocation;
|
||||
final currentTab = _tabFromLocation(location);
|
||||
|
||||
// Hide bottom nav during full-screen screens
|
||||
final hideNav = location.startsWith('/user/call') || location.startsWith('/user/pairing');
|
||||
|
||||
return Scaffold(
|
||||
body: widget.child,
|
||||
bottomNavigationBar: hideNav ? null : Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
boxShadow: [BoxShadow(color: Colors.black.withOpacity(0.08), blurRadius: 20, offset: const Offset(0, -4))],
|
||||
),
|
||||
child: SafeArea(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 8),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
children: [
|
||||
_navItem(context, 0, currentTab, Icons.remove_red_eye_outlined, Icons.remove_red_eye, 'Guide', '/user/walkguide'),
|
||||
_navItem(context, 1, currentTab, Icons.warning_amber_outlined, Icons.warning_amber, 'SOS', '/user/sos'),
|
||||
_navItem(context, 2, currentTab, Icons.list_alt_outlined, Icons.list_alt, 'Activity', '/user/activity'),
|
||||
_navItem(context, 3, currentTab, Icons.notifications_outlined, Icons.notifications, 'Notif', '/user/notifications'),
|
||||
_navItem(context, 4, currentTab, Icons.map_outlined, Icons.map, 'Navigate', '/user/navigation'),
|
||||
_navItem(context, 5, currentTab, Icons.settings_outlined, Icons.settings, 'Settings', '/user/settings'),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _navItem(BuildContext ctx, int idx, int current, IconData icon, IconData activeIcon, String label, String route) {
|
||||
final active = idx == current;
|
||||
return GestureDetector(
|
||||
onTap: () => ctx.go(route),
|
||||
child: AnimatedContainer(
|
||||
duration: const Duration(milliseconds: 200),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
|
||||
decoration: BoxDecoration(
|
||||
color: active ? const Color(0xFFEFF6FF) : Colors.transparent,
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
child: Column(mainAxisSize: MainAxisSize.min, children: [
|
||||
Icon(active ? activeIcon : icon, size: 22, color: active ? const Color(0xFF1A56DB) : const Color(0xFF94A3B8)),
|
||||
const SizedBox(height: 3),
|
||||
Text(label, style: GoogleFonts.inter(fontSize: 10, fontWeight: active ? FontWeight.w600 : FontWeight.w400,
|
||||
color: active ? const Color(0xFF1A56DB) : const Color(0xFF94A3B8))),
|
||||
]),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
export '../screens.dart';
|
||||
|
||||
Reference in New Issue
Block a user