Browse Source

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
pull/4/head
Eugen Rochko 4 years ago
committed by GitHub
parent
commit
846cd4e838
4595 changed files with 3317 additions and 2189 deletions
  1. +3
    -1
      app/javascript/mastodon/emoji.js
  2. +1
    -1
      app/javascript/mastodon/emojione_light.js
  3. +1
    -1
      app/javascript/mastodon/features/compose/components/compose_form.js
  4. +258
    -66
      app/javascript/mastodon/features/compose/components/emoji_picker_dropdown.js
  5. +1
    -1
      app/javascript/mastodon/features/ui/util/async-components.js
  6. +4
    -0
      app/javascript/mastodon/locales/ar.json
  7. +4
    -0
      app/javascript/mastodon/locales/bg.json
  8. +4
    -0
      app/javascript/mastodon/locales/ca.json
  9. +4
    -0
      app/javascript/mastodon/locales/de.json
  10. +16
    -9
      app/javascript/mastodon/locales/defaultMessages.json
  11. +4
    -0
      app/javascript/mastodon/locales/en.json
  12. +4
    -0
      app/javascript/mastodon/locales/eo.json
  13. +4
    -0
      app/javascript/mastodon/locales/es.json
  14. +4
    -0
      app/javascript/mastodon/locales/fa.json
  15. +4
    -0
      app/javascript/mastodon/locales/fi.json
  16. +4
    -0
      app/javascript/mastodon/locales/fr.json
  17. +4
    -0
      app/javascript/mastodon/locales/he.json
  18. +4
    -0
      app/javascript/mastodon/locales/hr.json
  19. +4
    -0
      app/javascript/mastodon/locales/hu.json
  20. +4
    -0
      app/javascript/mastodon/locales/id.json
  21. +4
    -0
      app/javascript/mastodon/locales/io.json
  22. +4
    -0
      app/javascript/mastodon/locales/it.json
  23. +4
    -0
      app/javascript/mastodon/locales/ja.json
  24. +4
    -0
      app/javascript/mastodon/locales/ko.json
  25. +6
    -5
      app/javascript/mastodon/locales/nl.json
  26. +4
    -0
      app/javascript/mastodon/locales/no.json
  27. +4
    -0
      app/javascript/mastodon/locales/oc.json
  28. +4
    -0
      app/javascript/mastodon/locales/pl.json
  29. +4
    -4
      app/javascript/mastodon/locales/pt-BR.json
  30. +4
    -0
      app/javascript/mastodon/locales/pt.json
  31. +4
    -0
      app/javascript/mastodon/locales/ru.json
  32. +4
    -0
      app/javascript/mastodon/locales/th.json
  33. +4
    -0
      app/javascript/mastodon/locales/tr.json
  34. +4
    -0
      app/javascript/mastodon/locales/uk.json
  35. +4
    -0
      app/javascript/mastodon/locales/zh-CN.json
  36. +4
    -0
      app/javascript/mastodon/locales/zh-HK.json
  37. +4
    -0
      app/javascript/mastodon/locales/zh-TW.json
  38. +1
    -1
      app/javascript/mastodon/reducers/compose.js
  39. +1
    -0
      app/javascript/styles/application.scss
  40. +35
    -183
      app/javascript/styles/components.scss
  41. +197
    -0
      app/javascript/styles/emoji_picker.scss
  42. +1
    -1
      app/views/layouts/application.html.haml
  43. +1
    -0
      package.json
  44. BIN
     
  45. +0
    -2
      public/emoji/0023-20e3.svg
  46. BIN
     
  47. +0
    -1
      public/emoji/0023.svg
  48. BIN
     
  49. +0
    -2
      public/emoji/002a-20e3.svg
  50. BIN
     
  51. +0
    -1
      public/emoji/002a.svg
  52. BIN
     
  53. +0
    -2
      public/emoji/0030-20e3.svg
  54. BIN
     
  55. +0
    -1
      public/emoji/0030.svg
  56. BIN
     
  57. +0
    -2
      public/emoji/0031-20e3.svg
  58. BIN
     
  59. +0
    -1
      public/emoji/0031.svg
  60. BIN
     
  61. +0
    -2
      public/emoji/0032-20e3.svg
  62. BIN
     
  63. +0
    -1
      public/emoji/0032.svg
  64. BIN
     
  65. +0
    -2
      public/emoji/0033-20e3.svg
  66. BIN
     
  67. +0
    -1
      public/emoji/0033.svg
  68. BIN
     
  69. +0
    -2
      public/emoji/0034-20e3.svg
  70. BIN
     
  71. +0
    -1
      public/emoji/0034.svg
  72. BIN
     
  73. +0
    -2
      public/emoji/0035-20e3.svg
  74. BIN
     
  75. +0
    -1
      public/emoji/0035.svg
  76. BIN
     
  77. +0
    -2
      public/emoji/0036-20e3.svg
  78. BIN
     
  79. +0
    -1
      public/emoji/0036.svg
  80. BIN
     
  81. +0
    -2
      public/emoji/0037-20e3.svg
  82. BIN
     
  83. +0
    -1
      public/emoji/0037.svg
  84. BIN
     
  85. +0
    -2
      public/emoji/0038-20e3.svg
  86. BIN
     
  87. +0
    -1
      public/emoji/0038.svg
  88. BIN
     
  89. +0
    -2
      public/emoji/0039-20e3.svg
  90. BIN
     
  91. +0
    -1
      public/emoji/0039.svg
  92. BIN
     
  93. +0
    -1
      public/emoji/00a9.svg
  94. BIN
     
  95. +0
    -1
      public/emoji/00ae.svg
  96. BIN
     
  97. +1
    -1
      public/emoji/1f004.svg
  98. BIN
     
  99. +1
    -1
      public/emoji/1f0cf.svg
  100. BIN
     

+ 3
- 1
app/javascript/mastodon/emoji.js View File

@ -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);
}
}

+ 1
- 1
app/javascript/mastodon/emojione_light.js View File

@ -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), { });

+ 1
- 1
app/javascript/mastodon/features/compose/components/compose_form.js View File

@ -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);
}

+ 258
- 66
app/javascript/mastodon/features/compose/components/emoji_picker_dropdown.js View File

@ -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>
);
}

+ 1
- 1
app/javascript/mastodon/features/ui/util/async-components.js View File

@ -1,5 +1,5 @@
export function EmojiPicker () {
return import(/* webpackChunkName: "emojione_picker" */'emojione-picker');
return import(/* webpackChunkName: "emoji_picker" */'emoji-mart');
}
export function Compose () {

+ 4
- 0
app/javascript/mastodon/locales/ar.json View File

@ -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": "الخط الزمني المحلي فارغ. اكتب شيئا ما للعامة كبداية.",

+ 4
- 0
app/javascript/mastodon/locales/bg.json View File

@ -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!",

+ 4
- 0
app/javascript/mastodon/locales/ca.json View File

@ -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!",

+ 4
- 0
app/javascript/mastodon/locales/de.json View File

@ -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!",

+ 16
- 9
app/javascript/mastodon/locales/defaultMessages.json View File

@ -516,6 +516,22 @@
"defaultMessage": "Search...",
"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"
@ -1331,15 +1347,6 @@
],
"path": "app/javascript/mastodon/features/ui/components/upload_area.json"
},
{
"descriptors": [
{
"defaultMessage": "Close",
"id": "lightbox.close"
}
],
"path": "app/javascript/mastodon/features/ui/components/video_modal.json"
},
{
"descriptors": [
{

+ 4
- 0
app/javascript/mastodon/locales/en.json View File

@ -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!",

+ 4
- 0
app/javascript/mastodon/locales/eo.json View File

@ -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!",

+ 4
- 0
app/javascript/mastodon/locales/es.json View File

@ -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!",

+ 4
- 0
app/javascript/mastodon/locales/fa.json View File

@ -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": "فهرست نوشته‌های محلی خالی است. چیزی بنویسید تا چرخش بچرخد!",

+ 4
- 0
app/javascript/mastodon/locales/fi.json View File

@ -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!",

+ 4
- 0
app/javascript/mastodon/locales/fr.json View File

@ -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 !",

+ 4
- 0
app/javascript/mastodon/locales/he.json View File

@ -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": "טור הסביבה ריק. יש לפרסם משהו כדי שדברים יתרחילו להתגלגל!",

+ 4
- 0
app/javascript/mastodon/locales/hr.json View File

@ -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!",

+ 4
- 0
app/javascript/mastodon/locales/hu.json View File

@ -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!",

+ 4
- 0
app/javascript/mastodon/locales/id.json View File

@ -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!",

+ 4
- 0
app/javascript/mastodon/locales/io.json View File

@ -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!",

+ 4
- 0
app/javascript/mastodon/locales/it.json View File

@ -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!",

+ 4
- 0
app/javascript/mastodon/locales/ja.json View File

@ -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": "ローカルタイムラインはまだ使われていません。何か書いてみましょう!",

+ 4
- 0
app/javascript/mastodon/locales/ko.json View File

@ -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": "로컬 타임라인에 아무 것도 없습니다. 아무거나 적어 보세요!",

+ 6
- 5
app/javascript/mastodon/locales/nl.json View File

@ -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",

+ 4
- 0
app/javascript/mastodon/locales/no.json View File

@ -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!",

+ 4
- 0
app/javascript/mastodon/locales/oc.json View File

@ -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 !",

+ 4
- 0
app/javascript/mastodon/locales/pl.json View File

@ -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ć!",

+ 4
- 4
app/javascript/mastodon/locales/pt-BR.json View File

@ -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",

+ 4
- 0
app/javascript/mastodon/locales/pt.json View File

@ -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!",

+ 4
- 0
app/javascript/mastodon/locales/ru.json View File

@ -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": "Локальная лента пуста. Напишите что-нибудь, чтобы разогреть народ!",

+ 4
- 0
app/javascript/mastodon/locales/th.json View File

@ -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!",

+ 4
- 0
app/javascript/mastodon/locales/tr.json View File

@ -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.",

+ 4
- 0
app/javascript/mastodon/locales/uk.json View File

@ -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": "Локальна стрічка пуста. Напишіть щось, щоб розігріти народ!",

+ 4
- 0
app/javascript/mastodon/locales/zh-CN.json View File

@ -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": "本站时间轴暂时未有内容,快嘟几个来抢头香啊!",

+ 4
- 0
app/javascript/mastodon/locales/zh-HK.json View File

@ -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": "本站時間軸暫時未有內容,快文章來搶頭香啊!",

+ 4
- 0
app/javascript/mastodon/locales/zh-TW.json View File

@ -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": "本地時間軸是空的。公開寫點什麼吧!",

+ 1
- 1
app/javascript/mastodon/reducers/compose.js View File

@ -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)}`);

+ 1
- 0
app/javascript/styles/application.scss View File

@ -15,6 +15,7 @@
@import 'accounts';
@import 'stream_entries';
@import 'components';
@import 'emoji_picker';
@import 'about';
@import 'tables';
@import 'admin';

+ 35
- 183
app/javascript/styles/components.scss View File

@ -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;