diff --git a/web/plugins/com.msgbyte.bbcode/src/index.tsx b/web/plugins/com.msgbyte.bbcode/src/index.tsx
index b3d76b99..9ddecaf7 100644
--- a/web/plugins/com.msgbyte.bbcode/src/index.tsx
+++ b/web/plugins/com.msgbyte.bbcode/src/index.tsx
@@ -1,8 +1,19 @@
import React from 'react';
-import { regMessageRender } from '@capital/common';
+import { regMessageRender, regMessageTextDecorators } from '@capital/common';
import { BBCode } from './bbcode';
import './tags/__all__';
regMessageRender((message) => {
return ;
});
+
+regMessageTextDecorators(() => ({
+ url: (plain) => `[url]${plain}[/url]`,
+ image: (plain, attrs) => {
+ if (attrs.height && attrs.width) {
+ return `[img height=${attrs.height} width=${attrs.width}]${plain}[/img]`;
+ }
+
+ return `[img]${plain}[/img]`;
+ },
+}));
diff --git a/web/plugins/com.msgbyte.draw/src/DrawModal.tsx b/web/plugins/com.msgbyte.draw/src/DrawModal.tsx
index 4dbe9560..abb09720 100644
--- a/web/plugins/com.msgbyte.draw/src/DrawModal.tsx
+++ b/web/plugins/com.msgbyte.draw/src/DrawModal.tsx
@@ -1,6 +1,7 @@
import {
ChatInputActionContextProps,
dataUrlToFile,
+ getMessageTextDecorators,
uploadFile,
useAsyncFn,
} from '@capital/common';
@@ -33,7 +34,9 @@ const DrawModal: React.FC<{
const file = dataUrlToFile(dataUrl);
const res = await uploadFile(file);
- sendMsg(`[img width=400 height=400]${res.url}[/img]`);
+ sendMsg(
+ getMessageTextDecorators().image(res.url, { width: 400, height: 400 })
+ );
onSuccess();
}, [sendMsg, onSuccess]);
diff --git a/web/src/components/ChatBox/ChatInputBox/Addon.tsx b/web/src/components/ChatBox/ChatInputBox/Addon.tsx
index c915f6a5..c9946480 100644
--- a/web/src/components/ChatBox/ChatInputBox/Addon.tsx
+++ b/web/src/components/ChatBox/ChatInputBox/Addon.tsx
@@ -1,5 +1,8 @@
import { FileSelector } from '@/components/FileSelector';
-import { pluginChatInputActions } from '@/plugin/common';
+import {
+ getMessageTextDecorators,
+ pluginChatInputActions,
+} from '@/plugin/common';
import { Icon } from '@iconify/react';
import { Dropdown, Menu } from 'antd';
import React from 'react';
@@ -19,9 +22,8 @@ export const ChatInputAddon: React.FC = React.memo(() => {
if (image) {
// 发送图片
uploadMessageImage(image).then(({ url, width, height }) => {
- // TODO: not good, should bind with plugin bbcode
actionContext.sendMsg(
- `[img width=${width} height=${height}]${url}[/img]`
+ getMessageTextDecorators().image(url, { width, height })
);
});
}
diff --git a/web/src/components/ChatBox/ChatInputBox/index.tsx b/web/src/components/ChatBox/ChatInputBox/index.tsx
index 26f88cd5..c8b374a2 100644
--- a/web/src/components/ChatBox/ChatInputBox/index.tsx
+++ b/web/src/components/ChatBox/ChatInputBox/index.tsx
@@ -1,3 +1,4 @@
+import { getMessageTextDecorators } from '@/plugin/common';
import { isEnterHotkey } from '@/utils/hot-key';
import { Input } from 'antd';
import React, { useCallback, useRef, useState } from 'react';
@@ -37,8 +38,9 @@ export const ChatInputBox: React.FC = React.memo((props) => {
// 上传图片
e.preventDefault();
uploadMessageImage(image).then(({ url, width, height }) => {
- // TODO: not good, should bind with plugin bbcode
- props.onSendMsg(`[img width=${width} height=${height}]${url}[/img]`);
+ props.onSendMsg(
+ getMessageTextDecorators().image(url, { width, height })
+ );
});
}
},
diff --git a/web/src/plugin/common/reg.ts b/web/src/plugin/common/reg.ts
index dc4c1031..1b15a2be 100644
--- a/web/src/plugin/common/reg.ts
+++ b/web/src/plugin/common/reg.ts
@@ -96,6 +96,20 @@ export const [getMessageRender, regMessageRender] = buildRegFn<
(message: string) => React.ReactNode
>('message-render', (message) => message);
+/**
+ * 消息渲染器
+ * 输入消息,返回渲染节点
+ */
+export const [getMessageTextDecorators, regMessageTextDecorators] = buildRegFn<
+ () => {
+ url: (plain: string) => string;
+ image: (plain: string, attrs: Record) => string;
+ }
+>('message-text-decorators', () => ({
+ url: (plain: string) => plain,
+ image: (plain: string) => plain,
+}));
+
interface ChatInputAction {
label: string;
onClick: (actions: ChatInputActionContextProps) => void;