Client reported crashes, wrong/frozen data and that the app floods the adapter MCU. See docs/FIX_2026-10-12.md for the full analysis. - Poller: strictly one request outstanding; next request only after a valid 128-byte reply or a 500 ms timeout, then a quiet period + buffer flush. Default 100 ms (10 Hz), minimum 80 ms. DTC clear/probe share the same lock. - BtNotifier: filter the adapter's default (no-ECU-data) frame instead of holding last values; EcuDataStatus + status banner; auto-reconnect on link loss, stalls or long default-only runs (rate-limited). A reconnect still in flight when the user disconnects is discarded. - S300 offsets corrected by column counting (trims, PA, ERR00-03, Eth, SW5, AF); INJ/AIN little-endian; fan = SW5 FANC only. Default-frame detection requires bytes 0-16 and 32-36. - KPro RPM/MAP2/AIN little-endian (RPM still needs a bench check). - Crash hardening: zone/Flutter/platform error handlers to an in-app log (copyable from Debug); permissions requested before listing devices. - Remove temporary debug prints; graph redraws live; polling options 100-300 ms, persisted. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
41 lines
1.4 KiB
Dart
41 lines
1.4 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
import '../../core/providers/bt_provider.dart';
|
|
|
|
class BtStatusChip extends ConsumerWidget {
|
|
const BtStatusChip({super.key});
|
|
|
|
@override
|
|
Widget build(BuildContext context, WidgetRef ref) {
|
|
final status = ref.watch(btProvider.select((s) => s.status));
|
|
final name = ref.watch(btProvider.select((s) => s.deviceName));
|
|
|
|
final (color, icon, label) = switch (status) {
|
|
BtStatus.connected => (Colors.green, Icons.bluetooth_connected, name ?? 'Connected'),
|
|
BtStatus.connecting => (Colors.orange, Icons.bluetooth_searching, 'Connecting…'),
|
|
BtStatus.reconnecting => (Colors.orange, Icons.bluetooth_searching, 'Reconnecting…'),
|
|
BtStatus.error => (Colors.red, Icons.bluetooth_disabled, 'Error'),
|
|
BtStatus.disconnected => (Colors.grey, Icons.bluetooth, 'Disconnected'),
|
|
};
|
|
|
|
return Padding(
|
|
padding: const EdgeInsets.only(right: 8),
|
|
child: Row(
|
|
mainAxisSize: MainAxisSize.min,
|
|
children: [
|
|
Icon(icon, size: 14, color: color),
|
|
const SizedBox(width: 4),
|
|
Text(
|
|
label,
|
|
style: TextStyle(
|
|
color: color,
|
|
fontSize: 11,
|
|
fontWeight: FontWeight.w600,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
}
|