mirror of
https://github.com/oxen-io/session-desktop.git
synced 2023-12-14 02:12:57 +01:00
Note to Self
This commit is contained in:
parent
681ca363fe
commit
a43a78731a
15 changed files with 411 additions and 148 deletions
|
@ -1544,6 +1544,10 @@
|
|||
"message": "Dark",
|
||||
"description": "Label text for dark theme"
|
||||
},
|
||||
"noteToSelf": {
|
||||
"message": "Note to Self",
|
||||
"description": "Name for the conversation with your own phone number"
|
||||
},
|
||||
"hideMenuBar": {
|
||||
"message": "Hide menu bar",
|
||||
"description": "Label text for menu bar visibility setting"
|
||||
|
|
1
images/note-28.svg
Normal file
1
images/note-28.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg id="Export" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 28 28"><title>note-28</title><path d="M21,3H7A2,2,0,0,0,5,5V23a2,2,0,0,0,2,2H21a2,2,0,0,0,2-2V5A2,2,0,0,0,21,3ZM17,19.5H7V18H17ZM21,16H7V14.5H21Zm0-3.5H7V11H21ZM21,9H7V7.5H21Z"/></svg>
|
After Width: | Height: | Size: 249 B |
|
@ -312,6 +312,7 @@
|
|||
|
||||
const result = {
|
||||
...this.format(),
|
||||
isMe: this.isMe(),
|
||||
conversationType: this.isPrivate() ? 'direct' : 'group',
|
||||
|
||||
lastUpdated: this.get('timestamp'),
|
||||
|
@ -908,6 +909,25 @@
|
|||
return null;
|
||||
}
|
||||
|
||||
const attachmentsWithData = await Promise.all(
|
||||
messageWithSchema.attachments.map(loadAttachmentData)
|
||||
);
|
||||
|
||||
// Special-case the self-send case - we send only a sync message
|
||||
if (this.isMe()) {
|
||||
const dataMessage = await textsecure.messaging.getMessageProto(
|
||||
destination,
|
||||
body,
|
||||
attachmentsWithData,
|
||||
quote,
|
||||
preview,
|
||||
now,
|
||||
expireTimer,
|
||||
profileKey
|
||||
);
|
||||
return message.sendSyncMessageOnly(dataMessage);
|
||||
}
|
||||
|
||||
const conversationType = this.get('type');
|
||||
const sendFunction = (() => {
|
||||
switch (conversationType) {
|
||||
|
@ -922,10 +942,6 @@
|
|||
}
|
||||
})();
|
||||
|
||||
const attachmentsWithData = await Promise.all(
|
||||
messageWithSchema.attachments.map(loadAttachmentData)
|
||||
);
|
||||
|
||||
const options = this.getSendOptions();
|
||||
return message.send(
|
||||
this.wrapSend(
|
||||
|
|
|
@ -736,10 +736,25 @@
|
|||
const quoteWithData = await loadQuoteData(this.get('quote'));
|
||||
const previewWithData = await loadPreviewData(this.get('preview'));
|
||||
|
||||
const conversation = this.getConversation();
|
||||
const options = conversation.getSendOptions();
|
||||
// Special-case the self-send case - we send only a sync message
|
||||
if (numbers.length === 1 && numbers[0] === this.OUR_NUMBER) {
|
||||
const [number] = numbers;
|
||||
const dataMessage = await textsecure.messaging.getMessageProto(
|
||||
number,
|
||||
this.get('body'),
|
||||
attachmentsWithData,
|
||||
quoteWithData,
|
||||
previewWithData,
|
||||
this.get('sent_at'),
|
||||
this.get('expireTimer'),
|
||||
profileKey
|
||||
);
|
||||
return this.sendSyncMessageOnly(dataMessage);
|
||||
}
|
||||
|
||||
let promise;
|
||||
const conversation = this.getConversation();
|
||||
const options = conversation.getSendOptions();
|
||||
|
||||
if (conversation.isPrivate()) {
|
||||
const [number] = numbers;
|
||||
|
@ -794,18 +809,21 @@
|
|||
// One caller today: ConversationView.forceSend()
|
||||
async resend(number) {
|
||||
const error = this.removeOutgoingErrors(number);
|
||||
if (error) {
|
||||
const profileKey = null;
|
||||
const attachmentsWithData = await Promise.all(
|
||||
(this.get('attachments') || []).map(loadAttachmentData)
|
||||
);
|
||||
const quoteWithData = await loadQuoteData(this.get('quote'));
|
||||
const previewWithData = await loadPreviewData(this.get('preview'));
|
||||
if (!error) {
|
||||
window.log.warn('resend: requested number was not present in errors');
|
||||
return null;
|
||||
}
|
||||
|
||||
const { wrap, sendOptions } = ConversationController.prepareForSend(
|
||||
number
|
||||
);
|
||||
const promise = textsecure.messaging.sendMessageToNumber(
|
||||
const profileKey = null;
|
||||
const attachmentsWithData = await Promise.all(
|
||||
(this.get('attachments') || []).map(loadAttachmentData)
|
||||
);
|
||||
const quoteWithData = await loadQuoteData(this.get('quote'));
|
||||
const previewWithData = await loadPreviewData(this.get('preview'));
|
||||
|
||||
// Special-case the self-send case - we send only a sync message
|
||||
if (number === this.OUR_NUMBER) {
|
||||
const dataMessage = await textsecure.messaging.getMessageProto(
|
||||
number,
|
||||
this.get('body'),
|
||||
attachmentsWithData,
|
||||
|
@ -813,12 +831,27 @@
|
|||
previewWithData,
|
||||
this.get('sent_at'),
|
||||
this.get('expireTimer'),
|
||||
profileKey,
|
||||
sendOptions
|
||||
profileKey
|
||||
);
|
||||
|
||||
this.send(wrap(promise));
|
||||
return this.sendSyncMessageOnly(dataMessage);
|
||||
}
|
||||
|
||||
const { wrap, sendOptions } = ConversationController.prepareForSend(
|
||||
number
|
||||
);
|
||||
const promise = textsecure.messaging.sendMessageToNumber(
|
||||
number,
|
||||
this.get('body'),
|
||||
attachmentsWithData,
|
||||
quoteWithData,
|
||||
previewWithData,
|
||||
this.get('sent_at'),
|
||||
this.get('expireTimer'),
|
||||
profileKey,
|
||||
sendOptions
|
||||
);
|
||||
|
||||
return this.send(wrap(promise));
|
||||
},
|
||||
removeOutgoingErrors(number) {
|
||||
const errors = _.partition(
|
||||
|
@ -912,7 +945,7 @@
|
|||
this.trigger('done');
|
||||
|
||||
// This is used by sendSyncMessage, then set to null
|
||||
if (result.dataMessage) {
|
||||
if (!this.get('synced') && result.dataMessage) {
|
||||
this.set({ dataMessage: result.dataMessage });
|
||||
}
|
||||
|
||||
|
@ -1013,6 +1046,35 @@
|
|||
return false;
|
||||
},
|
||||
|
||||
async sendSyncMessageOnly(dataMessage) {
|
||||
this.set({ dataMessage });
|
||||
|
||||
try {
|
||||
await this.sendSyncMessage();
|
||||
this.set({
|
||||
delivered_to: [this.OUR_NUMBER],
|
||||
read_by: [this.OUR_NUMBER],
|
||||
});
|
||||
} catch (result) {
|
||||
const errors = (result && result.errors) || [
|
||||
new Error('Unknown error'),
|
||||
];
|
||||
this.set({ errors });
|
||||
} finally {
|
||||
await window.Signal.Data.saveMessage(this.attributes, {
|
||||
Message: Whisper.Message,
|
||||
});
|
||||
this.trigger('done');
|
||||
|
||||
const errors = this.get('errors');
|
||||
if (errors) {
|
||||
this.trigger('send-error', errors);
|
||||
} else {
|
||||
this.trigger('sent');
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
sendSyncMessage() {
|
||||
const ourNumber = textsecure.storage.user.getNumber();
|
||||
const { wrap, sendOptions } = ConversationController.prepareForSend(
|
||||
|
@ -1021,7 +1083,7 @@
|
|||
);
|
||||
|
||||
this.syncPromise = this.syncPromise || Promise.resolve();
|
||||
this.syncPromise = this.syncPromise.then(() => {
|
||||
const next = () => {
|
||||
const dataMessage = this.get('dataMessage');
|
||||
if (this.get('synced') || !dataMessage) {
|
||||
return Promise.resolve();
|
||||
|
@ -1036,16 +1098,20 @@
|
|||
this.get('unidentifiedDeliveries'),
|
||||
sendOptions
|
||||
)
|
||||
).then(() => {
|
||||
).then(result => {
|
||||
this.set({
|
||||
synced: true,
|
||||
dataMessage: null,
|
||||
});
|
||||
return window.Signal.Data.saveMessage(this.attributes, {
|
||||
Message: Whisper.Message,
|
||||
});
|
||||
}).then(() => result);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
this.syncPromise = this.syncPromise.then(next, next);
|
||||
|
||||
return this.syncPromise;
|
||||
},
|
||||
|
||||
async saveErrors(providedErrors) {
|
||||
|
@ -1312,6 +1378,14 @@
|
|||
});
|
||||
}
|
||||
|
||||
// A sync'd message to ourself is automatically considered read and delivered
|
||||
if (conversation.isMe()) {
|
||||
message.set({
|
||||
read_by: conversation.getRecipients(),
|
||||
delivered_to: conversation.getRecipients(),
|
||||
});
|
||||
}
|
||||
|
||||
message.set({ recipients: conversation.getRecipients() });
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/* global ConversationController: false */
|
||||
/* global i18n: false */
|
||||
/* global Whisper: false */
|
||||
/* global ConversationController, i18n, textsecure, Whisper */
|
||||
|
||||
// eslint-disable-next-line func-names
|
||||
(function() {
|
||||
|
@ -81,9 +79,19 @@
|
|||
/* eslint-disable more/no-then */
|
||||
this.pending = this.pending.then(() =>
|
||||
this.typeahead.search(query).then(() => {
|
||||
this.typeahead_view.collection.reset(
|
||||
this.typeahead.filter(isSearchable)
|
||||
);
|
||||
let results = this.typeahead.filter(isSearchable);
|
||||
const noteToSelf = i18n('noteToSelf');
|
||||
if (noteToSelf.toLowerCase().indexOf(query.toLowerCase()) !== -1) {
|
||||
const ourNumber = textsecure.storage.user.getNumber();
|
||||
const conversation = ConversationController.get(ourNumber);
|
||||
if (conversation) {
|
||||
// ensure that we don't have duplicates in our results
|
||||
results = results.filter(item => item.id !== ourNumber);
|
||||
results.unshift(conversation);
|
||||
}
|
||||
}
|
||||
|
||||
this.typeahead_view.collection.reset(results);
|
||||
})
|
||||
);
|
||||
/* eslint-enable more/no-then */
|
||||
|
|
|
@ -759,6 +759,37 @@ MessageSender.prototype = {
|
|||
});
|
||||
},
|
||||
|
||||
async getMessageProto(
|
||||
number,
|
||||
body,
|
||||
attachments,
|
||||
quote,
|
||||
preview,
|
||||
timestamp,
|
||||
expireTimer,
|
||||
profileKey
|
||||
) {
|
||||
const attributes = {
|
||||
recipients: [number],
|
||||
body,
|
||||
timestamp,
|
||||
attachments,
|
||||
quote,
|
||||
preview,
|
||||
expireTimer,
|
||||
profileKey,
|
||||
};
|
||||
|
||||
const message = new Message(attributes);
|
||||
await Promise.all([
|
||||
this.uploadAttachments(message),
|
||||
this.uploadThumbnails(message),
|
||||
this.uploadLinkPreviews(message),
|
||||
]);
|
||||
|
||||
return message.toArrayBuffer();
|
||||
},
|
||||
|
||||
sendMessageToNumber(
|
||||
number,
|
||||
messageText,
|
||||
|
@ -1110,6 +1141,7 @@ textsecure.MessageSender = function MessageSenderWrapper(
|
|||
this.sendReadReceipts = sender.sendReadReceipts.bind(sender);
|
||||
this.makeProxiedRequest = sender.makeProxiedRequest.bind(sender);
|
||||
this.getProxiedSize = sender.getProxiedSize.bind(sender);
|
||||
this.getMessageProto = sender.getMessageProto.bind(sender);
|
||||
};
|
||||
|
||||
textsecure.MessageSender.prototype = {
|
||||
|
|
|
@ -1348,7 +1348,7 @@
|
|||
}
|
||||
|
||||
.module-conversation-header__title {
|
||||
margin-left: 8px;
|
||||
margin-left: 6px;
|
||||
|
||||
min-width: 0;
|
||||
font-size: 16px;
|
||||
|
@ -1356,8 +1356,8 @@
|
|||
font-weight: 300;
|
||||
color: $color-gray-90;
|
||||
|
||||
// width of avatar (28px) and our 8px left margin
|
||||
max-width: calc(100% - 36px);
|
||||
// width of avatar (28px) and our 6px left margin
|
||||
max-width: calc(100% - 34px);
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
|
@ -2036,6 +2036,12 @@
|
|||
width: 42px;
|
||||
}
|
||||
|
||||
.module-avatar__icon--note-to-self {
|
||||
width: 70%;
|
||||
height: 70%;
|
||||
@include color-svg('../images/note-28.svg', $color-white);
|
||||
}
|
||||
|
||||
.module-avatar--no-image {
|
||||
background-color: $color-conversation-grey;
|
||||
}
|
||||
|
|
|
@ -1098,6 +1098,10 @@ body.dark-theme {
|
|||
color: $color-dark-05;
|
||||
}
|
||||
|
||||
.module-conversation-header__note-to-self {
|
||||
color: $color-dark-05;
|
||||
}
|
||||
|
||||
.module-conversation-header__title__verified-icon {
|
||||
@include color-svg('../images/verified-check.svg', $color-dark-05);
|
||||
}
|
||||
|
@ -1262,11 +1266,15 @@ body.dark-theme {
|
|||
}
|
||||
|
||||
.module-avatar__icon--group {
|
||||
@include color-svg('../images/profile-group.svg', $color-gray-05);
|
||||
background-color: $color-gray-05;
|
||||
}
|
||||
|
||||
.module-avatar__icon--direct {
|
||||
@include color-svg('../images/profile-individual.svg', $color-gray-05);
|
||||
background-color: $color-gray-05;
|
||||
}
|
||||
|
||||
.module-avatar__icon--note-to-self {
|
||||
background-color: $color-gray-05;
|
||||
}
|
||||
|
||||
.module-avatar--no-image {
|
||||
|
|
|
@ -63,6 +63,45 @@
|
|||
</util.ConversationContext>
|
||||
```
|
||||
|
||||
### Note to self
|
||||
|
||||
```jsx
|
||||
<util.ConversationContext theme={util.theme} ios={util.ios}>
|
||||
<Avatar
|
||||
size={80}
|
||||
color="pink"
|
||||
noteToSelf={true}
|
||||
phoneNumber="(555) 353-3433"
|
||||
conversationType="direct"
|
||||
i18n={util.i18n}
|
||||
/>
|
||||
<Avatar
|
||||
size={48}
|
||||
color="pink"
|
||||
noteToSelf={true}
|
||||
phoneNumber="(555) 353-3433"
|
||||
conversationType="direct"
|
||||
i18n={util.i18n}
|
||||
/>
|
||||
<Avatar
|
||||
size={36}
|
||||
color="pink"
|
||||
noteToSelf={true}
|
||||
phoneNumber="(555) 353-3433"
|
||||
conversationType="direct"
|
||||
i18n={util.i18n}
|
||||
/>
|
||||
<Avatar
|
||||
size={28}
|
||||
color="pink"
|
||||
noteToSelf={true}
|
||||
phoneNumber="(555) 353-3433"
|
||||
conversationType="direct"
|
||||
i18n={util.i18n}
|
||||
/>
|
||||
</util.ConversationContext>
|
||||
```
|
||||
|
||||
### All colors
|
||||
|
||||
```jsx
|
||||
|
|
|
@ -9,6 +9,7 @@ interface Props {
|
|||
color?: string;
|
||||
conversationType: 'group' | 'direct';
|
||||
i18n: Localizer;
|
||||
noteToSelf?: boolean;
|
||||
name?: string;
|
||||
phoneNumber?: string;
|
||||
profileName?: string;
|
||||
|
@ -63,11 +64,23 @@ export class Avatar extends React.Component<Props, State> {
|
|||
}
|
||||
|
||||
public renderNoImage() {
|
||||
const { conversationType, name, size } = this.props;
|
||||
const { conversationType, name, noteToSelf, size } = this.props;
|
||||
|
||||
const initials = getInitials(name);
|
||||
const isGroup = conversationType === 'group';
|
||||
|
||||
if (noteToSelf) {
|
||||
return (
|
||||
<div
|
||||
className={classNames(
|
||||
'module-avatar__icon',
|
||||
'module-avatar__icon--note-to-self',
|
||||
`module-avatar__icon--${size}`
|
||||
)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
if (!isGroup && initials) {
|
||||
return (
|
||||
<div
|
||||
|
@ -93,10 +106,10 @@ export class Avatar extends React.Component<Props, State> {
|
|||
}
|
||||
|
||||
public render() {
|
||||
const { avatarPath, color, size } = this.props;
|
||||
const { avatarPath, color, size, noteToSelf } = this.props;
|
||||
const { imageBroken } = this.state;
|
||||
|
||||
const hasImage = avatarPath && !imageBroken;
|
||||
const hasImage = !noteToSelf && avatarPath && !imageBroken;
|
||||
|
||||
if (size !== 28 && size !== 36 && size !== 48 && size !== 80) {
|
||||
throw new Error(`Size ${size} is not supported!`);
|
||||
|
|
|
@ -38,6 +38,27 @@
|
|||
</util.LeftPaneContext>
|
||||
```
|
||||
|
||||
#### Conversation with yourself
|
||||
|
||||
```jsx
|
||||
<util.LeftPaneContext theme={util.theme}>
|
||||
<ConversationListItem
|
||||
isMe={true}
|
||||
phoneNumber="(202) 555-0011"
|
||||
conversationType={'direct'}
|
||||
name="Mr. Fire🔥"
|
||||
color="green"
|
||||
lastUpdated={Date.now() - 5 * 60 * 1000}
|
||||
lastMessage={{
|
||||
text: 'Just a second',
|
||||
status: 'read',
|
||||
}}
|
||||
onClick={() => console.log('onClick')}
|
||||
i18n={util.i18n}
|
||||
/>
|
||||
</util.LeftPaneContext>
|
||||
```
|
||||
|
||||
#### All types of status
|
||||
|
||||
```jsx
|
||||
|
|
|
@ -16,6 +16,7 @@ interface Props {
|
|||
color?: string;
|
||||
conversationType: 'group' | 'direct';
|
||||
avatarPath?: string;
|
||||
isMe: boolean;
|
||||
|
||||
lastUpdated: number;
|
||||
unreadCount: number;
|
||||
|
@ -38,6 +39,7 @@ export class ConversationListItem extends React.Component<Props> {
|
|||
color,
|
||||
conversationType,
|
||||
i18n,
|
||||
isMe,
|
||||
name,
|
||||
phoneNumber,
|
||||
profileName,
|
||||
|
@ -48,6 +50,7 @@ export class ConversationListItem extends React.Component<Props> {
|
|||
<Avatar
|
||||
avatarPath={avatarPath}
|
||||
color={color}
|
||||
noteToSelf={isMe}
|
||||
conversationType={conversationType}
|
||||
i18n={i18n}
|
||||
name={name}
|
||||
|
@ -78,6 +81,7 @@ export class ConversationListItem extends React.Component<Props> {
|
|||
const {
|
||||
unreadCount,
|
||||
i18n,
|
||||
isMe,
|
||||
lastUpdated,
|
||||
name,
|
||||
phoneNumber,
|
||||
|
@ -94,12 +98,16 @@ export class ConversationListItem extends React.Component<Props> {
|
|||
: null
|
||||
)}
|
||||
>
|
||||
<ContactName
|
||||
phoneNumber={phoneNumber}
|
||||
name={name}
|
||||
profileName={profileName}
|
||||
i18n={i18n}
|
||||
/>
|
||||
{isMe ? (
|
||||
i18n('noteToSelf')
|
||||
) : (
|
||||
<ContactName
|
||||
phoneNumber={phoneNumber}
|
||||
name={name}
|
||||
profileName={profileName}
|
||||
i18n={i18n}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
<div
|
||||
className={classNames(
|
||||
|
|
|
@ -5,100 +5,112 @@ Note the five items in gear menu, and the second-level menu with disappearing me
|
|||
#### With name and profile, verified
|
||||
|
||||
```jsx
|
||||
<ConversationHeader
|
||||
i18n={util.i18n}
|
||||
color="red"
|
||||
isVerified={true}
|
||||
avatarPath={util.gifObjectUrl}
|
||||
name="Someone 🔥 Somewhere"
|
||||
phoneNumber="(202) 555-0001"
|
||||
id="1"
|
||||
profileName="🔥Flames🔥"
|
||||
onSetDisappearingMessages={seconds =>
|
||||
console.log('onSetDisappearingMessages', seconds)
|
||||
}
|
||||
onDeleteMessages={() => console.log('onDeleteMessages')}
|
||||
onResetSession={() => console.log('onResetSession')}
|
||||
onShowSafetyNumber={() => console.log('onShowSafetyNumber')}
|
||||
onShowAllMedia={() => console.log('onShowAllMedia')}
|
||||
onShowGroupMembers={() => console.log('onShowGroupMembers')}
|
||||
onGoBack={() => console.log('onGoBack')}
|
||||
/>
|
||||
<util.ConversationContext theme={util.theme}>
|
||||
<ConversationHeader
|
||||
i18n={util.i18n}
|
||||
color="red"
|
||||
isVerified={true}
|
||||
avatarPath={util.gifObjectUrl}
|
||||
name="Someone 🔥 Somewhere"
|
||||
phoneNumber="(202) 555-0001"
|
||||
id="1"
|
||||
profileName="🔥Flames🔥"
|
||||
onSetDisappearingMessages={seconds =>
|
||||
console.log('onSetDisappearingMessages', seconds)
|
||||
}
|
||||
onDeleteMessages={() => console.log('onDeleteMessages')}
|
||||
onResetSession={() => console.log('onResetSession')}
|
||||
onShowSafetyNumber={() => console.log('onShowSafetyNumber')}
|
||||
onShowAllMedia={() => console.log('onShowAllMedia')}
|
||||
onShowGroupMembers={() => console.log('onShowGroupMembers')}
|
||||
onGoBack={() => console.log('onGoBack')}
|
||||
/>
|
||||
</util.ConversationContext>
|
||||
```
|
||||
|
||||
#### With name, not verified, no avatar
|
||||
|
||||
```jsx
|
||||
<ConversationHeader
|
||||
i18n={util.i18n}
|
||||
color="blue"
|
||||
isVerified={false}
|
||||
name="Someone 🔥 Somewhere"
|
||||
phoneNumber="(202) 555-0002"
|
||||
id="2"
|
||||
/>
|
||||
<util.ConversationContext theme={util.theme}>
|
||||
<ConversationHeader
|
||||
i18n={util.i18n}
|
||||
color="blue"
|
||||
isVerified={false}
|
||||
name="Someone 🔥 Somewhere"
|
||||
phoneNumber="(202) 555-0002"
|
||||
id="2"
|
||||
/>
|
||||
</util.ConversationContext>
|
||||
```
|
||||
|
||||
#### Profile, no name
|
||||
|
||||
```jsx
|
||||
<ConversationHeader
|
||||
i18n={util.i18n}
|
||||
color="teal"
|
||||
isVerified={false}
|
||||
phoneNumber="(202) 555-0003"
|
||||
id="3"
|
||||
profileName="🔥Flames🔥"
|
||||
/>
|
||||
<util.ConversationContext theme={util.theme}>
|
||||
<ConversationHeader
|
||||
i18n={util.i18n}
|
||||
color="teal"
|
||||
isVerified={false}
|
||||
phoneNumber="(202) 555-0003"
|
||||
id="3"
|
||||
profileName="🔥Flames🔥"
|
||||
/>
|
||||
</util.ConversationContext>
|
||||
```
|
||||
|
||||
#### No name, no profile, no color
|
||||
|
||||
```jsx
|
||||
<ConversationHeader i18n={util.i18n} phoneNumber="(202) 555-0011" id="11" />
|
||||
<util.ConversationContext theme={util.theme}>
|
||||
<ConversationHeader i18n={util.i18n} phoneNumber="(202) 555-0011" id="11" />
|
||||
</util.ConversationContext>
|
||||
```
|
||||
|
||||
### With back button
|
||||
|
||||
```jsx
|
||||
<ConversationHeader
|
||||
showBackButton={true}
|
||||
color="deep_orange"
|
||||
i18n={util.i18n}
|
||||
phoneNumber="(202) 555-0004"
|
||||
id="4"
|
||||
/>
|
||||
<util.ConversationContext theme={util.theme}>
|
||||
<ConversationHeader
|
||||
showBackButton={true}
|
||||
color="deep_orange"
|
||||
i18n={util.i18n}
|
||||
phoneNumber="(202) 555-0004"
|
||||
id="4"
|
||||
/>
|
||||
</util.ConversationContext>
|
||||
```
|
||||
|
||||
### Disappearing messages set
|
||||
|
||||
```jsx
|
||||
<ConversationHeader
|
||||
color="indigo"
|
||||
i18n={util.i18n}
|
||||
phoneNumber="(202) 555-0005"
|
||||
id="5"
|
||||
expirationSettingName="10 seconds"
|
||||
timerOptions={[
|
||||
{
|
||||
name: 'off',
|
||||
value: 0,
|
||||
},
|
||||
{
|
||||
name: '10 seconds',
|
||||
value: 10,
|
||||
},
|
||||
]}
|
||||
onSetDisappearingMessages={seconds =>
|
||||
console.log('onSetDisappearingMessages', seconds)
|
||||
}
|
||||
onDeleteMessages={() => console.log('onDeleteMessages')}
|
||||
onResetSession={() => console.log('onResetSession')}
|
||||
onShowSafetyNumber={() => console.log('onShowSafetyNumber')}
|
||||
onShowAllMedia={() => console.log('onShowAllMedia')}
|
||||
onShowGroupMembers={() => console.log('onShowGroupMembers')}
|
||||
onGoBack={() => console.log('onGoBack')}
|
||||
/>
|
||||
<util.ConversationContext theme={util.theme}>
|
||||
<ConversationHeader
|
||||
color="indigo"
|
||||
i18n={util.i18n}
|
||||
phoneNumber="(202) 555-0005"
|
||||
id="5"
|
||||
expirationSettingName="10 seconds"
|
||||
timerOptions={[
|
||||
{
|
||||
name: 'off',
|
||||
value: 0,
|
||||
},
|
||||
{
|
||||
name: '10 seconds',
|
||||
value: 10,
|
||||
},
|
||||
]}
|
||||
onSetDisappearingMessages={seconds =>
|
||||
console.log('onSetDisappearingMessages', seconds)
|
||||
}
|
||||
onDeleteMessages={() => console.log('onDeleteMessages')}
|
||||
onResetSession={() => console.log('onResetSession')}
|
||||
onShowSafetyNumber={() => console.log('onShowSafetyNumber')}
|
||||
onShowAllMedia={() => console.log('onShowAllMedia')}
|
||||
onShowGroupMembers={() => console.log('onShowGroupMembers')}
|
||||
onGoBack={() => console.log('onGoBack')}
|
||||
/>
|
||||
</util.ConversationContext>
|
||||
```
|
||||
|
||||
### In a group
|
||||
|
@ -106,34 +118,38 @@ Note the five items in gear menu, and the second-level menu with disappearing me
|
|||
Note that the menu should includes 'Show Members' instead of 'Show Safety Number'
|
||||
|
||||
```jsx
|
||||
<ConversationHeader
|
||||
i18n={util.i18n}
|
||||
color="green"
|
||||
phoneNumber="(202) 555-0006"
|
||||
id="6"
|
||||
isGroup={true}
|
||||
onSetDisappearingMessages={seconds =>
|
||||
console.log('onSetDisappearingMessages', seconds)
|
||||
}
|
||||
onDeleteMessages={() => console.log('onDeleteMessages')}
|
||||
onResetSession={() => console.log('onResetSession')}
|
||||
onShowSafetyNumber={() => console.log('onShowSafetyNumber')}
|
||||
onShowAllMedia={() => console.log('onShowAllMedia')}
|
||||
onShowGroupMembers={() => console.log('onShowGroupMembers')}
|
||||
onGoBack={() => console.log('onGoBack')}
|
||||
/>
|
||||
<util.ConversationContext theme={util.theme}>
|
||||
<ConversationHeader
|
||||
i18n={util.i18n}
|
||||
color="green"
|
||||
phoneNumber="(202) 555-0006"
|
||||
id="6"
|
||||
isGroup={true}
|
||||
onSetDisappearingMessages={seconds =>
|
||||
console.log('onSetDisappearingMessages', seconds)
|
||||
}
|
||||
onDeleteMessages={() => console.log('onDeleteMessages')}
|
||||
onResetSession={() => console.log('onResetSession')}
|
||||
onShowSafetyNumber={() => console.log('onShowSafetyNumber')}
|
||||
onShowAllMedia={() => console.log('onShowAllMedia')}
|
||||
onShowGroupMembers={() => console.log('onShowGroupMembers')}
|
||||
onGoBack={() => console.log('onGoBack')}
|
||||
/>
|
||||
</util.ConversationContext>
|
||||
```
|
||||
|
||||
### In chat with yourself
|
||||
|
||||
Note that the menu should not have a 'Show Safety Number' entry.
|
||||
This is the 'Note to self' conversation. Note that the menu should not have a 'Show Safety Number' entry.
|
||||
|
||||
```jsx
|
||||
<ConversationHeader
|
||||
color="cyan"
|
||||
i18n={util.i18n}
|
||||
phoneNumber="(202) 555-0007"
|
||||
id="7"
|
||||
isMe={true}
|
||||
/>
|
||||
<util.ConversationContext theme={util.theme}>
|
||||
<ConversationHeader
|
||||
color="cyan"
|
||||
i18n={util.i18n}
|
||||
phoneNumber="(202) 555-0007"
|
||||
id="7"
|
||||
isMe={true}
|
||||
/>
|
||||
</util.ConversationContext>
|
||||
```
|
||||
|
|
|
@ -84,7 +84,22 @@ export class ConversationHeader extends React.Component<Props> {
|
|||
}
|
||||
|
||||
public renderTitle() {
|
||||
const { name, phoneNumber, i18n, profileName, isVerified } = this.props;
|
||||
const {
|
||||
name,
|
||||
phoneNumber,
|
||||
i18n,
|
||||
isMe,
|
||||
profileName,
|
||||
isVerified,
|
||||
} = this.props;
|
||||
|
||||
if (isMe) {
|
||||
return (
|
||||
<div className="module-conversation-header__title">
|
||||
{i18n('noteToSelf')}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="module-conversation-header__title">
|
||||
|
@ -113,6 +128,7 @@ export class ConversationHeader extends React.Component<Props> {
|
|||
color,
|
||||
i18n,
|
||||
isGroup,
|
||||
isMe,
|
||||
name,
|
||||
phoneNumber,
|
||||
profileName,
|
||||
|
@ -125,6 +141,7 @@ export class ConversationHeader extends React.Component<Props> {
|
|||
color={color}
|
||||
conversationType={isGroup ? 'group' : 'direct'}
|
||||
i18n={i18n}
|
||||
noteToSelf={isMe}
|
||||
name={name}
|
||||
phoneNumber={phoneNumber}
|
||||
profileName={profileName}
|
||||
|
|
|
@ -206,8 +206,8 @@
|
|||
{
|
||||
"rule": "jQuery-wrap(",
|
||||
"path": "js/models/messages.js",
|
||||
"line": " this.send(wrap(promise));",
|
||||
"lineNumber": 820,
|
||||
"line": " return this.send(wrap(promise));",
|
||||
"lineNumber": 854,
|
||||
"reasonCategory": "falseMatch",
|
||||
"updated": "2018-10-05T23:12:28.961Z"
|
||||
},
|
||||
|
@ -215,7 +215,7 @@
|
|||
"rule": "jQuery-wrap(",
|
||||
"path": "js/models/messages.js",
|
||||
"line": " return wrap(",
|
||||
"lineNumber": 1029,
|
||||
"lineNumber": 1091,
|
||||
"reasonCategory": "falseMatch",
|
||||
"updated": "2018-10-05T23:12:28.961Z"
|
||||
},
|
||||
|
@ -527,7 +527,7 @@
|
|||
"rule": "jQuery-$(",
|
||||
"path": "js/views/conversation_search_view.js",
|
||||
"line": " this.$new_contact = this.$('.new-contact');",
|
||||
"lineNumber": 42,
|
||||
"lineNumber": 40,
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2018-09-19T21:59:32.770Z",
|
||||
"reasonDetail": "Protected from arbitrary input"
|
||||
|
@ -536,7 +536,7 @@
|
|||
"rule": "jQuery-append(",
|
||||
"path": "js/views/conversation_search_view.js",
|
||||
"line": " this.$el.append(this.typeahead_view.el);",
|
||||
"lineNumber": 59,
|
||||
"lineNumber": 57,
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2018-09-19T18:13:29.628Z",
|
||||
"reasonDetail": "Interacting with already-existing DOM nodes"
|
||||
|
@ -545,7 +545,7 @@
|
|||
"rule": "jQuery-$(",
|
||||
"path": "js/views/conversation_search_view.js",
|
||||
"line": " this.new_contact_view.$('.number').text(i18n('invalidNumberError'));",
|
||||
"lineNumber": 111,
|
||||
"lineNumber": 119,
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2018-09-19T21:59:32.770Z",
|
||||
"reasonDetail": "Protected from arbitrary input"
|
||||
|
@ -554,7 +554,7 @@
|
|||
"rule": "jQuery-insertAfter(",
|
||||
"path": "js/views/conversation_search_view.js",
|
||||
"line": " this.hintView.$el.insertAfter(this.$input);",
|
||||
"lineNumber": 147,
|
||||
"lineNumber": 155,
|
||||
"reasonCategory": "usageTrusted",
|
||||
"updated": "2018-09-19T18:13:29.628Z",
|
||||
"reasonDetail": "Interacting with already-existing DOM nodes"
|
||||
|
@ -6215,4 +6215,4 @@
|
|||
"updated": "2018-09-17T20:50:40.689Z",
|
||||
"reasonDetail": "Hard-coded value"
|
||||
}
|
||||
]
|
||||
]
|
Loading…
Reference in a new issue