mirror of
https://github.com/dz0ny/meshcore-sar.git
synced 2026-08-13 09:20:29 +00:00
fix: Add mounted checks and fix memory leaks across UI components
Address potential memory leaks and state-after-dispose issues: - AppProvider: Add dispose method to clean up listeners and callbacks - MapTab: Store and restore original location callback instead of nullifying - MessagesTab: Use Timer instead of Future.delayed for highlight cleanup - ConnectionDialog: Use named listener method for proper tab controller cleanup - RoomLoginSheet: Add _isDisposed flag to handle async callback race conditions - SettingsScreen: Clear location service callbacks in dispose - Various screens: Add mounted checks before setState after async operations (contacts_tab, device_config, home_screen, map_management, packet_log, sar_template_management, sar_update_sheet, permission_request_dialog)
This commit is contained in:
@@ -73,10 +73,12 @@ class _PacketLogScreenState extends State<PacketLogScreen> {
|
||||
|
||||
// Save to temporary file
|
||||
final tempDir = await getTemporaryDirectory();
|
||||
if (!context.mounted) return;
|
||||
final file = File('${tempDir.path}/ble_packets_${DateTime.now().millisecondsSinceEpoch}.csv');
|
||||
await file.writeAsString(buffer.toString());
|
||||
|
||||
// Share the file
|
||||
if (!context.mounted) return;
|
||||
await Share.shareXFiles(
|
||||
[XFile(file.path)],
|
||||
subject: 'MeshCore BLE Packet Logs',
|
||||
@@ -118,10 +120,12 @@ class _PacketLogScreenState extends State<PacketLogScreen> {
|
||||
|
||||
// Save to temporary file
|
||||
final tempDir = await getTemporaryDirectory();
|
||||
if (!context.mounted) return;
|
||||
final file = File('${tempDir.path}/ble_packets_${DateTime.now().millisecondsSinceEpoch}.txt');
|
||||
await file.writeAsString(buffer.toString());
|
||||
|
||||
// Share the file
|
||||
if (!context.mounted) return;
|
||||
await Share.shareXFiles(
|
||||
[XFile(file.path)],
|
||||
subject: 'MeshCore BLE Packet Logs',
|
||||
@@ -147,27 +151,31 @@ class _PacketLogScreenState extends State<PacketLogScreen> {
|
||||
}
|
||||
|
||||
void _clearLogs(BuildContext context) {
|
||||
final parentContext = context; // Store parent context for setState
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) => AlertDialog(
|
||||
title: Text(AppLocalizations.of(context)!.clearAllData),
|
||||
builder: (dialogContext) => AlertDialog(
|
||||
title: Text(AppLocalizations.of(dialogContext)!.clearAllData),
|
||||
content: const Text('Are you sure you want to clear all packet logs? This cannot be undone.'),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () => Navigator.pop(context),
|
||||
child: Text(AppLocalizations.of(context)!.cancel),
|
||||
onPressed: () => Navigator.pop(dialogContext),
|
||||
child: Text(AppLocalizations.of(dialogContext)!.cancel),
|
||||
),
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
widget.bleService.clearPacketLogs();
|
||||
Navigator.pop(context);
|
||||
Navigator.pop(dialogContext);
|
||||
if (!mounted) return;
|
||||
setState(() {});
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(content: Text('Packet logs cleared')),
|
||||
);
|
||||
if (parentContext.mounted) {
|
||||
ScaffoldMessenger.of(parentContext).showSnackBar(
|
||||
const SnackBar(content: Text('Packet logs cleared')),
|
||||
);
|
||||
}
|
||||
},
|
||||
style: TextButton.styleFrom(foregroundColor: Colors.red),
|
||||
child: Text(AppLocalizations.of(context)!.clear),
|
||||
child: Text(AppLocalizations.of(dialogContext)!.clear),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -381,6 +389,7 @@ class _PacketLogScreenState extends State<PacketLogScreen> {
|
||||
// Auto-scroll to bottom
|
||||
if (_autoScroll && index == logs.length - 1) {
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
if (!mounted) return;
|
||||
if (_scrollController.hasClients) {
|
||||
_scrollController.animateTo(
|
||||
_scrollController.position.maxScrollExtent,
|
||||
|
||||
Reference in New Issue
Block a user