import EmojiData from '@emoji-mart/data'; import classNames from 'classnames'; import { supportsPassiveEvents } from 'detect-passive-events'; import { Picker } from 'emoji-mart'; import PropTypes from 'prop-types'; import React, { useRef, useEffect } from 'react'; import ImmutablePropTypes from 'react-immutable-proptypes'; import { defineMessages, injectIntl } from 'react-intl'; import Overlay from 'react-overlays/lib/Overlay'; import { IconButton } from 'soapbox/components/ui'; import { buildCustomEmojis } from '../../emoji/emoji'; // import { EmojiPicker as EmojiPickerAsync } from '../../ui/util/async-components'; const messages = defineMessages({ emoji: { id: 'emoji_button.label', defaultMessage: 'Insert emoji' }, emoji_search: { id: 'emoji_button.search', defaultMessage: 'Search…' }, emoji_not_found: { id: 'emoji_button.not_found', defaultMessage: 'No emoji\'s found.' }, custom: { id: 'emoji_button.custom', defaultMessage: 'Custom' }, recent: { id: 'emoji_button.recent', defaultMessage: 'Frequently used' }, search_results: { id: 'emoji_button.search_results', defaultMessage: 'Search results' }, people: { id: 'emoji_button.people', defaultMessage: 'People' }, nature: { id: 'emoji_button.nature', defaultMessage: 'Nature' }, food: { id: 'emoji_button.food', defaultMessage: 'Food & Drink' }, activity: { id: 'emoji_button.activity', defaultMessage: 'Activity' }, travel: { id: 'emoji_button.travel', defaultMessage: 'Travel & Places' }, objects: { id: 'emoji_button.objects', defaultMessage: 'Objects' }, symbols: { id: 'emoji_button.symbols', defaultMessage: 'Symbols' }, flags: { id: 'emoji_button.flags', defaultMessage: 'Flags' }, }); function EmojiPicker({ customEmojis }) { const ref = useRef(); useEffect(() => { const emojis = buildCustomEmojis(customEmojis); const input = { data: EmojiData, ref, custom: [{ emojis }] }; // console.log(input); new Picker(input); }, []); return
; } // let EmojiPicker, Emoji; // load asynchronously // const backgroundImageFn = () => require('emoji-datasource/img/twitter/sheets/32.png'); const listenerOptions = supportsPassiveEvents ? { passive: true } : false; // const categoriesSort = [ // 'recent', // 'custom', // 'people', // 'nature', // 'foods', // 'activity', // 'places', // 'objects', // 'symbols', // 'flags', // ]; // class ModifierPickerMenu extends React.PureComponent { // // static propTypes = { // active: PropTypes.bool, // onSelect: PropTypes.func.isRequired, // onClose: PropTypes.func.isRequired, // }; // // handleClick = e => { // this.props.onSelect(e.currentTarget.getAttribute('data-index') * 1); // } // // componentDidUpdate(prevProps) { // if (this.props.active) { // this.attachListeners(); // } else { // this.removeListeners(); // } // } // // componentWillUnmount() { // this.removeListeners(); // } // // handleDocumentClick = e => { // if (this.node && !this.node.contains(e.target)) { // this.props.onClose(); // } // } // // attachListeners() { // document.addEventListener('click', this.handleDocumentClick, false); // document.addEventListener('touchend', this.handleDocumentClick, listenerOptions); // } // // removeListeners() { // document.removeEventListener('click', this.handleDocumentClick, false); // document.removeEventListener('touchend', this.handleDocumentClick, listenerOptions); // } // // setRef = c => { // this.node = c; // } // // render() { // const { active } = this.props; // // return ( //
// // // // // // //
// ); // } // // } // class ModifierPicker extends React.PureComponent { // // static propTypes = { // active: PropTypes.bool, // modifier: PropTypes.number, // onChange: PropTypes.func, // onClose: PropTypes.func, // onOpen: PropTypes.func, // }; // // handleClick = () => { // if (this.props.active) { // this.props.onClose(); // } else { // this.props.onOpen(); // } // } // // handleSelect = modifier => { // this.props.onChange(modifier); // this.props.onClose(); // } // // render() { // const { active, modifier } = this.props; // // return ( //
// // //
// ); // } // // } @injectIntl class EmojiPickerMenu extends React.PureComponent { static propTypes = { custom_emojis: ImmutablePropTypes.list, // frequentlyUsedEmojis: PropTypes.arrayOf(PropTypes.string), loading: PropTypes.bool, onClose: PropTypes.func.isRequired, onPick: PropTypes.func.isRequired, style: PropTypes.object, placement: PropTypes.string, arrowOffsetLeft: PropTypes.string, arrowOffsetTop: PropTypes.string, intl: PropTypes.object.isRequired, // skinTone: PropTypes.number.isRequired, onSkinTone: PropTypes.func.isRequired, }; static defaultProps = { style: {}, loading: true, frequentlyUsedEmojis: [], }; state = { modifierOpen: false, placement: null, }; handleDocumentClick = e => { if (this.node && !this.node.contains(e.target)) { this.props.onClose(); } } componentDidMount() { document.addEventListener('click', this.handleDocumentClick, false); document.addEventListener('touchend', this.handleDocumentClick, listenerOptions); } componentWillUnmount() { document.removeEventListener('click', this.handleDocumentClick, false); document.removeEventListener('touchend', this.handleDocumentClick, listenerOptions); } setRef = c => { this.node = c; } getI18n = () => { const { intl } = this.props; return { search: intl.formatMessage(messages.emoji_search), notfound: intl.formatMessage(messages.emoji_not_found), categories: { search: intl.formatMessage(messages.search_results), recent: intl.formatMessage(messages.recent), people: intl.formatMessage(messages.people), nature: intl.formatMessage(messages.nature), foods: intl.formatMessage(messages.food), activity: intl.formatMessage(messages.activity), places: intl.formatMessage(messages.travel), objects: intl.formatMessage(messages.objects), symbols: intl.formatMessage(messages.symbols), flags: intl.formatMessage(messages.flags), custom: intl.formatMessage(messages.custom), }, }; } handleClick = emoji => { if (!emoji.native) { emoji.native = emoji.colons; } this.props.onClose(); this.props.onPick(emoji); } handleModifierOpen = () => { this.setState({ modifierOpen: true }); } handleModifierClose = () => { this.setState({ modifierOpen: false }); } handleModifierChange = modifier => { this.props.onSkinTone(modifier); } render() { // const { loading, style, intl, custom_emojis, skinTone, frequentlyUsedEmojis } = this.props; const { loading, style, custom_emojis } = this.props; if (loading) { return
; } // const title = intl.formatMessage(messages.emoji); const { modifierOpen } = this.state; return (
); // return ( //
// // // //
// ); } } export default @injectIntl class EmojiPickerDropdown extends React.PureComponent { static propTypes = { custom_emojis: ImmutablePropTypes.list, frequentlyUsedEmojis: PropTypes.arrayOf(PropTypes.string), intl: PropTypes.object.isRequired, onPickEmoji: PropTypes.func.isRequired, onSkinTone: PropTypes.func.isRequired, skinTone: PropTypes.number.isRequired, }; state = { active: false, loading: false, }; setRef = (c) => { this.dropdown = c; } onShowDropdown = (e) => { e.stopPropagation(); this.setState({ active: true }); // if (!EmojiPicker) { // this.setState({ loading: true }); // // EmojiPickerAsync().then(EmojiMart => { // EmojiPicker = EmojiMart.Picker; // Emoji = EmojiMart.Emoji; // // this.setState({ loading: false }); // }).catch(() => { // this.setState({ loading: false }); // }); // } const { top } = e.target.getBoundingClientRect(); this.setState({ placement: top * 2 < innerHeight ? 'bottom' : 'top' }); } onHideDropdown = () => { this.setState({ active: false }); } onToggle = (e) => { if (!this.state.loading && (!e.key || e.key === 'Enter')) { if (this.state.active) { this.onHideDropdown(); } else { this.onShowDropdown(e); } } } handleKeyDown = e => { if (e.key === 'Escape') { this.onHideDropdown(); } } setTargetRef = c => { this.target = c; } findTarget = () => { return this.target; } render() { const { intl, onPickEmoji, onSkinTone, skinTone, frequentlyUsedEmojis } = this.props; const title = intl.formatMessage(messages.emoji); const { active, loading, placement } = this.state; return (
); } }