diff options
Diffstat (limited to 'app/javascript/flavours/glitch/features/composer/textarea/suggestions')
-rw-r--r-- | app/javascript/flavours/glitch/features/composer/textarea/suggestions/index.js | 43 | ||||
-rw-r--r-- | app/javascript/flavours/glitch/features/composer/textarea/suggestions/item/index.js | 101 |
2 files changed, 144 insertions, 0 deletions
diff --git a/app/javascript/flavours/glitch/features/composer/textarea/suggestions/index.js b/app/javascript/flavours/glitch/features/composer/textarea/suggestions/index.js new file mode 100644 index 000000000..dc72585f2 --- /dev/null +++ b/app/javascript/flavours/glitch/features/composer/textarea/suggestions/index.js @@ -0,0 +1,43 @@ +// Package imports. +import PropTypes from 'prop-types'; +import React from 'react'; +import ImmutablePropTypes from 'react-immutable-proptypes'; + +// Components. +import ComposerTextareaSuggestionsItem from './item'; + +// The component. +export default function ComposerTextareaSuggestions ({ + hidden, + onSuggestionClick, + suggestions, + value, +}) { + + // The result. + return ( + <div + className='composer--textarea--suggestions' + hidden={hidden || !suggestions || suggestions.isEmpty()} + > + {!hidden && suggestions ? suggestions.map( + (suggestion, index) => ( + <ComposerTextareaSuggestionsItem + index={index} + key={typeof suggestion === 'object' ? suggestion.id : suggestion} + onClick={onSuggestionClick} + selected={index === value} + suggestion={suggestion} + /> + ) + ) : null} + </div> + ); +} + +ComposerTextareaSuggestions.propTypes = { + hidden: PropTypes.bool, + onSuggestionClick: PropTypes.func, + suggestions: ImmutablePropTypes.list, + value: PropTypes.number, +}; diff --git a/app/javascript/flavours/glitch/features/composer/textarea/suggestions/item/index.js b/app/javascript/flavours/glitch/features/composer/textarea/suggestions/item/index.js new file mode 100644 index 000000000..d2c794ae9 --- /dev/null +++ b/app/javascript/flavours/glitch/features/composer/textarea/suggestions/item/index.js @@ -0,0 +1,101 @@ +// Package imports. +import classNames from 'classnames'; +import PropTypes from 'prop-types'; +import React from 'react'; + +// Components. +import AccountContainer from 'flavours/glitch/containers/account_container'; + +// Utils. +import { unicodeMapping } from 'flavours/glitch/util/emoji'; +import { assignHandlers } from 'flavours/glitch/util/react_helpers'; + +// Gets our asset host from the environment, if available. +const assetHost = ((process || {}).env || {}).CDN_HOST || ''; + +// Handlers. +const handlers = { + + // Handles a click on a suggestion. + handleClick (e) { + const { + index, + onClick, + } = this.props; + if (onClick) { + e.preventDefault(); + onClick(index); + } + }, +}; + +// The component. +export default class ComposerTextareaSuggestionsItem extends React.Component { + + // Constructor. + constructor (props) { + super(props); + assignHandlers(this, handlers); + } + + // Rendering. + render () { + const { handleClick } = this.handlers; + const { + selected, + suggestion, + } = this.props; + const computedClass = classNames('composer--textarea--suggestions--item', { selected }); + + // The result. + return ( + <div + className={computedClass} + onMouseDown={handleClick} + role='button' + tabIndex='0' + > + { // If the suggestion is an object, then we render an emoji. + // Otherwise, we render an account. + typeof suggestion === 'object' ? function () { + const url = function () { + if (suggestion.custom) { + return suggestion.imageUrl; + } else { + const mapping = unicodeMapping[suggestion.native] || unicodeMapping[suggestion.native.replace(/\uFE0F$/, '')]; + if (!mapping) { + return null; + } + return `${assetHost}/emoji/${mapping.filename}.svg`; + } + }(); + return url ? ( + <div className='emoji'> + <img + alt={suggestion.native || suggestion.colons} + className='emojione' + src={url} + /> + {suggestion.colons} + </div> + ) : null; + }() : ( + <AccountContainer + id={suggestion} + small + /> + ) + } + </div> + ); + } + +} + +// Props. +ComposerTextareaSuggestionsItem.propTypes = { + index: PropTypes.number, + onClick: PropTypes.func, + selected: PropTypes.bool, + suggestion: PropTypes.oneOfType([PropTypes.object, PropTypes.string]), +}; |