chore: cleanup data extraction notification

pull/3281/head
Audric Ackermann 4 months ago
parent 3c0f9fe14e
commit 7570bc6ba7
No known key found for this signature in database

@ -2,7 +2,6 @@ import { useLayoutEffect, useState } from 'react';
import { useSelector } from 'react-redux'; import { useSelector } from 'react-redux';
import useKey from 'react-use/lib/useKey'; import useKey from 'react-use/lib/useKey';
import { PropsForDataExtractionNotification } from '../../models/messageType';
import { PropsForExpirationTimer, PropsForGroupUpdate } from '../../state/ducks/conversations'; import { PropsForExpirationTimer, PropsForGroupUpdate } from '../../state/ducks/conversations';
import { import {
getOldBottomMessageId, getOldBottomMessageId,
@ -132,10 +131,8 @@ export const SessionMessagesList = (props: {
} }
if (messageProps.message?.messageType === 'data-extraction') { if (messageProps.message?.messageType === 'data-extraction') {
const msgProps = messageProps.message.props as PropsForDataExtractionNotification;
return [ return [
<DataExtractionNotification key={messageId} {...msgProps} />, <DataExtractionNotification key={messageId} messageId={messageId} />,
...componentToMerge, ...componentToMerge,
]; ];
} }

@ -1,12 +1,21 @@
import { PropsForDataExtractionNotification } from '../../../../models/messageType';
import { SignalService } from '../../../../protobuf';
import { ExpirableReadableMessage } from './ExpirableReadableMessage'; import { ExpirableReadableMessage } from './ExpirableReadableMessage';
import { NotificationBubble } from './notification-bubble/NotificationBubble'; import { NotificationBubble } from './notification-bubble/NotificationBubble';
import { Localizer } from '../../../basic/Localizer'; import { Localizer } from '../../../basic/Localizer';
import { useMessageAuthor } from '../../../../state/selectors';
import { useNicknameOrProfileNameOrShortenedPubkey } from '../../../../hooks/useParamSelector';
import type { WithMessageId } from '../../../../session/types/with';
export const DataExtractionNotification = (props: PropsForDataExtractionNotification) => { export const DataExtractionNotification = (props: WithMessageId) => {
const { name, type, source, messageId } = props; const { messageId } = props;
const author = useMessageAuthor(messageId);
const authorName = useNicknameOrProfileNameOrShortenedPubkey(author);
if (!author) {
return null;
}
// Note: we only support one type of data extraction notification now (media saved).
// the screenshot support is entirely removed.
return ( return (
<ExpirableReadableMessage <ExpirableReadableMessage
messageId={messageId} messageId={messageId}
@ -15,14 +24,7 @@ export const DataExtractionNotification = (props: PropsForDataExtractionNotifica
isControlMessage={true} isControlMessage={true}
> >
<NotificationBubble iconType="save"> <NotificationBubble iconType="save">
<Localizer <Localizer token={'attachmentsMediaSaved'} args={{ name: authorName }} />
token={
type === SignalService.DataExtractionNotification.Type.MEDIA_SAVED
? 'attachmentsMediaSaved'
: 'screenshotTaken'
}
args={{ name: name || source }}
/>
</NotificationBubble> </NotificationBubble>
</ExpirableReadableMessage> </ExpirableReadableMessage>
); );

@ -19,12 +19,10 @@ import {
uploadQuoteThumbnailsToFileServer, uploadQuoteThumbnailsToFileServer,
} from '../session/utils'; } from '../session/utils';
import { import {
DataExtractionNotificationMsg,
MessageAttributes, MessageAttributes,
MessageAttributesOptionals, MessageAttributesOptionals,
MessageGroupUpdate, MessageGroupUpdate,
MessageModelType, MessageModelType,
PropsForDataExtractionNotification,
fillMessageAttributesWithDefaults, fillMessageAttributesWithDefaults,
} from './messageType'; } from './messageType';
@ -222,7 +220,7 @@ export class MessageModel extends Backbone.Model<MessageAttributes> {
this.set(attributes); this.set(attributes);
} }
public isCommunityInvitation() { private isCommunityInvitation() {
return !!this.getCommunityInvitation(); return !!this.getCommunityInvitation();
} }
public getCommunityInvitation() { public getCommunityInvitation() {
@ -233,21 +231,16 @@ export class MessageModel extends Backbone.Model<MessageAttributes> {
return !!this.get('messageRequestResponse'); return !!this.get('messageRequestResponse');
} }
public isDataExtractionNotification() { private isDataExtractionNotification() {
return !!this.getDataExtractionNotification(); // if set to {} this returns true
} return !!this.get('dataExtractionNotification');
public getDataExtractionNotification() {
return this.get('dataExtractionNotification');
} }
public isCallNotification() { private isCallNotification() {
return !!this.getCallNotification(); return !!this.get('callNotificationType');
}
public getCallNotification() {
return this.get('callNotificationType');
} }
public isInteractionNotification() { private isInteractionNotification() {
return !!this.getInteractionNotification(); return !!this.getInteractionNotification();
} }
public getInteractionNotification() { public getInteractionNotification() {
@ -306,17 +299,8 @@ export class MessageModel extends Backbone.Model<MessageAttributes> {
} }
if (this.isDataExtractionNotification()) { if (this.isDataExtractionNotification()) {
const dataExtraction = this.get(
'dataExtractionNotification'
) as DataExtractionNotificationMsg;
if (dataExtraction.type === SignalService.DataExtractionNotification.Type.SCREENSHOT) {
return window.i18n.stripped('screenshotTaken', {
name: ConvoHub.use().getNicknameOrRealUsernameOrPlaceholder(dataExtraction.source),
});
}
return window.i18n.stripped('attachmentsMediaSaved', { return window.i18n.stripped('attachmentsMediaSaved', {
name: ConvoHub.use().getNicknameOrRealUsernameOrPlaceholder(dataExtraction.source), name: ConvoHub.use().getNicknameOrRealUsernameOrPlaceholder(this.get('source')),
}); });
} }
if (this.isCallNotification()) { if (this.isCallNotification()) {
@ -519,26 +503,8 @@ export class MessageModel extends Backbone.Model<MessageAttributes> {
}; };
} }
private getPropsForDataExtractionNotification(): PropsForDataExtractionNotification | null { private getPropsForDataExtractionNotification(): boolean {
if (!this.isDataExtractionNotification()) { return !!this.isDataExtractionNotification();
return null;
}
const dataExtractionNotification = this.getDataExtractionNotification();
if (!dataExtractionNotification) {
window.log.warn('dataExtractionNotification should not happen');
return null;
}
const contact = findAndFormatContact(dataExtractionNotification.source);
return {
...dataExtractionNotification,
name: contact.profileName || contact.name || dataExtractionNotification.source,
receivedAt: this.get('received_at'),
isUnread: this.isUnread(),
...this.getPropsForExpiringMessage(),
};
} }
private getPropsForGroupUpdateMessage(): PropsForGroupUpdate | null { private getPropsForGroupUpdateMessage(): PropsForGroupUpdate | null {

@ -127,12 +127,6 @@ export interface MessageAttributes {
interactionNotification?: InteractionNotificationType; interactionNotification?: InteractionNotificationType;
} }
export interface DataExtractionNotificationMsg {
type: number; // screenshot or saving event, based on SignalService.DataExtractionNotification.Type
source: string; // the guy who made a screenshot
referencedAttachmentTimestamp: number; // the attachment timestamp he screenshot
}
export interface MessageRequestResponseMsg { export interface MessageRequestResponseMsg {
source: string; source: string;
isApproved: boolean; isApproved: boolean;
@ -144,11 +138,13 @@ export enum MessageDirection {
any = '%', any = '%',
} }
export type PropsForDataExtractionNotification = DataExtractionNotificationMsg & { type DataExtractionNotificationMsg = {
name: string; // Note: we only support one type (media saved, screenshot is not supported at all anymore)
messageId: string; // Note: just keeping this an object in case we need to add details to it.
}; };
export type PropsForDataExtractionNotification = DataExtractionNotificationMsg;
export type PropsForMessageRequestResponse = MessageRequestResponseMsg & { export type PropsForMessageRequestResponse = MessageRequestResponseMsg & {
conversationId?: string; conversationId?: string;
name?: string; name?: string;
@ -196,11 +192,7 @@ export interface MessageAttributesOptionals {
hasAttachments?: boolean; hasAttachments?: boolean;
hasFileAttachments?: boolean; hasFileAttachments?: boolean;
hasVisualMediaAttachments?: boolean; hasVisualMediaAttachments?: boolean;
dataExtractionNotification?: { dataExtractionNotification?: DataExtractionNotificationMsg;
type: number;
source: string;
referencedAttachmentTimestamp: number;
};
messageRequestResponse?: { messageRequestResponse?: {
/** 1 means approved, 0 means unapproved. */ /** 1 means approved, 0 means unapproved. */
isApproved?: number; isApproved?: number;

@ -913,15 +913,14 @@ export async function handleDataExtractionNotification({
envelope, envelope,
expireUpdate, expireUpdate,
messageHash, messageHash,
dataExtractionNotification,
}: { }: {
envelope: EnvelopePlus; envelope: EnvelopePlus;
dataExtractionNotification: SignalService.DataExtractionNotification; dataExtractionNotification: SignalService.DataExtractionNotification;
expireUpdate: ReadyToDisappearMsgUpdate | undefined; expireUpdate: ReadyToDisappearMsgUpdate | undefined;
messageHash: string; messageHash: string;
}): Promise<void> { }): Promise<void> {
// we currently don't care about the timestamp included in the field itself, just the timestamp of the envelope // Note: we currently don't care about the timestamp included in the field itself, just the timestamp of the envelope
const { type, timestamp: referencedAttachment } = dataExtractionNotification; // Note: we only support one type of data extraction notification
const { source, timestamp } = envelope; const { source, timestamp } = envelope;
await IncomingMessageCache.removeFromCache(envelope); await IncomingMessageCache.removeFromCache(envelope);
@ -933,23 +932,20 @@ export async function handleDataExtractionNotification({
return; return;
} }
if (!type || !source || !timestamp) { if (!source || !timestamp) {
window?.log?.info('DataNotification pre check failed'); window?.log?.info('DataNotification pre check failed');
return; return;
} }
const sentAtTimestamp = toNumber(timestamp); const sentAtTimestamp = toNumber(timestamp);
const referencedAttachmentTimestamp = toNumber(referencedAttachment);
let created = await convo.addSingleIncomingMessage({ let created = await convo.addSingleIncomingMessage({
source, source,
messageHash, messageHash,
sent_at: sentAtTimestamp, sent_at: sentAtTimestamp,
dataExtractionNotification: { dataExtractionNotification: {
type, // just set it to non empty object. We don't need anything else than this for now
referencedAttachmentTimestamp, // currently unused
source,
}, },
}); });

@ -20,7 +20,7 @@ export class DataExtractionNotificationMessage extends ExpirableMessage {
constructor(params: DataExtractionNotificationMessageParams) { constructor(params: DataExtractionNotificationMessageParams) {
super(params); super(params);
this.referencedAttachmentTimestamp = params.referencedAttachmentTimestamp; this.referencedAttachmentTimestamp = params.referencedAttachmentTimestamp;
// this does not make any sense // this is unused. Probably on all platforms, but well.
if (!this.referencedAttachmentTimestamp) { if (!this.referencedAttachmentTimestamp) {
throw new Error('referencedAttachmentTimestamp must be set'); throw new Error('referencedAttachmentTimestamp must be set');
} }

@ -151,7 +151,6 @@ export const getSortedMessagesTypesOfSelectedConversation = createSelector(
...common, ...common,
message: { message: {
messageType: 'data-extraction', messageType: 'data-extraction',
props: { ...msg.propsForDataExtractionNotification },
}, },
}; };
} }

@ -203,3 +203,4 @@ export function useMessageCommunityInvitationFullUrl(messageId: string) {
export function useMessageCommunityInvitationCommunityName(messageId: string) { export function useMessageCommunityInvitationCommunityName(messageId: string) {
return useMessagePropsByMessageId(messageId)?.propsForGroupInvitation?.serverName; return useMessagePropsByMessageId(messageId)?.propsForGroupInvitation?.serverName;
} }

Loading…
Cancel
Save