fix: removed plain chat from app.cal.com/video (#18385)

* fix: removed plain chat from app.cal.com/video

* take user session and open plain out of use effect

* move undefined check and screen size check above useeffect

* turned restrcited paths into env var

* undefeined window below hooks

* chore: add window check

* fix: infinite re rendering

* remove console.log

---------

Co-authored-by: Udit Takkar <udit222001@gmail.com>
This commit is contained in:
Nizzy
2024-12-27 18:42:36 +00:00
committed by GitHub
co-authored by Udit Takkar
parent a697857fa0
commit a27e1498b8
3 changed files with 167 additions and 145 deletions
+1
View File
@@ -114,6 +114,7 @@ PLAIN_API_URL=https://api.plain.com/v1
PLAIN_HMAC_SECRET_KEY=
PLAIN_CHAT_ID=
PLAIN_CHAT_HMAC_SECRET_KEY=
NEXT_PUBLIC_PLAIN_CHAT_EXCLUDED_PATHS=
# Zendesk Config
NEXT_PUBLIC_ZENDESK_KEY=
+164 -144
View File
@@ -3,7 +3,7 @@
import { useSession } from "next-auth/react";
import { usePathname, useSearchParams } from "next/navigation";
import Script from "next/script";
import { useEffect, useState } from "react";
import { useEffect, useState, useCallback, useMemo } from "react";
declare global {
interface Window {
@@ -75,157 +75,177 @@ const PlainChat = () => {
const pathname = usePathname();
const searchParams = useSearchParams();
const isAppDomain = typeof window !== "undefined" && window.location.hostname === "app.cal.com";
const shouldOpenPlain = pathname === "/event-types" && searchParams?.has("openPlain");
const userEmail = session?.user?.email;
const isAppDomain = useMemo(() => {
const restrictedPaths = process.env.NEXT_PUBLIC_PLAIN_CHAT_EXCLUDED_PATHS?.split(",") || [];
return (
typeof window !== "undefined" &&
window.location.origin === process.env.NEXT_PUBLIC_WEBAPP_URL &&
!restrictedPaths.some((path) => pathname?.startsWith(path.trim()))
);
}, [pathname]);
const checkScreenSize = useCallback(() => {
if (typeof window === "undefined") return;
const isSmall = window.innerWidth < 768;
setIsSmallScreen(isSmall);
if (isSmall && window.Plain) {
const plainElement = document.querySelector("#plain-container");
plainElement?.remove();
window.Plain = undefined;
} else if (!isSmall && window.Plain === undefined) {
window.plainScriptLoaded?.();
}
}, []);
const initConfig = useCallback(async () => {
if (!userEmail) return;
try {
const response = await fetch("/api/plain-hash", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
});
if (!response.ok) {
const errorText = await response.text();
throw new Error(`Failed to generate hash: ${errorText}`);
}
const data = await response.json();
if (!data.hash || !data.email || !data.appId) {
throw new Error("Missing required fields in API response");
}
const plainChatConfig: PlainChatConfig = {
appId: data.appId,
customerDetails: {
email: data.email,
shortName: data.shortName,
fullName: data.fullName,
emailHash: data.hash,
chatAvatarUrl: data.chatAvatarUrl,
},
links: [
{
icon: "book",
text: "Documentation",
url: "https://cal.com/docs",
},
{
icon: "chat",
text: "Ask the community",
url: "https://github.com/calcom/cal.com/discussions",
},
],
chatButtons: [
{
icon: "chat",
text: "Ask a question",
type: "primary",
},
{
icon: "bulb",
text: "Send feedback",
type: "default",
},
{
icon: "error",
text: "Report an issue",
type: "default",
form: {
fields: [
{
type: "dropdown",
placeholder: "Select severity...",
options: [
{
icon: "support",
text: "I'm unable to use the app",
threadDetails: {
severity: "critical",
issueType: "critical",
labelTypeIds: ["lt_01JFJWNWAC464N8DZ6YE71YJRF"],
priority: "u",
},
},
{
icon: "error",
text: "Major functionality degraded",
threadDetails: {
severity: "major",
issueType: "major",
labelTypeIds: ["lt_01JFJWP3KECF1YQES6XF212RFW"],
priority: "h",
},
},
{
icon: "bug",
text: "Minor annoyance",
threadDetails: {
severity: "minor",
issueType: "minor",
labelTypeIds: ["lt_01JFJWPC8ADW0PK28JHMJR6NSS"],
priority: "l",
},
},
],
},
],
},
},
],
entryPoint: {
type: "chat",
},
hideBranding: true,
theme: "auto",
style: {
brandColor: "#FFFFFF",
launcherBackgroundColor: "#262626",
launcherIconColor: "#FFFFFF",
},
position: {
bottom: "20px",
right: "20px",
},
};
if (process.env.NODE_ENV === "development" || process.env.NODE_ENV === "test") {
window.__PLAIN_CONFIG__ = plainChatConfig;
}
setConfig(plainChatConfig);
if (shouldOpenPlain) {
const timer = setTimeout(() => {
if (window.Plain) {
window.Plain.open();
}
}, 100);
return () => clearTimeout(timer);
}
} catch (error) {
console.error("Failed to initialize Plain Chat:", error);
}
}, [userEmail, shouldOpenPlain]);
useEffect(() => {
if (!isAppDomain) return;
const checkScreenSize = () => {
setIsSmallScreen(window.innerWidth < 768);
};
checkScreenSize();
window.addEventListener("resize", checkScreenSize);
const initConfig = async () => {
if (!session?.user?.email) return;
try {
const response = await fetch("/api/plain-hash", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
});
if (!response.ok) {
const errorText = await response.text();
throw new Error(`Failed to generate hash: ${errorText}`);
}
const data = await response.json();
if (!data.hash || !data.email || !data.appId) {
throw new Error("Missing required fields in API response");
}
const plainChatConfig: PlainChatConfig = {
appId: data.appId,
customerDetails: {
email: data.email,
shortName: data.shortName,
fullName: data.fullName,
emailHash: data.hash,
chatAvatarUrl: data.chatAvatarUrl,
},
links: [
{
icon: "book",
text: "Documentation",
url: "https://cal.com/docs",
},
{
icon: "chat",
text: "Ask the community",
url: "https://github.com/calcom/cal.com/discussions",
},
],
chatButtons: [
{
icon: "chat",
text: "Ask a question",
type: "primary",
},
{
icon: "bulb",
text: "Send feedback",
type: "default",
},
{
icon: "error",
text: "Report an issue",
type: "default",
form: {
fields: [
{
type: "dropdown",
placeholder: "Select severity...",
options: [
{
icon: "support",
text: "I'm unable to use the app",
threadDetails: {
severity: "critical",
issueType: "critical",
labelTypeIds: ["lt_01JFJWNWAC464N8DZ6YE71YJRF"],
priority: "u",
},
},
{
icon: "error",
text: "Major functionality degraded",
threadDetails: {
severity: "major",
issueType: "major",
labelTypeIds: ["lt_01JFJWP3KECF1YQES6XF212RFW"],
priority: "h",
},
},
{
icon: "bug",
text: "Minor annoyance",
threadDetails: {
severity: "minor",
issueType: "minor",
labelTypeIds: ["lt_01JFJWPC8ADW0PK28JHMJR6NSS"],
priority: "l",
},
},
],
},
],
},
},
],
entryPoint: {
type: "chat",
},
hideBranding: true,
theme: "auto",
style: {
brandColor: "#FFFFFF",
launcherBackgroundColor: "#262626",
launcherIconColor: "#FFFFFF",
},
position: {
bottom: "20px",
right: "20px",
},
};
if (process.env.NODE_ENV === "development" || process.env.NODE_ENV === "test") {
window.__PLAIN_CONFIG__ = plainChatConfig;
}
setConfig(plainChatConfig);
if (pathname === "/event-types" && searchParams?.has("openPlain")) {
const timer = setTimeout(() => {
if (window.Plain) {
window.Plain.open();
}
}, 100);
return () => clearTimeout(timer);
}
} catch (error) {
console.error("Failed to initialize Plain Chat:", error);
}
};
initConfig();
return () => window.removeEventListener("resize", checkScreenSize);
}, [session, pathname, searchParams, isAppDomain]);
}, [isAppDomain, checkScreenSize, initConfig, userEmail]);
const plainChatScript = `
window.plainScriptLoaded = function() {
@@ -239,7 +259,7 @@ const PlainChat = () => {
}
`;
if (!isAppDomain || isSmallScreen || !config) return null;
if (!isAppDomain || isSmallScreen || !config || typeof window === "undefined") return null;
return (
<>
+2 -1
View File
@@ -119,7 +119,8 @@
"PLAIN_API_KEY",
"PLAIN_API_URL",
"PLAIN_CHAT_ID",
"PLAIN_CHAT_HMAC_SECRET_KEY"
"PLAIN_CHAT_HMAC_SECRET_KEY",
"NEXT_PUBLIC_PLAIN_CHAT_EXCLUDED_PATHS"
]
},
"build": {