Retry outbound "normal" messages for up to a day

This commit is contained in:
Evan Hahn 2021-08-31 15:58:39 -05:00 committed by GitHub
parent 62cf51c060
commit a85dd1be36
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
30 changed files with 1414 additions and 603 deletions

View file

@ -45,12 +45,16 @@ import {
getGroupSizeRecommendedLimit,
getGroupSizeHardLimit,
} from '../../groups/limits';
import { getMessagesById } from '../../messages/getMessagesById';
import { isMessageUnread } from '../../util/isMessageUnread';
import { toggleSelectedContactForGroupAddition } from '../../groups/toggleSelectedContactForGroupAddition';
import { GroupNameCollisionsWithIdsByTitle } from '../../util/groupMemberNameCollisions';
import { ContactSpoofingType } from '../../util/contactSpoofing';
import { writeProfile } from '../../services/writeProfile';
import { getMe } from '../selectors/conversations';
import {
getMe,
getMessageIdsPendingBecauseOfVerification,
} from '../selectors/conversations';
import { AvatarDataType, getDefaultAvatars } from '../../types/Avatar';
import { getAvatarData } from '../../util/getAvatarData';
import { isSameAvatarData } from '../../util/isSameAvatarData';
@ -302,6 +306,15 @@ export type ConversationsStateType = {
composer?: ComposerStateType;
contactSpoofingReview?: ContactSpoofingReviewStateType;
/**
* Each key is a conversation ID. Each value is an array of message IDs stopped by that
* conversation being unverified.
*/
outboundMessagesPendingConversationVerification: Record<
string,
Array<string>
>;
// Note: it's very important that both of these locations are always kept up to date
messagesLookup: MessageLookupType;
messagesByConversation: MessagesByConversationType;
@ -336,14 +349,21 @@ export const getConversationCallMode = (
export const COLORS_CHANGED = 'conversations/COLORS_CHANGED';
export const COLOR_SELECTED = 'conversations/COLOR_SELECTED';
const CANCEL_MESSAGES_PENDING_CONVERSATION_VERIFICATION =
'conversations/CANCEL_MESSAGES_PENDING_CONVERSATION_VERIFICATION';
const COMPOSE_TOGGLE_EDITING_AVATAR =
'conversations/compose/COMPOSE_TOGGLE_EDITING_AVATAR';
const COMPOSE_ADD_AVATAR = 'conversations/compose/ADD_AVATAR';
const COMPOSE_REMOVE_AVATAR = 'conversations/compose/REMOVE_AVATAR';
const COMPOSE_REPLACE_AVATAR = 'conversations/compose/REPLACE_AVATAR';
const CUSTOM_COLOR_REMOVED = 'conversations/CUSTOM_COLOR_REMOVED';
const MESSAGE_STOPPED_BY_MISSING_VERIFICATION =
'conversations/MESSAGE_STOPPED_BY_MISSING_VERIFICATION';
const REPLACE_AVATARS = 'conversations/REPLACE_AVATARS';
type CancelMessagesPendingConversationVerificationActionType = {
type: typeof CANCEL_MESSAGES_PENDING_CONVERSATION_VERIFICATION;
};
type CantAddContactToGroupActionType = {
type: 'CANT_ADD_CONTACT_TO_GROUP';
payload: {
@ -465,6 +485,13 @@ export type MessageSelectedActionType = {
conversationId: string;
};
};
type MessageStoppedByMissingVerificationActionType = {
type: typeof MESSAGE_STOPPED_BY_MISSING_VERIFICATION;
payload: {
messageId: string;
untrustedConversationIds: ReadonlyArray<string>;
};
};
export type MessageChangedActionType = {
type: 'MESSAGE_CHANGED';
payload: {
@ -656,6 +683,7 @@ type ReplaceAvatarsActionType = {
};
};
export type ConversationActionType =
| CancelMessagesPendingConversationVerificationActionType
| CantAddContactToGroupActionType
| ClearChangedMessagesActionType
| ClearGroupCreationErrorActionType
@ -679,6 +707,7 @@ export type ConversationActionType =
| CreateGroupPendingActionType
| CreateGroupRejectedActionType
| CustomColorRemovedActionType
| MessageStoppedByMissingVerificationActionType
| MessageChangedActionType
| MessageDeletedActionType
| MessageSelectedActionType
@ -716,6 +745,7 @@ export type ConversationActionType =
// Action Creators
export const actions = {
cancelMessagesPendingConversationVerification,
cantAddContactToGroup,
clearChangedMessages,
clearGroupCreationError,
@ -737,6 +767,7 @@ export const actions = {
createGroup,
deleteAvatarFromDisk,
doubleCheckMissingQuoteReference,
messageStoppedByMissingVerification,
messageChanged,
messageDeleted,
messageSizeChanged,
@ -775,6 +806,7 @@ export const actions = {
startSettingGroupMetadata,
toggleConversationInChooseMembers,
toggleComposeEditingAvatar,
verifyConversationsStoppingMessageSend,
};
function filterAvatarData(
@ -1074,6 +1106,26 @@ function toggleComposeEditingAvatar(): ToggleComposeEditingAvatarActionType {
};
}
function verifyConversationsStoppingMessageSend(): ThunkAction<
void,
RootStateType,
unknown,
never
> {
return async (_dispatch, getState) => {
const conversationIds = Object.keys(
getState().conversations.outboundMessagesPendingConversationVerification
);
await Promise.all(
conversationIds.map(async conversationId => {
const conversation = window.ConversationController.get(conversationId);
await conversation?.setVerifiedDefault();
})
);
};
}
function composeSaveAvatarToDisk(
avatarData: AvatarDataType
): ThunkAction<void, RootStateType, unknown, ComposeSaveAvatarActionType> {
@ -1128,6 +1180,31 @@ function composeReplaceAvatar(
};
}
function cancelMessagesPendingConversationVerification(): ThunkAction<
void,
RootStateType,
unknown,
CancelMessagesPendingConversationVerificationActionType
> {
return async (dispatch, getState) => {
const messageIdsPending = getMessageIdsPendingBecauseOfVerification(
getState()
);
const messagesStopped = await getMessagesById([...messageIdsPending]);
messagesStopped.forEach(message => {
message.markFailed();
});
dispatch({
type: CANCEL_MESSAGES_PENDING_CONVERSATION_VERIFICATION,
});
await window.Signal.Data.saveMessages(
messagesStopped.map(message => message.attributes)
);
};
}
function cantAddContactToGroup(
conversationId: string
): CantAddContactToGroupActionType {
@ -1162,9 +1239,22 @@ function conversationChanged(
id: string,
data: ConversationType
): ThunkAction<void, RootStateType, unknown, ConversationChangedActionType> {
return dispatch => {
return async (dispatch, getState) => {
calling.groupMembersChanged(id);
if (!data.isUntrusted) {
const messageIdsPending =
getOwn(
getState().conversations
.outboundMessagesPendingConversationVerification,
id
) ?? [];
const messagesPending = await getMessagesById(messageIdsPending);
messagesPending.forEach(message => {
message.retrySend();
});
}
dispatch({
type: 'CONVERSATION_CHANGED',
payload: {
@ -1264,6 +1354,19 @@ function selectMessage(
};
}
function messageStoppedByMissingVerification(
messageId: string,
untrustedConversationIds: ReadonlyArray<string>
): MessageStoppedByMissingVerificationActionType {
return {
type: MESSAGE_STOPPED_BY_MISSING_VERIFICATION,
payload: {
messageId,
untrustedConversationIds,
},
};
}
function messageChanged(
id: string,
conversationId: string,
@ -1651,6 +1754,7 @@ export function getEmptyState(): ConversationsStateType {
conversationsByE164: {},
conversationsByUuid: {},
conversationsByGroupId: {},
outboundMessagesPendingConversationVerification: {},
messagesByConversation: {},
messagesLookup: {},
selectedMessageCounter: 0,
@ -1799,6 +1903,13 @@ export function reducer(
state: Readonly<ConversationsStateType> = getEmptyState(),
action: Readonly<ConversationActionType>
): ConversationsStateType {
if (action.type === CANCEL_MESSAGES_PENDING_CONVERSATION_VERIFICATION) {
return {
...state,
outboundMessagesPendingConversationVerification: {},
};
}
if (action.type === 'CANT_ADD_CONTACT_TO_GROUP') {
const { composer } = state;
if (composer?.step !== ComposerStep.ChooseGroupMembers) {
@ -1887,6 +1998,9 @@ export function reducer(
[id]: data,
},
...updateConversationLookups(data, undefined, state),
outboundMessagesPendingConversationVerification: data.isUntrusted
? state.outboundMessagesPendingConversationVerification
: omit(state.outboundMessagesPendingConversationVerification, id),
};
}
if (action.type === 'CONVERSATION_CHANGED') {
@ -1933,6 +2047,9 @@ export function reducer(
[id]: data,
},
...updateConversationLookups(data, existing, state),
outboundMessagesPendingConversationVerification: data.isUntrusted
? state.outboundMessagesPendingConversationVerification
: omit(state.outboundMessagesPendingConversationVerification, id),
};
}
if (action.type === 'CONVERSATION_REMOVED') {
@ -2037,6 +2154,31 @@ export function reducer(
selectedMessageCounter: state.selectedMessageCounter + 1,
};
}
if (action.type === MESSAGE_STOPPED_BY_MISSING_VERIFICATION) {
const { messageId, untrustedConversationIds } = action.payload;
const newOutboundMessagesPendingConversationVerification = {
...state.outboundMessagesPendingConversationVerification,
};
untrustedConversationIds.forEach(conversationId => {
const existingPendingMessageIds =
getOwn(
newOutboundMessagesPendingConversationVerification,
conversationId
) ?? [];
if (!existingPendingMessageIds.includes(messageId)) {
newOutboundMessagesPendingConversationVerification[conversationId] = [
...existingPendingMessageIds,
messageId,
];
}
});
return {
...state,
outboundMessagesPendingConversationVerification: newOutboundMessagesPendingConversationVerification,
};
}
if (action.type === 'MESSAGE_CHANGED') {
const { id, conversationId, data } = action.payload;
const existingConversation = state.messagesByConversation[conversationId];