mirror of https://github.com/msgbyte/tailchat
feat: 喵语翻译与消息解释器
parent
6490901b64
commit
12af2a86b2
@ -0,0 +1,43 @@
|
|||||||
|
## 如何创建一个插件
|
||||||
|
|
||||||
|
### 内部插件
|
||||||
|
|
||||||
|
> 内部插件是指随 `tailchat` 分发而提供的插件
|
||||||
|
|
||||||
|
在web目录执行:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
yarn ministar createPlugin
|
||||||
|
```
|
||||||
|
|
||||||
|
插件名请准守反域名模式, 如: `com.msgbyte.xxx`
|
||||||
|
|
||||||
|
设置`tsconfig.json`如下:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"rootDir": "./src",
|
||||||
|
"baseUrl": "./src",
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"jsx": "react",
|
||||||
|
"paths": {
|
||||||
|
"@capital/*": ["../../../src/plugin/*"],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
创建一个`manifest.json`文件
|
||||||
|
|
||||||
|
示例:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"label": "网页面板插件",
|
||||||
|
"name": "com.msgbyte.webview",
|
||||||
|
"url": "/plugins/com.msgbyte.webview/index.js",
|
||||||
|
"version": "0.0.0",
|
||||||
|
"author": "msgbyte",
|
||||||
|
"description": "为群组提供创建网页面板的功能",
|
||||||
|
"requireRestart": false
|
||||||
|
}
|
||||||
|
```
|
@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"label": "喵语言",
|
||||||
|
"name": "com.msgbyte.miaolang",
|
||||||
|
"url": "/plugins/com.msgbyte.miaolang/index.js",
|
||||||
|
"version": "0.0.0",
|
||||||
|
"author": "msgbyte",
|
||||||
|
"description": "为聊天提供喵语言对话功能",
|
||||||
|
"requireRestart": true
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"name": "@plugins/com.msgbyte.miaolang",
|
||||||
|
"main": "src/index.ts",
|
||||||
|
"version": "0.0.0",
|
||||||
|
"private": true,
|
||||||
|
"dependencies": {
|
||||||
|
"miao-lang": "^1.0.3"
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
import { decode, encode, isMiao } from './trans';
|
||||||
|
import { regMessageInterpreter } from '@capital/common';
|
||||||
|
|
||||||
|
const miao = encode('喵语翻译已加载');
|
||||||
|
const human = decode(miao);
|
||||||
|
|
||||||
|
console.log(`${miao}\n${human}`);
|
||||||
|
|
||||||
|
regMessageInterpreter({
|
||||||
|
name: '喵语翻译',
|
||||||
|
explainMessage(message: string) {
|
||||||
|
// 喵语 -> 人话
|
||||||
|
if (!isMiao(message)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return decode(message);
|
||||||
|
},
|
||||||
|
});
|
@ -0,0 +1,13 @@
|
|||||||
|
import Miao from 'miao-lang';
|
||||||
|
|
||||||
|
export function encode(human: string): string {
|
||||||
|
return Miao.encode(human);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function decode(miao: string): string {
|
||||||
|
return Miao.decode(miao);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isMiao(input: string): boolean {
|
||||||
|
return Miao.isMiao(input);
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"rootDir": "./src",
|
||||||
|
"baseUrl": "./src",
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"jsx": "react",
|
||||||
|
"paths": {
|
||||||
|
"@capital/*": ["../../../src/plugin/*"],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,15 @@
|
|||||||
|
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
||||||
|
# yarn lockfile v1
|
||||||
|
|
||||||
|
|
||||||
|
js-base64@^3.6.0:
|
||||||
|
version "3.6.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-3.6.1.tgz#555aae398b74694b4037af1f8a5a6209d170efbe"
|
||||||
|
integrity sha512-Frdq2+tRRGLQUIQOgsIGSCd1VePCS2fsddTG5dTCqR0JHgltXWfsxnY0gIXPoMeRmdom6Oyq+UMOFg5suduOjQ==
|
||||||
|
|
||||||
|
miao-lang@^1.0.3:
|
||||||
|
version "1.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/miao-lang/-/miao-lang-1.0.3.tgz#276999788f6eee2b600db66a0d72b3f53bcbd6ab"
|
||||||
|
integrity sha512-AXxAKfRUSFwvF0RMJ8qkUtUbVHdNqGA71k+4/38ikh2mK1iRoiDueuTannVF+9NqzSXi770GKMuGEFXu/+Ithg==
|
||||||
|
dependencies:
|
||||||
|
js-base64 "^3.6.0"
|
@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"label": "网页面板插件",
|
||||||
|
"name": "com.msgbyte.webview",
|
||||||
|
"url": "/plugins/com.msgbyte.webview/index.js",
|
||||||
|
"version": "0.0.0",
|
||||||
|
"author": "msgbyte",
|
||||||
|
"description": "为群组提供创建网页面板的功能",
|
||||||
|
"requireRestart": false
|
||||||
|
}
|
@ -0,0 +1,52 @@
|
|||||||
|
import { messageInterpreter } from '@/plugin/common';
|
||||||
|
import { Icon } from '@iconify/react';
|
||||||
|
import { Popover } from 'antd';
|
||||||
|
import React from 'react';
|
||||||
|
import { useMemo } from 'react';
|
||||||
|
import { t } from 'tailchat-shared';
|
||||||
|
|
||||||
|
export function useRenderPluginMessageInterpreter(message: string) {
|
||||||
|
const availableInterpreter = useMemo(
|
||||||
|
() =>
|
||||||
|
messageInterpreter
|
||||||
|
.map(({ name, explainMessage }) => ({
|
||||||
|
name,
|
||||||
|
render: explainMessage(message),
|
||||||
|
}))
|
||||||
|
.filter(({ render }) => render !== null),
|
||||||
|
[message]
|
||||||
|
);
|
||||||
|
|
||||||
|
if (availableInterpreter.length === 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<span className="align-middle hidden group-hover:inline-block">
|
||||||
|
<Popover
|
||||||
|
placement="topLeft"
|
||||||
|
title={t('消息解释')}
|
||||||
|
content={
|
||||||
|
<div className="max-w-lg">
|
||||||
|
{availableInterpreter.map((ai, i) => (
|
||||||
|
<p key={i + (ai.name ?? '')}>
|
||||||
|
{ai.name && (
|
||||||
|
<span>
|
||||||
|
{t('来自')} {ai.name} :{' '}
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
{ai.render}
|
||||||
|
</p>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
trigger="click"
|
||||||
|
>
|
||||||
|
<Icon
|
||||||
|
className="cursor-pointer text-base"
|
||||||
|
icon="mdi:file-question-outline"
|
||||||
|
/>
|
||||||
|
</Popover>
|
||||||
|
</span>
|
||||||
|
);
|
||||||
|
}
|
Loading…
Reference in New Issue