From 4d9b4816298bec662c94c20c3210d8b906c36e0d Mon Sep 17 00:00:00 2001 From: moonrailgun Date: Mon, 13 Jun 2022 15:30:31 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E7=BE=A4=E7=BB=84=E6=96=87=E6=9C=AC?= =?UTF-8?q?=E9=9D=A2=E6=9D=BF=E9=A1=B9=E5=8F=B3=E9=94=AE=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E6=A0=87=E8=AE=B0=E4=B8=BA=E5=B7=B2=E8=AF=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/AvatarWithPreview/index.tsx | 1 + shared/index.tsx | 1 + shared/redux/hooks/useConverseAck.ts | 59 +++++++++++++++++++ web/src/components/ChatBox/useMessageAck.ts | 58 +++--------------- .../routes/Main/Content/Group/SidebarItem.tsx | 23 ++++++++ 5 files changed, 91 insertions(+), 51 deletions(-) create mode 100644 shared/redux/hooks/useConverseAck.ts diff --git a/packages/design/components/AvatarWithPreview/index.tsx b/packages/design/components/AvatarWithPreview/index.tsx index 93428be2..05880574 100644 --- a/packages/design/components/AvatarWithPreview/index.tsx +++ b/packages/design/components/AvatarWithPreview/index.tsx @@ -17,6 +17,7 @@ export const AvatarWithPreview: React.FC = React.memo((props) => { > + {hasImage && (
state.chat.lastMessageMap[converseId] + ); + + const lastMessageIdRef = useRef(''); + lastMessageIdRef.current = useAppSelector( + (state) => state.chat.ack[converseId] ?? '' + ); + + const setConverseAck = useMemo( + () => + _debounce( + (converseId: string, lastMessageId: string) => { + if ( + isValidStr(lastMessageIdRef.current) && + lastMessageId <= lastMessageIdRef.current + ) { + // 更新的数字比较小,跳过 + return; + } + + dispatch(chatActions.setConverseAck({ converseId, lastMessageId })); + updateAck(converseId, lastMessageId); + lastMessageIdRef.current = lastMessageId; + }, + 1000, + { leading: true, trailing: true } + ), + [] + ); + + /** + * 更新会话最新消息 + */ + const updateConverseAck = useCallback( + (lastMessageId: string) => { + setConverseAck(converseId, lastMessageId); + }, + [converseId] + ); + + const markConverseAllAck = useCallback(() => { + updateConverseAck(converseLastMessage); + }, [converseLastMessage]); + + return { updateConverseAck, markConverseAllAck }; +} diff --git a/web/src/components/ChatBox/useMessageAck.ts b/web/src/components/ChatBox/useMessageAck.ts index c47575a4..7aa24faa 100644 --- a/web/src/components/ChatBox/useMessageAck.ts +++ b/web/src/components/ChatBox/useMessageAck.ts @@ -1,45 +1,12 @@ -import { useCallback, useEffect, useMemo, useRef } from 'react'; -import { - ChatMessage, - isValidStr, - updateAck, - useAppDispatch, - useAppSelector, - useUpdateRef, -} from 'tailchat-shared'; -import { chatActions } from 'tailchat-shared/redux/slices'; +import { useEffect } from 'react'; +import { ChatMessage, useConverseAck, useUpdateRef } from 'tailchat-shared'; import _debounce from 'lodash/debounce'; +import _last from 'lodash/last'; export function useMessageAck(converseId: string, messages: ChatMessage[]) { + const { updateConverseAck } = useConverseAck(converseId); const messagesRef = useUpdateRef(messages); - const dispatch = useAppDispatch(); - - const lastMessageIdRef = useRef(''); - lastMessageIdRef.current = useAppSelector( - (state) => state.chat.ack[converseId] ?? '' - ); - - const setConverseAck = useMemo( - () => - _debounce( - (converseId: string, lastMessageId: string) => { - if ( - isValidStr(lastMessageIdRef.current) && - lastMessageId <= lastMessageIdRef.current - ) { - // 更新的数字比较小,跳过 - return; - } - - dispatch(chatActions.setConverseAck({ converseId, lastMessageId })); - updateAck(converseId, lastMessageId); - lastMessageIdRef.current = lastMessageId; - }, - 1000, - { leading: true, trailing: true } - ), - [] - ); + const updateConverseAckRef = useUpdateRef(updateConverseAck); useEffect(() => { // 设置当前 @@ -47,20 +14,9 @@ export function useMessageAck(converseId: string, messages: ChatMessage[]) { return; } - const lastMessageId = - messagesRef.current[messagesRef.current.length - 1]._id; - setConverseAck(converseId, lastMessageId); + const lastMessageId = _last(messagesRef.current)!._id; + updateConverseAckRef.current(lastMessageId); }, [converseId]); - /** - * 更新会话最新消息 - */ - const updateConverseAck = useCallback( - (lastMessageId: string) => { - setConverseAck(converseId, lastMessageId); - }, - [converseId] - ); - return { updateConverseAck }; } diff --git a/web/src/routes/Main/Content/Group/SidebarItem.tsx b/web/src/routes/Main/Content/Group/SidebarItem.tsx index 7d9cbe31..f10ec2a4 100644 --- a/web/src/routes/Main/Content/Group/SidebarItem.tsx +++ b/web/src/routes/Main/Content/Group/SidebarItem.tsx @@ -7,6 +7,7 @@ import { showToasts, t, useAppDispatch, + useConverseAck, useGroupInfo, } from 'tailchat-shared'; import { GroupPanelItem } from '@/components/GroupPanelItem'; @@ -17,6 +18,24 @@ import { usePanelWindow } from '@/hooks/usePanelWindow'; import { LoadingSpinner } from '@/components/LoadingSpinner'; import { Icon } from '@/components/Icon'; +const GroupAckMenuItem: React.FC<{ + panelId: string; +}> = (props) => { + const { markConverseAllAck } = useConverseAck(props.panelId); + + return ( + } + onClick={() => { + markConverseAllAck(); + }} + > + {t('标记为已读')} + + ); +}; +GroupAckMenuItem.displayName = 'GroupAckMenuItem'; + /** * 群组面板侧边栏组件 */ @@ -86,6 +105,10 @@ export const SidebarItem: React.FC<{ {t('Pin')} )} + + {panel.type === GroupPanelType.TEXT && ( + + )} );