feat: added quote source data to the conversation state as a separate object

this should help performance when loading quotes in the UI since individual db lookups will no longer be required
pull/2757/head
William Grant 2 years ago
parent e78d1dfb87
commit a83bc64d0a

@ -289,6 +289,9 @@ export type ConversationsStateType = {
selectedConversation?: string; selectedConversation?: string;
// NOTE the messages that are in view // NOTE the messages that are in view
messages: Array<MessageModelPropsWithoutConvoProps>; messages: Array<MessageModelPropsWithoutConvoProps>;
// NOTE the quotes that are in view
// key is message [timestamp]-[author-pubkey]
quotes: Record<string, MessageModelPropsWithoutConvoProps>;
firstUnreadMessageId: string | undefined; firstUnreadMessageId: string | undefined;
messageDetailProps?: MessagePropsDetails; messageDetailProps?: MessagePropsDetails;
showRightPanel: boolean; showRightPanel: boolean;
@ -340,26 +343,67 @@ async function getMessages({
}: { }: {
conversationKey: string; conversationKey: string;
messageId: string | null; messageId: string | null;
}): Promise<Array<MessageModelPropsWithoutConvoProps>> { }): Promise<{
messagesProps: Array<MessageModelPropsWithoutConvoProps>;
quotesProps: Record<string, MessageModelPropsWithoutConvoProps>;
}> {
const beforeTimestamp = Date.now(); const beforeTimestamp = Date.now();
const conversation = getConversationController().get(conversationKey); const conversation = getConversationController().get(conversationKey);
if (!conversation) { if (!conversation) {
// no valid conversation, early return // no valid conversation, early return
window?.log?.error('Failed to get convo on reducer.'); window?.log?.error('Failed to get convo on reducer.');
return []; return { messagesProps: [], quotesProps: {} };
} }
const messageSet = await Data.getMessagesByConversation(conversationKey, { const messageSet = await Data.getMessagesByConversation(conversationKey, {
messageId, messageId,
}); });
const messageProps: Array<MessageModelPropsWithoutConvoProps> = messageSet.models.map(m => const messagesProps: Array<MessageModelPropsWithoutConvoProps> = messageSet.models.map(m =>
m.getMessageModelProps() m.getMessageModelProps()
); );
const time = Date.now() - beforeTimestamp; const time = Date.now() - beforeTimestamp;
window?.log?.info(`Loading ${messageProps.length} messages took ${time}ms to load.`); window?.log?.info(`Loading ${messagesProps.length} messages took ${time}ms to load.`);
return messageProps;
const quotesProps: Record<string, MessageModelPropsWithoutConvoProps> = {};
messagesProps
.filter(
message => message.propsForMessage?.quote?.messageId && message.propsForMessage.quote?.sender
)
.forEach(async message => {
const id = message.propsForMessage?.quote?.messageId;
const sender = message.propsForMessage.quote?.sender;
// TODO use this is the renderering process
// const contact = message.findAndFormatContact(author);
// const authorName = contact?.profileName || contact?.name || '';
if (id && sender) {
const timestamp = Number(id);
// See if message is already in memory if not lookup in db
let results = [];
results = messagesProps.filter(
message =>
message.propsForMessage.timestamp === timestamp &&
message.propsForMessage.sender === sender
);
if (results.length) {
message = results[0];
} else {
const dbResult = (
await Data.getMessageBySenderAndTimestamp({ source: sender, timestamp })
)?.getMessageModelProps();
if (dbResult) {
message = dbResult;
}
}
quotesProps[`${timestamp}-${sender}`] = message;
}
});
return { messagesProps, quotesProps };
} }
export type SortedMessageModelProps = MessageModelPropsWithoutConvoProps & { export type SortedMessageModelProps = MessageModelPropsWithoutConvoProps & {
@ -391,7 +435,7 @@ export const fetchTopMessagesForConversation = createAsyncThunk(
window.log.info('fetchTopMessagesForConversation: we are already at the top'); window.log.info('fetchTopMessagesForConversation: we are already at the top');
return null; return null;
} }
const messagesProps = await getMessages({ const { messagesProps } = await getMessages({
conversationKey, conversationKey,
messageId: oldTopMessageId, messageId: oldTopMessageId,
}); });
@ -428,7 +472,7 @@ export const fetchBottomMessagesForConversation = createAsyncThunk(
window.log.info('fetchBottomMessagesForConversation: we are already at the bottom'); window.log.info('fetchBottomMessagesForConversation: we are already at the bottom');
return null; return null;
} }
const messagesProps = await getMessages({ const { messagesProps } = await getMessages({
conversationKey, conversationKey,
messageId: oldBottomMessageId, messageId: oldBottomMessageId,
}); });
@ -448,6 +492,7 @@ export function getEmptyConversationState(): ConversationsStateType {
return { return {
conversationLookup: {}, conversationLookup: {},
messages: [], messages: [],
quotes: {},
messageDetailProps: undefined, messageDetailProps: undefined,
showRightPanel: false, showRightPanel: false,
selectedMessageIds: [], selectedMessageIds: [],
@ -753,6 +798,7 @@ const conversationsSlice = createSlice({
firstUnreadIdOnOpen: string | undefined; firstUnreadIdOnOpen: string | undefined;
mostRecentMessageIdOnOpen: string | null; mostRecentMessageIdOnOpen: string | null;
initialMessages: Array<MessageModelPropsWithoutConvoProps>; initialMessages: Array<MessageModelPropsWithoutConvoProps>;
initialQuotes: Record<string, MessageModelPropsWithoutConvoProps>;
}> }>
) { ) {
// this is quite hacky, but we don't want to show the showScrollButton if we have only a small amount of messages, // this is quite hacky, but we don't want to show the showScrollButton if we have only a small amount of messages,
@ -776,6 +822,7 @@ const conversationsSlice = createSlice({
selectedConversation: action.payload.conversationKey, selectedConversation: action.payload.conversationKey,
firstUnreadMessageId: action.payload.firstUnreadIdOnOpen, firstUnreadMessageId: action.payload.firstUnreadIdOnOpen,
messages: action.payload.initialMessages, messages: action.payload.initialMessages,
quotes: action.payload.initialQuotes,
areMoreMessagesBeingFetched: false, areMoreMessagesBeingFetched: false,
showRightPanel: false, showRightPanel: false,
@ -803,6 +850,7 @@ const conversationsSlice = createSlice({
mostRecentMessageIdOnOpen: string | null; mostRecentMessageIdOnOpen: string | null;
initialMessages: Array<MessageModelPropsWithoutConvoProps>; initialMessages: Array<MessageModelPropsWithoutConvoProps>;
initialQuotes: Record<string, MessageModelPropsWithoutConvoProps>;
}> }>
) { ) {
return { return {
@ -811,6 +859,7 @@ const conversationsSlice = createSlice({
mostRecentMessageIdOnOpen: action.payload.mostRecentMessageIdOnOpen, mostRecentMessageIdOnOpen: action.payload.mostRecentMessageIdOnOpen,
areMoreMessagesBeingFetched: false, areMoreMessagesBeingFetched: false,
messages: action.payload.initialMessages, messages: action.payload.initialMessages,
quotes: action.payload.initialQuotes,
showScrollButton: Boolean( showScrollButton: Boolean(
action.payload.messageIdToNavigateTo !== action.payload.mostRecentMessageIdOnOpen action.payload.messageIdToNavigateTo !== action.payload.mostRecentMessageIdOnOpen
), ),
@ -1040,7 +1089,7 @@ export async function openConversationWithMessages(args: {
const firstUnreadIdOnOpen = await Data.getFirstUnreadMessageIdInConversation(conversationKey); const firstUnreadIdOnOpen = await Data.getFirstUnreadMessageIdInConversation(conversationKey);
const mostRecentMessageIdOnOpen = await Data.getLastMessageIdInConversation(conversationKey); const mostRecentMessageIdOnOpen = await Data.getLastMessageIdInConversation(conversationKey);
const initialMessages = await getMessages({ const { messagesProps: initialMessages, quotesProps: initialQuotes } = await getMessages({
conversationKey, conversationKey,
messageId: messageId || null, messageId: messageId || null,
}); });
@ -1051,6 +1100,7 @@ export async function openConversationWithMessages(args: {
firstUnreadIdOnOpen, firstUnreadIdOnOpen,
mostRecentMessageIdOnOpen, mostRecentMessageIdOnOpen,
initialMessages, initialMessages,
initialQuotes,
}) })
); );
} }
@ -1062,7 +1112,10 @@ export async function openConversationToSpecificMessage(args: {
}) { }) {
const { conversationKey, messageIdToNavigateTo, shouldHighlightMessage } = args; const { conversationKey, messageIdToNavigateTo, shouldHighlightMessage } = args;
const messagesAroundThisMessage = await getMessages({ const {
messagesProps: messagesAroundThisMessage,
quotesProps: quotesAroundThisMessage,
} = await getMessages({
conversationKey, conversationKey,
messageId: messageIdToNavigateTo, messageId: messageIdToNavigateTo,
}); });
@ -1077,6 +1130,7 @@ export async function openConversationToSpecificMessage(args: {
mostRecentMessageIdOnOpen, mostRecentMessageIdOnOpen,
shouldHighlightMessage, shouldHighlightMessage,
initialMessages: messagesAroundThisMessage, initialMessages: messagesAroundThisMessage,
initialQuotes: quotesAroundThisMessage,
}) })
); );
} }

Loading…
Cancel
Save