updateContentOfStoryboard function

Future<void> updateContentOfStoryboard({
  1. String? imagePath,
  2. String? color,
  3. String? iosContentMode,
  4. String? backgroundImage,
  5. String? iosBackgroundContentMode,
})

Update the default storyboard content with the provided details Image, Color and contentMode

Implementation

Future<void> updateContentOfStoryboard({
  String? imagePath,
  String? color,
  String? iosContentMode,
  String? backgroundImage,
  String? iosBackgroundContentMode,
}) async {
  final file = File(CmdStrings.storyboardPath);
  final xmlDocument = XmlDocument.parse(file.readAsStringSync());
  final documentData = xmlDocument.getElement(
    IOSStrings.documentElement,
  );

  /// Find the default view in the storyboard
  final view =
      documentData?.descendants.whereType<XmlElement>().firstWhere((element) {
    return element.name.qualified == IOSStrings.viewElement &&
        element.getAttribute(IOSStrings.viewIdAttr) == IOSStrings.defaultViewId;
  });
  if (view == null) {
    log(
      'Default Flutter view with ${IOSStrings.defaultViewId} ID not found.',
    );
    exit(1);
  }

  /// Find the default subViews element in the storyboard
  final subViews = view.getElement(IOSStrings.subViewsElement);
  if (subViews == null) {
    final subview = _createImageSubView(backgroundImage: backgroundImage);

    /// Add subViews element as child in view element
    view.children.add(subview);
  }

  if (color != null) {
    /// Update or add a `color` element for the background color
    final colorElement = view.getElement(IOSStrings.colorElement);
    if (colorElement != null) {
      /// Update existing color with provided color code
      _updateColorAttributes(colorElement, color);
    } else {
      /// Add a new color element with provided color code
      view.children.add(XmlElement(
        XmlName(IOSStrings.colorElement),
        _buildColorAttributes(color),
      ));
    }
  } else {
    final colorElement = view.getElement(IOSStrings.colorElement);
    if (colorElement != null) {
      /// Update existing color to white background
      _updateColorAttributes(colorElement, IOSStrings.defaultColor);
    } else {
      /// Add a new color element with white background color as child in view element
      view.children.add(XmlElement(
        XmlName(IOSStrings.colorElement),
        _buildColorAttributes(IOSStrings.defaultColor),
      ));
    }
  }
  XmlNode? backgroundImageElement;
  if (backgroundImage != null) {
    final backgroundImageFile = File(backgroundImage);
    final backgroundImageFileExists = await backgroundImageFile.exists();

    if (backgroundImageFileExists) {
      await createBackgroundImage(
        const Image(
          scale: '3x',
          filename: '${IOSStrings.backgroundImageSnakeCase}.png',
          idiom: 'universal',
        ),
        backgroundImageFile,
      );
      backgroundImageElement = getBackgroundImageElement(subViews);
    } else {
      log("$backgroundImage doesn't exists. No background image was set.");
    }
  }
  if (imagePath != null) {
    /// Find the imageView element in subViews element
    final imageView = subViews?.children.whereType<XmlElement?>().firstWhere(
      (element) =>
          element?.name.qualified == IOSStrings.imageViewElement &&
          element?.getAttribute(IOSStrings.image) == IOSStrings.imageValue,
      orElse: () {
        log(
          'Unable to find default imageView with the LaunchImage',
        );
        exit(1);
      },
    );

    /// Update the fill property
    imageView?.setAttribute(
      IOSStrings.contentMode,
      iosContentMode ?? IOSStrings.contentModeValue,
    );

    /// Remove existing or old constraints
    view.children.remove(view.getElement(IOSStrings.constraintsElement));

    /// Add constraints in view element
    view.children.add(
      XmlDocument.parse(backgroundImageElement == null
              ? SplashScreenContentString.splashAndBackConstraints
              : SplashScreenContentString.splashImageConstraints)
          .rootElement
          .copy(),
    );

    final imageViewCopy = imageView?.copy();
    imageView?.remove();
    if (backgroundImageElement == null) {
      backgroundImageElement = getImageXMLElement(
        elementId: IOSStrings.backgroundImageViewIdValue,
        imageName: IOSStrings.backgroundImage,
        contentMode: iosBackgroundContentMode ?? IOSStrings.contentModeValue,
      );
      subViews?.children.add(backgroundImageElement);
    } else {
      if (iosBackgroundContentMode != null) {
        backgroundImageElement.setAttribute(
          IOSStrings.contentMode,
          IosContentMode.fromString(iosBackgroundContentMode).mode,
        );
      }
      log("BackgroundImage already exists. Background image wasn't set.");
    }
    if (imageViewCopy != null) subViews?.children.add(imageViewCopy);
  } else {
    /// Image is not available then
    ///
    /// remove constraints
    view.children.remove(view.getElement(IOSStrings.constraintsElement));

    final subviewsTag =
        documentData?.findAllElements(IOSStrings.subViewsElement).firstOrNull;

    /// subview element
    subviewsTag?.remove();
  }

  /// Write the updated storyboard content to the file.
  file.writeAsStringSync(
    '${xmlDocument.toXmlString(pretty: true, indent: '    ')}\n',
  );
}