The code powering m.abunchtell.com https://m.abunchtell.com
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

146 lines
4.2 KiB

  1. import React from 'react';
  2. import Dropdown, { DropdownTrigger, DropdownContent } from 'react-simple-dropdown';
  3. import PropTypes from 'prop-types';
  4. import { defineMessages, injectIntl } from 'react-intl';
  5. import { EmojiPicker as EmojiPickerAsync } from '../../ui/util/async-components';
  6. const messages = defineMessages({
  7. emoji: { id: 'emoji_button.label', defaultMessage: 'Insert emoji' },
  8. emoji_search: { id: 'emoji_button.search', defaultMessage: 'Search...' },
  9. people: { id: 'emoji_button.people', defaultMessage: 'People' },
  10. nature: { id: 'emoji_button.nature', defaultMessage: 'Nature' },
  11. food: { id: 'emoji_button.food', defaultMessage: 'Food & Drink' },
  12. activity: { id: 'emoji_button.activity', defaultMessage: 'Activity' },
  13. travel: { id: 'emoji_button.travel', defaultMessage: 'Travel & Places' },
  14. objects: { id: 'emoji_button.objects', defaultMessage: 'Objects' },
  15. symbols: { id: 'emoji_button.symbols', defaultMessage: 'Symbols' },
  16. flags: { id: 'emoji_button.flags', defaultMessage: 'Flags' },
  17. });
  18. const settings = {
  19. imageType: 'png',
  20. sprites: false,
  21. imagePathPNG: '/emoji/',
  22. };
  23. let EmojiPicker; // load asynchronously
  24. @injectIntl
  25. export default class EmojiPickerDropdown extends React.PureComponent {
  26. static propTypes = {
  27. intl: PropTypes.object.isRequired,
  28. onPickEmoji: PropTypes.func.isRequired,
  29. };
  30. state = {
  31. active: false,
  32. loading: false,
  33. };
  34. setRef = (c) => {
  35. this.dropdown = c;
  36. }
  37. handleChange = (data) => {
  38. this.dropdown.hide();
  39. this.props.onPickEmoji(data);
  40. }
  41. onShowDropdown = () => {
  42. this.setState({ active: true });
  43. if (!EmojiPicker) {
  44. this.setState({ loading: true });
  45. EmojiPickerAsync().then(TheEmojiPicker => {
  46. EmojiPicker = TheEmojiPicker.default;
  47. this.setState({ loading: false });
  48. }).catch(() => {
  49. // TODO: show the user an error?
  50. this.setState({ loading: false });
  51. });
  52. }
  53. }
  54. onHideDropdown = () => {
  55. this.setState({ active: false });
  56. }
  57. onToggle = (e) => {
  58. if (!this.state.loading && (!e.key || e.key === 'Enter')) {
  59. if (this.state.active) {
  60. this.onHideDropdown();
  61. } else {
  62. this.onShowDropdown();
  63. }
  64. }
  65. }
  66. onEmojiPickerKeyDown = (e) => {
  67. if (e.key === 'Escape') {
  68. this.onHideDropdown();
  69. }
  70. }
  71. render () {
  72. const { intl } = this.props;
  73. const categories = {
  74. people: {
  75. title: intl.formatMessage(messages.people),
  76. emoji: 'smile',
  77. },
  78. nature: {
  79. title: intl.formatMessage(messages.nature),
  80. emoji: 'hamster',
  81. },
  82. food: {
  83. title: intl.formatMessage(messages.food),
  84. emoji: 'pizza',
  85. },
  86. activity: {
  87. title: intl.formatMessage(messages.activity),
  88. emoji: 'soccer',
  89. },
  90. travel: {
  91. title: intl.formatMessage(messages.travel),
  92. emoji: 'earth_americas',
  93. },
  94. objects: {
  95. title: intl.formatMessage(messages.objects),
  96. emoji: 'bulb',
  97. },
  98. symbols: {
  99. title: intl.formatMessage(messages.symbols),
  100. emoji: 'clock9',
  101. },
  102. flags: {
  103. title: intl.formatMessage(messages.flags),
  104. emoji: 'flag_gb',
  105. },
  106. };
  107. const { active, loading } = this.state;
  108. const title = intl.formatMessage(messages.emoji);
  109. return (
  110. <Dropdown ref={this.setRef} className='emoji-picker__dropdown' active={active && !loading} onShow={this.onShowDropdown} onHide={this.onHideDropdown}>
  111. <DropdownTrigger className='emoji-button' title={title} aria-label={title} aria-pressed={active} role='button' onKeyDown={this.onToggle} tabIndex={0} >
  112. <img
  113. className={`emojione ${active && loading ? 'pulse-loading' : ''}`}
  114. alt='🙂'
  115. src='/emoji/1f602.svg'
  116. />
  117. </DropdownTrigger>
  118. <DropdownContent className='dropdown__left'>
  119. {
  120. this.state.active && !this.state.loading &&
  121. (<EmojiPicker emojione={settings} onChange={this.handleChange} searchPlaceholder={intl.formatMessage(messages.emoji_search)} onKeyDown={this.onEmojiPickerKeyDown} categories={categories} search />)
  122. }
  123. </DropdownContent>
  124. </Dropdown>
  125. );
  126. }
  127. }