merge messagesChanged and messagesAdded to a single redux event

pull/2142/head
Audric Ackermann 3 years ago
parent b72b8e8387
commit 1eba9dce30
No known key found for this signature in database
GPG Key ID: 999F434D76324AD4

@ -18,6 +18,7 @@ import {
getOldestMessageId, getOldestMessageId,
getQuotedMessageToAnimate, getQuotedMessageToAnimate,
getSelectedConversationKey, getSelectedConversationKey,
getShowScrollButton,
getYoungestMessageId, getYoungestMessageId,
} from '../../../../state/selectors/conversations'; } from '../../../../state/selectors/conversations';
import { getIsAppFocused } from '../../../../state/selectors/section'; import { getIsAppFocused } from '../../../../state/selectors/section';
@ -69,6 +70,7 @@ export const ReadableMessage = (props: ReadableMessageProps) => {
const youngestMessageId = useSelector(getYoungestMessageId); const youngestMessageId = useSelector(getYoungestMessageId);
const fetchingMoreInProgress = useSelector(areMoreMessagesBeingFetched); const fetchingMoreInProgress = useSelector(areMoreMessagesBeingFetched);
const conversationHasUnread = useSelector(getConversationHasUnread); const conversationHasUnread = useSelector(getConversationHasUnread);
const scrollButtonVisible = useSelector(getShowScrollButton);
const shouldMarkReadWhenVisible = isUnread; const shouldMarkReadWhenVisible = isUnread;
const [didScroll, setDidScroll] = useState(false); const [didScroll, setDidScroll] = useState(false);
@ -83,6 +85,7 @@ export const ReadableMessage = (props: ReadableMessageProps) => {
if ( if (
props.messageId === youngestMessageId && props.messageId === youngestMessageId &&
!quotedMessageToAnimate && !quotedMessageToAnimate &&
!scrollButtonVisible &&
!didScroll && !didScroll &&
!conversationHasUnread !conversationHasUnread
) { ) {

@ -836,6 +836,10 @@ export class ConversationModel extends Backbone.Model<ConversationAttributes> {
}); });
} }
if (this.isActive()) {
this.set('active_at', timestamp);
}
// tell the UI this conversation was updated // tell the UI this conversation was updated
await this.commit(); await this.commit();
@ -1481,14 +1485,8 @@ export class ConversationModel extends Backbone.Model<ConversationAttributes> {
await model.setToExpire(); await model.setToExpire();
window.inboxStore?.dispatch( const messageModelProps = model.getMessageModelProps();
conversationActions.messagesAdded([ window.inboxStore?.dispatch(conversationActions.messagesChanged([messageModelProps]));
{
conversationKey: this.id,
messageModelProps: model.getMessageModelProps(),
},
])
);
const unreadCount = await this.getUnreadCount(); const unreadCount = await this.getUnreadCount();
this.set({ unreadCount }); this.set({ unreadCount });
this.updateLastMessage(); this.updateLastMessage();

@ -7,7 +7,7 @@ import { getConversationController } from '../session/conversations';
import { ConversationModel, ConversationTypeEnum } from '../models/conversation'; import { ConversationModel, ConversationTypeEnum } from '../models/conversation';
import { MessageModel } from '../models/message'; import { MessageModel } from '../models/message';
import { getMessageById, getMessagesBySentAt } from '../../ts/data/data'; import { getMessageById, getMessagesBySentAt } from '../../ts/data/data';
import { MessageModelPropsWithoutConvoProps, messagesAdded } from '../state/ducks/conversations';
import { updateProfileOneAtATime } from './dataMessage'; import { updateProfileOneAtATime } from './dataMessage';
import { SignalService } from '../protobuf'; import { SignalService } from '../protobuf';
import { UserUtils } from '../session/utils'; import { UserUtils } from '../session/utils';
@ -393,15 +393,6 @@ export async function handleMessageJob(
); );
} }
// this updates the redux store.
// if the convo on which this message should become visible,
// it will be shown to the user, and might as well be read right away
updatesToDispatch.set(messageModel.id, {
conversationKey: conversation.id,
messageModelProps: messageModel.getMessageModelProps(),
});
throttledAllMessagesAddedDispatch();
if (messageModel.get('unread')) { if (messageModel.get('unread')) {
conversation.throttledNotify(messageModel); conversation.throttledNotify(messageModel);
} }
@ -419,16 +410,3 @@ export async function handleMessageJob(
throw error; throw error;
} }
} }
const throttledAllMessagesAddedDispatch = _.throttle(() => {
if (updatesToDispatch.size === 0) {
return;
}
window.inboxStore?.dispatch(messagesAdded([...updatesToDispatch.values()]));
updatesToDispatch.clear();
}, 1000);
const updatesToDispatch: Map<
string,
{ conversationKey: string; messageModelProps: MessageModelPropsWithoutConvoProps }
> = new Map();

@ -16,7 +16,6 @@ import {
MessageModelType, MessageModelType,
PropsForDataExtractionNotification, PropsForDataExtractionNotification,
} from '../../models/messageType'; } from '../../models/messageType';
import { perfEnd, perfStart } from '../../session/utils/Performance';
import { omit } from 'lodash'; import { omit } from 'lodash';
import { ReplyingToMessageProps } from '../../components/conversation/composition/CompositionBox'; import { ReplyingToMessageProps } from '../../components/conversation/composition/CompositionBox';
import { QuotedAttachmentType } from '../../components/conversation/message/message-content/Quote'; import { QuotedAttachmentType } from '../../components/conversation/message/message-content/Quote';
@ -300,7 +299,8 @@ export type ConversationsStateType = {
/** /**
* Contains the most recent message id for this conversation. * Contains the most recent message id for this conversation.
* This is the one at the bottom, if the most recent page of the conversation was loaded * This is the one at the bottom, if the most recent page of the conversation was loaded.
* But this might also be a message not visible (like if the user scrolled up, the most recent message is not rendered)
*/ */
mostRecentMessageId: string | null; mostRecentMessageId: string | null;
@ -387,6 +387,7 @@ type FetchedBottomMessageResults = {
conversationKey: string; conversationKey: string;
messagesProps: Array<MessageModelPropsWithoutConvoProps>; messagesProps: Array<MessageModelPropsWithoutConvoProps>;
oldBottomMessageId: string | null; oldBottomMessageId: string | null;
newMostRecentMessageIdInConversation: string | null;
} | null; } | null;
export const fetchBottomMessagesForConversation = createAsyncThunk( export const fetchBottomMessagesForConversation = createAsyncThunk(
@ -417,6 +418,7 @@ export const fetchBottomMessagesForConversation = createAsyncThunk(
conversationKey, conversationKey,
messagesProps, messagesProps,
oldBottomMessageId, oldBottomMessageId,
newMostRecentMessageIdInConversation: mostRecentMessage.id,
}; };
} }
); );
@ -441,77 +443,42 @@ export function getEmptyConversationState(): ConversationsStateType {
}; };
} }
function handleMessageAdded( function handleMessageChangedOrAdded(
state: ConversationsStateType, state: ConversationsStateType,
payload: { changedOrAddedMessageProps: MessageModelPropsWithoutConvoProps
conversationKey: string;
messageModelProps: MessageModelPropsWithoutConvoProps;
}
) { ) {
const { messages } = state; if (changedOrAddedMessageProps.propsForMessage.convoId !== state.selectedConversation) {
const { conversationKey, messageModelProps: addedMessageProps } = payload;
if (conversationKey !== state.selectedConversation) {
return state; return state;
} }
const messageInStoreIndex = state.messages.findIndex( const messageInStoreIndex = state.messages.findIndex(
m => m.propsForMessage.id === addedMessageProps.propsForMessage.id m => m.propsForMessage.id === changedOrAddedMessageProps.propsForMessage.id
); );
if (messageInStoreIndex >= 0) { if (messageInStoreIndex >= 0) {
// we cannot edit the array directly, so slice the first part, insert our edited message, and slice the second part state.messages[messageInStoreIndex] = changedOrAddedMessageProps;
const editedMessages = [
...state.messages.slice(0, messageInStoreIndex),
addedMessageProps,
...state.messages.slice(messageInStoreIndex + 1),
];
return {
...state,
messages: editedMessages,
};
}
return {
...state,
messages: [...messages, addedMessageProps], // sorting happens in the selector
};
}
function handleMessageChanged(
state: ConversationsStateType,
changedMessage: MessageModelPropsWithoutConvoProps
) {
if (state.selectedConversation !== changedMessage.propsForMessage.convoId) {
return state; return state;
} }
const messageInStoreIndex = state?.messages?.findIndex(
m => m.propsForMessage.id === changedMessage.propsForMessage.id
);
if (messageInStoreIndex >= 0) {
// we cannot edit the array directly, so slice the first part, insert our edited message, and slice the second part
const editedMessages = [
...state.messages.slice(0, messageInStoreIndex),
changedMessage,
...state.messages.slice(messageInStoreIndex + 1),
];
return { // this message was not present before in the state, and we assume it was added at the bottom.
...state, // as showScrollButton is set, it means we are not scrolled down, hence, that message is not visible
messages: editedMessages, if (state.showScrollButton) {
}; return state;
} }
console.warn('messages should be added at the bottom only if it is in the current view');
// sorting happens in the selector
state.messages.push(changedOrAddedMessageProps);
return state; return state;
} }
function handleMessagesChanged( function handleMessagesChangedOrAdded(
state: ConversationsStateType, state: ConversationsStateType,
payload: Array<MessageModelPropsWithoutConvoProps> payload: Array<MessageModelPropsWithoutConvoProps>
) { ) {
payload.forEach(element => { payload.forEach(element => {
// tslint:disable-next-line: no-parameter-reassignment // tslint:disable-next-line: no-parameter-reassignment
state = handleMessageChanged(state, element); state = handleMessageChangedOrAdded(state, element);
}); });
return state; return state;
@ -678,29 +645,11 @@ const conversationsSlice = createSlice({
return getEmptyConversationState(); return getEmptyConversationState();
}, },
messagesAdded(
state: ConversationsStateType,
action: PayloadAction<
Array<{
conversationKey: string;
messageModelProps: MessageModelPropsWithoutConvoProps;
}>
>
) {
perfStart('messagesAdded');
action.payload.forEach(added => {
// tslint:disable-next-line: no-parameter-reassignment
state = handleMessageAdded(state, added);
});
perfEnd('messagesAdded', 'messagesAdded');
return state;
},
messagesChanged( messagesChanged(
state: ConversationsStateType, state: ConversationsStateType,
action: PayloadAction<Array<MessageModelPropsWithoutConvoProps>> action: PayloadAction<Array<MessageModelPropsWithoutConvoProps>>
) { ) {
return handleMessagesChanged(state, action.payload); return handleMessagesChangedOrAdded(state, action.payload);
}, },
messageExpired( messageExpired(
@ -794,7 +743,9 @@ const conversationsSlice = createSlice({
mostRecentMessageIdOnOpen: action.payload.mostRecentMessageIdOnOpen, mostRecentMessageIdOnOpen: action.payload.mostRecentMessageIdOnOpen,
areMoreMessagesBeingFetched: false, areMoreMessagesBeingFetched: false,
messages: action.payload.initialMessages, messages: action.payload.initialMessages,
showScrollButton: true, showScrollButton: Boolean(
action.payload.messageIdToNavigateTo !== action.payload.mostRecentMessageIdOnOpen
),
animateQuotedMessageId: action.payload.messageIdToNavigateTo, animateQuotedMessageId: action.payload.messageIdToNavigateTo,
shouldHighlightMessage: action.payload.shouldHighlightMessage, shouldHighlightMessage: action.payload.shouldHighlightMessage,
oldTopMessageId: null, oldTopMessageId: null,
@ -900,7 +851,12 @@ const conversationsSlice = createSlice({
return { ...state, areMoreMessagesBeingFetched: false }; return { ...state, areMoreMessagesBeingFetched: false };
} }
// this is called once the messages are loaded from the db for the currently selected conversation // this is called once the messages are loaded from the db for the currently selected conversation
const { messagesProps, conversationKey, oldBottomMessageId } = action.payload; const {
messagesProps,
conversationKey,
oldBottomMessageId,
newMostRecentMessageIdInConversation,
} = action.payload;
// double check that this update is for the shown convo // double check that this update is for the shown convo
if (conversationKey === state.selectedConversation) { if (conversationKey === state.selectedConversation) {
return { return {
@ -908,6 +864,7 @@ const conversationsSlice = createSlice({
oldBottomMessageId, oldBottomMessageId,
messages: messagesProps, messages: messagesProps,
areMoreMessagesBeingFetched: false, areMoreMessagesBeingFetched: false,
mostRecentMessageId: newMostRecentMessageIdInConversation,
}; };
} }
return state; return state;
@ -963,7 +920,6 @@ export const {
conversationRemoved, conversationRemoved,
removeAllConversations, removeAllConversations,
messageExpired, messageExpired,
messagesAdded,
messageDeleted, messageDeleted,
conversationReset, conversationReset,
messagesChanged, messagesChanged,

Loading…
Cancel
Save