enable back attachments download on context menu

pull/1387/head
Audric Ackermann 5 years ago
parent f166ec814e
commit a7c4ce77a1
No known key found for this signature in database
GPG Key ID: 999F434D76324AD4

@ -621,12 +621,6 @@
onDelete: () => this.trigger('delete', this),
onClickLinkPreview: url => this.trigger('navigate-to', url),
onDownload: isDangerous =>
this.trigger('download', {
attachment: firstAttachment,
message: this,
isDangerous,
}),
onShowUserDetails: pubkey =>
window.Whisper.events.trigger('onShowUserDetails', {
userPubKey: pubkey,

@ -112,7 +112,7 @@ export interface Props {
onSelectMessage: (messageId: string) => void;
onReply?: (messagId: number) => void;
onRetrySend?: () => void;
onDownload?: (isDangerous: boolean) => void;
onDownload?: (attachment: AttachmentType) => void;
onDelete?: () => void;
onCopyPubKey?: () => void;
onBanUser?: () => void;
@ -853,7 +853,7 @@ export class Message extends React.PureComponent<Props, State> {
onClick={(e: any) => {
e.event.stopPropagation();
if (onDownload) {
onDownload(isDangerous);
onDownload(attachments[0]);
}
}}
>

@ -22,7 +22,7 @@ import { SessionConversationMessagesList } from './SessionConversationMessagesLi
import { LightboxGallery, MediaItemType } from '../../LightboxGallery';
import { Message } from '../../conversation/media-gallery/types/Message';
import { AttachmentType } from '../../../types/Attachment';
import { AttachmentType, save } from '../../../types/Attachment';
import { ToastUtils } from '../../../session/utils';
import * as MIME from '../../../types/MIME';
import { SessionFileDropzone } from './SessionFileDropzone';
@ -133,6 +133,7 @@ export class SessionConversation extends React.Component<Props, State> {
this.replyToMessage = this.replyToMessage.bind(this);
this.onClickAttachment = this.onClickAttachment.bind(this);
this.downloadAttachment = this.downloadAttachment.bind(this);
this.getMessages = this.getMessages.bind(this);
// Keyboard navigation
@ -435,7 +436,6 @@ export class SessionConversation extends React.Component<Props, State> {
),
members,
subscriberCount: conversation.get('subscriberCount'),
selectedMessages: this.state.selectedMessages?.length,
isKickedFromGroup: conversation.get('isKickedFromGroup'),
expirationSettingName,
showBackButton: Boolean(this.state.infoViewState),
@ -534,6 +534,7 @@ export class SessionConversation extends React.Component<Props, State> {
replyToMessage: this.replyToMessage,
doneInitialScroll: this.state.doneInitialScroll,
onClickAttachment: this.onClickAttachment,
onDownloadAttachment: this.downloadAttachment,
messageContainerRef: this.messageContainerRef,
};
}
@ -965,12 +966,12 @@ export class SessionConversation extends React.Component<Props, State> {
index,
}: {
attachment: AttachmentType;
message: Message;
index: number;
message?: Message;
index?: number;
}) {
const { getAbsoluteAttachmentPath } = window.Signal.Migrations;
window.Signal.Types.Attachment.save({
save({
attachment,
document,
getAbsolutePath: getAbsoluteAttachmentPath,

@ -8,6 +8,8 @@ import { ResetSessionNotification } from '../../conversation/ResetSessionNotific
import { Constants } from '../../../session';
import _ from 'lodash';
import { ConversationModel } from '../../../../js/models/conversations';
import { contextMenu } from 'react-contexify';
import { AttachmentType } from '../../../types/Attachment';
interface State {
isScrolledToBottom: boolean;
@ -31,6 +33,7 @@ interface Props {
) => Promise<{ previousTopMessage: string }>;
replyToMessage: (messageId: number) => Promise<void>;
onClickAttachment: (attachment: any, message: any) => void;
onDownloadAttachment: ({ attachment }: { attachment: any}) => void;
}
export class SessionConversationMessagesList extends React.Component<
@ -122,8 +125,6 @@ export class SessionConversationMessagesList extends React.Component<
<>
{messages.map((message: any) => {
const messageProps = message.propsForMessage;
// const quoteProps = messageProps.quote;
// console.warn('propsForQuote', quoteProps);
const timerProps = message.propsForTimerNotification;
const resetSessionProps = message.propsForResetSessionNotification;
@ -136,7 +137,6 @@ export class SessionConversationMessagesList extends React.Component<
// in a series of messages from the same user
item = messageProps
? this.renderMessage(
message,
messageProps,
message.firstMessageOfSeries,
multiSelectMode
@ -149,7 +149,6 @@ export class SessionConversationMessagesList extends React.Component<
) : (
item
);
// item = attachmentProps ? this.renderMessage(timerProps) : item;
return item;
})}
@ -158,7 +157,6 @@ export class SessionConversationMessagesList extends React.Component<
}
public renderMessage(
message: any,
messageProps: any,
firstMessageOfSeries: boolean,
multiSelectMode: boolean
@ -182,7 +180,9 @@ export class SessionConversationMessagesList extends React.Component<
messageProps.onClickAttachment = (attachment: any) => {
this.props.onClickAttachment(attachment, messageProps);
};
// messageProps.onDownload = ()
messageProps.onDownload = (attachment: AttachmentType) => {
this.props.onDownloadAttachment({attachment});
};
return <Message {...messageProps} />;
}

@ -15,6 +15,7 @@ import {
ConversationAvatar,
usingClosedConversationDetails,
} from '../usingClosedConversationDetails';
import { save } from '../../../types/Attachment';
interface Props {
id: string;
@ -184,7 +185,7 @@ class SessionRightPanel extends React.Component<Props, State> {
const saveAttachment = async ({ attachment, message }: any = {}) => {
const timestamp = message.received_at;
window.Signal.Types.Attachment.save({
save({
attachment,
document,
getAbsolutePath: window.Signal.Migrations.getAbsoluteAttachmentPath,

@ -7,19 +7,22 @@ import { SignalService } from '../../protobuf';
// @ts-ignore
import { stringToArrayBuffer } from '../../../js/modules/string_to_array_buffer';
// tslint:disable-next-line: max-func-body-length
describe('Attachment', () => {
describe('getFileExtension', () => {
it('should return file extension from content type', () => {
const input: Attachment.Attachment = {
data: stringToArrayBuffer('foo'),
contentType: MIME.IMAGE_GIF,
const input: Attachment.AttachmentType = {
fileName: 'funny-cat.mov',
url: 'funny-cat.mov',
contentType: MIME.VIDEO_QUICKTIME,
};
assert.strictEqual(Attachment.getFileExtension(input), 'gif');
});
it('should return file extension for QuickTime videos', () => {
const input: Attachment.Attachment = {
data: stringToArrayBuffer('foo'),
const input: Attachment.AttachmentType = {
fileName: 'funny-cat.mov',
url: 'funny-cat.mov',
contentType: MIME.VIDEO_QUICKTIME,
};
assert.strictEqual(Attachment.getFileExtension(input), 'mov');
@ -29,9 +32,9 @@ describe('Attachment', () => {
describe('getSuggestedFilename', () => {
context('for attachment with filename', () => {
it('should return existing filename if present', () => {
const attachment: Attachment.Attachment = {
const attachment: Attachment.AttachmentType = {
fileName: 'funny-cat.mov',
data: stringToArrayBuffer('foo'),
url: 'funny-cat.mov',
contentType: MIME.VIDEO_QUICKTIME,
};
const actual = Attachment.getSuggestedFilename({ attachment });
@ -41,9 +44,11 @@ describe('Attachment', () => {
});
context('for attachment without filename', () => {
it('should generate a filename based on timestamp', () => {
const attachment: Attachment.Attachment = {
data: stringToArrayBuffer('foo'),
const attachment: Attachment.AttachmentType = {
contentType: MIME.VIDEO_QUICKTIME,
url: 'funny-cat.mov',
fileName: 'funny-cat.mov',
};
const timestamp = moment('2000-01-01').toDate();
const actual = Attachment.getSuggestedFilename({
@ -56,10 +61,10 @@ describe('Attachment', () => {
});
context('for attachment with index', () => {
it('should generate a filename based on timestamp', () => {
const attachment: Attachment.Attachment = {
data: stringToArrayBuffer('foo'),
contentType: MIME.VIDEO_QUICKTIME,
};
const attachment: Attachment.AttachmentType = {
fileName: 'funny-cat.mov',
url: 'funny-cat.mov',
contentType: MIME.VIDEO_QUICKTIME, };
const timestamp = new Date(new Date(0).getTimezoneOffset() * 60 * 1000);
const actual = Attachment.getSuggestedFilename({
attachment,

@ -330,19 +330,14 @@ export const save = ({
getAbsolutePath,
timestamp,
}: {
attachment: Attachment;
attachment: AttachmentType;
document: Document;
index: number;
index?: number;
getAbsolutePath: (relativePath: string) => string;
timestamp?: number;
}): void => {
const isObjectURLRequired = is.undefined(attachment.path);
const url = !is.undefined(attachment.path)
? getAbsolutePath(attachment.path)
: arrayBufferToObjectURL({
data: attachment.data,
type: MIME.APPLICATION_OCTET_STREAM,
});
const isObjectURLRequired = is.undefined(attachment.fileName);
const url = getAbsolutePath(attachment.fileName);
const filename = getSuggestedFilename({ attachment, timestamp, index });
saveURLAsFile({ url, filename, document });
if (isObjectURLRequired) {
@ -355,7 +350,7 @@ export const getSuggestedFilename = ({
timestamp,
index,
}: {
attachment: Attachment;
attachment: AttachmentType;
timestamp?: number | Date;
index?: number;
}): string => {
@ -375,7 +370,7 @@ export const getSuggestedFilename = ({
};
export const getFileExtension = (
attachment: Attachment
attachment: AttachmentType
): string | undefined => {
if (!attachment.contentType) {
return;

Loading…
Cancel
Save