diff --git a/.babelrc.js b/.babelrc.js
index 0bf885695d82..315ad1ac0253 100644
--- a/.babelrc.js
+++ b/.babelrc.js
@@ -1,8 +1,15 @@
module.exports = {
presets: ['@babel/preset-react', '@babel/preset-typescript'],
+ // Detects the type of file being babel'd (either esmodule or commonjs)
+ sourceType: 'unambiguous',
plugins: [
'react-hot-loader/babel',
'lodash',
'@babel/plugin-proposal-class-properties',
- ],
+ // This plugin converts commonjs to esmodules which is required for
+ // importing commonjs modules from esmodules in storybook. As a part of
+ // converting to TypeScript we should use esmodules and can eventually
+ // remove this plugin
+ process.env.SIGNAL_ENV === 'storybook' && '@babel/transform-runtime',
+ ].filter(Boolean),
};
diff --git a/.storybook/config.js b/.storybook/config.js
index 9bd434504d35..05965ae38dd2 100644
--- a/.storybook/config.js
+++ b/.storybook/config.js
@@ -1,27 +1,83 @@
import * as React from 'react';
import { addDecorator, configure } from '@storybook/react';
-import { withKnobs } from '@storybook/addon-knobs';
+import { withKnobs, boolean, optionsKnob } from '@storybook/addon-knobs';
import classnames from 'classnames';
import * as styles from './styles.scss';
import messages from '../_locales/en/messages.json';
import { I18n } from '../sticker-creator/util/i18n';
-import { ThemedProvider } from '../ts/components/PopperRootContext';
+import { ClassyProvider } from '../ts/components/PopperRootContext';
+
+const optionsConfig = {
+ display: 'inline-radio',
+};
+
+const makeThemeKnob = pane =>
+ optionsKnob(
+ `${pane} Pane Theme`,
+ { Light: '', Dark: classnames('dark-theme', styles.darkTheme) },
+ '',
+ optionsConfig,
+ `${pane} Pane`
+ );
+
+const makeDeviceThemeKnob = pane =>
+ optionsKnob(
+ `${pane} Pane Device Theme`,
+ { Android: '', iOS: 'ios-theme' },
+ '',
+ optionsConfig,
+ `${pane} Pane`
+ );
+
+const makeModeKnob = pane =>
+ optionsKnob(
+ `${pane} Pane Mode`,
+ { Mouse: 'mouse-mode', Keyboard: 'keyboard-mode' },
+ 'mouse-mode',
+ optionsConfig,
+ `${pane} Pane`
+ );
addDecorator(withKnobs);
addDecorator((storyFn /* , context */) => {
const contents = storyFn();
+ const firstPaneTheme = makeThemeKnob('First');
+ const firstPaneDeviceTheme = makeDeviceThemeKnob('First');
+ const firstPaneMode = makeModeKnob('First');
+
+ const secondPane = boolean('Second Pane Active', false, 'Second Pane');
+
+ const secondPaneTheme = makeThemeKnob('Second');
+ const secondPaneDeviceTheme = makeDeviceThemeKnob('Second');
+ const secondPaneMode = makeModeKnob('Second');
return (
-
{contents}
-
+
{contents}
-
+
+ {secondPane ? (
+
+ {contents}
+
+ ) : null}
);
});
@@ -39,4 +95,11 @@ configure(() => {
/\.stories\.tsx?$/
);
stickerCreatorContext.keys().forEach(f => stickerCreatorContext(f));
+ // Load main app stories
+ const tsComponentsContext = require.context(
+ '../ts/components',
+ true,
+ /\.stories.tsx?$/
+ );
+ tsComponentsContext.keys().forEach(f => tsComponentsContext(f));
}, module);
diff --git a/.storybook/preview-head.html b/.storybook/preview-head.html
index 76e0bd779b22..cb7b5c1bde86 100644
--- a/.storybook/preview-head.html
+++ b/.storybook/preview-head.html
@@ -1,2 +1,2 @@
-
+
diff --git a/.storybook/styles.scss b/.storybook/styles.scss
index 3fc8c681e7fc..58481dfcbb26 100644
--- a/.storybook/styles.scss
+++ b/.storybook/styles.scss
@@ -1,3 +1,5 @@
+@import '../stylesheets/variables';
+
.container {
display: flex;
flex-direction: row;
@@ -9,13 +11,12 @@
.panel {
flex: 1;
- display: flex;
- flex-direction: column;
- justify-content: space-around;
- align-items: center;
padding: 16px;
+ height: 100%;
+ overflow: auto;
}
.dark-theme {
- background-color: #17191d;
+ background-color: $color-gray-95;
+ color: $color-gray-05;
}
diff --git a/.storybook/webpack.config.js b/.storybook/webpack.config.js
index e4465f9da544..268602c5e0ff 100644
--- a/.storybook/webpack.config.js
+++ b/.storybook/webpack.config.js
@@ -6,8 +6,9 @@ module.exports = ({ config }) => {
config.module.rules.unshift(
{
- test: /\.tsx?$/,
+ test: /\.[jt]sx?$/,
loader: 'babel-loader',
+ exclude: /node_modules/,
},
{
test: /\.scss$/,
diff --git a/package.json b/package.json
index 8d1b20f1e177..beec2bd2a502 100644
--- a/package.json
+++ b/package.json
@@ -46,7 +46,7 @@
"dev:grunt": "yarn grunt dev",
"dev:webpack": "NODE_ENV=development webpack-dev-server --hot",
"dev:typed-scss": "yarn build:typed-scss -w",
- "dev:storybook": "start-storybook -p 6006 -s ./",
+ "dev:storybook": "SIGNAL_ENV=storybook start-storybook -p 6006 -s ./",
"build": "run-s --print-label build:grunt build:typed-scss build:webpack build:release",
"build:dev": "run-s --print-label build:grunt build:typed-scss build:webpack",
"build:grunt": "yarn grunt",
@@ -148,6 +148,7 @@
"devDependencies": {
"@babel/core": "7.7.7",
"@babel/plugin-proposal-class-properties": "7.7.4",
+ "@babel/plugin-transform-runtime": "^7.8.3",
"@babel/preset-react": "7.7.4",
"@babel/preset-typescript": "7.7.7",
"@storybook/addon-actions": "5.1.11",
diff --git a/styleguide.config.js b/styleguide.config.js
index 7185f36fc4bd..4d670f5f1cf1 100644
--- a/styleguide.config.js
+++ b/styleguide.config.js
@@ -10,36 +10,43 @@ module.exports = {
name: 'Components',
description: '',
components: 'ts/components/[^_]*.tsx',
+ ignore: ['**/*.stories.*'],
},
{
name: 'Conversation',
description: 'Everything necessary to render a conversation',
components: 'ts/components/conversation/[^_]*.tsx',
+ ignore: ['**/*.stories.*'],
},
{
name: 'Emoji',
description: 'All components related to emojis',
components: 'ts/components/emoji/[^_]*.tsx',
+ ignore: ['**/*.stories.*'],
},
{
name: 'Media Gallery',
description: 'Display media and documents in a conversation',
components: 'ts/components/conversation/media-gallery/[^_]*.tsx',
+ ignore: ['**/*.stories.*'],
},
{
name: 'Stickers',
description: 'All components related to stickers',
components: 'ts/components/stickers/[^_]*.tsx',
+ ignore: ['**/*.stories.*'],
},
{
name: 'Utility',
description: 'Utility components used across the application',
components: 'ts/components/utility/[^_]*.tsx',
+ ignore: ['**/*.stories.*'],
},
{
name: 'Test',
description: 'Components only used for testing',
components: 'ts/styleguide/**/*.tsx',
+ ignore: ['**/*.stories.*'],
},
],
context: {
diff --git a/stylesheets/_modules.scss b/stylesheets/_modules.scss
index 825a0ca961cf..12d95862899b 100644
--- a/stylesheets/_modules.scss
+++ b/stylesheets/_modules.scss
@@ -6724,7 +6724,9 @@ button.module-image__border-overlay:focus {
}
.module-emoji {
- display: block;
+ display: flex;
+ justify-content: center;
+ align-items: center;
color: transparent;
font-family: auto;
diff --git a/ts/components/PopperRootContext.tsx b/ts/components/PopperRootContext.tsx
index 2a58014cf93f..4eb0d75c43e1 100644
--- a/ts/components/PopperRootContext.tsx
+++ b/ts/components/PopperRootContext.tsx
@@ -1,12 +1,12 @@
import * as React from 'react';
-const makeApi = (themes?: Array) => ({
+const makeApi = (classes?: Array) => ({
createRoot: () => {
const div = document.createElement('div');
- if (themes) {
- themes.forEach(theme => {
- div.classList.add(`${theme}-theme`);
+ if (classes) {
+ classes.forEach(theme => {
+ div.classList.add(theme);
});
}
@@ -21,16 +21,16 @@ const makeApi = (themes?: Array) => ({
export const PopperRootContext = React.createContext(makeApi());
-export type ThemedProviderProps = {
- themes?: Array;
+export type ClassyProviderProps = {
+ classes?: Array;
children?: React.ReactChildren;
};
-export const ThemedProvider: React.FunctionComponent = ({
- themes,
+export const ClassyProvider: React.FunctionComponent = ({
+ classes,
children,
}) => {
- const api = React.useMemo(() => makeApi(themes), [themes]);
+ const api = React.useMemo(() => makeApi(classes), [classes]);
return (
diff --git a/ts/components/conversation/Message.stories.tsx b/ts/components/conversation/Message.stories.tsx
new file mode 100644
index 000000000000..f94e33abf5c8
--- /dev/null
+++ b/ts/components/conversation/Message.stories.tsx
@@ -0,0 +1,1302 @@
+import * as React from 'react';
+
+import { storiesOf } from '@storybook/react';
+import { action } from '@storybook/addon-actions';
+
+// @ts-ignore
+import { setup as setupI18n } from '../../../js/modules/i18n';
+// @ts-ignore
+import enMessages from '../../../_locales/en/messages.json';
+
+import { Message, PropsActions, PropsData, PropsHousekeeping } from './Message';
+
+const book = storiesOf('Components/Conversation/Message', module);
+
+const baseDataProps: Pick<
+ PropsData,
+ | 'id'
+ | 'conversationId'
+ | 'interactionMode'
+ | 'conversationType'
+ | 'previews'
+ | 'timestamp'
+ | 'authorPhoneNumber'
+> = {
+ id: 'asdf',
+ conversationId: 'asdf',
+ interactionMode: 'mouse',
+ conversationType: 'direct',
+ previews: [],
+ timestamp: Date.now(),
+ authorPhoneNumber: '(202) 555-2001',
+};
+
+type MessageStory = [
+ string,
+ Array<{
+ makeDataProps: () => PropsData;
+ makeActionProps?: () => PropsActions;
+ makeHouseKeepingProps?: () => PropsHousekeeping;
+ title?: string;
+ }>
+];
+
+const makeDefaultActionProps = (): PropsActions => ({
+ clearSelectedMessage: action('clearSelectedMessage'),
+ reactToMessage: action('reactToMessage'),
+ replyToMessage: action('replyToMessage'),
+ retrySend: action('retrySend'),
+ deleteMessage: action('deleteMessage'),
+ showMessageDetail: action('showMessageDetail'),
+ openConversation: action('openConversation'),
+ showContactDetail: action('showContactDetail'),
+ showVisualAttachment: action('showVisualAttachment'),
+ downloadAttachment: action('downloadAttachment'),
+ displayTapToViewMessage: action('displayTapToViewMessage'),
+ openLink: action('openLink'),
+ scrollToQuotedMessage: action('scrollToQuotedMessage'),
+ selectMessage: action('selectMessage'),
+ showExpiredIncomingTapToViewToast: action(
+ 'showExpiredIncomingTapToViewToast'
+ ),
+ showExpiredOutgoingTapToViewToast: action(
+ 'showExpiredOutgoingTapToViewToast'
+ ),
+});
+
+const makeDefaultHousekeepingProps = (): PropsHousekeeping => ({
+ i18n: setupI18n('en', enMessages),
+});
+
+const stories: Array = [
+ [
+ 'Plain Message',
+ [
+ {
+ makeDataProps: () => ({
+ ...baseDataProps,
+ direction: 'incoming',
+ authorColor: 'green',
+ text: '🔥',
+ }),
+ },
+ {
+ makeDataProps: () => ({
+ ...baseDataProps,
+ direction: 'incoming',
+ authorColor: 'green',
+ text: 'Hello there from the new world! http://somewhere.com',
+ }),
+ },
+ {
+ makeDataProps: () => ({
+ ...baseDataProps,
+ direction: 'incoming',
+ authorColor: 'red',
+ text: 'Hello there from the new world!',
+ }),
+ makeHouseKeepingProps: () => ({
+ ...makeDefaultHousekeepingProps(),
+ collapseMetadata: true,
+ }),
+ },
+ {
+ makeDataProps: () => ({
+ ...baseDataProps,
+ direction: 'incoming',
+ authorColor: 'gray',
+ text:
+ 'Hello there from the new world! And this is multiple lines of text. Lines and lines and lines.',
+ }),
+ },
+ {
+ makeDataProps: () => ({
+ ...baseDataProps,
+ direction: 'incoming',
+ authorColor: 'deep_orange',
+ text:
+ 'Hello there from the new world! And this is multiple lines of text. Lines and lines and lines.',
+ }),
+ makeHouseKeepingProps: () => ({
+ ...makeDefaultHousekeepingProps(),
+ collapseMetadata: true,
+ }),
+ },
+ {
+ makeDataProps: () => ({
+ ...baseDataProps,
+ direction: 'outgoing',
+ status: 'sent',
+ authorColor: 'pink',
+ text: '🔥',
+ }),
+ },
+ {
+ makeDataProps: () => ({
+ ...baseDataProps,
+ direction: 'outgoing',
+ status: 'read',
+ authorColor: 'pink',
+ text: 'Hello there from the new world! http://somewhere.com',
+ }),
+ },
+ {
+ makeDataProps: () => ({
+ ...baseDataProps,
+ direction: 'outgoing',
+ status: 'sent',
+ text: 'Hello there from the new world! 🔥',
+ }),
+ makeHouseKeepingProps: () => ({
+ ...makeDefaultHousekeepingProps(),
+ collapseMetadata: true,
+ }),
+ },
+ {
+ makeDataProps: () => ({
+ ...baseDataProps,
+ direction: 'outgoing',
+ status: 'sent',
+ authorColor: 'blue',
+ text:
+ 'Hello there from the new world! And this is multiple lines of text. Lines and lines and lines.',
+ }),
+ makeHouseKeepingProps: () => ({
+ ...makeDefaultHousekeepingProps(),
+ collapseMetadata: true,
+ }),
+ },
+ ],
+ ],
+ [
+ 'Reactions',
+ [
+ ...([
+ {
+ title: 'Single Reaction (not me)',
+ reactions: [
+ {
+ emoji: '👍',
+ from: {
+ id: '+14155552671',
+ phoneNumber: '+14155552671',
+ name: 'Jack Sparrow',
+ },
+ },
+ ],
+ },
+ {
+ title: 'Two Reactions (neither me)',
+ reactions: [
+ {
+ emoji: '👍',
+ from: {
+ id: '+14155552671',
+ phoneNumber: '+14155552671',
+ name: 'Jack Sparrow',
+ },
+ },
+ {
+ emoji: '😂',
+ from: {
+ id: '+14155552672',
+ phoneNumber: '+14155552672',
+ profileName: 'Davy Jones',
+ },
+ },
+ ],
+ },
+ {
+ title: 'Three Reactions (none me)',
+ reactions: [
+ {
+ emoji: '👍',
+ from: {
+ id: '+14155552671',
+ phoneNumber: '+14155552671',
+ name: 'Jack Sparrow',
+ },
+ },
+ {
+ emoji: '😂',
+ from: {
+ id: '+14155552672',
+ phoneNumber: '+14155552672',
+ name: 'Amelia Briggs',
+ },
+ },
+ {
+ emoji: '😮',
+ from: {
+ id: '+14155552673',
+ phoneNumber: '+14155552673',
+ profileName: 'Joel Ferrari',
+ },
+ },
+ ],
+ },
+ {
+ title: 'Six Reactions (none me)',
+ reactions: [
+ {
+ emoji: '👍',
+ from: {
+ id: '+14155552671',
+ phoneNumber: '+14155552671',
+ name: 'Jack Sparrow',
+ },
+ },
+ {
+ emoji: '😂',
+ from: {
+ id: '+14155552672',
+ phoneNumber: '+14155552672',
+ name: 'Amelia Briggs',
+ },
+ },
+ {
+ emoji: '😮',
+ from: {
+ id: '+14155552673',
+ phoneNumber: '+14155552673',
+ name: 'Amelia Briggs',
+ },
+ },
+ {
+ emoji: '😡',
+ from: {
+ id: '+14155552674',
+ phoneNumber: '+14155552674',
+ name: 'Amelia Briggs',
+ },
+ },
+ {
+ emoji: '👎',
+ from: {
+ id: '+14155552675',
+ phoneNumber: '+14155552675',
+ name: 'Amelia Briggs',
+ },
+ },
+ {
+ emoji: '❤️',
+ from: {
+ id: '+14155552676',
+ phoneNumber: '+14155552676',
+ name: 'Amelia Briggs',
+ },
+ },
+ ],
+ },
+ {
+ title: 'Four Reactions, Three Same (none me)',
+ reactions: [
+ {
+ emoji: '👍',
+ from: {
+ id: '+14155552671',
+ phoneNumber: '+14155552671',
+ name: 'Amelia Briggs',
+ },
+ },
+ {
+ emoji: '👍',
+ from: {
+ id: '+14155552672',
+ phoneNumber: '+14155552672',
+ name: 'Amelia Briggs',
+ },
+ },
+ {
+ emoji: '👍',
+ from: {
+ id: '+14155552673',
+ phoneNumber: '+14155552673',
+ name: 'Amelia Briggs',
+ },
+ },
+ {
+ emoji: '😂',
+ from: {
+ id: '+14155552674',
+ phoneNumber: '+14155552674',
+ name: 'Amelia Briggs',
+ },
+ },
+ ],
+ },
+ {
+ title: 'Seven Reactions, Three Same, One Different (none me)',
+ reactions: [
+ {
+ emoji: '👍',
+ from: {
+ id: '+14155552671',
+ phoneNumber: '+14155552671',
+ name: 'Amelia Briggs',
+ },
+ },
+ {
+ emoji: '👍',
+ from: {
+ id: '+14155552672',
+ phoneNumber: '+14155552672',
+ name: 'Amelia Briggs',
+ },
+ },
+ {
+ emoji: '👍',
+ from: {
+ id: '+14155552673',
+ phoneNumber: '+14155552673',
+ name: 'Amelia Briggs',
+ },
+ },
+ {
+ emoji: '😂',
+ from: {
+ id: '+14155552674',
+ phoneNumber: '+14155552674',
+ name: 'Amelia Briggs',
+ },
+ },
+ {
+ emoji: '😡',
+ from: {
+ id: '+14155552675',
+ phoneNumber: '+14155552675',
+ name: 'Amelia Briggs',
+ },
+ },
+ {
+ emoji: '👎',
+ from: {
+ id: '+14155552676',
+ phoneNumber: '+14155552676',
+ name: 'Amelia Briggs',
+ },
+ },
+ {
+ emoji: '❤️',
+ from: {
+ id: '+14155552678',
+ phoneNumber: '+14155552678',
+ name: 'Amelia Briggs',
+ },
+ },
+ ],
+ },
+ {
+ title: 'Three Reations, All Same (none me)',
+ reactions: [
+ {
+ emoji: '👍',
+ from: {
+ id: '+14155552671',
+ phoneNumber: '+14155552671',
+ name: 'Amelia Briggs',
+ },
+ },
+ {
+ emoji: '👍',
+ from: {
+ id: '+14155552672',
+ phoneNumber: '+14155552672',
+ name: 'Amelia Briggs',
+ },
+ },
+ {
+ emoji: '👍',
+ from: {
+ id: '+14155552673',
+ phoneNumber: '+14155552673',
+ name: 'Amelia Briggs',
+ },
+ },
+ ],
+ },
+ {
+ title: 'Six Reactions, Two Kinds (none me)',
+ reactions: [
+ {
+ emoji: '👍',
+ from: {
+ id: '+14155552671',
+ phoneNumber: '+14155552671',
+ name: 'Amelia Briggs',
+ },
+ },
+ {
+ emoji: '👍',
+ from: {
+ id: '+14155552672',
+ phoneNumber: '+14155552672',
+ name: 'Amelia Briggs',
+ },
+ },
+ {
+ emoji: '👍',
+ from: {
+ id: '+14155552673',
+ phoneNumber: '+14155552673',
+ name: 'Amelia Briggs',
+ },
+ },
+ {
+ emoji: '😂',
+ from: {
+ id: '+14155552674',
+ phoneNumber: '+14155552674',
+ name: 'Amelia Briggs',
+ },
+ },
+ {
+ emoji: '😂',
+ from: {
+ id: '+14155552675',
+ phoneNumber: '+14155552675',
+ name: 'Amelia Briggs',
+ },
+ },
+ {
+ emoji: '😂',
+ from: {
+ id: '+14155552676',
+ phoneNumber: '+14155552676',
+ name: 'Amelia Briggs',
+ },
+ },
+ ],
+ },
+ {
+ title: 'Nine Reactions, Three Kinds (none me)',
+ reactions: [
+ {
+ emoji: '👍',
+ from: {
+ id: '+14155552671',
+ phoneNumber: '+14155552671',
+ name: 'Amelia Briggs',
+ },
+ },
+ {
+ emoji: '👍',
+ from: {
+ id: '+14155552672',
+ phoneNumber: '+14155552672',
+ name: 'Amelia Briggs',
+ },
+ },
+ {
+ emoji: '👍',
+ from: {
+ id: '+14155552673',
+ phoneNumber: '+14155552673',
+ name: 'Amelia Briggs',
+ },
+ },
+ {
+ emoji: '😂',
+ from: {
+ id: '+14155552674',
+ phoneNumber: '+14155552674',
+ name: 'Amelia Briggs',
+ },
+ },
+ {
+ emoji: '😂',
+ from: {
+ id: '+14155552675',
+ phoneNumber: '+14155552675',
+ name: 'Amelia Briggs',
+ },
+ },
+ {
+ emoji: '😂',
+ from: {
+ id: '+14155552676',
+ phoneNumber: '+14155552676',
+ name: 'Amelia Briggs',
+ },
+ },
+ {
+ emoji: '😮',
+ from: {
+ id: '+14155552677',
+ phoneNumber: '+14155552677',
+ name: 'Amelia Briggs',
+ },
+ },
+ {
+ emoji: '😮',
+ from: {
+ id: '+14155552678',
+ phoneNumber: '+14155552678',
+ name: 'Amelia Briggs',
+ },
+ },
+ {
+ emoji: '😮',
+ from: {
+ id: '+14155552679',
+ phoneNumber: '+14155552679',
+ name: 'Amelia Briggs',
+ },
+ },
+ ],
+ },
+ {
+ title: 'Short Message, Seven Reactions (none me)',
+ short: true,
+ reactions: [
+ {
+ emoji: '👍',
+ from: {
+ id: '+14155552671',
+ phoneNumber: '+14155552671',
+ name: 'Amelia Briggs',
+ },
+ },
+ {
+ emoji: '👍',
+ from: {
+ id: '+14155552672',
+ phoneNumber: '+14155552672',
+ name: 'Amelia Briggs',
+ },
+ },
+ {
+ emoji: '👍',
+ from: {
+ id: '+14155552673',
+ phoneNumber: '+14155552673',
+ name: 'Amelia Briggs',
+ },
+ },
+ {
+ emoji: '😂',
+ from: {
+ id: '+14155552674',
+ phoneNumber: '+14155552674',
+ name: 'Amelia Briggs',
+ },
+ },
+ {
+ emoji: '😡',
+ from: {
+ id: '+14155552675',
+ phoneNumber: '+14155552675',
+ name: 'Amelia Briggs',
+ },
+ },
+ {
+ emoji: '👎',
+ from: {
+ id: '+14155552676',
+ phoneNumber: '+14155552676',
+ name: 'Amelia Briggs',
+ },
+ },
+ {
+ emoji: '❤️',
+ from: {
+ id: '+14155552677',
+ phoneNumber: '+14155552677',
+ name: 'Amelia Briggs',
+ },
+ },
+ ],
+ },
+ {
+ title: 'Short Message, Six Reactions (none me)',
+ short: true,
+ reactions: [
+ {
+ emoji: '👍',
+ from: {
+ id: '+14155552671',
+ phoneNumber: '+14155552671',
+ name: 'Amelia Briggs',
+ },
+ },
+ {
+ emoji: '👍',
+ from: {
+ id: '+14155552672',
+ phoneNumber: '+14155552672',
+ name: 'Amelia Briggs',
+ },
+ },
+ {
+ emoji: '👍',
+ from: {
+ id: '+14155552673',
+ phoneNumber: '+14155552673',
+ name: 'Amelia Briggs',
+ },
+ },
+ {
+ emoji: '😂',
+ from: {
+ id: '+14155552674',
+ phoneNumber: '+14155552674',
+ name: 'Amelia Briggs',
+ },
+ },
+ {
+ emoji: '😂',
+ from: {
+ id: '+14155552675',
+ phoneNumber: '+14155552675',
+ name: 'Amelia Briggs',
+ },
+ },
+ {
+ emoji: '😂',
+ from: {
+ id: '+14155552676',
+ phoneNumber: '+14155552676',
+ name: 'Amelia Briggs',
+ },
+ },
+ ],
+ },
+ {
+ title: 'Short Message, No Reactions',
+ short: true,
+ reactions: [],
+ },
+ {
+ title: 'Nine Reactions (me in second group)',
+ reactions: [
+ {
+ emoji: '👍',
+ from: {
+ isMe: true,
+ id: '+14155552671',
+ phoneNumber: '+14155552671',
+ name: 'Amelia Briggs',
+ },
+ },
+ {
+ emoji: '👍',
+ from: {
+ id: '+14155552672',
+ phoneNumber: '+14155552672',
+ name: 'Amelia Briggs',
+ },
+ },
+ {
+ emoji: '👍',
+ from: {
+ id: '+14155552673',
+ phoneNumber: '+14155552673',
+ name: 'Amelia Briggs',
+ },
+ },
+ {
+ emoji: '😂',
+ from: {
+ id: '+14155552674',
+ phoneNumber: '+14155552674',
+ name: 'Amelia Briggs',
+ },
+ },
+ {
+ emoji: '😂',
+ from: {
+ id: '+14155552675',
+ phoneNumber: '+14155552675',
+ name: 'Amelia Briggs',
+ },
+ },
+ {
+ emoji: '😂',
+ from: {
+ id: '+14155552676',
+ phoneNumber: '+14155552676',
+ name: 'Amelia Briggs',
+ },
+ },
+ {
+ emoji: '😡',
+ from: {
+ id: '+14155552677',
+ phoneNumber: '+14155552677',
+ name: 'Amelia Briggs',
+ },
+ },
+ {
+ emoji: '👎',
+ from: {
+ id: '+14155552678',
+ phoneNumber: '+14155552678',
+ name: 'Amelia Briggs',
+ },
+ },
+ {
+ emoji: '❤️',
+ from: {
+ id: '+14155552679',
+ phoneNumber: '+14155552679',
+ name: 'Amelia Briggs',
+ },
+ },
+ ],
+ },
+ {
+ title: 'Nine Reactions (me in first group)',
+ reactions: [
+ {
+ emoji: '👍',
+ from: {
+ id: '+14155552671',
+ phoneNumber: '+14155552671',
+ name: 'Amelia Briggs',
+ },
+ },
+ {
+ emoji: '👍',
+ from: {
+ id: '+14155552672',
+ phoneNumber: '+14155552672',
+ name: 'Amelia Briggs',
+ },
+ },
+ {
+ emoji: '👍',
+ from: {
+ id: '+14155552673',
+ phoneNumber: '+14155552673',
+ name: 'Amelia Briggs',
+ },
+ },
+ {
+ emoji: '😂',
+ from: {
+ isMe: true,
+ id: '+14155552674',
+ phoneNumber: '+14155552674',
+ name: 'Amelia Briggs',
+ },
+ },
+ {
+ emoji: '😂',
+ from: {
+ id: '+14155552675',
+ phoneNumber: '+14155552675',
+ name: 'Amelia Briggs',
+ },
+ },
+ {
+ emoji: '😂',
+ from: {
+ id: '+14155552676',
+ phoneNumber: '+14155552676',
+ name: 'Amelia Briggs',
+ },
+ },
+ {
+ emoji: '😡',
+ from: {
+ id: '+14155552677',
+ phoneNumber: '+14155552677',
+ name: 'Amelia Briggs',
+ },
+ },
+ {
+ emoji: '👎',
+ from: {
+ id: '+14155552678',
+ phoneNumber: '+14155552678',
+ name: 'Amelia Briggs',
+ },
+ },
+ {
+ emoji: '❤️',
+ from: {
+ id: '+14155552679',
+ phoneNumber: '+14155552679',
+ name: 'Amelia Briggs',
+ },
+ },
+ ],
+ },
+ {
+ title: 'Nine Reactions (me in third group)',
+ reactions: [
+ {
+ emoji: '👍',
+ from: {
+ id: '+14155552671',
+ phoneNumber: '+14155552671',
+ name: 'Amelia Briggs',
+ },
+ },
+ {
+ emoji: '👍',
+ from: {
+ id: '+14155552672',
+ phoneNumber: '+14155552672',
+ name: 'Amelia Briggs',
+ },
+ },
+ {
+ emoji: '👍',
+ from: {
+ id: '+14155552673',
+ phoneNumber: '+14155552673',
+ name: 'Amelia Briggs',
+ },
+ },
+ {
+ emoji: '😂',
+ from: {
+ id: '+14155552674',
+ phoneNumber: '+14155552674',
+ name: 'Amelia Briggs',
+ },
+ },
+ {
+ emoji: '😂',
+ from: {
+ id: '+14155552675',
+ phoneNumber: '+14155552675',
+ name: 'Amelia Briggs',
+ },
+ },
+ {
+ emoji: '😂',
+ from: {
+ id: '+14155552676',
+ phoneNumber: '+14155552676',
+ name: 'Amelia Briggs',
+ },
+ },
+ {
+ emoji: '😡',
+ from: {
+ isMe: true,
+ id: '+14155552677',
+ phoneNumber: '+14155552677',
+ name: 'Amelia Briggs',
+ },
+ },
+ {
+ emoji: '👎',
+ from: {
+ id: '+14155552678',
+ phoneNumber: '+14155552678',
+ name: 'Amelia Briggs',
+ },
+ },
+ {
+ emoji: '❤️',
+ from: {
+ id: '+14155552679',
+ phoneNumber: '+14155552679',
+ name: 'Amelia Briggs',
+ },
+ },
+ ],
+ },
+ {
+ title: 'Outgoing Message, One Reaction (not me)',
+ outgoing: true,
+ reactions: [
+ {
+ emoji: '😂',
+ from: {
+ id: '+14155552671',
+ phoneNumber: '+14155552671',
+ name: 'Amelia Briggs',
+ },
+ },
+ ],
+ },
+ {
+ title: 'Outgoing Message, Nine Reactions (none me)',
+ outgoing: true,
+ reactions: [
+ {
+ emoji: '👍',
+ from: {
+ id: '+14155552671',
+ phoneNumber: '+14155552671',
+ name: 'Amelia Briggs',
+ },
+ },
+ {
+ emoji: '👍',
+ from: {
+ id: '+14155552672',
+ phoneNumber: '+14155552672',
+ name: 'Amelia Briggs',
+ },
+ },
+ {
+ emoji: '👍',
+ from: {
+ id: '+14155552673',
+ phoneNumber: '+14155552673',
+ name: 'Amelia Briggs',
+ },
+ },
+ {
+ emoji: '😂',
+ from: {
+ id: '+14155552674',
+ phoneNumber: '+14155552674',
+ name: 'Amelia Briggs',
+ },
+ },
+ {
+ emoji: '😂',
+ from: {
+ id: '+14155552675',
+ phoneNumber: '+14155552675',
+ name: 'Amelia Briggs',
+ },
+ },
+ {
+ emoji: '😂',
+ from: {
+ id: '+14155552676',
+ phoneNumber: '+14155552676',
+ name: 'Amelia Briggs',
+ },
+ },
+ {
+ emoji: '😡',
+ from: {
+ id: '+14155552677',
+ phoneNumber: '+14155552677',
+ name: 'Amelia Briggs',
+ },
+ },
+ {
+ emoji: '👎',
+ from: {
+ id: '+14155552678',
+ phoneNumber: '+14155552678',
+ name: 'Amelia Briggs',
+ },
+ },
+ {
+ emoji: '❤️',
+ from: {
+ id: '+14155552679',
+ phoneNumber: '+14155552679',
+ name: 'Amelia Briggs',
+ },
+ },
+ ],
+ },
+ {
+ title: 'Outgoing Message, Nine Reactions (me in first group)',
+ outgoing: true,
+ reactions: [
+ {
+ emoji: '👍',
+ from: {
+ id: '+14155552671',
+ phoneNumber: '+14155552671',
+ name: 'Amelia Briggs',
+ },
+ },
+ {
+ emoji: '👍',
+ from: {
+ id: '+14155552672',
+ phoneNumber: '+14155552672',
+ name: 'Amelia Briggs',
+ },
+ },
+ {
+ emoji: '👍',
+ from: {
+ id: '+14155552673',
+ phoneNumber: '+14155552673',
+ name: 'Amelia Briggs',
+ },
+ },
+ {
+ emoji: '😂',
+ from: {
+ isMe: true,
+ id: '+14155552674',
+ phoneNumber: '+14155552674',
+ name: 'Amelia Briggs',
+ },
+ },
+ {
+ emoji: '😂',
+ from: {
+ id: '+14155552675',
+ phoneNumber: '+14155552675',
+ name: 'Amelia Briggs',
+ },
+ },
+ {
+ emoji: '😂',
+ from: {
+ id: '+14155552676',
+ phoneNumber: '+14155552676',
+ name: 'Amelia Briggs',
+ },
+ },
+ {
+ emoji: '😡',
+ from: {
+ id: '+14155552677',
+ phoneNumber: '+14155552677',
+ name: 'Amelia Briggs',
+ },
+ },
+ {
+ emoji: '👎',
+ from: {
+ id: '+14155552678',
+ phoneNumber: '+14155552678',
+ name: 'Amelia Briggs',
+ },
+ },
+ {
+ emoji: '❤️',
+ from: {
+ id: '+14155552679',
+ phoneNumber: '+14155552679',
+ name: 'Amelia Briggs',
+ },
+ },
+ ],
+ },
+ {
+ title: 'Outgoing Short Message, Nine Reactions (none me)',
+ outgoing: true,
+ short: true,
+ reactions: [
+ {
+ emoji: '👍',
+ from: {
+ id: '+14155552671',
+ phoneNumber: '+14155552671',
+ name: 'Amelia Briggs',
+ },
+ },
+ {
+ emoji: '👍',
+ from: {
+ id: '+14155552672',
+ phoneNumber: '+14155552672',
+ name: 'Amelia Briggs',
+ },
+ },
+ {
+ emoji: '👍',
+ from: {
+ id: '+14155552673',
+ phoneNumber: '+14155552673',
+ name: 'Amelia Briggs',
+ },
+ },
+ {
+ emoji: '😂',
+ from: {
+ id: '+14155552674',
+ phoneNumber: '+14155552674',
+ name: 'Amelia Briggs',
+ },
+ },
+ {
+ emoji: '😂',
+ from: {
+ id: '+14155552675',
+ phoneNumber: '+14155552675',
+ name: 'Amelia Briggs',
+ },
+ },
+ {
+ emoji: '😂',
+ from: {
+ id: '+14155552676',
+ phoneNumber: '+14155552676',
+ name: 'Amelia Briggs',
+ },
+ },
+ {
+ emoji: '😡',
+ from: {
+ id: '+14155552677',
+ phoneNumber: '+14155552677',
+ name: 'Amelia Briggs',
+ },
+ },
+ {
+ emoji: '👎',
+ from: {
+ id: '+14155552678',
+ phoneNumber: '+14155552678',
+ name: 'Amelia Briggs',
+ },
+ },
+ {
+ emoji: '❤️',
+ from: {
+ id: '+14155552679',
+ phoneNumber: '+14155552679',
+ name: 'Amelia Briggs',
+ },
+ },
+ ],
+ },
+ {
+ title: 'Outgoing Short Message, Six Reactions, Two Groups (none me)',
+ outgoing: true,
+ short: true,
+ reactions: [
+ {
+ emoji: '👍',
+ from: {
+ id: '+14155552671',
+ phoneNumber: '+14155552671',
+ name: 'Amelia Briggs',
+ },
+ },
+ {
+ emoji: '👍',
+ from: {
+ id: '+14155552672',
+ phoneNumber: '+14155552672',
+ name: 'Amelia Briggs',
+ },
+ },
+ {
+ emoji: '👍',
+ from: {
+ id: '+14155552673',
+ phoneNumber: '+14155552673',
+ name: 'Amelia Briggs',
+ },
+ },
+ {
+ emoji: '😂',
+ from: {
+ id: '+14155552674',
+ phoneNumber: '+14155552674',
+ name: 'Amelia Briggs',
+ },
+ },
+ {
+ emoji: '😂',
+ from: {
+ id: '+14155552675',
+ phoneNumber: '+14155552675',
+ name: 'Amelia Briggs',
+ },
+ },
+ {
+ emoji: '😂',
+ from: {
+ id: '+14155552676',
+ phoneNumber: '+14155552676',
+ name: 'Amelia Briggs',
+ },
+ },
+ ],
+ },
+ {
+ title: 'Outgoing Short Message, Three Reactions, All Same (none me)',
+ outgoing: true,
+ short: true,
+ reactions: [
+ {
+ emoji: '👍',
+ from: {
+ id: '+14155552671',
+ phoneNumber: '+14155552671',
+ name: 'Amelia Briggs',
+ },
+ },
+ {
+ emoji: '👍',
+ from: {
+ id: '+14155552672',
+ phoneNumber: '+14155552672',
+ name: 'Amelia Briggs',
+ },
+ },
+ {
+ emoji: '👍',
+ from: {
+ id: '+14155552673',
+ phoneNumber: '+14155552673',
+ name: 'Amelia Briggs',
+ },
+ },
+ ],
+ },
+ ] as Array<{
+ outgoing: boolean;
+ short: boolean;
+ reactions: PropsData['reactions'];
+ title?: string;
+ }>).map(spec => ({
+ title: spec.title,
+ makeDataProps: () => ({
+ ...baseDataProps,
+ // tsc disagrees with tslint, I favor safety (tsc)
+ // tslint:disable-next-line no-unnecessary-type-assertion
+ direction: (spec.outgoing
+ ? 'outgoing'
+ : 'incoming') as PropsData['direction'],
+ text: spec.short
+ ? 'hahaha'
+ : "I'd like to order one large phone with extra phones please. cell phone, no no no rotary... and payphone on half.",
+ reactions: spec.reactions
+ ? spec.reactions.map((re, i) => ({
+ ...re,
+ timestamp: i,
+ }))
+ : [],
+ }),
+ })),
+ ],
+ ],
+];
+
+stories.forEach(([chapterTitle, propsArr]) =>
+ book.add(chapterTitle, () =>
+ propsArr.map(
+ (
+ {
+ title,
+ makeDataProps,
+ makeActionProps = makeDefaultActionProps,
+ makeHouseKeepingProps = makeDefaultHousekeepingProps,
+ },
+ i
+ ) => {
+ const dataProps = makeDataProps();
+ const outgoing = dataProps.direction === 'outgoing';
+
+ return (
+ <>
+ {title ? (
+
+ {title}
+
+ ) : null}
+
+
+
+ >
+ );
+ }
+ )
+ )
+);
diff --git a/ts/components/conversation/Message.tsx b/ts/components/conversation/Message.tsx
index 24768c081701..702848010c75 100644
--- a/ts/components/conversation/Message.tsx
+++ b/ts/components/conversation/Message.tsx
@@ -65,9 +65,9 @@ export type PropsData = {
conversationId: string;
text?: string;
textPending?: boolean;
- isSticker: boolean;
- isSelected: boolean;
- isSelectedCounter: number;
+ isSticker?: boolean;
+ isSelected?: boolean;
+ isSelectedCounter?: number;
interactionMode: 'mouse' | 'keyboard';
direction: 'incoming' | 'outgoing';
timestamp: number;
@@ -94,7 +94,7 @@ export type PropsData = {
};
previews: Array;
authorAvatarPath?: string;
- isExpired: boolean;
+ isExpired?: boolean;
isTapToView?: boolean;
isTapToViewExpired?: boolean;
@@ -107,7 +107,7 @@ export type PropsData = {
selectedReaction?: string;
};
-type PropsHousekeeping = {
+export type PropsHousekeeping = {
i18n: LocalizerType;
disableMenu?: boolean;
disableScroll?: boolean;
@@ -158,8 +158,8 @@ interface State {
expired: boolean;
imageBroken: boolean;
- isSelected: boolean;
- prevSelectedCounter: number;
+ isSelected?: boolean;
+ prevSelectedCounter?: number;
pickedReaction?: string;
reactionViewerRoot: HTMLDivElement | null;
diff --git a/ts/components/conversation/ReactionViewer.tsx b/ts/components/conversation/ReactionViewer.tsx
index 80e93152ffb7..52c61b01b353 100644
--- a/ts/components/conversation/ReactionViewer.tsx
+++ b/ts/components/conversation/ReactionViewer.tsx
@@ -101,7 +101,7 @@ export const ReactionViewer = React.forwardRef(
return (
- {...renderedEmojis
+ {renderedEmojis
.filter(e => e === 'all' || Boolean(grouped[e]))
.map((cat, index) => {
const re = grouped[cat] || reactions;
diff --git a/tsconfig.json b/tsconfig.json
index d9680f2be3cf..471083a62464 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -33,6 +33,7 @@
// Module Resolution Options
"moduleResolution": "node", // Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6).
+ "resolveJsonModule": true,
// "baseUrl": "./", // Base directory to resolve non-absolute module names.
// "paths": {}, // A series of entries which re-map imports to lookup locations relative to the 'baseUrl'.
// "rootDirs": [], // List of root folders whose combined content represents the structure of the project at runtime.
diff --git a/yarn.lock b/yarn.lock
index 288d92c556a1..9f71d638d7bd 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -226,6 +226,13 @@
dependencies:
"@babel/types" "^7.0.0"
+"@babel/helper-module-imports@^7.8.3":
+ version "7.8.3"
+ resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.8.3.tgz#7fe39589b39c016331b6b8c3f441e8f0b1419498"
+ integrity sha512-R0Bx3jippsbAEtzkpZ/6FIiuzOURPcMjHp+Z6xPe6DtApDJx+w7UYyOLanZqO8+wKR9G10s/FmHXvxaMd9s6Kg==
+ dependencies:
+ "@babel/types" "^7.8.3"
+
"@babel/helper-module-transforms@^7.1.0", "@babel/helper-module-transforms@^7.4.4":
version "7.5.5"
resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.5.5.tgz#f84ff8a09038dcbca1fd4355661a500937165b4a"
@@ -257,6 +264,11 @@
resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.0.0.tgz#bbb3fbee98661c569034237cc03967ba99b4f250"
integrity sha512-CYAOUCARwExnEixLdB6sDm2dIJ/YgEAKDM1MOeMeZu9Ld/bDgVo8aiWrXwcY7OBh+1Ea2uUcVRcxKk0GJvW7QA==
+"@babel/helper-plugin-utils@^7.8.3":
+ version "7.8.3"
+ resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz#9ea293be19babc0f52ff8ca88b34c3611b208670"
+ integrity sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==
+
"@babel/helper-regex@^7.0.0", "@babel/helper-regex@^7.4.4":
version "7.5.5"
resolved "https://registry.yarnpkg.com/@babel/helper-regex/-/helper-regex-7.5.5.tgz#0aa6824f7100a2e0e89c1527c23936c152cab351"
@@ -811,6 +823,16 @@
resolve "^1.8.1"
semver "^5.5.1"
+"@babel/plugin-transform-runtime@^7.8.3":
+ version "7.8.3"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.8.3.tgz#c0153bc0a5375ebc1f1591cb7eea223adea9f169"
+ integrity sha512-/vqUt5Yh+cgPZXXjmaG9NT8aVfThKk7G4OqkVhrXqwsC5soMn/qTCxs36rZ2QFhpfTJcjw4SNDIZ4RUb8OL4jQ==
+ dependencies:
+ "@babel/helper-module-imports" "^7.8.3"
+ "@babel/helper-plugin-utils" "^7.8.3"
+ resolve "^1.8.1"
+ semver "^5.5.1"
+
"@babel/plugin-transform-shorthand-properties@^7.2.0":
version "7.2.0"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.2.0.tgz#6333aee2f8d6ee7e28615457298934a3b46198f0"
@@ -1071,6 +1093,15 @@
lodash "^4.17.13"
to-fast-properties "^2.0.0"
+"@babel/types@^7.8.3":
+ version "7.8.3"
+ resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.8.3.tgz#5a383dffa5416db1b73dedffd311ffd0788fb31c"
+ integrity sha512-jBD+G8+LWpMBBWvVcdr4QysjUE4mU/syrhN17o1u3gx0/WzJB1kwiVZAXRtWbsIPOwW8pF/YJV5+nmetPzepXg==
+ dependencies:
+ esutils "^2.0.2"
+ lodash "^4.17.13"
+ to-fast-properties "^2.0.0"
+
"@develar/schema-utils@~2.1.0":
version "2.1.0"
resolved "https://registry.yarnpkg.com/@develar/schema-utils/-/schema-utils-2.1.0.tgz#eceb1695bfbed6f6bb84666d5d3abe5e1fd54e17"