import 'package:abawo_bt_app/controller/bluetooth.dart'; import 'package:abawo_bt_app/database/database.dart'; import 'package:abawo_bt_app/model/bluetooth_device_model.dart'; import 'package:abawo_bt_app/widgets/device_listitem.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:go_router/go_router.dart'; class HomePage extends StatelessWidget { const HomePage({super.key}); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('Abawo BT App'), actions: [ IconButton( icon: const Icon(Icons.settings), onPressed: () => context.go('/settings'), ), ], ), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ const Text( 'Welcome to Abawo BT App', style: TextStyle(fontSize: 20), ), const SizedBox(height: 20), // Devices Section Container( padding: const EdgeInsets.only(left: 16, right: 16), child: Column( children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ const Text( 'Devices', style: TextStyle( fontSize: 20, fontWeight: FontWeight.w500), ), IconButton( icon: const Icon(Icons.add_circle), onPressed: () => context.go('/connect_device'), tooltip: 'Connect a device', ), ], ), const SizedBox(height: 10), Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration( border: Border.all(color: Colors.grey.shade300), borderRadius: BorderRadius.circular(8), ), child: const Center( child: DevicesList(), ), ), ], ), ), const SizedBox(height: 30), ElevatedButton( onPressed: () => context.go('/settings'), child: const Text('Go to Settings'), ), ], ), ), ); } } class DevicesList extends ConsumerStatefulWidget { const DevicesList({super.key}); @override ConsumerState createState() => _DevicesListState(); } class _DevicesListState extends ConsumerState { String? _connectingDeviceId; // ID of device currently being connected Future _removeDevice(ConnectedDevice device) async { final shouldRemove = await showDialog( context: context, builder: (dialogContext) => AlertDialog( title: const Text('Remove device?'), content: Text('Do you want to remove ${device.deviceName} from the app?'), actions: [ TextButton( onPressed: () => Navigator.of(dialogContext).pop(false), child: const Text('Cancel'), ), FilledButton( onPressed: () => Navigator.of(dialogContext).pop(true), child: const Text('Remove'), ), ], ), ); if (shouldRemove != true || !mounted) { return; } final result = await ref .read(nConnectedDevicesProvider.notifier) .deleteConnectedDevice(device.id); if (!mounted) { return; } if (result.isErr()) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text('Failed to remove device: ${result.unwrapErr()}')), ); return; } if (_connectingDeviceId == device.deviceAddress) { setState(() { _connectingDeviceId = null; }); } ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('${device.deviceName} removed from the app.')), ); } @override Widget build(BuildContext context) { final asyncDevices = ref.watch(nConnectedDevicesProvider); return asyncDevices.when( loading: () => const Center( child: CircularProgressIndicator(), ), error: (error, stackTrace) => Center( child: Text( 'Error loading devices: ${error.toString()}', style: TextStyle(color: Colors.red), textAlign: TextAlign.center, ), ), data: (devices) { if (devices.isEmpty) { return const Center( child: Text( 'No devices connected yet', style: TextStyle(color: Colors.grey), ), ); } return ListView.builder( itemCount: devices.length, shrinkWrap: true, itemBuilder: (context, index) { final device = devices[index]; return InkWell( onTap: () async { if (_connectingDeviceId != null) return; setState(() { _connectingDeviceId = device.deviceAddress; }); try { final controller = await ref.read(bluetoothProvider.future); final result = await controller.connectById( device.deviceAddress, timeout: const Duration(seconds: 10), ); if (result.isOk()) { context.go('/device/${device.deviceAddress}'); } else { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text( 'Connection failed. Is the device turned on and in range?'), duration: const Duration(seconds: 3), ), ); } } catch (e) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('Error: ${e.toString()}')), ); } finally { setState(() { _connectingDeviceId = null; }); } }, child: DeviceListItem( deviceName: device.deviceName, deviceId: device.deviceAddress, type: deviceTypeFromString(device.deviceType), isConnecting: device.deviceAddress == _connectingDeviceId, trailing: IconButton( tooltip: 'Remove device', icon: const Icon(Icons.delete_outline), onPressed: () => _removeDevice(device), ), ), ); }, ); }, ); } }