Simplify edit handling of attachments

This commit is contained in:
trevor-signal
2025-10-24 15:58:25 -04:00
committed by GitHub
parent 4199c2cb5c
commit a7303477a1
3 changed files with 22 additions and 53 deletions

View File

@@ -16,6 +16,7 @@ import {
isImageTypeSupported, isImageTypeSupported,
isVideoTypeSupported, isVideoTypeSupported,
} from './GoogleChrome.std.js'; } from './GoogleChrome.std.js';
import { strictAssert } from './assert.std.js';
const THUMBNAIL_SIZE = 150; const THUMBNAIL_SIZE = 150;
const THUMBNAIL_CONTENT_TYPE = IMAGE_PNG; const THUMBNAIL_CONTENT_TYPE = IMAGE_PNG;
@@ -80,6 +81,11 @@ export async function captureDimensionsAndScreenshot(
const localUrl = getLocalAttachmentUrl(attachment); const localUrl = getLocalAttachmentUrl(attachment);
if (isImageTypeSupported(contentType)) { if (isImageTypeSupported(contentType)) {
if (attachment.thumbnail?.path) {
// Already generated thumbnail / width / height
return attachment;
}
try { try {
const { width, height } = await getImageDimensionsFromURL({ const { width, height } = await getImageDimensionsFromURL({
objectUrl: localUrl, objectUrl: localUrl,
@@ -125,6 +131,13 @@ export async function captureDimensionsAndScreenshot(
} }
} }
strictAssert(isVideoTypeSupported(contentType), 'enforced by early return');
if (attachment.screenshot?.path) {
// Already generated screenshot / width / height
return attachment;
}
let screenshotObjectUrl: string | undefined; let screenshotObjectUrl: string | undefined;
try { try {
const { blob, duration } = await makeVideoScreenshot({ const { blob, duration } = await makeVideoScreenshot({

View File

@@ -137,29 +137,13 @@ export async function handleEditMessage(
editAttributes.message editAttributes.message
); );
// Copies over the attachments from the main message if they're the same
// and they have already been downloaded.
const attachmentSignatures: Map<string, AttachmentType> = new Map();
const previewSignatures: Map<string, AttachmentType> = new Map(); const previewSignatures: Map<string, AttachmentType> = new Map();
const quoteSignatures: Map<string, AttachmentType> = new Map();
mainMessage.attachments?.forEach(attachment => {
cacheAttachmentBySignature(attachmentSignatures, attachment);
});
mainMessage.preview?.forEach(preview => { mainMessage.preview?.forEach(preview => {
if (!preview.image) { if (!preview.image) {
return; return;
} }
cacheAttachmentBySignature(previewSignatures, preview.image); cacheAttachmentBySignature(previewSignatures, preview.image);
}); });
if (mainMessage.quote) {
for (const attachment of mainMessage.quote.attachments) {
if (!attachment.thumbnail) {
continue;
}
cacheAttachmentBySignature(quoteSignatures, attachment.thumbnail);
}
}
const nextEditedMessagePreview = upgradedEditedMessageData.preview?.map( const nextEditedMessagePreview = upgradedEditedMessageData.preview?.map(
preview => { preview => {

View File

@@ -11,7 +11,6 @@ import type {
} from '../model-types.d.ts'; } from '../model-types.d.ts';
import { createLogger } from '../logging/log.std.js'; import { createLogger } from '../logging/log.std.js';
import { DataReader, DataWriter } from '../sql/Client.preload.js'; import { DataReader, DataWriter } from '../sql/Client.preload.js';
import type { AttachmentType } from '../types/Attachment.std.js';
import { ErrorWithToast } from '../types/ErrorWithToast.std.js'; import { ErrorWithToast } from '../types/ErrorWithToast.std.js';
import { SendStatus } from '../messages/MessageSendState.std.js'; import { SendStatus } from '../messages/MessageSendState.std.js';
import { ToastType } from '../types/Toast.dom.js'; import { ToastType } from '../types/Toast.dom.js';
@@ -107,28 +106,6 @@ export async function sendEditedMessage(
conversation.clearTypingTimers(); conversation.clearTypingTimers();
// Can't send both preview and attachments
const attachments =
preview && preview.length ? [] : targetMessage.get('attachments') || [];
const fixNewAttachment = (
attachment: AttachmentType,
temporaryDigest: string
): AttachmentType => {
// Check if this is an existing attachment or a new attachment coming
// from composer
if (attachment.digest) {
return attachment;
}
// Generated semi-unique digest so that `handleEditMessage` understand
// it is a new attachment
return {
...attachment,
digest: `${temporaryDigest}:${attachment.path}`,
};
};
let quote: QuotedMessageType | undefined; let quote: QuotedMessageType | undefined;
if (quoteSentAt !== undefined && quoteAuthorAci !== undefined) { if (quoteSentAt !== undefined && quoteAuthorAci !== undefined) {
const existingQuote = targetMessage.get('quote'); const existingQuote = targetMessage.get('quote');
@@ -173,25 +150,20 @@ export async function sendEditedMessage(
}) })
); );
const originalAttachments = targetMessage.get('attachments');
let previewToSend: Array<LinkPreviewType> | undefined = preview;
if (originalAttachments?.length && preview.length) {
log.error('Cannot send message with both attachments and preview');
previewToSend = undefined;
}
// An ephemeral message that we just use to handle the edit // An ephemeral message that we just use to handle the edit
const tmpMessage: MessageAttributesType = { const tmpMessage: MessageAttributesType = {
attachments: attachments?.map((attachment, index) => attachments: originalAttachments,
fixNewAttachment(attachment, `attachment:${index}`)
),
body, body,
bodyRanges, bodyRanges,
conversationId, conversationId,
preview: preview?.map((entry, index) => { preview: previewToSend,
const image =
entry.image && fixNewAttachment(entry.image, `preview:${index}`);
if (entry.image === image) {
return entry;
}
return {
...entry,
image,
};
}),
id: generateUuid(), id: generateUuid(),
quote, quote,
received_at: incrementMessageCounter(), received_at: incrementMessageCounter(),