@@ -149,6 +149,10 @@ class AppStateProvider extends ChangeNotifier {
149149 List <File > _debugLogFiles = [];
150150 String ? _viewingLogContent;
151151
152+ // Last connected device info (persistent, for bug reports)
153+ String ? _lastConnectedDeviceName;
154+ String ? _lastConnectedPublicKey;
155+
152156 // Zone state for geo-auth
153157 bool ? _inZone; // null = not checked yet, true/false = checked
154158 Map <String , dynamic >? _currentZone; // Zone info when inZone == true
@@ -226,6 +230,10 @@ class AppStateProvider extends ChangeNotifier {
226230 List <File > get debugLogFiles => List .unmodifiable (_debugLogFiles);
227231 String ? get viewingLogContent => _viewingLogContent;
228232
233+ // Last connected device info getters (persistent, for bug reports)
234+ String ? get lastConnectedDeviceName => _lastConnectedDeviceName;
235+ String ? get lastConnectedPublicKey => _lastConnectedPublicKey;
236+
229237 // Zone state getters
230238 bool ? get inZone => _inZone;
231239 Map <String , dynamic >? get currentZone => _currentZone;
@@ -366,6 +374,9 @@ class AppStateProvider extends ChangeNotifier {
366374 // Load user preferences
367375 await _loadPreferences ();
368376
377+ // Load last connected device info (for bug reports)
378+ await _loadLastConnectedDevice ();
379+
369380 // Set device ID for API
370381 _apiService.setDeviceId (_deviceId);
371382
@@ -609,6 +620,18 @@ class AppStateProvider extends ChangeNotifier {
609620 _deviceModel = _meshCoreConnection! .deviceModel;
610621 _devicePublicKey = _meshCoreConnection! .devicePublicKey;
611622 debugLog ('[APP] Device public key stored: ${_devicePublicKey ?.substring (0 , 16 ) ?? 'null' }...' );
623+
624+ // Persist device info for bug reports when disconnected
625+ // Use companion name (selfInfo.name) or BLE device name with MeshCore- prefix stripped
626+ var deviceName = _meshCoreConnection! .selfInfo? .name ??
627+ connectedDeviceName;
628+ if (deviceName != null ) {
629+ // Always strip MeshCore- prefix if present
630+ deviceName = deviceName.replaceFirst ('MeshCore-' , '' );
631+ }
632+ if (deviceName != null && deviceName.isNotEmpty && _devicePublicKey != null ) {
633+ _saveLastConnectedDevice (deviceName, _devicePublicKey! );
634+ }
612635 }
613636 notifyListeners ();
614637 });
@@ -2132,6 +2155,34 @@ class AppStateProvider extends ChangeNotifier {
21322155 }
21332156 }
21342157
2158+ /// Prepare debug logs for upload by rotating the current log file
2159+ ///
2160+ /// This ensures the files being uploaded are complete and not actively being written to.
2161+ /// Returns the list of files that are safe to upload (excludes the new current log).
2162+ Future <List <File >> prepareDebugLogsForUpload () async {
2163+ try {
2164+ // Rotate the current log file if logging is enabled
2165+ if (_debugLogsEnabled) {
2166+ debugLog ('[DEBUG] Rotating log file for upload...' );
2167+ await DebugFileLogger .rotateLogFile ();
2168+ }
2169+
2170+ // Get uploadable files (excludes current log file)
2171+ final files = await DebugFileLogger .listUploadableLogFiles ();
2172+ debugLog ('[DEBUG] Found ${files .length } log files available for upload' );
2173+
2174+ // Also refresh the main list
2175+ _debugLogFiles = await DebugFileLogger .listLogFiles ();
2176+ notifyListeners ();
2177+
2178+ return files;
2179+ } catch (e) {
2180+ debugError ('[DEBUG] Failed to prepare debug logs for upload: $e ' );
2181+ // Fall back to returning all files
2182+ return await DebugFileLogger .listLogFiles ();
2183+ }
2184+ }
2185+
21352186 /// Delete all debug log files
21362187 ///
21372188 /// Disables logging if active, then deletes all log files.
@@ -2398,6 +2449,38 @@ class AppStateProvider extends ChangeNotifier {
23982449 }
23992450 }
24002451
2452+ // ============================================
2453+ // Last Connected Device Persistence
2454+ // ============================================
2455+
2456+ /// Load last connected device info from Hive storage
2457+ Future <void > _loadLastConnectedDevice () async {
2458+ try {
2459+ final box = await Hive .openBox (_preferencesBoxName);
2460+ _lastConnectedDeviceName = box.get ('last_connected_device_name' ) as String ? ;
2461+ _lastConnectedPublicKey = box.get ('last_connected_public_key' ) as String ? ;
2462+ if (_lastConnectedDeviceName != null ) {
2463+ debugLog ('[APP] Loaded last connected device: $_lastConnectedDeviceName ' );
2464+ }
2465+ } catch (e) {
2466+ debugLog ('[APP] Failed to load last connected device: $e ' );
2467+ }
2468+ }
2469+
2470+ /// Save last connected device info to Hive storage
2471+ Future <void > _saveLastConnectedDevice (String deviceName, String publicKey) async {
2472+ try {
2473+ final box = await Hive .openBox (_preferencesBoxName);
2474+ await box.put ('last_connected_device_name' , deviceName);
2475+ await box.put ('last_connected_public_key' , publicKey);
2476+ _lastConnectedDeviceName = deviceName;
2477+ _lastConnectedPublicKey = publicKey;
2478+ debugLog ('[APP] Saved last connected device: $deviceName ' );
2479+ } catch (e) {
2480+ debugLog ('[APP] Failed to save last connected device: $e ' );
2481+ }
2482+ }
2483+
24012484 // ============================================
24022485 // Cleanup
24032486 // ============================================
0 commit comments