Skip to content

Commit 1e00834

Browse files
committed
feat: 增加引用时可以跳转到某个面板
1 parent 998e7a6 commit 1e00834

File tree

9 files changed

+58
-4
lines changed

9 files changed

+58
-4
lines changed

client/web/plugins/com.msgbyte.bbcode/src/index.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ regMessageRender((message) => {
1919
});
2020

2121
regMessageTextDecorators(() => ({
22-
url: (plain) => `[url]${plain}[/url]`,
22+
url: (url, label?) =>
23+
label ? `[url=${url}]${label}[/url]` : `[url]${url}[/url]`,
2324
image: (plain, attrs) => {
2425
if (attrs.height && attrs.width) {
2526
return `[img height=${attrs.height} width=${attrs.width}]${plain}[/img]`;

client/web/plugins/com.msgbyte.bbcode/src/tags/UrlTag.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { Link } from '@capital/component';
12
import React from 'react';
23
import type { TagProps } from '../bbcode/type';
34

@@ -6,6 +7,11 @@ export const UrlTag: React.FC<TagProps> = React.memo((props) => {
67
const text = node.content.join('');
78
const url = node.attrs.url ?? text;
89

10+
if (url.startsWith('/') || url.startsWith(window.location.origin)) {
11+
// 内部地址,使用 react-router 进行导航
12+
return <Link to={url}>{text}</Link>;
13+
}
14+
915
return (
1016
<a href={url} title={text} target="_blank" rel="noopener noreferrer">
1117
{text}

client/web/src/App.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ export const App: React.FC = React.memo(() => {
142142
}
143143
/>
144144

145-
<Route path="/" element={<Navigate to="/entry" replace={true} />} />
145+
<Route path="/*" element={<Navigate to="/entry" replace={true} />} />
146146
</Routes>
147147
</AppContainer>
148148
</AppProvider>
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import React from 'react';
2+
import { Icon } from 'tailchat-design';
3+
4+
/**
5+
* 提及命令列表项
6+
*/
7+
export const MentionCommandItem: React.FC<{
8+
icon: string;
9+
label: string;
10+
}> = React.memo((props) => {
11+
return (
12+
<div className="flex items-center py-2 px-3">
13+
<Icon className="mr-1 text-lg" icon={props.icon} />
14+
15+
<div>{props.label}</div>
16+
</div>
17+
);
18+
});
19+
MentionCommandItem.displayName = 'MentionCommandItem';

client/web/src/components/ChatBox/ChatInputBox/context.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ export function useChatInputActionContext() {
2424
*/
2525
interface ChatInputMentionsContextProps extends PropsWithChildren {
2626
users: SuggestionDataItem[];
27+
panels: SuggestionDataItem[];
2728
placeholder?: string;
2829
disabled?: boolean;
2930
}
@@ -47,6 +48,7 @@ export function useChatInputMentionsContext(): ChatInputMentionsContextProps {
4748

4849
return {
4950
users: context?.users ?? [],
51+
panels: context?.panels ?? [],
5052
placeholder: context?.placeholder,
5153
disabled: context?.disabled,
5254
};

client/web/src/components/ChatBox/ChatInputBox/input.tsx

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { Mention, MentionsInput } from 'react-mentions';
66
import { t } from 'tailchat-shared';
77
import { useChatInputMentionsContext } from './context';
88
import './input.less';
9+
import { MentionCommandItem } from './MentionCommandItem';
910

1011
interface ChatInputBoxInputProps
1112
extends Omit<
@@ -18,7 +19,8 @@ interface ChatInputBoxInputProps
1819
}
1920
export const ChatInputBoxInput: React.FC<ChatInputBoxInputProps> = React.memo(
2021
(props) => {
21-
const { users, placeholder, disabled } = useChatInputMentionsContext();
22+
const { users, panels, placeholder, disabled } =
23+
useChatInputMentionsContext();
2224

2325
return (
2426
<MentionsInput
@@ -51,6 +53,16 @@ export const ChatInputBoxInput: React.FC<ChatInputBoxInputProps> = React.memo(
5153
)}
5254
markup={getMessageTextDecorators().mention('__id__', '__display__')}
5355
/>
56+
<Mention
57+
trigger="#"
58+
data={panels}
59+
displayTransform={(id, display) => `#${display}`}
60+
appendSpaceOnAdd={true}
61+
renderSuggestion={(suggestion) => (
62+
<MentionCommandItem icon="mdi:pound" label={suggestion.display} />
63+
)}
64+
markup={getMessageTextDecorators().url('__id__', '#__display__')}
65+
/>
5466
</MentionsInput>
5567
);
5668
}

client/web/src/components/Panel/group/TextPanel.tsx

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ import {
1111
useInterval,
1212
useHasGroupPermission,
1313
PERMISSION,
14+
useGroupInfo,
15+
GroupPanelType,
1416
} from 'tailchat-shared';
1517
import { GroupPanelWrapper } from './Wrapper';
1618

@@ -68,10 +70,15 @@ interface TextPanelProps {
6870
}
6971
export const TextPanel: React.FC<TextPanelProps> = React.memo(
7072
({ groupId, panelId }) => {
73+
const group = useGroupInfo(groupId);
7174
const groupMembers = useGroupMemberInfos(groupId);
7275
const panelInfo = useGroupPanelInfo(groupId, panelId);
7376
const { disabled, placeholder } = useChatInputInfo(groupId);
7477

78+
if (!group) {
79+
return null;
80+
}
81+
7582
if (!panelInfo) {
7683
return null;
7784
}
@@ -83,6 +90,12 @@ export const TextPanel: React.FC<TextPanelProps> = React.memo(
8390
id: m._id,
8491
display: m.nickname,
8592
}))}
93+
panels={group.panels
94+
.filter((p) => p.type !== GroupPanelType.GROUP)
95+
.map((p) => ({
96+
id: `/main/group/${groupId}/${p.id}`,
97+
display: p.name,
98+
}))}
8699
disabled={disabled}
87100
placeholder={placeholder}
88101
>

client/web/src/plugin/common/reg.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ export const [getMessageRender, regMessageRender] = buildRegFn<
117117
* 输入消息,返回渲染节点
118118
*/
119119
const defaultMessageTextDecorators = {
120-
url: (plain: string) => plain,
120+
url: (url: string, label?: string) => url,
121121
image: (plain: string, attrs: Record<string, unknown>) => plain,
122122
mention: (userId: string, userName: string) => `@${userName}`,
123123
emoji: (emojiCode: string) => emojiCode,

client/web/src/plugin/component/index.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ export {
2727
createMetaFormSchema,
2828
metaFormFieldSchema,
2929
} from 'tailchat-design';
30+
export { Link } from 'react-router-dom';
3031

3132
export { Image } from '@/components/Image';
3233
export { IconBtn } from '@/components/IconBtn';

0 commit comments

Comments
 (0)