Skip to content

Commit

Permalink
fix(process-modal): refactor modal handling to use overlay for better…
Browse files Browse the repository at this point in the history
… state management
  • Loading branch information
tsutsu3 committed Jan 2, 2025
1 parent bcadb9a commit 460d5a4
Showing 1 changed file with 26 additions and 58 deletions.
84 changes: 26 additions & 58 deletions lib/classes/process_modal.dart
Original file line number Diff line number Diff line change
@@ -1,75 +1,43 @@
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:pi_hole_client/functions/logger.dart';

import 'package:pi_hole_client/widgets/process_dialog.dart';

class ProcessModal {
final BuildContext context;

bool _isOpenModal = false;
Timer? _closeTimer;
BuildContext? _dialogContext;
OverlayEntry? _overlayEntry;

ProcessModal({required this.context});

/// Opens the modal. If other modals are open, they are closed first.
/// Opens the process dialog as an overlay.
void open(String message) {
if (_isOpenModal) return;

_isOpenModal = true;
logger.d('Modal opened');

// Ensure other modals are closed before opening ProcessModal.
Future.delayed(Duration.zero, () {
if (!context.mounted) return;
if (_overlayEntry != null) return; // If already open, do nothing

showDialog(
context: context,
builder: (dialogContext) {
_dialogContext = dialogContext;
return ProcessDialog(message: message);
},
barrierDismissible: false,
useSafeArea: true,
).then((_) {
if (_isOpenModal) {
_resetState();
logger.d('Modal closed via then');
}
});

// TODO: Close the modal reliably without a timer
// Schedule a timer to close the modal after 1 seconds.
// If `close()` fails for any reason, this prevents the loading from continuing indefinitely.
_closeTimer = Timer(const Duration(milliseconds: 1000), close);
});
_overlayEntry = _createOverlayEntry(message);
Overlay.of(context).insert(_overlayEntry!);
}

/// Closes the modal if it is open.
/// Closes the process dialog if it's open.
void close() {
if (!_isOpenModal || _dialogContext == null) return;

try {
_closeTimer?.cancel();
_closeTimer = null;

if (Navigator.of(_dialogContext!).canPop()) {
Navigator.of(_dialogContext!).pop();
logger.d('Modal closed successfully');
} else {
logger.w('Modal cannot pop');
}
} catch (e) {
logger.e('Error closing modal: $e');
} finally {
_resetState();
}
_overlayEntry?.remove();
_overlayEntry = null;
}

/// Resets the internal state of the modal.
void _resetState() {
_isOpenModal = false;
_dialogContext = null;
logger.d('Modal state reset');
/// Creates an overlay entry for the process dialog.
OverlayEntry _createOverlayEntry(String message) {
return OverlayEntry(
builder: (context) => Stack(
children: [
ModalBarrier(
dismissible: false,
color: Colors.black.withOpacity(0.5),
),
Center(
child: ProcessDialog(
message: message,
),
),
],
),
);
}
}

0 comments on commit 460d5a4

Please sign in to comment.