Migrate MessageDetail to Storybook
This commit is contained in:
parent
f8fc23a7a3
commit
bcd4f6407f
5 changed files with 237 additions and 178 deletions
|
@ -61,7 +61,7 @@ interface LinkPreviewType {
|
||||||
image?: AttachmentType;
|
image?: AttachmentType;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const Statuses = [
|
export const MessageStatuses = [
|
||||||
'delivered',
|
'delivered',
|
||||||
'error',
|
'error',
|
||||||
'partial-sent',
|
'partial-sent',
|
||||||
|
@ -69,6 +69,16 @@ export const Statuses = [
|
||||||
'sending',
|
'sending',
|
||||||
'sent',
|
'sent',
|
||||||
] as const;
|
] as const;
|
||||||
|
export type MessageStatusType = typeof MessageStatuses[number];
|
||||||
|
|
||||||
|
export const InteractionModes = ['mouse', 'keyboard'] as const;
|
||||||
|
export type InteractionModeType = typeof InteractionModes[number];
|
||||||
|
|
||||||
|
export const Directions = ['incoming', 'outgoing'] as const;
|
||||||
|
export type DirectionType = typeof Directions[number];
|
||||||
|
|
||||||
|
export const ConversationTypes = ['direct', 'group'] as const;
|
||||||
|
export type ConversationTypesType = typeof ConversationTypes[number];
|
||||||
|
|
||||||
export type PropsData = {
|
export type PropsData = {
|
||||||
id: string;
|
id: string;
|
||||||
|
@ -78,17 +88,17 @@ export type PropsData = {
|
||||||
isSticker?: boolean;
|
isSticker?: boolean;
|
||||||
isSelected?: boolean;
|
isSelected?: boolean;
|
||||||
isSelectedCounter?: number;
|
isSelectedCounter?: number;
|
||||||
interactionMode: 'mouse' | 'keyboard';
|
interactionMode: InteractionModeType;
|
||||||
direction: 'incoming' | 'outgoing';
|
direction: DirectionType;
|
||||||
timestamp: number;
|
timestamp: number;
|
||||||
status?: typeof Statuses[number];
|
status?: MessageStatusType;
|
||||||
contact?: ContactType;
|
contact?: ContactType;
|
||||||
authorTitle: string;
|
authorTitle: string;
|
||||||
authorName?: string;
|
authorName?: string;
|
||||||
authorProfileName?: string;
|
authorProfileName?: string;
|
||||||
authorPhoneNumber?: string;
|
authorPhoneNumber?: string;
|
||||||
authorColor?: ColorType;
|
authorColor?: ColorType;
|
||||||
conversationType: 'group' | 'direct';
|
conversationType: ConversationTypesType;
|
||||||
attachments?: Array<AttachmentType>;
|
attachments?: Array<AttachmentType>;
|
||||||
quote?: {
|
quote?: {
|
||||||
text: string;
|
text: string;
|
||||||
|
|
|
@ -1,166 +0,0 @@
|
||||||
### Incoming message
|
|
||||||
|
|
||||||
```jsx
|
|
||||||
<MessageDetail
|
|
||||||
message={{
|
|
||||||
disableMenu: true,
|
|
||||||
direction: 'incoming',
|
|
||||||
timestamp: Date.now(),
|
|
||||||
authorColor: 'pink',
|
|
||||||
text:
|
|
||||||
'Hello there from the new world! And this is multiple lines of text. Lines and lines and lines.',
|
|
||||||
onDelete: () => console.log('onDelete'),
|
|
||||||
}}
|
|
||||||
sentAt={Date.now() - 2 * 60 * 1000}
|
|
||||||
receivedAt={Date.now() - 10 * 1000}
|
|
||||||
contacts={[
|
|
||||||
{
|
|
||||||
phoneNumber: '(202) 555-1001',
|
|
||||||
avatarPath: util.gifObjectUrl,
|
|
||||||
},
|
|
||||||
]}
|
|
||||||
i18n={util.i18n}
|
|
||||||
/>
|
|
||||||
```
|
|
||||||
|
|
||||||
### Message to group, multiple contacts
|
|
||||||
|
|
||||||
```jsx
|
|
||||||
<MessageDetail
|
|
||||||
message={{
|
|
||||||
disableMenu: true,
|
|
||||||
direction: 'outgoing',
|
|
||||||
timestamp: Date.now(),
|
|
||||||
authorColor: 'pink',
|
|
||||||
text:
|
|
||||||
'Hello there from the new world! And this is multiple lines of text. Lines and lines and lines.',
|
|
||||||
status: 'read',
|
|
||||||
onDelete: () => console.log('onDelete'),
|
|
||||||
}}
|
|
||||||
sentAt={Date.now()}
|
|
||||||
contacts={[
|
|
||||||
{
|
|
||||||
phoneNumber: '(202) 555-1001',
|
|
||||||
profileName: 'Mr. Fire',
|
|
||||||
avatarPath: util.gifObjectUrl,
|
|
||||||
status: 'sending',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
phoneNumber: '(202) 555-1002',
|
|
||||||
avatarPath: util.pngObjectUrl,
|
|
||||||
status: 'delivered',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
phoneNumber: '(202) 555-1003',
|
|
||||||
color: 'teal',
|
|
||||||
status: 'read',
|
|
||||||
},
|
|
||||||
]}
|
|
||||||
i18n={util.i18n}
|
|
||||||
/>
|
|
||||||
```
|
|
||||||
|
|
||||||
### 1:1 conversation, just one recipient
|
|
||||||
|
|
||||||
```jsx
|
|
||||||
<MessageDetail
|
|
||||||
message={{
|
|
||||||
disableMenu: true,
|
|
||||||
direction: 'outgoing',
|
|
||||||
timestamp: Date.now(),
|
|
||||||
authorColor: 'pink',
|
|
||||||
text:
|
|
||||||
'Hello there from the new world! And this is multiple lines of text. Lines and lines and lines.',
|
|
||||||
status: 'sending',
|
|
||||||
onDelete: () => console.log('onDelete'),
|
|
||||||
}}
|
|
||||||
contacts={[
|
|
||||||
{
|
|
||||||
phoneNumber: '(202) 555-1001',
|
|
||||||
avatarPath: util.gifObjectUrl,
|
|
||||||
status: 'sending',
|
|
||||||
},
|
|
||||||
]}
|
|
||||||
sentAt={Date.now()}
|
|
||||||
i18n={util.i18n}
|
|
||||||
/>
|
|
||||||
```
|
|
||||||
|
|
||||||
### Errors for some users, including on OutgoingKeyError
|
|
||||||
|
|
||||||
```jsx
|
|
||||||
<MessageDetail
|
|
||||||
message={{
|
|
||||||
disableMenu: true,
|
|
||||||
direction: 'outgoing',
|
|
||||||
timestamp: Date.now(),
|
|
||||||
authorColor: 'pink',
|
|
||||||
text:
|
|
||||||
'Hello there from the new world! And this is multiple lines of text. Lines and lines and lines.',
|
|
||||||
status: 'error',
|
|
||||||
onDelete: () => console.log('onDelete'),
|
|
||||||
}}
|
|
||||||
contacts={[
|
|
||||||
{
|
|
||||||
phoneNumber: '(202) 555-1001',
|
|
||||||
avatarPath: util.gifObjectUrl,
|
|
||||||
status: 'error',
|
|
||||||
errors: [new Error('Something went wrong'), new Error('Bad things')],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
phoneNumber: '(202) 555-1002',
|
|
||||||
avatarPath: util.pngObjectUrl,
|
|
||||||
status: 'error',
|
|
||||||
isOutgoingKeyError: true,
|
|
||||||
errors: [new Error(util.i18n('newIdentity'))],
|
|
||||||
onShowSafetyNumber: () => console.log('onShowSafetyNumber'),
|
|
||||||
onSendAnyway: () => console.log('onSendAnyway'),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
phoneNumber: '(202) 555-1003',
|
|
||||||
color: 'teal',
|
|
||||||
status: 'read',
|
|
||||||
},
|
|
||||||
]}
|
|
||||||
sentAt={Date.now()}
|
|
||||||
i18n={util.i18n}
|
|
||||||
/>
|
|
||||||
```
|
|
||||||
|
|
||||||
### Unidentified Delivery
|
|
||||||
|
|
||||||
```jsx
|
|
||||||
<MessageDetail
|
|
||||||
message={{
|
|
||||||
disableMenu: true,
|
|
||||||
direction: 'outgoing',
|
|
||||||
timestamp: Date.now(),
|
|
||||||
conversationColor: 'pink',
|
|
||||||
text:
|
|
||||||
'Hello there from the new world! And this is multiple lines of text. Lines and lines and lines.',
|
|
||||||
status: 'read',
|
|
||||||
onDelete: () => console.log('onDelete'),
|
|
||||||
}}
|
|
||||||
contacts={[
|
|
||||||
{
|
|
||||||
phoneNumber: '(202) 555-1001',
|
|
||||||
avatarPath: util.gifObjectUrl,
|
|
||||||
status: 'read',
|
|
||||||
isUnidentifiedDelivery: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
phoneNumber: '(202) 555-1002',
|
|
||||||
avatarPath: util.pngObjectUrl,
|
|
||||||
status: 'delivered',
|
|
||||||
isUnidentifiedDelivery: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
phoneNumber: '(202) 555-1003',
|
|
||||||
color: 'teal',
|
|
||||||
status: 'read',
|
|
||||||
},
|
|
||||||
]}
|
|
||||||
sentAt={Date.now()}
|
|
||||||
i18n={util.i18n}
|
|
||||||
/>
|
|
||||||
```
|
|
215
ts/components/conversation/MessageDetail.stories.tsx
Normal file
215
ts/components/conversation/MessageDetail.stories.tsx
Normal file
|
@ -0,0 +1,215 @@
|
||||||
|
import * as React from 'react';
|
||||||
|
|
||||||
|
import { action } from '@storybook/addon-actions';
|
||||||
|
import { number } from '@storybook/addon-knobs';
|
||||||
|
import { storiesOf } from '@storybook/react';
|
||||||
|
|
||||||
|
import { Props as MessageProps } from './Message';
|
||||||
|
import { MessageDetail, Props } from './MessageDetail';
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
import { setup as setupI18n } from '../../../js/modules/i18n';
|
||||||
|
// @ts-ignore
|
||||||
|
import enMessages from '../../../_locales/en/messages.json';
|
||||||
|
const i18n = setupI18n('en', enMessages);
|
||||||
|
|
||||||
|
const story = storiesOf('Components/Conversation/MessageDetail', module);
|
||||||
|
|
||||||
|
const defaultMessage: MessageProps = {
|
||||||
|
authorTitle: 'Max',
|
||||||
|
canReply: true,
|
||||||
|
clearSelectedMessage: () => null,
|
||||||
|
conversationId: 'my-convo',
|
||||||
|
conversationType: 'direct',
|
||||||
|
deleteMessage: action('deleteMessage'),
|
||||||
|
direction: 'incoming',
|
||||||
|
displayTapToViewMessage: () => null,
|
||||||
|
downloadAttachment: () => null,
|
||||||
|
i18n,
|
||||||
|
id: 'my-message',
|
||||||
|
interactionMode: 'keyboard',
|
||||||
|
openConversation: () => null,
|
||||||
|
openLink: () => null,
|
||||||
|
previews: [],
|
||||||
|
reactToMessage: () => null,
|
||||||
|
renderEmojiPicker: () => <div />,
|
||||||
|
replyToMessage: () => null,
|
||||||
|
retrySend: () => null,
|
||||||
|
scrollToQuotedMessage: () => null,
|
||||||
|
showContactDetail: () => null,
|
||||||
|
showExpiredIncomingTapToViewToast: () => null,
|
||||||
|
showExpiredOutgoingTapToViewToast: () => null,
|
||||||
|
showMessageDetail: () => null,
|
||||||
|
showVisualAttachment: () => null,
|
||||||
|
status: 'sent',
|
||||||
|
text: 'A message from Max',
|
||||||
|
timestamp: Date.now(),
|
||||||
|
};
|
||||||
|
|
||||||
|
const createProps = (overrideProps: Partial<Props> = {}): Props => ({
|
||||||
|
contacts: overrideProps.contacts || [
|
||||||
|
{
|
||||||
|
color: 'green',
|
||||||
|
isOutgoingKeyError: false,
|
||||||
|
isUnidentifiedDelivery: false,
|
||||||
|
onSendAnyway: action('onSendAnyway'),
|
||||||
|
onShowSafetyNumber: action('onShowSafetyNumber'),
|
||||||
|
status: 'delivered',
|
||||||
|
title: 'Just Max',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
errors: overrideProps.errors || [],
|
||||||
|
i18n,
|
||||||
|
message: overrideProps.message || defaultMessage,
|
||||||
|
receivedAt: number('receivedAt', overrideProps.receivedAt || Date.now()),
|
||||||
|
sentAt: number('sentAt', overrideProps.sentAt || Date.now()),
|
||||||
|
});
|
||||||
|
|
||||||
|
story.add('Delivered Incoming', () => {
|
||||||
|
const props = createProps({});
|
||||||
|
return <MessageDetail {...props} />;
|
||||||
|
});
|
||||||
|
|
||||||
|
story.add('Delivered Outgoing', () => {
|
||||||
|
const props = createProps({
|
||||||
|
message: {
|
||||||
|
...defaultMessage,
|
||||||
|
direction: 'outgoing',
|
||||||
|
text: 'A message to Max',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
return <MessageDetail {...props} />;
|
||||||
|
});
|
||||||
|
|
||||||
|
story.add('Message Statuses', () => {
|
||||||
|
const props = createProps({
|
||||||
|
contacts: [
|
||||||
|
{
|
||||||
|
color: 'green',
|
||||||
|
isOutgoingKeyError: false,
|
||||||
|
isUnidentifiedDelivery: false,
|
||||||
|
onSendAnyway: action('onSendAnyway'),
|
||||||
|
onShowSafetyNumber: action('onShowSafetyNumber'),
|
||||||
|
status: 'sent',
|
||||||
|
title: 'Max',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color: 'blue',
|
||||||
|
isOutgoingKeyError: false,
|
||||||
|
isUnidentifiedDelivery: false,
|
||||||
|
onSendAnyway: action('onSendAnyway'),
|
||||||
|
onShowSafetyNumber: action('onShowSafetyNumber'),
|
||||||
|
status: 'sending',
|
||||||
|
title: 'Sally',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color: 'brown',
|
||||||
|
isOutgoingKeyError: false,
|
||||||
|
isUnidentifiedDelivery: false,
|
||||||
|
onSendAnyway: action('onSendAnyway'),
|
||||||
|
onShowSafetyNumber: action('onShowSafetyNumber'),
|
||||||
|
status: 'partial-sent',
|
||||||
|
title: 'Terry',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color: 'light_green',
|
||||||
|
isOutgoingKeyError: false,
|
||||||
|
isUnidentifiedDelivery: false,
|
||||||
|
onSendAnyway: action('onSendAnyway'),
|
||||||
|
onShowSafetyNumber: action('onShowSafetyNumber'),
|
||||||
|
status: 'delivered',
|
||||||
|
title: 'Theo',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color: 'blue_grey',
|
||||||
|
isOutgoingKeyError: false,
|
||||||
|
isUnidentifiedDelivery: false,
|
||||||
|
onSendAnyway: action('onSendAnyway'),
|
||||||
|
onShowSafetyNumber: action('onShowSafetyNumber'),
|
||||||
|
status: 'read',
|
||||||
|
title: 'Nikki',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
message: {
|
||||||
|
...defaultMessage,
|
||||||
|
conversationType: 'group',
|
||||||
|
text: 'A message to you all!',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
return <MessageDetail {...props} />;
|
||||||
|
});
|
||||||
|
|
||||||
|
story.add('Not Delivered', () => {
|
||||||
|
const props = createProps({
|
||||||
|
message: {
|
||||||
|
...defaultMessage,
|
||||||
|
direction: 'outgoing',
|
||||||
|
text: 'A message to Max',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
props.receivedAt = undefined as any;
|
||||||
|
|
||||||
|
return <MessageDetail {...props} />;
|
||||||
|
});
|
||||||
|
|
||||||
|
story.add('No Contacts', () => {
|
||||||
|
const props = createProps({
|
||||||
|
contacts: [],
|
||||||
|
message: {
|
||||||
|
...defaultMessage,
|
||||||
|
direction: 'outgoing',
|
||||||
|
text: 'Is anybody there?',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
return <MessageDetail {...props} />;
|
||||||
|
});
|
||||||
|
|
||||||
|
story.add('All Errors', () => {
|
||||||
|
const props = createProps({
|
||||||
|
errors: [
|
||||||
|
{
|
||||||
|
name: 'Another Error',
|
||||||
|
message: 'Wow, that went bad.',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
message: {
|
||||||
|
...defaultMessage,
|
||||||
|
},
|
||||||
|
contacts: [
|
||||||
|
{
|
||||||
|
color: 'green',
|
||||||
|
isOutgoingKeyError: true,
|
||||||
|
isUnidentifiedDelivery: false,
|
||||||
|
onSendAnyway: action('onSendAnyway'),
|
||||||
|
onShowSafetyNumber: action('onShowSafetyNumber'),
|
||||||
|
status: 'error',
|
||||||
|
title: 'Max',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color: 'blue',
|
||||||
|
errors: [
|
||||||
|
{
|
||||||
|
name: 'Big Error',
|
||||||
|
message: 'Stuff happened, in a bad way.',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
isOutgoingKeyError: false,
|
||||||
|
isUnidentifiedDelivery: true,
|
||||||
|
onSendAnyway: action('onSendAnyway'),
|
||||||
|
onShowSafetyNumber: action('onShowSafetyNumber'),
|
||||||
|
status: 'error',
|
||||||
|
title: 'Sally',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color: 'brown',
|
||||||
|
isOutgoingKeyError: true,
|
||||||
|
isUnidentifiedDelivery: true,
|
||||||
|
onSendAnyway: action('onSendAnyway'),
|
||||||
|
onShowSafetyNumber: action('onShowSafetyNumber'),
|
||||||
|
status: 'error',
|
||||||
|
title: 'Terry',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
return <MessageDetail {...props} />;
|
||||||
|
});
|
|
@ -4,12 +4,12 @@ import moment from 'moment';
|
||||||
|
|
||||||
import { Avatar } from '../Avatar';
|
import { Avatar } from '../Avatar';
|
||||||
import { ContactName } from './ContactName';
|
import { ContactName } from './ContactName';
|
||||||
import { Message, Props as MessageProps } from './Message';
|
import { Message, MessageStatusType, Props as MessageProps } from './Message';
|
||||||
import { LocalizerType } from '../../types/Util';
|
import { LocalizerType } from '../../types/Util';
|
||||||
import { ColorType } from '../../types/Colors';
|
import { ColorType } from '../../types/Colors';
|
||||||
|
|
||||||
interface Contact {
|
interface Contact {
|
||||||
status: string;
|
status: MessageStatusType;
|
||||||
|
|
||||||
title: string;
|
title: string;
|
||||||
phoneNumber?: string;
|
phoneNumber?: string;
|
||||||
|
@ -26,7 +26,7 @@ interface Contact {
|
||||||
onShowSafetyNumber: () => void;
|
onShowSafetyNumber: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Props {
|
export interface Props {
|
||||||
sentAt: number;
|
sentAt: number;
|
||||||
receivedAt: number;
|
receivedAt: number;
|
||||||
|
|
||||||
|
|
|
@ -11464,7 +11464,7 @@
|
||||||
"rule": "React-createRef",
|
"rule": "React-createRef",
|
||||||
"path": "ts/components/conversation/Message.js",
|
"path": "ts/components/conversation/Message.js",
|
||||||
"line": " this.audioRef = react_1.default.createRef();",
|
"line": " this.audioRef = react_1.default.createRef();",
|
||||||
"lineNumber": 54,
|
"lineNumber": 57,
|
||||||
"reasonCategory": "usageTrusted",
|
"reasonCategory": "usageTrusted",
|
||||||
"updated": "2020-01-21T15:46:51.245Z"
|
"updated": "2020-01-21T15:46:51.245Z"
|
||||||
},
|
},
|
||||||
|
@ -11472,7 +11472,7 @@
|
||||||
"rule": "React-createRef",
|
"rule": "React-createRef",
|
||||||
"path": "ts/components/conversation/Message.js",
|
"path": "ts/components/conversation/Message.js",
|
||||||
"line": " this.reactionsContainerRef = react_1.default.createRef();",
|
"line": " this.reactionsContainerRef = react_1.default.createRef();",
|
||||||
"lineNumber": 56,
|
"lineNumber": 59,
|
||||||
"reasonCategory": "usageTrusted",
|
"reasonCategory": "usageTrusted",
|
||||||
"updated": "2020-01-21T15:46:51.245Z",
|
"updated": "2020-01-21T15:46:51.245Z",
|
||||||
"reasonDetail": "Used for detecting clicks outside reaction viewer"
|
"reasonDetail": "Used for detecting clicks outside reaction viewer"
|
||||||
|
@ -11481,7 +11481,7 @@
|
||||||
"rule": "React-createRef",
|
"rule": "React-createRef",
|
||||||
"path": "ts/components/conversation/Message.tsx",
|
"path": "ts/components/conversation/Message.tsx",
|
||||||
"line": " public audioRef: React.RefObject<HTMLAudioElement> = React.createRef();",
|
"line": " public audioRef: React.RefObject<HTMLAudioElement> = React.createRef();",
|
||||||
"lineNumber": 195,
|
"lineNumber": 205,
|
||||||
"reasonCategory": "usageTrusted",
|
"reasonCategory": "usageTrusted",
|
||||||
"updated": "2020-05-21T16:56:07.875Z"
|
"updated": "2020-05-21T16:56:07.875Z"
|
||||||
},
|
},
|
||||||
|
@ -11489,7 +11489,7 @@
|
||||||
"rule": "React-createRef",
|
"rule": "React-createRef",
|
||||||
"path": "ts/components/conversation/Message.tsx",
|
"path": "ts/components/conversation/Message.tsx",
|
||||||
"line": " > = React.createRef();",
|
"line": " > = React.createRef();",
|
||||||
"lineNumber": 199,
|
"lineNumber": 209,
|
||||||
"reasonCategory": "usageTrusted",
|
"reasonCategory": "usageTrusted",
|
||||||
"updated": "2020-05-21T16:56:07.875Z"
|
"updated": "2020-05-21T16:56:07.875Z"
|
||||||
},
|
},
|
||||||
|
|
Loading…
Add table
Reference in a new issue