presentNudge function
Future<void>
presentNudge({
- required BuildContext context,
- required NudgeConfig config,
- EngageActionContext actionContext = EngageActionContext.unknown,
- VariableScope scope = VariableScope.empty,
- VoidCallback? onPresented,
- ValueChanged<
ModalRoute> ? onRoute,
Presents a NudgeConfig over the app, choosing the bottom-sheet or dialog strategy by its surface. Returns a future that completes when the nudge is dismissed (button action, close affordance, scrim, or drag-down).
Implementation
Future<void> presentNudge({
required BuildContext context,
required NudgeConfig config,
EngageActionContext actionContext = EngageActionContext.unknown,
VariableScope scope = VariableScope.empty,
VoidCallback? onPresented,
ValueChanged<ModalRoute<dynamic>>? onRoute,
}) {
final presentation = _presentations[config.surface.displayType] ??
const BottomSheetPresentation();
final viewportWidth = MediaQuery.sizeOf(context).width;
final canvas = config.canvas;
final surfaceScale = campaignCanvasDesignScale(
viewportWidth: viewportWidth,
designWidth: config.designWidth,
fullWidth: config.surface.isBottomSheet,
);
final maxDialogCanvasWidth = math.max(
1.0,
config.designWidth - 2 * config.surface.minHorizontalMargin,
);
final fittedCanvasWidth = config.surface.isBottomSheet
? canvas.width
: math.min(canvas.width, maxDialogCanvasWidth);
final runtimeWidthFraction =
(fittedCanvasWidth * surfaceScale / viewportWidth)
.clamp(0.01, 1.0)
.toDouble();
final runtimeSurface = config.surface.scaled(
surfaceScale,
widthFractionOverride:
config.surface.isBottomSheet ? null : runtimeWidthFraction,
);
final closePlacement = config.surface.closeButton.placement;
final customCanvasFrame = !config.surface.isFullScreen;
// Wrap the content so button taps can hand the host the campaign context, and
// so the renderers can interpolate `{{ placeholder }}` copy against [scope].
final nudgeContent = EngageActionContextScope(
actionContext: actionContext,
child: VariableScopeProvider(
scope: scope,
child: _AutoDismissNudge(
// Any authored auto-dismiss is honored on every surface. The dashboard
// authors it for full-screen nudges only; the SDK stays ready for more.
after: config.surface.autoDismissAfter,
child: CampaignCanvasActionScope(
onActions: _handleCanvasActions,
child: config.surface.isFullScreen
? FullScreenNudgeView(
canvas: canvas,
designWidth: config.designWidth,
surface: config.surface,
)
: customCanvasFrame
? CampaignCanvasStage(
canvas: canvas,
showBackground: !config.surface.isBottomSheet,
)
: CampaignCanvasView(
canvas: canvas,
designWidth: config.designWidth,
fullWidth: runtimeSurface.isBottomSheet,
),
),
),
),
);
final presented = onPresented == null
? nudgeContent
: _NudgePresented(onPresented: onPresented, child: nudgeContent);
final content = onRoute == null
? presented
: _NudgeRouteCapture(onRoute: onRoute, child: presented);
if (customCanvasFrame) {
return presentPlacedCanvasNudge(
context: context,
surface: config.surface,
closePlacement: closePlacement,
authoredSize: Size(canvas.width, canvas.height),
designWidth: config.designWidth,
stage: content,
canvasBackground: config.surface.isBottomSheet ? canvas.background : null,
);
}
return presentation.present(
context: context,
surface: runtimeSurface,
content: content,
);
}