diff --git a/lib/screens/ble_debug_log_screen.dart b/lib/screens/ble_debug_log_screen.dart index 6d18697..81c4602 100644 --- a/lib/screens/ble_debug_log_screen.dart +++ b/lib/screens/ble_debug_log_screen.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:flutter/foundation.dart'; import 'package:provider/provider.dart'; import 'package:flutter/services.dart'; import '../l10n/l10n.dart'; @@ -6,6 +7,9 @@ import '../services/ble_debug_log_service.dart'; import '../connector/meshcore_protocol.dart'; import '../widgets/adaptive_app_bar_title.dart'; import '../helpers/snack_bar_builder.dart'; +import 'package:share_plus/share_plus.dart'; +import 'package:url_launcher/url_launcher.dart'; +import '../services/file_log_service.dart'; enum _BleLogView { frames, rawLogRx } @@ -29,10 +33,18 @@ class _BleDebugLogScreenState extends State { final hasEntries = showingFrames ? entries.isNotEmpty : rawEntries.isNotEmpty; + final isMobile = + defaultTargetPlatform == TargetPlatform.android || + defaultTargetPlatform == TargetPlatform.iOS; return Scaffold( appBar: AppBar( title: AdaptiveAppBarTitle(context.l10n.debugLog_bleTitle), actions: [ + IconButton( + tooltip: isMobile ? 'Share logs' : 'Open logs folder', + icon: Icon(isMobile ? Icons.ios_share : Icons.folder_open), + onPressed: () => _exportLogs(context), + ), IconButton( tooltip: context.l10n.debugLog_copyLog, icon: const Icon(Icons.copy), @@ -160,6 +172,36 @@ class _BleDebugLogScreenState extends State { ); } + /// Export the on-disk log (#97): the system share sheet on mobile, or open the + /// logs folder in the file manager on desktop. The file holds both the app log + /// and BLE frames, flushed first so it's current. + Future _exportLogs(BuildContext context) async { + final messenger = ScaffoldMessenger.of(context); + final file = await FileLogService.instance.flushAndGetActiveFile(); + if (file == null) { + messenger.showSnackBar( + const SnackBar( + content: Text('File logging is unavailable on this platform'), + ), + ); + return; + } + final isMobile = + defaultTargetPlatform == TargetPlatform.android || + defaultTargetPlatform == TargetPlatform.iOS; + if (isMobile) { + await SharePlus.instance.share( + ShareParams( + subject: 'Offband Meshcore logs', + files: [XFile(file.path)], + ), + ); + } else { + final dir = FileLogService.instance.logDir; + if (dir != null) await launchUrl(Uri.file(dir.path)); + } + } + void _showRawDialog(BuildContext context, _RawPacketInfo info) { showDialog( context: context,