mirror of
https://github.com/signalapp/Signal-Desktop.git
synced 2026-02-14 23:18:54 +00:00
View-once media: backend send support
This commit is contained in:
@@ -86,6 +86,7 @@ import { uuidToBytes } from '../../util/uuidToBytes.std.js';
|
||||
import { fromBase64 } from '../../Bytes.std.js';
|
||||
import { MIMETypeToString } from '../../types/MIME.std.js';
|
||||
import { canReuseExistingTransitCdnPointerForEditedMessage } from '../../util/Attachment.std.js';
|
||||
import { eraseMessageContents } from '../../util/cleanup.preload.js';
|
||||
|
||||
const { isNumber } = lodash;
|
||||
|
||||
@@ -231,6 +232,7 @@ export async function sendNormalMessage(
|
||||
contact,
|
||||
deletedForEveryoneTimestamp,
|
||||
expireTimer,
|
||||
isViewOnce,
|
||||
bodyRanges,
|
||||
preview,
|
||||
quote,
|
||||
@@ -365,6 +367,7 @@ export async function sendNormalMessage(
|
||||
deletedForEveryoneTimestamp,
|
||||
expireTimer,
|
||||
groupV2: groupV2Info,
|
||||
isViewOnce,
|
||||
body,
|
||||
preview,
|
||||
profileKey,
|
||||
@@ -432,6 +435,7 @@ export async function sendNormalMessage(
|
||||
deletedForEveryoneTimestamp,
|
||||
expireTimer,
|
||||
expireTimerVersion: conversation.getExpireTimerVersion(),
|
||||
isViewOnce,
|
||||
preview,
|
||||
profileKey,
|
||||
quote,
|
||||
@@ -495,6 +499,10 @@ export async function sendNormalMessage(
|
||||
}
|
||||
throw new Error('message did not fully send');
|
||||
}
|
||||
|
||||
if (isViewOnce) {
|
||||
await eraseMessageContents(message, 'view-once-sent');
|
||||
}
|
||||
} catch (thrownError: unknown) {
|
||||
const errors = [thrownError, ...messageSendErrors];
|
||||
await handleMultipleSendErrors({
|
||||
@@ -626,6 +634,7 @@ async function getMessageSendData({
|
||||
deletedForEveryoneTimestamp: undefined | number;
|
||||
expireTimer: undefined | DurationInSeconds;
|
||||
bodyRanges: undefined | ReadonlyArray<RawBodyRange>;
|
||||
isViewOnce?: boolean;
|
||||
preview: Array<OutgoingLinkPreviewType> | undefined;
|
||||
quote: OutgoingQuoteType | undefined;
|
||||
sticker: OutgoingStickerType | undefined;
|
||||
@@ -753,6 +762,7 @@ async function getMessageSendData({
|
||||
contact,
|
||||
deletedForEveryoneTimestamp: message.get('deletedForEveryoneTimestamp'),
|
||||
expireTimer: message.get('expireTimer'),
|
||||
isViewOnce: message.get('isViewOnce'),
|
||||
bodyRanges: getPropForTimestamp({
|
||||
log,
|
||||
message: message.attributes,
|
||||
|
||||
@@ -728,7 +728,7 @@ export async function handleDataMessage(
|
||||
}
|
||||
|
||||
if (isTapToView(message.attributes) && type === 'outgoing') {
|
||||
await eraseMessageContents(message, 'view-once-viewed');
|
||||
await eraseMessageContents(message, 'view-once-sent');
|
||||
}
|
||||
|
||||
if (
|
||||
|
||||
@@ -4087,6 +4087,7 @@ export class ConversationModel {
|
||||
body,
|
||||
contact,
|
||||
bodyRanges,
|
||||
isViewOnce,
|
||||
preview,
|
||||
quote,
|
||||
sticker,
|
||||
@@ -4096,6 +4097,7 @@ export class ConversationModel {
|
||||
body: string | undefined;
|
||||
contact?: Array<EmbeddedContactWithHydratedAvatar>;
|
||||
bodyRanges?: DraftBodyRanges;
|
||||
isViewOnce?: boolean;
|
||||
preview?: Array<LinkPreviewWithHydratedData>;
|
||||
quote?: QuotedMessageType;
|
||||
sticker?: StickerWithHydratedData;
|
||||
@@ -4230,6 +4232,7 @@ export class ConversationModel {
|
||||
received_at_ms: now,
|
||||
expirationStartTimestamp,
|
||||
expireTimer,
|
||||
isViewOnce,
|
||||
readStatus: ReadStatus.Read,
|
||||
seenStatus: SeenStatus.NotApplicable,
|
||||
sticker,
|
||||
|
||||
@@ -613,6 +613,7 @@ function sendMultiMediaMessage(
|
||||
options: WithPreSendChecksOptions & {
|
||||
bodyRanges?: DraftBodyRanges;
|
||||
draftAttachments?: ReadonlyArray<AttachmentDraftType>;
|
||||
isViewOnce?: boolean;
|
||||
timestamp?: number;
|
||||
}
|
||||
): ThunkAction<
|
||||
@@ -635,6 +636,7 @@ function sendMultiMediaMessage(
|
||||
const {
|
||||
draftAttachments,
|
||||
bodyRanges,
|
||||
isViewOnce,
|
||||
message = '',
|
||||
timestamp = Date.now(),
|
||||
voiceNoteAttachment,
|
||||
@@ -676,6 +678,7 @@ function sendMultiMediaMessage(
|
||||
quote,
|
||||
preview: getLinkPreviewForSend(message),
|
||||
bodyRanges,
|
||||
isViewOnce,
|
||||
},
|
||||
{
|
||||
sendHQImages,
|
||||
|
||||
@@ -212,6 +212,7 @@ export type SharedMessageOptionsType = Readonly<{
|
||||
flags?: number;
|
||||
groupCallUpdate?: GroupCallUpdateType;
|
||||
groupV2?: GroupV2InfoType;
|
||||
isViewOnce?: boolean;
|
||||
pinMessage?: SendPinMessageType;
|
||||
pollVote?: OutgoingPollVote;
|
||||
pollCreate?: PollCreateType;
|
||||
@@ -272,6 +273,8 @@ class Message {
|
||||
|
||||
groupV2?: GroupV2InfoType;
|
||||
|
||||
isViewOnce?: boolean;
|
||||
|
||||
preview?: ReadonlyArray<OutgoingLinkPreviewType>;
|
||||
|
||||
profileKey?: Uint8Array;
|
||||
@@ -314,6 +317,7 @@ class Message {
|
||||
this.expireTimerVersion = options.expireTimerVersion;
|
||||
this.flags = options.flags;
|
||||
this.groupV2 = options.groupV2;
|
||||
this.isViewOnce = options.isViewOnce;
|
||||
this.preview = options.preview;
|
||||
this.profileKey = options.profileKey;
|
||||
this.quote = options.quote;
|
||||
@@ -584,6 +588,9 @@ class Message {
|
||||
if (this.profileKey) {
|
||||
proto.profileKey = this.profileKey;
|
||||
}
|
||||
if (this.isViewOnce) {
|
||||
proto.isViewOnce = true;
|
||||
}
|
||||
if (this.deletedForEveryoneTimestamp) {
|
||||
proto.delete = {
|
||||
targetSentTimestamp: Long.fromNumber(this.deletedForEveryoneTimestamp),
|
||||
@@ -1125,6 +1132,7 @@ export class MessageSender {
|
||||
flags,
|
||||
groupCallUpdate,
|
||||
groupV2,
|
||||
isViewOnce,
|
||||
body,
|
||||
preview,
|
||||
profileKey,
|
||||
@@ -1173,6 +1181,7 @@ export class MessageSender {
|
||||
flags,
|
||||
groupCallUpdate,
|
||||
groupV2,
|
||||
isViewOnce,
|
||||
preview,
|
||||
profileKey,
|
||||
quote,
|
||||
|
||||
@@ -46,6 +46,7 @@ export async function eraseMessageContents(
|
||||
| 'view-once-viewed'
|
||||
| 'view-once-invalid'
|
||||
| 'view-once-expired'
|
||||
| 'view-once-sent'
|
||||
| 'unsupported-message'
|
||||
| 'delete-for-everyone',
|
||||
additionalProperties = {}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// Copyright 2017 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import { fabric } from 'fabric';
|
||||
import lodash from 'lodash';
|
||||
import { contextBridge } from 'electron';
|
||||
|
||||
@@ -31,11 +32,7 @@ import { Environment, getEnvironment } from '../../environment.std.js';
|
||||
import { isProduction } from '../../util/version.std.js';
|
||||
import { benchmarkConversationOpen } from '../../CI/benchmarkConversationOpen.preload.js';
|
||||
import { itemStorage } from '../../textsecure/Storage.preload.js';
|
||||
import { enqueuePollCreateForSend } from '../../util/enqueuePollCreateForSend.dom.js';
|
||||
import {
|
||||
isPollSendEnabled,
|
||||
type PollCreateType,
|
||||
} from '../../types/Polls.dom.js';
|
||||
import { IMAGE_PNG } from '../../types/MIME.std.js';
|
||||
|
||||
const { has } = lodash;
|
||||
|
||||
@@ -120,17 +117,39 @@ if (
|
||||
|
||||
calling._iceServerOverride = override;
|
||||
},
|
||||
sendPollInSelectedConversation: async (poll: PollCreateType) => {
|
||||
if (!isPollSendEnabled()) {
|
||||
throw new Error('Poll sending is not enabled');
|
||||
}
|
||||
sendViewOnceImageInSelectedConversation: async () => {
|
||||
const conversationId =
|
||||
window.reduxStore.getState().conversations.selectedConversationId;
|
||||
const conversation = window.ConversationController.get(conversationId);
|
||||
if (!conversation) {
|
||||
throw new Error('No conversation selected');
|
||||
}
|
||||
await enqueuePollCreateForSend(conversation, poll);
|
||||
|
||||
const canvas = new fabric.StaticCanvas(null, {
|
||||
width: 100,
|
||||
height: 100,
|
||||
backgroundColor: '#3b82f6',
|
||||
});
|
||||
const dataURL = canvas.toDataURL({ format: 'png' });
|
||||
const base64Data = dataURL.split(',')[1];
|
||||
const data = Uint8Array.from(atob(base64Data), c => c.charCodeAt(0));
|
||||
|
||||
await conversation.enqueueMessageForSend(
|
||||
{
|
||||
body: undefined,
|
||||
attachments: [
|
||||
{
|
||||
contentType: IMAGE_PNG,
|
||||
size: data.byteLength,
|
||||
data,
|
||||
},
|
||||
],
|
||||
isViewOnce: true,
|
||||
},
|
||||
{}
|
||||
);
|
||||
|
||||
log.info('Sent view-once test image');
|
||||
},
|
||||
...(window.SignalContext.config.ciMode === 'benchmark'
|
||||
? {
|
||||
|
||||
Reference in New Issue
Block a user