Merge pull request #45 from mtlynch/flutter-analyze

Fix issues flagged by flutter analyze
This commit is contained in:
zjs81 2026-01-17 11:38:08 -07:00 committed by GitHub
commit 06fc08c41f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 65 additions and 22 deletions

23
.github/workflows/flutter_analyze.yml vendored Normal file
View file

@ -0,0 +1,23 @@
name: Flutter Analyze
on:
pull_request:
push:
jobs:
analyze:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up Flutter
uses: subosito/flutter-action@v2
with:
channel: stable
- name: Install dependencies
run: flutter pub get
- name: Analyze
run: flutter analyze --fatal-infos --fatal-warnings

View file

@ -1766,7 +1766,7 @@ class MeshCoreConnector extends ChangeNotifier {
_batteryMillivolts = readUint16LE(frame, 1);
final volts = (_batteryMillivolts! / 1000.0).toStringAsFixed(2);
_appDebugLogService?.info(
'Pulled battery: $volts V (${_batteryMillivolts} mV)',
'Pulled battery: $volts V ($_batteryMillivolts mV)',
tag: 'Battery',
);
notifyListeners();
@ -2272,7 +2272,6 @@ class MeshCoreConnector extends ChangeNotifier {
// [6-9] = estimated_timeout_ms (uint32)
if (frame.length >= 10) {
final isFlood = frame[1] != 0;
final ackHash = Uint8List.fromList(frame.sublist(2, 6));
final timeoutMs = readUint32LE(frame, 6);
@ -2618,7 +2617,7 @@ class MeshCoreConnector extends ChangeNotifier {
final keyLen = psk.length < 16 ? psk.length : 16;
key16.setRange(0, keyLen, psk);
final cipher = ECBBlockCipher(AESFastEngine());
final cipher = ECBBlockCipher(AESEngine());
cipher.init(false, KeyParameter(key16));
final out = Uint8List(cipherText.length);
for (var i = 0; i < cipherText.length; i += 16) {
@ -2992,7 +2991,6 @@ const int _phVerMask = 0x03;
const int _routeTransportFlood = 0x00;
const int _routeFlood = 0x01;
const int _routeDirect = 0x02;
const int _routeTransportDirect = 0x03;
const int _payloadTypeGroupText = 0x05;

View file

@ -27,7 +27,7 @@ void main() async {
final storage = StorageService();
final connector = MeshCoreConnector();
final pathHistoryService = PathHistoryService(storage);
final retryService = MessageRetryService(storage);
final retryService = MessageRetryService();
final appSettingsService = AppSettingsService();
final bleDebugLogService = BleDebugLogService();
final appDebugLogService = AppDebugLogService();

View file

@ -388,8 +388,9 @@ class _MapScreenState extends State<MapScreen> {
if (!contact.hasLocation) continue;
// Apply node type filters
if (contact.type == advTypeRepeater && !settings.mapShowRepeaters)
if (contact.type == advTypeRepeater && !settings.mapShowRepeaters) {
continue;
}
if (contact.type == advTypeChat && !settings.mapShowChatNodes) continue;
if (contact.type != advTypeChat &&
contact.type != advTypeRepeater &&

View file

@ -895,7 +895,7 @@ class _RepeaterSettingsScreenState extends State<RepeaterSettingsScreen> {
),
const SizedBox(height: 16),
DropdownButtonFormField<int>(
value: _bandwidth,
initialValue: _bandwidth,
decoration: InputDecoration(
labelText: l10n.repeater_bandwidth,
border: const OutlineInputBorder(),
@ -917,7 +917,7 @@ class _RepeaterSettingsScreenState extends State<RepeaterSettingsScreen> {
),
const SizedBox(height: 16),
DropdownButtonFormField<int>(
value: _spreadingFactor,
initialValue: _spreadingFactor,
decoration: InputDecoration(
labelText: l10n.repeater_spreadingFactor,
border: const OutlineInputBorder(),
@ -939,7 +939,7 @@ class _RepeaterSettingsScreenState extends State<RepeaterSettingsScreen> {
),
const SizedBox(height: 16),
DropdownButtonFormField<int>(
value: _codingRate,
initialValue: _codingRate,
decoration: InputDecoration(
labelText: l10n.repeater_codingRate,
border: const OutlineInputBorder(),

View file

@ -1,7 +1,4 @@
import 'dart:async';
import 'dart:convert';
import 'dart:math';
import 'dart:typed_data';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
@ -34,7 +31,6 @@ class _TelemetryScreenState extends State<TelemetryScreen> {
static const int _statusResponseBytes =
_statusPayloadOffset + _statusStatsSize;
Uint8List _tagData = Uint8List(4);
int _timeEstment = 0;
bool _isLoading = false;
bool _isLoaded = false;
@ -64,18 +60,19 @@ class _TelemetryScreenState extends State<TelemetryScreen> {
if (frame[0] == respCodeSent) {
_tagData = frame.sublist(2, 6);
_timeEstment = frame.buffer.asByteData().getUint32(6, Endian.little);
}
// Check if it's a binary response
if (frame[0] == pushCodeBinaryResponse &&
listEquals(frame.sublist(2, 6), _tagData)) {
_handleStatusResponse(context, frame.sublist(6));
if (!mounted) return;
_handleStatusResponse(frame.sublist(6));
}
});
}
void _handleStatusResponse(BuildContext context, Uint8List frame) {
void _handleStatusResponse(Uint8List frame) {
if (!mounted) return;
setState(() {
_parsedTelemetry = CayenneLpp.parseByChannel(frame);
});

View file

@ -86,14 +86,26 @@ class BleDebugLogService extends ChangeNotifier {
}
String _describeFrame(int code, Uint8List frame, bool outgoing, String? note) {
final label = _codeLabel(code);
final label = _codeLabel(code, outgoing: outgoing);
final prefix = outgoing ? 'TX' : 'RX';
final extra = _frameDetail(code, frame);
final noteText = note != null ? '$note' : '';
return '$prefix $label$extra$noteText';
}
String _codeLabel(int code) {
String _codeLabel(int code, {required bool outgoing}) {
if (outgoing) {
return _commandLabel(code) ?? 'CODE_$code';
}
final pushLabel = _pushLabel(code);
if (pushLabel != null) return pushLabel;
final responseLabel = _responseLabel(code);
if (responseLabel != null) return responseLabel;
return 'CODE_$code';
}
String? _commandLabel(int code) {
switch (code) {
case cmdAppStart:
return 'CMD_APP_START';
@ -135,6 +147,13 @@ class BleDebugLogService extends ChangeNotifier {
return 'CMD_SET_CHANNEL';
case cmdGetRadioSettings:
return 'CMD_GET_RADIO_SETTINGS';
default:
return null;
}
}
String? _responseLabel(int code) {
switch (code) {
case respCodeOk:
return 'RESP_CODE_OK';
case respCodeErr:
@ -167,6 +186,13 @@ class BleDebugLogService extends ChangeNotifier {
return 'RESP_CODE_CHANNEL_INFO';
case respCodeRadioSettings:
return 'RESP_CODE_RADIO_SETTINGS';
default:
return null;
}
}
String? _pushLabel(int code) {
switch (code) {
case pushCodeAdvert:
return 'PUSH_CODE_ADVERT';
case pushCodePathUpdated:
@ -184,7 +210,7 @@ class BleDebugLogService extends ChangeNotifier {
case pushCodeNewAdvert:
return 'PUSH_CODE_NEW_ADVERT';
default:
return 'CODE_$code';
return null;
}
}

View file

@ -6,7 +6,6 @@ import 'package:crypto/crypto.dart';
import '../models/contact.dart';
import '../models/message.dart';
import '../models/path_selection.dart';
import 'storage_service.dart';
import 'app_settings_service.dart';
import 'app_debug_log_service.dart';
@ -36,7 +35,6 @@ class MessageRetryService extends ChangeNotifier {
static const int maxRetries = 5;
static const int maxAckHistorySize = 100;
final StorageService _storage;
final Map<String, Timer> _timeoutTimers = {};
final Map<String, Message> _pendingMessages = {};
final Map<String, Contact> _pendingContacts = {};
@ -59,7 +57,7 @@ class MessageRetryService extends ChangeNotifier {
AppDebugLogService? _debugLogService;
Function(String, PathSelection, bool, int?)? _recordPathResultCallback;
MessageRetryService(this._storage);
MessageRetryService();
void initialize({
required Function(Contact, String, int, int) sendMessageCallback,