Finish hooking up attachments

pull/1198/head
Mikunj 5 years ago
parent fbbbadada5
commit c589f4a4af

@ -1191,6 +1191,18 @@
};
},
getOpenGroup() {
if (!this.isPublic()) {
return undefined;
}
return new libsession.Types.OpenGroup({
server: this.get('server'),
channel: this.get('channelId'),
conversationId: this.id,
});
},
async sendMessage(
body,
attachments,
@ -1291,30 +1303,18 @@
return null;
}
const attachmentsWithData = await Promise.all(
messageWithSchema.attachments.map(loadAttachmentData)
);
const {
body: messageBody,
attachments: finalAttachments,
} = Whisper.Message.getLongMessageAttachment({
body,
attachments: attachmentsWithData,
now,
});
try {
const uploads = await message.uploadData();
// FIXME audric add back profileKey
const chatMessage = new libsession.Messages.Outgoing.ChatMessage({
body: messageBody,
body: uploads.body,
timestamp: Date.now(),
attachments: finalAttachments,
attachments: uploads.attachments,
expireTimer,
preview,
quote,
preview: uploads.preview,
quote: uploads.quote,
});
// Start handle ChatMessages (attachments/quote/preview/body)
// FIXME AUDRIC handle attachments, quote, preview, profileKey
if (this.isMe()) {
await message.markMessageSyncOnly();
@ -1325,12 +1325,8 @@
options.messageType = message.get('type');
options.isPublic = this.isPublic();
if (this.isPublic()) {
// FIXME audric add back attachments, quote, preview
const openGroup = {
server: this.get('server'),
channel: this.get('channelId'),
conversationId: this.id,
};
const openGroup = this.getOpenGroup();
const openGroupParams = {
body,
timestamp: Date.now(),
@ -1406,7 +1402,14 @@
`Invalid conversation type: '${conversationType}'`
);
}
return true;
} catch (e) {
log.warn('Failed to send message: ', e);
await message.saveErrors(e);
return null;
}
});
},
wrapSend(promise) {

@ -28,8 +28,8 @@
deleteExternalMessageFiles,
getAbsoluteAttachmentPath,
loadAttachmentData,
// loadQuoteData,
// loadPreviewData,
loadQuoteData,
loadPreviewData,
} = window.Signal.Migrations;
const { bytesFromString } = window.Signal.Crypto;
@ -991,6 +991,49 @@
});
},
/**
* Uploads attachments, previews and quotes.
* If body is too long then it is also converted to an attachment.
*
* @returns The uploaded data which includes: body, attachments, preview and quote.
*/
async uploadData() {
// TODO: In the future it might be best if we cache the upload results if possible.
// This way we don't upload duplicated data.
const attachmentsWithData = await Promise.all(
(this.get('attachments') || []).map(loadAttachmentData)
);
const {
body,
attachments: finalAttachments,
} = Whisper.Message.getLongMessageAttachment({
body: this.get('body'),
attachments: attachmentsWithData,
now: this.get('sent_at'),
});
const quoteWithData = await loadQuoteData(this.get('quote'));
const previewWithData = await loadPreviewData(this.get('preview'));
const conversation = this.getConversation();
const openGroup = conversation && conversation.getOpenGroup();
const { AttachmentUtils } = libsession.Utils;
const [attachments, preview, quote] = await Promise.all([
AttachmentUtils.uploadAttachments(finalAttachments, openGroup),
AttachmentUtils.uploadLinkPreviews(previewWithData, openGroup),
AttachmentUtils.uploadQuoteThumbnails(quoteWithData, openGroup),
]);
return {
body,
attachments,
preview,
quote,
};
},
// One caller today: event handler for the 'Retry Send' entry in triple-dot menu
async retrySend() {
if (!textsecure.messaging) {
@ -1000,6 +1043,7 @@
this.set({ errors: null });
try {
const conversation = this.getConversation();
const intendedRecipients = this.get('recipients') || [];
const successfulRecipients = this.get('sent_to') || [];
@ -1020,28 +1064,17 @@
});
}
const attachmentsWithData = await Promise.all(
(this.get('attachments') || []).map(loadAttachmentData)
);
const { body } = Whisper.Message.getLongMessageAttachment({
body: this.get('body'),
attachments: attachmentsWithData,
now: this.get('sent_at'),
});
// TODO add logic for attachments, quote and preview here
// don't blindly reuse the one from loadQuoteData loadPreviewData and getLongMessageAttachment.
// they have similar data structure to the ones we need
// but the main difference is that they haven't been uploaded
// so no url exists in them
// so passing it to chat message is incorrect
// const quoteWithData = await loadQuoteData(this.get('quote'));
// const previewWithData = await loadPreviewData(this.get('preview'));
const { body, attachments, preview, quote } = await this.uploadData();
const chatMessage = new libsession.Messages.Outgoing.ChatMessage({
body,
timestamp: this.get('sent_at'),
expireTimer: this.get('expireTimer'),
attachments,
preview,
quote,
});
// Special-case the self-send case - we send only a sync message
if (recipients.length === 1 && recipients[0] === this.OUR_NUMBER) {
this.trigger('pending');
@ -1079,6 +1112,11 @@
.sendUsingMultiDevice(recipientPubKey, closedGroupChatMessage);
})
);
} catch (e) {
window.log.warn('Failed message retry send: ', e);
await this.saveErrors(e);
return null;
}
},
isReplayableError(e) {
return (
@ -1102,31 +1140,22 @@
return null;
}
const attachmentsWithData = await Promise.all(
(this.get('attachments') || []).map(loadAttachmentData)
);
const { body } = Whisper.Message.getLongMessageAttachment({
body: this.get('body'),
attachments: attachmentsWithData,
now: this.get('sent_at'),
});
// TODO add logic for attachments, quote and preview here
// don't blindly reuse the one from loadQuoteData loadPreviewData and getLongMessageAttachment.
// they have similar data structure to the ones we need
// but the main difference is that they haven't been uploaded
// so no url exists in them
// so passing it to chat message is incorrect
// const quoteWithData = await loadQuoteData(this.get('quote'));
// const previewWithData = await loadPreviewData(this.get('preview'));
try {
const { body, attachments, preview, quote } = await this.uploadData();
const chatMessage = new libsession.Messages.Outgoing.ChatMessage({
body,
timestamp: this.get('sent_at'),
expireTimer: this.get('expireTimer'),
attachments,
preview,
quote,
});
this.trigger('pending');
// Special-case the self-send case - we send only a sync message
if (number === this.OUR_NUMBER) {
this.trigger('pending');
await this.markMessageSyncOnly();
// sending is done in the private case below
}
@ -1134,7 +1163,6 @@
const recipientPubKey = new libsession.Types.PubKey(number);
if (conversation.isPrivate()) {
this.trigger('pending');
return libsession
.getMessageQueue()
.sendUsingMultiDevice(recipientPubKey, chatMessage);
@ -1147,10 +1175,13 @@
}
);
// resend tries to send the message to that specific user only in the context of a closed group
this.trigger('pending');
return libsession
.getMessageQueue()
.sendUsingMultiDevice(recipientPubKey, closedGroupChatMessage);
} catch (e) {
await this.saveErrors(e);
return null;
}
},
removeOutgoingErrors(number) {
const errors = _.partition(

@ -108,7 +108,7 @@ export class AttachmentUtils {
attachments: Array<Attachment>,
openGroup?: OpenGroup
): Promise<Array<AttachmentPointer>> {
const promises = attachments.map(async attachment =>
const promises = (attachments || []).map(async attachment =>
this.upload({
attachment,
openGroup,
@ -122,7 +122,7 @@ export class AttachmentUtils {
previews: Array<RawPreview>,
openGroup?: OpenGroup
): Promise<Array<Preview>> {
const promises = previews.map(async item => ({
const promises = (previews || []).map(async item => ({
...item,
image: await this.upload({
attachment: item.image,
@ -133,9 +133,13 @@ export class AttachmentUtils {
}
public static async uploadQuoteThumbnails(
quote: RawQuote,
quote?: RawQuote,
openGroup?: OpenGroup
): Promise<Quote> {
): Promise<Quote | undefined> {
if (!quote) {
return undefined;
}
const promises = (quote.attachments ?? []).map(async attachment => {
let thumbnail: AttachmentPointer | undefined;
if (attachment.thumbnail) {

Loading…
Cancel
Save