From df81bc4a9745288d2eb1f6a924ceb9b79017b04f Mon Sep 17 00:00:00 2001 From: Nolan Lawson Date: Sat, 6 May 2017 17:42:38 -0700 Subject: [PATCH] add asynchronous emojione-picker (code-splitting) (#2863) --- .babelrc | 1 + .../components/emoji_picker_dropdown.js | 45 ++++++++++++++++--- app/javascript/styles/components.scss | 14 ++++++ package.json | 1 + 4 files changed, 54 insertions(+), 7 deletions(-) diff --git a/.babelrc b/.babelrc index 13578a79f6..31f4e2e0cd 100644 --- a/.babelrc +++ b/.babelrc @@ -12,6 +12,7 @@ ] ], "plugins": [ + "syntax-dynamic-import", "transform-object-rest-spread", [ "react-intl", diff --git a/app/javascript/mastodon/features/compose/components/emoji_picker_dropdown.js b/app/javascript/mastodon/features/compose/components/emoji_picker_dropdown.js index 3e0b290d61..c95b4a2799 100644 --- a/app/javascript/mastodon/features/compose/components/emoji_picker_dropdown.js +++ b/app/javascript/mastodon/features/compose/components/emoji_picker_dropdown.js @@ -1,6 +1,5 @@ import React from 'react'; import Dropdown, { DropdownTrigger, DropdownContent } from 'react-simple-dropdown'; -import EmojiPicker from 'emojione-picker'; import PropTypes from 'prop-types'; import { defineMessages, injectIntl } from 'react-intl'; @@ -37,12 +36,20 @@ const dropdownTriggerStyle = { width: '24px' } +let EmojiPicker; // load asynchronously + class EmojiPickerDropdown extends React.PureComponent { constructor (props, context) { super(props, context); this.setRef = this.setRef.bind(this); this.handleChange = this.handleChange.bind(this); + this.onHideDropdown = this.onHideDropdown.bind(this); + this.onShowDropdown = this.onShowDropdown.bind(this); + this.state = { + active: false, + loading: false + }; } setRef (c) { @@ -54,6 +61,24 @@ class EmojiPickerDropdown extends React.PureComponent { this.props.onPickEmoji(data); } + onShowDropdown () { + this.setState({active: true}); + if (!EmojiPicker) { + this.setState({loading: true}); + import('emojione-picker').then(TheEmojiPicker => { + EmojiPicker = TheEmojiPicker.default; + this.setState({loading: false}); + }).catch(err => { + // TODO: show the user an error? + this.setState({loading: false}); + }); + } + } + + onHideDropdown () { + this.setState({active: false}); + } + render () { const { intl } = this.props; @@ -92,14 +117,20 @@ class EmojiPickerDropdown extends React.PureComponent { } } - return ( - - - 🙂 - + const { active, loading } = this.state; + return ( + + + 🙂 + - + { + this.state.active && !this.state.loading && + () + } ); diff --git a/app/javascript/styles/components.scss b/app/javascript/styles/components.scss index 93a3d70462..f2d6f988c3 100644 --- a/app/javascript/styles/components.scss +++ b/app/javascript/styles/components.scss @@ -2141,6 +2141,20 @@ button.icon-button.active i.fa-retweet { background: radial-gradient(ellipse, rgba($color4, 0.23) 0%, rgba($color4, 0) 60%); } +@keyframes pulse { + 0% { + opacity: 1; + } + 100% { + opacity: 0.5; + } +} + +.pulse-loading { + animation: pulse 1s ease-in-out infinite; + animation-direction: alternate; +} + .emoji-dialog { width: 245px; height: 270px; diff --git a/package.json b/package.json index 136c92860a..f1135f20d9 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,7 @@ "babel-plugin-lodash": "^3.2.11", "babel-plugin-react-intl": "^2.3.1", "babel-plugin-react-transform": "^2.0.2", + "babel-plugin-syntax-dynamic-import": "^6.18.0", "babel-plugin-transform-object-rest-spread": "^6.23.0", "babel-plugin-transform-react-constant-elements": "^6.23.0", "babel-plugin-transform-react-inline-elements": "^6.22.0",