New message state: Partially sent

This commit is contained in:
Josh Perez 2020-08-06 21:22:52 -04:00 committed by GitHub
parent 81cb7730a5
commit 6a68b37c83
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 185 additions and 38 deletions

View file

@ -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"

View file

@ -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';
}

View file

@ -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',

View file

@ -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>
```

View file

@ -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;
};

View file

@ -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"

View file

@ -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;
}

View file

@ -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;