diff --git a/js/models/messages.js b/js/models/messages.js index 5b55a7317..27f307739 100644 --- a/js/models/messages.js +++ b/js/models/messages.js @@ -571,7 +571,6 @@ const isGroup = !!conversation && !conversation.isPrivate(); const attachments = this.get('attachments') || []; - const firstAttachment = attachments[0]; return { text: this.createNonBreakingLastSeparator(this.get('body')), @@ -987,6 +986,13 @@ attachments: attachmentsWithData, now: this.get('sent_at'), }); + const filenameOverridenAttachments = finalAttachments.map(attachment => ({ + ...attachment, + fileName: Signal.Types.Attachment.getSuggestedFilenameSending({ + attachment, + timestamp: Date.now(), + }), + })); const quoteWithData = await loadQuoteData(this.get('quote')); const previewWithData = await loadPreviewData(this.get('preview')); @@ -996,7 +1002,10 @@ const { AttachmentUtils } = libsession.Utils; const [attachments, preview, quote] = await Promise.all([ - AttachmentUtils.uploadAttachments(finalAttachments, openGroup), + AttachmentUtils.uploadAttachments( + filenameOverridenAttachments, + openGroup + ), AttachmentUtils.uploadLinkPreviews(previewWithData, openGroup), AttachmentUtils.uploadQuoteThumbnails(quoteWithData, openGroup), ]); diff --git a/js/modules/types/attachment.js b/js/modules/types/attachment.js index 1aaa1e0b0..26e91b16a 100644 --- a/js/modules/types/attachment.js +++ b/js/modules/types/attachment.js @@ -214,6 +214,7 @@ exports.deleteData = deleteOnDisk => { exports.isVoiceMessage = AttachmentTS.isVoiceMessage; exports.save = AttachmentTS.save; exports.getFileExtension = AttachmentTS.getFileExtension; +exports.getSuggestedFilenameSending = AttachmentTS.getSuggestedFilenameSending; const THUMBNAIL_SIZE = 150; const THUMBNAIL_CONTENT_TYPE = 'image/png'; diff --git a/stylesheets/_session.scss b/stylesheets/_session.scss index 38569d474..6b4b9c5de 100644 --- a/stylesheets/_session.scss +++ b/stylesheets/_session.scss @@ -1340,6 +1340,7 @@ input { position: absolute; bottom: 15px; right: 25px; + z-index: 2; .session-icon-button { display: flex; diff --git a/ts/components/conversation/Message.tsx b/ts/components/conversation/Message.tsx index 84ce4361a..525821323 100644 --- a/ts/components/conversation/Message.tsx +++ b/ts/components/conversation/Message.tsx @@ -181,7 +181,6 @@ export class Message extends React.PureComponent { this.checkExpired(); } - public checkExpired() { const now = Date.now(); const { isExpired, expirationTimestamp, expirationLength } = this.props; @@ -956,7 +955,6 @@ export class Message extends React.PureComponent { } = this.props; const { expired, expiring } = this.state; - if (expired) { return null; } @@ -988,7 +986,11 @@ export class Message extends React.PureComponent { } return ( -
+
{this.renderAvatar()}
{ // User clicked on message body const target = event.target as HTMLDivElement; - if (!multiSelectMode && target.className === 'text-selectable' || window.contextMenuShown) { + if ( + (!multiSelectMode && target.className === 'text-selectable') || + window.contextMenuShown + ) { return; } @@ -1035,7 +1040,10 @@ export class Message extends React.PureComponent { // User clicked on message body const target = event.target as HTMLDivElement; - if (target.className === 'text-selectable' || window.contextMenuShown) { + if ( + target.className === 'text-selectable' || + window.contextMenuShown + ) { return; } @@ -1062,11 +1070,7 @@ export class Message extends React.PureComponent { private handleContextMenu(e: any) { e.preventDefault(); e.stopPropagation(); - const { - isRss, - multiSelectMode, - isKickedFromGroup, - } = this.props; + const { isRss, multiSelectMode, isKickedFromGroup } = this.props; const enableContextMenu = !isRss && !multiSelectMode && !isKickedFromGroup; if (enableContextMenu) { diff --git a/ts/components/session/conversation/SessionConversationMessagesList.tsx b/ts/components/session/conversation/SessionConversationMessagesList.tsx index ee29bd734..392701b15 100644 --- a/ts/components/session/conversation/SessionConversationMessagesList.tsx +++ b/ts/components/session/conversation/SessionConversationMessagesList.tsx @@ -33,7 +33,7 @@ interface Props { ) => Promise<{ previousTopMessage: string }>; replyToMessage: (messageId: number) => Promise; onClickAttachment: (attachment: any, message: any) => void; - onDownloadAttachment: ({ attachment }: { attachment: any}) => void; + onDownloadAttachment: ({ attachment }: { attachment: any }) => void; } export class SessionConversationMessagesList extends React.Component< @@ -181,7 +181,7 @@ export class SessionConversationMessagesList extends React.Component< this.props.onClickAttachment(attachment, messageProps); }; messageProps.onDownload = (attachment: AttachmentType) => { - this.props.onDownloadAttachment({attachment}); + this.props.onDownloadAttachment({ attachment }); }; return ; diff --git a/ts/session/utils/Attachments.ts b/ts/session/utils/Attachments.ts index bcb22e458..10345d500 100644 --- a/ts/session/utils/Attachments.ts +++ b/ts/session/utils/Attachments.ts @@ -67,7 +67,6 @@ export class AttachmentUtils { } server = openGroupServer; } - const pointer: AttachmentPointer = { contentType: attachment.contentType ? (attachment.contentType as string) diff --git a/ts/test/types/Attachment_test.ts b/ts/test/types/Attachment_test.ts index e3c18b2c8..6d2c15ff3 100644 --- a/ts/test/types/Attachment_test.ts +++ b/ts/test/types/Attachment_test.ts @@ -48,7 +48,6 @@ describe('Attachment', () => { contentType: MIME.VIDEO_QUICKTIME, url: 'funny-cat.mov', fileName: 'funny-cat.mov', - }; const timestamp = moment('2000-01-01').toDate(); const actual = Attachment.getSuggestedFilename({ @@ -64,7 +63,8 @@ describe('Attachment', () => { const attachment: Attachment.AttachmentType = { fileName: 'funny-cat.mov', url: 'funny-cat.mov', - contentType: MIME.VIDEO_QUICKTIME, }; + contentType: MIME.VIDEO_QUICKTIME, + }; const timestamp = new Date(new Date(0).getTimezoneOffset() * 60 * 1000); const actual = Attachment.getSuggestedFilename({ attachment, diff --git a/ts/types/Attachment.ts b/ts/types/Attachment.ts index 09f6af521..a4fb4ffa0 100644 --- a/ts/types/Attachment.ts +++ b/ts/types/Attachment.ts @@ -369,6 +369,24 @@ export const getSuggestedFilename = ({ return `${prefix}${suffix}${indexSuffix}${extension}`; }; +// Used for overriden the sent filename of an attachment, but keeping the file extension the same +export const getSuggestedFilenameSending = ({ + attachment, + timestamp, +}: { + attachment: AttachmentType; + timestamp?: number | Date; +}): string => { + const prefix = 'session-attachment'; + const suffix = timestamp + ? moment(timestamp).format('-YYYY-MM-DD-HHmmss') + : ''; + const fileType = getFileExtension(attachment); + const extension = fileType ? `.${fileType}` : ''; + + return `${prefix}${suffix}${extension}`; +}; + export const getFileExtension = ( attachment: AttachmentType ): string | undefined => {