fix attachment not being uploaded since electron upgrade
This commit is contained in:
parent
9f7e20b8b8
commit
8a19b50c0f
|
@ -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,
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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: {
|
||||
|
|
Loading…
Reference in New Issue