export const HOME_CHAT_ANIMATION_CONFIG_KEY = "home_chat_animation_config"; export const HOME_CHAT_ANIMATION_MAX_BYTES = 1024 * 1024; export type HomeChatAnimationConfig = { enabled: boolean; fileName: string; htmlContent: string; updatedAt: string | null; }; export function normalizeHomeChatAnimationHtml(value: unknown): string { if (typeof value !== "string") { return ""; } return value .replace(/^\uFEFF/, "") .replace(/\u0000/g, "") .replace(/\u2028|\u2029/g, "\n"); } export function getHomeChatAnimationHtmlBytes(htmlContent: string): number { return Buffer.byteLength(htmlContent, "utf8"); } export function normalizeHomeChatAnimationConfig( value: unknown, ): HomeChatAnimationConfig { const raw = value && typeof value === "object" && !Array.isArray(value) ? (value as Record) : {}; const enabled = raw.enabled === true; const fileName = String(raw.fileName || "").trim().slice(0, 255); const htmlContent = normalizeHomeChatAnimationHtml(raw.htmlContent); const updatedAt = String(raw.updatedAt || "").trim() || null; return { enabled, fileName, htmlContent, updatedAt, }; } export function getDefaultHomeChatAnimationHtml(): string { return ""; } export function resolvePublicHomeChatAnimationConfig( value: unknown, ): HomeChatAnimationConfig & { usesDefaultFallback: boolean } { const normalized = normalizeHomeChatAnimationConfig(value); const fallbackHtml = getDefaultHomeChatAnimationHtml(); const htmlContent = normalized.htmlContent || fallbackHtml; const usesDefaultFallback = !normalized.htmlContent && Boolean(fallbackHtml); if (!normalized.enabled || !htmlContent) { return { enabled: false, fileName: normalized.fileName, htmlContent: "", updatedAt: normalized.updatedAt, usesDefaultFallback, }; } return { enabled: true, fileName: normalized.fileName || (usesDefaultFallback ? "动画效果.html" : ""), htmlContent, updatedAt: normalized.updatedAt, usesDefaultFallback, }; }