fix attachment not being uploaded since electron upgrade

This commit is contained in:
audric 2021-08-17 16:03:57 +10:00
parent 9f7e20b8b8
commit 8a19b50c0f
9 changed files with 115 additions and 99 deletions

View File

@ -121,7 +121,13 @@ const InviteContactsDialogInner = (props: Props) => {
);
if (privateConvo) {
void privateConvo.sendMessage('', null, null, null, groupInvitation);
void privateConvo.sendMessage({
body: '',
attachments: undefined,
groupInvitation,
preview: undefined,
quote: undefined,
});
}
});
}

View File

@ -1,20 +1,18 @@
import React from 'react';
import _, { debounce } from 'lodash';
import { Attachment, AttachmentType } from '../../../types/Attachment';
import { AttachmentType } from '../../../types/Attachment';
import * as MIME from '../../../types/MIME';
import { SessionIconButton, SessionIconSize, SessionIconType } from '../icon';
import { SessionEmojiPanel } from './SessionEmojiPanel';
import { SessionRecording } from './SessionRecording';
import { SignalService } from '../../../protobuf';
import { Constants } from '../../../session';
import { toArray } from 'react-emoji-render';
import { Flex } from '../../basic/Flex';
import { StagedAttachmentList } from '../../conversation/AttachmentList';
import { StagedAttachmentList } from '../../conversation/StagedAttachmentList';
import { ToastUtils } from '../../../session/utils';
import { AttachmentUtil } from '../../../util';
import {
@ -79,8 +77,16 @@ export interface StagedAttachmentType extends AttachmentType {
file: File;
}
export type SendMessageType = {
body: string;
attachments: Array<StagedAttachmentType> | undefined;
quote: any | undefined;
preview: any | undefined;
groupInvitation: { url: string | undefined; name: string } | undefined;
};
interface Props {
sendMessage: any;
sendMessage: (msg: SendMessageType) => void;
draft: string;
onLoadVoiceNoteView: any;
@ -872,14 +878,13 @@ class SessionCompositionBoxInner extends React.Component<Props, State> {
try {
const attachments = await this.getFiles();
await this.props.sendMessage(
messagePlaintext,
attachments,
extractedQuotedMessageProps,
linkPreviews,
null,
{}
);
this.props.sendMessage({
body: messagePlaintext,
attachments: attachments || [],
quote: extractedQuotedMessageProps,
preview: linkPreviews,
groupInvitation: undefined,
});
this.props.clearAttachments();
@ -921,27 +926,27 @@ class SessionCompositionBoxInner extends React.Component<Props, State> {
return;
}
const fileBuffer = await new Response(audioBlob).arrayBuffer();
const file = new File([audioBlob], 'audio-blob');
const audioAttachment: Attachment = {
data: fileBuffer,
flags: SignalService.AttachmentPointer.Flags.VOICE_MESSAGE,
const audioAttachment: StagedAttachmentType = {
file,
contentType: MIME.AUDIO_MP3,
size: audioBlob.size,
fileSize: null,
screenshot: null,
fileName: 'audio-message',
thumbnail: null,
url: '',
isVoiceMessage: true,
};
const messageSuccess = this.props.sendMessage(
'',
[audioAttachment],
undefined,
undefined,
null,
{}
);
if (messageSuccess) {
// success!
}
await this.props.sendMessage({
body: '',
attachments: [audioAttachment],
preview: undefined,
quote: undefined,
groupInvitation: undefined,
});
this.onExitVoiceNoteView();
}

View File

@ -2,7 +2,11 @@ import React from 'react';
import classNames from 'classnames';
import { SessionCompositionBox, StagedAttachmentType } from './SessionCompositionBox';
import {
SendMessageType,
SessionCompositionBox,
StagedAttachmentType,
} from './SessionCompositionBox';
import { Constants } from '../../../session';
import _ from 'lodash';
@ -178,6 +182,47 @@ export class SessionConversation extends React.Component<Props, State> {
}
}
public sendMessageFn(msg: SendMessageType) {
const { selectedConversationKey } = this.props;
const conversationModel = getConversationController().get(selectedConversationKey);
if (!conversationModel) {
return;
}
const sendAndScroll = () => {
void conversationModel.sendMessage(msg);
if (this.messageContainerRef.current) {
(this.messageContainerRef
.current as any).scrollTop = this.messageContainerRef.current?.scrollHeight;
}
};
// const recoveryPhrase = window.textsecure.storage.get('mnemonic');
const recoveryPhrase = UserUtils.getCurrentRecoveryPhrase();
// string replace to fix case where pasted text contains invis characters causing false negatives
if (msg.body.replace(/\s/g, '').includes(recoveryPhrase.replace(/\s/g, ''))) {
window.inboxStore?.dispatch(
updateConfirmModal({
title: window.i18n('sendRecoveryPhraseTitle'),
message: window.i18n('sendRecoveryPhraseMessage'),
okTheme: SessionButtonColor.Danger,
onClickOk: () => {
sendAndScroll();
},
onClickClose: () => {
window.inboxStore?.dispatch(updateConfirmModal(null));
},
})
);
} else {
sendAndScroll();
}
window.inboxStore?.dispatch(quoteMessage(undefined));
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ~~~~~~~~~~~~~~ RENDER METHODS ~~~~~~~~~~~~~~
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -186,7 +231,6 @@ export class SessionConversation extends React.Component<Props, State> {
const {
selectedConversation,
selectedConversationKey,
messagesProps,
showMessageDetails,
selectedMessages,
@ -200,50 +244,6 @@ export class SessionConversation extends React.Component<Props, State> {
}
const selectionMode = selectedMessages.length > 0;
const conversationModel = getConversationController().get(selectedConversationKey);
const sendMessageFn = (
body: any,
attachments: any,
quote: any,
preview: any,
groupInvitation: any
) => {
if (!conversationModel) {
return;
}
const sendAndScroll = () => {
void conversationModel.sendMessage(body, attachments, quote, preview, groupInvitation);
if (this.messageContainerRef.current) {
(this.messageContainerRef
.current as any).scrollTop = this.messageContainerRef.current?.scrollHeight;
}
};
// const recoveryPhrase = window.textsecure.storage.get('mnemonic');
const recoveryPhrase = UserUtils.getCurrentRecoveryPhrase();
// string replace to fix case where pasted text contains invis characters causing false negatives
if (body.replace(/\s/g, '').includes(recoveryPhrase.replace(/\s/g, ''))) {
window.inboxStore?.dispatch(
updateConfirmModal({
title: window.i18n('sendRecoveryPhraseTitle'),
message: window.i18n('sendRecoveryPhraseMessage'),
okTheme: SessionButtonColor.Danger,
onClickOk: () => {
sendAndScroll();
},
onClickClose: () => {
window.inboxStore?.dispatch(updateConfirmModal(null));
},
})
);
} else {
sendAndScroll();
}
window.inboxStore?.dispatch(quoteMessage(undefined));
};
return (
<SessionTheme theme={this.props.theme}>
@ -273,7 +273,7 @@ export class SessionConversation extends React.Component<Props, State> {
</div>
<SessionCompositionBox
sendMessage={sendMessageFn}
sendMessage={this.sendMessageFn}
stagedAttachments={stagedAttachments}
onLoadVoiceNoteView={this.onLoadVoiceNoteView}
onExitVoiceNoteView={this.onExitVoiceNoteView}

View File

@ -10,7 +10,7 @@ import { StagedLinkPreview } from '../../conversation/StagedLinkPreview';
export interface StagedLinkPreviewProps extends StagedLinkPreviewData {
onClose: (url: string) => void;
}
export const LINK_PREVIEW_TIMEOUT = 60 * 1000;
export const LINK_PREVIEW_TIMEOUT = 20 * 1000;
export interface GetLinkPreviewResultImage {
data: ArrayBuffer;

View File

@ -195,6 +195,7 @@ export function init() {
// We can't send ArrayBuffers or BigNumbers (what we get from proto library for dates).
function _cleanData(data: any): any {
const keys = Object.keys(data);
for (let index = 0, max = keys.length; index < max; index += 1) {
const key = keys[index];
const value = data[key];
@ -210,6 +211,9 @@ function _cleanData(data: any): any {
} else if (Array.isArray(value)) {
// eslint-disable-next-line no-param-reassign
data[key] = value.map(_cleanData);
} else if (_.isObject(value) && value instanceof File) {
// eslint-disable-next-line no-param-reassign
data[key] = { name: value.name, path: value.path, size: value.size, type: value.type };
} else if (_.isObject(value)) {
// eslint-disable-next-line no-param-reassign
data[key] = _cleanData(value);

View File

@ -43,7 +43,10 @@ import { OpenGroupRequestCommonType } from '../opengroup/opengroupV2/ApiUtil';
import { getOpenGroupV2FromConversationId } from '../opengroup/utils/OpenGroupUtils';
import { createTaskWithTimeout } from '../session/utils/TaskWithTimeout';
import { perfEnd, perfStart } from '../session/utils/Performance';
import { ReplyingToMessageProps } from '../components/session/conversation/SessionCompositionBox';
import {
ReplyingToMessageProps,
SendMessageType,
} from '../components/session/conversation/SessionCompositionBox';
import { ed25519Str } from '../session/onions/onionPath';
export enum ConversationTypeEnum {
@ -702,13 +705,8 @@ export class ConversationModel extends Backbone.Model<ConversationAttributes> {
return null;
}
}
public async sendMessage(
body: string,
attachments: any,
quote: any,
preview: any,
groupInvitation: any = null
) {
public async sendMessage(msg: SendMessageType) {
const { attachments, body, groupInvitation, preview, quote } = msg;
this.clearTypingTimers();
const destination = this.id;
@ -745,21 +743,33 @@ export class ConversationModel extends Backbone.Model<ConversationAttributes> {
if (!this.isPublic()) {
messageWithSchema.destination = destination;
// set the serverTimestamp only if this conversation is a public one.
messageWithSchema.serverTimestamp = new Date().getTime();
}
messageWithSchema.source = UserUtils.getOurPubKeyStrFromCache();
messageWithSchema.sourceDevice = 1;
// set the serverTimestamp only if this conversation is a public one.
const attributes: MessageAttributesOptionals = {
...messageWithSchema,
groupInvitation,
conversationId: this.id,
destination: isPrivate ? destination : undefined,
serverTimestamp: this.isPublic() ? new Date().getTime() : undefined,
};
const messageModel = await this.addSingleMessage(attributes);
// We're offline!
if (!window.textsecure.messaging) {
const error = new Error('Network is not available');
error.name = 'SendMessageNetworkError';
(error as any).number = this.id;
await messageModel.saveErrors([error]);
await this.commit();
return;
}
this.set({
lastMessage: messageModel.getNotificationText(),
lastMessageStatus: 'sending',
@ -767,18 +777,9 @@ export class ConversationModel extends Backbone.Model<ConversationAttributes> {
});
await this.commit();
// We're offline!
if (!window.textsecure.messaging) {
const error = new Error('Network is not available');
error.name = 'SendMessageNetworkError';
(error as any).number = this.id;
await messageModel.saveErrors([error]);
return null;
}
this.queueJob(async () => {
await this.sendMessageJob(messageModel, expireTimer);
});
return null;
}
public async bouncyUpdateLastMessage() {

View File

@ -90,7 +90,7 @@ export async function autoScale<T extends { contentType: string; file: any }>(
resolve({
...attachment,
file: blob,
file: new File([blob], 'blob-file'),
});
};
img.src = url;

2
ts/window.d.ts vendored
View File

@ -70,7 +70,7 @@ declare global {
profileImages: any;
MediaRecorder: any;
dataURLToBlobSync: any;
autoOrientImage: any;
autoOrientImage: (fileOrBlobOrURL: string | File | Blob, options: any = {}) => Promise<string>;
contextMenuShown: boolean;
inboxStore?: Store;
openConversationWithMessages: (args: {