eagletracker/lib/deviceSelection.dart
2024-07-08 14:49:33 +02:00

369 lines
14 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter_blue_plus/flutter_blue_plus.dart';
import 'package:eagletracker/class/BLEProvider.dart';
import 'package:eagletracker/class/devicesSaved.dart' as DevicesSaved;
import 'package:eagletracker/class/preferenceSaved.dart' as PreferenceSaved;
import 'package:eagletracker/deviceAdvertizinScan.dart';
import 'package:eagletracker/deviceFlowMap.dart';
import 'package:provider/provider.dart';
class DeviceSelection extends StatefulWidget {
const DeviceSelection({super.key});
@override
State<DeviceSelection> createState() => _DeviceSelectionState();
}
class _DeviceSelectionState extends State<DeviceSelection> {
List<ScanResult> scanResults = [];
TextEditingController tecSearch = TextEditingController();
bool isScanning = false;
List<DevicesSaved.DevicesSaved> devicesSaved = [];
PreferenceSaved.PreferenceSaved preferenceSaved =
PreferenceSaved.PreferenceSaved.empty();
TextEditingController tecTimeTakingPointSecond = TextEditingController();
// Initialize Bluetooth scanning and subscription in initState
@override
void initState() {
super.initState();
isScanning = true;
PreferenceSaved.restoreLocal().then((value) {
setState(() {
preferenceSaved = value;
tecTimeTakingPointSecond.text =
preferenceSaved.timeTakingPointSecond.toString();
});
});
DevicesSaved.restoreLocal().then((value) {
setState(() {
devicesSaved = value;
});
});
FlutterBluePlus.isSupported.then((isSupported) {
if (!isSupported) {
showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: const Text("Bluetooth non activé"),
content: const Text(
"Le Bluetooth n'est pas activé sur cet appareil. Veillez l'activer pour continuer."),
actions: [
TextButton(
onPressed: () {
Navigator.of(context).pop();
},
child: const Text("OK"),
),
],
);
},
);
}
});
}
@override
Widget build(BuildContext context) {
final bleProvider = Provider.of<BLEProvider>(context);
scanResults = bleProvider.scanResults;
// Filtered list of devices
List<ScanResult> filteredDevices = scanResults
.where((result) => result.device.platformName
.toLowerCase()
.contains(tecSearch.text.toLowerCase()))
.toList();
//Saved devices list is connected ?
for (var element in devicesSaved) {
element.connected = scanResults
.where((result) => result.device.remoteId.str == element.remoteId)
.isNotEmpty;
}
return Scaffold(
appBar: AppBar(
actions: [
IconButton(
icon: const Icon(Icons.settings, color: Colors.white),
onPressed: () {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: const Text('Paramètres'),
content: SizedBox(
height: 100,
child: Column(children: [
const Text('Capture des points (secondes)'),
TextField(
controller: tecTimeTakingPointSecond,
keyboardType: TextInputType.number,
),
]),
),
actions: <Widget>[
TextButton(
onPressed: () {
Navigator.of(context).pop();
},
child: const Text('Annuler'),
),
TextButton(
onPressed: () {
Navigator.of(context).pop();
preferenceSaved.timeTakingPointSecond =
int.parse(tecTimeTakingPointSecond.text);
PreferenceSaved.saveLocal(preferenceSaved);
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('Paramètres enregistrés'),
),
);
},
child: const Text('Enregistrer'),
),
],
);
},
);
})
],
backgroundColor: Colors.blue,
title:
const Text("Eagle Tr@cker", style: TextStyle(color: Colors.white)),
),
body: Column(
children: [
devicesSaved.isNotEmpty
? Column(
children: [
const Padding(
padding: EdgeInsets.all(16.0),
child: Text('Appareils sauvegardés',
style: TextStyle(
fontSize: 18.0, fontWeight: FontWeight.bold)),
),
ListView.builder(
shrinkWrap: true,
itemCount: devicesSaved.length,
itemBuilder: (context, index) {
DevicesSaved.DevicesSaved device = devicesSaved[index];
return Container(
margin:
const EdgeInsets.only(left: 10, right: 10.0),
child: Card(
child: ListTile(
title: Row(children: [
Icon(Icons.circle,
color: devicesSaved[index].connected
? Colors.green
: Colors.orange,
size: 10.0),
Text(device.deviceName)
]),
subtitle: Text(device.deviceAddress),
trailing: Row(
mainAxisSize: MainAxisSize.min,
children: [
GestureDetector(
onTap: () async {
devicesSaved.removeAt(index);
await DevicesSaved.saveLocal(
devicesSaved);
setState(() {
devicesSaved = devicesSaved;
});
},
child: const Icon(Icons.delete)),
GestureDetector(
onTap: () {
if (checkIsScanning(
context, isScanning)) {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
DeviceAdvertizinScan(
deviceName:
device.deviceName,
deviceAddress:
device.deviceAddress,
remoteId: device.remoteId,
)),
);
}
},
child: const Icon(Icons.info_outline),
),
GestureDetector(
onTap: () {
if (checkIsScanning(
context, isScanning)) {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => DeviceFlowMap(
deviceName: device.deviceName,
deviceAddress:
device.deviceAddress,
),
),
);
}
},
child: const Icon(Icons.map_outlined),
),
],
),
)));
},
),
],
)
: Container(),
const Padding(
padding: EdgeInsets.all(16.0),
child: Text('Recherche d\' appareils BLE',
style: TextStyle(fontSize: 18.0, fontWeight: FontWeight.bold)),
),
Padding(
padding: const EdgeInsets.all(16.0),
child: TextFormField(
controller: tecSearch,
decoration: const InputDecoration(
hintText: 'Rechercher un appareil par nom',
prefixIcon: Icon(Icons.search),
),
onChanged: (value) {
setState(() {});
},
),
),
const SizedBox(height: 16.0),
Expanded(
child: ListView.builder(
itemCount: filteredDevices.length,
itemBuilder: (context, index) {
ScanResult result = filteredDevices[index];
return ListTile(
trailing: Row(
mainAxisSize: MainAxisSize.min,
children: [
GestureDetector(
onTap: () async {
if (devicesSaved
.where((element) =>
element.deviceAddress ==
result.device.remoteId.str)
.isNotEmpty) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content:
Text('Cet appareil est déjà sauvegardé'),
),
);
return;
}
devicesSaved.add(DevicesSaved.DevicesSaved(
deviceName: result.device.platformName,
deviceAddress: result.device.remoteId.str,
remoteId: result.device.remoteId.str,
));
await DevicesSaved.saveLocal(devicesSaved);
setState(() {
devicesSaved = devicesSaved;
});
;
},
child: const Icon(Icons.add),
),
GestureDetector(
onTap: () {
if (checkIsScanning(context, isScanning)) {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => DeviceAdvertizinScan(
deviceName: result.device.platformName,
deviceAddress: result.device.remoteId.str,
remoteId: result.device.remoteId.str,
),
),
);
}
},
child: const Icon(Icons.info_outline),
),
GestureDetector(
onTap: () {
if (checkIsScanning(context, isScanning)) {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => DeviceFlowMap(
deviceName: result.device.platformName,
deviceAddress: result.device.remoteId.str,
),
),
);
}
},
child: const Icon(Icons.map_outlined),
),
],
),
title: Row(children: [
const Icon(Icons.circle, color: Colors.green, size: 10.0),
Text(result.device.platformName)
]),
subtitle: Text(result.device.remoteId.str),
);
},
),
),
],
),
floatingActionButton: FloatingActionButton(
backgroundColor: Colors.blue,
onPressed: () {
setState(() {
isScanning = !isScanning;
if (isScanning) {
bleProvider.startScan();
} else {
bleProvider.stopScan();
}
});
},
child: Icon(isScanning ? Icons.stop : Icons.play_arrow,
color: Colors.white),
),
);
}
}
bool checkIsScanning(BuildContext context, bool isScanning) {
if (!isScanning) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('Vous devez activer le scan pour continuer'),
),
);
return false;
} else {
return true;
}
}