diff options
4 files changed, 66 insertions, 22 deletions
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 210721d9c..9be8909d8 100644 --- a/app/javascript/mastodon/features/compose/components/emoji_picker_dropdown.js +++ b/app/javascript/mastodon/features/compose/components/emoji_picker_dropdown.js @@ -31,6 +31,19 @@ let EmojiPicker, Emoji; // load asynchronously const backgroundImageFn = () => `${assetHost}/emoji/sheet.png`; const listenerOptions = detectPassiveEvents.hasSupport ? { passive: true } : false; +const categoriesSort = [ + 'recent', + 'custom', + 'people', + 'nature', + 'foods', + 'activity', + 'places', + 'objects', + 'symbols', + 'flags', +]; + class ModifierPickerMenu extends React.PureComponent { static propTypes = { @@ -141,6 +154,9 @@ class EmojiPickerMenu extends React.PureComponent { arrowOffsetLeft: PropTypes.string, arrowOffsetTop: PropTypes.string, intl: PropTypes.object.isRequired, + skinTone: PropTypes.number.isRequired, + onSkinTone: PropTypes.func.isRequired, + autoPlay: PropTypes.bool, }; static defaultProps = { @@ -151,7 +167,6 @@ class EmojiPickerMenu extends React.PureComponent { state = { modifierOpen: false, - modifier: 1, }; handleDocumentClick = e => { @@ -214,20 +229,18 @@ class EmojiPickerMenu extends React.PureComponent { } handleModifierChange = modifier => { - if (modifier !== this.state.modifier) { - this.setState({ modifier }); - } + this.props.onSkinTone(modifier); } render () { - const { loading, style, intl } = this.props; + const { loading, style, intl, custom_emojis, autoPlay, skinTone } = this.props; if (loading) { return <div style={{ width: 299 }} />; } const title = intl.formatMessage(messages.emoji); - const { modifierOpen, modifier } = this.state; + const { modifierOpen } = this.state; return ( <div className={classNames('emoji-picker-dropdown__menu', { selecting: modifierOpen })} style={style} ref={this.setRef}> @@ -235,20 +248,22 @@ class EmojiPickerMenu extends React.PureComponent { perLine={8} emojiSize={22} sheetSize={32} + custom={buildCustomEmojis(custom_emojis, autoPlay)} color='' emoji='' set='twitter' title={title} i18n={this.getI18n()} onClick={this.handleClick} - skin={modifier} + include={categoriesSort} + skin={skinTone} showPreview={false} backgroundImageFn={backgroundImageFn} /> <ModifierPicker active={modifierOpen} - modifier={modifier} + modifier={skinTone} onOpen={this.handleModifierOpen} onClose={this.handleModifierClose} onChange={this.handleModifierChange} @@ -267,6 +282,8 @@ export default class EmojiPickerDropdown extends React.PureComponent { autoPlay: PropTypes.bool, intl: PropTypes.object.isRequired, onPickEmoji: PropTypes.func.isRequired, + onSkinTone: PropTypes.func.isRequired, + skinTone: PropTypes.number.isRequired, }; state = { @@ -279,8 +296,6 @@ export default class EmojiPickerDropdown extends React.PureComponent { } onShowDropdown = () => { - const { autoPlay } = this.props; - this.setState({ active: true }); if (!EmojiPicker) { @@ -288,9 +303,8 @@ export default class EmojiPickerDropdown extends React.PureComponent { EmojiPickerAsync().then(EmojiMart => { EmojiPicker = EmojiMart.Picker; - Emoji = EmojiMart.Emoji; - // populate custom emoji in search - EmojiMart.emojiIndex.search('', { custom: buildCustomEmojis(this.props.custom_emojis, autoPlay) }); + Emoji = EmojiMart.Emoji; + this.setState({ loading: false }); }).catch(() => { this.setState({ loading: false }); @@ -327,7 +341,7 @@ export default class EmojiPickerDropdown extends React.PureComponent { } render () { - const { intl, onPickEmoji } = this.props; + const { intl, onPickEmoji, autoPlay, onSkinTone, skinTone } = this.props; const title = intl.formatMessage(messages.emoji); const { active, loading } = this.state; @@ -347,6 +361,9 @@ export default class EmojiPickerDropdown extends React.PureComponent { loading={loading} onClose={this.onHideDropdown} onPick={onPickEmoji} + autoPlay={autoPlay} + onSkinTone={onSkinTone} + skinTone={skinTone} /> </Overlay> </div> diff --git a/app/javascript/mastodon/features/compose/containers/emoji_picker_dropdown_container.js b/app/javascript/mastodon/features/compose/containers/emoji_picker_dropdown_container.js index cecc46320..56cc6c3b1 100644 --- a/app/javascript/mastodon/features/compose/containers/emoji_picker_dropdown_container.js +++ b/app/javascript/mastodon/features/compose/containers/emoji_picker_dropdown_container.js @@ -1,9 +1,17 @@ import { connect } from 'react-redux'; import EmojiPickerDropdown from '../components/emoji_picker_dropdown'; +import { changeSetting } from '../../../actions/settings'; const mapStateToProps = state => ({ custom_emojis: state.get('custom_emojis'), autoPlay: state.getIn(['meta', 'auto_play_gif']), + skinTone: state.getIn(['settings', 'skinTone']), }); -export default connect(mapStateToProps)(EmojiPickerDropdown); +const mapDispatchToProps = dispatch => ({ + onSkinTone: skinTone => { + dispatch(changeSetting(['skinTone'], skinTone)); + }, +}); + +export default connect(mapStateToProps, mapDispatchToProps)(EmojiPickerDropdown); diff --git a/app/javascript/mastodon/reducers/settings.js b/app/javascript/mastodon/reducers/settings.js index dd2d76ec0..3063ddadd 100644 --- a/app/javascript/mastodon/reducers/settings.js +++ b/app/javascript/mastodon/reducers/settings.js @@ -7,6 +7,8 @@ import uuid from '../uuid'; const initialState = ImmutableMap({ onboarded: false, + skinTone: 1, + home: ImmutableMap({ shows: ImmutableMap({ reblog: true, diff --git a/app/javascript/styles/components.scss b/app/javascript/styles/components.scss index aecc98e76..6c64528d6 100644 --- a/app/javascript/styles/components.scss +++ b/app/javascript/styles/components.scss @@ -2653,19 +2653,36 @@ button.icon-button.active i.fa-retweet { flex-direction: column; } -@keyframes pulse { - 0% { - opacity: 1; +@keyframes heartbeat { + from { + transform: scale(1); + transform-origin: center center; + animation-timing-function: ease-out; } - 100% { - opacity: 0.5; + 10% { + transform: scale(0.91); + animation-timing-function: ease-in; + } + + 17% { + transform: scale(0.98); + animation-timing-function: ease-out; + } + + 33% { + transform: scale(0.87); + animation-timing-function: ease-in; + } + + 45% { + transform: scale(1); + animation-timing-function: ease-out; } } .pulse-loading { - animation: pulse 1s ease-in-out infinite; - animation-direction: alternate; + animation: heartbeat 1.5s ease-in-out infinite both; } .emoji-picker-dropdown__menu { |