diff options
author | Eugen Rochko <eugen@zeonfederated.com> | 2017-09-23 01:41:00 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-09-23 01:41:00 +0200 |
commit | 846cd4e8381c891816cf814582304b534db4ee5f (patch) | |
tree | fb7c718bd3071bf5128f6c270901623aab54a0f0 /app/javascript | |
parent | 0de82dd316839ed329504bfbf9bd0f2d3d96e654 (diff) |
Switch from EmojiOne to Twemoji, different emoji picker (#5046)
* Switch from EmojiOne to Twemoji, different emoji picker * Make emoji-mart use a local spritesheet * Fix emojify test * yarn manage:translations
Diffstat (limited to 'app/javascript')
41 files changed, 640 insertions, 272 deletions
diff --git a/app/javascript/mastodon/emoji.js b/app/javascript/mastodon/emoji.js index 7a0dab9d1..407b21b4b 100644 --- a/app/javascript/mastodon/emoji.js +++ b/app/javascript/mastodon/emoji.js @@ -3,6 +3,8 @@ import Trie from 'substring-trie'; const trie = new Trie(Object.keys(unicodeMapping)); +const assetHost = process.env.CDN_HOST || ''; + const emojify = (str, customEmojis = {}) => { let rtn = ''; for (;;) { @@ -37,7 +39,7 @@ const emojify = (str, customEmojis = {}) => { str = str.slice(i + 1); } else { const [filename, shortCode] = unicodeMapping[match]; - rtn += str.slice(0, i) + `<img draggable="false" class="emojione" alt="${match}" title=":${shortCode}:" src="/emoji/${filename}.svg" />`; + rtn += str.slice(0, i) + `<img draggable="false" class="emojione" alt="${match}" title=":${shortCode}:" src="${assetHost}/emoji/${filename}.svg" />`; str = str.slice(i + match.length); } } diff --git a/app/javascript/mastodon/emojione_light.js b/app/javascript/mastodon/emojione_light.js index 0d07d012f..ecba35d03 100644 --- a/app/javascript/mastodon/emojione_light.js +++ b/app/javascript/mastodon/emojione_light.js @@ -9,5 +9,5 @@ const excluded = ['®', '©', '™']; module.exports.unicodeMapping = Object.keys(emojione.jsEscapeMap) .filter(c => !excluded.includes(c)) .map(unicodeStr => [unicodeStr, mappedUnicode[emojione.jsEscapeMap[unicodeStr]]]) - .map(([unicodeStr, shortCode]) => ({ [unicodeStr]: [emojione.emojioneList[shortCode].fname, shortCode.slice(1, shortCode.length - 1)] })) + .map(([unicodeStr, shortCode]) => ({ [unicodeStr]: [emojione.emojioneList[shortCode].fname.replace(/^0+/g, ''), shortCode.slice(1, shortCode.length - 1)] })) .reduce((x, y) => Object.assign(x, y), { }); diff --git a/app/javascript/mastodon/features/compose/components/compose_form.js b/app/javascript/mastodon/features/compose/components/compose_form.js index 413142d81..bb747b611 100644 --- a/app/javascript/mastodon/features/compose/components/compose_form.js +++ b/app/javascript/mastodon/features/compose/components/compose_form.js @@ -138,7 +138,7 @@ export default class ComposeForm extends ImmutablePureComponent { handleEmojiPick = (data) => { const position = this.autosuggestTextarea.textarea.selectionStart; - const emojiChar = data.unicode.split('-').map(code => String.fromCodePoint(parseInt(code, 16))).join(''); + const emojiChar = data.native; this._restoreCaret = position + emojiChar.length + 1; this.props.onPickEmoji(position, data); } 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 9d05b7a34..43e175be5 100644 --- a/app/javascript/mastodon/features/compose/components/emoji_picker_dropdown.js +++ b/app/javascript/mastodon/features/compose/components/emoji_picker_dropdown.js @@ -1,12 +1,17 @@ import React from 'react'; -import Dropdown, { DropdownTrigger, DropdownContent } from 'react-simple-dropdown'; import PropTypes from 'prop-types'; import { defineMessages, injectIntl } from 'react-intl'; import { EmojiPicker as EmojiPickerAsync } from '../../ui/util/async-components'; +import { Overlay } from 'react-overlays'; +import classNames from 'classnames'; 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 emojos!! (╯°□°)╯︵ ┻━┻' }, + 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' }, @@ -17,13 +22,234 @@ const messages = defineMessages({ flags: { id: 'emoji_button.flags', defaultMessage: 'Flags' }, }); -const settings = { - imageType: 'png', - sprites: false, - imagePathPNG: '/emoji/', -}; +const assetHost = process.env.CDN_HOST || ''; -let EmojiPicker; // load asynchronously +let EmojiPicker, Emoji; // load asynchronously + +const backgroundImageFn = () => `${assetHost}/emoji/sheet.png`; + +class ModifierPickerMenu extends React.PureComponent { + + static propTypes = { + active: PropTypes.bool, + onSelect: PropTypes.func.isRequired, + onClose: PropTypes.func.isRequired, + }; + + handleClick = (e) => { + const modifier = [].slice.call(e.currentTarget.parentNode.children).indexOf(e.target) + 1; + this.props.onSelect(modifier); + } + + componentWillReceiveProps (nextProps) { + if (nextProps.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, false); + } + + removeListeners () { + document.removeEventListener('click', this.handleDocumentClick, false); + document.removeEventListener('touchend', this.handleDocumentClick, false); + } + + setRef = c => { + this.node = c; + } + + render () { + const { active } = this.props; + + return ( + <div className='emoji-picker-dropdown__modifiers__menu' style={{ display: active ? 'block' : 'none' }} ref={this.setRef}> + <button onClick={this.handleClick}><Emoji emoji='fist' set='twitter' size={22} sheetSize={32} skin={1} backgroundImageFn={backgroundImageFn} /></button> + <button onClick={this.handleClick}><Emoji emoji='fist' set='twitter' size={22} sheetSize={32} skin={2} backgroundImageFn={backgroundImageFn} /></button> + <button onClick={this.handleClick}><Emoji emoji='fist' set='twitter' size={22} sheetSize={32} skin={3} backgroundImageFn={backgroundImageFn} /></button> + <button onClick={this.handleClick}><Emoji emoji='fist' set='twitter' size={22} sheetSize={32} skin={4} backgroundImageFn={backgroundImageFn} /></button> + <button onClick={this.handleClick}><Emoji emoji='fist' set='twitter' size={22} sheetSize={32} skin={5} backgroundImageFn={backgroundImageFn} /></button> + <button onClick={this.handleClick}><Emoji emoji='fist' set='twitter' size={22} sheetSize={32} skin={6} backgroundImageFn={backgroundImageFn} /></button> + </div> + ); + } + +} + +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 ( + <div className='emoji-picker-dropdown__modifiers'> + <Emoji emoji='fist' set='twitter' size={22} sheetSize={32} skin={modifier} onClick={this.handleClick} backgroundImageFn={backgroundImageFn} /> + <ModifierPickerMenu active={active} onSelect={this.handleSelect} onClose={this.props.onClose} /> + </div> + ); + } + +} + +@injectIntl +class EmojiPickerMenu extends React.PureComponent { + + static propTypes = { + 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, + }; + + static defaultProps = { + style: {}, + loading: true, + placement: 'bottom', + }; + + state = { + modifierOpen: false, + modifier: 1, + }; + + 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, false); + } + + componentWillUnmount () { + document.removeEventListener('click', this.handleDocumentClick, false); + document.removeEventListener('touchend', this.handleDocumentClick, false); + } + + 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 => { + this.props.onClose(); + this.props.onPick(emoji); + } + + handleModifierOpen = () => { + this.setState({ modifierOpen: true }); + } + + handleModifierClose = () => { + this.setState({ modifierOpen: false }); + } + + handleModifierChange = modifier => { + if (modifier !== this.state.modifier) { + this.setState({ modifier }); + } + } + + render () { + const { loading, style, intl } = this.props; + + if (loading) { + return <div style={{ width: 299 }} />; + } + + const title = intl.formatMessage(messages.emoji); + const { modifierOpen, modifier } = this.state; + + return ( + <div className={classNames('emoji-picker-dropdown__menu', { selecting: modifierOpen })} style={style} ref={this.setRef}> + <EmojiPicker + perLine={8} + emojiSize={22} + sheetSize={32} + color='' + emoji='' + set='twitter' + title={title} + i18n={this.getI18n()} + onClick={this.handleClick} + skin={modifier} + backgroundImageFn={backgroundImageFn} + /> + + <ModifierPicker + active={modifierOpen} + modifier={modifier} + onOpen={this.handleModifierOpen} + onClose={this.handleModifierClose} + onChange={this.handleModifierChange} + /> + </div> + ); + } + +} @injectIntl export default class EmojiPickerDropdown extends React.PureComponent { @@ -42,20 +268,17 @@ export default class EmojiPickerDropdown extends React.PureComponent { this.dropdown = c; } - handleChange = (data) => { - this.dropdown.hide(); - this.props.onPickEmoji(data); - } - onShowDropdown = () => { this.setState({ active: true }); + if (!EmojiPicker) { this.setState({ loading: true }); - EmojiPickerAsync().then(TheEmojiPicker => { - EmojiPicker = TheEmojiPicker.default; + + EmojiPickerAsync().then(EmojiMart => { + EmojiPicker = EmojiMart.Picker; + Emoji = EmojiMart.Emoji; this.setState({ loading: false }); }).catch(() => { - // TODO: show the user an error? this.setState({ loading: false }); }); } @@ -75,70 +298,39 @@ export default class EmojiPickerDropdown extends React.PureComponent { } } - onEmojiPickerKeyDown = (e) => { + handleKeyDown = e => { if (e.key === 'Escape') { this.onHideDropdown(); } } - render () { - const { intl } = this.props; + setTargetRef = c => { + this.target = c; + } - const categories = { - people: { - title: intl.formatMessage(messages.people), - emoji: 'smile', - }, - nature: { - title: intl.formatMessage(messages.nature), - emoji: 'hamster', - }, - food: { - title: intl.formatMessage(messages.food), - emoji: 'pizza', - }, - activity: { - title: intl.formatMessage(messages.activity), - emoji: 'soccer', - }, - travel: { - title: intl.formatMessage(messages.travel), - emoji: 'earth_americas', - }, - objects: { - title: intl.formatMessage(messages.objects), - emoji: 'bulb', - }, - symbols: { - title: intl.formatMessage(messages.symbols), - emoji: 'clock9', - }, - flags: { - title: intl.formatMessage(messages.flags), - emoji: 'flag_gb', - }, - }; + findTarget = () => { + return this.target; + } - const { active, loading } = this.state; + render () { + const { intl, onPickEmoji } = this.props; const title = intl.formatMessage(messages.emoji); + const { active, loading } = this.state; return ( - <Dropdown ref={this.setRef} className='emoji-picker__dropdown' active={active && !loading} onShow={this.onShowDropdown} onHide={this.onHideDropdown}> - <DropdownTrigger className='emoji-button' title={title} aria-label={title} aria-expanded={active} role='button' onKeyDown={this.onToggle} tabIndex={0} > + <div className='emoji-picker-dropdown' onKeyDown={this.handleKeyDown}> + <div ref={this.setTargetRef} className='emoji-button' title={title} aria-label={title} aria-expanded={active} role='button' onClick={this.onToggle} onKeyDown={this.onToggle} tabIndex={0}> <img - className={`emojione ${active && loading ? 'pulse-loading' : ''}`} + className={classNames('emojione', { 'pulse-loading': active && loading })} alt='🙂' - src='/emoji/1f602.svg' + src={`${assetHost}/emoji/1f602.svg`} /> - </DropdownTrigger> - - <DropdownContent className='dropdown__left'> - { - this.state.active && !this.state.loading && - (<EmojiPicker emojione={settings} onChange={this.handleChange} searchPlaceholder={intl.formatMessage(messages.emoji_search)} onKeyDown={this.onEmojiPickerKeyDown} categories={categories} search />) - } - </DropdownContent> - </Dropdown> + </div> + + <Overlay show={active} placement='bottom' target={this.findTarget}> + <EmojiPickerMenu loading={loading} onClose={this.onHideDropdown} onPick={onPickEmoji} /> + </Overlay> + </div> ); } diff --git a/app/javascript/mastodon/features/ui/util/async-components.js b/app/javascript/mastodon/features/ui/util/async-components.js index c0b93a3a1..bd2fca337 100644 --- a/app/javascript/mastodon/features/ui/util/async-components.js +++ b/app/javascript/mastodon/features/ui/util/async-components.js @@ -1,5 +1,5 @@ export function EmojiPicker () { - return import(/* webpackChunkName: "emojione_picker" */'emojione-picker'); + return import(/* webpackChunkName: "emoji_picker" */'emoji-mart'); } export function Compose () { diff --git a/app/javascript/mastodon/locales/ar.json b/app/javascript/mastodon/locales/ar.json index 3a6fa2874..e27c19f4e 100644 --- a/app/javascript/mastodon/locales/ar.json +++ b/app/javascript/mastodon/locales/ar.json @@ -67,13 +67,17 @@ "embed.instructions": "Embed this status on your website by copying the code below.", "embed.preview": "Here is what it will look like:", "emoji_button.activity": "الأنشطة", + "emoji_button.custom": "Custom", "emoji_button.flags": "الأعلام", "emoji_button.food": "الطعام والشراب", "emoji_button.label": "أدرج إيموجي", "emoji_button.nature": "الطبيعة", + "emoji_button.not_found": "No emojos!! (╯°□°)╯︵ ┻━┻", "emoji_button.objects": "أشياء", "emoji_button.people": "الناس", + "emoji_button.recent": "Frequently used", "emoji_button.search": "ابحث...", + "emoji_button.search_results": "Search results", "emoji_button.symbols": "رموز", "emoji_button.travel": "أماكن و أسفار", "empty_column.community": "الخط الزمني المحلي فارغ. اكتب شيئا ما للعامة كبداية.", diff --git a/app/javascript/mastodon/locales/bg.json b/app/javascript/mastodon/locales/bg.json index 9afe2d038..85ede7dfd 100644 --- a/app/javascript/mastodon/locales/bg.json +++ b/app/javascript/mastodon/locales/bg.json @@ -67,13 +67,17 @@ "embed.instructions": "Embed this status on your website by copying the code below.", "embed.preview": "Here is what it will look like:", "emoji_button.activity": "Activity", + "emoji_button.custom": "Custom", "emoji_button.flags": "Flags", "emoji_button.food": "Food & Drink", "emoji_button.label": "Insert emoji", "emoji_button.nature": "Nature", + "emoji_button.not_found": "No emojos!! (╯°□°)╯︵ ┻━┻", "emoji_button.objects": "Objects", "emoji_button.people": "People", + "emoji_button.recent": "Frequently used", "emoji_button.search": "Search...", + "emoji_button.search_results": "Search results", "emoji_button.symbols": "Symbols", "emoji_button.travel": "Travel & Places", "empty_column.community": "The local timeline is empty. Write something publicly to get the ball rolling!", diff --git a/app/javascript/mastodon/locales/ca.json b/app/javascript/mastodon/locales/ca.json index 7d45b4d6b..901241322 100644 --- a/app/javascript/mastodon/locales/ca.json +++ b/app/javascript/mastodon/locales/ca.json @@ -67,13 +67,17 @@ "embed.instructions": "Embed this status on your website by copying the code below.", "embed.preview": "Here is what it will look like:", "emoji_button.activity": "Activitat", + "emoji_button.custom": "Custom", "emoji_button.flags": "Flags", "emoji_button.food": "Menjar i Beure", "emoji_button.label": "Inserir emoji", "emoji_button.nature": "Natura", + "emoji_button.not_found": "No emojos!! (╯°□°)╯︵ ┻━┻", "emoji_button.objects": "Objectes", "emoji_button.people": "Gent", + "emoji_button.recent": "Frequently used", "emoji_button.search": "Cercar...", + "emoji_button.search_results": "Search results", "emoji_button.symbols": "Símbols", "emoji_button.travel": "Viatges i Llocs", "empty_column.community": "La línia de temps local és buida. Escriu alguna cosa públicament per fer rodar la pilota!", diff --git a/app/javascript/mastodon/locales/de.json b/app/javascript/mastodon/locales/de.json index 712c635c8..c5fbc3a4c 100644 --- a/app/javascript/mastodon/locales/de.json +++ b/app/javascript/mastodon/locales/de.json @@ -67,13 +67,17 @@ "embed.instructions": "Du kannst diesen Beitrag auf deiner Webseite einbetten, in dem du den folgenden Code einfügst.", "embed.preview": "So wird es aussehen:", "emoji_button.activity": "Aktivitäten", + "emoji_button.custom": "Custom", "emoji_button.flags": "Flaggen", "emoji_button.food": "Essen und Trinken", "emoji_button.label": "Emoji einfügen", "emoji_button.nature": "Natur", + "emoji_button.not_found": "No emojos!! (╯°□°)╯︵ ┻━┻", "emoji_button.objects": "Dinge", "emoji_button.people": "Leute", + "emoji_button.recent": "Frequently used", "emoji_button.search": "Suche…", + "emoji_button.search_results": "Search results", "emoji_button.symbols": "Symbole", "emoji_button.travel": "Reise und Orte", "empty_column.community": "Die lokale Zeitleiste ist leer. Schreibe etwas öffentlich, um den Ball ins Rollen zu bringen!", diff --git a/app/javascript/mastodon/locales/defaultMessages.json b/app/javascript/mastodon/locales/defaultMessages.json index 42df796a7..b9a951a7f 100644 --- a/app/javascript/mastodon/locales/defaultMessages.json +++ b/app/javascript/mastodon/locales/defaultMessages.json @@ -517,6 +517,22 @@ "id": "emoji_button.search" }, { + "defaultMessage": "No emojos!! (╯°□°)╯︵ ┻━┻", + "id": "emoji_button.not_found" + }, + { + "defaultMessage": "Custom", + "id": "emoji_button.custom" + }, + { + "defaultMessage": "Frequently used", + "id": "emoji_button.recent" + }, + { + "defaultMessage": "Search results", + "id": "emoji_button.search_results" + }, + { "defaultMessage": "People", "id": "emoji_button.people" }, @@ -1334,15 +1350,6 @@ { "descriptors": [ { - "defaultMessage": "Close", - "id": "lightbox.close" - } - ], - "path": "app/javascript/mastodon/features/ui/components/video_modal.json" - }, - { - "descriptors": [ - { "defaultMessage": "Play", "id": "video.play" }, diff --git a/app/javascript/mastodon/locales/en.json b/app/javascript/mastodon/locales/en.json index 436079aeb..7ce57c4fe 100644 --- a/app/javascript/mastodon/locales/en.json +++ b/app/javascript/mastodon/locales/en.json @@ -67,13 +67,17 @@ "embed.instructions": "Embed this status on your website by copying the code below.", "embed.preview": "Here is what it will look like:", "emoji_button.activity": "Activity", + "emoji_button.custom": "Custom", "emoji_button.flags": "Flags", "emoji_button.food": "Food & Drink", "emoji_button.label": "Insert emoji", "emoji_button.nature": "Nature", + "emoji_button.not_found": "No emojos!! (╯°□°)╯︵ ┻━┻", "emoji_button.objects": "Objects", "emoji_button.people": "People", + "emoji_button.recent": "Frequently used", "emoji_button.search": "Search...", + "emoji_button.search_results": "Search results", "emoji_button.symbols": "Symbols", "emoji_button.travel": "Travel & Places", "empty_column.community": "The local timeline is empty. Write something publicly to get the ball rolling!", diff --git a/app/javascript/mastodon/locales/eo.json b/app/javascript/mastodon/locales/eo.json index 945fcd8e0..8dfb05bc3 100644 --- a/app/javascript/mastodon/locales/eo.json +++ b/app/javascript/mastodon/locales/eo.json @@ -67,13 +67,17 @@ "embed.instructions": "Embed this status on your website by copying the code below.", "embed.preview": "Here is what it will look like:", "emoji_button.activity": "Activity", + "emoji_button.custom": "Custom", "emoji_button.flags": "Flags", "emoji_button.food": "Food & Drink", "emoji_button.label": "Insert emoji", "emoji_button.nature": "Nature", + "emoji_button.not_found": "No emojos!! (╯°□°)╯︵ ┻━┻", "emoji_button.objects": "Objects", "emoji_button.people": "People", + "emoji_button.recent": "Frequently used", "emoji_button.search": "Search...", + "emoji_button.search_results": "Search results", "emoji_button.symbols": "Symbols", "emoji_button.travel": "Travel & Places", "empty_column.community": "The local timeline is empty. Write something publicly to get the ball rolling!", diff --git a/app/javascript/mastodon/locales/es.json b/app/javascript/mastodon/locales/es.json index 5182b5094..0489da64d 100644 --- a/app/javascript/mastodon/locales/es.json +++ b/app/javascript/mastodon/locales/es.json @@ -67,13 +67,17 @@ "embed.instructions": "Añade este toot a tu sitio web con el siguiente código.", "embed.preview": "Así es como se verá:", "emoji_button.activity": "Actividad", + "emoji_button.custom": "Custom", "emoji_button.flags": "Marcas", "emoji_button.food": "Comida y bebida", "emoji_button.label": "Insertar emoji", "emoji_button.nature": "Naturaleza", + "emoji_button.not_found": "No emojos!! (╯°□°)╯︵ ┻━┻", "emoji_button.objects": "Objetos", "emoji_button.people": "Gente", + "emoji_button.recent": "Frequently used", "emoji_button.search": "Buscar…", + "emoji_button.search_results": "Search results", "emoji_button.symbols": "Símbolos", "emoji_button.travel": "Viajes y lugares", "empty_column.community": "La línea de tiempo local está vacía. ¡Escribe algo para empezar la fiesta!", diff --git a/app/javascript/mastodon/locales/fa.json b/app/javascript/mastodon/locales/fa.json index 23f4a41d6..64a9172cf 100644 --- a/app/javascript/mastodon/locales/fa.json +++ b/app/javascript/mastodon/locales/fa.json @@ -67,13 +67,17 @@ "embed.instructions": "برای جاگذاری این نوشته در سایت خودتان، کد زیر را کپی کنید.", "embed.preview": "نوشتهٔ جاگذاریشده این گونه به نظر خواهد رسید:", "emoji_button.activity": "فعالیت", + "emoji_button.custom": "Custom", "emoji_button.flags": "پرچمها", "emoji_button.food": "غذا و نوشیدنی", "emoji_button.label": "افزودن شکلک", "emoji_button.nature": "طبیعت", + "emoji_button.not_found": "No emojos!! (╯°□°)╯︵ ┻━┻", "emoji_button.objects": "اشیا", "emoji_button.people": "مردم", + "emoji_button.recent": "Frequently used", "emoji_button.search": "جستجو...", + "emoji_button.search_results": "Search results", "emoji_button.symbols": "نمادها", "emoji_button.travel": "سفر و مکان", "empty_column.community": "فهرست نوشتههای محلی خالی است. چیزی بنویسید تا چرخش بچرخد!", diff --git a/app/javascript/mastodon/locales/fi.json b/app/javascript/mastodon/locales/fi.json index fc409a932..ea8433107 100644 --- a/app/javascript/mastodon/locales/fi.json +++ b/app/javascript/mastodon/locales/fi.json @@ -67,13 +67,17 @@ "embed.instructions": "Embed this status on your website by copying the code below.", "embed.preview": "Here is what it will look like:", "emoji_button.activity": "Activity", + "emoji_button.custom": "Custom", "emoji_button.flags": "Flags", "emoji_button.food": "Food & Drink", "emoji_button.label": "Insert emoji", "emoji_button.nature": "Nature", + "emoji_button.not_found": "No emojos!! (╯°□°)╯︵ ┻━┻", "emoji_button.objects": "Objects", "emoji_button.people": "People", + "emoji_button.recent": "Frequently used", "emoji_button.search": "Search...", + "emoji_button.search_results": "Search results", "emoji_button.symbols": "Symbols", "emoji_button.travel": "Travel & Places", "empty_column.community": "The local timeline is empty. Write something publicly to get the ball rolling!", diff --git a/app/javascript/mastodon/locales/fr.json b/app/javascript/mastodon/locales/fr.json index 5a436891b..a4ecc6c17 100644 --- a/app/javascript/mastodon/locales/fr.json +++ b/app/javascript/mastodon/locales/fr.json @@ -67,13 +67,17 @@ "embed.instructions": "Intégrez ce statut à votre site en copiant ce code ci-dessous.", "embed.preview": "Il apparaîtra comme cela : ", "emoji_button.activity": "Activités", + "emoji_button.custom": "Custom", "emoji_button.flags": "Drapeaux", "emoji_button.food": "Boire et manger", "emoji_button.label": "Insérer un emoji", "emoji_button.nature": "Nature", + "emoji_button.not_found": "No emojos!! (╯°□°)╯︵ ┻━┻", "emoji_button.objects": "Objets", "emoji_button.people": "Personnages", + "emoji_button.recent": "Frequently used", "emoji_button.search": "Recherche…", + "emoji_button.search_results": "Search results", "emoji_button.symbols": "Symboles", "emoji_button.travel": "Lieux et voyages", "empty_column.community": "Le fil public local est vide. Écrivez-donc quelque chose pour le remplir !", diff --git a/app/javascript/mastodon/locales/he.json b/app/javascript/mastodon/locales/he.json index 06b401d39..dbba9d3bc 100644 --- a/app/javascript/mastodon/locales/he.json +++ b/app/javascript/mastodon/locales/he.json @@ -67,13 +67,17 @@ "embed.instructions": "Embed this status on your website by copying the code below.", "embed.preview": "Here is what it will look like:", "emoji_button.activity": "פעילות", + "emoji_button.custom": "Custom", "emoji_button.flags": "דגלים", "emoji_button.food": "אוכל ושתיה", "emoji_button.label": "הוספת אמוג'י", "emoji_button.nature": "טבע", + "emoji_button.not_found": "No emojos!! (╯°□°)╯︵ ┻━┻", "emoji_button.objects": "חפצים", "emoji_button.people": "אנשים", + "emoji_button.recent": "Frequently used", "emoji_button.search": "חיפוש...", + "emoji_button.search_results": "Search results", "emoji_button.symbols": "סמלים", "emoji_button.travel": "טיולים ואתרים", "empty_column.community": "טור הסביבה ריק. יש לפרסם משהו כדי שדברים יתרחילו להתגלגל!", diff --git a/app/javascript/mastodon/locales/hr.json b/app/javascript/mastodon/locales/hr.json index cb28ce9c1..4c877d95b 100644 --- a/app/javascript/mastodon/locales/hr.json +++ b/app/javascript/mastodon/locales/hr.json @@ -67,13 +67,17 @@ "embed.instructions": "Embed this status on your website by copying the code below.", "embed.preview": "Here is what it will look like:", "emoji_button.activity": "Aktivnost", + "emoji_button.custom": "Custom", "emoji_button.flags": "Zastave", "emoji_button.food": "Hrana & Piće", "emoji_button.label": "Umetni smajlije", "emoji_button.nature": "Priroda", + "emoji_button.not_found": "No emojos!! (╯°□°)╯︵ ┻━┻", "emoji_button.objects": "Objekti", "emoji_button.people": "Ljudi", + "emoji_button.recent": "Frequently used", "emoji_button.search": "Traži...", + "emoji_button.search_results": "Search results", "emoji_button.symbols": "Simboli", "emoji_button.travel": "Putovanja & Mjesta", "empty_column.community": "Lokalni timeline je prazan. Napiši nešto javno kako bi pokrenuo stvari!", diff --git a/app/javascript/mastodon/locales/hu.json b/app/javascript/mastodon/locales/hu.json index a13e4fee2..699fc265d 100644 --- a/app/javascript/mastodon/locales/hu.json +++ b/app/javascript/mastodon/locales/hu.json @@ -67,13 +67,17 @@ "embed.instructions": "Embed this status on your website by copying the code below.", "embed.preview": "Here is what it will look like:", "emoji_button.activity": "Activity", + "emoji_button.custom": "Custom", "emoji_button.flags": "Flags", "emoji_button.food": "Food & Drink", "emoji_button.label": "Insert emoji", "emoji_button.nature": "Nature", + "emoji_button.not_found": "No emojos!! (╯°□°)╯︵ ┻━┻", "emoji_button.objects": "Objects", "emoji_button.people": "People", + "emoji_button.recent": "Frequently used", "emoji_button.search": "Search...", + "emoji_button.search_results": "Search results", "emoji_button.symbols": "Symbols", "emoji_button.travel": "Travel & Places", "empty_column.community": "The local timeline is empty. Write something publicly to get the ball rolling!", diff --git a/app/javascript/mastodon/locales/id.json b/app/javascript/mastodon/locales/id.json index 349423cce..cbacc68ff 100644 --- a/app/javascript/mastodon/locales/id.json +++ b/app/javascript/mastodon/locales/id.json @@ -67,13 +67,17 @@ "embed.instructions": "Embed this status on your website by copying the code below.", "embed.preview": "Here is what it will look like:", "emoji_button.activity": "Aktivitas", + "emoji_button.custom": "Custom", "emoji_button.flags": "Bendera", "emoji_button.food": "Makanan & Minuman", "emoji_button.label": "Tambahkan emoji", "emoji_button.nature": "Alam", + "emoji_button.not_found": "No emojos!! (╯°□°)╯︵ ┻━┻", "emoji_button.objects": "Benda-benda", "emoji_button.people": "Orang", + "emoji_button.recent": "Frequently used", "emoji_button.search": "Cari...", + "emoji_button.search_results": "Search results", "emoji_button.symbols": "Simbol", "emoji_button.travel": "Tempat Wisata", "empty_column.community": "Linimasa lokal masih kosong. Tulis sesuatu secara publik dan buat roda berputar!", diff --git a/app/javascript/mastodon/locales/io.json b/app/javascript/mastodon/locales/io.json index 5f19509e2..9b2cc27d3 100644 --- a/app/javascript/mastodon/locales/io.json +++ b/app/javascript/mastodon/locales/io.json @@ -67,13 +67,17 @@ "embed.instructions": "Embed this status on your website by copying the code below.", "embed.preview": "Here is what it will look like:", "emoji_button.activity": "Activity", + "emoji_button.custom": "Custom", "emoji_button.flags": "Flags", "emoji_button.food": "Food & Drink", "emoji_button.label": "Insertar emoji", "emoji_button.nature": "Nature", + "emoji_button.not_found": "No emojos!! (╯°□°)╯︵ ┻━┻", "emoji_button.objects": "Objects", "emoji_button.people": "People", + "emoji_button.recent": "Frequently used", "emoji_button.search": "Search...", + "emoji_button.search_results": "Search results", "emoji_button.symbols": "Symbols", "emoji_button.travel": "Travel & Places", "empty_column.community": "La lokala tempolineo esas vakua. Skribez ulo publike por iniciar la agiveso!", diff --git a/app/javascript/mastodon/locales/it.json b/app/javascript/mastodon/locales/it.json index cedbb947c..2106e59c7 100644 --- a/app/javascript/mastodon/locales/it.json +++ b/app/javascript/mastodon/locales/it.json @@ -67,13 +67,17 @@ "embed.instructions": "Embed this status on your website by copying the code below.", "embed.preview": "Here is what it will look like:", "emoji_button.activity": "Activity", + "emoji_button.custom": "Custom", "emoji_button.flags": "Flags", "emoji_button.food": "Food & Drink", "emoji_button.label": "Inserisci emoji", "emoji_button.nature": "Nature", + "emoji_button.not_found": "No emojos!! (╯°□°)╯︵ ┻━┻", "emoji_button.objects": "Objects", "emoji_button.people": "People", + "emoji_button.recent": "Frequently used", "emoji_button.search": "Search...", + "emoji_button.search_results": "Search results", "emoji_button.symbols": "Symbols", "emoji_button.travel": "Travel & Places", "empty_column.community": "La timeline locale è vuota. Condividi qualcosa pubblicamente per dare inizio alla festa!", diff --git a/app/javascript/mastodon/locales/ja.json b/app/javascript/mastodon/locales/ja.json index e78ac4c26..013cd6ef1 100644 --- a/app/javascript/mastodon/locales/ja.json +++ b/app/javascript/mastodon/locales/ja.json @@ -67,13 +67,17 @@ "embed.instructions": "下記のコードをコピーしてウェブサイトに埋め込みます。", "embed.preview": "表示例:", "emoji_button.activity": "活動", + "emoji_button.custom": "Custom", "emoji_button.flags": "国旗", "emoji_button.food": "食べ物", "emoji_button.label": "絵文字を追加", "emoji_button.nature": "自然", + "emoji_button.not_found": "No emojos!! (╯°□°)╯︵ ┻━┻", "emoji_button.objects": "物", "emoji_button.people": "人々", + "emoji_button.recent": "Frequently used", "emoji_button.search": "検索...", + "emoji_button.search_results": "Search results", "emoji_button.symbols": "記号", "emoji_button.travel": "旅行と場所", "empty_column.community": "ローカルタイムラインはまだ使われていません。何か書いてみましょう!", diff --git a/app/javascript/mastodon/locales/ko.json b/app/javascript/mastodon/locales/ko.json index 46ed772cf..57d74ea6f 100644 --- a/app/javascript/mastodon/locales/ko.json +++ b/app/javascript/mastodon/locales/ko.json @@ -67,13 +67,17 @@ "embed.instructions": "Embed this status on your website by copying the code below.", "embed.preview": "Here is what it will look like:", "emoji_button.activity": "활동", + "emoji_button.custom": "Custom", "emoji_button.flags": "국기", "emoji_button.food": "음식", "emoji_button.label": "emoji를 추가", "emoji_button.nature": "자연", + "emoji_button.not_found": "No emojos!! (╯°□°)╯︵ ┻━┻", "emoji_button.objects": "물건", "emoji_button.people": "사람들", + "emoji_button.recent": "Frequently used", "emoji_button.search": "검색...", + "emoji_button.search_results": "Search results", "emoji_button.symbols": "기호", "emoji_button.travel": "여행과 장소", "empty_column.community": "로컬 타임라인에 아무 것도 없습니다. 아무거나 적어 보세요!", diff --git a/app/javascript/mastodon/locales/nl.json b/app/javascript/mastodon/locales/nl.json index b696bccfd..c9f837b20 100644 --- a/app/javascript/mastodon/locales/nl.json +++ b/app/javascript/mastodon/locales/nl.json @@ -33,9 +33,8 @@ "column.home": "Start", "column.mutes": "Genegeerde gebruikers", "column.notifications": "Meldingen", - "column.pins": "Pinned toot", - "column.public": "Globale tijdlijn", "column.pins": "Vastgezette toots", + "column.public": "Globale tijdlijn", "column_back_button.label": "terug", "column_header.hide_settings": "Instellingen verbergen", "column_header.moveLeft_settings": "Kolom naar links verplaatsen", @@ -68,13 +67,17 @@ "embed.instructions": "Embed deze toot op jouw website, door de onderstaande code te kopiëren.", "embed.preview": "Zo komt het eruit te zien:", "emoji_button.activity": "Activiteiten", + "emoji_button.custom": "Custom", "emoji_button.flags": "Vlaggen", "emoji_button.food": "Eten en drinken", "emoji_button.label": "Emoji toevoegen", "emoji_button.nature": "Natuur", + "emoji_button.not_found": "No emojos!! (╯°□°)╯︵ ┻━┻", "emoji_button.objects": "Voorwerpen", "emoji_button.people": "Mensen", + "emoji_button.recent": "Frequently used", "emoji_button.search": "Zoeken...", + "emoji_button.search_results": "Search results", "emoji_button.symbols": "Symbolen", "emoji_button.travel": "Reizen en plekken", "empty_column.community": "De lokale tijdlijn is nog leeg. Toot iets in het openbaar om de bal aan het rollen te krijgen!", @@ -87,7 +90,6 @@ "follow_request.authorize": "Goedkeuren", "follow_request.reject": "Afkeuren", "getting_started.appsshort": "Apps", - "getting_started.donate": "Doneren", "getting_started.faq": "FAQ", "getting_started.heading": "Beginnen", "getting_started.open_source_notice": "Mastodon is open-sourcesoftware. Je kunt bijdragen of problemen melden op GitHub via {github}.", @@ -112,10 +114,9 @@ "navigation_bar.info": "Uitgebreide informatie", "navigation_bar.logout": "Afmelden", "navigation_bar.mutes": "Genegeerde gebruikers", - "navigation_bar.pins": "Pinned toots", + "navigation_bar.pins": "Vastgezette toots", "navigation_bar.preferences": "Instellingen", "navigation_bar.public_timeline": "Globale tijdlijn", - "navigation_bar.pins": "Vastgezette toots", "notification.favourite": "{name} markeerde jouw toot als favoriet", "notification.follow": "{name} volgt jou nu", "notification.mention": "{name} vermeldde jou", diff --git a/app/javascript/mastodon/locales/no.json b/app/javascript/mastodon/locales/no.json index 742017c66..a34ee51f4 100644 --- a/app/javascript/mastodon/locales/no.json +++ b/app/javascript/mastodon/locales/no.json @@ -67,13 +67,17 @@ "embed.instructions": "Embed this status on your website by copying the code below.", "embed.preview": "Here is what it will look like:", "emoji_button.activity": "Aktivitet", + "emoji_button.custom": "Custom", "emoji_button.flags": "Flagg", "emoji_button.food": "Mat og drikke", "emoji_button.label": "Sett inn emoji", "emoji_button.nature": "Natur", + "emoji_button.not_found": "No emojos!! (╯°□°)╯︵ ┻━┻", "emoji_button.objects": "Objekter", "emoji_button.people": "Mennesker", + "emoji_button.recent": "Frequently used", "emoji_button.search": "Søk...", + "emoji_button.search_results": "Search results", "emoji_button.symbols": "Symboler", "emoji_button.travel": "Reise & steder", "empty_column.community": "Den lokale tidslinjen er tom. Skriv noe offentlig for å få snøballen til å rulle!", diff --git a/app/javascript/mastodon/locales/oc.json b/app/javascript/mastodon/locales/oc.json index 512e4120d..81babfb2b 100644 --- a/app/javascript/mastodon/locales/oc.json +++ b/app/javascript/mastodon/locales/oc.json @@ -67,13 +67,17 @@ "embed.instructions": "Embarcar aqueste estatut per lo far veire sus un site Internet en copiar lo còdi çai-jos.", "embed.preview": "Semblarà aquò : ", "emoji_button.activity": "Activitats", + "emoji_button.custom": "Custom", "emoji_button.flags": "Drapèus", "emoji_button.food": "Beure e manjar", "emoji_button.label": "Inserir un emoji", "emoji_button.nature": "Natura", + "emoji_button.not_found": "No emojos!! (╯°□°)╯︵ ┻━┻", "emoji_button.objects": "Objèctes", "emoji_button.people": "Gents", + "emoji_button.recent": "Frequently used", "emoji_button.search": "Cercar…", + "emoji_button.search_results": "Search results", "emoji_button.symbols": "Simbòls", "emoji_button.travel": "Viatges & lòcs", "empty_column.community": "Lo flux public local es void. Escrivètz quicòm per lo garnir !", diff --git a/app/javascript/mastodon/locales/pl.json b/app/javascript/mastodon/locales/pl.json index 1d2443690..a35668b6b 100644 --- a/app/javascript/mastodon/locales/pl.json +++ b/app/javascript/mastodon/locales/pl.json @@ -67,13 +67,17 @@ "embed.instructions": "Osadź ten status na swojej stronie wklejając poniższy kod.", "embed.preview": "Tak będzie to wyglądać:", "emoji_button.activity": "Aktywność", + "emoji_button.custom": "Custom", "emoji_button.flags": "Flagi", "emoji_button.food": "Żywność i napoje", "emoji_button.label": "Wstaw emoji", "emoji_button.nature": "Natura", + "emoji_button.not_found": "No emojos!! (╯°□°)╯︵ ┻━┻", "emoji_button.objects": "Objekty", "emoji_button.people": "Ludzie", + "emoji_button.recent": "Frequently used", "emoji_button.search": "Szukaj…", + "emoji_button.search_results": "Search results", "emoji_button.symbols": "Symbole", "emoji_button.travel": "Podróże i miejsca", "empty_column.community": "Lokalna oś czasu jest pusta. Napisz coś publicznie, aby zagaić!", diff --git a/app/javascript/mastodon/locales/pt-BR.json b/app/javascript/mastodon/locales/pt-BR.json index a5def0ad0..7ef7a9bc5 100644 --- a/app/javascript/mastodon/locales/pt-BR.json +++ b/app/javascript/mastodon/locales/pt-BR.json @@ -35,7 +35,6 @@ "column.notifications": "Notificações", "column.pins": "Postagens fixadas", "column.public": "Global", - "column.pins": "Postagens fixadas", "column_back_button.label": "Voltar", "column_header.hide_settings": "Esconder configurações", "column_header.moveLeft_settings": "Mover coluna para a esquerda", @@ -68,13 +67,17 @@ "embed.instructions": "Incorpore esta postagem em seu site copiando o código abaixo:", "embed.preview": "Aqui está uma previsão de como ficará:", "emoji_button.activity": "Atividades", + "emoji_button.custom": "Custom", "emoji_button.flags": "Bandeiras", "emoji_button.food": "Comidas & Bebidas", "emoji_button.label": "Inserir Emoji", "emoji_button.nature": "Natureza", + "emoji_button.not_found": "No emojos!! (╯°□°)╯︵ ┻━┻", "emoji_button.objects": "Objetos", "emoji_button.people": "Pessoas", + "emoji_button.recent": "Frequently used", "emoji_button.search": "Buscar...", + "emoji_button.search_results": "Search results", "emoji_button.symbols": "Símbolos", "emoji_button.travel": "Viagens & Lugares", "empty_column.community": "A timeline local está vazia. Escreva algo publicamente para começar!", @@ -114,9 +117,6 @@ "navigation_bar.pins": "Postagens fixadas", "navigation_bar.preferences": "Preferências", "navigation_bar.public_timeline": "Global", - "navigation_bar.preferences": "Preferências", - "navigation_bar.public_timeline": "Global", - "navigation_bar.pins": "Postagens fixadas", "notification.favourite": "{name} adicionou a sua postagem aos favoritos", "notification.follow": "{name} te seguiu", "notification.mention": "{name} te mencionou", diff --git a/app/javascript/mastodon/locales/pt.json b/app/javascript/mastodon/locales/pt.json index cff528f83..7f9681fff 100644 --- a/app/javascript/mastodon/locales/pt.json +++ b/app/javascript/mastodon/locales/pt.json @@ -67,13 +67,17 @@ "embed.instructions": "Embed this status on your website by copying the code below.", "embed.preview": "Here is what it will look like:", "emoji_button.activity": "Activity", + "emoji_button.custom": "Custom", "emoji_button.flags": "Flags", "emoji_button.food": "Food & Drink", "emoji_button.label": "Inserir Emoji", "emoji_button.nature": "Nature", + "emoji_button.not_found": "No emojos!! (╯°□°)╯︵ ┻━┻", "emoji_button.objects": "Objects", "emoji_button.people": "People", + "emoji_button.recent": "Frequently used", "emoji_button.search": "Search...", + "emoji_button.search_results": "Search results", "emoji_button.symbols": "Symbols", "emoji_button.travel": "Travel & Places", "empty_column.community": "Ainda não existem conteúdo local para mostrar!", diff --git a/app/javascript/mastodon/locales/ru.json b/app/javascript/mastodon/locales/ru.json index fcc147c87..f6094d630 100644 --- a/app/javascript/mastodon/locales/ru.json +++ b/app/javascript/mastodon/locales/ru.json @@ -67,13 +67,17 @@ "embed.instructions": "Embed this status on your website by copying the code below.", "embed.preview": "Here is what it will look like:", "emoji_button.activity": "Занятия", + "emoji_button.custom": "Custom", "emoji_button.flags": "Флаги", "emoji_button.food": "Еда и напитки", "emoji_button.label": "Вставить эмодзи", "emoji_button.nature": "Природа", + "emoji_button.not_found": "No emojos!! (╯°□°)╯︵ ┻━┻", "emoji_button.objects": "Предметы", "emoji_button.people": "Люди", + "emoji_button.recent": "Frequently used", "emoji_button.search": "Найти...", + "emoji_button.search_results": "Search results", "emoji_button.symbols": "Символы", "emoji_button.travel": "Путешествия", "empty_column.community": "Локальная лента пуста. Напишите что-нибудь, чтобы разогреть народ!", diff --git a/app/javascript/mastodon/locales/th.json b/app/javascript/mastodon/locales/th.json index f2752f5e0..c1b6b74e4 100644 --- a/app/javascript/mastodon/locales/th.json +++ b/app/javascript/mastodon/locales/th.json @@ -67,13 +67,17 @@ "embed.instructions": "Embed this status on your website by copying the code below.", "embed.preview": "Here is what it will look like:", "emoji_button.activity": "Activity", + "emoji_button.custom": "Custom", "emoji_button.flags": "Flags", "emoji_button.food": "Food & Drink", "emoji_button.label": "Insert emoji", "emoji_button.nature": "Nature", + "emoji_button.not_found": "No emojos!! (╯°□°)╯︵ ┻━┻", "emoji_button.objects": "Objects", "emoji_button.people": "People", + "emoji_button.recent": "Frequently used", "emoji_button.search": "Search...", + "emoji_button.search_results": "Search results", "emoji_button.symbols": "Symbols", "emoji_button.travel": "Travel & Places", "empty_column.community": "The local timeline is empty. Write something publicly to get the ball rolling!", diff --git a/app/javascript/mastodon/locales/tr.json b/app/javascript/mastodon/locales/tr.json index 2676b851c..b9b249bc0 100644 --- a/app/javascript/mastodon/locales/tr.json +++ b/app/javascript/mastodon/locales/tr.json @@ -67,13 +67,17 @@ "embed.instructions": "Embed this status on your website by copying the code below.", "embed.preview": "Here is what it will look like:", "emoji_button.activity": "Aktivite", + "emoji_button.custom": "Custom", "emoji_button.flags": "Bayraklar", "emoji_button.food": "Yiyecek ve İçecek", "emoji_button.label": "Emoji ekle", "emoji_button.nature": "Doğa", + "emoji_button.not_found": "No emojos!! (╯°□°)╯︵ ┻━┻", "emoji_button.objects": "Nesneler", "emoji_button.people": "İnsanlar", + "emoji_button.recent": "Frequently used", "emoji_button.search": "Emoji ara...", + "emoji_button.search_results": "Search results", "emoji_button.symbols": "Semboller", "emoji_button.travel": "Seyahat ve Yerler", "empty_column.community": "Yerel zaman tüneliniz boş. Daha fazla eğlence için herkese açık bir gönderi paylaşın.", diff --git a/app/javascript/mastodon/locales/uk.json b/app/javascript/mastodon/locales/uk.json index 6b5ab64ef..9d3e7ec7c 100644 --- a/app/javascript/mastodon/locales/uk.json +++ b/app/javascript/mastodon/locales/uk.json @@ -67,13 +67,17 @@ "embed.instructions": "Embed this status on your website by copying the code below.", "embed.preview": "Here is what it will look like:", "emoji_button.activity": "Заняття", + "emoji_button.custom": "Custom", "emoji_button.flags": "Прапори", "emoji_button.food": "Їжа та напої", "emoji_button.label": "Вставити емодзі", "emoji_button.nature": "Природа", + "emoji_button.not_found": "No emojos!! (╯°□°)╯︵ ┻━┻", "emoji_button.objects": "Предмети", "emoji_button.people": "Люди", + "emoji_button.recent": "Frequently used", "emoji_button.search": "Знайти...", + "emoji_button.search_results": "Search results", "emoji_button.symbols": "Символи", "emoji_button.travel": "Подорожі", "empty_column.community": "Локальна стрічка пуста. Напишіть щось, щоб розігріти народ!", diff --git a/app/javascript/mastodon/locales/zh-CN.json b/app/javascript/mastodon/locales/zh-CN.json index 6037e7581..70589adfb 100644 --- a/app/javascript/mastodon/locales/zh-CN.json +++ b/app/javascript/mastodon/locales/zh-CN.json @@ -67,13 +67,17 @@ "embed.instructions": "要内嵌此嘟文,请将以下代码贴进你的网站。", "embed.preview": "到时大概长这样:", "emoji_button.activity": "活动", + "emoji_button.custom": "Custom", "emoji_button.flags": "旗帜", "emoji_button.food": "食物和饮料", "emoji_button.label": "加入表情符号", "emoji_button.nature": "自然", + "emoji_button.not_found": "No emojos!! (╯°□°)╯︵ ┻━┻", "emoji_button.objects": "物体", "emoji_button.people": "人物", + "emoji_button.recent": "Frequently used", "emoji_button.search": "搜索…", + "emoji_button.search_results": "Search results", "emoji_button.symbols": "符号", "emoji_button.travel": "旅途和地点", "empty_column.community": "本站时间轴暂时未有内容,快嘟几个来抢头香啊!", diff --git a/app/javascript/mastodon/locales/zh-HK.json b/app/javascript/mastodon/locales/zh-HK.json index 66d32fb7e..e702a385e 100644 --- a/app/javascript/mastodon/locales/zh-HK.json +++ b/app/javascript/mastodon/locales/zh-HK.json @@ -67,13 +67,17 @@ "embed.instructions": "要內嵌此文章,請將以下代碼貼進你的網站。", "embed.preview": "看上去會是這樣:", "emoji_button.activity": "活動", + "emoji_button.custom": "Custom", "emoji_button.flags": "旗幟", "emoji_button.food": "飲飲食食", "emoji_button.label": "加入表情符號", "emoji_button.nature": "自然", + "emoji_button.not_found": "No emojos!! (╯°□°)╯︵ ┻━┻", "emoji_button.objects": "物品", "emoji_button.people": "人物", + "emoji_button.recent": "Frequently used", "emoji_button.search": "搜尋…", + "emoji_button.search_results": "Search results", "emoji_button.symbols": "符號", "emoji_button.travel": "旅遊景物", "empty_column.community": "本站時間軸暫時未有內容,快文章來搶頭香啊!", diff --git a/app/javascript/mastodon/locales/zh-TW.json b/app/javascript/mastodon/locales/zh-TW.json index b3cc6add7..964ce15c0 100644 --- a/app/javascript/mastodon/locales/zh-TW.json +++ b/app/javascript/mastodon/locales/zh-TW.json @@ -67,13 +67,17 @@ "embed.instructions": "要內嵌此貼文,請將以下代碼貼進你的網站。", "embed.preview": "看上去會變成這樣:", "emoji_button.activity": "活動", + "emoji_button.custom": "Custom", "emoji_button.flags": "旗幟", "emoji_button.food": "食物與飲料", "emoji_button.label": "插入表情符號", "emoji_button.nature": "自然", + "emoji_button.not_found": "No emojos!! (╯°□°)╯︵ ┻━┻", "emoji_button.objects": "物件", "emoji_button.people": "人", + "emoji_button.recent": "Frequently used", "emoji_button.search": "搜尋…", + "emoji_button.search_results": "Search results", "emoji_button.symbols": "符號", "emoji_button.travel": "旅遊與地點", "empty_column.community": "本地時間軸是空的。公開寫點什麼吧!", diff --git a/app/javascript/mastodon/reducers/compose.js b/app/javascript/mastodon/reducers/compose.js index 34f5dab7f..526dbd0c5 100644 --- a/app/javascript/mastodon/reducers/compose.js +++ b/app/javascript/mastodon/reducers/compose.js @@ -120,7 +120,7 @@ const insertSuggestion = (state, position, token, completion) => { }; const insertEmoji = (state, position, emojiData) => { - const emoji = emojiData.unicode.split('-').map(code => String.fromCodePoint(parseInt(code, 16))).join(''); + const emoji = emojiData.native; return state.withMutations(map => { map.update('text', oldText => `${oldText.slice(0, position)}${emoji} ${oldText.slice(position)}`); diff --git a/app/javascript/styles/application.scss b/app/javascript/styles/application.scss index f418ba699..0eb6ac6d8 100644 --- a/app/javascript/styles/application.scss +++ b/app/javascript/styles/application.scss @@ -15,6 +15,7 @@ @import 'accounts'; @import 'stream_entries'; @import 'components'; +@import 'emoji_picker'; @import 'about'; @import 'tables'; @import 'admin'; diff --git a/app/javascript/styles/components.scss b/app/javascript/styles/components.scss index e0a310b6c..abf5cfd5b 100644 --- a/app/javascript/styles/components.scss +++ b/app/javascript/styles/components.scss @@ -390,17 +390,11 @@ .compose-form__autosuggest-wrapper { position: relative; - .emoji-picker__dropdown { + .emoji-picker-dropdown { position: absolute; right: 5px; top: 5px; - &.dropdown--active::after { - border-color: transparent transparent $base-border-color; - bottom: -1px; - right: 8px; - } - ::-webkit-scrollbar-track:hover, ::-webkit-scrollbar-track:active { background-color: rgba($base-overlay-background, 0.3); @@ -2583,197 +2577,55 @@ button.icon-button.active i.fa-retweet { animation-direction: alternate; } -.emoji-dialog { - width: 245px; - height: 270px; +.emoji-picker-dropdown__menu { background: $simple-background-color; - box-sizing: border-box; + position: absolute; + box-shadow: 4px 4px 6px rgba($base-shadow-color, 0.4); border-radius: 4px; - overflow: hidden; - position: relative; - box-shadow: 0 0 8px rgba($base-shadow-color, 0.2); - - .emojione { - margin: 0; - width: 100%; - height: auto; - } - - .emoji-dialog-header { - padding: 0 10px; - - ul { - padding: 0; - margin: 0; - list-style: none; - } - - li { - display: inline-block; - box-sizing: border-box; - padding: 10px 5px; - cursor: pointer; - border-bottom: 2px solid transparent; - - .emoji { - width: 18px; - height: 18px; - } - - img, - svg { - width: 18px; - height: 18px; - filter: grayscale(100%); - } - - &:hover { - img, - svg { - filter: grayscale(0); - } - } - - &.active { - border-bottom-color: $ui-highlight-color; - - img, - svg { - filter: grayscale(0); - } - } - } - } - - .emoji-row { - box-sizing: border-box; - overflow-y: hidden; - padding-left: 10px; - - .emoji { - display: inline-block; - padding: 2.5px; - border-radius: 4px; - } - } - - .emoji-category-header { - box-sizing: border-box; - overflow-y: hidden; - padding: 10px 8px 10px 16px; - display: table; - - > * { - display: table-cell; - vertical-align: middle; - } - } + margin-top: 5px; - .emoji-category-title { - font-size: 12px; - text-transform: uppercase; - font-weight: 500; - color: darken($ui-secondary-color, 18%); - cursor: default; + .emoji-mart-scroll { + transition: opacity 200ms ease; } - .emoji-category-heading-decoration { - text-align: right; + &.selecting .emoji-mart-scroll { + opacity: 0.5; } +} - .modifiers { - list-style: none; - padding: 0; - margin: 0; - vertical-align: middle; - white-space: nowrap; - margin-top: 4px; - - li { - display: inline-block; - padding: 0 2px; - - &:last-of-type { - padding-right: 0; - } - } - - .modifier { - display: inline-block; - border-radius: 10px; - width: 15px; - height: 15px; - position: relative; - cursor: pointer; - - &.active::after { - content: ""; - display: block; - position: absolute; - width: 7px; - height: 7px; - border-radius: 10px; - border: 2px solid $base-border-color; - top: 2px; - left: 2px; - } - } - } +.emoji-picker-dropdown__modifiers { + position: absolute; + top: 60px; + right: 11px; + cursor: pointer; +} - .emoji-search-wrapper { - padding: 10px; - border-bottom: 1px solid lighten($ui-secondary-color, 4%); - } +.emoji-picker-dropdown__modifiers__menu { + position: absolute; + z-index: 4; + top: -4px; + left: -8px; + background: $simple-background-color; + border-radius: 4px; + box-shadow: 1px 2px 6px rgba($base-shadow-color, 0.2); + overflow: hidden; - .emoji-search { - font-size: 14px; - font-weight: 400; - padding: 7px 9px; - font-family: inherit; + button { display: block; - width: 100%; - background: rgba($ui-secondary-color, 0.3); - color: darken($ui-secondary-color, 18%); - border: 1px solid $ui-secondary-color; - border-radius: 4px; - } - - .emoji-categories-wrapper { - position: absolute; - top: 42px; - bottom: 0; - left: 0; - right: 0; - } - - .emoji-search-wrapper + .emoji-categories-wrapper { - top: 93px; - } - - .emoji-row .emoji { - img, - svg { - transition: transform 60ms ease-in-out; - } - - &:hover { - background: lighten($ui-secondary-color, 3%); + cursor: pointer; + border: 0; + padding: 4px 8px; + background: transparent; - img, - svg { - transform: translateZ(0) scale(1.2); - } + &:hover, + &:focus, + &:active { + background: rgba($ui-secondary-color, 0.4); } } - .emoji { - width: 22px; + .emoji-mart-emoji { height: 22px; - cursor: pointer; - - &:focus { - outline: 0; - } } } diff --git a/app/javascript/styles/emoji_picker.scss b/app/javascript/styles/emoji_picker.scss new file mode 100644 index 000000000..dbd9dbd97 --- /dev/null +++ b/app/javascript/styles/emoji_picker.scss @@ -0,0 +1,197 @@ +.emoji-mart { + &, + * { + box-sizing: border-box; + line-height: 1.15; + } + + font-size: 13px; + display: inline-block; + color: $ui-base-color; + + .emoji-mart-emoji { + padding: 6px; + } +} + +.emoji-mart-bar { + border: 0 solid darken($ui-secondary-color, 8%); + + &:first-child { + border-bottom-width: 1px; + border-top-left-radius: 5px; + border-top-right-radius: 5px; + background: $ui-secondary-color; + } + + &:last-child { + border-top-width: 1px; + border-bottom-left-radius: 5px; + border-bottom-right-radius: 5px; + display: none; + } +} + +.emoji-mart-anchors { + display: flex; + justify-content: space-between; + padding: 0 6px; + color: $ui-primary-color; + line-height: 0; +} + +.emoji-mart-anchor { + position: relative; + flex: 1; + text-align: center; + padding: 12px 4px; + overflow: hidden; + transition: color .1s ease-out; + cursor: pointer; + + &:hover { + color: darken($ui-primary-color, 4%); + } +} + +.emoji-mart-anchor-selected { + color: darken($ui-highlight-color, 3%); + + &:hover { + color: darken($ui-highlight-color, 3%); + } + + .emoji-mart-anchor-bar { + bottom: 0; + } +} + +.emoji-mart-anchor-bar { + position: absolute; + bottom: -3px; + left: 0; + width: 100%; + height: 3px; + background-color: darken($ui-highlight-color, 3%); +} + +.emoji-mart-anchors { + i { + display: inline-block; + width: 100%; + max-width: 22px; + } + + svg { + fill: currentColor; + max-height: 18px; + } +} + +.emoji-mart-scroll { + overflow-y: scroll; + height: 270px; + padding: 0 6px 6px; + background: $simple-background-color; +} + +.emoji-mart-search { + padding: 10px; + padding-right: 45px; + background: $simple-background-color; + + input { + font-size: 14px; + font-weight: 400; + padding: 7px 9px; + font-family: inherit; + display: block; + width: 100%; + background: rgba($ui-secondary-color, 0.3); + color: $ui-primary-color; + border: 1px solid $ui-secondary-color; + border-radius: 4px; + + &::-moz-focus-inner { + border: 0; + } + + &::-moz-focus-inner, + &:focus, + &:active { + outline: 0 !important; + } + } +} + +.emoji-mart-category .emoji-mart-emoji { + cursor: pointer; + + span { + z-index: 1; + position: relative; + text-align: center; + } + + &:hover::before { + z-index: 0; + content: ""; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-color: rgba($ui-secondary-color, 0.7); + border-radius: 100%; + } +} + +.emoji-mart-category-label { + z-index: 2; + position: relative; + position: -webkit-sticky; + position: sticky; + top: 0; + + span { + display: block; + width: 100%; + font-weight: 500; + padding: 5px 6px; + background: $simple-background-color; + } +} + +.emoji-mart-emoji { + position: relative; + display: inline-block; + font-size: 0; + + span { + width: 22px; + height: 22px; + } +} + +.emoji-mart-no-results { + font-size: 14px; + text-align: center; + padding-top: 70px; + color: $ui-primary-color; + + .emoji-mart-category-label { + display: none; + } + + .emoji-mart-no-results-label { + margin-top: .2em; + } + + .emoji-mart-emoji:hover::before { + content: none; + } +} + +.emoji-mart-preview { + display: none; +} |