From ed76d163cf393ebb255af73ed715735af4ab0db3 Mon Sep 17 00:00:00 2001 From: Hariom Balhara Date: Tue, 23 Apr 2024 15:06:12 +0530 Subject: [PATCH] fix: Add navigatedToBooker event and fix infinite loop of events (#14694) ## What does this PR do? 1. cal.com/sales page is a special case where embed-iframe exists in top as well as in iframe. This causes a looping of events somehow due to embed-iframe firing events and those being received by the top embed-iframe. 2. Added new `navigatedToBooker` event to know when the user lands on booker page. Corresponding PR in website that uses `navigatedToBooker` event and has a demo as well https://github.com/calcom/website/pull/741 Earlier added `routed` event seems to happen too early ## Type of change - Bug fix (non-breaking change which fixes an issue) ## How should this be tested? - Simply navigate to booker and wait for the event. ## Mandatory Tasks - [x] Make sure you have self-reviewed the code. A decent size PR without self-review might be rejected. ## Tests - Didn't add any tests for this as the changed seems straightforward ## Checklist - I haven't added tests that prove my fix is effective or that my feature works --- packages/embeds/embed-core/src/embed-iframe.ts | 10 +++++++++- packages/embeds/embed-core/src/sdk-action-manager.ts | 1 + packages/platform/atoms/booker/BookerWebWrapper.tsx | 7 ++++++- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/packages/embeds/embed-core/src/embed-iframe.ts b/packages/embeds/embed-core/src/embed-iframe.ts index a4d72bf32c..709d855200 100644 --- a/packages/embeds/embed-core/src/embed-iframe.ts +++ b/packages/embeds/embed-core/src/embed-iframe.ts @@ -508,7 +508,10 @@ function keepParentInformedAboutDimensionChanges() { }); } -if (isBrowser) { +function main() { + if (!isBrowser) { + return; + } log("Embed SDK loaded", { isEmbed: window?.isEmbed?.() || false }); const url = new URL(document.URL); embedStore.theme = window?.getEmbedTheme?.(); @@ -523,6 +526,9 @@ if (isBrowser) { // If embed link is opened in top, and not in iframe. Let the page be visible. if (top === window) { unhideBody(); + // We would want to avoid a situation where Cal.com embeds cal.com and then embed-iframe is in the top as well. In such case, we would want to avoid infinite loop of events being passed. + log("Embed SDK Skipped as we are in top"); + return; } window.addEventListener("message", (e) => { @@ -618,3 +624,5 @@ function connectPreloadedEmbed({ url }: { url: URL }) { const isPrerendering = () => { return new URL(document.URL).searchParams.get("prerender") === "true"; }; + +main(); diff --git a/packages/embeds/embed-core/src/sdk-action-manager.ts b/packages/embeds/embed-core/src/sdk-action-manager.ts index 90172b1761..95d82aecf4 100644 --- a/packages/embeds/embed-core/src/sdk-action-manager.ts +++ b/packages/embeds/embed-core/src/sdk-action-manager.ts @@ -60,6 +60,7 @@ export type EventDataMap = { actionType: "customPageMessage" | "externalRedirectUrl" | "eventTypeRedirectUrl"; actionValue: string; }; + navigatedToBooker: Record; "*": Record; __routeChanged: Record; __windowLoadComplete: Record; diff --git a/packages/platform/atoms/booker/BookerWebWrapper.tsx b/packages/platform/atoms/booker/BookerWebWrapper.tsx index b8dc486d1a..ba1fb17e91 100644 --- a/packages/platform/atoms/booker/BookerWebWrapper.tsx +++ b/packages/platform/atoms/booker/BookerWebWrapper.tsx @@ -1,10 +1,11 @@ import { useSession } from "next-auth/react"; import { useSearchParams } from "next/navigation"; import { usePathname, useRouter } from "next/navigation"; -import { useMemo, useCallback } from "react"; +import { useMemo, useCallback, useEffect } from "react"; import { shallow } from "zustand/shallow"; import dayjs from "@calcom/dayjs"; +import { sdkActionManager } from "@calcom/embed-core/embed-iframe"; import type { BookerProps } from "@calcom/features/bookings/Booker"; import { Booker as BookerComponent } from "@calcom/features/bookings/Booker"; import { useBookerLayout } from "@calcom/features/bookings/Booker/components/hooks/useBookerLayout"; @@ -39,6 +40,10 @@ export const BookerWebWrapper = (props: BookerWebWrapperAtomProps) => { typeof window !== "undefined" ? new URLSearchParams(window.location.search).get("bookingUid") : null; const date = dayjs(selectedDate).format("YYYY-MM-DD"); + useEffect(() => { + sdkActionManager?.fire("navigatedToBooker", {}); + }, []); + useInitializeBookerStore({ ...props, eventId: event?.data?.id,