showPopup static method

void showPopup(
  1. String? popupBackgroundImage,
  2. String? popupBackground,
  3. String title,
  4. int titleFontSize,
  5. String apiUrl,
  6. String clientApiUrl,
  7. String titleFontFamily,
  8. String titleColor,
  9. String titleFontWeight,
  10. String titleVisibility,
  11. List<Map<String, dynamic>> items,
  12. List<String> emojiList,
  13. String interaction,
  14. String popUpId,
  15. String userName,
  16. String popUpToken,
  17. String userId,
  18. List components,
  19. String videoLink,
  20. int? popupTime,
  21. int? primaryPeriority,
  22. BuildContext context,
  23. AppDatabase database,
  24. String appId, {
  25. bool isFromCache = false,
})

Implementation

static void showPopup(
    String? popupBackgroundImage,
    String? popupBackground,
    String title,
    int titleFontSize,
    String apiUrl,
    String clientApiUrl,
    String titleFontFamily,
    String titleColor,
    String titleFontWeight,
    String titleVisibility,
    List<Map<String, dynamic>> items,
    List<String> emojiList,
    String interaction,
    String popUpId,
    String userName,
    String popUpToken,
    String userId,
    List components,
    String videoLink,
    int? popupTime,
    int? primaryPeriority,
    BuildContext context,
    AppDatabase database,
    String appId,
    {bool isFromCache = false}) {
  PageController expandablePageController = PageController();
  TextEditingController commentValueController = TextEditingController();
  bool isClosedPopUp = false;
  String? currentlyDisplayedPopUpId;
  Set<String> shownPopupIds = Set<String>();

  final ApiService apiService =
      ApiService(apiUrl, clientApiUrl, database, appId);
  final thirdColor = const Color(0xFF25C4F4);
  int currentPageIndex = 0;
  ValueNotifier<int> currentPageNotifier =
      ValueNotifier<int>(currentPageIndex);
  print(
      "Showing popup ID: $popUpId, Source: ${isFromCache ? 'CACHE' : 'API'}");

  if (shownPopupIds.length > 1) {
    Navigator.of(context).pop();
  }
  showDialog(
    barrierDismissible: true,
    context: context,
    barrierColor: Colors.grey.withOpacity(0.3), // Here the solution
    builder: (BuildContext context) {
      bool isArabic(String str) {
        RegExp arabicRegex = RegExp(r'[\u0600-\u06FF\u0750-\u077F]');
        return arabicRegex.hasMatch(str);
      }

      String getTextDirection(String words) {
        words = words.trim() ?? '';
        if (words.isNotEmpty) {
          return isArabic(words[0]) ? 'rtl' : 'ltr';
        }
        return 'ltr';
      }

      if (popupTime != null && popupTime > 0) {
        print("from cache $isFromCache,popupTime $popupTime");
        Future.delayed(Duration(minutes: popupTime), () {
          print("popup deleted and closed");

          Navigator.of(context).pop();
          database.popupDao.deletePopupById(popUpId);

          apiService.closePopUp(popUpId, userName, popUpToken, userId);
        });
      }

      return StatefulBuilder(
        builder: (context, setState) {
          currentlyDisplayedPopUpId = popUpId;

          return AlertDialog(
            backgroundColor: popupBackground != "#fff"
                ? Color(int.parse('0xFF${popupBackground?.substring(1)}'))
                : Colors.white,
            contentPadding: EdgeInsets.zero,
            title: Container(
              padding: EdgeInsets.only(top: 8.h, bottom: 5.h),
              child: Row(
                mainAxisAlignment: MainAxisAlignment.end,
                children: [
                  GestureDetector(
                    onTap: () async {
                      apiService.closePopUp(
                          popUpId, userName, popUpToken, userId);
                      try {
                        // Verify popUpId
                        if (popUpId == null || popUpId.isEmpty) {
                          print("Invalid popUpId: $popUpId");
                          return;
                        }

                        print("Deleting popup with ID: $popUpId");

                        // Check if the popup exists first
                        final existingPopup =
                            await database.popupDao.findPopupById(popUpId);
                        if (existingPopup == null) {
                          print(
                              "Popup with ID $popUpId not found in database");
                        } else {
                          print(
                              "Found popup to delete: ${existingPopup.title}");
                        }

                        // Perform the deletion
                        if (isFromCache == true) {
                          await database.popupDao.deletePopupById(popUpId);
                        } else {
                          apiService.closePopUp(
                              popUpId, userName, popUpToken, userId);
                        }

                        // Verify deletion
                        final checkAfterDeletion =
                            await database.popupDao.findPopupById(popUpId);
                        if (checkAfterDeletion != null) {
                          print(
                              "WARNING: Popup still exists after deletion attempt");
                        } else {
                          print("Popup successfully deleted from database");
                        }

                        setState(() {
                          primaryPeriority = -1;
                          shownPopupIds.remove(popUpId);
                        });
                        Navigator.of(context).pop();
                      } catch (e, stacktrace) {
                        print("Error deleting popup: $e");
                        print("Stack trace: $stacktrace");
                      }
                    },
                    child: Container(
                      decoration: BoxDecoration(
                          color: thirdColor,
                          borderRadius: BorderRadius.circular(15.r)),
                      width: 120.w,
                      height: 30.h,
                      child: Center(
                        child: Text(
                          "Don't show again",
                          style:
                              TextStyle(color: Colors.white, fontSize: 12.sp),
                          textAlign: TextAlign.center,
                        ),
                      ),
                    ),
                  ),
                  SizedBox(width: 5.w),
                  Padding(
                    padding: EdgeInsets.only(right: 8.w),
                    child: GestureDetector(
                      onTap: () {
                        Navigator.pop(context);
                        setState(() {
                          primaryPeriority = -1;
                        });
                      },
                      child: Icon(
                        Icons.close,
                        size: 25.sp,
                      ),
                    ),
                  ),
                ],
              ),
            ),
            content: Container(
              width: MediaQuery.of(context).size.width,
              decoration: BoxDecoration(
                image: popupBackgroundImage != null
                    ? DecorationImage(
                        image: NetworkImage(popupBackgroundImage),
                        fit: BoxFit.cover)
                    : null,
                color: popupBackground != "#fff"
                    ? Color(int.parse('0xFF${popupBackground?.substring(1)}'))
                    : Colors.white,
              ),
              child: Builder(builder: (context) {
                return SingleChildScrollView(
                  child: Column(
                    children: [
                      Visibility(
                        visible: titleVisibility == "public" ? true : false,
                        child: Container(
                          padding: EdgeInsets.symmetric(horizontal: 10.w),
                          child: Text(
                            title,
                            textAlign: TextAlign.center,
                            textDirection: getTextDirection(title) == 'rtl'
                                ? TextDirection.rtl
                                : TextDirection.ltr,
                            style: TextStyle(
                              fontWeight: titleFontWeight == "bolder"
                                  ? FontWeight.bold
                                  : titleFontWeight == "lighter"
                                      ? FontWeight.w100
                                      : FontWeight.normal,
                              // color: Color(int.parse(
                              //     '0xFF${titleColor.substring(1)}')),
                              fontFamily: titleFontFamily,
                              fontSize: titleFontSize.sp,
                            ),
                          ),
                        ),
                      ),
                      SizedBox(height: 10.h),
                      Padding(
                        padding: EdgeInsets.symmetric(horizontal: 22.w),
                        child: ExpandablePageView.builder(
                          controller: expandablePageController,
                          onPageChanged: (int page) {
                            currentPageNotifier.value = page;
                          },
                          itemCount: components.length,
                          itemBuilder: (context, index) {
                            List<dynamic> contentItems = components[index];
                            List<String> videoLinks = [];
                            for (var contentItem in contentItems) {
                              if (contentItem['type'] == 'video') {
                                videoLinks.add(contentItem['value']);
                              }
                            }

                            return SizedBox(
                              height: components.length != 1
                                  ? MediaQuery.of(context).size.height / 1.5
                                  : null,
                              child: SingleChildScrollView(
                                child: Column(
                                  children: contentItems.map((contentItem) {
                                    Alignment alignTextPopup =
                                        Alignment.centerRight;
                                    if (contentItem['type'] == 'text') {
                                      List<Map<String, dynamic>> textList =
                                          List<Map<String, dynamic>>.from(
                                              contentItem['value'] ?? []);

                                      List<InlineSpan> textSpans = [];
                                      textList.forEach((textMap) {
                                        if (textMap['content'] == '\$br') {
                                          textSpans.add(
                                              const TextSpan(text: '\n'));
                                        } else {
                                          String textContent =
                                              textMap['content'] ?? '';
                                          Map<String, dynamic> style =
                                              textMap['style'] ?? {};
                                          String fontFamily =
                                              style["fontFamily"] ??
                                                  "Poppins";
                                          Color bgColor = style.containsKey(
                                                  'backgroundColor')
                                              ? Color(int.parse(
                                                  '0xFF${style['backgroundColor'].substring(1)}'))
                                              : Colors.transparent;
                                          Color textColor = style
                                                  .containsKey('color')
                                              ? Color(int.parse(
                                                  '0xFF${style['color'].substring(1)}'))
                                              : Colors.black;
                                          int originalFontSize =
                                              style['fontSize'] ?? 16;
                                          int modifiedFontSize =
                                              (originalFontSize * 0.9)
                                                  .round();
                                          bool boldText =
                                              style["bold"] ?? false;
                                          bool italicText =
                                              style["italique"] ?? false;
                                          Alignment textAlign =
                                              style['textAlign'] == 'left'
                                                  ? Alignment.centerLeft
                                                  : style['textAlign'] ==
                                                          'right'
                                                      ? Alignment.centerRight
                                                      : Alignment.center;
                                          alignTextPopup = textAlign;

                                          textSpans.add(TextSpan(
                                            text: textContent,
                                            style: TextStyle(
                                              fontFamily: fontFamily,
                                              fontSize: modifiedFontSize.sp,
                                              backgroundColor: bgColor,
                                              color: textColor,
                                              fontWeight: boldText
                                                  ? FontWeight.bold
                                                  : FontWeight.normal,
                                              fontStyle: italicText
                                                  ? FontStyle.italic
                                                  : FontStyle.normal,
                                            ),
                                          ));
                                        }
                                      });

                                      return Align(
                                        alignment: alignTextPopup,
                                        child: Padding(
                                          padding: EdgeInsets.symmetric(
                                              vertical: 6.h),
                                          child: RichText(
                                            text:
                                                TextSpan(children: textSpans),
                                            textDirection:
                                                contentItem["direction"] ==
                                                        "ltr"
                                                    ? TextDirection.ltr
                                                    : TextDirection.rtl,
                                          ),
                                        ),
                                      );
                                    } else if (contentItem['type'] ==
                                        'video') {
                                      for (var videoLink in videoLinks) {
                                        return PopUpVideoPlayer(
                                            videoLink: videoLink);
                                      }
                                    } else if (contentItem['type'] ==
                                        'button') {
                                      // Extract button properties
                                      String buttonText =
                                          contentItem['value'];
                                      String buttonTextFont =
                                          contentItem['fontFamily'];
                                      String buttonUrl = contentItem['url'];
                                      String buttonAlignment =
                                          contentItem['align'];
                                      String buttonBgColorHex =
                                          contentItem['backgroundColor'];
                                      String buttonTextColorHex =
                                          contentItem['color'];
                                      int buttonFontSize =
                                          contentItem['fontSize'] ?? 14;
                                      Color buttonTextColor = Color(int.parse(
                                          '0xFF${buttonTextColorHex.substring(1)}'));
                                      Color buttonBgColor = Color(int.parse(
                                          '0xFF${buttonBgColorHex.substring(1)}'));
                                      int paddingX =
                                          contentItem['paddingX'] ?? 10;
                                      int paddingY =
                                          contentItem['paddingY'] ?? 10;
                                      int borderRadius =
                                          contentItem['borderRaduis'] ?? 0;
                                      String buttonFontWeight =
                                          contentItem["fontWeight"];

                                      return Padding(
                                        padding: EdgeInsets.symmetric(
                                            vertical: 5.h),
                                        child: Align(
                                          alignment: buttonAlignment == 'left'
                                              ? Alignment.centerLeft
                                              : buttonAlignment == "right"
                                                  ? Alignment.centerRight
                                                  : Alignment.center,
                                          child: ElevatedButton(
                                            onPressed: () {
                                              if (buttonUrl.isNotEmpty) {
                                                launchUrl(Uri.parse(buttonUrl));
                                              }
                                            },
                                            style: ElevatedButton.styleFrom(
                                              foregroundColor:
                                                  buttonTextColor,
                                              backgroundColor: buttonBgColor,
                                              padding: EdgeInsets.symmetric(
                                                  horizontal:
                                                      paddingX.toDouble(),
                                                  vertical:
                                                      paddingY.toDouble()),
                                              shape: RoundedRectangleBorder(
                                                borderRadius: BorderRadius
                                                    .all(Radius.circular(
                                                        borderRadius
                                                            .sp)), // <-- Radius
                                              ),
                                            ),
                                            child: Text(
                                              buttonText,
                                              style: TextStyle(
                                                fontFamily: buttonTextFont,
                                                fontWeight:
                                                    buttonFontWeight ==
                                                            "lighter"
                                                        ? FontWeight.w400
                                                        : buttonFontWeight ==
                                                                "bolder"
                                                            ? FontWeight.bold
                                                            : FontWeight
                                                                .normal,
                                                color: buttonTextColor,
                                                fontSize: buttonFontSize.sp,
                                              ),
                                            ),
                                          ),
                                        ),
                                      );
                                    } else if (contentItem['type'] ==
                                        "image") {
                                      String imagePath = contentItem['value'];
                                      String lastThreeChars = imagePath
                                          .substring(imagePath.length - 3);

                                      if (lastThreeChars == "svg") {
                                        return Container(
                                          padding: EdgeInsets.symmetric(
                                              vertical: 6.h),
                                          width: MediaQuery.of(context)
                                              .size
                                              .width,
                                          child: SvgPicture.network(imagePath
                                              // fit: BoxFit.cover,
                                              ),
                                        );
                                      } else {
                                        return Container(
                                          padding: EdgeInsets.symmetric(
                                              vertical: 6.h),
                                          width: MediaQuery.of(context)
                                              .size
                                              .width,
                                          child: Image.network(imagePath),
                                        );
                                      }
                                    } else if (contentItem['type'] ==
                                        'custom-form') {
                                      return CustomFormWidget(
                                        contentItem: contentItem,
                                        onSubmit: (Map<String, dynamic>
                                            formAnswers) async {
                                          print(
                                              "Received messages: $formAnswers");
                                          Navigator.of(context)
                                              .pop();
                                          await apiService.submitSurvey(
                                            userName: userName,
                                            formAnswers: formAnswers,
                                            participatorId: userId,
                                            messageId: popUpId,
                                            popUpToken: popUpToken,
                                          );
                                          apiService.closePopUp(popUpId, userName, popUpToken, userId);


                                          database.popupDao
                                              .deletePopupById(
                                              popUpId);
                                        },
                                      );
                                    }

                                    return Container();
                                  }).toList(),
                                ),
                              ),
                            );
                          },
                        ),
                      ),
                      components.length > 1
                          ? Padding(
                              padding: EdgeInsets.only(top: 5.h),
                              child: Row(
                                mainAxisAlignment: MainAxisAlignment.center,
                                children: <Widget>[
                                  ...Iterable<int>.generate(components.length)
                                      .map(
                                    (int pageIndex) => Flexible(
                                        child: ValueListenableBuilder<int>(
                                      valueListenable: currentPageNotifier,
                                      builder: (context, value, child) {
                                        return AnimatedContainer(
                                          curve: Curves.easeIn,
                                          duration: const Duration(
                                              milliseconds: 500),
                                          height: 10.h,
                                          width: value == pageIndex
                                              ? 30.w
                                              : 10.w,
                                          margin: EdgeInsets.symmetric(
                                              horizontal: 4.w),
                                          decoration: BoxDecoration(
                                              color: value == pageIndex
                                                  ? thirdColor
                                                  : Colors.grey,
                                              borderRadius:
                                                  BorderRadius.circular(20.r)
                                              // shape: BoxShape.circle,
                                              ),
                                        );
                                      },
                                    )),
                                  ),
                                ],
                              ),
                            )
                          : const SizedBox.shrink(),
                      SizedBox(height: 10.h),
                      ValueListenableBuilder<int>(
                          valueListenable: currentPageNotifier,
                          builder: (context, value, child) {
                            return Column(
                              children: [
                                if (interaction == "reaction" &&
                                    currentPageNotifier.value ==
                                        (components.length - 1))
                                  Column(
                                    crossAxisAlignment:
                                        CrossAxisAlignment.start,
                                    children: [
                                      Wrap(
                                        spacing: 8.0,
                                        children: emojiList
                                            .map((interaction) =>
                                                GestureDetector(
                                                  onTap: () {
                                                    apiService.postReact(
                                                        popUpId,
                                                        userName,
                                                        popUpToken,
                                                        userId,
                                                        interaction);

                                                    setState(() {
                                                      // isClosedPopUp = true;
                                                      primaryPeriority = -1;
                                                    });

                                                    Future.delayed(
                                                        const Duration(
                                                            milliseconds:
                                                                700), () {
                                                      Navigator.of(context)
                                                          .pop();
                                                      print(
                                                          "test event provided");
                                                    });

                                                    if (isClosedPopUp) {
                                                      Navigator.of(context)
                                                          .pop();
                                                      database.popupDao
                                                          .deletePopupById(
                                                              popUpId);
                                                    }
                                                    shownPopupIds.clear();
                                                  },
                                                  child: Chip(
                                                    label: Text(interaction),
                                                  ),
                                                ))
                                            .toList(),
                                      ),
                                      SizedBox(height: 15.h),
                                    ],
                                  ),
                                if (interaction == "comment" &&
                                    currentPageNotifier.value ==
                                        (components.length - 1))
                                  Container(
                                    height: 67.h,
                                    padding: EdgeInsets.symmetric(
                                      horizontal: 10.w,
                                      vertical:
                                          0, // Adjust vertical padding as needed
                                    ),
                                    color: const Color(0xFFF3F5F7),
                                    child: Row(
                                      children: [
                                        // SvgPicture.asset(
                                        //     "assets/icons/popup_comment.svg"),
                                        Expanded(
                                          child: TextFormField(
                                            // validator: (value) =>
                                            //     validateEmptyField(value!,
                                            //         "Comment", context),
                                            controller:
                                                commentValueController,
                                            decoration: const InputDecoration(
                                              filled: true,
                                              hintText: "Write a reply",
                                              hintStyle: TextStyle(),
                                              fillColor: Color(0xFFF3F5F7),
                                              border: InputBorder.none,
                                              focusedBorder: InputBorder.none,
                                            ),
                                          ),
                                        ),
                                        GestureDetector(
                                          onTap: () {
                                            String commentValue =
                                                commentValueController.text;
                                            apiService.commentPopUp(
                                                popUpId,
                                                userName,
                                                popUpToken,
                                                userId,
                                                commentValue);

                                            setState(() {
                                              isClosedPopUp = true;
                                              primaryPeriority = -1;
                                            });

                                            Future.delayed(
                                                Duration(milliseconds: 700),
                                                () {
                                              print("test event provided");
                                              Navigator.of(context).pop();
                                              // BlocProvider.of<CoreBloc>(
                                              //     context)
                                              //     .add(GetRemoteUser());
                                            });

                                            // if (isClosedPopUp) {
                                            //   Navigator.of(context).pop();
                                            // }
                                            commentValueController.clear();
                                            database.popupDao
                                                .deletePopupById(popUpId);
                                          },
                                          child: const Icon(
                                            Icons.send,
                                            color: Colors.grey,
                                          ),
                                        ),
                                      ],
                                    ),
                                  )
                              ],
                            );
                          })
                    ],
                  ),
                );
              }),
            ),
          );
        },
      );
    },
  );
}