fromCampaignJson static method

GuideConfig? fromCampaignJson(
  1. Map<String, dynamic> json, {
  2. DesignTokenCatalog designTokens = DesignTokenCatalog.empty,
})

Parses a guide from a campaign's JSON, mirroring RN's _parseTemplateConfig (flat templateConfig with templateType tooltip/spotlight).

Implementation

static GuideConfig? fromCampaignJson(
  Map<String, dynamic> json, {
  DesignTokenCatalog designTokens = DesignTokenCatalog.empty,
}) {
  final tc = optMap(json, 'templateConfig');
  if (tc == null) return null;
  final type = optString(tc, 'templateType');
  final rawSteps = optList(tc, 'steps') ?? const [];
  final templateId = _optStringOrNull(tc, 'templateId');
  final outsideTap = OutsideTapBehavior.tryFromWire(
    optString(tc, 'outsideTapBehavior', 'next'),
  );
  if (outsideTap == null) return null;
  final rawDesignWidth = optDouble(
    tc,
    'designWidth',
    defaultCampaignCanvasDesignWidth,
  );
  final designWidth =
      rawDesignWidth > 0 ? rawDesignWidth : defaultCampaignCanvasDesignWidth;

  if (type == 'tooltip') {
    final steps = <TooltipStep>[];
    for (final raw in rawSteps) {
      if (raw is Map) {
        final s = TooltipStep.fromJson(
          raw.cast<String, dynamic>(),
          designTokens: designTokens,
        );
        if (s != null) steps.add(s);
      }
    }
    if (steps.isEmpty) return null;
    return TooltipGuideConfig(
      steps: steps,
      templateId: templateId,
      outsideTapBehavior: outsideTap,
      designWidth: designWidth,
    );
  }
  if (type == 'spotlight') {
    final steps = <SpotlightStep>[];
    for (final raw in rawSteps) {
      if (raw is Map) {
        final s = SpotlightStep.fromJson(
          raw.cast<String, dynamic>(),
          designTokens: designTokens,
        );
        if (s != null) steps.add(s);
      }
    }
    if (steps.isEmpty) return null;
    final hasAnchorlessStep = steps.any((step) => step.anchorKey == null);
    if (hasAnchorlessStep) {
      if (steps.any((step) => step.anchorKey != null) ||
          steps.length != rawSteps.length) {
        return null;
      }
      final stepIds = <String>{};
      String? pageKey;
      for (final step in steps) {
        if (!stepIds.add(step.stepId!)) return null;
        final targetPageKey = step.anchorlessTarget?['pageKey'];
        if (targetPageKey is! String || targetPageKey.trim().isEmpty) {
          return null;
        }
        pageKey ??= targetPageKey;
        if (pageKey != targetPageKey) return null;
      }
    }
    return SpotlightGuideConfig(
      steps: steps,
      templateId: templateId,
      outsideTapBehavior: outsideTap,
      designWidth: designWidth,
    );
  }
  return null;
}