chore: bump version to v0.9.62 and add showPopup feature to widget
This commit is contained in:
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "vocechat-web",
|
"name": "vocechat-web",
|
||||||
"version": "0.9.61",
|
"version": "0.9.62",
|
||||||
"homepage": "https://voce.chat",
|
"homepage": "https://voce.chat",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@metamask/onboarding": "^1.0.1",
|
"@metamask/onboarding": "^1.0.1",
|
||||||
|
|||||||
+4
-1
@@ -18,6 +18,7 @@
|
|||||||
popupSubtitle = "Our staff are always ready to help!",
|
popupSubtitle = "Our staff are always ready to help!",
|
||||||
popupImage = "",
|
popupImage = "",
|
||||||
popupClosable = "true",
|
popupClosable = "true",
|
||||||
|
showPopup = "true",
|
||||||
useShadowDom = "true"
|
useShadowDom = "true"
|
||||||
} = d.currentScript.dataset;
|
} = d.currentScript.dataset;
|
||||||
const _src = d.currentScript.src;
|
const _src = d.currentScript.src;
|
||||||
@@ -74,6 +75,7 @@
|
|||||||
|
|
||||||
// 加载并执行 widget 脚本
|
// 加载并执行 widget 脚本
|
||||||
const script = d.createElement("script");
|
const script = d.createElement("script");
|
||||||
|
script.type = "text/javascript";
|
||||||
script.src = `${origin}${manifest.files["widget.js"]}`;
|
script.src = `${origin}${manifest.files["widget.js"]}`;
|
||||||
script.onload = () => {
|
script.onload = () => {
|
||||||
// 脚本加载完成后,需要手动初始化 React 应用到 shadow DOM
|
// 脚本加载完成后,需要手动初始化 React 应用到 shadow DOM
|
||||||
@@ -91,6 +93,7 @@
|
|||||||
popupSubtitle,
|
popupSubtitle,
|
||||||
popupImage,
|
popupImage,
|
||||||
popupClosable,
|
popupClosable,
|
||||||
|
showPopup,
|
||||||
embed: "true",
|
embed: "true",
|
||||||
closeWidth,
|
closeWidth,
|
||||||
closeHeight,
|
closeHeight,
|
||||||
@@ -131,7 +134,7 @@
|
|||||||
Object.assign(wrapper.style, baseStyles);
|
Object.assign(wrapper.style, baseStyles);
|
||||||
wrapper.src = `${origin}/widget.html?id=${id}&host=${hostId}&autoReg=${autoReg}&token=${loginToken}&themeColor=${encodeURIComponent(
|
wrapper.src = `${origin}/widget.html?id=${id}&host=${hostId}&autoReg=${autoReg}&token=${loginToken}&themeColor=${encodeURIComponent(
|
||||||
themeColor
|
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}`;
|
)}&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}`;
|
||||||
wrapper.width = actualCloseWidth;
|
wrapper.width = actualCloseWidth;
|
||||||
wrapper.height = actualCloseHeight;
|
wrapper.height = actualCloseHeight;
|
||||||
wrapper.frameborder = 0;
|
wrapper.frameborder = 0;
|
||||||
|
|||||||
@@ -1,3 +1,18 @@
|
|||||||
|
// 在 Shadow DOM 模式下,动态设置 webpack 的 publicPath
|
||||||
|
// 这样 webpack 运行时加载的动态资源(如代码分割的 chunk)会从正确的源服务器加载
|
||||||
|
if (typeof document !== 'undefined') {
|
||||||
|
const currentScript = document.currentScript as HTMLScriptElement;
|
||||||
|
if (currentScript && currentScript.src) {
|
||||||
|
try {
|
||||||
|
const scriptUrl = new URL(currentScript.src);
|
||||||
|
// 设置为脚本所在的目录路径
|
||||||
|
__webpack_public_path__ = scriptUrl.origin + '/';
|
||||||
|
} catch (e) {
|
||||||
|
console.warn('Failed to set webpack public path:', e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
import ReactDOM from "react-dom/client";
|
import ReactDOM from "react-dom/client";
|
||||||
import { Toaster } from "react-hot-toast";
|
import { Toaster } from "react-hot-toast";
|
||||||
import { Provider } from "react-redux";
|
import { Provider } from "react-redux";
|
||||||
|
|||||||
Vendored
+4
@@ -33,6 +33,10 @@ interface BeforeInstallPromptEvent extends Event {
|
|||||||
export declare global {
|
export declare global {
|
||||||
import { PrecacheEntry } from "workbox-precaching/src/_types";
|
import { PrecacheEntry } from "workbox-precaching/src/_types";
|
||||||
import localforage from "localforage";
|
import localforage from "localforage";
|
||||||
|
|
||||||
|
// Webpack public path for dynamic imports
|
||||||
|
var __webpack_public_path__: string;
|
||||||
|
|
||||||
interface Document {
|
interface Document {
|
||||||
webkitHidden: boolean;
|
webkitHidden: boolean;
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -10,7 +10,7 @@ type Props = {
|
|||||||
|
|
||||||
const Icon = ({ handleClick }: Props) => {
|
const Icon = ({ handleClick }: Props) => {
|
||||||
const serverLogo = useAppSelector((store) => store.server.logo, shallowEqual);
|
const serverLogo = useAppSelector((store) => store.server.logo, shallowEqual);
|
||||||
const { popupTitle, popupSubtitle, popupImage, logo: customLogo, popupClosable } = useWidget();
|
const { popupTitle, popupSubtitle, popupImage, logo: customLogo, popupClosable, showPopup } = useWidget();
|
||||||
const [tooltipVisible, setTooltipVisible] = useState(true);
|
const [tooltipVisible, setTooltipVisible] = useState(true);
|
||||||
|
|
||||||
// 优先使用自定义 logo,否则使用服务器 logo
|
// 优先使用自定义 logo,否则使用服务器 logo
|
||||||
@@ -19,8 +19,8 @@ const Icon = ({ handleClick }: Props) => {
|
|||||||
// 检测是否是移动端
|
// 检测是否是移动端
|
||||||
const isMobile = typeof window !== 'undefined' && window.innerWidth < 768;
|
const isMobile = typeof window !== 'undefined' && window.innerWidth < 768;
|
||||||
|
|
||||||
// 是否显示 tooltip(桌面端 + 有内容 + 用户未关闭)
|
// 是否显示 tooltip(桌面端 + 有内容 + 用户未关闭 + showPopup 开关打开)
|
||||||
const showTooltip = !isMobile && tooltipVisible && (popupTitle || popupSubtitle);
|
const showTooltip = !isMobile && tooltipVisible && (popupTitle || popupSubtitle) && showPopup;
|
||||||
|
|
||||||
if (!logo) return null;
|
if (!logo) return null;
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ const popupTitle = decodeURIComponent(query.get("popupTitle") || "Need help?");
|
|||||||
const popupSubtitle = decodeURIComponent(query.get("popupSubtitle") || "Our staff are always ready to help!");
|
const popupSubtitle = decodeURIComponent(query.get("popupSubtitle") || "Our staff are always ready to help!");
|
||||||
const popupImage = decodeURIComponent(query.get("popupImage") || "");
|
const popupImage = decodeURIComponent(query.get("popupImage") || "");
|
||||||
const popupClosable = decodeURIComponent(query.get("popupClosable") || "true") == "true";
|
const popupClosable = decodeURIComponent(query.get("popupClosable") || "true") == "true";
|
||||||
|
const showPopup = decodeURIComponent(query.get("showPopup") || "true") == "true";
|
||||||
const fgColor = getContrastColor(color);
|
const fgColor = getContrastColor(color);
|
||||||
// 从 URL 参数读取 embed 状态,如果没有则检测是否在 iframe 中
|
// 从 URL 参数读取 embed 状态,如果没有则检测是否在 iframe 中
|
||||||
const embedParam = query.get("embed");
|
const embedParam = query.get("embed");
|
||||||
@@ -49,6 +50,7 @@ const WidgetContext = createContext({
|
|||||||
popupSubtitle,
|
popupSubtitle,
|
||||||
popupImage,
|
popupImage,
|
||||||
popupClosable,
|
popupClosable,
|
||||||
|
showPopup,
|
||||||
serverVersion: "",
|
serverVersion: "",
|
||||||
openWidth,
|
openWidth,
|
||||||
openHeight,
|
openHeight,
|
||||||
@@ -84,6 +86,7 @@ function WidgetProvider({ children }: { children: ReactNode }) {
|
|||||||
popupSubtitle,
|
popupSubtitle,
|
||||||
popupImage,
|
popupImage,
|
||||||
popupClosable,
|
popupClosable,
|
||||||
|
showPopup,
|
||||||
serverVersion: data,
|
serverVersion: data,
|
||||||
openWidth,
|
openWidth,
|
||||||
openHeight,
|
openHeight,
|
||||||
|
|||||||
Reference in New Issue
Block a user