feat: 增加topic插件的收件箱通知项

pull/70/head
moonrailgun 2 years ago
parent 206b90d026
commit 6dcc18a7e0

@ -0,0 +1,50 @@
import React from 'react';
import { useNavigate } from 'react-router';
import { t } from 'tailchat-shared';
interface Props {
link: string;
text: string;
}
/**
*
*/
export const JumpToButton: React.FC<Props> = React.memo((props) => {
const navigate = useNavigate();
return (
<div className="absolute bottom-4 left-0 right-0 text-center">
<div
className="shadow-lg px-6 py-2 rounded-full inline-block bg-indigo-600 hover:bg-indigo-700 text-white cursor-pointer"
onClick={() => {
navigate(props.link);
}}
>
{props.text}
</div>
</div>
);
});
JumpToButton.displayName = 'JumpToButton';
export const JumpToGroupPanelButton: React.FC<{
groupId: string;
panelId: string;
}> = React.memo((props) => {
const link = `/main/group/${props.groupId}/${props.panelId}`;
return <JumpToButton link={link} text={t('跳转到面板')} />;
});
JumpToGroupPanelButton.displayName = 'JumpToGroupPanelButton';
export const JumpToConverseButton: React.FC<{
groupId?: string;
converseId: string;
}> = React.memo((props) => {
const link = props.groupId
? `/main/group/${props.groupId}/${props.converseId}`
: `/main/personal/converse/${props.converseId}`;
return <JumpToButton link={link} text={t('跳转到会话')} />;
});
JumpToConverseButton.displayName = 'JumpToConverseButton';

@ -1,5 +1,5 @@
.pill-tabs.ant-tabs.ant-tabs-card {
@apply text-gray-700 dark:text-gray-100;
@apply text-gray-700 dark:text-gray-100 max-h-full;
.ant-tabs-nav {
@apply px-2 py-3 m-0 text-base;

@ -7,6 +7,8 @@ import {
regSocketEventListener,
PermissionItemType,
GroupPanelFeature,
InboxItem,
buildRegMap,
} from 'tailchat-shared';
import type { MetaFormFieldMeta } from 'tailchat-design';
import type { FullModalFactoryConfig } from '@/components/FullModal/Factory';
@ -278,3 +280,18 @@ type PluginSettings = FullModalFactoryConfig & {
*/
export const [pluginSettings, regPluginSettings] =
buildRegList<PluginSettings>();
interface PluginInboxItem {
/**
*
*/
source: string;
getPreview: (inboxItem: InboxItem) => { title: string; desc: string };
render: React.ComponentType<{ inboxItem: InboxItem }>;
}
/**
*
*/
export const [pluginInboxItemMap, regPluginInboxItemMap] =
buildRegMap<PluginInboxItem>();

@ -60,3 +60,9 @@ export { UserName } from '@/components/UserName';
export { Markdown } from '@/components/Markdown';
export { Webview, WebviewKeepAlive } from '@/components/Webview';
export { Card } from '@/components/Card';
export { Problem } from '@/components/Problem';
export {
JumpToButton,
JumpToGroupPanelButton,
JumpToConverseButton,
} from '@/components/JumpToButton';

@ -1,23 +1,16 @@
import { MessageHighlightContainer } from '@/components/ChatBox/ChatMessageList/MessageHighlightContainer';
import { NormalMessageList } from '@/components/ChatBox/ChatMessageList/NormalList';
import { JumpToConverseButton } from '@/components/JumpToButton';
import { LoadingSpinner } from '@/components/LoadingSpinner';
import { Problem } from '@/components/Problem';
import React from 'react';
import { useNavigate } from 'react-router';
import {
InboxItem,
model,
showErrorToasts,
t,
useAsync,
} from 'tailchat-shared';
import { InboxItem, model, showErrorToasts, useAsync } from 'tailchat-shared';
interface Props {
info: InboxItem;
}
export const InboxMessageContent: React.FC<Props> = React.memo((props) => {
const info = props.info;
const navigate = useNavigate();
const message = info.message;
if (!message) {
@ -31,21 +24,7 @@ export const InboxMessageContent: React.FC<Props> = React.memo((props) => {
<NearbyMessages converseId={converseId} messageId={messageId} />
</div>
<div className="absolute bottom-4 left-0 right-0 text-center">
<div
className="shadow-lg px-6 py-2 rounded-full inline-block bg-indigo-600 hover:bg-indigo-700 text-white cursor-pointer"
onClick={() => {
if (groupId) {
// 跳转到群组
navigate(`/main/group/${groupId}/${converseId}`);
} else {
navigate(`/main/personal/converse/${converseId}`);
}
}}
>
{t('跳转到会话')}
</div>
</div>
<JumpToConverseButton groupId={groupId} converseId={converseId} />
</div>
);
});

@ -1,4 +1,5 @@
import { NotFound } from '@/components/NotFound';
import { pluginInboxItemMap } from '@/plugin/common';
import React from 'react';
import { useParams } from 'react-router';
import {
@ -30,6 +31,11 @@ export const InboxContent: React.FC = React.memo((props) => {
if (inboxItem.type === 'message') {
return <InboxMessageContent info={inboxItem} />;
} else if (pluginInboxItemMap[inboxItem.type]) {
const info = pluginInboxItemMap[inboxItem.type];
const Component = info.render;
return <Component inboxItem={inboxItem} />;
}
return <NotFound message={t('没有找到该类型的渲染方式')} />;

@ -14,7 +14,7 @@ import clsx from 'clsx';
import _orderBy from 'lodash/orderBy';
import { GroupName } from '@/components/GroupName';
import { ConverseName } from '@/components/ConverseName';
import { getMessageRender } from '@/plugin/common';
import { getMessageRender, pluginInboxItemMap } from '@/plugin/common';
import { useLocation } from 'react-router';
import { Link } from 'react-router-dom';
import { PillTabPane, PillTabs } from '@/components/PillTabs';
@ -52,6 +52,20 @@ export const InboxSidebar: React.FC = React.memo(() => {
to={buildLink(item._id)}
/>
);
} else if (pluginInboxItemMap[item.type]) {
const info = pluginInboxItemMap[item.type];
const preview = info.getPreview(item);
return (
<InboxSidebarItem
key={item._id}
title={preview.title}
desc={preview.desc}
source={info.source ?? 'Unknown'}
readed={item.readed}
to={buildLink(item._id)}
/>
);
}
return null;
@ -99,7 +113,7 @@ export const InboxSidebar: React.FC = React.memo(() => {
{t('收件箱')}
</SectionHeader>
<div>
<div className="overflow-hidden">
<PillTabs>
<PillTabPane key="1" tab={`${t('全部')}`}>
{fullList.map((item) => renderInbox(item))}

@ -312,6 +312,10 @@ declare module '@capital/common' {
export const regPluginSettings: any;
export const pluginInboxItemMap: any;
export const regPluginInboxItemMap: any;
export const useGroupIdContext: () => string;
export const useGroupPanelContext: () => {
@ -499,4 +503,14 @@ declare module '@capital/component' {
export const Webview: any;
export const WebviewKeepAlive: any;
export const Card: any;
export const Problem: any;
export const JumpToButton: any;
export const JumpToGroupPanelButton: any;
export const JumpToConverseButton: any;
}

@ -10,7 +10,6 @@ import {
import { Base, TimeStamps } from '@typegoose/typegoose/lib/defaultClasses';
import type { Types } from 'mongoose';
import { User } from '../user/user';
import { Message } from './message';
interface InboxMessage {
/**

@ -179,10 +179,24 @@ class GroupTopicService extends TcService {
const json = await this.transformDocuments(ctx, {}, topic);
// TODO: 回复需要添加到收件箱
this.roomcastNotify(ctx, panelId, 'createComment', json);
// 向所有参与者都添加收件箱消息
const memberIds = _.uniq([
topic.author,
...topic.comments.map((c) => c.author),
]);
await Promise.all(
memberIds.map((memberId) =>
call(ctx).appendInbox(
'plugin:com.msgbyte.topic.comment',
json,
String(memberId)
)
)
);
return true;
}
}

@ -0,0 +1,27 @@
import React from 'react';
import { TopicCard } from '../components/TopicCard';
import { Problem, JumpToGroupPanelButton } from '@capital/component';
import { Translate } from '../translate';
export const TopicInboxItem: React.FC<{ inboxItem: any }> = React.memo(
(props) => {
const payload = props.inboxItem.payload;
if (!payload) {
return <Problem text={Translate.topicDataError} />;
}
return (
<div style={{ width: '100%' }}>
<div style={{ height: '100%', overflow: 'auto', paddingBottom: 50 }}>
<TopicCard topic={payload} />
</div>
<JumpToGroupPanelButton
groupId={payload.groupId}
panelId={payload.panelId}
/>
</div>
);
}
);
TopicInboxItem.displayName = 'TopicInboxItem';

@ -1,4 +1,8 @@
import { regGroupPanel } from '@capital/common';
import {
getMessageRender,
regGroupPanel,
regPluginInboxItemMap,
} from '@capital/common';
import { Loadable } from '@capital/component';
import { Translate } from './translate';
@ -11,3 +15,16 @@ regGroupPanel({
render: Loadable(() => import('./group/GroupTopicPanelRender')),
feature: ['subscribe', 'ack'],
});
regPluginInboxItemMap('plugin:com.msgbyte.topic.comment', {
source: Translate.topicpanel,
getPreview: (item) => {
return {
title: Translate.topicpanel,
desc: getMessageRender(item?.payload?.content ?? ''),
};
},
render: Loadable(() =>
import('./inbox/TopicInboxItem').then((module) => module.TopicInboxItem)
),
});

@ -21,4 +21,8 @@ export const Translate = {
'zh-CN': '加载中...',
'en-US': 'Loading...',
}),
topicDataError: localTrans({
'zh-CN': '话题信息异常',
'en-US': 'Topic Data Error',
}),
};

@ -312,6 +312,10 @@ declare module '@capital/common' {
export const regPluginSettings: any;
export const pluginInboxItemMap: any;
export const regPluginInboxItemMap: any;
export const useGroupIdContext: () => string;
export const useGroupPanelContext: () => {
@ -499,4 +503,14 @@ declare module '@capital/component' {
export const Webview: any;
export const WebviewKeepAlive: any;
export const Card: any;
export const Problem: any;
export const JumpToButton: any;
export const JumpToGroupPanelButton: any;
export const JumpToConverseButton: any;
}

Loading…
Cancel
Save