Reactions/Edits: Mark read after database save

This commit is contained in:
Scott Nonnenberg 2024-08-27 07:42:44 +10:00 committed by GitHub
parent 768ad8e928
commit 688de5a99b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 59 additions and 70 deletions

View file

@ -2528,6 +2528,9 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
await DataWriter.saveMessage(this.attributes, { await DataWriter.saveMessage(this.attributes, {
ourAci: window.textsecure.storage.user.getCheckedAci(), ourAci: window.textsecure.storage.user.getCheckedAci(),
}); });
window.reduxActions.conversations.markOpenConversationRead(
conversation.id
);
} }
} }

View file

@ -611,6 +611,7 @@ const PUSH_PANEL = 'conversations/PUSH_PANEL';
const POP_PANEL = 'conversations/POP_PANEL'; const POP_PANEL = 'conversations/POP_PANEL';
const PANEL_ANIMATION_DONE = 'conversations/PANEL_ANIMATION_DONE'; const PANEL_ANIMATION_DONE = 'conversations/PANEL_ANIMATION_DONE';
const PANEL_ANIMATION_STARTED = 'conversations/PANEL_ANIMATION_STARTED'; const PANEL_ANIMATION_STARTED = 'conversations/PANEL_ANIMATION_STARTED';
export const MARK_READ = 'conversations/MARK_READ';
export const MESSAGE_CHANGED = 'MESSAGE_CHANGED'; export const MESSAGE_CHANGED = 'MESSAGE_CHANGED';
export const MESSAGE_DELETED = 'MESSAGE_DELETED'; export const MESSAGE_DELETED = 'MESSAGE_DELETED';
export const MESSAGE_EXPIRED = 'conversations/MESSAGE_EXPIRED'; export const MESSAGE_EXPIRED = 'conversations/MESSAGE_EXPIRED';
@ -780,6 +781,12 @@ type ConversationStoppedByMissingVerificationActionType = ReadonlyDeep<{
untrustedServiceIds: ReadonlyArray<ServiceIdString>; untrustedServiceIds: ReadonlyArray<ServiceIdString>;
}; };
}>; }>;
export type MarkReadActionType = ReadonlyDeep<{
type: typeof MARK_READ;
payload: {
conversationId: string;
};
}>;
export type MessageChangedActionType = ReadonlyDeep<{ export type MessageChangedActionType = ReadonlyDeep<{
type: typeof MESSAGE_CHANGED; type: typeof MESSAGE_CHANGED;
payload: { payload: {
@ -1027,6 +1034,7 @@ export type ConversationActionType =
| CreateGroupRejectedActionType | CreateGroupRejectedActionType
| CustomColorRemovedActionType | CustomColorRemovedActionType
| DiscardMessagesActionType | DiscardMessagesActionType
| MarkReadActionType
| MessageChangedActionType | MessageChangedActionType
| MessageDeletedActionType | MessageDeletedActionType
| MessageExpandedActionType | MessageExpandedActionType
@ -1122,6 +1130,7 @@ export const actions = {
loadRecentMediaItems, loadRecentMediaItems,
markAttachmentAsCorrupted, markAttachmentAsCorrupted,
markMessageRead, markMessageRead,
markOpenConversationRead,
messageChanged, messageChanged,
messageDeleted, messageDeleted,
messageExpanded, messageExpanded,
@ -2888,6 +2897,26 @@ function conversationStoppedByMissingVerification(payload: {
}; };
} }
export function markOpenConversationRead(
conversationId: string
): ThunkAction<void, RootStateType, unknown, MarkReadActionType> {
return async (dispatch, getState) => {
const state = getState();
const { nav } = state;
if (nav.selectedNavTab !== NavTab.Chats) {
return;
}
dispatch({
type: MARK_READ,
payload: {
conversationId,
},
});
};
}
export function messageChanged( export function messageChanged(
id: string, id: string,
conversationId: string, conversationId: string,
@ -5524,6 +5553,28 @@ export function reducer(
}; };
} }
if (action.type === MARK_READ) {
const { conversationId } = action.payload;
const existingConversation = state.messagesByConversation[conversationId];
// We don't keep track of messages unless their conversation is loaded...
if (!existingConversation) {
return state;
}
return {
...state,
messagesByConversation: {
...state.messagesByConversation,
[conversationId]: {
...existingConversation,
messageChangeCounter:
(existingConversation.messageChangeCounter || 0) + 1,
},
},
};
}
if (action.type === MESSAGE_CHANGED) { if (action.type === MESSAGE_CHANGED) {
const { id, conversationId, data } = action.payload; const { id, conversationId, data } = action.payload;
const existingConversation = state.messagesByConversation[conversationId]; const existingConversation = state.messagesByConversation[conversationId];
@ -5553,8 +5604,6 @@ export function reducer(
const hasNewEdit = const hasNewEdit =
existingMessage.editHistory?.length !== data.editHistory?.length ? 1 : 0; existingMessage.editHistory?.length !== data.editHistory?.length ? 1 : 0;
const toIncrement = data.reactions?.length || hasNewEdit;
const updatedMessage = { const updatedMessage = {
...data, ...data,
displayLimit: existingMessage.displayLimit, displayLimit: existingMessage.displayLimit,
@ -5572,14 +5621,6 @@ export function reducer(
state state
), ),
preloadData: undefined, preloadData: undefined,
messagesByConversation: {
...state.messagesByConversation,
[conversationId]: {
...existingConversation,
messageChangeCounter:
(existingConversation.messageChangeCounter || 0) + toIncrement,
},
},
messagesLookup: { messagesLookup: {
...state.messagesLookup, ...state.messagesLookup,
[id]: updatedMessage, [id]: updatedMessage,

View file

@ -68,8 +68,7 @@ describe('backup/calling', () => {
callLink = { callLink = {
rootKey: rootKey.toString(), rootKey: rootKey.toString(),
roomId: getRoomIdFromRootKey(rootKey), roomId: getRoomIdFromRootKey(rootKey),
// TODO: DESKTOP-7511 adminKey: fromAdminKeyBytes(adminKey),
adminKey: fromAdminKeyBytes(Buffer.concat([adminKey, adminKey])),
name: "Let's Talk Rocks", name: "Let's Talk Rocks",
restrictions: CallLinkRestrictions.AdminApproval, restrictions: CallLinkRestrictions.AdminApproval,
revoked: false, revoked: false,

View file

@ -1577,64 +1577,6 @@ describe('both/state/ducks/conversations', () => {
0 0
); );
}); });
it('increments message change counter if new message has reactions', () => {
const changedMessageWithReaction: MessageType = {
...changedMessage,
reactions: [
{
emoji: '✨',
fromId: 'some-other-id',
timestamp: 2222,
receivedAtDate: 3333,
targetTimestamp: 1111,
},
],
};
const state = reducer(
startState,
messageChanged(messageId, conversationId, changedMessageWithReaction)
);
assert.deepEqual(
state.messagesLookup[messageId],
changedMessageWithReaction
);
assert.strictEqual(
state.messagesByConversation[conversationId]?.messageChangeCounter,
1
);
});
it('does not increment message change counter if only old message had reactions', () => {
const updatedStartState = {
...startState,
messagesLookup: {
[messageId]: {
...startState.messagesLookup[messageId],
reactions: [
{
emoji: '✨',
fromId: 'some-other-id',
timestamp: 2222,
receivedAtDate: 3333,
targetTimestamp: 1111,
},
],
},
},
};
const state = reducer(
updatedStartState,
messageChanged(messageId, conversationId, changedMessage)
);
assert.deepEqual(state.messagesLookup[messageId], changedMessage);
assert.strictEqual(
state.messagesByConversation[conversationId]?.messageChangeCounter,
0
);
});
}); });
describe('SHOW_ARCHIVED_CONVERSATIONS', () => { describe('SHOW_ARCHIVED_CONVERSATIONS', () => {

View file

@ -370,6 +370,10 @@ export async function handleEditMessage(
isFirstRun: false, isFirstRun: false,
skipEdits: true, skipEdits: true,
}); });
window.reduxActions.conversations.markOpenConversationRead(
mainMessageConversation.id
);
} }
// Apply any other pending edits that target this message // Apply any other pending edits that target this message