From a1048b77fd11413b9c388c35cd067bc7fe6b048b Mon Sep 17 00:00:00 2001 From: moonrailgun Date: Sun, 25 Jun 2023 16:16:47 +0800 Subject: [PATCH] feat: add markdown inbox item which help to develop system notice --- Dockerfile | 1 + client/shared/index.tsx | 1 + client/shared/model/inbox.ts | 40 +++---------------- client/shared/package.json | 1 + client/web/src/plugin/common/reg.ts | 5 ++- .../Main/Content/Inbox/Content/Markdown.tsx | 26 ++++++++++++ .../Main/Content/Inbox/Content/Message.tsx | 8 ++-- .../Main/Content/Inbox/Content/index.tsx | 16 ++++++-- .../src/routes/Main/Content/Inbox/Sidebar.tsx | 34 +++++++++++++--- packages/types/model/inbox.ts | 25 +++++++++++- pnpm-lock.yaml | 28 +++++++------ server/packages/sdk/package.json | 3 +- server/packages/sdk/src/structs/chat.ts | 25 ++---------- 13 files changed, 128 insertions(+), 85 deletions(-) create mode 100644 client/web/src/routes/Main/Content/Inbox/Content/Markdown.tsx diff --git a/Dockerfile b/Dockerfile index 7de222e3..3ed2939f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -18,6 +18,7 @@ RUN chmod +x /usr/local/bin/mc # Install plugins and sdk dependency COPY ./tsconfig.json ./tsconfig.json +COPY ./packages ./packages COPY ./server/packages ./server/packages COPY ./server/plugins ./server/plugins COPY ./server/package.json ./server/package.json diff --git a/client/shared/index.tsx b/client/shared/index.tsx index de51fd6a..1a3a1b5a 100644 --- a/client/shared/index.tsx +++ b/client/shared/index.tsx @@ -152,6 +152,7 @@ export type { export type { BasicInboxItem, MessageInboxItem, + MarkdownInboxItem, InboxItem, } from './model/inbox'; export { diff --git a/client/shared/model/inbox.ts b/client/shared/model/inbox.ts index 894e94c5..375b2dd7 100644 --- a/client/shared/model/inbox.ts +++ b/client/shared/model/inbox.ts @@ -1,38 +1,10 @@ import { request } from '../api/request'; - -/** - * 收件箱记录项类型 - */ -export interface BasicInboxItem { - _id: string; - userId: string; - readed: boolean; - type: string; - payload?: object; - createdAt: string; - updatedAt: string; -} - -export interface MessageInboxItem extends BasicInboxItem { - type: 'message'; - /** - * @deprecated - */ - message?: { - groupId?: string; - converseId: string; - messageId: string; - messageSnippet: string; - }; - payload: { - groupId?: string; - converseId: string; - messageId: string; - messageSnippet: string; - }; -} - -export type InboxItem = MessageInboxItem; +export type { + BasicInboxItem, + MessageInboxItem, + MarkdownInboxItem, + InboxItem, +} from 'tailchat-types'; /** * 设置收件箱某条记录已读 diff --git a/client/shared/package.json b/client/shared/package.json index a99133d0..d9ac1679 100644 --- a/client/shared/package.json +++ b/client/shared/package.json @@ -25,6 +25,7 @@ "regenerator-runtime": "^0.13.9", "socket.io-client": "^4.1.2", "socket.io-msgpack-parser": "^3.0.2", + "tailchat-types": "workspace:^", "url-regex": "^5.0.0", "yup": "^0.32.9", "zustand": "^4.3.6" diff --git a/client/web/src/plugin/common/reg.ts b/client/web/src/plugin/common/reg.ts index fe9d4f63..5c2cb0a0 100644 --- a/client/web/src/plugin/common/reg.ts +++ b/client/web/src/plugin/common/reg.ts @@ -9,6 +9,7 @@ import { GroupPanelFeature, InboxItem, buildRegMap, + BasicInboxItem, } from 'tailchat-shared'; import type { MetaFormFieldMeta } from 'tailchat-design'; import type { FullModalFactoryConfig } from '@/components/FullModal/Factory'; @@ -293,8 +294,8 @@ interface PluginInboxItem { * 来源 */ source: string; - getPreview: (inboxItem: InboxItem) => { title: string; desc: string }; - render: React.ComponentType<{ inboxItem: InboxItem }>; + getPreview: (inboxItem: BasicInboxItem) => { title: string; desc: string }; + render: React.ComponentType<{ inboxItem: BasicInboxItem }>; } /** diff --git a/client/web/src/routes/Main/Content/Inbox/Content/Markdown.tsx b/client/web/src/routes/Main/Content/Inbox/Content/Markdown.tsx new file mode 100644 index 00000000..b0574339 --- /dev/null +++ b/client/web/src/routes/Main/Content/Inbox/Content/Markdown.tsx @@ -0,0 +1,26 @@ +import { Markdown } from '@/components/Markdown'; +import { CommonPanelWrapper } from '@/components/Panel/common/Wrapper'; +import { Problem } from '@/components/Problem'; +import React from 'react'; +import { MarkdownInboxItem, t } from 'tailchat-shared'; + +interface Props { + info: MarkdownInboxItem; +} +export const InboxMarkdownContent: React.FC = React.memo((props) => { + const info = props.info; + + const payload = info.payload; + if (!payload) { + return ; + } + + return ( + +
+ +
+
+ ); +}); +InboxMarkdownContent.displayName = 'InboxMarkdownContent'; diff --git a/client/web/src/routes/Main/Content/Inbox/Content/Message.tsx b/client/web/src/routes/Main/Content/Inbox/Content/Message.tsx index f22c0d98..9d863c66 100644 --- a/client/web/src/routes/Main/Content/Inbox/Content/Message.tsx +++ b/client/web/src/routes/Main/Content/Inbox/Content/Message.tsx @@ -2,12 +2,14 @@ import { MessageHighlightContainer } from '@/components/ChatBox/ChatMessageList/ import { NormalMessageList } from '@/components/ChatBox/ChatMessageList/NormalList'; import { JumpToConverseButton } from '@/components/JumpToButton'; import { LoadingSpinner } from '@/components/LoadingSpinner'; +import { CommonPanelWrapper } from '@/components/Panel/common/Wrapper'; import { Problem } from '@/components/Problem'; import React from 'react'; import { MessageInboxItem, model, showErrorToasts, + t, useAsync, } from 'tailchat-shared'; @@ -24,13 +26,13 @@ export const InboxMessageContent: React.FC = React.memo((props) => { const { groupId, converseId, messageId } = payload; return ( -
-
+ +
-
+ ); }); InboxMessageContent.displayName = 'InboxMessageContent'; diff --git a/client/web/src/routes/Main/Content/Inbox/Content/index.tsx b/client/web/src/routes/Main/Content/Inbox/Content/index.tsx index d762d109..e2ebc997 100644 --- a/client/web/src/routes/Main/Content/Inbox/Content/index.tsx +++ b/client/web/src/routes/Main/Content/Inbox/Content/index.tsx @@ -3,6 +3,7 @@ import { pluginInboxItemMap } from '@/plugin/common'; import React from 'react'; import { useParams } from 'react-router'; import { + BasicInboxItem, model, t, useAppDispatch, @@ -10,6 +11,7 @@ import { useWatch, } from 'tailchat-shared'; import { chatActions } from 'tailchat-shared'; +import { InboxMarkdownContent } from './Markdown'; import { InboxMessageContent } from './Message'; /** @@ -31,11 +33,19 @@ export const InboxContent: React.FC = React.memo((props) => { if (inboxItem.type === 'message') { return ; - } else if (pluginInboxItemMap[inboxItem.type]) { - const info = pluginInboxItemMap[inboxItem.type]; + } + + if (inboxItem.type === 'markdown') { + return ; + } + + // For plugins + const _item = inboxItem as BasicInboxItem; + if (pluginInboxItemMap[_item.type]) { + const info = pluginInboxItemMap[_item.type]; const Component = info.render; - return ; + return ; } return ; diff --git a/client/web/src/routes/Main/Content/Inbox/Sidebar.tsx b/client/web/src/routes/Main/Content/Inbox/Sidebar.tsx index da97d342..5f078d35 100644 --- a/client/web/src/routes/Main/Content/Inbox/Sidebar.tsx +++ b/client/web/src/routes/Main/Content/Inbox/Sidebar.tsx @@ -1,6 +1,6 @@ import React, { useMemo } from 'react'; -import { CommonSidebarWrapper } from '@/components/CommonSidebarWrapper'; import { + BasicInboxItem, chatActions, InboxItem, isValidStr, @@ -20,6 +20,7 @@ import { Link } from 'react-router-dom'; import { PillTabPane, PillTabs } from '@/components/PillTabs'; import { SectionHeader } from '@/components/SectionHeader'; import { openReconfirmModalP } from '@/components/Modal'; +import { CommonSidebarWrapper } from '@/components/CommonSidebarWrapper'; const buildLink = (itemId: string) => `/main/inbox/${itemId}`; @@ -52,18 +53,39 @@ 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); + } + + if (item.type === 'markdown') { + const payload: Partial = + item.payload ?? {}; + const title = payload.title || t('新消息'); return ( + ); + } + + // For plugins + const _item = item as BasicInboxItem; + if (pluginInboxItemMap[_item.type]) { + const info = pluginInboxItemMap[_item.type]; + const preview = info.getPreview(_item); + + return ( + ); } diff --git a/packages/types/model/inbox.ts b/packages/types/model/inbox.ts index 68c16a41..bba5d247 100644 --- a/packages/types/model/inbox.ts +++ b/packages/types/model/inbox.ts @@ -3,7 +3,13 @@ */ export interface BasicInboxItem { _id: string; + /** + * 用户id + */ userId: string; + /** + * 是否已读 + */ readed: boolean; type: string; payload?: Record; @@ -14,7 +20,7 @@ export interface BasicInboxItem { export interface MessageInboxItem extends BasicInboxItem { type: 'message'; /** - * @deprecated + * @deprecated ALl info should move into payload */ message?: { groupId?: string; @@ -26,8 +32,23 @@ export interface MessageInboxItem extends BasicInboxItem { groupId?: string; converseId: string; messageId: string; + messageAuthor: string; messageSnippet: string; + messagePlainContent?: string; + }; +} + +export interface MarkdownInboxItem extends BasicInboxItem { + type: 'markdown'; + + payload: { + title?: string; + content: string; + /** + * 消息来源 + */ + source?: string; }; } -export type InboxItem = MessageInboxItem; +export type InboxItem = MessageInboxItem | MarkdownInboxItem; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b759de7b..0f03404a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -547,13 +547,13 @@ importers: version: 18.2.0(react@18.2.0) react-i18next: specifier: ^11.18.6 - version: 11.18.6(i18next@21.9.2)(react-dom@18.2.0)(react@18.2.0) + version: 11.18.6(i18next@21.9.2)(react@18.2.0) react-native-storage: specifier: npm:@trpgengine/react-native-storage@^1.0.1 version: /@trpgengine/react-native-storage@1.0.1 react-redux: specifier: ^8.0.2 - version: 8.0.2(@types/react@18.0.20)(react-dom@18.2.0)(react@18.2.0)(redux@4.2.1) + version: 8.0.2(@types/react@18.0.20)(react@18.2.0)(redux@4.2.1) regenerator-runtime: specifier: ^0.13.9 version: 0.13.9 @@ -563,6 +563,9 @@ importers: socket.io-msgpack-parser: specifier: ^3.0.2 version: 3.0.2 + tailchat-types: + specifier: workspace:^ + version: link:../../packages/types url-regex: specifier: ^5.0.0 version: 5.0.0 @@ -571,7 +574,7 @@ importers: version: 0.32.11 zustand: specifier: ^4.3.6 - version: 4.3.6(immer@9.0.15)(react@18.2.0) + version: 4.3.6(immer@9.0.21)(react@18.2.0) devDependencies: '@types/crc': specifier: ^3.4.0 @@ -1776,6 +1779,9 @@ importers: path-to-regexp: specifier: ^6.2.1 version: 6.2.1 + tailchat-types: + specifier: workspace:^ + version: link:../../../packages/types devDependencies: '@types/jest': specifier: ^29.5.1 @@ -1851,7 +1857,7 @@ importers: version: 5.3.6(react-dom@18.2.0)(react-is@18.2.0)(react@18.2.0) zustand: specifier: ^4.3.6 - version: 4.3.6(immer@9.0.15)(react@18.2.0) + version: 4.3.6(immer@9.0.21)(react@18.2.0) server/plugins/com.msgbyte.getui: dependencies: @@ -2029,7 +2035,7 @@ importers: version: 5.3.6(react-dom@18.2.0)(react-is@18.2.0)(react@18.2.0) zustand: specifier: ^4.3.6 - version: 4.3.6(immer@9.0.15)(react@18.2.0) + version: 4.3.6(immer@9.0.21)(react@18.2.0) server/plugins/com.msgbyte.welcome: dependencies: @@ -8394,7 +8400,7 @@ packages: dependencies: immer: 9.0.15 react: 18.2.0 - react-redux: 8.0.2(@types/react@18.0.20)(react-dom@18.2.0)(react@18.2.0)(redux@4.2.1) + react-redux: 8.0.2(@types/react@18.0.20)(react@18.2.0)(redux@4.2.1) redux: 4.2.1 redux-thunk: 2.4.1(redux@4.2.1) reselect: 4.1.6 @@ -21725,10 +21731,10 @@ packages: /immer@9.0.15: resolution: {integrity: sha512-2eB/sswms9AEUSkOm4SbV5Y7Vmt/bKRwByd52jfLkW4OLYeaTP3EEiJ9agqU0O/tq6Dk62Zfj+TJSqfm1rLVGQ==} + dev: false /immer@9.0.21: resolution: {integrity: sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==} - dev: false /import-fresh@2.0.0: resolution: {integrity: sha512-eZ5H8rcgYazHbKC3PG4ClHNykCSxtAhxSSEM+2mb+7evD2CKF5V7c0dNum7AdpDh0ZdICwZY9sRSn8f+KH96sg==} @@ -29987,7 +29993,7 @@ packages: react: 18.2.0 dev: false - /react-i18next@11.18.6(i18next@21.9.2)(react-dom@18.2.0)(react@18.2.0): + /react-i18next@11.18.6(i18next@21.9.2)(react@18.2.0): resolution: {integrity: sha512-yHb2F9BiT0lqoQDt8loZ5gWP331GwctHz9tYQ8A2EIEUu+CcEdjBLQWli1USG3RdWQt3W+jqQLg/d4rrQR96LA==} peerDependencies: i18next: '>= 19.0.0' @@ -30004,7 +30010,6 @@ packages: html-parse-stringify: 3.0.1 i18next: 21.9.2 react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) dev: false /react-i18next@12.3.1(i18next@22.5.0)(react-dom@18.2.0)(react@18.2.0): @@ -30177,7 +30182,7 @@ packages: scheduler: 0.20.2 dev: false - /react-redux@8.0.2(@types/react@18.0.20)(react-dom@18.2.0)(react@18.2.0)(redux@4.2.1): + /react-redux@8.0.2(@types/react@18.0.20)(react@18.2.0)(redux@4.2.1): resolution: {integrity: sha512-nBwiscMw3NoP59NFCXFf02f8xdo+vSHT/uZ1ldDwF7XaTpzm+Phk97VT4urYBl5TYAPNVaFm12UHAEyzkpNzRA==} peerDependencies: '@types/react': ^16.8 || ^17.0 || ^18.0 @@ -30204,7 +30209,6 @@ packages: '@types/use-sync-external-store': 0.0.3 hoist-non-react-statics: 3.3.2 react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) react-is: 18.2.0 redux: 4.2.1 use-sync-external-store: 1.2.0(react@18.2.0) @@ -36388,6 +36392,7 @@ packages: immer: 9.0.15 react: 18.2.0 use-sync-external-store: 1.2.0(react@18.2.0) + dev: false /zustand@4.3.6(immer@9.0.21)(react@18.2.0): resolution: {integrity: sha512-6J5zDxjxLE+yukC2XZWf/IyWVKnXT9b9HUv09VJ/bwGCpKNcaTqp7Ws28Xr8jnbvnZcdRaidztAPsXFBIqufiw==} @@ -36404,7 +36409,6 @@ packages: immer: 9.0.21 react: 18.2.0 use-sync-external-store: 1.2.0(react@18.2.0) - dev: false /zwitch@1.0.5: resolution: {integrity: sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw==} diff --git a/server/packages/sdk/package.json b/server/packages/sdk/package.json index 1e507b4d..85c6be92 100644 --- a/server/packages/sdk/package.json +++ b/server/packages/sdk/package.json @@ -55,6 +55,7 @@ "moment": "^2.29.1", "mongodb": "4.2.1", "mongoose": "6.1.1", - "path-to-regexp": "^6.2.1" + "path-to-regexp": "^6.2.1", + "tailchat-types": "workspace:^" } } diff --git a/server/packages/sdk/src/structs/chat.ts b/server/packages/sdk/src/structs/chat.ts index 28a9e456..5aba1395 100644 --- a/server/packages/sdk/src/structs/chat.ts +++ b/server/packages/sdk/src/structs/chat.ts @@ -1,3 +1,5 @@ +import type { InboxItem } from 'tailchat-types'; + export interface MessageReactionStruct { name: string; author?: string; @@ -64,25 +66,4 @@ export interface BasicInboxItem { readed: boolean; } -export interface MessageInboxItem extends BasicInboxItem { - type: 'message'; - /** - * @deprecated - */ - message?: { - groupId?: string; - converseId: string; - messageId: string; - messageSnippet: string; - }; - payload: { - groupId?: string; - converseId: string; - messageId: string; - messageAuthor: string; - messageSnippet: string; - messagePlainContent?: string; - }; -} - -export type InboxStruct = MessageInboxItem; +export type InboxStruct = InboxItem;