New message state: Partially sent
This commit is contained in:
parent
81cb7730a5
commit
6a68b37c83
8 changed files with 185 additions and 38 deletions
|
@ -1281,6 +1281,10 @@
|
|||
"message": "Send failed",
|
||||
"description": "Shown on outgoing message if it fails to send"
|
||||
},
|
||||
"partiallySent": {
|
||||
"message": "Partially sent, click for details",
|
||||
"description": "Shown on outgoing message if it is partially sent"
|
||||
},
|
||||
"showMore": {
|
||||
"message": "Details",
|
||||
"description": "Displays the details of a key change"
|
||||
|
|
|
@ -688,7 +688,13 @@
|
|||
return this.get('type') === 'incoming';
|
||||
},
|
||||
getMessagePropStatus() {
|
||||
const sent = this.get('sent');
|
||||
const sentTo = this.get('sent_to') || [];
|
||||
|
||||
if (this.hasErrors()) {
|
||||
if (sent || sentTo.length > 0) {
|
||||
return 'partial-sent';
|
||||
}
|
||||
return 'error';
|
||||
}
|
||||
if (!this.isOutgoing()) {
|
||||
|
@ -704,8 +710,6 @@
|
|||
if (delivered || deliveredTo.length > 0) {
|
||||
return 'delivered';
|
||||
}
|
||||
const sent = this.get('sent');
|
||||
const sentTo = this.get('sent_to') || [];
|
||||
if (sent || sentTo.length > 0) {
|
||||
return 'sent';
|
||||
}
|
||||
|
|
|
@ -1170,6 +1170,9 @@
|
|||
color: $color-white-alpha-80;
|
||||
}
|
||||
}
|
||||
.module-message__metadata__tapable {
|
||||
@include button-reset;
|
||||
}
|
||||
.module-message__metadata__date--incoming {
|
||||
color: $color-white-alpha-80;
|
||||
|
||||
|
@ -3853,7 +3856,8 @@ $timer-icons: '55', '50', '45', '40', '35', '30', '25', '20', '15', '10', '05',
|
|||
}
|
||||
width: 18px;
|
||||
}
|
||||
.module-conversation-list-item__message__status-icon--error {
|
||||
.module-conversation-list-item__message__status-icon--error,
|
||||
.module-conversation-list-item__message__status-icon--partial-sent {
|
||||
@include light-theme {
|
||||
@include color-svg(
|
||||
'../images/icons/v2/error-outline-12.svg',
|
||||
|
|
|
@ -153,6 +153,20 @@
|
|||
onClick={result => console.log('onClick', result)}
|
||||
i18n={util.i18n}
|
||||
/>
|
||||
<ConversationListItem
|
||||
id="conversationId5"
|
||||
phoneNumber="(202) 555-0011"
|
||||
type={'direct'}
|
||||
name="Mr. Fire🔥"
|
||||
color="green"
|
||||
lastUpdated={Date.now() - 5 * 60 * 1000}
|
||||
lastMessage={{
|
||||
text: 'Partially Sent',
|
||||
status: 'partial-sent',
|
||||
}}
|
||||
onClick={result => console.log('onClick', result)}
|
||||
i18n={util.i18n}
|
||||
/>
|
||||
</div>
|
||||
</util.LeftPaneContext>
|
||||
```
|
||||
|
|
|
@ -32,7 +32,13 @@ export type PropsData = {
|
|||
|
||||
typingContact?: Object;
|
||||
lastMessage?: {
|
||||
status: 'sending' | 'sent' | 'delivered' | 'read' | 'error';
|
||||
status:
|
||||
| 'sending'
|
||||
| 'sent'
|
||||
| 'delivered'
|
||||
| 'read'
|
||||
| 'error'
|
||||
| 'partial-sent';
|
||||
text: string;
|
||||
deletedForEveryone?: boolean;
|
||||
};
|
||||
|
|
|
@ -200,6 +200,16 @@ Note that timestamp and status can be hidden with the `collapseMetadata` boolean
|
|||
onRetrySend={() => console.log('onRetrySend')}
|
||||
/>
|
||||
</div>
|
||||
<div className="module-message-container">
|
||||
<Message
|
||||
direction="outgoing"
|
||||
status="partial-sent"
|
||||
authorColor="green"
|
||||
timestamp={Date.now()}
|
||||
text="This has been partially sent!"
|
||||
i18n={util.i18n}
|
||||
/>
|
||||
</div>
|
||||
<div className="module-message-container">
|
||||
<Message
|
||||
direction="outgoing"
|
||||
|
@ -219,6 +229,25 @@ Note that timestamp and status can be hidden with the `collapseMetadata` boolean
|
|||
onRetrySend={() => console.log('onRetrySend')}
|
||||
/>
|
||||
</div>
|
||||
<div className="module-message-container">
|
||||
<Message
|
||||
direction="outgoing"
|
||||
status="partial-sent"
|
||||
authorColor="red"
|
||||
timestamp={Date.now() - 56}
|
||||
text="Error -- partially sent!"
|
||||
attachments={[
|
||||
{
|
||||
url: util.gifObjectUrl,
|
||||
contentType: 'image/gif',
|
||||
width: 320,
|
||||
height: 240,
|
||||
},
|
||||
]}
|
||||
i18n={util.i18n}
|
||||
onRetrySend={() => console.log('onRetrySend')}
|
||||
/>
|
||||
</div>
|
||||
<div className="module-message-container">
|
||||
<Message
|
||||
direction="outgoing"
|
||||
|
@ -270,6 +299,17 @@ Note that timestamp and status can be hidden with the `collapseMetadata` boolean
|
|||
onRetrySend={() => console.log('onRetrySend')}
|
||||
/>
|
||||
</div>
|
||||
<div className="module-message-container">
|
||||
<Message
|
||||
direction="outgoing"
|
||||
status="partial-sent"
|
||||
authorColor="blue"
|
||||
timestamp={Date.now() - 57}
|
||||
text="🔥"
|
||||
i18n={util.i18n}
|
||||
onRetrySend={() => console.log('onRetrySend')}
|
||||
/>
|
||||
</div>
|
||||
<div className="module-message-container">
|
||||
<Message
|
||||
direction="outgoing"
|
||||
|
@ -289,6 +329,25 @@ Note that timestamp and status can be hidden with the `collapseMetadata` boolean
|
|||
onRetrySend={() => console.log('onRetrySend')}
|
||||
/>
|
||||
</div>
|
||||
<div className="module-message-container">
|
||||
<Message
|
||||
direction="outgoing"
|
||||
status="partial-sent"
|
||||
authorColor="green"
|
||||
timestamp={Date.now() - 57}
|
||||
attachments={[
|
||||
{
|
||||
url: util.gifObjectUrl,
|
||||
contentType: 'image/gif',
|
||||
width: 320,
|
||||
height: 240,
|
||||
},
|
||||
]}
|
||||
text="🔥"
|
||||
i18n={util.i18n}
|
||||
onRetrySend={() => console.log('onRetrySend')}
|
||||
/>
|
||||
</div>
|
||||
<div className="module-message-container">
|
||||
<Message
|
||||
direction="outgoing"
|
||||
|
@ -300,6 +359,17 @@ Note that timestamp and status can be hidden with the `collapseMetadata` boolean
|
|||
onRetrySend={() => console.log('onRetrySend')}
|
||||
/>
|
||||
</div>
|
||||
<div className="module-message-container">
|
||||
<Message
|
||||
direction="outgoing"
|
||||
status="partial-sent"
|
||||
authorColor="blue"
|
||||
timestamp={Date.now() - 57}
|
||||
text="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam efficitur finibus tellus. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed eu metus leo. Nullam consequat leo ut accumsan aliquam. In est elit, faucibus vel arcu vitae, dapibus egestas nunc. Curabitur nec orci semper, auctor justo ornare, sagittis massa. Aliquam ultrices sem ac ex vestibulum dapibus. Etiam erat purus, interdum sit amet magna vitae, elementum lacinia leo. Duis vel mauris dui. Morbi sed accumsan erat, at facilisis metus. Nullam molestie lectus eleifend congue ultrices. Nunc porta at justo semper egestas. Proin non iaculis nibh. Cras sit amet urna dignissim, venenatis arcu a, pulvinar ipsum."
|
||||
i18n={util.i18n}
|
||||
onRetrySend={() => console.log('onRetrySend')}
|
||||
/>
|
||||
</div>
|
||||
<div className="module-message-container">
|
||||
<Message
|
||||
direction="incoming"
|
||||
|
|
|
@ -71,7 +71,7 @@ export type PropsData = {
|
|||
interactionMode: 'mouse' | 'keyboard';
|
||||
direction: 'incoming' | 'outgoing';
|
||||
timestamp: number;
|
||||
status?: 'sending' | 'sent' | 'delivered' | 'read' | 'error';
|
||||
status?: 'sending' | 'sent' | 'delivered' | 'read' | 'error' | 'partial-sent';
|
||||
contact?: ContactType;
|
||||
authorTitle: string;
|
||||
authorName?: string;
|
||||
|
@ -381,6 +381,71 @@ export class Message extends React.PureComponent<Props, State> {
|
|||
}
|
||||
}
|
||||
|
||||
public renderTimestamp() {
|
||||
const {
|
||||
direction,
|
||||
i18n,
|
||||
id,
|
||||
isSticker,
|
||||
isTapToViewExpired,
|
||||
showMessageDetail,
|
||||
status,
|
||||
text,
|
||||
timestamp,
|
||||
} = this.props;
|
||||
|
||||
const isShowingImage = this.isShowingImage();
|
||||
const withImageNoCaption = Boolean(!isSticker && !text && isShowingImage);
|
||||
|
||||
const isError = status === 'error' && direction === 'outgoing';
|
||||
const isPartiallySent =
|
||||
status === 'partial-sent' && direction === 'outgoing';
|
||||
|
||||
if (isError || isPartiallySent) {
|
||||
return (
|
||||
<span
|
||||
className={classNames({
|
||||
'module-message__metadata__date': true,
|
||||
'module-message__metadata__date--with-sticker': isSticker,
|
||||
[`module-message__metadata__date--${direction}`]: !isSticker,
|
||||
'module-message__metadata__date--with-image-no-caption': withImageNoCaption,
|
||||
})}
|
||||
>
|
||||
{isError ? (
|
||||
i18n('sendFailed')
|
||||
) : (
|
||||
<button
|
||||
className="module-message__metadata__tapable"
|
||||
onClick={(event: React.MouseEvent) => {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
|
||||
showMessageDetail(id);
|
||||
}}
|
||||
>
|
||||
{i18n('partiallySent')}
|
||||
</button>
|
||||
)}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
const metadataDirection = isSticker ? undefined : direction;
|
||||
|
||||
return (
|
||||
<Timestamp
|
||||
i18n={i18n}
|
||||
timestamp={timestamp}
|
||||
extended={true}
|
||||
direction={metadataDirection}
|
||||
withImageNoCaption={withImageNoCaption}
|
||||
withSticker={isSticker}
|
||||
withTapToViewExpired={isTapToViewExpired}
|
||||
module="module-message__metadata__date"
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
// tslint:disable-next-line cyclomatic-complexity
|
||||
public renderMetadata() {
|
||||
const {
|
||||
|
@ -388,14 +453,12 @@ export class Message extends React.PureComponent<Props, State> {
|
|||
direction,
|
||||
expirationLength,
|
||||
expirationTimestamp,
|
||||
i18n,
|
||||
isSticker,
|
||||
isTapToViewExpired,
|
||||
reactions,
|
||||
status,
|
||||
text,
|
||||
textPending,
|
||||
timestamp,
|
||||
} = this.props;
|
||||
|
||||
if (collapseMetadata) {
|
||||
|
@ -405,7 +468,6 @@ export class Message extends React.PureComponent<Props, State> {
|
|||
const isShowingImage = this.isShowingImage();
|
||||
const withImageNoCaption = Boolean(!isSticker && !text && isShowingImage);
|
||||
const withReactions = reactions && reactions.length > 0;
|
||||
const showError = status === 'error' && direction === 'outgoing';
|
||||
const metadataDirection = isSticker ? undefined : direction;
|
||||
|
||||
return (
|
||||
|
@ -419,33 +481,7 @@ export class Message extends React.PureComponent<Props, State> {
|
|||
: null
|
||||
)}
|
||||
>
|
||||
{showError ? (
|
||||
<span
|
||||
className={classNames(
|
||||
'module-message__metadata__date',
|
||||
isSticker ? 'module-message__metadata__date--with-sticker' : null,
|
||||
!isSticker
|
||||
? `module-message__metadata__date--${direction}`
|
||||
: null,
|
||||
withImageNoCaption
|
||||
? 'module-message__metadata__date--with-image-no-caption'
|
||||
: null
|
||||
)}
|
||||
>
|
||||
{i18n('sendFailed')}
|
||||
</span>
|
||||
) : (
|
||||
<Timestamp
|
||||
i18n={i18n}
|
||||
timestamp={timestamp}
|
||||
extended={true}
|
||||
direction={metadataDirection}
|
||||
withImageNoCaption={withImageNoCaption}
|
||||
withSticker={isSticker}
|
||||
withTapToViewExpired={isTapToViewExpired}
|
||||
module="module-message__metadata__date"
|
||||
/>
|
||||
)}
|
||||
{this.renderTimestamp()}
|
||||
{expirationLength && expirationTimestamp ? (
|
||||
<ExpireTimer
|
||||
direction={metadataDirection}
|
||||
|
@ -461,7 +497,10 @@ export class Message extends React.PureComponent<Props, State> {
|
|||
<Spinner svgSize="small" size="14px" direction={direction} />
|
||||
</div>
|
||||
) : null}
|
||||
{!textPending && direction === 'outgoing' && status !== 'error' ? (
|
||||
{!textPending &&
|
||||
direction === 'outgoing' &&
|
||||
status !== 'error' &&
|
||||
status !== 'partial-sent' ? (
|
||||
<div
|
||||
className={classNames(
|
||||
'module-message__metadata__status-icon',
|
||||
|
@ -1001,7 +1040,7 @@ export class Message extends React.PureComponent<Props, State> {
|
|||
public renderError(isCorrectSide: boolean) {
|
||||
const { status, direction } = this.props;
|
||||
|
||||
if (!isCorrectSide || status !== 'error') {
|
||||
if (!isCorrectSide || (status !== 'error' && status !== 'partial-sent')) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
@ -38,7 +38,13 @@ export type ConversationType = {
|
|||
timestamp?: number;
|
||||
inboxPosition?: number;
|
||||
lastMessage?: {
|
||||
status: 'error' | 'sending' | 'sent' | 'delivered' | 'read';
|
||||
status:
|
||||
| 'error'
|
||||
| 'partial-sent'
|
||||
| 'sending'
|
||||
| 'sent'
|
||||
| 'delivered'
|
||||
| 'read';
|
||||
text: string;
|
||||
};
|
||||
phoneNumber?: string;
|
||||
|
|
Loading…
Reference in a new issue