feat: add theme color param to widget

This commit is contained in:
Tristan Yang
2023-02-08 17:27:10 +08:00
parent ffd68f2c06
commit 9cefd14565
8 changed files with 22 additions and 11 deletions
+1
View File
@@ -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",
+1
View File
@@ -190,6 +190,7 @@
"default_value": "默认值",
"remark": "备注",
"param_host": "指定和谁聊天(用户ID)",
"param_theme_color": "挂件的主题色",
"param_close_width": "挂件关闭态的宽度",
"param_close_height": "挂件关闭态的高度",
"param_open_width": "挂件打开态的宽度",
+3 -2
View File
@@ -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;
+2 -1
View File
@@ -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
);
+5 -1
View File
@@ -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)`,
+3 -2
View File
@@ -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>
+3 -2
View File
@@ -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 */}
+4 -3
View File
@@ -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;