diff --git a/app/soapbox/features/compose/components/emoji_picker_dropdown.js b/app/soapbox/features/compose/components/emoji_picker_dropdown.js index ca1fff018..7419f0edf 100644 --- a/app/soapbox/features/compose/components/emoji_picker_dropdown.js +++ b/app/soapbox/features/compose/components/emoji_picker_dropdown.js @@ -1,7 +1,9 @@ +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 from 'react'; +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'; @@ -9,7 +11,7 @@ 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'; +// import { EmojiPicker as EmojiPickerAsync } from '../../ui/util/async-components'; const messages = defineMessages({ emoji: { id: 'emoji_button.label', defaultMessage: 'Insert emoji' }, @@ -28,127 +30,141 @@ const messages = defineMessages({ flags: { id: 'emoji_button.flags', defaultMessage: 'Flags' }, }); -let EmojiPicker, Emoji; // load asynchronously +function EmojiPicker({ customEmojis }) { + const ref = useRef(); -const backgroundImageFn = () => require('emoji-datasource/img/twitter/sheets/32.png'); + 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', -]; +// const categoriesSort = [ +// 'recent', +// 'custom', +// 'people', +// 'nature', +// 'foods', +// 'activity', +// 'places', +// 'objects', +// 'symbols', +// 'flags', +// ]; -class ModifierPickerMenu extends React.PureComponent { +// 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 ( +//
+// +// +// +// +// +// +//
+// ); +// } +// +// } - 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 ( -
- - -
- ); - } - -} +// 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), + // frequentlyUsedEmojis: PropTypes.arrayOf(PropTypes.string), loading: PropTypes.bool, onClose: PropTypes.func.isRequired, onPick: PropTypes.func.isRequired, @@ -157,7 +173,7 @@ class EmojiPickerMenu extends React.PureComponent { arrowOffsetLeft: PropTypes.string, arrowOffsetTop: PropTypes.string, intl: PropTypes.object.isRequired, - skinTone: PropTypes.number.isRequired, + // skinTone: PropTypes.number.isRequired, onSkinTone: PropTypes.func.isRequired, }; @@ -236,46 +252,53 @@ class EmojiPickerMenu extends React.PureComponent { } render() { - const { loading, style, intl, custom_emojis, skinTone, frequentlyUsedEmojis } = this.props; + // 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 title = intl.formatMessage(messages.emoji); const { modifierOpen } = this.state; return (
- - - +
); + + // return ( + //
+ // + // + // + //
+ // ); } } @@ -306,18 +329,18 @@ class EmojiPickerDropdown extends React.PureComponent { 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 }); - }); - } + // 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' }); diff --git a/app/soapbox/features/emoji/emoji.js b/app/soapbox/features/emoji/emoji.js index 0ce74c4de..909629979 100644 --- a/app/soapbox/features/emoji/emoji.js +++ b/app/soapbox/features/emoji/emoji.js @@ -90,12 +90,13 @@ export const buildCustomEmojis = (customEmojis, autoplay = false) => { emojis.push({ id: name, name, - short_names: [name], - text: '', - emoticons: [], keywords: [name], + skins: [{ src: url }], imageUrl: url, - custom: true, + // short_names: [name], + // text: '', + // emoticons: [], + // custom: true, }); }); diff --git a/app/soapbox/features/soapbox_config/components/icon_picker_dropdown.js b/app/soapbox/features/soapbox_config/components/icon_picker_dropdown.js index 8c2bdf473..9a75ed32f 100644 --- a/app/soapbox/features/soapbox_config/components/icon_picker_dropdown.js +++ b/app/soapbox/features/soapbox_config/components/icon_picker_dropdown.js @@ -1,6 +1,7 @@ +// import EmojiData from '@emoji-mart/data'; import classNames from 'classnames'; import { supportsPassiveEvents } from 'detect-passive-events'; -import Picker from 'emoji-mart/dist-es/components/picker/picker'; +import { Picker } from 'emoji-mart'; import PropTypes from 'prop-types'; import React from 'react'; import { defineMessages, injectIntl } from 'react-intl'; diff --git a/app/soapbox/features/ui/util/async-components.ts b/app/soapbox/features/ui/util/async-components.ts index a6379b130..ffb3d9ed2 100644 --- a/app/soapbox/features/ui/util/async-components.ts +++ b/app/soapbox/features/ui/util/async-components.ts @@ -1,6 +1,6 @@ -export function EmojiPicker() { - return import(/* webpackChunkName: "emoji_picker" */'../../emoji/emoji_picker'); -} +// export function EmojiPicker() { +// return import(/* webpackChunkName: "emoji_picker" */'../../emoji/emoji_picker'); +// } export function Notifications() { return import(/* webpackChunkName: "features/notifications" */'../../notifications'); diff --git a/package.json b/package.json index cb9ab4481..8fdbe6fe4 100644 --- a/package.json +++ b/package.json @@ -50,6 +50,7 @@ "@babel/preset-react": "^7.17.12", "@babel/preset-typescript": "^7.17.12", "@babel/runtime": "^7.18.3", + "@emoji-mart/data": "^1.0.2", "@fontsource/inter": "^4.5.1", "@fontsource/roboto": "^4.5.0", "@gamestdio/websocket": "^0.3.2", @@ -113,7 +114,7 @@ "detect-passive-events": "^2.0.0", "dotenv": "^8.0.0", "emoji-datasource": "5.0.0", - "emoji-mart": "npm:emoji-mart-lazyload", + "emoji-mart": "^5.1.0", "entities": "^3.0.1", "es6-symbol": "^3.1.1", "escape-html": "^1.0.3", @@ -196,7 +197,7 @@ "webpack": "^5.72.1", "webpack-assets-manifest": "^5.1.0", "webpack-bundle-analyzer": "^4.5.0", - "webpack-cli": "^4.9.2", + "webpack-cli": "^4.10.0", "webpack-deadcode-plugin": "^0.1.16", "webpack-merge": "^5.8.0", "wicg-inert": "^3.1.1" diff --git a/yarn.lock b/yarn.lock index 8d2248152..5cc86ff0b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1271,7 +1271,7 @@ dependencies: regenerator-runtime "^0.12.0" -"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.10.2", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.1", "@babel/runtime@^7.2.0", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2": +"@babel/runtime@^7.1.2", "@babel/runtime@^7.10.2", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.1", "@babel/runtime@^7.2.0", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2": version "7.15.4" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.15.4.tgz#fd17d16bfdf878e6dd02d19753a39fa8a8d9c84a" integrity sha512-99catp6bHCaxr4sJ/DbTGgHS4+Rs2RVd2g7iOap6SLGPDknRK9ztKNsE/Fg6QhSeh1FGE5f6gHGQmvvn3I3xhw== @@ -1382,6 +1382,11 @@ resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.5.tgz#9283c9ce5b289a3c4f61c12757469e59377f81f3" integrity sha512-6nFkfkmSeV/rqSaS4oWHgmpnYw194f6hmWF5is6b0J1naJZoiD0NTc9AiUwPHvWsowkjuHErCZT1wa0jg+BLIA== +"@emoji-mart/data@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@emoji-mart/data/-/data-1.0.2.tgz#2b94c5b5f2c79611c12238438dad9516576a09ab" + integrity sha512-+ZdzBM4llDJJvjuCEsdOYVoSlNA16MMmxKG3oF5LARkwhx6N5clr6phzneWV1qIwJsywqwG7NaBjH8DV6yzjcA== + "@es-joy/jsdoccomment@~0.29.0": version "0.29.0" resolved "https://registry.yarnpkg.com/@es-joy/jsdoccomment/-/jsdoccomment-0.29.0.tgz#527c7eefadeaf5c5d0c3b2721b5fa425d2119e98" @@ -3102,22 +3107,22 @@ "@webassemblyjs/ast" "1.11.1" "@xtuc/long" "4.2.2" -"@webpack-cli/configtest@^1.1.1": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@webpack-cli/configtest/-/configtest-1.1.1.tgz#9f53b1b7946a6efc2a749095a4f450e2932e8356" - integrity sha512-1FBc1f9G4P/AxMqIgfZgeOTuRnwZMten8E7zap5zgpPInnCrP8D4Q81+4CWIch8i/Nf7nXjP0v6CjjbHOrXhKg== +"@webpack-cli/configtest@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@webpack-cli/configtest/-/configtest-1.2.0.tgz#7b20ce1c12533912c3b217ea68262365fa29a6f5" + integrity sha512-4FB8Tj6xyVkyqjj1OaTqCjXYULB9FMkqQ8yGrZjRDrYh0nOE+7Lhs45WioWQQMV+ceFlE368Ukhe6xdvJM9Egg== -"@webpack-cli/info@^1.4.1": - version "1.4.1" - resolved "https://registry.yarnpkg.com/@webpack-cli/info/-/info-1.4.1.tgz#2360ea1710cbbb97ff156a3f0f24556e0fc1ebea" - integrity sha512-PKVGmazEq3oAo46Q63tpMr4HipI3OPfP7LiNOEJg963RMgT0rqheag28NCML0o3GIzA3DmxP1ZIAv9oTX1CUIA== +"@webpack-cli/info@^1.5.0": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@webpack-cli/info/-/info-1.5.0.tgz#6c78c13c5874852d6e2dd17f08a41f3fe4c261b1" + integrity sha512-e8tSXZpw2hPl2uMJY6fsMswaok5FdlGNRTktvFk2sD8RjH0hE2+XistawJx1vmKteh4NmGmNUrp+Tb2w+udPcQ== dependencies: envinfo "^7.7.3" -"@webpack-cli/serve@^1.6.1": - version "1.6.1" - resolved "https://registry.yarnpkg.com/@webpack-cli/serve/-/serve-1.6.1.tgz#0de2875ac31b46b6c5bb1ae0a7d7f0ba5678dffe" - integrity sha512-gNGTiTrjEVQ0OcVnzsRSqTxaBSr+dmTfm+qJsCDluky8uhdLWep7Gcr62QsAKHTMxjCS/8nEITsmFAhfIx+QSw== +"@webpack-cli/serve@^1.7.0": + version "1.7.0" + resolved "https://registry.yarnpkg.com/@webpack-cli/serve/-/serve-1.7.0.tgz#e1993689ac42d2b16e9194376cfb6753f6254db1" + integrity sha512-oxnCNGj88fL+xzV+dacXs44HcDwf1ovs3AuEzvP7mqXw7fQntqIhQ1BRmynh4qEKQSSSRSWVyXRjmTbZIX9V2Q== "@xtuc/ieee754@^1.2.0": version "1.2.0" @@ -5038,14 +5043,10 @@ emoji-datasource@5.0.0: resolved "https://registry.yarnpkg.com/emoji-datasource/-/emoji-datasource-5.0.0.tgz#1522fdba3c52223a1cf5a1c1fc282935400eaa06" integrity sha512-LuvLWFnxznTH++GytEzpzOPUo1SB+6CUFqIlVETJJ3x9fpyMCKFfyqberbhMLOpT1qcNe+km+zoyBeUSC3u5Rw== -"emoji-mart@npm:emoji-mart-lazyload": - version "3.0.1-j" - resolved "https://registry.yarnpkg.com/emoji-mart-lazyload/-/emoji-mart-lazyload-3.0.1-j.tgz#87a90d30b79d9145ece078d53e3e683c1a10ce9c" - integrity sha512-0wKF7MR0/iAeCIoiBLY+JjXCugycTgYRC2SL0y9/bjNSQlbeMdzILmPQJAufU/mgLFDUitOvjxLDhOZ9yxZ48g== - dependencies: - "@babel/runtime" "^7.0.0" - intersection-observer "^0.12.0" - prop-types "^15.6.0" +emoji-mart@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/emoji-mart/-/emoji-mart-5.1.0.tgz#8a36a872e1297747342d1385bd7b7141ac2f4365" + integrity sha512-ytXgeemyw4FormPQqWd35Vh06ZSnQFhVUqW51kASZzzjhQOPSGtiN3VCC7vDq94Pkxmsbet+Gps/qj5N90mEnw== emoji-regex@^8.0.0: version "8.0.0" @@ -11822,18 +11823,18 @@ webpack-bundle-analyzer@^4.5.0: sirv "^1.0.7" ws "^7.3.1" -webpack-cli@^4.9.2: - version "4.9.2" - resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-4.9.2.tgz#77c1adaea020c3f9e2db8aad8ea78d235c83659d" - integrity sha512-m3/AACnBBzK/kMTcxWHcZFPrw/eQuY4Df1TxvIWfWM2x7mRqBQCqKEd96oCUa9jkapLBaFfRce33eGDb4Pr7YQ== +webpack-cli@^4.10.0: + version "4.10.0" + resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-4.10.0.tgz#37c1d69c8d85214c5a65e589378f53aec64dab31" + integrity sha512-NLhDfH/h4O6UOy+0LSso42xvYypClINuMNBVVzX4vX98TmTaTUxwRbXdhucbFMd2qLaCTcLq/PdYrvi8onw90w== dependencies: "@discoveryjs/json-ext" "^0.5.0" - "@webpack-cli/configtest" "^1.1.1" - "@webpack-cli/info" "^1.4.1" - "@webpack-cli/serve" "^1.6.1" + "@webpack-cli/configtest" "^1.2.0" + "@webpack-cli/info" "^1.5.0" + "@webpack-cli/serve" "^1.7.0" colorette "^2.0.14" commander "^7.0.0" - execa "^5.0.0" + cross-spawn "^7.0.3" fastest-levenshtein "^1.0.12" import-local "^3.0.2" interpret "^2.2.0"