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

@ -28,8 +28,8 @@
deleteExternalMessageFiles, deleteExternalMessageFiles,
getAbsoluteAttachmentPath, getAbsoluteAttachmentPath,
loadAttachmentData, loadAttachmentData,
// loadQuoteData, loadQuoteData,
// loadPreviewData, loadPreviewData,
} = window.Signal.Migrations; } = window.Signal.Migrations;
const { bytesFromString } = window.Signal.Crypto; 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 // One caller today: event handler for the 'Retry Send' entry in triple-dot menu
async retrySend() { async retrySend() {
if (!textsecure.messaging) { if (!textsecure.messaging) {
@ -1000,6 +1043,7 @@
this.set({ errors: null }); this.set({ errors: null });
try {
const conversation = this.getConversation(); const conversation = this.getConversation();
const intendedRecipients = this.get('recipients') || []; const intendedRecipients = this.get('recipients') || [];
const successfulRecipients = this.get('sent_to') || []; const successfulRecipients = this.get('sent_to') || [];
@ -1020,28 +1064,17 @@
}); });
} }
const attachmentsWithData = await Promise.all( const { body, attachments, preview, quote } = await this.uploadData();
(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 chatMessage = new libsession.Messages.Outgoing.ChatMessage({ const chatMessage = new libsession.Messages.Outgoing.ChatMessage({
body, body,
timestamp: this.get('sent_at'), timestamp: this.get('sent_at'),
expireTimer: this.get('expireTimer'), expireTimer: this.get('expireTimer'),
attachments,
preview,
quote,
}); });
// Special-case the self-send case - we send only a sync message // Special-case the self-send case - we send only a sync message
if (recipients.length === 1 && recipients[0] === this.OUR_NUMBER) { if (recipients.length === 1 && recipients[0] === this.OUR_NUMBER) {
this.trigger('pending'); this.trigger('pending');
@ -1079,6 +1112,11 @@
.sendUsingMultiDevice(recipientPubKey, closedGroupChatMessage); .sendUsingMultiDevice(recipientPubKey, closedGroupChatMessage);
}) })
); );
} catch (e) {
window.log.warn('Failed message retry send: ', e);
await this.saveErrors(e);
return null;
}
}, },
isReplayableError(e) { isReplayableError(e) {
return ( return (
@ -1102,31 +1140,22 @@
return null; return null;
} }
const attachmentsWithData = await Promise.all( try {
(this.get('attachments') || []).map(loadAttachmentData) const { body, attachments, preview, quote } = await this.uploadData();
);
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 chatMessage = new libsession.Messages.Outgoing.ChatMessage({ const chatMessage = new libsession.Messages.Outgoing.ChatMessage({
body, body,
timestamp: this.get('sent_at'), timestamp: this.get('sent_at'),
expireTimer: this.get('expireTimer'), expireTimer: this.get('expireTimer'),
attachments,
preview,
quote,
}); });
this.trigger('pending');
// Special-case the self-send case - we send only a sync message // Special-case the self-send case - we send only a sync message
if (number === this.OUR_NUMBER) { if (number === this.OUR_NUMBER) {
this.trigger('pending');
await this.markMessageSyncOnly(); await this.markMessageSyncOnly();
// sending is done in the private case below // sending is done in the private case below
} }
@ -1134,7 +1163,6 @@
const recipientPubKey = new libsession.Types.PubKey(number); const recipientPubKey = new libsession.Types.PubKey(number);
if (conversation.isPrivate()) { if (conversation.isPrivate()) {
this.trigger('pending');
return libsession return libsession
.getMessageQueue() .getMessageQueue()
.sendUsingMultiDevice(recipientPubKey, chatMessage); .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 // resend tries to send the message to that specific user only in the context of a closed group
this.trigger('pending');
return libsession return libsession
.getMessageQueue() .getMessageQueue()
.sendUsingMultiDevice(recipientPubKey, closedGroupChatMessage); .sendUsingMultiDevice(recipientPubKey, closedGroupChatMessage);
} catch (e) {
await this.saveErrors(e);
return null;
}
}, },
removeOutgoingErrors(number) { removeOutgoingErrors(number) {
const errors = _.partition( const errors = _.partition(

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

Loading…
Cancel
Save