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:
Janez Troha
2025-12-04 19:34:48 +01:00
parent 3e2e4aa4d9
commit 96824e455e
15 changed files with 119 additions and 57 deletions

View File

@@ -1,3 +1,4 @@
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:provider/provider.dart';
@@ -33,6 +34,7 @@ class _MessagesTabState extends State<MessagesTab> {
int _characterCount = 0;
static const int _maxCharacters = 160;
String? _highlightedMessageId;
Timer? _highlightTimer; // Timer for clearing message highlight
// Message destination state
String _destinationType =
@@ -73,6 +75,7 @@ class _MessagesTabState extends State<MessagesTab> {
@override
void dispose() {
_highlightTimer?.cancel();
_textController.dispose();
_focusNode.dispose();
_scrollController.dispose();
@@ -112,8 +115,9 @@ class _MessagesTabState extends State<MessagesTab> {
_highlightedMessageId = messageId;
});
// Clear highlight after 2 seconds
Future.delayed(const Duration(seconds: 2), () {
// Clear highlight after 2 seconds using a properly managed Timer
_highlightTimer?.cancel();
_highlightTimer = Timer(const Duration(seconds: 2), () {
if (mounted) {
setState(() {
_highlightedMessageId = null;