mirror of
https://github.com/signalapp/Signal-Desktop.git
synced 2026-04-02 00:07:56 +01:00
Add expire timers to pin/unpin data messages
This commit is contained in:
@@ -2495,6 +2495,8 @@ export async function startApp(): Promise<void> {
|
||||
pinnedByAci: data.sourceAci,
|
||||
sentAtTimestamp: data.timestamp,
|
||||
receivedAtTimestamp: data.receivedAtDate,
|
||||
expireTimer: data.message.expireTimer,
|
||||
expirationStartTimestamp: null,
|
||||
});
|
||||
confirm();
|
||||
return;
|
||||
@@ -3003,6 +3005,8 @@ export async function startApp(): Promise<void> {
|
||||
pinnedByAci: sourceServiceId,
|
||||
sentAtTimestamp: data.timestamp,
|
||||
receivedAtTimestamp: data.receivedAtDate,
|
||||
expireTimer: data.message.expireTimer,
|
||||
expirationStartTimestamp: data.expirationStartTimestamp ?? null,
|
||||
});
|
||||
confirm();
|
||||
return;
|
||||
|
||||
@@ -209,6 +209,7 @@ const pinMessageJobDataSchema = z.object({
|
||||
targetAuthorAci: aciSchema,
|
||||
targetSentTimestamp: z.number(),
|
||||
pinDurationSeconds: z.number().nullable(),
|
||||
pinnedAt: z.number(),
|
||||
});
|
||||
export type PinMessageJobData = z.infer<typeof pinMessageJobDataSchema>;
|
||||
|
||||
@@ -290,6 +291,7 @@ const unpinMessageJobDataSchema = z.object({
|
||||
targetMessageId: z.string(),
|
||||
targetAuthorAci: aciSchema,
|
||||
targetSentTimestamp: z.number(),
|
||||
unpinnedAt: z.number(),
|
||||
});
|
||||
export type UnpinMessageJobData = z.infer<typeof unpinMessageJobDataSchema>;
|
||||
|
||||
|
||||
@@ -27,9 +27,9 @@ export type SendMessageJobOptions<Data> = Readonly<{
|
||||
sendType: SendTypesType;
|
||||
getMessageId: (data: Data) => string | null;
|
||||
getMessageOptions: (
|
||||
data: Data,
|
||||
jobTimestamp: number
|
||||
data: Data
|
||||
) => Omit<SharedMessageOptionsType, 'recipients'>;
|
||||
getExpirationStartTimestamp: (data: Data) => number | null;
|
||||
}>;
|
||||
|
||||
export function createSendMessageJob<Data>(
|
||||
@@ -40,7 +40,13 @@ export function createSendMessageJob<Data>(
|
||||
job: ConversationQueueJobBundle,
|
||||
data: Data
|
||||
): Promise<void> {
|
||||
const { sendName, sendType, getMessageId, getMessageOptions } = options;
|
||||
const {
|
||||
sendName,
|
||||
sendType,
|
||||
getMessageId,
|
||||
getMessageOptions,
|
||||
getExpirationStartTimestamp,
|
||||
} = options;
|
||||
|
||||
const logId = `${sendName}(${conversation.idForLogging()}/${job.timestamp})`;
|
||||
const log = job.log.child(logId);
|
||||
@@ -71,7 +77,12 @@ export function createSendMessageJob<Data>(
|
||||
}
|
||||
|
||||
const messageId = getMessageId(data);
|
||||
const messageOptions = getMessageOptions(data, job.timestamp);
|
||||
const messageOptions = {
|
||||
...getMessageOptions(data),
|
||||
expireTimer: conversation.get('expireTimer'),
|
||||
expireTimerVersion: conversation.getExpireTimerVersion(),
|
||||
};
|
||||
const expirationStartTimestamp = getExpirationStartTimestamp(data);
|
||||
|
||||
try {
|
||||
if (recipientServiceIdsWithoutMe.length === 0) {
|
||||
@@ -96,7 +107,7 @@ export function createSendMessageJob<Data>(
|
||||
timestamp: job.timestamp,
|
||||
destinationE164: conversation.get('e164'),
|
||||
destinationServiceId: conversation.getServiceId(),
|
||||
expirationStartTimestamp: null,
|
||||
expirationStartTimestamp,
|
||||
isUpdate: false,
|
||||
options: sendOptions,
|
||||
urgent: false,
|
||||
@@ -128,7 +139,7 @@ export function createSendMessageJob<Data>(
|
||||
send: sender => {
|
||||
return sender.sendMessageToServiceId({
|
||||
serviceId: recipientServiceId,
|
||||
messageOptions: getMessageOptions(data, job.timestamp),
|
||||
messageOptions,
|
||||
groupId: undefined,
|
||||
contentHint: ContentHint.Resendable,
|
||||
options: sendOptions,
|
||||
@@ -138,6 +149,7 @@ export function createSendMessageJob<Data>(
|
||||
},
|
||||
sendType,
|
||||
timestamp: job.timestamp,
|
||||
expirationStartTimestamp,
|
||||
});
|
||||
}
|
||||
);
|
||||
@@ -162,8 +174,8 @@ export function createSendMessageJob<Data>(
|
||||
abortSignal,
|
||||
contentHint: ContentHint.Resendable,
|
||||
groupSendOptions: {
|
||||
...messageOptions,
|
||||
groupV2: groupV2Info,
|
||||
...getMessageOptions(data, job.timestamp),
|
||||
},
|
||||
messageId: messageId ?? undefined,
|
||||
sendOptions,
|
||||
@@ -174,6 +186,7 @@ export function createSendMessageJob<Data>(
|
||||
},
|
||||
sendType,
|
||||
timestamp: job.timestamp,
|
||||
expirationStartTimestamp,
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
@@ -213,6 +213,7 @@ export async function sendDeleteForEveryone(
|
||||
}),
|
||||
sendType,
|
||||
timestamp,
|
||||
expirationStartTimestamp: null,
|
||||
});
|
||||
|
||||
await updateMessageWithSuccessfulSends(message);
|
||||
@@ -252,6 +253,7 @@ export async function sendDeleteForEveryone(
|
||||
}),
|
||||
sendType,
|
||||
timestamp,
|
||||
expirationStartTimestamp: null,
|
||||
});
|
||||
|
||||
await updateMessageWithSuccessfulSends(message);
|
||||
|
||||
@@ -153,6 +153,7 @@ export async function sendDirectExpirationTimerUpdate(
|
||||
}),
|
||||
sendType,
|
||||
timestamp,
|
||||
expirationStartTimestamp: null,
|
||||
});
|
||||
}
|
||||
} catch (error: unknown) {
|
||||
|
||||
@@ -97,6 +97,7 @@ export async function sendGroupCallUpdate(
|
||||
),
|
||||
sendType,
|
||||
timestamp,
|
||||
expirationStartTimestamp: null,
|
||||
});
|
||||
} catch (error: unknown) {
|
||||
await handleMultipleSendErrors({
|
||||
|
||||
@@ -117,6 +117,7 @@ export async function sendGroupUpdate(
|
||||
}),
|
||||
sendType,
|
||||
timestamp,
|
||||
expirationStartTimestamp: null,
|
||||
})
|
||||
);
|
||||
} catch (error: unknown) {
|
||||
|
||||
@@ -9,9 +9,9 @@ export const sendPinMessage = createSendMessageJob<PinMessageJobData>({
|
||||
getMessageId(data) {
|
||||
return data.targetMessageId;
|
||||
},
|
||||
getMessageOptions(data, jobTimestamp) {
|
||||
getMessageOptions(data) {
|
||||
return {
|
||||
timestamp: jobTimestamp,
|
||||
timestamp: data.pinnedAt,
|
||||
pinMessage: {
|
||||
targetAuthorAci: data.targetAuthorAci,
|
||||
targetSentTimestamp: data.targetSentTimestamp,
|
||||
@@ -19,4 +19,7 @@ export const sendPinMessage = createSendMessageJob<PinMessageJobData>({
|
||||
},
|
||||
};
|
||||
},
|
||||
getExpirationStartTimestamp(data) {
|
||||
return data.pinnedAt;
|
||||
},
|
||||
});
|
||||
|
||||
@@ -133,6 +133,7 @@ export async function sendPollTerminate(
|
||||
}),
|
||||
sendType: 'pollTerminate',
|
||||
timestamp,
|
||||
expirationStartTimestamp: null,
|
||||
});
|
||||
|
||||
await markTerminateSuccess(pollMessage, jobLog);
|
||||
|
||||
@@ -10,13 +10,16 @@ export const sendUnpinMessage = createSendMessageJob<UnpinMessageJobData>({
|
||||
getMessageId(data) {
|
||||
return data.targetMessageId;
|
||||
},
|
||||
getMessageOptions(data, jobTimestamp) {
|
||||
getMessageOptions(data) {
|
||||
return {
|
||||
timestamp: jobTimestamp,
|
||||
timestamp: data.unpinnedAt,
|
||||
unpinMessage: {
|
||||
targetAuthorAci: data.targetAuthorAci,
|
||||
targetSentTimestamp: data.targetSentTimestamp,
|
||||
},
|
||||
};
|
||||
},
|
||||
getExpirationStartTimestamp(data) {
|
||||
return data.unpinnedAt;
|
||||
},
|
||||
});
|
||||
|
||||
@@ -30,6 +30,8 @@ export type PinnedMessageAddProps = Readonly<{
|
||||
pinnedByAci: AciString;
|
||||
sentAtTimestamp: number;
|
||||
receivedAtTimestamp: number;
|
||||
expireTimer: DurationInSeconds | null;
|
||||
expirationStartTimestamp: number | null;
|
||||
}>;
|
||||
|
||||
export type PinnedMessageRemoveProps = Readonly<{
|
||||
@@ -125,6 +127,8 @@ export async function onPinnedMessageAdd(
|
||||
senderAci: props.pinnedByAci,
|
||||
sentAtTimestamp: props.sentAtTimestamp,
|
||||
receivedAtTimestamp: props.receivedAtTimestamp,
|
||||
expireTimer: props.expireTimer,
|
||||
expirationStartTimestamp: props.expirationStartTimestamp,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -3567,6 +3567,8 @@ export class ConversationModel {
|
||||
senderAci: AciString;
|
||||
sentAtTimestamp: number;
|
||||
receivedAtTimestamp: number;
|
||||
expireTimer: DurationInSeconds | null;
|
||||
expirationStartTimestamp: number | null;
|
||||
}): Promise<void> {
|
||||
const ourAci = itemStorage.user.getCheckedAci();
|
||||
const senderIsMe = params.senderAci === ourAci;
|
||||
@@ -3581,8 +3583,8 @@ export class ConversationModel {
|
||||
readStatus: senderIsMe ? ReadStatus.Read : ReadStatus.Unread,
|
||||
seenStatus: senderIsMe ? SeenStatus.Seen : SeenStatus.Unseen,
|
||||
sourceServiceId: params.senderAci,
|
||||
expireTimer: this.get('expireTimer'),
|
||||
expirationStartTimestamp: senderIsMe ? params.sentAtTimestamp : null,
|
||||
expireTimer: params.expireTimer ?? undefined,
|
||||
expirationStartTimestamp: params.expirationStartTimestamp,
|
||||
pinMessage: params.pinMessage,
|
||||
});
|
||||
|
||||
|
||||
@@ -5199,15 +5199,17 @@ function onPinnedMessageAdd(
|
||||
);
|
||||
strictAssert(targetConversation != null, 'Missing target conversation');
|
||||
|
||||
const pinnedAt = Date.now();
|
||||
|
||||
await conversationJobQueue.add({
|
||||
type: conversationQueueJobEnum.enum.PinMessage,
|
||||
...target,
|
||||
pinDurationSeconds,
|
||||
pinnedAt,
|
||||
});
|
||||
|
||||
const pinnedMessagesLimit = getPinnedMessagesLimit();
|
||||
|
||||
const pinnedAt = Date.now();
|
||||
const expiresAt = getPinnedMessageExpiresAt(pinnedAt, pinDurationSeconds);
|
||||
|
||||
await DataWriter.appendPinnedMessage(pinnedMessagesLimit, {
|
||||
@@ -5226,6 +5228,8 @@ function onPinnedMessageAdd(
|
||||
senderAci: itemStorage.user.getCheckedAci(),
|
||||
sentAtTimestamp: pinnedAt,
|
||||
receivedAtTimestamp: pinnedAt,
|
||||
expireTimer: targetConversation.get('expireTimer') ?? null,
|
||||
expirationStartTimestamp: pinnedAt,
|
||||
});
|
||||
|
||||
dispatch(onPinnedMessagesChanged(target.conversationId));
|
||||
@@ -5238,6 +5242,7 @@ function onPinnedMessageRemove(targetMessageId: string): StateThunk {
|
||||
await conversationJobQueue.add({
|
||||
type: conversationQueueJobEnum.enum.UnpinMessage,
|
||||
...target,
|
||||
unpinnedAt: Date.now(),
|
||||
});
|
||||
await DataWriter.deletePinnedMessageByMessageId(targetMessageId);
|
||||
drop(pinnedMessagesCleanupService.trigger('onPinnedMessageRemove'));
|
||||
|
||||
@@ -25,6 +25,7 @@ export async function wrapWithSyncMessageSend({
|
||||
send,
|
||||
sendType,
|
||||
timestamp,
|
||||
expirationStartTimestamp,
|
||||
}: {
|
||||
conversation: ConversationModel;
|
||||
logId: string;
|
||||
@@ -32,6 +33,7 @@ export async function wrapWithSyncMessageSend({
|
||||
send: (sender: MessageSender) => Promise<CallbackResultType>;
|
||||
sendType: SendTypesType;
|
||||
timestamp: number;
|
||||
expirationStartTimestamp: number | null;
|
||||
}): Promise<void> {
|
||||
const logId = `wrapWithSyncMessageSend(${parentLogId}, ${timestamp})`;
|
||||
|
||||
@@ -84,7 +86,7 @@ export async function wrapWithSyncMessageSend({
|
||||
destinationE164: conversation.get('e164'),
|
||||
destinationServiceId: conversation.getServiceId(),
|
||||
encodedDataMessage: dataMessage,
|
||||
expirationStartTimestamp: null,
|
||||
expirationStartTimestamp,
|
||||
options,
|
||||
timestamp,
|
||||
urgent: false,
|
||||
|
||||
Reference in New Issue
Block a user