feat: group invitiations now disappear

pull/2660/head
William Grant 2 years ago
parent 2d6d6b4134
commit f36bbb9c7c

@ -64,8 +64,9 @@ function useIsExpired(props: PropsForExpiringMessage) {
return { isExpired };
}
const StyledReadableMessage = styled(ReadableMessage)`
const StyledReadableMessage = styled(ReadableMessage)<{ isIncoming: boolean }>`
display: flex;
justify-content: ${props => (props.isIncoming ? 'flex-start' : 'flex-end')};
align-items: center;
width: 100%;
`;
@ -106,6 +107,7 @@ export const ExpirableReadableMessage = (props: ExpirableReadableMessageProps) =
messageId={messageId}
receivedAt={receivedAt}
isUnread={!!isUnread}
isIncoming={isIncoming}
key={`readable-message-${messageId}`}
>
{expirationLength && expirationTimestamp && (

@ -3,8 +3,8 @@ import classNames from 'classnames';
import { PropsForGroupInvitation } from '../../../../state/ducks/conversations';
import { acceptOpenGroupInvitation } from '../../../../interactions/messageInteractions';
import { SessionIconButton } from '../../../icon';
import { ReadableMessage } from './ReadableMessage';
import styled from 'styled-components';
import { ExpirableReadableMessage } from './ExpirableReadableMessage';
const StyledIconContainer = styled.div`
background-color: var(--message-link-preview-background-color);
@ -21,10 +21,15 @@ export const GroupInvitation = (props: PropsForGroupInvitation) => {
const openGroupInvitation = window.i18n('openGroupInvitation');
return (
<ReadableMessage
<ExpirableReadableMessage
convoId={props.convoId}
messageId={messageId}
direction={props.direction}
receivedAt={receivedAt}
isUnread={isUnread}
isUnread={Boolean(isUnread)}
expirationLength={props.expirationLength}
expirationTimestamp={props.expirationTimestamp}
isExpired={props.isExpired}
key={`readable-message-${messageId}`}
>
<div className="group-invitation-container" id={`msg-${props.messageId}`}>
@ -52,6 +57,6 @@ export const GroupInvitation = (props: PropsForGroupInvitation) => {
</div>
</div>
</div>
</ReadableMessage>
</ExpirableReadableMessage>
);
};

@ -636,7 +636,8 @@ export class ConversationModel extends Backbone.Model<ConversationAttributes> {
timestamp: sentAt,
name: groupInvitation.name,
url: groupInvitation.url,
expireTimer: this.get('expireTimer'),
expirationType,
expireTimer,
});
// we need the return await so that errors are caught in the catch {}
await getMessageQueue().sendToPubKey(destinationPubkey, groupInviteMessage);

@ -35,6 +35,7 @@ import {
messagesChanged,
PropsForAttachment,
PropsForExpirationTimer,
PropsForExpiringMessage,
PropsForGroupInvitation,
PropsForGroupUpdate,
PropsForGroupUpdateAdd,
@ -91,7 +92,7 @@ import {
getUsBlindedInThatServer,
isUsAnySogsFromCache,
} from '../session/apis/open_group_api/sogsv3/knownBlindedkeys';
import { QUOTED_TEXT_MAX_LENGTH } from '../session/constants';
import { DURATION, QUOTED_TEXT_MAX_LENGTH } from '../session/constants';
import { ReactionList } from '../types/Reaction';
import { getAttachmentMetadata } from '../types/message/initializeAttachmentMetadata';
import { expireMessageOnSnode } from '../session/apis/snode_api/expire';
@ -306,6 +307,24 @@ export class MessageModel extends Backbone.Model<MessageAttributes> {
return basicProps;
}
public getPropsForExpiringMessage(): PropsForExpiringMessage | null {
const expirationType = this.get('expirationType');
const expireTimerStart = this.get('expirationStartTimestamp') || null;
const expirationLength = this.get('expireTimer') || null;
const expirationTimestamp =
expirationType && expireTimerStart && expirationLength
? expireTimerStart + expirationLength * DURATION.SECONDS
: null;
return {
convoId: this.get('conversationId'),
messageId: this.get('id'),
expirationLength,
expirationTimestamp,
isExpired: this.isExpired(),
};
}
public getPropsForGroupInvitation(): PropsForGroupInvitation | null {
if (!this.isGroupInvitation()) {
return null;
@ -333,6 +352,7 @@ export class MessageModel extends Backbone.Model<MessageAttributes> {
messageId: this.id as string,
receivedAt: this.get('received_at'),
isUnread: this.isUnread(),
...this.getPropsForExpiringMessage(),
};
}

@ -554,7 +554,7 @@ export async function retrieveNextMessages(
handleTimestampOffset('retrieve', json.t);
await handleHardforkResult(json);
console.log(`WIP: retrieveNextMessages`, json.messages);
// console.log(`WIP: retrieveNextMessages`, json.messages);
return json.messages || [];
} catch (e) {

@ -30,10 +30,10 @@ async function generateSignature({
`expire${timestamp}${messageHashes.join('')}`,
'utf8'
);
console.log(
`WIP: generateSignature verificationData`,
`expire${timestamp}${messageHashes.join('')}`
);
// console.log(
// `WIP: generateSignature verificationData`,
// `expire${timestamp}${messageHashes.join('')}`
// );
const message = new Uint8Array(verificationData);
const sodium = await getSodiumRenderer();
@ -76,10 +76,10 @@ async function verifySignature({
`${pubkey.key}${expiryApplied}${messageHashes.join('')}${resultHashes.join('')}`,
'utf8'
);
console.log(
`WIP: verifySignature verificationData`,
`${pubkey.key}${expiryApplied}${messageHashes.join('')}${resultHashes.join('')}`
);
// console.log(
// `WIP: verifySignature verificationData`,
// `${pubkey.key}${expiryApplied}${messageHashes.join('')}${resultHashes.join('')}`
// );
const sodium = await getSodiumRenderer();
try {
@ -108,10 +108,10 @@ async function processExpirationResults(
// TODO need proper typing for swarm and results
const results: Record<string, { hashes: Array<string>; expiry: number }> = {};
console.log(`WIP: processExpirationResults`, swarm, messageHashes);
// console.log(`WIP: processExpirationResults`, swarm, messageHashes);
for (const nodeKey of Object.keys(swarm)) {
console.log(`WIP: processExpirationResults we got this far`, nodeKey, swarm[nodeKey]);
// console.log(`WIP: processExpirationResults we got this far`, nodeKey, swarm[nodeKey]);
if (!isEmpty(swarm[nodeKey].failed)) {
const reason = 'Unknown';
const statusCode = '404';
@ -173,14 +173,9 @@ async function expireOnNodes(targetNode: Snode, params: ExpireParams) {
try {
const parsed = JSON.parse(result.body);
const expirationResults = await processExpirationResults(
params.pubkey,
targetNode,
parsed.swarm,
params.messages
);
await processExpirationResults(params.pubkey, targetNode, parsed.swarm, params.messages);
console.log(`WIP: expireOnNodes attempt complete. Here are the results`, expirationResults);
// console.log(`WIP: expireOnNodes attempt complete. Here are the results`, expirationResults);
return true;
} catch (e) {
@ -198,12 +193,12 @@ async function expireOnNodes(targetNode: Snode, params: ExpireParams) {
}
export async function expireMessageOnSnode(messageHash: string, expireTimer: number) {
console.log(`WIP: expireMessageOnSnode running!`);
// console.log(`WIP: expireMessageOnSnode running!`);
const ourPubKey = UserUtils.getOurPubKeyFromCache();
const ourEd25519Key = await UserUtils.getUserED25519KeyPair();
if (!ourPubKey || !ourEd25519Key) {
window.log.info(`WIP: expireMessageOnSnode failed!`, messageHash);
// window.log.info(`WIP: expireMessageOnSnode failed!`, messageHash);
return;
}
@ -217,7 +212,7 @@ export async function expireMessageOnSnode(messageHash: string, expireTimer: num
});
if (!signResult) {
window.log.info(`WIP: Signing message expiry on swarm failed!`, messageHash);
// window.log.info(`WIP: Signing message expiry on swarm failed!`, messageHash);
return;
}
@ -248,7 +243,7 @@ export async function expireMessageOnSnode(messageHash: string, expireTimer: num
try {
const firstSuccessSnode = await firstTrue(promises);
snode = firstSuccessSnode;
console.log(`WIP: expireMessageOnSnode firstSuccessSnode`, firstSuccessSnode);
// console.log(`WIP: expireMessageOnSnode firstSuccessSnode`, firstSuccessSnode);
} catch (e) {
const snodeStr = snode ? `${snode.ip}:${snode.port}` : 'null';
window?.log?.warn(

@ -1,25 +1,30 @@
import { DataMessage } from '..';
import { SignalService } from '../../../../protobuf';
import { DisappearingMessageType } from '../../../../util/expiringMessages';
import { MessageParams } from '../Message';
import { VisibleMessage } from './VisibleMessage';
interface GroupInvitationMessageParams extends MessageParams {
url: string;
name: string;
// if there is an expire timer set for the conversation, we need to set it.
// if disappearing messages is set for the conversation, we need to set it.
// otherwise, it will disable the expire timer on the receiving side.
expirationType?: DisappearingMessageType;
expireTimer?: number;
}
export class GroupInvitationMessage extends DataMessage {
export class GroupInvitationMessage extends VisibleMessage {
private readonly url: string;
private readonly name: string;
private readonly expireTimer?: number;
constructor(params: GroupInvitationMessageParams) {
super({ timestamp: params.timestamp, identifier: params.identifier });
super({
timestamp: params.timestamp,
identifier: params.identifier,
expirationType: params.expirationType,
expireTimer: params.expireTimer,
});
this.url = params.url;
this.name = params.name;
this.expireTimer = params.expireTimer;
}
public dataProto(): SignalService.DataMessage {

@ -100,14 +100,6 @@ async function handleMessageSentSuccess(
void PnServer.notifyPnServer(wrappedEnvelope, sentMessage.device);
}
}
if (!shouldMarkMessageAsSynced) {
const expirationType = fetchedMessage.get('expirationType');
if (expirationType) {
fetchedMessage =
setExpirationStartTimestamp(fetchedMessage, expirationType, effectiveTimestamp) ||
fetchedMessage;
}
}
// Handle the sync logic here
if (shouldTriggerSyncMessage) {
@ -142,6 +134,14 @@ async function handleMessageSentSuccess(
sent_at: effectiveTimestamp,
});
if (!shouldMarkMessageAsSynced) {
const expirationType = fetchedMessage.get('expirationType');
if (expirationType) {
fetchedMessage =
setExpirationStartTimestamp(fetchedMessage, expirationType) || fetchedMessage;
}
}
await fetchedMessage.commit();
fetchedMessage.getConversation()?.updateLastMessage();
}

@ -211,17 +211,18 @@ export function setExpirationStartTimestamp(
if (timestamp) {
expirationStartTimestamp = Math.min(getNowWithNetworkOffset(), timestamp);
message.set('expirationStartTimestamp', expirationStartTimestamp);
}
message.set('expirationStartTimestamp', expirationStartTimestamp);
if (mode === 'deleteAfterRead') {
window.log.info(
`WIP: setExpirationStartTimestamp we set the start timetamp for a delete after read message`,
`WIP: setExpirationStartTimestamp we set the start timestamp for a delete after read message`,
message
);
} else if (mode === 'deleteAfterSend') {
window.log.info(
`WIP: setExpirationStartTimestamp we set the start timetamp for a delete after send message`,
`WIP: setExpirationStartTimestamp we set the start timestamp for a delete after send message`,
message
);
} else {

Loading…
Cancel
Save