feat: converse suppport order with message, and add more checker for local message

feat/group-preview
moonrailgun 2 years ago
parent edc076f430
commit 2468d45c66

@ -1,8 +1,9 @@
import { request } from '../api/request'; import { request } from '../api/request';
export enum ChatConverseType { export enum ChatConverseType {
DM = 'DM', DM = 'DM', // 单人会话
Group = 'Group', Multi = 'Multi', // 多人会话
Group = 'Group', // 群组会话(暂时无用)
} }
export interface ChatConverseInfo { export interface ChatConverseInfo {

@ -1,4 +1,5 @@
import { useMemo } from 'react'; import { useMemo } from 'react';
import { ChatConverseType } from '../../model/converse';
import type { ChatConverseState } from '../slices/chat'; import type { ChatConverseState } from '../slices/chat';
import { useAppSelector } from './useAppSelector'; import { useAppSelector } from './useAppSelector';
@ -8,12 +9,23 @@ import { useAppSelector } from './useAppSelector';
*/ */
export function useDMConverseList(): ChatConverseState[] { export function useDMConverseList(): ChatConverseState[] {
const converses = useAppSelector((state) => state.chat.converses); const converses = useAppSelector((state) => state.chat.converses);
const lastMessageMap = useAppSelector((state) => state.chat.lastMessageMap);
return useMemo( const filteredConverse = useMemo(
() => () =>
Object.entries(converses) Object.entries(converses)
.filter(([, info]) => info.type === 'DM') .filter(([, info]) =>
[ChatConverseType.DM, ChatConverseType.Multi].includes(info.type)
)
.map(([, info]) => info), .map(([, info]) => info),
[converses] [converses]
); );
return useMemo(() => {
return filteredConverse.sort((a, b) => {
return (lastMessageMap[a._id] ?? '') < (lastMessageMap[b._id] ?? '')
? 1
: -1;
});
}, [filteredConverse, lastMessageMap]);
} }

@ -1,7 +1,7 @@
import { useRef } from 'react'; import { useRef } from 'react';
import { useAppDispatch, useAppSelector } from './useAppSelector'; import { useAppDispatch, useAppSelector } from './useAppSelector';
import _debounce from 'lodash/debounce'; import _debounce from 'lodash/debounce';
import { isValidStr } from '../../utils/string-helper'; import { isLocalMessageId, isValidStr } from '../../utils/string-helper';
import { chatActions } from '../slices'; import { chatActions } from '../slices';
import { updateAck } from '../../model/converse'; import { updateAck } from '../../model/converse';
import { useMemoizedFn } from '../../hooks/useMemoizedFn'; import { useMemoizedFn } from '../../hooks/useMemoizedFn';
@ -30,6 +30,11 @@ export function useConverseAck(converseId: string) {
const setConverseAck = useMemoizedFn( const setConverseAck = useMemoizedFn(
(converseId: string, lastMessageId: string) => { (converseId: string, lastMessageId: string) => {
if (isLocalMessageId(lastMessageId)) {
// 跳过本地消息
return;
}
if ( if (
isValidStr(lastMessageIdRef.current) && isValidStr(lastMessageIdRef.current) &&
lastMessageId <= lastMessageIdRef.current lastMessageId <= lastMessageIdRef.current

@ -184,7 +184,9 @@ function listenNotify(socket: AppSocket, store: AppStore) {
// 如果会话没有加载, 但是是私信消息 // 如果会话没有加载, 但是是私信消息
// 则获取会话信息后添加到会话消息中 // 则获取会话信息后添加到会话消息中
getCachedConverseInfo(converseId).then((converse) => { getCachedConverseInfo(converseId).then((converse) => {
if (converse.type === ChatConverseType.DM) { if (
[ChatConverseType.DM, ChatConverseType.Multi].includes(converse.type)
) {
// 如果是私人会话, 则添加到dmlist // 如果是私人会话, 则添加到dmlist
appendUserDMConverse(converse._id); appendUserDMConverse(converse._id);
} }

@ -9,7 +9,7 @@ import type {
import _uniqBy from 'lodash/uniqBy'; import _uniqBy from 'lodash/uniqBy';
import _orderBy from 'lodash/orderBy'; import _orderBy from 'lodash/orderBy';
import _last from 'lodash/last'; import _last from 'lodash/last';
import { isValidStr } from '../../utils/string-helper'; import { isLocalMessageId, isValidStr } from '../../utils/string-helper';
import type { InboxItem } from '../../model/inbox'; import type { InboxItem } from '../../model/inbox';
export interface ChatConverseState extends ChatConverseInfo { export interface ChatConverseState extends ChatConverseInfo {
@ -85,6 +85,7 @@ const chatSlice = createSlice({
return; return;
} }
// NOTICE: 按照该规则能确保本地消息一直在最后因为l大于任何ObjectId
const newMessages = _orderBy( const newMessages = _orderBy(
_uniqBy([...state.converses[converseId].messages, ...messages], '_id'), _uniqBy([...state.converses[converseId].messages, ...messages], '_id'),
'_id', '_id',
@ -93,10 +94,16 @@ const chatSlice = createSlice({
state.converses[converseId].messages = newMessages; state.converses[converseId].messages = newMessages;
if (state.currentConverseId !== converseId) { const lastMessageId = _last(
const lastMessageId = _last(newMessages)?._id; newMessages.filter((m) => !isLocalMessageId(m._id))
if (isValidStr(lastMessageId)) { )?._id;
state.lastMessageMap[converseId] = lastMessageId;
if (isValidStr(lastMessageId)) {
state.lastMessageMap[converseId] = lastMessageId;
if (state.currentConverseId === converseId) {
// 如果是当前会话,则立即已读
state.ack[converseId] = lastMessageId;
} }
} }
}, },

@ -47,3 +47,11 @@ export function is(it: string) {
export function isValidStr(str: unknown): str is string { export function isValidStr(str: unknown): str is string {
return typeof str == 'string' && str !== ''; return typeof str == 'string' && str !== '';
} }
export function isLocalMessageId(str: unknown): str is string {
if (typeof str !== 'string') {
return false;
}
return str.startsWith('localMessage_');
}

Loading…
Cancel
Save