fix menu action for unsending messages

This commit is contained in:
Audric Ackermann 2021-10-26 16:07:13 +11:00
parent 314b76388f
commit 5d9565a559
No known key found for this signature in database
GPG Key ID: 999F434D76324AD4
5 changed files with 97 additions and 66 deletions

View File

@ -43,7 +43,7 @@ window.lokiFeatureFlags = {
useFileOnionRequestsV2: true, // more compact encoding of files in response
padOutgoingAttachments: true,
enablePinConversations: true,
useCallMessage: true,
useCallMessage: false,
};
window.isBeforeVersion = (toCheck, baseVersion) => {

View File

@ -32,7 +32,6 @@ async function unsendMessagesForEveryone(
}
const unsendMsgObjects = getUnsendMessagesObjects(msgsToDelete);
let allDeleted = false;
if (conversation.isPrivate()) {
// sending to recipient all the messages separately for now
await Promise.all(
@ -49,7 +48,6 @@ async function unsendMessagesForEveryone(
.catch(window?.log?.error)
)
);
allDeleted = await deleteMessagesFromSwarmAndCompletelyLocally(conversation, msgsToDelete);
} else if (conversation.isClosedGroup()) {
// sending to recipient all the messages separately for now
await Promise.all(
@ -59,18 +57,11 @@ async function unsendMessagesForEveryone(
.catch(window?.log?.error)
)
);
allDeleted = await deleteMessagesFromSwarmAndCompletelyLocally(conversation, msgsToDelete);
return;
}
await deleteMessagesFromSwarmAndCompletelyLocally(conversation, msgsToDelete);
window.inboxStore?.dispatch(resetSelectedMessageIds());
if (allDeleted) {
ToastUtils.pushDeleted();
} else {
ToastUtils.someDeletionsFailed();
}
ToastUtils.pushDeleted();
}
function getUnsendMessagesObjects(messages: Array<MessageModel>) {
@ -119,7 +110,7 @@ export async function deleteMessagesFromSwarmOnly(messages: Array<MessageModel>)
* Delete the messages from the swarm with an unsend request and if it worked, delete those messages locally.
* If an error happened, we just return false, Toast an error, and do not remove the messages locally at all.
*/
async function deleteMessagesFromSwarmAndCompletelyLocally(
export async function deleteMessagesFromSwarmAndCompletelyLocally(
conversation: ConversationModel,
messages: Array<MessageModel>
) {
@ -128,14 +119,33 @@ async function deleteMessagesFromSwarmAndCompletelyLocally(
window.log.warn(
'deleteMessagesFromSwarmAndCompletelyLocally: some messages failed to be deleted '
);
return false;
}
await Promise.all(
messages.map(async message => {
return deleteMessageLocallyOnly({ conversation, message, deletionType: 'complete' });
})
);
return true;
}
/**
* Delete the messages from the swarm with an unsend request and if it worked, mark those messages locally as deleted but do not remove them.
* If an error happened, we still mark the message locally as deleted.
*/
export async function deleteMessagesFromSwarmAndMarkAsDeletedLocally(
conversation: ConversationModel,
messages: Array<MessageModel>
) {
const deletedFromSwarm = await deleteMessagesFromSwarmOnly(messages);
if (!deletedFromSwarm) {
window.log.warn(
'deleteMessagesFromSwarmAndMarkAsDeletedLocally: some messages failed to be deleted but still removing the messages content... '
);
}
await Promise.all(
messages.map(async message => {
return deleteMessageLocallyOnly({ conversation, message, deletionType: 'markDeleted' });
})
);
}
/**
@ -164,25 +174,32 @@ export async function deleteMessageLocallyOnly({
}
/**
* Send an UnsendMessage synced message so our devices removes those messages locally,
* and send an unsend request on our swarm so this message is effectively removed.
*
* Show a toast on error/success and reset the selection
*/
async function deleteJustForThisUser(
async function unsendMessageJustForThisUser(
conversation: ConversationModel,
msgsToDelete: Array<MessageModel>
) {
window?.log?.warn('Deleting messages just for this user');
// is deleting on swarm sufficient or does it need to be unsent as well?
const deleteResult = await deleteMessagesFromSwarmAndCompletelyLocally(
conversation,
msgsToDelete
const unsendMsgObjects = getUnsendMessagesObjects(msgsToDelete);
// sending to recipient all the messages separately for now
await Promise.all(
unsendMsgObjects.map(unsendObject =>
getMessageQueue()
.sendSyncMessage(unsendObject)
.catch(window?.log?.error)
)
);
await deleteMessagesFromSwarmAndCompletelyLocally(conversation, msgsToDelete);
// Update view and trigger update
window.inboxStore?.dispatch(resetSelectedMessageIds());
if (deleteResult) {
ToastUtils.pushDeleted();
} else {
ToastUtils.someDeletionsFailed();
}
ToastUtils.pushDeleted();
}
const doDeleteSelectedMessagesInSOGS = async (
@ -233,11 +250,15 @@ const doDeleteSelectedMessagesInSOGS = async (
*
* It does what needs to be done on a user action to delete messages for each conversation type
*/
const doDeleteSelectedMessages = async (
selectedMessages: Array<MessageModel>,
conversation: ConversationModel,
shouldDeleteForEveryone: boolean
) => {
const doDeleteSelectedMessages = async ({
conversation,
selectedMessages,
deleteForEveryone,
}: {
selectedMessages: Array<MessageModel>;
conversation: ConversationModel;
deleteForEveryone: boolean;
}) => {
const ourDevicePubkey = UserUtils.getOurPubKeyStrFromCache();
if (!ourDevicePubkey) {
return;
@ -249,16 +270,16 @@ const doDeleteSelectedMessages = async (
}
//#region deletion for 1-1 and closed groups
if (!isAllOurs) {
ToastUtils.pushMessageDeleteForbidden();
window.inboxStore?.dispatch(resetSelectedMessageIds());
return;
}
if (shouldDeleteForEveryone) {
if (deleteForEveryone) {
if (!isAllOurs) {
ToastUtils.pushMessageDeleteForbidden();
window.inboxStore?.dispatch(resetSelectedMessageIds());
return;
}
return unsendMessagesForEveryone(conversation, selectedMessages);
}
return deleteJustForThisUser(conversation, selectedMessages);
return unsendMessageJustForThisUser(conversation, selectedMessages);
//#endregion
};
@ -284,7 +305,7 @@ export async function deleteMessagesByIdForEveryone(
okText: window.i18n('deleteForEveryone'),
okTheme: SessionButtonColor.Danger,
onClickOk: async () => {
await doDeleteSelectedMessages(selectedMessages, conversation, true);
await doDeleteSelectedMessages({ selectedMessages, conversation, deleteForEveryone: true });
// explicity close modal for this case.
window.inboxStore?.dispatch(updateConfirmModal(null));
@ -295,7 +316,6 @@ export async function deleteMessagesByIdForEveryone(
);
}
// tslint:disable-next-line: max-func-body-length
export async function deleteMessagesById(messageIds: Array<string>, conversationId: string) {
const conversation = getConversationController().getOrThrow(conversationId);
const selectedMessages = _.compact(
@ -313,7 +333,12 @@ export async function deleteMessagesById(messageIds: Array<string>, conversation
okText: window.i18n('delete'),
okTheme: SessionButtonColor.Danger,
onClickOk: async () => {
await doDeleteSelectedMessages(selectedMessages, conversation, false);
await doDeleteSelectedMessages({
selectedMessages,
conversation,
deleteForEveryone: false,
});
window.inboxStore?.dispatch(updateConfirmModal(null));
},
closeAfterInput: false,
})

View File

@ -20,8 +20,8 @@ import { getAllCachedECKeyPair } from './closedGroups';
import { getMessageBySenderAndTimestamp } from '../data/data';
import { handleCallMessage } from './callMessage';
import {
deleteMessageLocallyOnly,
deleteMessagesFromSwarmOnly,
deleteMessagesFromSwarmAndCompletelyLocally,
deleteMessagesFromSwarmAndMarkAsDeletedLocally,
} from '../interactions/conversations/unsendingInteractions';
export async function handleContentMessage(envelope: EnvelopePlus, messageHash?: string) {
@ -499,21 +499,16 @@ async function handleTypingMessage(
* @param unsendMessage data required to delete message
*/
async function handleUnsendMessage(envelope: EnvelopePlus, unsendMessage: SignalService.Unsend) {
const { source: unsendSource } = envelope;
const { author: messageAuthor, timestamp } = unsendMessage;
await removeFromCache(envelope);
//#region early exit conditions
if (!unsendMessage || !unsendSource) {
window?.log?.error('UnsendMessageHandler:: Invalid parameters -- dropping message.');
if (!unsendMessage) {
window?.log?.error('handleUnsendMessage: Invalid parameters -- dropping message.');
}
if (!timestamp) {
window?.log?.error('UnsendMessageHander:: Invalid timestamp -- dropping message');
}
const conversation = getConversationController().get(unsendSource);
if (!conversation) {
return;
window?.log?.error('handleUnsendMessage: Invalid timestamp -- dropping message');
}
const messageToDelete = await getMessageBySenderAndTimestamp({
source: messageAuthor,
timestamp: Lodash.toNumber(timestamp),
@ -523,21 +518,22 @@ async function handleUnsendMessage(envelope: EnvelopePlus, unsendMessage: Signal
//#region executing deletion
if (messageHash && messageToDelete) {
const wasDeleted = await deleteMessagesFromSwarmOnly([messageToDelete]);
if (!wasDeleted) {
window.log.warn(
'handleUnsendMessage: got a request to delete ',
messageHash,
' but an error happened during deleting it from our swarm.'
);
window.log.info('handleUnsendMessage: got a request to delete ', messageHash);
const conversation = getConversationController().get(messageToDelete.get('conversationId'));
if (!conversation) {
await removeFromCache(envelope);
return;
}
if (messageToDelete.getSource() === UserUtils.getOurPubKeyStrFromCache()) {
// a message we sent is completely removed when we get a unsend request
void deleteMessagesFromSwarmAndCompletelyLocally(conversation, [messageToDelete]);
} else {
void deleteMessagesFromSwarmAndMarkAsDeletedLocally(conversation, [messageToDelete]);
}
// still, delete it locally
await deleteMessageLocallyOnly({
conversation,
message: messageToDelete,
deletionType: 'markDeleted',
});
}
await removeFromCache(envelope);
//#endregion
}

View File

@ -114,7 +114,11 @@ export class MessageQueue {
if (!message) {
return;
}
if (!(message instanceof ConfigurationMessage) && !(message as any)?.syncTarget) {
if (
!(message instanceof ConfigurationMessage) &&
!(message instanceof UnsendMessage) &&
!(message as any)?.syncTarget
) {
throw new Error('Invalid message given to sendSyncMessage');
}
@ -226,6 +230,7 @@ export class MessageQueue {
if (
message instanceof ConfigurationMessage ||
message instanceof ClosedGroupNewMessage ||
message instanceof UnsendMessage ||
(message as any).syncTarget?.length > 0
) {
window?.log?.warn('Processing sync message');

View File

@ -27,6 +27,7 @@ import { ExpirationTimerUpdateMessage } from '../messages/outgoing/controlMessag
import { getV2OpenGroupRoom } from '../../data/opengroups';
import { getCompleteUrlFromRoom } from '../../opengroup/utils/OpenGroupUtils';
import { DURATION } from '../constants';
import { UnsendMessage } from '../messages/outgoing/controlMessage/UnsendMessage';
const ITEM_ID_LAST_SYNC_TIMESTAMP = 'lastSyncedTimestamp';
@ -295,7 +296,11 @@ const buildSyncExpireTimerMessage = (
});
};
export type SyncMessageType = VisibleMessage | ExpirationTimerUpdateMessage | ConfigurationMessage;
export type SyncMessageType =
| VisibleMessage
| ExpirationTimerUpdateMessage
| ConfigurationMessage
| UnsendMessage;
export const buildSyncMessage = (
identifier: string,