feat: recover bootloader OTA transfers

This commit is contained in:
2026-04-29 19:59:11 +02:00
parent 16365e1d04
commit dc1f53b6e1
3 changed files with 445 additions and 111 deletions

View File

@ -497,10 +497,6 @@ class _DeviceDetailsPageState extends ConsumerState<DeviceDetailsPage> {
}
Future<FirmwareUpdateService?> _ensureFirmwareUpdateService() async {
final shifter = _shifterService;
if (shifter == null) {
return null;
}
if (_firmwareUpdateService != null) {
return _firmwareUpdateService;
}
@ -513,7 +509,7 @@ class _DeviceDetailsPageState extends ConsumerState<DeviceDetailsPage> {
final service = FirmwareUpdateService(
transport: ShifterFirmwareUpdateTransport(
shifterService: shifter,
shifterService: _shifterService,
bluetoothController: bluetooth,
buttonDeviceId: widget.deviceAddress,
),
@ -585,7 +581,6 @@ class _DeviceDetailsPageState extends ConsumerState<DeviceDetailsPage> {
return;
}
await _startStatusStreamingIfNeeded();
final updater = await _ensureFirmwareUpdateService();
if (!mounted) {
return;
@ -872,9 +867,10 @@ class _DeviceDetailsPageState extends ConsumerState<DeviceDetailsPage> {
currentConnectionStatus == ConnectionStatus.connected;
final hasDeviceAccess =
isCurrentConnected && _shifterService != null && _latestStatus != null;
final canUseFirmwareUpdate = isCurrentConnected;
final canSelectFirmware =
hasDeviceAccess && !_isSelectingFirmware && !_isFirmwareUpdateBusy;
final canStartFirmware = hasDeviceAccess &&
canUseFirmwareUpdate && !_isSelectingFirmware && !_isFirmwareUpdateBusy;
final canStartFirmware = canUseFirmwareUpdate &&
!_isSelectingFirmware &&
!_isFirmwareUpdateBusy &&
_selectedFirmware != null;
@ -907,8 +903,26 @@ class _DeviceDetailsPageState extends ConsumerState<DeviceDetailsPage> {
status: _latestStatus,
),
const SizedBox(height: 20),
if (hasDeviceAccess) ...[
if (canUseFirmwareUpdate) ...[
_FirmwareUpdateCard(
selectedFirmware: _selectedFirmware,
progress: _dfuProgress,
isSelecting: _isSelectingFirmware,
isStarting: _isStartingFirmwareUpdate,
canSelect: canSelectFirmware,
canStart: canStartFirmware,
phaseText: _dfuPhaseText(_dfuProgress.state),
statusText: _firmwareUserMessage,
formattedProgressBytes:
'${_formatBytes(_dfuProgress.sentBytes)} / ${_formatBytes(_dfuProgress.totalBytes)}',
onSelectFirmware: _selectFirmwareFile,
onStartUpdate: _startFirmwareUpdate,
expectedOffsetHex:
'0x${_dfuProgress.expectedOffset.toRadixString(16).padLeft(8, '0').toUpperCase()}',
),
const SizedBox(height: 16),
],
if (hasDeviceAccess) ...[
_StatusBanner(
status: _latestStatus,
onTap: _showStatusHistory,
@ -1009,23 +1023,6 @@ class _DeviceDetailsPageState extends ConsumerState<DeviceDetailsPage> {
),
),
),
const SizedBox(height: 16),
_FirmwareUpdateCard(
selectedFirmware: _selectedFirmware,
progress: _dfuProgress,
isSelecting: _isSelectingFirmware,
isStarting: _isStartingFirmwareUpdate,
canSelect: canSelectFirmware,
canStart: canStartFirmware,
phaseText: _dfuPhaseText(_dfuProgress.state),
statusText: _firmwareUserMessage,
formattedProgressBytes:
'${_formatBytes(_dfuProgress.sentBytes)} / ${_formatBytes(_dfuProgress.totalBytes)}',
onSelectFirmware: _selectFirmwareFile,
onStartUpdate: _startFirmwareUpdate,
expectedOffsetHex:
'0x${_dfuProgress.expectedOffset.toRadixString(16).padLeft(8, '0').toUpperCase()}',
),
] else if (isCurrentConnected) ...[
_PairingRequiredCard(
isChecking: _isPairingCheckRunning,