From db39f90c7f484becd9fec2f8280d4f3e7cf62bec Mon Sep 17 00:00:00 2001 From: n4ze3m Date: Sat, 23 Dec 2023 21:05:54 +0530 Subject: [PATCH 1/4] Fix widget positioning and add custom icon support --- app/script/src/button.ts | 18 ++- app/script/src/index.ts | 14 +- app/script/src/widget.ts | 64 ++++++---- .../Bot/Appearance/AppearancePreview.tsx | 120 +++++++++--------- app/ui/src/components/Bot/Playground/Form.tsx | 2 +- app/widget/src/components/BotForm.tsx | 92 ++++---------- app/widget/src/components/BotHeader.tsx | 83 +++++++++--- app/widget/src/index.css | 6 +- 8 files changed, 209 insertions(+), 190 deletions(-) diff --git a/app/script/src/button.ts b/app/script/src/button.ts index 4b64b7bb..31158e31 100644 --- a/app/script/src/button.ts +++ b/app/script/src/button.ts @@ -1,15 +1,15 @@ import { CLOSE_SVG, OPEN_SVG } from "./svg"; import { ButtonContainerStyle, ChatButtonStyle } from "./types"; -export function createChatButton( - scriptElement: HTMLScriptElement, -): void { +export function createChatButton(scriptElement: HTMLScriptElement): void { let buttonContainer: HTMLDivElement = document.createElement("div"); let buttonContainerStyle: ButtonContainerStyle = buttonContainer.style; buttonContainerStyle.display = "block"; buttonContainerStyle.position = "fixed"; + const widgetIcon = scriptElement.getAttribute("data-widget-icon"); const position = scriptElement.getAttribute("data-btn-position"); + const color = scriptElement.getAttribute("data-widget-btn-color") || "#9b59b6"; if (position === "bottom-left") { buttonContainerStyle.bottom = "20px"; @@ -31,11 +31,13 @@ export function createChatButton( buttonContainerStyle.zIndex = "999999"; let chatButton: HTMLButtonElement = document.createElement("button"); chatButton.setAttribute("id", "dialoq-btn"); - chatButton.innerHTML = OPEN_SVG; + chatButton.innerHTML = widgetIcon + ? `` + : OPEN_SVG; chatButton.onclick = function () { let widgetContainer: HTMLDivElement = document.querySelector( - "#dialoq", + "#dialoq" ) as HTMLDivElement; if (widgetContainer) { if (widgetContainer.style.display === "none") { @@ -43,7 +45,9 @@ export function createChatButton( chatButton.innerHTML = CLOSE_SVG; } else { widgetContainer.style.display = "none"; - chatButton.innerHTML = OPEN_SVG; + chatButton.innerHTML = widgetIcon + ? `` + : OPEN_SVG; } } else { console.log("widgetContainer not found"); @@ -51,7 +55,7 @@ export function createChatButton( }; let chatButtonStyle: ChatButtonStyle = chatButton.style; - chatButtonStyle.backgroundColor = "#9b59b6"; + chatButtonStyle.backgroundColor = color; chatButtonStyle.color = "white"; chatButtonStyle.width = "50px"; chatButtonStyle.height = "50px"; diff --git a/app/script/src/index.ts b/app/script/src/index.ts index ee4c79ce..2a081dbd 100644 --- a/app/script/src/index.ts +++ b/app/script/src/index.ts @@ -2,8 +2,10 @@ import { createChatButton } from "./button"; import { OPEN_SVG } from "./svg"; import { createChatWidget } from "./widget"; function setupChatWidget(): void { - let scriptElement: HTMLScriptElement = document - .currentScript as HTMLScriptElement; + let scriptElement: HTMLScriptElement = + document.currentScript as HTMLScriptElement; + + const widgetIcon = scriptElement.getAttribute("data-widget-icon"); if (document.readyState === "complete") { createChatButton(scriptElement); @@ -21,16 +23,18 @@ function setupChatWidget(): void { // close dailoq widget if (event.data === "db-iframe-close") { let widgetContainer: HTMLDivElement = document.querySelector( - "#dialoq", + "#dialoq" ) as HTMLDivElement; let chatButton: HTMLButtonElement = document.querySelector( - "#dialoq-btn", + "#dialoq-btn" ) as HTMLButtonElement; if (widgetContainer) { widgetContainer.style.display = "none"; } if (chatButton) { - chatButton.innerHTML = OPEN_SVG; + chatButton.innerHTML = widgetIcon + ? `` + : OPEN_SVG; } } }); diff --git a/app/script/src/widget.ts b/app/script/src/widget.ts index d1c48ddb..caed5b5a 100644 --- a/app/script/src/widget.ts +++ b/app/script/src/widget.ts @@ -4,11 +4,10 @@ import { WindowWithMatchMedia, } from "./types"; -export function createChatWidget( - scriptElement: HTMLScriptElement, -): void { - let mediaQuery: MediaQueryList = (window as WindowWithMatchMedia) - .matchMedia("(min-width: 768px)"); +export function createChatWidget(scriptElement: HTMLScriptElement): void { + let mediaQuery: MediaQueryList = (window as WindowWithMatchMedia).matchMedia( + "(min-width: 768px)" + ); let widgetContainer: HTMLDivElement = document.createElement("div"); widgetContainer.setAttribute("id", "dialoq"); let widgetContainerStyle: WidgetContainerStyle = widgetContainer.style; @@ -70,28 +69,49 @@ export function createChatWidget( widgetContainerStyle.height = "100%"; iframeStyle.borderRadius = "0"; iframeStyle.border = "0"; - if (position === "bottom-left") { - widgetContainerStyle.bottom = "80px"; - widgetContainerStyle.left = "20px"; - } else if (position === "bottom-right") { - widgetContainerStyle.bottom = "80px"; - widgetContainerStyle.right = "20px"; - } else if (position === "top-left") { - widgetContainerStyle.top = "80px"; - widgetContainerStyle.left = "20px"; - } else if (position === "top-right") { - widgetContainerStyle.top = "80px"; - widgetContainerStyle.right = "20px"; - } else { - widgetContainerStyle.bottom = "80px"; - widgetContainerStyle.right = "20px"; - } + // make iframe full screen + iframeStyle.position = "fixed"; + iframeStyle.top = "0"; + iframeStyle.left = "0"; + iframeStyle.right = "0"; + iframeStyle.bottom = "0"; + // make it fit the screen + iframeStyle.width = "100%"; + iframeStyle.height = "100%"; } widgetContainer.appendChild(iframe); let chatbotUrl: string = scriptElement.getAttribute( - "data-chat-url", + "data-chat-url" ) as string; let iframeSource: string = `${chatbotUrl}?mode=iframe`; iframe.src = iframeSource; document.body.appendChild(widgetContainer); + + // listen to media query changes + mediaQuery.addEventListener("change", (e) => { + if (e.matches) { + widgetContainerStyle.width = "400px"; + // make it not full screen + iframeStyle.position = "absolute"; + iframeStyle.right = "0"; + iframeStyle.top = "0"; + iframeStyle.width = "100%"; + iframeStyle.height = "100%"; + + } else { + widgetContainerStyle.width = "100%"; + widgetContainerStyle.height = "100%"; + iframeStyle.borderRadius = "0"; + iframeStyle.border = "0"; + // make iframe full screen + iframeStyle.position = "fixed"; + iframeStyle.top = "0"; + iframeStyle.left = "0"; + iframeStyle.right = "0"; + iframeStyle.bottom = "0"; + // make it fit the screen + iframeStyle.width = "100%"; + iframeStyle.height = "100%"; + } + }); } diff --git a/app/ui/src/components/Bot/Appearance/AppearancePreview.tsx b/app/ui/src/components/Bot/Appearance/AppearancePreview.tsx index ab0e6aef..642e6905 100644 --- a/app/ui/src/components/Bot/Appearance/AppearancePreview.tsx +++ b/app/ui/src/components/Bot/Appearance/AppearancePreview.tsx @@ -19,22 +19,42 @@ export const AppearancePreview = ({ form }: { form: FormInstance }) => {

{botName}

- +
+ + + + +
@@ -79,58 +99,34 @@ export const AppearancePreview = ({ form }: { form: FormInstance }) => {
-
-
+
+
- - - -
-
+ +