import 'dart:async'; import 'package:flutter/material.dart'; import 'package:ju_rc_app/lib/serial.dart'; // ignore: must_be_immutable class ConnectionBar extends StatefulWidget { USerial serial = getSerial(); ConnectionBar({super.key}); @override // ignore: library_private_types_in_public_api _ConnectionBarState createState() => _ConnectionBarState(); } class _ConnectionBarState extends State { late Timer timer; String _status = ""; List _ports = []; StateSetter? sheetsetstate; UPort? connectedTo; _ConnectionBarState() { timer = Timer.periodic(const Duration(seconds: 1), (_) async { if (sheetsetstate == null) return; var ports = await widget.serial.getPorts(); setState(() { _ports = ports; }); }); } @override void dispose() { timer.cancel(); super.dispose(); } @override void setState(VoidCallback fn) { super.setState(fn); try { if (sheetsetstate != null) (sheetsetstate!)(() {}); } catch (_) {} } void showModal() async { if (connectedTo != null && connectedTo!.connected) { await widget.serial.disconnect(); setState(() { connectedTo = null; }); } else { var ports = await widget.serial.getPorts(); setState(() { _ports = ports; _status = ""; }); // ignore: use_build_context_synchronously showModalBottomSheet( context: context, builder: (context) => StatefulBuilder( builder: (BuildContext context, StateSetter setStateM) { sheetsetstate = setStateM; return BottomSheet( enableDrag: false, builder: (context) => Column(children: [ Padding( padding: const EdgeInsets.all(8), child: Column(children: [ const Text("Devices", style: TextStyle( fontSize: 20.0, fontWeight: FontWeight.bold, )), Text(_status, style: const TextStyle( fontSize: 10.0, fontWeight: FontWeight.bold, )) ])), ..._ports.map((port) => ListTile( leading: const Icon(Icons.usb), title: Text(port.productName), subtitle: Text(port.manufacturerName), trailing: ElevatedButton( child: Text(port.connected ? "Disconnect" : "Connect"), onPressed: () async { if (port.connected) { await widget.serial.disconnect(); setState(() { connectedTo = null; _status = "Successfully disconnected!"; }); } else { if (await widget.serial.connect(port)) { setState(() { connectedTo = port; _status = "Successfully connected!"; }); } else { setState(() { _status = "Error while connecting!"; }); } } var ports = await widget.serial.getPorts(); setState(() { _ports = ports; }); }, ))) ]), onClosing: () { sheetsetstate = null; }, ); })); } } @override Widget build(BuildContext context) { return ListTile( leading: const Icon(Icons.usb), title: Text(connectedTo != null && connectedTo!.connected ? connectedTo!.productName : "Not connected"), subtitle: Text(connectedTo != null && connectedTo!.connected ? connectedTo!.manufacturerName : "Click 'connect'"), trailing: ElevatedButton( onPressed: () { setState(() { showModal(); }); }, child: Text(connectedTo != null && connectedTo!.connected ? "Disconnect" : "Connect"), )); } }