fix: changed some message control to not expire

still some to discuss with the team
pull/2940/head
Audric Ackermann 1 year ago
parent 5b704ebdc7
commit 744283fc56

@ -276,8 +276,7 @@ export const OverlayRightPanelSettings = () => {
? window.i18n('youLeftTheGroup') ? window.i18n('youLeftTheGroup')
: window.i18n('leaveGroup'); : window.i18n('leaveGroup');
const showUpdateGroupNameButton = const showUpdateGroupNameButton = isGroup && weAreAdmin && !commonNoShow; // legacy groups non-admin cannot change groupname anymore
isGroup && (!isPublic || (isPublic && weAreAdmin)) && !commonNoShow;
const showAddRemoveModeratorsButton = weAreAdmin && !commonNoShow && isPublic; const showAddRemoveModeratorsButton = weAreAdmin && !commonNoShow && isPublic;
const showUpdateGroupMembersButton = !isPublic && isGroup && !commonNoShow; const showUpdateGroupMembersButton = !isPublic && isGroup && !commonNoShow;

@ -2038,15 +2038,12 @@ export class ConversationModel extends Backbone.Model<ConversationAttributes> {
const lastMessageStatus = lastMessageModel.getMessagePropStatus() || undefined; const lastMessageStatus = lastMessageModel.getMessagePropStatus() || undefined;
const lastMessageNotificationText = lastMessageModel.getNotificationText() || undefined; const lastMessageNotificationText = lastMessageModel.getNotificationText() || undefined;
// we just want to set the `status` to `undefined` if there are no `lastMessageNotificationText` // we just want to set the `status` to `undefined` if there are no `lastMessageNotificationText`
const lastMessageUpdate = const lastMessageUpdate = !isEmpty(lastMessageNotificationText)
!!lastMessageNotificationText && !isEmpty(lastMessageNotificationText) ? {
? { lastMessage: lastMessageNotificationText || '',
lastMessage: lastMessageNotificationText || '', lastMessageStatus,
lastMessageStatus, }
} : { lastMessage: '', lastMessageStatus: undefined };
: { lastMessage: '', lastMessageStatus: undefined };
// TODO when the last message get removed from a conversation, the lastUpdate is ignored and we keep the last message.
if ( if (
lastMessageUpdate.lastMessage !== existingLastMessageAttribute || lastMessageUpdate.lastMessage !== existingLastMessageAttribute ||

@ -486,6 +486,12 @@ export class MessageModel extends Backbone.Model<MessageAttributes> {
return undefined; return undefined;
} }
// some incoming legacy group updates are outgoing, but when synced to our other devices have just the received_at field set.
// when that is the case, we don't want to render the spinning 'sending' state
if (this.get('received_at')) {
return undefined;
}
if (this.isDataExtractionNotification() || this.get('callNotificationType')) { if (this.isDataExtractionNotification() || this.get('callNotificationType')) {
return undefined; return undefined;
} }

@ -946,7 +946,7 @@ async function sendLatestKeyPairToUsers(
groupId: groupPubKey, groupId: groupPubKey,
timestamp: Date.now(), timestamp: Date.now(),
encryptedKeyPairs: wrappers, encryptedKeyPairs: wrappers,
expirationType: null, expirationType: null, // we keep that one **not** expiring (not rendered in the clients, and we need it to be as available as possible on the swarm)
expireTimer: null, expireTimer: null,
}); });

@ -360,7 +360,10 @@ export async function handleMessageJob(
window?.log?.info( window?.log?.info(
`Starting handleMessageJob for message ${messageModel.idForLogging()}, ${messageModel.get( `Starting handleMessageJob for message ${messageModel.idForLogging()}, ${messageModel.get(
'serverTimestamp' 'serverTimestamp'
) || messageModel.get('timestamp')} in conversation ${conversation.idForLogging()}` ) ||
messageModel.get(
'timestamp'
)} in conversation ${conversation.idForLogging()}, messageHash:${messageHash}`
); );
const sendingDeviceConversation = await getConversationController().getOrCreateAndWait( const sendingDeviceConversation = await getConversationController().getOrCreateAndWait(

@ -70,7 +70,6 @@ async function getExpiriesFromNodes(
throw Error(`getExpiriesFromNodes result is not 200 but ${firstResult.code}`); throw Error(`getExpiriesFromNodes result is not 200 but ${firstResult.code}`);
} }
debugger;
// expirationResults is a record of {messageHash: currentExpiry} // expirationResults is a record of {messageHash: currentExpiry}
const expirationResults = await processGetExpiriesRequestResponse( const expirationResults = await processGetExpiriesRequestResponse(
targetNode, targetNode,

@ -26,6 +26,7 @@ import { OpenGroupUtils } from '../apis/open_group_api/utils';
import { getSwarmPollingInstance } from '../apis/snode_api'; import { getSwarmPollingInstance } from '../apis/snode_api';
import { GetNetworkTime } from '../apis/snode_api/getNetworkTime'; import { GetNetworkTime } from '../apis/snode_api/getNetworkTime';
import { SnodeNamespaces } from '../apis/snode_api/namespaces'; import { SnodeNamespaces } from '../apis/snode_api/namespaces';
import { DisappearingMessages } from '../disappearing_messages';
import { ClosedGroupMemberLeftMessage } from '../messages/outgoing/controlMessage/group/ClosedGroupMemberLeftMessage'; import { ClosedGroupMemberLeftMessage } from '../messages/outgoing/controlMessage/group/ClosedGroupMemberLeftMessage';
import { UserUtils } from '../utils'; import { UserUtils } from '../utils';
import { ConfigurationSync } from '../utils/job_runners/jobs/ConfigurationSyncJob'; import { ConfigurationSync } from '../utils/job_runners/jobs/ConfigurationSyncJob';
@ -496,8 +497,12 @@ async function leaveClosedGroup(groupId: string, fromSyncMessage: boolean) {
const ourLeavingMessage = new ClosedGroupMemberLeftMessage({ const ourLeavingMessage = new ClosedGroupMemberLeftMessage({
timestamp: networkTimestamp, timestamp: networkTimestamp,
groupId, groupId,
expirationType: null, expirationType: DisappearingMessages.changeToDisappearingMessageType(
expireTimer: null, convo,
convo.getExpireTimer(),
convo.getExpirationMode()
),
expireTimer: convo.getExpireTimer(),
}); });
window?.log?.info(`We are leaving the group ${groupId}. Sending our leaving message.`); window?.log?.info(`We are leaving the group ${groupId}. Sending our leaving message.`);

@ -8,7 +8,6 @@ import { updateConfirmModal } from '../../state/ducks/modalDialog';
import { getSwarmPollingInstance } from '../apis/snode_api'; import { getSwarmPollingInstance } from '../apis/snode_api';
import { SnodeNamespaces } from '../apis/snode_api/namespaces'; import { SnodeNamespaces } from '../apis/snode_api/namespaces';
import { generateClosedGroupPublicKey, generateCurve25519KeyPairWithoutPrefix } from '../crypto'; import { generateClosedGroupPublicKey, generateCurve25519KeyPairWithoutPrefix } from '../crypto';
import { DisappearAfterSendOnly, DisappearingMessageType } from '../disappearing_messages/types';
import { import {
ClosedGroupNewMessage, ClosedGroupNewMessage,
ClosedGroupNewMessageParams, ClosedGroupNewMessageParams,
@ -68,15 +67,14 @@ export async function createClosedGroup(groupName: string, members: Array<string
await convo.commit(); await convo.commit();
convo.updateLastMessage(); convo.updateLastMessage();
// Send a closed group update message to all members individually // Send a closed group update message to all members individually.
// Note: we do not make those messages expire
const allInvitesSent = await sendToGroupMembers( const allInvitesSent = await sendToGroupMembers(
listOfMembers, listOfMembers,
groupPublicKey, groupPublicKey,
groupName, groupName,
admins, admins,
encryptionKeyPair, encryptionKeyPair
existingExpirationType,
existingExpireTimer
); );
if (allInvitesSent) { if (allInvitesSent) {
@ -103,8 +101,6 @@ async function sendToGroupMembers(
groupName: string, groupName: string,
admins: Array<string>, admins: Array<string>,
encryptionKeyPair: ECKeyPair, encryptionKeyPair: ECKeyPair,
existingExpirationType: DisappearAfterSendOnly,
existingExpireTimer: number,
isRetry: boolean = false isRetry: boolean = false
): Promise<any> { ): Promise<any> {
const promises = createInvitePromises( const promises = createInvitePromises(
@ -112,9 +108,7 @@ async function sendToGroupMembers(
groupPublicKey, groupPublicKey,
groupName, groupName,
admins, admins,
encryptionKeyPair, encryptionKeyPair
existingExpirationType,
existingExpireTimer
); );
window?.log?.info(`Sending invites for group ${groupPublicKey} to ${listOfMembers}`); window?.log?.info(`Sending invites for group ${groupPublicKey} to ${listOfMembers}`);
// evaluating if all invites sent, if failed give the option to retry failed invites via modal dialog // evaluating if all invites sent, if failed give the option to retry failed invites via modal dialog
@ -169,8 +163,6 @@ async function sendToGroupMembers(
groupName, groupName,
admins, admins,
encryptionKeyPair, encryptionKeyPair,
existingExpirationType,
existingExpireTimer,
isRetrySend isRetrySend
); );
} }
@ -186,9 +178,7 @@ function createInvitePromises(
groupPublicKey: string, groupPublicKey: string,
groupName: string, groupName: string,
admins: Array<string>, admins: Array<string>,
encryptionKeyPair: ECKeyPair, encryptionKeyPair: ECKeyPair
existingExpirationType: DisappearingMessageType,
existingExpireTimer: number
) { ) {
return listOfMembers.map(async m => { return listOfMembers.map(async m => {
const messageParams: ClosedGroupNewMessageParams = { const messageParams: ClosedGroupNewMessageParams = {
@ -198,8 +188,8 @@ function createInvitePromises(
admins, admins,
keypair: encryptionKeyPair, keypair: encryptionKeyPair,
timestamp: Date.now(), timestamp: Date.now(),
expirationType: existingExpirationType, expirationType: null, // Note: we do not make those messages expire as we want them available as much as possible on the swarm of the recipient
expireTimer: existingExpireTimer, expireTimer: 0,
}; };
const message = new ClosedGroupNewMessage(messageParams); const message = new ClosedGroupNewMessage(messageParams);
return getMessageQueue().sendToPubKeyNonDurably({ return getMessageQueue().sendToPubKeyNonDurably({

@ -290,8 +290,12 @@ async function sendNewName(convo: ConversationModel, name: string, messageId: st
groupId, groupId,
identifier: messageId, identifier: messageId,
name, name,
expirationType: null, expirationType: DisappearingMessages.changeToDisappearingMessageType(
expireTimer: null, convo,
convo.getExpireTimer(),
convo.getExpirationMode()
),
expireTimer: convo.getExpireTimer(),
}); });
await getMessageQueue().sendToGroup({ await getMessageQueue().sendToGroup({
message: nameChangeMessage, message: nameChangeMessage,
@ -328,8 +332,12 @@ async function sendAddedMembers(
groupId, groupId,
addedMembers, addedMembers,
identifier: messageId, identifier: messageId,
expirationType: null, expirationType: DisappearingMessages.changeToDisappearingMessageType(
expireTimer: null, convo,
convo.getExpireTimer(),
convo.getExpirationMode()
),
expireTimer: convo.getExpireTimer(),
}); });
await getMessageQueue().sendToGroup({ await getMessageQueue().sendToGroup({
message: closedGroupControlMessage, message: closedGroupControlMessage,
@ -393,8 +401,12 @@ export async function sendRemovedMembers(
groupId, groupId,
removedMembers, removedMembers,
identifier: messageId, identifier: messageId,
expirationType: null, expirationType: DisappearingMessages.changeToDisappearingMessageType(
expireTimer: null, convo,
convo.getExpireTimer(),
convo.getExpirationMode()
),
expireTimer: convo.getExpireTimer(),
}); });
// Send the group update, and only once sent, generate and distribute a new encryption key pair if needed // Send the group update, and only once sent, generate and distribute a new encryption key pair if needed
await getMessageQueue().sendToGroup({ await getMessageQueue().sendToGroup({
@ -455,7 +467,7 @@ async function generateAndSendNewEncryptionKeyPair(
groupId: toHex(groupId), groupId: toHex(groupId),
timestamp: GetNetworkTime.getNowWithNetworkOffset(), timestamp: GetNetworkTime.getNowWithNetworkOffset(),
encryptedKeyPairs: wrappers, encryptedKeyPairs: wrappers,
expirationType: null, expirationType: null, // we keep that one **not** expiring (not rendered in the clients, and we need it to be as available as possible on the swarm)
expireTimer: null, expireTimer: null,
}); });

@ -1,23 +1,21 @@
import { v4 as uuid } from 'uuid';
import { ContentMessage } from '..';
import { getMessageQueue } from '../../..'; import { getMessageQueue } from '../../..';
import { SignalService } from '../../../../protobuf'; import { SignalService } from '../../../../protobuf';
import { SnodeNamespaces } from '../../../apis/snode_api/namespaces'; import { SnodeNamespaces } from '../../../apis/snode_api/namespaces';
import { getConversationController } from '../../../conversations'; import { getConversationController } from '../../../conversations';
import { DisappearingMessages } from '../../../disappearing_messages';
import { PubKey } from '../../../types'; import { PubKey } from '../../../types';
import { UserUtils } from '../../../utils'; import { UserUtils } from '../../../utils';
import { MessageParams } from '../Message'; import { ExpirableMessage, ExpirableMessageParams } from '../ExpirableMessage';
interface DataExtractionNotificationMessageParams extends MessageParams { interface DataExtractionNotificationMessageParams extends ExpirableMessageParams {
referencedAttachmentTimestamp: number; referencedAttachmentTimestamp: number;
} }
export class DataExtractionNotificationMessage extends ContentMessage { export class DataExtractionNotificationMessage extends ExpirableMessage {
public readonly referencedAttachmentTimestamp: number; public readonly referencedAttachmentTimestamp: number;
constructor(params: DataExtractionNotificationMessageParams) { constructor(params: DataExtractionNotificationMessageParams) {
super({ timestamp: params.timestamp, identifier: params.identifier }); super(params);
this.referencedAttachmentTimestamp = params.referencedAttachmentTimestamp; this.referencedAttachmentTimestamp = params.referencedAttachmentTimestamp;
// this does not make any sense // this does not make any sense
if (!this.referencedAttachmentTimestamp) { if (!this.referencedAttachmentTimestamp) {
@ -57,11 +55,20 @@ export const sendDataExtractionNotification = async (
return; return;
} }
const expireTimer = convo.getExpireTimer();
const expirationType = DisappearingMessages.changeToDisappearingMessageType(
convo,
expireTimer,
convo.getExpirationMode()
);
const dataExtractionNotificationMessage = new DataExtractionNotificationMessage({ const dataExtractionNotificationMessage = new DataExtractionNotificationMessage({
referencedAttachmentTimestamp, referencedAttachmentTimestamp,
identifier: uuid(),
timestamp: Date.now(), timestamp: Date.now(),
expirationType,
expireTimer,
}); });
const pubkey = PubKey.cast(conversationId); const pubkey = PubKey.cast(conversationId);
window.log.info( window.log.info(
`Sending DataExtractionNotification to ${conversationId} about attachment: ${referencedAttachmentTimestamp}` `Sending DataExtractionNotification to ${conversationId} about attachment: ${referencedAttachmentTimestamp}`

@ -4,6 +4,7 @@ import { ContentMessage } from '../ContentMessage';
import { MessageParams } from '../Message'; import { MessageParams } from '../Message';
import { buildProfileForOutgoingMessage } from '../visibleMessage/VisibleMessage'; import { buildProfileForOutgoingMessage } from '../visibleMessage/VisibleMessage';
// Note: a MessageRequestResponse message should not expire at all on the recipient side/nor our side.
export interface MessageRequestResponseParams extends MessageParams { export interface MessageRequestResponseParams extends MessageParams {
lokiProfile?: LokiProfile; lokiProfile?: LokiProfile;
} }

@ -1,7 +1,7 @@
import { ContentMessage } from '..';
import { Constants } from '../../..';
import { SignalService } from '../../../../protobuf'; import { SignalService } from '../../../../protobuf';
import { MessageParams } from '../Message'; import { MessageParams } from '../Message';
import { Constants } from '../../..';
import { ContentMessage } from '..';
interface TypingMessageParams extends MessageParams { interface TypingMessageParams extends MessageParams {
isTyping: boolean; isTyping: boolean;

Loading…
Cancel
Save