Responsive banner saying to wait for up to minute, as well as battery status.
This commit is contained in:
@@ -32,6 +32,8 @@ class _PeripheralScreenState extends State<PeripheralScreen> {
|
||||
double _blindPosition = 5.0;
|
||||
DateTime? lastSet;
|
||||
String lastSetMessage = "";
|
||||
int? batterySoc;
|
||||
bool _movementPending = false;
|
||||
|
||||
final _peripheralRenameController = TextEditingController();
|
||||
|
||||
@@ -130,6 +132,7 @@ class _PeripheralScreenState extends State<PeripheralScreen> {
|
||||
if (!mounted) return;
|
||||
final type = data['type'] as String? ?? '';
|
||||
final soc = data['soc'] as int? ?? 0;
|
||||
setState(() => batterySoc = soc);
|
||||
final (String message, Color color) = switch (type) {
|
||||
'overvoltage' => ('Battery fault detected. Please check your charger.', Colors.red),
|
||||
'critical_low' => ('Battery critically low ($soc%). Device shutting down.', Colors.red),
|
||||
@@ -169,6 +172,7 @@ class _PeripheralScreenState extends State<PeripheralScreen> {
|
||||
if (!mounted) return;
|
||||
setState(() {
|
||||
_blindPosition = (data['pos'] as int).toDouble();
|
||||
_movementPending = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -341,6 +345,20 @@ class _PeripheralScreenState extends State<PeripheralScreen> {
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> getDeviceBatterySoc() async {
|
||||
try {
|
||||
final payload = {'deviceId': widget.deviceId};
|
||||
final response = await secureGet('device_name', queryParameters: payload);
|
||||
if (response == null) throw Exception("auth error");
|
||||
if (response.statusCode != 200) throw Exception("Server Error");
|
||||
final body = json.decode(response.body);
|
||||
if (!mounted) return;
|
||||
setState(() => batterySoc = body['battery_soc'] as int?);
|
||||
} catch (e) {
|
||||
// Battery SOC is non-critical; swallow silently
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> checkDeviceConnection() async {
|
||||
try {
|
||||
final payload = {
|
||||
@@ -413,6 +431,7 @@ class _PeripheralScreenState extends State<PeripheralScreen> {
|
||||
getName();
|
||||
checkDeviceConnection();
|
||||
fetchState();
|
||||
getDeviceBatterySoc();
|
||||
}
|
||||
|
||||
void rename() {
|
||||
@@ -548,37 +567,50 @@ class _PeripheralScreenState extends State<PeripheralScreen> {
|
||||
),
|
||||
backgroundColor: Theme.of(context).primaryColorLight,
|
||||
foregroundColor: Colors.white,
|
||||
bottom: !deviceConnected ? PreferredSize(
|
||||
preferredSize: const Size.fromHeight(48.0),
|
||||
child: Container(
|
||||
width: double.infinity,
|
||||
padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 16),
|
||||
color: Colors.orange.shade700,
|
||||
child: Row(
|
||||
children: [
|
||||
const Icon(
|
||||
Icons.wifi_off,
|
||||
color: Colors.white,
|
||||
size: 20,
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
const Expanded(
|
||||
child: Text(
|
||||
'Device Disconnected',
|
||||
style: TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
actions: [
|
||||
if (batterySoc != null)
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||
child: Row(
|
||||
children: [
|
||||
Icon(
|
||||
batterySoc! <= 10 ? Icons.battery_alert
|
||||
: batterySoc! <= 20 ? Icons.battery_1_bar
|
||||
: batterySoc! <= 40 ? Icons.battery_2_bar
|
||||
: batterySoc! <= 60 ? Icons.battery_3_bar
|
||||
: batterySoc! <= 80 ? Icons.battery_5_bar
|
||||
: Icons.battery_full,
|
||||
color: batterySoc! <= 10 ? Colors.red : Colors.white,
|
||||
),
|
||||
),
|
||||
],
|
||||
const SizedBox(width: 4),
|
||||
Text('$batterySoc%', style: const TextStyle(color: Colors.white)),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
) : null,
|
||||
],
|
||||
),
|
||||
|
||||
body: loaded
|
||||
body: Column(
|
||||
children: [
|
||||
if (_movementPending)
|
||||
Container(
|
||||
width: double.infinity,
|
||||
padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 16),
|
||||
color: Colors.orange.shade700,
|
||||
child: Row(
|
||||
children: [
|
||||
const Icon(Icons.access_time, color: Colors.white, size: 20),
|
||||
const SizedBox(width: 12),
|
||||
const Expanded(
|
||||
child: Text(
|
||||
'Movement pending... Will take up to 1 minute',
|
||||
style: TextStyle(color: Colors.white, fontSize: 14, fontWeight: FontWeight.w500),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Expanded(child: loaded
|
||||
? (calibrating
|
||||
? RefreshIndicator(
|
||||
onRefresh: initAll,
|
||||
@@ -666,8 +698,9 @@ class _PeripheralScreenState extends State<PeripheralScreen> {
|
||||
onPositionChanged: (value) {
|
||||
setState(() {
|
||||
_blindPosition = value;
|
||||
updateBlindPosition();
|
||||
_movementPending = true;
|
||||
});
|
||||
updateBlindPosition();
|
||||
},
|
||||
),
|
||||
Container(
|
||||
@@ -718,7 +751,9 @@ class _PeripheralScreenState extends State<PeripheralScreen> {
|
||||
)
|
||||
)
|
||||
)))
|
||||
: BlindmasterProgressIndicator(),
|
||||
: BlindmasterProgressIndicator()),
|
||||
],
|
||||
),
|
||||
floatingActionButton: Container(
|
||||
padding: EdgeInsets.all(25),
|
||||
child: Row(
|
||||
|
||||
Reference in New Issue
Block a user