private shouldInvokeModal()

in packages/ketcher-core/src/application/editor/tools/Bond.ts [548:670]


  private shouldInvokeModal(
    firstMonomer: BaseMonomer,
    secondMonomer: BaseMonomer,
    checkForPotentialBonds = true,
  ) {
    if (this.isHydrogenBond) {
      return;
    }

    // No Modal: no free attachment point on second monomer
    if (!secondMonomer.hasFreeAttachmentPoint) {
      return false;
    }

    // No Modal: Both monomers have APs selected
    if (
      firstMonomer.chosenFirstAttachmentPointForBond !== null &&
      secondMonomer.chosenSecondAttachmentPointForBond !== null
    ) {
      return false;
    }

    // Modal: either of the monomers doesn't have any potential APs
    if (
      checkForPotentialBonds &&
      (!firstMonomer.hasPotentialBonds() || !secondMonomer.hasPotentialBonds())
    ) {
      return true;
    }

    // No Modal: Both monomers have only 1 attachment point
    if (
      firstMonomer.unUsedAttachmentPointsNamesList.length === 1 &&
      secondMonomer.unUsedAttachmentPointsNamesList.length === 1
    ) {
      return false;
    }

    // Modal: Any or both monomers are Chems
    if (firstMonomer instanceof Chem || secondMonomer instanceof Chem) {
      return true;
    }

    // Modal: Any or both monomers are unresolved
    if (
      firstMonomer instanceof UnresolvedMonomer ||
      secondMonomer instanceof UnresolvedMonomer
    ) {
      return true;
    }

    // Modal: One monomer is Peptide and another is RNA monomer
    const rnaMonomerClasses = [Sugar, RNABase, Phosphate];
    const firstMonomerIsRNA = rnaMonomerClasses.find(
      (RNAClass) => firstMonomer instanceof RNAClass,
    );
    const secondMonomerIsRNA = rnaMonomerClasses.find(
      (RNAClass) => secondMonomer instanceof RNAClass,
    );
    if (
      (firstMonomerIsRNA && secondMonomer instanceof Peptide) ||
      (secondMonomerIsRNA && firstMonomer instanceof Peptide) ||
      (firstMonomerIsRNA && secondMonomer instanceof UnsplitNucleotide) ||
      (secondMonomerIsRNA && firstMonomer instanceof UnsplitNucleotide) ||
      (firstMonomerIsRNA &&
        secondMonomer instanceof AmbiguousMonomer &&
        secondMonomer.monomerClass === KetMonomerClass.AminoAcid) ||
      (secondMonomerIsRNA &&
        firstMonomer instanceof AmbiguousMonomer &&
        firstMonomer.monomerClass === KetMonomerClass.AminoAcid)
    ) {
      return true;
    }
    // if (
    //   (firstMonomer instanceof RNABase &&
    //     secondMonomer instanceof Sugar &&
    //     secondMonomer.isAttachmentPointExistAndFree(AttachmentPointName.R3)) ||
    //   (secondMonomer instanceof RNABase &&
    //     firstMonomer instanceof Sugar &&
    //     firstMonomer.isAttachmentPointExistAndFree(AttachmentPointName.R3))
    // ) {
    //   return true;
    // }

    // Modal: special case for Peptide chain
    if (secondMonomer instanceof Peptide && firstMonomer instanceof Peptide) {
      // one of monomers has more than 2 AP
      const hasPlentyAttachmentPoints =
        firstMonomer.listOfAttachmentPoints.length > 2 ||
        secondMonomer.listOfAttachmentPoints.length > 2;

      // at least one of monomers has more than 1 free AP
      const hasPlentyFreeAttachmentPoints =
        firstMonomer.unUsedAttachmentPointsNamesList.length > 1 ||
        secondMonomer.unUsedAttachmentPointsNamesList.length > 1;

      // there is no possibility to connect R1-R2
      const BothR1AttachmentPointUsed =
        firstMonomer.isAttachmentPointUsed(AttachmentPointName.R1) &&
        secondMonomer.isAttachmentPointUsed(AttachmentPointName.R1);

      const BothR2AttachmentPointUsed =
        firstMonomer.isAttachmentPointUsed(AttachmentPointName.R2) &&
        secondMonomer.isAttachmentPointUsed(AttachmentPointName.R2);

      const R1AndR2AttachmentPointUsed =
        (firstMonomer.isAttachmentPointUsed(AttachmentPointName.R2) &&
          firstMonomer.isAttachmentPointUsed(AttachmentPointName.R1)) ||
        (secondMonomer.isAttachmentPointUsed(AttachmentPointName.R2) &&
          secondMonomer.isAttachmentPointUsed(AttachmentPointName.R1));

      if (
        hasPlentyAttachmentPoints &&
        hasPlentyFreeAttachmentPoints &&
        (BothR1AttachmentPointUsed ||
          BothR2AttachmentPointUsed ||
          R1AndR2AttachmentPointUsed)
      ) {
        return true;
      }
    }
    return false;
  }