feat: add support chat widget demo and state management

- Implemented SupportWidgetDemo component for configuring and mounting the support chat widget.
- Introduced Zustand store for managing support chat state, including message handling and socket connection.
- Created support host bridge for communication between the widget and parent window.
- Added utility functions for JWT token generation and local storage management.
- Enhanced user experience with notifications for new messages and chat status updates.
This commit is contained in:
mlogclub
2026-05-30 14:00:23 +08:00
parent bcab31eaa8
commit 86ff71596d
28 changed files with 139 additions and 139 deletions
+9 -9
View File
@@ -51,12 +51,12 @@ export function renderIMMessageHTML(message: {
asset.filename || "image"
)}"></p>`
}
return `<p>${escapeHTML(t("kefu.imageSummary"))}</p>`
return `<p>${escapeHTML(t("supportChat.imageSummary"))}</p>`
}
if (message.messageType === "attachment") {
if (asset?.url) {
const title = escapeHTML(asset.filename || message.content || t("kefu.attachmentSummary"))
const title = escapeHTML(asset.filename || message.content || t("supportChat.attachmentSummary"))
const meta = formatFileSize(asset.fileSize ?? 0)
const metaHTML = meta ? `<div class="im-attachment-meta">${escapeHTML(meta)}</div>` : ""
return `<div class="im-attachment"><a href="${escapeHTMLAttr(
@@ -65,7 +65,7 @@ export function renderIMMessageHTML(message: {
asset.filename || ""
)}" class="im-attachment-link"><span class="im-attachment-icon" aria-hidden="true">${getAttachmentIconSVG()}</span><span class="im-attachment-content"><span class="im-attachment-title">${title}</span>${metaHTML}</span></a></div>`
}
return `<p>${escapeHTML(message.content || t("kefu.attachmentSummary"))}</p>`
return `<p>${escapeHTML(message.content || t("supportChat.attachmentSummary"))}</p>`
}
return renderTextMessageHTML(message.content || "")
@@ -77,13 +77,13 @@ export function summarizeIMMessage(message: {
payload?: string
}) {
if (message.messageType === "image") {
return t("kefu.imageSummary")
return t("supportChat.imageSummary")
}
if (message.messageType === "attachment") {
const asset = parseMessageAssetPayload(message.payload)
return asset?.filename?.trim()
? `${t("kefu.attachmentSummary")} ${asset.filename.trim()}`
: t("kefu.attachmentSummary")
? `${t("supportChat.attachmentSummary")} ${asset.filename.trim()}`
: t("supportChat.attachmentSummary")
}
if (message.messageType === "html") {
const text = extractTextFromHTML(message.content)
@@ -91,11 +91,11 @@ export function summarizeIMMessage(message: {
return text.substring(0, 100)
}
if (message.content.includes("<img")) {
return t("kefu.imageSummary")
return t("supportChat.imageSummary")
}
return t("kefu.messageSummary")
return t("supportChat.messageSummary")
}
return message.content?.substring(0, 100) || t("kefu.messageSummary")
return message.content?.substring(0, 100) || t("supportChat.messageSummary")
}
export function formatFileSize(size: number) {