diff --git a/src/app/services/channel.js b/src/app/services/channel.js index f7b18d40..2af80b99 100644 --- a/src/app/services/channel.js +++ b/src/app/services/channel.js @@ -59,12 +59,12 @@ export const channelApi = createApi({ }, }), getHistoryMessages: builder.query({ - query: ({ gid, mid = null, limit = 100 }) => ({ + query: ({ id, mid = null, limit = 100 }) => ({ url: mid - ? `/group/${gid}/history?before=${mid}&limit=${limit}` - : `/group/${gid}/history?limit=${limit}`, + ? `/group/${id}/history?before=${mid}&limit=${limit}` + : `/group/${id}/history?limit=${limit}`, }), - async onQueryStarted(id, { dispatch, getState, queryFulfilled }) { + async onQueryStarted(params, { dispatch, getState, queryFulfilled }) { const { data: messages } = await queryFulfilled; if (messages?.length) { messages.forEach((msg) => { diff --git a/src/app/services/contact.js b/src/app/services/contact.js index 6ab8d753..b0ba2206 100644 --- a/src/app/services/contact.js +++ b/src/app/services/contact.js @@ -7,6 +7,8 @@ import { updateMute } from "../slices/footprint"; import { fullfillContacts } from "../slices/contacts"; import BASE_URL, { ContentTypes } from "../config"; import { onMessageSendStarted } from "./handlers"; +import handleChatMessage from "../../common/hook/useStreaming/chat.handler"; + export const contactApi = createApi({ reducerPath: "contactApi", baseQuery, @@ -110,10 +112,26 @@ export const contactApi = createApi({ await onMessageSendStarted.call(this, param1, param2, "user"); }, }), + getHistoryMessages: builder.query({ + query: ({ id, mid = null, limit = 100 }) => ({ + url: mid + ? `/user/${id}/history?before=${mid}&limit=${limit}` + : `/user/${id}/history?limit=${limit}`, + }), + async onQueryStarted(params, { dispatch, getState, queryFulfilled }) { + const { data: messages } = await queryFulfilled; + if (messages?.length) { + messages.forEach((msg) => { + handleChatMessage(msg, dispatch, getState()); + }); + } + }, + }), }), }); export const { + useLazyGetHistoryMessagesQuery, useUpdateContactMutation, useUpdateMuteSettingMutation, useLazyDeleteContactQuery, diff --git a/src/common/hook/useMessageFeed.js b/src/common/hook/useMessageFeed.js index 9e88a18a..10da0a52 100644 --- a/src/common/hook/useMessageFeed.js +++ b/src/common/hook/useMessageFeed.js @@ -1,6 +1,7 @@ import { useEffect, useState, useRef } from "react"; import { useSelector } from "react-redux"; import { useLazyGetHistoryMessagesQuery } from "../../app/services/channel"; +import { useLazyGetHistoryMessagesQuery as useLazyGetDMHistoryMsg } from "../../app/services/contact"; const getFeedWithPagination = (config) => { const { pageNumber = 1, pageSize = 40, mids = [], isLast = false } = @@ -39,13 +40,16 @@ const getFeedWithPagination = (config) => { let curScrollPos = 0; let oldScroll = 0; export default function useMessageFeed({ context = "channel", id = null }) { - const [loadMoreFromServer] = useLazyGetHistoryMessagesQuery(); + const [loadMoreChannelMsgs] = useLazyGetHistoryMessagesQuery(); + const [loadMoreDmMsgs] = useLazyGetDMHistoryMsg(); const listRef = useRef([]); const pageRef = useRef(null); const containerRef = useRef(null); const [hasMore, setHasMore] = useState(true); const [appends, setAppends] = useState([]); const [items, setItems] = useState([]); + const loadMoreMsgsFromServer = + context == "channel" ? loadMoreChannelMsgs : loadMoreDmMsgs; const { mids, messageData, loginUid } = useSelector((store) => { return { loginUid: store.authData.uid, @@ -127,9 +131,9 @@ export default function useMessageFeed({ context = "channel", id = null }) { // 第一页 if (currPageInfo && currPageInfo.isFirst) { const [firstMid] = currPageInfo.ids; - const { data: newList } = await loadMoreFromServer({ + const { data: newList } = await loadMoreMsgsFromServer({ mid: firstMid, - gid: id, + id, }); if (newList.length == 0) { setHasMore(false); diff --git a/src/routes/chat/ChannelChat/index.js b/src/routes/chat/ChannelChat/index.js index 1c7f2977..4a5d1070 100644 --- a/src/routes/chat/ChannelChat/index.js +++ b/src/routes/chat/ChannelChat/index.js @@ -30,7 +30,7 @@ import { StyledHeader, } from "./styled"; import InviteModal from "../../../common/component/InviteModal"; -import LoadMore from "./LoadMore"; +import LoadMore from "../LoadMore"; // import useChatScroll from "../../../common/hook/useChatScroll"; export default function ChannelChat({ cid = "", dropFiles = [] }) { diff --git a/src/routes/chat/DMChat/index.js b/src/routes/chat/DMChat/index.js index e7eabb7d..cc2e8886 100644 --- a/src/routes/chat/DMChat/index.js +++ b/src/routes/chat/DMChat/index.js @@ -11,39 +11,40 @@ import IconHeadphone from "../../../assets/icons/headphone.svg"; import boardosIcon from "../../../assets/icons/app.boardos.svg?url"; import webrowseIcon from "../../../assets/icons/app.webrowse.svg?url"; -import useChatScroll from "../../../common/hook/useChatScroll"; +// import useChatScroll from "../../../common/hook/useChatScroll"; import { useReadMessageMutation } from "../../../app/services/message"; import Contact from "../../../common/component/Contact"; import Layout from "../Layout"; import { StyledHeader, StyledDMChat } from "./styled"; +import LoadMore from "../LoadMore"; import { renderMessageFragment } from "../utils"; +import useMessageFeed from "../../../common/hook/useMessageFeed"; export default function DMChat({ uid = "", dropFiles = [] }) { + const { list: msgIds, appends, hasMore, pullUp } = useMessageFeed({ + context: "user", + id: uid, + }); const [updateReadIndex] = useReadMessageMutation(); const updateReadDebounced = useDebounce(updateReadIndex, 300); console.log("dm files", dropFiles); // const [mids, setMids] = useState([]); - const { - msgIds, - currUser, - messageData, - footprint, - loginUid, - selects, - } = useSelector((store) => { - return { - selects: store.ui.selectMessages[`user_${uid}`], - loginUid: store.authData.uid, - footprint: store.footprint, - currUser: store.contacts.byId[uid], - msgIds: store.userMessage.byId[uid] || [], - messageData: store.message, - }; - }); - const ref = useChatScroll(msgIds); + const { currUser, messageData, footprint, loginUid, selects } = useSelector( + (store) => { + return { + selects: store.ui.selectMessages[`user_${uid}`], + loginUid: store.authData.uid, + footprint: store.footprint, + currUser: store.contacts.byId[uid], + messageData: store.message, + }; + } + ); + // const ref = useChatScroll(msgIds); if (!currUser) return null; // console.log("user msgs", msgs); const readIndex = footprint.readUsers[uid]; + const feeds = [...msgIds, ...appends]; return ( opt icon */} - + } > - - {[...msgIds] - .sort((a, b) => { - return Number(a) - Number(b); - }) - .map((mid, idx) => { - const curr = messageData[mid]; - const prev = idx == 0 ? null : messageData[msgIds[idx - 1]]; - const read = curr?.from_uid == loginUid || mid <= readIndex; - return renderMessageFragment({ - selectMode: !!selects, - updateReadIndex: updateReadDebounced, - read, - prev, - curr, - contextId: uid, - context: "user", - }); - })} + + {hasMore ? : null} + {[...feeds].map((mid, idx) => { + const curr = messageData[mid]; + const prev = idx == 0 ? null : messageData[feeds[idx - 1]]; + const read = curr?.from_uid == loginUid || mid <= readIndex; + return renderMessageFragment({ + selectMode: !!selects, + updateReadIndex: updateReadDebounced, + read, + prev, + curr, + contextId: uid, + context: "user", + }); + })} ); diff --git a/src/routes/chat/ChannelChat/LoadMore.js b/src/routes/chat/LoadMore.js similarity index 100% rename from src/routes/chat/ChannelChat/LoadMore.js rename to src/routes/chat/LoadMore.js