* feat: add embed prerendering support and enhance event handling - Introduced `useIsEmbedPrerendering` hook to determine if the embed is in prerender mode. - Updated `useAvailabilityEvents` to prevent firing events during prerendering. - Added `bookerLoadedEvent` and `availabilityRefreshed` types to `EventDataMap`. - Implemented `useFirebookerLoadedEvent` to manage firing the booker loaded event conditionally. - Refactored event firing logic in `useSchedule` and `BookerWebWrapper` components to utilize new hooks. * feat: add embed prerendering support and enhance event handling - Introduced `useIsEmbedPrerendering` hook to determine if the embed is in prerender mode. - Updated `useAvailabilityEvents` to prevent firing events during prerendering. - Added `bookerLoadedEvent` and `availabilityRefreshed` types to `EventDataMap`. - Implemented `useFirebookerLoadedEvent` to manage firing the booker loaded event conditionally. - Refactored event firing logic in `useSchedule` and `BookerWebWrapper` components to utilize new hooks. * feat: enhance embed event handling and introduce link reopening detection - Added `useEmbedReopened` hook to track when the embed is reopened. - Updated `BookerWebWrapper` to reset event firing state upon embed reopening. - Refactored event firing logic to use `bookerViewed` instead of `bookerLoadedEvent`. - Introduced scheduling for event firing in `useSchedule` to ensure correct order of events during prerendering. * feat: add lifecycle diagrams for inline and modal embeds - Introduced `inline-embed-lifecycle.mermaid` and `modal-embed-lifecycle.mermaid` files to visualize the lifecycle events and states of inline and modal embeds. - Updated `LIFECYCLE.md` to reference the new diagrams and provide a clearer explanation of the embed lifecycle processes. - Added `modal-prerendering-flow.mermaid` to illustrate the prerendering flow for modal embeds. - Enhanced the routing playground with new features and improved event handling for availability and booking events. * refactor: update event handling for booker lifecycle events - Replaced `availabilityLoaded` event with `bookerReady` to better reflect the state when the booker view is fully loaded and ready for interaction. - Updated related documentation and diagrams to reflect changes in event triggers and descriptions. - Adjusted internal state management to track `viewId` instead of `reopenCount` for distinguishing between initial views and reopens. - Added tests for new event handling logic to ensure correct firing of `bookerViewed`, `bookerReopened`, and `bookerReady` events. * refactor: enhance embed event handling and state management - Updated event handling for booker lifecycle events, replacing `resetViewVariables` with `resetPageData` to manage page-specific state. - Introduced new utility functions for managing event firing states and reload initiation. - Refactored `fireBookerViewedEvent` and `fireBookerReadyEvent` to utilize the new state management functions. - Added comprehensive tests for the updated event handling logic and state resets to ensure correct functionality across various scenarios. * refactor: update embed iframe configuration and utility functions - Reduced `slotsStaleTimeMs` from 30 seconds to 10 seconds and `iframeForceReloadThresholdMs` from 100 seconds to 30 seconds for improved responsiveness. - Refactored utility functions to use `isBrowser` for client-side checks instead of `isClientSide`. - Removed unused `isPrerendering` function and updated related documentation for clarity. - Enhanced event handling by exporting `useBookerEmbedEvents` from the appropriate module for better accessibility. * refactor: update embed iframe configuration and utility functions - Reduced `slotsStaleTimeMs` from 30 seconds to 10 seconds and `iframeForceReloadThresholdMs` from 100 seconds to 30 seconds for improved responsiveness. - Refactored utility functions to use `isBrowser` for client-side checks instead of `isClientSide`. - Removed unused `isPrerendering` function and updated related documentation for clarity. - Enhanced event handling by exporting `useBookerEmbedEvents` from the appropriate module for better accessibility. * fix cubic feedback
117 lines
3.3 KiB
TypeScript
117 lines
3.3 KiB
TypeScript
"use client";
|
|
/**
|
|
* All hooks defined in this file must be client side hooks and must not be executed in server side.
|
|
* So, they should start with isBrowser check.
|
|
*/
|
|
import { sdkActionManager } from "../sdk-event";
|
|
import { embedStore, getEventHasFired, setEventHasFired, getReloadInitiated, setReloadInitiated } from "./lib/embedStore";
|
|
import { isBrowser, isPrerendering } from "./lib/utils";
|
|
|
|
/**
|
|
* Fires bookerViewed, bookerReopened, or bookerReloaded events
|
|
*/
|
|
const fireBookerViewedEvent = ({
|
|
eventId,
|
|
eventSlug,
|
|
slotsLoaded,
|
|
}: {
|
|
eventId: number | undefined;
|
|
eventSlug: string | undefined;
|
|
slotsLoaded: boolean;
|
|
}) => {
|
|
const isFirstTime = embedStore.viewId === 1;
|
|
const isReload = getReloadInitiated();
|
|
const eventName: "bookerViewed" | "bookerReopened" | "bookerReloaded" = isReload ? "bookerReloaded" : isFirstTime ? "bookerViewed" : "bookerReopened";
|
|
|
|
if (getEventHasFired(eventName)) {
|
|
return;
|
|
}
|
|
|
|
fireEvent(eventName);
|
|
|
|
function fireEvent(eventName: "bookerViewed" | "bookerReopened" | "bookerReloaded") {
|
|
setEventHasFired(eventName, true);
|
|
if (slotsLoaded) {
|
|
if (eventId && eventSlug) {
|
|
sdkActionManager?.fire(eventName, {
|
|
eventId,
|
|
eventSlug,
|
|
slotsLoaded: true,
|
|
});
|
|
} else {
|
|
// This situation shouldn't arise but not throwing error because for a tracking event we don't want to crash booker
|
|
console.error("BookerViewed event not fired because slotsLoaded is true but eventId or eventSlug are falsy");
|
|
}
|
|
} else {
|
|
sdkActionManager?.fire(eventName, {
|
|
eventId: null,
|
|
eventSlug: null,
|
|
slotsLoaded: false,
|
|
});
|
|
}
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Fires bookerReady event when booker view is loaded and slots are ready.
|
|
* Only fires once per link view when slots are successfully loaded.
|
|
*/
|
|
const fireBookerReadyEvent = ({
|
|
eventId,
|
|
eventSlug,
|
|
slotsLoaded,
|
|
}: {
|
|
eventId: number;
|
|
eventSlug: string;
|
|
slotsLoaded: boolean;
|
|
}) => {
|
|
if (!slotsLoaded) {
|
|
return;
|
|
}
|
|
if (!getEventHasFired("bookerReady")) {
|
|
sdkActionManager?.fire("bookerReady", { eventId, eventSlug });
|
|
setEventHasFired("bookerReady", true);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Hook that fires embed events (bookerViewed/bookerReopened/bookerReloaded and bookerReady).
|
|
* Manages event state using embedStore to prevent duplicate events and track modal reopens/reloads.
|
|
*/
|
|
export const useBookerEmbedEvents = ({
|
|
eventId,
|
|
eventSlug,
|
|
schedule,
|
|
}: {
|
|
eventId: number | undefined;
|
|
eventSlug: string | undefined;
|
|
schedule: {
|
|
isSuccess: boolean;
|
|
dataUpdatedAt: number;
|
|
};
|
|
}) => {
|
|
if (!isBrowser) {
|
|
return;
|
|
}
|
|
const viewId = embedStore.viewId;
|
|
|
|
if (isPrerendering() || !viewId) {
|
|
return;
|
|
}
|
|
// first BookerViewed event happens, followed by bookerReady if slots are loaded
|
|
fireBookerViewedEvent({
|
|
eventId,
|
|
eventSlug,
|
|
slotsLoaded: schedule.isSuccess,
|
|
});
|
|
|
|
if (eventId && eventSlug) {
|
|
fireBookerReadyEvent({
|
|
eventId,
|
|
eventSlug,
|
|
slotsLoaded: schedule.isSuccess,
|
|
});
|
|
}
|
|
};
|
|
|