feat: 论坛 emoji 表情支持

- 新增 dyEmoji 表情库与解析测试、EmojiPicker 选择器与 EmojiImg 组件
- Markdown 编辑器/渲染支持表情图片,新增 public/emoji 资源与生成脚本
- 聊天室与首页适配
This commit is contained in:
2026-09-28 01:28:41 +08:00
parent 2f96a36275
commit 34aee91a13
3522 changed files with 1560 additions and 251 deletions

View File

@@ -42,6 +42,29 @@ export default function MdImage({ src, alt, title, className, ...rest }: MdImage
const provided = (typeof alt === "string" ? alt.trim() : "") || (typeof title === "string" ? title.trim() : "");
const imgAlt = provided || "图片";
// 抖音表情(/emoji/ 路径):行内小图,不进图箱、不带 caption;
// alt 由 expandDyEmojiShortcodes 产出("dy:<key>"),悬停 title 显示其短代码
const isEmoji = typeof src === "string" && src.includes("/emoji/");
const emojiSc =
typeof alt === "string" && alt.startsWith("dy:") ? `[:${alt.slice(3)}:]` : undefined;
if (isEmoji && !broken) {
return (
/* eslint-disable-next-line @next/next/no-img-element */
<img
{...rest}
src={src}
alt={imgAlt}
title={emojiSc}
className={`j13-md-emoji${className ? ` ${className}` : ""}`}
loading="lazy"
decoding="async"
draggable={false}
onContextMenu={(e) => e.preventDefault()}
onError={() => setBroken(true)}
/>
);
}
if (!src || broken) {
return (
<span className="md-img-fallback" role="img" aria-label={provided || "图片加载失败"}>