feat: add theme color param to widget
This commit is contained in:
@@ -195,6 +195,7 @@
|
||||
"default_value": "Default Value",
|
||||
"remark": "Remarks",
|
||||
"param_host": "Assign the user chatting with visitor(User ID)",
|
||||
"param_theme_color": "The theme color of widget",
|
||||
"param_close_width": "The width while widget closed",
|
||||
"param_close_height": "The height while widget closed",
|
||||
"param_open_width": "The width while widget opened",
|
||||
|
||||
@@ -190,6 +190,7 @@
|
||||
"default_value": "默认值",
|
||||
"remark": "备注",
|
||||
"param_host": "指定和谁聊天(用户ID)",
|
||||
"param_theme_color": "挂件的主题色",
|
||||
"param_close_width": "挂件关闭态的宽度",
|
||||
"param_close_height": "挂件关闭态的高度",
|
||||
"param_open_width": "挂件打开态的宽度",
|
||||
|
||||
+3
-2
@@ -3,7 +3,8 @@ const {
|
||||
closeWidth = 48,
|
||||
closeHeight = 48,
|
||||
openWidth = 380,
|
||||
openHeight = 680
|
||||
openHeight = 680,
|
||||
themeColor = "#1fe1f9"
|
||||
} = document.currentScript.dataset;
|
||||
const _src = document.currentScript.src;
|
||||
const wrapper = document.createElement("iframe");
|
||||
@@ -17,7 +18,7 @@ const styles = {
|
||||
boxShadow: `rgb(0 0 0 / 25%) 0px 25px 50px -12px`
|
||||
};
|
||||
Object.assign(wrapper.style, styles);
|
||||
wrapper.src = `${new URL(_src).origin}/widget.html?host=${hostId}`;
|
||||
wrapper.src = `${new URL(_src).origin}/widget.html?host=${hostId}&themeColor=${themeColor}`;
|
||||
wrapper.width = closeWidth;
|
||||
wrapper.height = closeHeight;
|
||||
wrapper.frameborder = 0;
|
||||
|
||||
@@ -8,8 +8,9 @@ import './i18n';
|
||||
|
||||
const root = ReactDOM.createRoot(document.getElementById("root") as HTMLElement);
|
||||
const hostId = new URLSearchParams(location.search).get("host");
|
||||
const themeColor = new URLSearchParams(location.search).get("themeColor") || "#1fe1f9";
|
||||
root.render(
|
||||
hostId ? <Provider store={store}>
|
||||
<Widget hostId={Number(hostId)} />
|
||||
<Widget hostId={Number(hostId)} themeColor={themeColor} />
|
||||
</Provider> : null
|
||||
);
|
||||
|
||||
@@ -29,7 +29,7 @@ export default function Widget() {
|
||||
{t('code')}:
|
||||
</label>
|
||||
<SyntaxHighlighter id="code" language="html" style={vscDarkPlus} className="rounded">
|
||||
{`<!-- ${t('code_comment')} -->\n<script \n data-host-id="1" \n data-close-width="48" \n data-close-height="48" \n data-open-width="380" \n data-open-height="680" \n src="${location.origin}/widget.js" \n async \n/>`}
|
||||
{`<!-- ${t('code_comment')} -->\n<script \n data-host-id="1" \n data-theme-color="#1fe1f9" \n data-close-width="48" \n data-close-height="48" \n data-open-width="380" \n data-open-height="680" \n src="${location.origin}/widget.js" \n async \n/>`}
|
||||
</SyntaxHighlighter>
|
||||
<div className="text-gray-500 dark:text-white text-sm mt-5 mb-2">
|
||||
{t('config')}:
|
||||
@@ -48,6 +48,10 @@ export default function Widget() {
|
||||
paramKey: "host-id",
|
||||
paramDefault: 1,
|
||||
remarks: t("param_host")
|
||||
}, {
|
||||
paramKey: "theme-color",
|
||||
paramDefault: "#1fe1f9",
|
||||
remarks: t("param_theme_color")
|
||||
}, {
|
||||
paramKey: "close-width",
|
||||
paramDefault: `48(px)`,
|
||||
|
||||
@@ -4,12 +4,13 @@ import IconClose from './close.svg';
|
||||
|
||||
type Props = {
|
||||
handleClose: () => void;
|
||||
themeColor?: string
|
||||
};
|
||||
|
||||
const Index: FC<Props> = ({ handleClose }) => {
|
||||
const Index: FC<Props> = ({ handleClose, themeColor = "#1fe1f9" }) => {
|
||||
const { name, logo } = useAppSelector(store => store.server);
|
||||
return (
|
||||
<header className="relative flex justify-between items-center h-14 px-4 bg-[#1fe1f9]">
|
||||
<header className="relative flex justify-between items-center h-14 px-4" style={{ backgroundColor: themeColor }}>
|
||||
<div className="relative w-8 h-8">
|
||||
<img src={logo} alt="logo" className="w-full h-full rounded-full" />
|
||||
</div>
|
||||
|
||||
@@ -9,10 +9,11 @@ import useSSE from '../useSSE';
|
||||
|
||||
type Props = {
|
||||
hostId: number,
|
||||
themeColor?: string,
|
||||
handleClose: () => void
|
||||
}
|
||||
|
||||
const Index = ({ handleClose, hostId }: Props) => {
|
||||
const Index = ({ handleClose, hostId, themeColor }: Props) => {
|
||||
// 建立SSE连接
|
||||
useSSE();
|
||||
const { user: loginUser, token, guest: isGuest } = useAppSelector(store => store.authData);
|
||||
@@ -21,7 +22,7 @@ const Index = ({ handleClose, hostId }: Props) => {
|
||||
const notLogin = !token || isGuest;
|
||||
return (
|
||||
<aside className="flex flex-col bg-white w-full h-full rounded-md overflow-hidden">
|
||||
<Header handleClose={handleClose} />
|
||||
<Header themeColor={themeColor} handleClose={handleClose} />
|
||||
{/* message list */}
|
||||
<main id='MESSAGE_LIST_CONTAINER' className="relative flex-1 overflow-y-auto scroll-smooth">
|
||||
{/* placeholder */}
|
||||
|
||||
@@ -5,10 +5,11 @@ import Icon from "./Icon";
|
||||
import Popup from "./Popup";
|
||||
import useCache from "./useCache";
|
||||
type Props = {
|
||||
hostId: number
|
||||
hostId: number,
|
||||
themeColor?: string
|
||||
};
|
||||
|
||||
function Widget({ hostId }: Props) {
|
||||
function Widget({ hostId, themeColor }: Props) {
|
||||
const { rehydrated } = useCache();
|
||||
const [visible, setVisible] = useState(!!new URLSearchParams(location.search).get("open"));
|
||||
const { isLoading, isError } = useGetServerQuery();
|
||||
@@ -21,7 +22,7 @@ function Widget({ hostId }: Props) {
|
||||
setVisible((prev) => !prev);
|
||||
};
|
||||
if (isLoading || isError || !rehydrated) return null;
|
||||
return visible ? <Popup handleClose={toggleVisible} hostId={hostId} /> : <Icon handleClick={toggleVisible} />;
|
||||
return visible ? <Popup handleClose={toggleVisible} hostId={hostId} themeColor={themeColor} /> : <Icon handleClick={toggleVisible} />;
|
||||
}
|
||||
|
||||
export default Widget;
|
||||
|
||||
Reference in New Issue
Block a user