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

@@ -38,6 +38,7 @@ class _PermissionRequestDialogState extends State<PermissionRequestDialog> {
try {
// Check if location service is enabled
final serviceEnabled = await Geolocator.isLocationServiceEnabled();
if (!mounted) return;
if (!serviceEnabled) {
setState(() {
_errorMessage = 'Location services are disabled. Please enable location services in your device settings.';
@@ -48,10 +49,12 @@ class _PermissionRequestDialogState extends State<PermissionRequestDialog> {
// Check current permission
LocationPermission permission = await Geolocator.checkPermission();
if (!mounted) return;
if (permission == LocationPermission.denied) {
// Request permission
permission = await Geolocator.requestPermission();
if (!mounted) return;
}
if (permission == LocationPermission.denied) {
@@ -78,11 +81,10 @@ class _PermissionRequestDialogState extends State<PermissionRequestDialog> {
});
// Close dialog and notify parent
if (mounted) {
Navigator.of(context).pop();
widget.onPermissionsGranted();
}
Navigator.of(context).pop();
widget.onPermissionsGranted();
} catch (e) {
if (!mounted) return;
setState(() {
_errorMessage = 'Error requesting permissions: $e';
_isRequesting = false;