// Copyright 2020-2021 Signal Messenger, LLC // SPDX-License-Identifier: AGPL-3.0-only import * as React from 'react'; import { isString } from 'lodash'; import { action } from '@storybook/addon-actions'; import { boolean, text } from '@storybook/addon-knobs'; import { storiesOf } from '@storybook/react'; import { ConversationColors } from '../../types/Colors'; import { pngUrl } from '../../storybook/Fixtures'; import { Message, Props as MessagesProps } from './Message'; import { AUDIO_MP3, IMAGE_PNG, LONG_MESSAGE, MIMEType, VIDEO_MP4, } from '../../types/MIME'; import { Props, Quote } from './Quote'; import { setup as setupI18n } from '../../../js/modules/i18n'; import enMessages from '../../../_locales/en/messages.json'; import { getDefaultConversation } from '../../test-both/helpers/getDefaultConversation'; const i18n = setupI18n('en', enMessages); const story = storiesOf('Components/Conversation/Quote', module); const defaultMessageProps: MessagesProps = { author: getDefaultConversation({ id: 'some-id', title: 'Person X', }), canReply: true, canDeleteForEveryone: true, canDownload: true, clearSelectedMessage: () => null, conversationColor: 'crimson', conversationId: 'conversationId', conversationType: 'direct', // override deleteMessage: () => null, deleteMessageForEveryone: () => null, direction: 'incoming', displayTapToViewMessage: () => null, downloadAttachment: () => null, i18n, id: 'messageId', interactionMode: 'keyboard', isBlocked: false, isMessageRequestAccepted: true, kickOffAttachmentDownload: () => null, markAttachmentAsCorrupted: () => null, openConversation: () => null, openLink: () => null, previews: [], reactToMessage: () => null, renderEmojiPicker: () =>
, renderAudioAttachment: () =>
*AudioAttachment*
, replyToMessage: () => null, retrySend: () => null, scrollToQuotedMessage: () => null, selectMessage: () => null, showContactDetail: () => null, showContactModal: () => null, showExpiredIncomingTapToViewToast: () => null, showExpiredOutgoingTapToViewToast: () => null, showForwardMessageModal: () => null, showMessageDetail: () => null, showVisualAttachment: () => null, status: 'sent', text: 'This is really interesting.', timestamp: Date.now(), }; const renderInMessage = ({ authorName, authorPhoneNumber, authorProfileName, authorTitle, conversationColor, isFromMe, rawAttachment, isViewOnce, referencedMessageNotFound, text: quoteText, }: Props) => { const messageProps = { ...defaultMessageProps, conversationColor, quote: { authorId: 'an-author', authorName, authorPhoneNumber, authorProfileName, authorTitle, conversationColor, isFromMe, rawAttachment, isViewOnce, referencedMessageNotFound, sentAt: Date.now() - 30 * 1000, text: quoteText, }, }; return (

); }; const createProps = (overrideProps: Partial = {}): Props => ({ authorName: text('authorName', overrideProps.authorName || ''), authorPhoneNumber: text( 'authorPhoneNumber', overrideProps.authorPhoneNumber || '' ), authorProfileName: text( 'authorProfileName', overrideProps.authorProfileName || '' ), authorTitle: text('authorTitle', overrideProps.authorTitle || ''), conversationColor: overrideProps.conversationColor || 'forest', i18n, isFromMe: boolean('isFromMe', overrideProps.isFromMe || false), isIncoming: boolean('isIncoming', overrideProps.isIncoming || false), onClick: action('onClick'), onClose: action('onClose'), rawAttachment: overrideProps.rawAttachment || undefined, referencedMessageNotFound: boolean( 'referencedMessageNotFound', overrideProps.referencedMessageNotFound || false ), isViewOnce: boolean('isViewOnce', overrideProps.isViewOnce || false), text: text( 'text', isString(overrideProps.text) ? overrideProps.text : 'A sample message from a pal' ), withContentAbove: boolean( 'withContentAbove', overrideProps.withContentAbove || false ), }); story.add('Outgoing by Another Author', () => { const props = createProps({ authorTitle: 'Terrence Malick', }); return ; }); story.add('Outgoing by Me', () => { const props = createProps({ isFromMe: true, }); return ; }); story.add('Incoming by Another Author', () => { const props = createProps({ authorTitle: 'Terrence Malick', isIncoming: true, }); return ; }); story.add('Incoming by Me', () => { const props = createProps({ isFromMe: true, isIncoming: true, }); return ; }); story.add('Incoming/Outgoing Colors', () => { const props = createProps({}); return ( <> {ConversationColors.map(color => renderInMessage({ ...props, conversationColor: color }) )} ); }); story.add('Content Above', () => { const props = createProps({ withContentAbove: true, }); return ( <>
Content Above
); }); story.add('Image Only', () => { const props = createProps({ text: '', rawAttachment: { contentType: IMAGE_PNG, fileName: 'sax.png', isVoiceMessage: false, thumbnail: { contentType: IMAGE_PNG, objectUrl: pngUrl, }, }, }); return ; }); story.add('Image Attachment', () => { const props = createProps({ rawAttachment: { contentType: IMAGE_PNG, fileName: 'sax.png', isVoiceMessage: false, thumbnail: { contentType: IMAGE_PNG, objectUrl: pngUrl, }, }, }); return ; }); story.add('Image Attachment w/o Thumbnail', () => { const props = createProps({ rawAttachment: { contentType: IMAGE_PNG, fileName: 'sax.png', isVoiceMessage: false, }, }); return ; }); story.add('Image Tap-to-View', () => { const props = createProps({ text: '', isViewOnce: true, rawAttachment: { contentType: IMAGE_PNG, fileName: 'sax.png', isVoiceMessage: false, }, }); return ; }); story.add('Video Only', () => { const props = createProps({ rawAttachment: { contentType: VIDEO_MP4, fileName: 'great-video.mp4', isVoiceMessage: false, thumbnail: { contentType: IMAGE_PNG, objectUrl: pngUrl, }, }, }); // eslint-disable-next-line @typescript-eslint/no-explicit-any props.text = undefined as any; return ; }); story.add('Video Attachment', () => { const props = createProps({ rawAttachment: { contentType: VIDEO_MP4, fileName: 'great-video.mp4', isVoiceMessage: false, thumbnail: { contentType: IMAGE_PNG, objectUrl: pngUrl, }, }, }); return ; }); story.add('Video Attachment w/o Thumbnail', () => { const props = createProps({ rawAttachment: { contentType: VIDEO_MP4, fileName: 'great-video.mp4', isVoiceMessage: false, }, }); return ; }); story.add('Video Tap-to-View', () => { const props = createProps({ text: '', isViewOnce: true, rawAttachment: { contentType: VIDEO_MP4, fileName: 'great-video.mp4', isVoiceMessage: false, }, }); return ; }); story.add('Audio Only', () => { const props = createProps({ rawAttachment: { contentType: AUDIO_MP3, fileName: 'great-video.mp3', isVoiceMessage: false, }, }); // eslint-disable-next-line @typescript-eslint/no-explicit-any props.text = undefined as any; return ; }); story.add('Audio Attachment', () => { const props = createProps({ rawAttachment: { contentType: AUDIO_MP3, fileName: 'great-video.mp3', isVoiceMessage: false, }, }); return ; }); story.add('Voice Message Only', () => { const props = createProps({ rawAttachment: { contentType: AUDIO_MP3, fileName: 'great-video.mp3', isVoiceMessage: true, }, }); // eslint-disable-next-line @typescript-eslint/no-explicit-any props.text = undefined as any; return ; }); story.add('Voice Message Attachment', () => { const props = createProps({ rawAttachment: { contentType: AUDIO_MP3, fileName: 'great-video.mp3', isVoiceMessage: true, }, }); return ; }); story.add('Other File Only', () => { const props = createProps({ rawAttachment: { contentType: 'application/json' as MIMEType, fileName: 'great-data.json', isVoiceMessage: false, }, }); // eslint-disable-next-line @typescript-eslint/no-explicit-any props.text = undefined as any; return ; }); story.add('Media Tap-to-View', () => { const props = createProps({ text: '', isViewOnce: true, rawAttachment: { contentType: AUDIO_MP3, fileName: 'great-video.mp3', isVoiceMessage: false, }, }); return ; }); story.add('Other File Attachment', () => { const props = createProps({ rawAttachment: { contentType: 'application/json' as MIMEType, fileName: 'great-data.json', isVoiceMessage: false, }, }); return ; }); story.add('Long message attachment (should be hidden)', () => { const props = createProps({ rawAttachment: { contentType: LONG_MESSAGE, fileName: 'signal-long-message-123.txt', isVoiceMessage: false, }, }); return ; }); story.add('No Close Button', () => { const props = createProps(); props.onClose = undefined; return ; }); story.add('Message Not Found', () => { const props = createProps({ referencedMessageNotFound: true, }); return renderInMessage(props); }); story.add('Missing Text & Attachment', () => { const props = createProps(); // eslint-disable-next-line @typescript-eslint/no-explicit-any props.text = undefined as any; return ; }); story.add('@mention + outgoing + another author', () => { const props = createProps({ authorTitle: 'Tony Stark', text: '@Captain America Lunch later?', }); return ; }); story.add('@mention + outgoing + me', () => { const props = createProps({ isFromMe: true, text: '@Captain America Lunch later?', }); return ; }); story.add('@mention + incoming + another author', () => { const props = createProps({ authorTitle: 'Captain America', isIncoming: true, text: '@Tony Stark sure', }); return ; }); story.add('@mention + incoming + me', () => { const props = createProps({ isFromMe: true, isIncoming: true, text: '@Tony Stark sure', }); return ; }); story.add('Custom Color', () => ( <> ));