diff --git a/package.json b/package.json index ec0a1522..ee13148a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "vocechat-web", - "version": "0.9.68", + "version": "0.9.69", "homepage": "https://voce.chat", "dependencies": { "@metamask/onboarding": "^1.0.1", diff --git a/public/widget.js b/public/widget.js index 9618cd63..1e0b58f0 100644 --- a/public/widget.js +++ b/public/widget.js @@ -78,6 +78,8 @@ script.src = `${origin}${manifest.files["widget.js"]}`; script.onload = () => { // 脚本加载完成后,需要手动初始化 React 应用到 shadow DOM + // 检测父窗口是否为移动端 + const isMobile = w.innerWidth < 768; const params = new URLSearchParams({ id, host: hostId, @@ -97,7 +99,8 @@ closeWidth, closeHeight, openWidth, - openHeight + openHeight, + isMobile }); // 将参数传递给 shadow DOM 内的应用 @@ -131,9 +134,11 @@ const wrapper = d.createElement("iframe"); wrapper.id = "VOCECHAT_WIDGET"; Object.assign(wrapper.style, baseStyles); + // 检测父窗口是否为移动端 + const isMobile = w.innerWidth < 768; wrapper.src = `${origin}/widget.html?id=${id}&host=${hostId}&autoReg=${autoReg}&token=${loginToken}&themeColor=${encodeURIComponent( themeColor - )}&from=${encodeURIComponent(location.hostname)}&welcome=${encodeURIComponent(welcome)}&title=${encodeURIComponent(title)}&logo=${encodeURIComponent(logo)}&popupTitle=${encodeURIComponent(popupTitle)}&popupSubtitle=${encodeURIComponent(popupSubtitle)}&popupImage=${encodeURIComponent(popupImage)}&popupClosable=${popupClosable}&showPopup=${showPopup}`; + )}&from=${encodeURIComponent(location.hostname)}&welcome=${encodeURIComponent(welcome)}&title=${encodeURIComponent(title)}&logo=${encodeURIComponent(logo)}&popupTitle=${encodeURIComponent(popupTitle)}&popupSubtitle=${encodeURIComponent(popupSubtitle)}&popupImage=${encodeURIComponent(popupImage)}&popupClosable=${popupClosable}&showPopup=${showPopup}&isMobile=${isMobile}`; wrapper.width = actualCloseWidth; wrapper.height = actualCloseHeight; wrapper.frameborder = 0; diff --git a/src/widget/Icon.tsx b/src/widget/Icon.tsx index a72359a7..2cd5f82c 100644 --- a/src/widget/Icon.tsx +++ b/src/widget/Icon.tsx @@ -10,14 +10,16 @@ type Props = { const Icon = ({ handleClick }: Props) => { const serverLogo = useAppSelector((store) => store.server.logo, shallowEqual); - const { popupTitle, popupSubtitle, popupImage, logo: customLogo, popupClosable, showPopup } = useWidget(); + const { popupTitle, popupSubtitle, popupImage, logo: customLogo, popupClosable, showPopup, embed, isMobile: isMobileFromContext } = useWidget(); const [tooltipVisible, setTooltipVisible] = useState(true); // 优先使用自定义 logo,否则使用服务器 logo const logo = customLogo || serverLogo; // 检测是否是移动端 - const isMobile = typeof window !== 'undefined' && window.innerWidth < 768; + // 在 embed 模式(iframe/shadow DOM)下,使用从父窗口传递的 isMobile 参数 + // 在非 embed 模式下,直接检测当前窗口宽度 + const isMobile = embed ? isMobileFromContext : (typeof window !== 'undefined' && window.innerWidth < 768); // 是否显示 tooltip(桌面端 + 有内容 + 用户未关闭 + showPopup 开关打开) const showTooltip = !isMobile && tooltipVisible && (popupTitle || popupSubtitle) && showPopup; diff --git a/src/widget/Popup/index.tsx b/src/widget/Popup/index.tsx index 66ac6134..0581fc46 100644 --- a/src/widget/Popup/index.tsx +++ b/src/widget/Popup/index.tsx @@ -32,7 +32,7 @@ const Index = ({ handleClose, hostId }: Props) => { className={clsx( "flex flex-col bg-white dark:bg-gray-700 rounded-md overflow-hidden shadow-xl", embed - ? "" + ? "border border-gray-200 dark:border-gray-600" : `w-full h-full md:max-w-lg md:h-[calc(100dvh_-_20px)] m-auto md:my-2 md:shadow-lg rounded-none md:rounded-md` )} style={embed ? { width: `${openWidth}px`, height: `${openHeight}px` } : {}} diff --git a/src/widget/WidgetContext.tsx b/src/widget/WidgetContext.tsx index 9b184e4e..396df239 100644 --- a/src/widget/WidgetContext.tsx +++ b/src/widget/WidgetContext.tsx @@ -32,6 +32,7 @@ const openWidth = parseInt(query.get("openWidth") || "380"); const openHeight = parseInt(query.get("openHeight") || "680"); const closeWidth = parseInt(query.get("closeWidth") || "48"); const closeHeight = parseInt(query.get("closeHeight") || "48"); +const isMobile = query.get("isMobile") === "true"; const WidgetContext = createContext({ id, token, @@ -55,7 +56,8 @@ const WidgetContext = createContext({ openWidth, openHeight, closeWidth, - closeHeight + closeHeight, + isMobile }); function WidgetProvider({ children }: { children: ReactNode }) { @@ -91,7 +93,8 @@ function WidgetProvider({ children }: { children: ReactNode }) { openWidth, openHeight, closeWidth, - closeHeight + closeHeight, + isMobile }} > {children}