Fix: chat loading only one page per time (#19511)
This commit is contained in:
parent
16c15f64b3
commit
b524f0b9fb
@ -12,7 +12,8 @@ import {
|
||||
import { Message } from '/imports/ui/Types/message';
|
||||
import ChatMessage from './chat-message/component';
|
||||
import { GraphqlDataHookSubscriptionResponse } from '/imports/ui/Types/hook';
|
||||
import useLoadedChatMessages from '/imports/ui/core/hooks/useLoadedChatMessages';
|
||||
import { useCreateUseSubscription } from '/imports/ui/core/hooks/createUseSubscription';
|
||||
import { setLoadedMessageGathering } from '/imports/ui/core/hooks/useLoadedChatMessages';
|
||||
|
||||
// @ts-ignore - temporary, while meteor exists in the project
|
||||
const CHAT_CONFIG = Meteor.settings.public.chat;
|
||||
@ -93,8 +94,6 @@ const ChatListPageContainer: React.FC<ChatListPageContainerProps> = ({
|
||||
markMessageAsSeen,
|
||||
scrollRef,
|
||||
}) => {
|
||||
const { setChatMessagesGraphqlVariablesAndQuery } = useContext(PluginsContext);
|
||||
|
||||
const isPublicChat = chatId === PUBLIC_GROUP_CHAT_KEY;
|
||||
const chatQuery = isPublicChat
|
||||
? CHAT_MESSAGE_PUBLIC_SUBSCRIPTION
|
||||
@ -103,32 +102,31 @@ const ChatListPageContainer: React.FC<ChatListPageContainerProps> = ({
|
||||
const variables = isPublicChat
|
||||
? defaultVariables : { ...defaultVariables, requestedChatId: chatId };
|
||||
|
||||
const resp = useLoadedChatMessages((msg) => msg) as GraphqlDataHookSubscriptionResponse<Message[]>;
|
||||
const useChatMessageSubscription = useCreateUseSubscription<Message>(chatQuery, variables, true);
|
||||
const {
|
||||
data: chatMessageData,
|
||||
} = useChatMessageSubscription((msg) => msg) as GraphqlDataHookSubscriptionResponse<Message[]>;
|
||||
|
||||
const chatMessageData = resp?.data;
|
||||
useEffect(() => {
|
||||
setChatMessagesGraphqlVariablesAndQuery(
|
||||
{
|
||||
query: chatQuery,
|
||||
variables,
|
||||
},
|
||||
);
|
||||
}, [chatId, page, pageSize]);
|
||||
if (chatMessageData) {
|
||||
if (chatMessageData.length > 0 && chatMessageData[chatMessageData.length - 1].user?.userId) {
|
||||
setLastSender(page, chatMessageData[chatMessageData.length - 1].user?.userId);
|
||||
}
|
||||
|
||||
return (
|
||||
<ChatListPage
|
||||
messages={chatMessageData}
|
||||
lastSenderPreviousPage={lastSenderPreviousPage}
|
||||
page={page}
|
||||
markMessageAsSeen={markMessageAsSeen}
|
||||
scrollRef={scrollRef}
|
||||
/>
|
||||
);
|
||||
} return (<></>);
|
||||
// component will unmount
|
||||
return () => {
|
||||
setLoadedMessageGathering(page, []);
|
||||
};
|
||||
}, []);
|
||||
if (!chatMessageData) return null;
|
||||
if (chatMessageData.length > 0 && chatMessageData[chatMessageData.length - 1].user?.userId) {
|
||||
setLastSender(page, chatMessageData[chatMessageData.length - 1].user?.userId);
|
||||
}
|
||||
setLoadedMessageGathering(page, chatMessageData);
|
||||
return (
|
||||
<ChatListPage
|
||||
messages={chatMessageData}
|
||||
lastSenderPreviousPage={lastSenderPreviousPage}
|
||||
page={page}
|
||||
markMessageAsSeen={markMessageAsSeen}
|
||||
scrollRef={scrollRef}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default ChatListPageContainer;
|
||||
|
@ -1,7 +1,6 @@
|
||||
import React, { createContext, useState } from 'react';
|
||||
import { ExtensibleArea } from '/imports/ui/components/plugins-engine/extensible-areas/types';
|
||||
import { ChatMessagesGraphqlVariablesAndQuery, PluginsContextType, UserListGraphqlVariables } from './types';
|
||||
import { CHAT_MESSAGE_PUBLIC_SUBSCRIPTION } from '../../chat/chat-graphql/chat-message-list/page/queries';
|
||||
import { PluginsContextType, UserListGraphqlVariables } from './types';
|
||||
|
||||
export const PluginsContext = createContext<PluginsContextType>({} as PluginsContextType);
|
||||
|
||||
@ -14,12 +13,6 @@ export const PluginsContextProvider = ({ children, ...props }: any) => {
|
||||
{} as UserListGraphqlVariables,
|
||||
);
|
||||
const [domElementManipulationMessageIds, setDomElementManipulationMessageIds] = useState<string[]>([]);
|
||||
const [
|
||||
chatMessagesGraphqlVariablesAndQuery,
|
||||
setChatMessagesGraphqlVariablesAndQuery,
|
||||
] = useState<ChatMessagesGraphqlVariablesAndQuery>(
|
||||
{ query: CHAT_MESSAGE_PUBLIC_SUBSCRIPTION } as ChatMessagesGraphqlVariablesAndQuery,
|
||||
);
|
||||
|
||||
return (
|
||||
<PluginsContext.Provider
|
||||
@ -29,8 +22,6 @@ export const PluginsContextProvider = ({ children, ...props }: any) => {
|
||||
pluginsExtensibleAreasAggregatedState,
|
||||
userListGraphqlVariables,
|
||||
setUserListGraphqlVariables,
|
||||
chatMessagesGraphqlVariablesAndQuery,
|
||||
setChatMessagesGraphqlVariablesAndQuery,
|
||||
domElementManipulationMessageIds,
|
||||
setDomElementManipulationMessageIds,
|
||||
}}
|
||||
|
@ -1,4 +1,3 @@
|
||||
import { DocumentNode } from 'graphql';
|
||||
import { ExtensibleArea } from '/imports/ui/components/plugins-engine/extensible-areas/types';
|
||||
import React from 'react';
|
||||
|
||||
@ -16,20 +15,12 @@ export type ChatMessagesVariables = {
|
||||
limit: number;
|
||||
}
|
||||
|
||||
export interface ChatMessagesGraphqlVariablesAndQuery {
|
||||
query: DocumentNode;
|
||||
variables: ChatMessagesVariables;
|
||||
}
|
||||
|
||||
export interface PluginsContextType {
|
||||
pluginsExtensibleAreasAggregatedState: ExtensibleArea;
|
||||
setPluginsExtensibleAreasAggregatedState: React.Dispatch<React.SetStateAction<ExtensibleArea>>;
|
||||
userListGraphqlVariables: UserListGraphqlVariables;
|
||||
setUserListGraphqlVariables: React.Dispatch<
|
||||
React.SetStateAction<UserListGraphqlVariables>>;
|
||||
chatMessagesGraphqlVariablesAndQuery: ChatMessagesGraphqlVariablesAndQuery;
|
||||
setChatMessagesGraphqlVariablesAndQuery: React.Dispatch<
|
||||
React.SetStateAction<ChatMessagesGraphqlVariablesAndQuery>>;
|
||||
domElementManipulationMessageIds: string[];
|
||||
setDomElementManipulationMessageIds: React.Dispatch<
|
||||
React.SetStateAction<string[]>>;
|
||||
|
@ -8,25 +8,22 @@ import {
|
||||
} from 'bigbluebutton-html-plugin-sdk/dist/cjs/core/enum';
|
||||
import { DataConsumptionHooks } from 'bigbluebutton-html-plugin-sdk/dist/cjs/data-consumption/enums';
|
||||
import { UpdatedEventDetails } from 'bigbluebutton-html-plugin-sdk/dist/cjs/core/types';
|
||||
import useLoadedChatMessages from '/imports/ui/core/hooks/useLoadedChatMessages';
|
||||
import { GraphqlDataHookSubscriptionResponse } from '/imports/ui/Types/hook';
|
||||
import useLoadedPageGathering from '/imports/ui/core/hooks/useLoadedChatMessages';
|
||||
import { Message } from '/imports/ui/Types/message';
|
||||
import formatLoadedChatMessagesDataFromGraphql from './utils';
|
||||
|
||||
const LoadedChatMessagesHookContainer = () => {
|
||||
const [sendSignal, setSendSignal] = useState(false);
|
||||
const chatMessagesData: GraphqlDataHookSubscriptionResponse<Partial<Message>[]> = useLoadedChatMessages(
|
||||
(message: Partial<Message>) => ({
|
||||
createdAt: message.createdAt,
|
||||
message: message.message,
|
||||
messageId: message.messageId,
|
||||
user: message.user,
|
||||
}),
|
||||
);
|
||||
const [chatMessagesData] = useLoadedPageGathering((message: Partial<Message>) => ({
|
||||
createdAt: message.createdAt,
|
||||
message: message.message,
|
||||
messageId: message.messageId,
|
||||
user: message.user,
|
||||
}));
|
||||
|
||||
const updateLoadedChatMessagesForPlugin = () => {
|
||||
window.dispatchEvent(new CustomEvent<
|
||||
UpdatedEventDetails<PluginSdk.GraphqlResponseWrapper<LoadedChatMessage>>
|
||||
UpdatedEventDetails<PluginSdk.GraphqlResponseWrapper<LoadedChatMessage[]>>
|
||||
>(HookEvents.UPDATED, {
|
||||
detail: {
|
||||
data: formatLoadedChatMessagesDataFromGraphql(chatMessagesData),
|
||||
|
@ -1,18 +1,17 @@
|
||||
import { GraphqlDataHookSubscriptionResponse } from '/imports/ui/Types/hook';
|
||||
import { Message } from '/imports/ui/Types/message';
|
||||
import * as PluginSdk from 'bigbluebutton-html-plugin-sdk';
|
||||
|
||||
const formatLoadedChatMessagesDataFromGraphql = (
|
||||
responseDataFromGraphql: GraphqlDataHookSubscriptionResponse<Partial<Message>[]>,
|
||||
responseData: Partial<Message>[],
|
||||
) => ({
|
||||
data: !responseDataFromGraphql.loading ? responseDataFromGraphql.data?.map((chatMessagesData) => ({
|
||||
data: responseData.map((chatMessagesData) => ({
|
||||
createdAt: chatMessagesData.createdAt,
|
||||
message: chatMessagesData.message,
|
||||
messageId: chatMessagesData.messageId,
|
||||
senderUserId: chatMessagesData.user?.userId,
|
||||
}) as PluginSdk.LoadedChatMessage) : undefined,
|
||||
loading: responseDataFromGraphql.loading,
|
||||
error: responseDataFromGraphql.errors?.[0],
|
||||
} as PluginSdk.GraphqlResponseWrapper<PluginSdk.LoadedChatMessage>);
|
||||
}) as PluginSdk.LoadedChatMessage),
|
||||
loading: !(responseData),
|
||||
error: undefined,
|
||||
} as PluginSdk.GraphqlResponseWrapper<PluginSdk.LoadedChatMessage[]>);
|
||||
|
||||
export default formatLoadedChatMessagesDataFromGraphql;
|
||||
|
@ -1,27 +1,46 @@
|
||||
import { useContext } from 'react';
|
||||
import { DocumentNode } from 'graphql';
|
||||
import { isEqual } from 'radash';
|
||||
import { makeVar, useReactiveVar } from '@apollo/client';
|
||||
import { Message } from '/imports/ui/Types/message';
|
||||
import createUseSubscription from './createUseSubscription';
|
||||
import { PluginsContext } from '../../components/components-data/plugin-context/context';
|
||||
import { ChatMessagesVariables } from '../../components/components-data/plugin-context/types';
|
||||
|
||||
const createUseLoadedChatMessagesSubscription = (
|
||||
query: DocumentNode,
|
||||
variables: ChatMessagesVariables,
|
||||
) => createUseSubscription<Message>(
|
||||
query,
|
||||
{ ...variables },
|
||||
);
|
||||
interface LoadedChatMessages {
|
||||
[pageNumber: number]: Partial<Message>[];
|
||||
}
|
||||
|
||||
const useLoadedChatMessages = (fn: (c: Partial<Message>) => Partial<Message>) => {
|
||||
const { chatMessagesGraphqlVariablesAndQuery } = useContext(PluginsContext);
|
||||
const {
|
||||
query,
|
||||
variables,
|
||||
} = chatMessagesGraphqlVariablesAndQuery;
|
||||
const useLoadedChatMessagesSubscription = createUseLoadedChatMessagesSubscription(query, variables);
|
||||
const loadedChatMessages = useLoadedChatMessagesSubscription(fn);
|
||||
return loadedChatMessages;
|
||||
const createLoadedPageGathering = (): [
|
||||
(fn: (c: Partial<Message>) => Partial<Message>) => [
|
||||
Partial<Message>[],
|
||||
(pageNumber: number, result: Partial<Message>[]) => void,
|
||||
],
|
||||
(pageNumber: number, result: Partial<Message>[]) => void,
|
||||
] => {
|
||||
const loadedPages = makeVar<LoadedChatMessages>({});
|
||||
|
||||
const pagesGathering = (pageNumber: number, result: Partial<Message>[]): void => {
|
||||
const pageMessages = loadedPages()[pageNumber];
|
||||
const hasMessages = pageMessages && pageMessages.length > 0;
|
||||
const shouldAdd = !hasMessages || !isEqual(pageMessages, result);
|
||||
if (shouldAdd) {
|
||||
const a = {
|
||||
...loadedPages(),
|
||||
[pageNumber]: result,
|
||||
};
|
||||
loadedPages(a);
|
||||
}
|
||||
};
|
||||
|
||||
const useResultPage = (fn: (c: Partial<Message>) => Partial<Message>): [
|
||||
Partial<Message>[],
|
||||
(pageNumber: number, result: Partial<Message>[]) => void,
|
||||
] => {
|
||||
const gatheredPages = useReactiveVar(loadedPages);
|
||||
const messages = Object.values(gatheredPages).filter((i) => Array.isArray(i)).flat();
|
||||
return [messages.map(fn), pagesGathering];
|
||||
};
|
||||
|
||||
return [useResultPage, pagesGathering];
|
||||
};
|
||||
|
||||
export default useLoadedChatMessages;
|
||||
const [useLoadedPageGathering, setLoadedMessageGathering] = createLoadedPageGathering();
|
||||
|
||||
export default useLoadedPageGathering;
|
||||
export { setLoadedMessageGathering, useLoadedPageGathering };
|
||||
|
Loading…
Reference in New Issue
Block a user