addPop static method

void addPop(
  1. PopOverlayContent popContent, {
  2. BuildContext? context,
})

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:

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();
        }
      });
    }
  }
}