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,
getQuotedMessageToAnimate,
getSelectedConversationKey,
getShowScrollButton,
getYoungestMessageId,
} from '../../../../state/selectors/conversations';
import { getIsAppFocused } from '../../../../state/selectors/section';
@ -69,6 +70,7 @@ export const ReadableMessage = (props: ReadableMessageProps) => {
const youngestMessageId = useSelector(getYoungestMessageId);
const fetchingMoreInProgress = useSelector(areMoreMessagesBeingFetched);
const conversationHasUnread = useSelector(getConversationHasUnread);
const scrollButtonVisible = useSelector(getShowScrollButton);
const shouldMarkReadWhenVisible = isUnread;
const [didScroll, setDidScroll] = useState(false);
@ -83,6 +85,7 @@ export const ReadableMessage = (props: ReadableMessageProps) => {
if (
props.messageId === youngestMessageId &&
!quotedMessageToAnimate &&
!scrollButtonVisible &&
!didScroll &&
!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
await this.commit();
@ -1481,14 +1485,8 @@ export class ConversationModel extends Backbone.Model<ConversationAttributes> {
await model.setToExpire();
window.inboxStore?.dispatch(
conversationActions.messagesAdded([
{
conversationKey: this.id,
messageModelProps: model.getMessageModelProps(),
},
])
);
const messageModelProps = model.getMessageModelProps();
window.inboxStore?.dispatch(conversationActions.messagesChanged([messageModelProps]));
const unreadCount = await this.getUnreadCount();
this.set({ unreadCount });
this.updateLastMessage();

@ -7,7 +7,7 @@ import { getConversationController } from '../session/conversations';
import { ConversationModel, ConversationTypeEnum } from '../models/conversation';
import { MessageModel } from '../models/message';
import { getMessageById, getMessagesBySentAt } from '../../ts/data/data';
import { MessageModelPropsWithoutConvoProps, messagesAdded } from '../state/ducks/conversations';
import { updateProfileOneAtATime } from './dataMessage';
import { SignalService } from '../protobuf';
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')) {
conversation.throttledNotify(messageModel);
}
@ -419,16 +410,3 @@ export async function handleMessageJob(
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,
PropsForDataExtractionNotification,
} from '../../models/messageType';
import { perfEnd, perfStart } from '../../session/utils/Performance';
import { omit } from 'lodash';
import { ReplyingToMessageProps } from '../../components/conversation/composition/CompositionBox';
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.
* 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;
@ -387,6 +387,7 @@ type FetchedBottomMessageResults = {
conversationKey: string;
messagesProps: Array<MessageModelPropsWithoutConvoProps>;
oldBottomMessageId: string | null;
newMostRecentMessageIdInConversation: string | null;
} | null;
export const fetchBottomMessagesForConversation = createAsyncThunk(
@ -417,6 +418,7 @@ export const fetchBottomMessagesForConversation = createAsyncThunk(
conversationKey,
messagesProps,
oldBottomMessageId,
newMostRecentMessageIdInConversation: mostRecentMessage.id,
};
}
);
@ -441,77 +443,42 @@ export function getEmptyConversationState(): ConversationsStateType {
};
}
function handleMessageAdded(
function handleMessageChangedOrAdded(
state: ConversationsStateType,
payload: {
conversationKey: string;
messageModelProps: MessageModelPropsWithoutConvoProps;
}
changedOrAddedMessageProps: MessageModelPropsWithoutConvoProps
) {
const { messages } = state;
const { conversationKey, messageModelProps: addedMessageProps } = payload;
if (conversationKey !== state.selectedConversation) {
if (changedOrAddedMessageProps.propsForMessage.convoId !== state.selectedConversation) {
return state;
}
const messageInStoreIndex = state.messages.findIndex(
m => m.propsForMessage.id === addedMessageProps.propsForMessage.id
m => m.propsForMessage.id === changedOrAddedMessageProps.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),
addedMessageProps,
...state.messages.slice(messageInStoreIndex + 1),
];
return {
...state,
messages: editedMessages,
};
}
return {
...state,
messages: [...messages, addedMessageProps], // sorting happens in the selector
};
}
state.messages[messageInStoreIndex] = changedOrAddedMessageProps;
function handleMessageChanged(
state: ConversationsStateType,
changedMessage: MessageModelPropsWithoutConvoProps
) {
if (state.selectedConversation !== changedMessage.propsForMessage.convoId) {
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 {
...state,
messages: editedMessages,
};
// this message was not present before in the state, and we assume it was added at the bottom.
// as showScrollButton is set, it means we are not scrolled down, hence, that message is not visible
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;
}
function handleMessagesChanged(
function handleMessagesChangedOrAdded(
state: ConversationsStateType,
payload: Array<MessageModelPropsWithoutConvoProps>
) {
payload.forEach(element => {
// tslint:disable-next-line: no-parameter-reassignment
state = handleMessageChanged(state, element);
state = handleMessageChangedOrAdded(state, element);
});
return state;
@ -678,29 +645,11 @@ const conversationsSlice = createSlice({
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(
state: ConversationsStateType,
action: PayloadAction<Array<MessageModelPropsWithoutConvoProps>>
) {
return handleMessagesChanged(state, action.payload);
return handleMessagesChangedOrAdded(state, action.payload);
},
messageExpired(
@ -794,7 +743,9 @@ const conversationsSlice = createSlice({
mostRecentMessageIdOnOpen: action.payload.mostRecentMessageIdOnOpen,
areMoreMessagesBeingFetched: false,
messages: action.payload.initialMessages,
showScrollButton: true,
showScrollButton: Boolean(
action.payload.messageIdToNavigateTo !== action.payload.mostRecentMessageIdOnOpen
),
animateQuotedMessageId: action.payload.messageIdToNavigateTo,
shouldHighlightMessage: action.payload.shouldHighlightMessage,
oldTopMessageId: null,
@ -900,7 +851,12 @@ const conversationsSlice = createSlice({
return { ...state, areMoreMessagesBeingFetched: false };
}
// 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
if (conversationKey === state.selectedConversation) {
return {
@ -908,6 +864,7 @@ const conversationsSlice = createSlice({
oldBottomMessageId,
messages: messagesProps,
areMoreMessagesBeingFetched: false,
mostRecentMessageId: newMostRecentMessageIdInConversation,
};
}
return state;
@ -963,7 +920,6 @@ export const {
conversationRemoved,
removeAllConversations,
messageExpired,
messagesAdded,
messageDeleted,
conversationReset,
messagesChanged,

Loading…
Cancel
Save