Allow to switch between default and emoji-one emoji style
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
import FileAttachmentList from './file_attachment_list.jsx';
|
import FileAttachmentList from './file_attachment_list.jsx';
|
||||||
import UserStore from '../stores/user_store.jsx';
|
import UserStore from '../stores/user_store.jsx';
|
||||||
|
import PreferenceStore from '../stores/preference_store.jsx';
|
||||||
import * as Utils from '../utils/utils.jsx';
|
import * as Utils from '../utils/utils.jsx';
|
||||||
import Constants from '../utils/constants.jsx';
|
import Constants from '../utils/constants.jsx';
|
||||||
import * as TextFormatting from '../utils/text_formatting.jsx';
|
import * as TextFormatting from '../utils/text_formatting.jsx';
|
||||||
@@ -19,6 +20,7 @@ export default class PostBody extends React.Component {
|
|||||||
this.isImgLoading = false;
|
this.isImgLoading = false;
|
||||||
|
|
||||||
this.handleUserChange = this.handleUserChange.bind(this);
|
this.handleUserChange = this.handleUserChange.bind(this);
|
||||||
|
this.handlePreferenceChange = this.handlePreferenceChange.bind(this);
|
||||||
this.parseEmojis = this.parseEmojis.bind(this);
|
this.parseEmojis = this.parseEmojis.bind(this);
|
||||||
this.createEmbed = this.createEmbed.bind(this);
|
this.createEmbed = this.createEmbed.bind(this);
|
||||||
this.createImageEmbed = this.createImageEmbed.bind(this);
|
this.createImageEmbed = this.createImageEmbed.bind(this);
|
||||||
@@ -52,7 +54,11 @@ export default class PostBody extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
parseEmojis() {
|
parseEmojis() {
|
||||||
twemoji.parse(ReactDOM.findDOMNode(this), {size: Constants.EMOJI_SIZE});
|
twemoji.parse(ReactDOM.findDOMNode(this), {
|
||||||
|
className: 'emoji twemoji',
|
||||||
|
base: '',
|
||||||
|
folder: Utils.getImagePathForEmoticon()
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillMount() {
|
componentWillMount() {
|
||||||
@@ -65,6 +71,7 @@ export default class PostBody extends React.Component {
|
|||||||
this.parseEmojis();
|
this.parseEmojis();
|
||||||
|
|
||||||
UserStore.addChangeListener(this.handleUserChange);
|
UserStore.addChangeListener(this.handleUserChange);
|
||||||
|
PreferenceStore.addChangeListener(this.handlePreferenceChange);
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidUpdate() {
|
componentDidUpdate() {
|
||||||
@@ -73,6 +80,7 @@ export default class PostBody extends React.Component {
|
|||||||
|
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
UserStore.removeChangeListener(this.handleUserChange);
|
UserStore.removeChangeListener(this.handleUserChange);
|
||||||
|
PreferenceStore.removeChangeListener(this.handlePreferenceChange);
|
||||||
}
|
}
|
||||||
|
|
||||||
handleUserChange() {
|
handleUserChange() {
|
||||||
@@ -83,6 +91,13 @@ export default class PostBody extends React.Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
handlePreferenceChange() {
|
||||||
|
$('.twemoji').each((idx, elem) => {
|
||||||
|
elem.src = Utils.getImagePathForEmoticon(twemoji.convert.toCodePoint(elem.alt));
|
||||||
|
});
|
||||||
|
this.forceUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
componentWillReceiveProps(nextProps) {
|
componentWillReceiveProps(nextProps) {
|
||||||
const linkData = Utils.extractLinks(nextProps.post.message);
|
const linkData = Utils.extractLinks(nextProps.post.message);
|
||||||
if (this.props.post.filenames.length === 0 && this.state.links && this.state.links.length > 0) {
|
if (this.props.post.filenames.length === 0 && this.state.links && this.state.links.length > 0) {
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import * as TextFormatting from '../utils/text_formatting.jsx';
|
|||||||
import * as utils from '../utils/utils.jsx';
|
import * as utils from '../utils/utils.jsx';
|
||||||
import FileAttachmentList from './file_attachment_list.jsx';
|
import FileAttachmentList from './file_attachment_list.jsx';
|
||||||
import twemoji from 'twemoji';
|
import twemoji from 'twemoji';
|
||||||
import Constants from '../utils/constants.jsx';
|
|
||||||
import PostBodyAdditionalContent from './post_body_additional_content.jsx';
|
import PostBodyAdditionalContent from './post_body_additional_content.jsx';
|
||||||
import * as EventHelpers from '../dispatcher/event_helpers.jsx';
|
import * as EventHelpers from '../dispatcher/event_helpers.jsx';
|
||||||
|
|
||||||
@@ -21,7 +20,11 @@ export default class RhsRootPost extends React.Component {
|
|||||||
this.state = {};
|
this.state = {};
|
||||||
}
|
}
|
||||||
parseEmojis() {
|
parseEmojis() {
|
||||||
twemoji.parse(ReactDOM.findDOMNode(this), {size: Constants.EMOJI_SIZE});
|
twemoji.parse(ReactDOM.findDOMNode(this), {
|
||||||
|
className: 'emoji twemoji',
|
||||||
|
base: '',
|
||||||
|
folder: utils.getImagePathForEmoticon()
|
||||||
|
});
|
||||||
}
|
}
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.parseEmojis();
|
this.parseEmojis();
|
||||||
|
|||||||
@@ -6,14 +6,17 @@ import SettingItemMin from '../setting_item_min.jsx';
|
|||||||
import SettingItemMax from '../setting_item_max.jsx';
|
import SettingItemMax from '../setting_item_max.jsx';
|
||||||
import Constants from '../../utils/constants.jsx';
|
import Constants from '../../utils/constants.jsx';
|
||||||
import PreferenceStore from '../../stores/preference_store.jsx';
|
import PreferenceStore from '../../stores/preference_store.jsx';
|
||||||
|
import * as Utils from '../../utils/utils.jsx';
|
||||||
|
|
||||||
function getDisplayStateFromStores() {
|
function getDisplayStateFromStores() {
|
||||||
const militaryTime = PreferenceStore.getPreference(Constants.Preferences.CATEGORY_DISPLAY_SETTINGS, 'use_military_time', {value: 'false'});
|
const militaryTime = PreferenceStore.getPreference(Constants.Preferences.CATEGORY_DISPLAY_SETTINGS, 'use_military_time', {value: 'false'});
|
||||||
const nameFormat = PreferenceStore.getPreference(Constants.Preferences.CATEGORY_DISPLAY_SETTINGS, 'name_format', {value: 'username'});
|
const nameFormat = PreferenceStore.getPreference(Constants.Preferences.CATEGORY_DISPLAY_SETTINGS, 'name_format', {value: 'username'});
|
||||||
|
const emojiStyle = PreferenceStore.getPreference(Constants.Preferences.CATEGORY_DISPLAY_SETTINGS, 'emoji_style', {value: 'default'});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
militaryTime: militaryTime.value,
|
militaryTime: militaryTime.value,
|
||||||
nameFormat: nameFormat.value
|
nameFormat: nameFormat.value,
|
||||||
|
emojiStyle: emojiStyle.value
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -31,8 +34,9 @@ export default class UserSettingsDisplay extends React.Component {
|
|||||||
handleSubmit() {
|
handleSubmit() {
|
||||||
const timePreference = PreferenceStore.setPreference(Constants.Preferences.CATEGORY_DISPLAY_SETTINGS, 'use_military_time', this.state.militaryTime);
|
const timePreference = PreferenceStore.setPreference(Constants.Preferences.CATEGORY_DISPLAY_SETTINGS, 'use_military_time', this.state.militaryTime);
|
||||||
const namePreference = PreferenceStore.setPreference(Constants.Preferences.CATEGORY_DISPLAY_SETTINGS, 'name_format', this.state.nameFormat);
|
const namePreference = PreferenceStore.setPreference(Constants.Preferences.CATEGORY_DISPLAY_SETTINGS, 'name_format', this.state.nameFormat);
|
||||||
|
const emojiStyle = PreferenceStore.setPreference(Constants.Preferences.CATEGORY_DISPLAY_SETTINGS, 'emoji_style', this.state.emojiStyle);
|
||||||
|
|
||||||
savePreferences([timePreference, namePreference],
|
savePreferences([timePreference, namePreference, emojiStyle],
|
||||||
() => {
|
() => {
|
||||||
PreferenceStore.emitChange();
|
PreferenceStore.emitChange();
|
||||||
this.updateSection('');
|
this.updateSection('');
|
||||||
@@ -48,6 +52,9 @@ export default class UserSettingsDisplay extends React.Component {
|
|||||||
handleNameRadio(nameFormat) {
|
handleNameRadio(nameFormat) {
|
||||||
this.setState({nameFormat});
|
this.setState({nameFormat});
|
||||||
}
|
}
|
||||||
|
handleEmojiRadio(emojiStyle) {
|
||||||
|
this.setState({emojiStyle});
|
||||||
|
}
|
||||||
updateSection(section) {
|
updateSection(section) {
|
||||||
this.setState(getDisplayStateFromStores());
|
this.setState(getDisplayStateFromStores());
|
||||||
this.props.updateSection(section);
|
this.props.updateSection(section);
|
||||||
@@ -56,6 +63,7 @@ export default class UserSettingsDisplay extends React.Component {
|
|||||||
const serverError = this.state.serverError || null;
|
const serverError = this.state.serverError || null;
|
||||||
let clockSection;
|
let clockSection;
|
||||||
let nameFormatSection;
|
let nameFormatSection;
|
||||||
|
let emojiSection;
|
||||||
if (this.props.activeSection === 'clock') {
|
if (this.props.activeSection === 'clock') {
|
||||||
const clockFormat = [false, false];
|
const clockFormat = [false, false];
|
||||||
if (this.state.militaryTime === 'true') {
|
if (this.state.militaryTime === 'true') {
|
||||||
@@ -209,6 +217,77 @@ export default class UserSettingsDisplay extends React.Component {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.props.activeSection === 'emoji') {
|
||||||
|
const inputs = [
|
||||||
|
<div key='userDisplayClockOptions'>
|
||||||
|
<div className='radio'>
|
||||||
|
<label>
|
||||||
|
<input
|
||||||
|
type='radio'
|
||||||
|
checked={this.state.emojiStyle === 'default'}
|
||||||
|
onChange={this.handleEmojiRadio.bind(this, 'default')}
|
||||||
|
/>
|
||||||
|
{'Default Style'}
|
||||||
|
<img
|
||||||
|
className='emoji'
|
||||||
|
src={Utils.getImagePathForEmoticon('smile', 'default')}
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
<br/>
|
||||||
|
</div>
|
||||||
|
<div className='radio'>
|
||||||
|
<label>
|
||||||
|
<input
|
||||||
|
type='radio'
|
||||||
|
checked={this.state.emojiStyle === 'emojione'}
|
||||||
|
onChange={this.handleEmojiRadio.bind(this, 'emojione')}
|
||||||
|
/>
|
||||||
|
{'Emoji One Style'}
|
||||||
|
<img
|
||||||
|
className='emoji'
|
||||||
|
src={Utils.getImagePathForEmoticon('smile', 'emojione')}
|
||||||
|
/>
|
||||||
|
<span className='emojiAffiliation'>
|
||||||
|
{'Emoji provided free by '}
|
||||||
|
<a
|
||||||
|
href='http://emojione.com/'
|
||||||
|
target='blank'
|
||||||
|
>
|
||||||
|
{'Emoji One'}
|
||||||
|
</a>
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
<br/>
|
||||||
|
</div>
|
||||||
|
<div><br/>{'Select how you prefer time displayed.'}</div>
|
||||||
|
</div>
|
||||||
|
];
|
||||||
|
|
||||||
|
emojiSection = (
|
||||||
|
<SettingItemMax
|
||||||
|
title='Emoji Style'
|
||||||
|
inputs={inputs}
|
||||||
|
submit={this.handleSubmit}
|
||||||
|
server_error={serverError}
|
||||||
|
updateSection={(e) => {
|
||||||
|
this.updateSection('');
|
||||||
|
e.preventDefault();
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
const describe = this.state.emojiStyle === 'default' ? 'Default Style' : 'Emoji One Style';
|
||||||
|
emojiSection = (
|
||||||
|
<SettingItemMin
|
||||||
|
title='Emoji Style'
|
||||||
|
describe={describe}
|
||||||
|
updateSection={() => {
|
||||||
|
this.props.updateSection('emoji');
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<div className='modal-header'>
|
<div className='modal-header'>
|
||||||
@@ -239,6 +318,8 @@ export default class UserSettingsDisplay extends React.Component {
|
|||||||
<div className='divider-dark'/>
|
<div className='divider-dark'/>
|
||||||
{nameFormatSection}
|
{nameFormatSection}
|
||||||
<div className='divider-dark'/>
|
<div className='divider-dark'/>
|
||||||
|
{emojiSection}
|
||||||
|
<div className='divider-dark'/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -122,5 +122,6 @@ class PreferenceStoreClass extends EventEmitter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const PreferenceStore = new PreferenceStoreClass();
|
const PreferenceStore = new PreferenceStoreClass();
|
||||||
|
PreferenceStore.setMaxListeners(0);
|
||||||
export default PreferenceStore;
|
export default PreferenceStore;
|
||||||
window.PreferenceStore = PreferenceStore;
|
window.PreferenceStore = PreferenceStore;
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved.
|
// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved.
|
||||||
// See License.txt for license information.
|
// See License.txt for license information.
|
||||||
|
|
||||||
|
import * as Utils from './utils.jsx';
|
||||||
|
|
||||||
const emoticonPatterns = {
|
const emoticonPatterns = {
|
||||||
smile: /(^|\s)(:-?\))(?=$|\s)/g, // :)
|
smile: /(^|\s)(:-?\))(?=$|\s)/g, // :)
|
||||||
wink: /(^|\s)(;-?\))(?=$|\s)/g, // ;)
|
wink: /(^|\s)(;-?\))(?=$|\s)/g, // ;)
|
||||||
@@ -133,7 +135,7 @@ export function handleEmoticons(text, tokens) {
|
|||||||
const alias = `MM_EMOTICON${index}`;
|
const alias = `MM_EMOTICON${index}`;
|
||||||
|
|
||||||
tokens.set(alias, {
|
tokens.set(alias, {
|
||||||
value: `<img align="absmiddle" alt="${matchText}" class="emoji" src="${getImagePathForEmoticon(name)}" title="${matchText}" />`,
|
value: `<img align="absmiddle" alt="${matchText}" class="emoji" src="${Utils.getImagePathForEmoticon(name)}" title="${matchText}" />`,
|
||||||
originalText: fullMatch
|
originalText: fullMatch
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -154,6 +156,3 @@ export function handleEmoticons(text, tokens) {
|
|||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getImagePathForEmoticon(name) {
|
|
||||||
return `/static/images/emoji/${name}.png`;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1227,3 +1227,12 @@ export function getPostTerm(post) {
|
|||||||
export function isFeatureEnabled(feature) {
|
export function isFeatureEnabled(feature) {
|
||||||
return PreferenceStore.getPreference(Constants.Preferences.CATEGORY_ADVANCED_SETTINGS, Constants.FeatureTogglePrefix + feature.label, {value: 'false'}).value === 'true';
|
return PreferenceStore.getPreference(Constants.Preferences.CATEGORY_ADVANCED_SETTINGS, Constants.FeatureTogglePrefix + feature.label, {value: 'false'}).value === 'true';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getImagePathForEmoticon(name, style) {
|
||||||
|
const emojiStyle = style || PreferenceStore.getPreference(Constants.Preferences.CATEGORY_DISPLAY_SETTINGS, 'emoji_style', {value: 'default'}).value;
|
||||||
|
|
||||||
|
if (name) {
|
||||||
|
return `/static/images/emoji/${emojiStyle}/${name}.png`;
|
||||||
|
}
|
||||||
|
return `/static/images/emoji/${emojiStyle}`;
|
||||||
|
}
|
||||||
@@ -36,8 +36,17 @@
|
|||||||
}
|
}
|
||||||
label {
|
label {
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
|
.emoji {
|
||||||
|
margin-left: 5px;
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.no-padding--left {
|
|
||||||
|
.emojiAffiliation {
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
.no-padding--left {
|
||||||
padding-left: 0;
|
padding-left: 0;
|
||||||
}
|
}
|
||||||
.padding-top {
|
.padding-top {
|
||||||
|
|||||||
|
До Ширина: | Высота: | Размер: 5.0 KiB После Ширина: | Высота: | Размер: 5.0 KiB |
|
До Ширина: | Высота: | Размер: 5.0 KiB После Ширина: | Высота: | Размер: 5.0 KiB |
1
web/static/images/emoji/default/0023-20e3.png
Символическая ссылка
@@ -0,0 +1 @@
|
|||||||
|
hash.png
|
||||||
1
web/static/images/emoji/default/0030-20e3.png
Символическая ссылка
@@ -0,0 +1 @@
|
|||||||
|
zero.png
|
||||||
1
web/static/images/emoji/default/0031-20e3.png
Символическая ссылка
@@ -0,0 +1 @@
|
|||||||
|
one.png
|
||||||
1
web/static/images/emoji/default/0032-20e3.png
Символическая ссылка
@@ -0,0 +1 @@
|
|||||||
|
two.png
|
||||||
1
web/static/images/emoji/default/0033-20e3.png
Символическая ссылка
@@ -0,0 +1 @@
|
|||||||
|
three.png
|
||||||
1
web/static/images/emoji/default/0034-20e3.png
Символическая ссылка
@@ -0,0 +1 @@
|
|||||||
|
four.png
|
||||||
1
web/static/images/emoji/default/0035-20e3.png
Символическая ссылка
@@ -0,0 +1 @@
|
|||||||
|
five.png
|
||||||
1
web/static/images/emoji/default/0036-20e3.png
Символическая ссылка
@@ -0,0 +1 @@
|
|||||||
|
six.png
|
||||||
1
web/static/images/emoji/default/0037-20e3.png
Символическая ссылка
@@ -0,0 +1 @@
|
|||||||
|
seven.png
|
||||||
1
web/static/images/emoji/default/0038-20e3.png
Символическая ссылка
@@ -0,0 +1 @@
|
|||||||
|
eight.png
|
||||||
1
web/static/images/emoji/default/0039-20e3.png
Символическая ссылка
@@ -0,0 +1 @@
|
|||||||
|
nine.png
|
||||||
1
web/static/images/emoji/default/00a9.png
Символическая ссылка
@@ -0,0 +1 @@
|
|||||||
|
copyright.png
|
||||||
1
web/static/images/emoji/default/00ae.png
Символическая ссылка
@@ -0,0 +1 @@
|
|||||||
|
registered.png
|
||||||
|
До Ширина: | Высота: | Размер: 3.2 KiB После Ширина: | Высота: | Размер: 3.2 KiB |
|
До Ширина: | Высота: | Размер: 4.6 KiB После Ширина: | Высота: | Размер: 4.6 KiB |
1
web/static/images/emoji/default/1f004.png
Символическая ссылка
@@ -0,0 +1 @@
|
|||||||
|
mahjong.png
|
||||||
1
web/static/images/emoji/default/1f0cf.png
Символическая ссылка
@@ -0,0 +1 @@
|
|||||||
|
black_joker.png
|
||||||
1
web/static/images/emoji/default/1f170.png
Символическая ссылка
@@ -0,0 +1 @@
|
|||||||
|
a.png
|
||||||
1
web/static/images/emoji/default/1f171.png
Символическая ссылка
@@ -0,0 +1 @@
|
|||||||
|
b.png
|
||||||
1
web/static/images/emoji/default/1f17e.png
Символическая ссылка
@@ -0,0 +1 @@
|
|||||||
|
o2.png
|
||||||
1
web/static/images/emoji/default/1f17f.png
Символическая ссылка
@@ -0,0 +1 @@
|
|||||||
|
parking.png
|
||||||
1
web/static/images/emoji/default/1f18e.png
Символическая ссылка
@@ -0,0 +1 @@
|
|||||||
|
ab.png
|
||||||
1
web/static/images/emoji/default/1f191.png
Символическая ссылка
@@ -0,0 +1 @@
|
|||||||
|
cl.png
|
||||||
1
web/static/images/emoji/default/1f192.png
Символическая ссылка
@@ -0,0 +1 @@
|
|||||||
|
cool.png
|
||||||
1
web/static/images/emoji/default/1f193.png
Символическая ссылка
@@ -0,0 +1 @@
|
|||||||
|
free.png
|
||||||
1
web/static/images/emoji/default/1f194.png
Символическая ссылка
@@ -0,0 +1 @@
|
|||||||
|
id.png
|
||||||
1
web/static/images/emoji/default/1f195.png
Символическая ссылка
@@ -0,0 +1 @@
|
|||||||
|
new.png
|
||||||
1
web/static/images/emoji/default/1f196.png
Символическая ссылка
@@ -0,0 +1 @@
|
|||||||
|
ng.png
|
||||||
1
web/static/images/emoji/default/1f197.png
Символическая ссылка
@@ -0,0 +1 @@
|
|||||||
|
ok.png
|
||||||
1
web/static/images/emoji/default/1f198.png
Символическая ссылка
@@ -0,0 +1 @@
|
|||||||
|
sos.png
|
||||||
1
web/static/images/emoji/default/1f199.png
Символическая ссылка
@@ -0,0 +1 @@
|
|||||||
|
up.png
|
||||||
1
web/static/images/emoji/default/1f19a.png
Символическая ссылка
@@ -0,0 +1 @@
|
|||||||
|
vs.png
|
||||||
1
web/static/images/emoji/default/1f1e8-1f1f3.png
Символическая ссылка
@@ -0,0 +1 @@
|
|||||||
|
cn.png
|
||||||
1
web/static/images/emoji/default/1f1e9-1f1ea.png
Символическая ссылка
@@ -0,0 +1 @@
|
|||||||
|
de.png
|
||||||
1
web/static/images/emoji/default/1f1ea-1f1f8.png
Символическая ссылка
@@ -0,0 +1 @@
|
|||||||
|
es.png
|
||||||
1
web/static/images/emoji/default/1f1eb-1f1f7.png
Символическая ссылка
@@ -0,0 +1 @@
|
|||||||
|
fr.png
|
||||||
1
web/static/images/emoji/default/1f1ec-1f1e7.png
Символическая ссылка
@@ -0,0 +1 @@
|
|||||||
|
gb.png
|
||||||
1
web/static/images/emoji/default/1f1ee-1f1f9.png
Символическая ссылка
@@ -0,0 +1 @@
|
|||||||
|
it.png
|
||||||
1
web/static/images/emoji/default/1f1ef-1f1f5.png
Символическая ссылка
@@ -0,0 +1 @@
|
|||||||
|
jp.png
|
||||||
1
web/static/images/emoji/default/1f1f0-1f1f7.png
Символическая ссылка
@@ -0,0 +1 @@
|
|||||||
|
kr.png
|
||||||
1
web/static/images/emoji/default/1f1f7-1f1fa.png
Символическая ссылка
@@ -0,0 +1 @@
|
|||||||
|
ru.png
|
||||||
1
web/static/images/emoji/default/1f1fa-1f1f8.png
Символическая ссылка
@@ -0,0 +1 @@
|
|||||||
|
us.png
|
||||||
1
web/static/images/emoji/default/1f201.png
Символическая ссылка
@@ -0,0 +1 @@
|
|||||||
|
koko.png
|
||||||
1
web/static/images/emoji/default/1f202.png
Символическая ссылка
@@ -0,0 +1 @@
|
|||||||
|
sa.png
|
||||||
1
web/static/images/emoji/default/1f21a.png
Символическая ссылка
@@ -0,0 +1 @@
|
|||||||
|
u7121.png
|
||||||
1
web/static/images/emoji/default/1f22f.png
Символическая ссылка
@@ -0,0 +1 @@
|
|||||||
|
u6307.png
|
||||||
1
web/static/images/emoji/default/1f232.png
Символическая ссылка
@@ -0,0 +1 @@
|
|||||||
|
u7981.png
|
||||||
1
web/static/images/emoji/default/1f233.png
Символическая ссылка
@@ -0,0 +1 @@
|
|||||||
|
u7a7a.png
|
||||||
1
web/static/images/emoji/default/1f234.png
Символическая ссылка
@@ -0,0 +1 @@
|
|||||||
|
u5408.png
|
||||||
1
web/static/images/emoji/default/1f235.png
Символическая ссылка
@@ -0,0 +1 @@
|
|||||||
|
u6e80.png
|
||||||
1
web/static/images/emoji/default/1f236.png
Символическая ссылка
@@ -0,0 +1 @@
|
|||||||
|
u6709.png
|
||||||
1
web/static/images/emoji/default/1f237.png
Символическая ссылка
@@ -0,0 +1 @@
|
|||||||
|
u6708.png
|
||||||
1
web/static/images/emoji/default/1f238.png
Символическая ссылка
@@ -0,0 +1 @@
|
|||||||
|
u7533.png
|
||||||
1
web/static/images/emoji/default/1f239.png
Символическая ссылка
@@ -0,0 +1 @@
|
|||||||
|
u5272.png
|
||||||
1
web/static/images/emoji/default/1f23a.png
Символическая ссылка
@@ -0,0 +1 @@
|
|||||||
|
u55b6.png
|
||||||
1
web/static/images/emoji/default/1f250.png
Символическая ссылка
@@ -0,0 +1 @@
|
|||||||
|
ideograph_advantage.png
|
||||||
1
web/static/images/emoji/default/1f251.png
Символическая ссылка
@@ -0,0 +1 @@
|
|||||||
|
accept.png
|
||||||
1
web/static/images/emoji/default/1f300.png
Символическая ссылка
@@ -0,0 +1 @@
|
|||||||
|
cyclone.png
|
||||||
1
web/static/images/emoji/default/1f301.png
Символическая ссылка
@@ -0,0 +1 @@
|
|||||||
|
foggy.png
|
||||||
1
web/static/images/emoji/default/1f302.png
Символическая ссылка
@@ -0,0 +1 @@
|
|||||||
|
closed_umbrella.png
|
||||||
1
web/static/images/emoji/default/1f304.png
Символическая ссылка
@@ -0,0 +1 @@
|
|||||||
|
sunrise_over_mountains.png
|
||||||
1
web/static/images/emoji/default/1f305.png
Символическая ссылка
@@ -0,0 +1 @@
|
|||||||
|
sunrise.png
|
||||||
1
web/static/images/emoji/default/1f306.png
Символическая ссылка
@@ -0,0 +1 @@
|
|||||||
|
city_sunset.png
|
||||||
1
web/static/images/emoji/default/1f307.png
Символическая ссылка
@@ -0,0 +1 @@
|
|||||||
|
city_sunrise.png
|
||||||
1
web/static/images/emoji/default/1f308.png
Символическая ссылка
@@ -0,0 +1 @@
|
|||||||
|
rainbow.png
|
||||||
1
web/static/images/emoji/default/1f309.png
Символическая ссылка
@@ -0,0 +1 @@
|
|||||||
|
bridge_at_night.png
|
||||||
1
web/static/images/emoji/default/1f30a.png
Символическая ссылка
@@ -0,0 +1 @@
|
|||||||
|
ocean.png
|
||||||
1
web/static/images/emoji/default/1f30b.png
Символическая ссылка
@@ -0,0 +1 @@
|
|||||||
|
volcano.png
|
||||||
1
web/static/images/emoji/default/1f30c.png
Символическая ссылка
@@ -0,0 +1 @@
|
|||||||
|
milky_way.png
|
||||||
1
web/static/images/emoji/default/1f30d.png
Символическая ссылка
@@ -0,0 +1 @@
|
|||||||
|
earth_africa.png
|
||||||
1
web/static/images/emoji/default/1f30e.png
Символическая ссылка
@@ -0,0 +1 @@
|
|||||||
|
earth_americas.png
|
||||||
1
web/static/images/emoji/default/1f30f.png
Символическая ссылка
@@ -0,0 +1 @@
|
|||||||
|
earth_asia.png
|
||||||
1
web/static/images/emoji/default/1f310.png
Символическая ссылка
@@ -0,0 +1 @@
|
|||||||
|
globe_with_meridians.png
|
||||||
1
web/static/images/emoji/default/1f311.png
Символическая ссылка
@@ -0,0 +1 @@
|
|||||||
|
new_moon.png
|
||||||
1
web/static/images/emoji/default/1f312.png
Символическая ссылка
@@ -0,0 +1 @@
|
|||||||
|
waxing_crescent_moon.png
|
||||||
1
web/static/images/emoji/default/1f313.png
Символическая ссылка
@@ -0,0 +1 @@
|
|||||||
|
first_quarter_moon.png
|
||||||
1
web/static/images/emoji/default/1f314.png
Символическая ссылка
@@ -0,0 +1 @@
|
|||||||
|
waxing_gibbous_moon.png
|
||||||
1
web/static/images/emoji/default/1f315.png
Символическая ссылка
@@ -0,0 +1 @@
|
|||||||
|
full_moon.png
|
||||||
1
web/static/images/emoji/default/1f316.png
Символическая ссылка
@@ -0,0 +1 @@
|
|||||||
|
waning_gibbous_moon.png
|
||||||
1
web/static/images/emoji/default/1f317.png
Символическая ссылка
@@ -0,0 +1 @@
|
|||||||
|
last_quarter_moon.png
|
||||||
1
web/static/images/emoji/default/1f318.png
Символическая ссылка
@@ -0,0 +1 @@
|
|||||||
|
waning_crescent_moon.png
|
||||||
1
web/static/images/emoji/default/1f319.png
Символическая ссылка
@@ -0,0 +1 @@
|
|||||||
|
crescent_moon.png
|
||||||
1
web/static/images/emoji/default/1f31a.png
Символическая ссылка
@@ -0,0 +1 @@
|
|||||||
|
new_moon_with_face.png
|
||||||
1
web/static/images/emoji/default/1f31b.png
Символическая ссылка
@@ -0,0 +1 @@
|
|||||||
|
first_quarter_moon_with_face.png
|
||||||
1
web/static/images/emoji/default/1f31c.png
Символическая ссылка
@@ -0,0 +1 @@
|
|||||||
|
last_quarter_moon_with_face.png
|
||||||
1
web/static/images/emoji/default/1f31d.png
Символическая ссылка
@@ -0,0 +1 @@
|
|||||||
|
full_moon_with_face.png
|
||||||
1
web/static/images/emoji/default/1f31e.png
Символическая ссылка
@@ -0,0 +1 @@
|
|||||||
|
sun_with_face.png
|
||||||
1
web/static/images/emoji/default/1f31f.png
Символическая ссылка
@@ -0,0 +1 @@
|
|||||||
|
star2.png
|
||||||
1
web/static/images/emoji/default/1f320.png
Символическая ссылка
@@ -0,0 +1 @@
|
|||||||
|
stars.png
|
||||||
1
web/static/images/emoji/default/1f330.png
Символическая ссылка
@@ -0,0 +1 @@
|
|||||||
|
chestnut.png
|
||||||
1
web/static/images/emoji/default/1f331.png
Символическая ссылка
@@ -0,0 +1 @@
|
|||||||
|
seedling.png
|
||||||