Refactor USB screen, add debug logging, fix UI issues

- Rewrite UsbScreen to mirror ScannerScreen patterns (status bar,
  tap-to-connect port list, bottom FABs, SnackBar errors)
- Extract MeshCoreUsbManager from MeshCoreConnector for cleaner
  USB transport ownership
- Add debug logging throughout USB connection flow (connector,
  manager, web/native services)
- Print debug logs to console in debug mode even when app debug
  log setting is disabled
- Localize remaining hardcoded strings (Web Serial Device fallback
  label, USB status bar keys, companion firmware timeout hint)
- Fix Swedish misspelling in translations (stöderliga → stödda)
- Guard Linux notification init against missing D-Bus session bus
- Fix SNRIndicator hit-test error by adding minimum size constraints
- Update USB flow tests for new UI patterns
This commit is contained in:
zjs81
2026-03-07 12:38:28 -07:00
parent 8238b6197f
commit fef73b7b62
42 changed files with 981 additions and 553 deletions
+21
View File
@@ -1,9 +1,11 @@
import 'dart:io' show Platform, File;
import 'dart:ui';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:flutter/foundation.dart';
import '../l10n/app_localizations.dart';
import '../utils/platform_info.dart';
class NotificationService {
static final NotificationService _instance = NotificationService._internal();
@@ -75,6 +77,15 @@ class NotificationService {
linux: linuxSettings,
);
// On Linux, the notifications plugin opens a D-Bus session bus
// connection whose async subscription can throw an unhandled
// SocketException when the bus socket is missing (e.g. running as
// root or inside a container without a session bus).
if (PlatformInfo.isLinux && !_isDbusSessionAvailable()) {
debugPrint('Skipping notification init: D-Bus session bus unavailable');
return;
}
try {
await _notifications.initialize(
settings: initSettings,
@@ -86,6 +97,16 @@ class NotificationService {
}
}
static bool _isDbusSessionAvailable() {
final addr = Platform.environment['DBUS_SESSION_BUS_ADDRESS'];
if (addr != null && addr.isNotEmpty) return true;
// Fallback: check the default socket for the current user.
final uid = Platform.environment['UID'] ??
Platform.environment['EUID'];
final path = '/run/user/${uid ?? '1000'}/bus';
return File(path).existsSync();
}
Future<bool> _ensureInitialized() async {
if (!_isInitialized) {
await initialize();