Receive support for DOE messages
This commit is contained in:
parent
b8a674bbb6
commit
ba5e2ff6e5
17 changed files with 291 additions and 42 deletions
|
@ -31,6 +31,7 @@ export type PropsData = {
|
|||
lastMessage?: {
|
||||
status: 'sending' | 'sent' | 'delivered' | 'read' | 'error';
|
||||
text: string;
|
||||
deletedForEveryone?: boolean;
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -152,6 +153,9 @@ export class ConversationListItem extends React.PureComponent<Props> {
|
|||
}
|
||||
|
||||
const showingDraft = shouldShowDraft && draftPreview;
|
||||
const deletedForEveryone = Boolean(
|
||||
lastMessage && lastMessage.deletedForEveryone
|
||||
);
|
||||
|
||||
// Note: instead of re-using showingDraft here we explode it because
|
||||
// typescript can't tell that draftPreview is truthy otherwise
|
||||
|
@ -181,6 +185,10 @@ export class ConversationListItem extends React.PureComponent<Props> {
|
|||
<span className="module-conversation-list-item__message__draft-prefix">
|
||||
{i18n('ConversationListItem--draft-prefix')}
|
||||
</span>
|
||||
) : deletedForEveryone ? (
|
||||
<span className="module-conversation-list-item__message__deleted-for-everyone">
|
||||
{i18n('message--deletedForEveryone')}
|
||||
</span>
|
||||
) : null}
|
||||
<MessageBody
|
||||
text={text.split('\n')[0]}
|
||||
|
|
|
@ -106,6 +106,8 @@ export type PropsData = {
|
|||
reactions?: ReactionViewerProps['reactions'];
|
||||
selectedReaction?: string;
|
||||
|
||||
deletedForEveryone?: boolean;
|
||||
|
||||
canReply: boolean;
|
||||
};
|
||||
|
||||
|
@ -934,12 +936,20 @@ export class Message extends React.PureComponent<Props, State> {
|
|||
}
|
||||
|
||||
public renderText() {
|
||||
const { text, textPending, i18n, direction, status } = this.props;
|
||||
const {
|
||||
deletedForEveryone,
|
||||
direction,
|
||||
i18n,
|
||||
status,
|
||||
text,
|
||||
textPending,
|
||||
} = this.props;
|
||||
|
||||
const contents =
|
||||
direction === 'incoming' && status === 'error'
|
||||
? i18n('incomingError')
|
||||
: text;
|
||||
const contents = deletedForEveryone
|
||||
? i18n('message--deletedForEveryone')
|
||||
: direction === 'incoming' && status === 'error'
|
||||
? i18n('incomingError')
|
||||
: text;
|
||||
|
||||
if (!contents) {
|
||||
return null;
|
||||
|
@ -1677,7 +1687,11 @@ export class Message extends React.PureComponent<Props, State> {
|
|||
}
|
||||
|
||||
public renderContents() {
|
||||
const { isTapToView } = this.props;
|
||||
const { isTapToView, deletedForEveryone } = this.props;
|
||||
|
||||
if (deletedForEveryone) {
|
||||
return this.renderText();
|
||||
}
|
||||
|
||||
if (isTapToView) {
|
||||
return (
|
||||
|
@ -1863,9 +1877,11 @@ export class Message extends React.PureComponent<Props, State> {
|
|||
this.handleOpen(event);
|
||||
};
|
||||
|
||||
// tslint:disable-next-line: cyclomatic-complexity
|
||||
public renderContainer() {
|
||||
const {
|
||||
authorColor,
|
||||
deletedForEveryone,
|
||||
direction,
|
||||
isSticker,
|
||||
isTapToView,
|
||||
|
@ -1903,6 +1919,9 @@ export class Message extends React.PureComponent<Props, State> {
|
|||
: null,
|
||||
reactions && reactions.length > 0
|
||||
? 'module-message__container--with-reactions'
|
||||
: null,
|
||||
deletedForEveryone
|
||||
? 'module-message__container--deleted-for-everyone'
|
||||
: null
|
||||
);
|
||||
const containerStyles = {
|
||||
|
|
|
@ -88,6 +88,7 @@ export type MessageType = {
|
|||
phoneNumber?: string;
|
||||
};
|
||||
}>;
|
||||
deletedForEveryone?: boolean;
|
||||
|
||||
errors?: Array<Error>;
|
||||
group_update?: any;
|
||||
|
@ -627,6 +628,12 @@ function hasMessageHeightChanged(
|
|||
return true;
|
||||
}
|
||||
|
||||
const isDeletedForEveryone = message.deletedForEveryone;
|
||||
const wasDeletedForEveryone = previous.deletedForEveryone;
|
||||
if (isDeletedForEveryone !== wasDeletedForEveryone) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -38,6 +38,7 @@ describe('Conversation', () => {
|
|||
const expected = {
|
||||
lastMessage: 'New outgoing message',
|
||||
lastMessageStatus: 'read',
|
||||
lastMessageDeletedForEveryone: undefined,
|
||||
timestamp: 666,
|
||||
};
|
||||
|
||||
|
@ -61,6 +62,7 @@ describe('Conversation', () => {
|
|||
const expected = {
|
||||
lastMessage: 'xoxoxoxo',
|
||||
lastMessageStatus: null,
|
||||
lastMessageDeletedForEveryone: undefined,
|
||||
timestamp: 555,
|
||||
};
|
||||
|
||||
|
@ -84,6 +86,7 @@ describe('Conversation', () => {
|
|||
const expected = {
|
||||
lastMessage: '',
|
||||
lastMessageStatus: null,
|
||||
lastMessageDeletedForEveryone: undefined,
|
||||
timestamp: 555,
|
||||
};
|
||||
|
||||
|
@ -112,6 +115,7 @@ describe('Conversation', () => {
|
|||
const expected = {
|
||||
lastMessage: 'Last message before expired',
|
||||
lastMessageStatus: null,
|
||||
lastMessageDeletedForEveryone: undefined,
|
||||
timestamp: 555,
|
||||
};
|
||||
|
||||
|
|
5
ts/textsecure.d.ts
vendored
5
ts/textsecure.d.ts
vendored
|
@ -235,6 +235,7 @@ export declare class DataMessageClass {
|
|||
requiredProtocolVersion?: number;
|
||||
isViewOnce?: boolean;
|
||||
reaction?: DataMessageClass.Reaction;
|
||||
delete?: DataMessageClass.Delete;
|
||||
}
|
||||
|
||||
// Note: we need to use namespaces to express nested classes in Typescript
|
||||
|
@ -287,6 +288,10 @@ export declare namespace DataMessageClass {
|
|||
targetTimestamp?: ProtoBigNumberType;
|
||||
}
|
||||
|
||||
class Delete {
|
||||
targetSentTimestamp?: ProtoBigNumberType;
|
||||
}
|
||||
|
||||
class Sticker {
|
||||
packId?: ProtoBinaryType;
|
||||
packKey?: ProtoBinaryType;
|
||||
|
|
|
@ -1089,6 +1089,7 @@ class MessageReceiverInner extends EventTarget {
|
|||
ev.data = {
|
||||
destination,
|
||||
timestamp: timestamp.toNumber(),
|
||||
serverTimestamp: envelope.serverTimestamp,
|
||||
device: envelope.sourceDevice,
|
||||
unidentifiedStatus,
|
||||
message,
|
||||
|
@ -1159,6 +1160,7 @@ class MessageReceiverInner extends EventTarget {
|
|||
sourceUuid: envelope.sourceUuid,
|
||||
sourceDevice: envelope.sourceDevice,
|
||||
timestamp: envelope.timestamp.toNumber(),
|
||||
serverTimestamp: envelope.serverTimestamp,
|
||||
unidentifiedDeliveryReceived: envelope.unidentifiedDeliveryReceived,
|
||||
message,
|
||||
};
|
||||
|
@ -1795,6 +1797,13 @@ class MessageReceiverInner extends EventTarget {
|
|||
}
|
||||
}
|
||||
|
||||
const { delete: del } = decrypted;
|
||||
if (del) {
|
||||
if (del.targetSentTimestamp) {
|
||||
del.targetSentTimestamp = del.targetSentTimestamp.toNumber();
|
||||
}
|
||||
}
|
||||
|
||||
const groupMembers = decrypted.group ? decrypted.group.members || [] : [];
|
||||
|
||||
window.normalizeUuids(
|
||||
|
|
|
@ -4,6 +4,7 @@ interface ConversationLastMessageUpdate {
|
|||
lastMessage: string;
|
||||
lastMessageStatus: string | null;
|
||||
timestamp: number | null;
|
||||
lastMessageDeletedForEveryone?: boolean;
|
||||
}
|
||||
|
||||
export const createLastMessageUpdate = ({
|
||||
|
@ -25,7 +26,7 @@ export const createLastMessageUpdate = ({
|
|||
};
|
||||
}
|
||||
|
||||
const { type, expirationTimerUpdate } = lastMessage;
|
||||
const { type, expirationTimerUpdate, deletedForEveryone } = lastMessage;
|
||||
const isMessageHistoryUnsynced = type === 'message-history-unsynced';
|
||||
const isVerifiedChangeMessage = type === 'verified-change';
|
||||
const isExpireTimerUpdateFromSync = Boolean(
|
||||
|
@ -47,8 +48,9 @@ export const createLastMessageUpdate = ({
|
|||
: '';
|
||||
|
||||
return {
|
||||
lastMessage: newLastMessageText || '',
|
||||
lastMessage: deletedForEveryone ? '' : newLastMessageText || '',
|
||||
lastMessageStatus: lastMessageStatus || null,
|
||||
timestamp: newTimestamp || null,
|
||||
lastMessageDeletedForEveryone: deletedForEveryone,
|
||||
};
|
||||
};
|
||||
|
|
|
@ -2,10 +2,11 @@ import { Attachment } from './Attachment';
|
|||
import { ContactType } from './Contact';
|
||||
import { IndexableBoolean, IndexablePresence } from './IndexedDB';
|
||||
|
||||
export type Message =
|
||||
export type Message = (
|
||||
| UserMessage
|
||||
| VerifiedChangeMessage
|
||||
| MessageHistoryUnsyncedMessage;
|
||||
| MessageHistoryUnsyncedMessage
|
||||
) & { deletedForEveryone?: boolean };
|
||||
export type UserMessage = IncomingMessage | OutgoingMessage;
|
||||
|
||||
export type IncomingMessage = Readonly<
|
||||
|
|
|
@ -11648,17 +11648,17 @@
|
|||
"rule": "React-createRef",
|
||||
"path": "ts/components/conversation/Message.tsx",
|
||||
"line": " public audioRef: React.RefObject<HTMLAudioElement> = React.createRef();",
|
||||
"lineNumber": 179,
|
||||
"lineNumber": 181,
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2020-03-03T22:30:27.594Z"
|
||||
"updated": "2020-04-16T19:36:47.586Z"
|
||||
},
|
||||
{
|
||||
"rule": "React-createRef",
|
||||
"path": "ts/components/conversation/Message.tsx",
|
||||
"line": " > = React.createRef();",
|
||||
"lineNumber": 183,
|
||||
"lineNumber": 185,
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2020-03-03T22:30:27.594Z"
|
||||
"updated": "2020-04-16T19:36:47.586Z"
|
||||
},
|
||||
{
|
||||
"rule": "React-createRef",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue