addPop static method
Displays a pop overlay on screen
This is the main entry point for showing overlays in the application.
Features:
- Prevents duplicate overlays (checks by ID)
- Automatically sorts overlays based on priority rules
- Supports auto-dismissal when duration is provided
Parameters:
popContent: The PopOverlayContent configuration for the overlay.
Example:
// Show a notification overlay
PopOverlay.addPop(PopOverlayContent(
id: "notification_1",
widget: NotificationWidget(message: "Update complete"),
duration: Duration(seconds: 3),
shouldDismissOnBackgroundTap: true,
));
Implementation
static void addPop(PopOverlayContent popContent, {BuildContext? context}) {
// Ensure the overlay system is installed before adding content
_PopOverlayBootstrapper.ensureInstalled(context: context);
// Check if the overlay is already active but invisible
if (PopOverlay.isActiveById(popContent.id) &&
_invisibleController.state.contains(popContent.id)) {
final existingOverlay = PopOverlay.getActiveById(popContent.id);
if (existingOverlay != null) {
// Check if offsetToPopFrom has changed
final hasOffsetChanged =
existingOverlay.offsetToPopFrom != popContent.offsetToPopFrom;
if (hasOffsetChanged) {
// Replace the existing overlay with the new one (which has updated offsetToPopFrom)
_controller.update<List<PopOverlayContent>>((state) {
final index =
state.indexWhere((element) => element.id == popContent.id);
if (index != -1) {
// Copy the animation and position controllers from the old popup to the new one
popContent.animationController.state =
existingOverlay.animationController.state;
popContent.positionController.state =
existingOverlay.positionController.state;
popContent.isDraggingController.value =
existingOverlay.isDraggingController.value;
// Replace the old popup with the new one
state[index] = popContent;
}
return state;
});
}
// Make the overlay visible (either the updated one or the existing one)
final overlayToShow = hasOffsetChanged ? popContent : existingOverlay;
PopOverlay._makePopOverlayVisible(overlayToShow);
}
return;
}
// Only add if an overlay with this ID doesn't already exist
if (PopOverlay.isActiveById(popContent.id) == false) {
// If onBeforeCreatingPop callback is provided, call it before adding the overlay
popContent.initState?.call();
// Update the controller's state with the new overlay
_controller.update<List<PopOverlayContent>>((state) {
// Add the new overlay to the list
state.add(popContent);
// // Sort the list based on priority rules
PopOverlay._sortPopList(state);
return state;
});
// If shouldStartInvisible is true and shouldMakeInvisibleOnDismiss is also true,
// immediately make the popup invisible
if (popContent.shouldStartInvisible &&
popContent.shouldMakeInvisibleOnDismiss) {
PopOverlay._makePopOverlayInvisible(popContent);
}
// Handle auto-dismissal if duration is specified
if (popContent.duration != null) {
// Cancel any existing timer for this popup
popContent._autoDismissTimer?.cancel();
// Create a new timer for auto-dismissal
popContent._autoDismissTimer = Timer(popContent.duration!, () {
// Check if popup still exists and is visible before dismissing
if (PopOverlay.isActiveById(popContent.id) &&
!_invisibleController.state.contains(popContent.id)) {
if (popContent.shouldMakeInvisibleOnDismiss) {
_makePopOverlayInvisible(popContent);
} else {
removePop(popContent.id);
}
popContent.onDismissed?.call();
}
});
}
}
}