Refresh the emoji library (#7001)
* refresh the emoji library * fix img_trans.gif * compress sprite sheet * remove note on compression - webpack seems to handle compression decently * better emoji sheet preloading * requested changes
@@ -1,4 +1,4 @@
|
||||
.PHONY: build test run clean stop check-style run-unit
|
||||
.PHONY: build test run clean stop check-style run-unit emojis
|
||||
|
||||
BUILD_SERVER_DIR = ..
|
||||
|
||||
@@ -54,3 +54,6 @@ clean:
|
||||
rm -rf dist
|
||||
rm -rf node_modules
|
||||
rm -f .yarninstall
|
||||
|
||||
emojis:
|
||||
./make-emojis
|
||||
|
||||
@@ -17,6 +17,7 @@ import MsgTyping from './msg_typing.jsx';
|
||||
import FileUpload from './file_upload.jsx';
|
||||
import FilePreview from './file_preview.jsx';
|
||||
import EmojiPickerOverlay from 'components/emoji_picker/emoji_picker_overlay.jsx';
|
||||
import * as EmojiPicker from 'components/emoji_picker/emoji_picker.jsx';
|
||||
import * as Utils from 'utils/utils.jsx';
|
||||
import * as UserAgent from 'utils/user_agent.jsx';
|
||||
import * as GlobalActions from 'actions/global_actions.jsx';
|
||||
@@ -588,6 +589,7 @@ export default class CreateComment extends React.Component {
|
||||
<span
|
||||
className={'fa fa-smile-o icon--emoji-picker emoji-rhs'}
|
||||
onClick={this.toggleEmojiPicker}
|
||||
onMouseOver={EmojiPicker.beginPreloading}
|
||||
/>
|
||||
</span>
|
||||
);
|
||||
|
||||
@@ -9,6 +9,7 @@ import FilePreview from './file_preview.jsx';
|
||||
import PostDeletedModal from './post_deleted_modal.jsx';
|
||||
import TutorialTip from './tutorial/tutorial_tip.jsx';
|
||||
import EmojiPickerOverlay from 'components/emoji_picker/emoji_picker_overlay.jsx';
|
||||
import * as EmojiPicker from 'components/emoji_picker/emoji_picker.jsx';
|
||||
|
||||
import AppDispatcher from 'dispatcher/app_dispatcher.jsx';
|
||||
import * as GlobalActions from 'actions/global_actions.jsx';
|
||||
@@ -746,6 +747,7 @@ export default class CreatePost extends React.Component {
|
||||
<span
|
||||
className={'fa fa-smile-o icon--emoji-picker emoji-main'}
|
||||
onClick={this.toggleEmojiPicker}
|
||||
onMouseOver={EmojiPicker.beginPreloading}
|
||||
/>
|
||||
</span>
|
||||
);
|
||||
|
||||
@@ -14,7 +14,8 @@ export default class EmojiPickerItem extends React.Component {
|
||||
onItemOut: PropTypes.func.isRequired,
|
||||
onItemClick: PropTypes.func.isRequired,
|
||||
onItemUnmount: PropTypes.func.isRequired,
|
||||
category: PropTypes.string.isRequired
|
||||
category: PropTypes.string.isRequired,
|
||||
isLoaded: PropTypes.bool.isRequired
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
@@ -61,8 +62,8 @@ export default class EmojiPickerItem extends React.Component {
|
||||
item =
|
||||
(<div >
|
||||
<img
|
||||
src='/static/emoji/img_trans.gif'
|
||||
className={' emojisprite emoji-' + this.props.emoji.filename + ' '}
|
||||
src='/static/images/img_trans.gif'
|
||||
className={' emojisprite' + (this.props.isLoaded ? '' : '-loading') + ' emoji-' + this.props.emoji.filename + ' '}
|
||||
onMouseOver={this.handleMouseOver}
|
||||
onMouseOut={this.handleMouseOut}
|
||||
onClick={this.handleClick}
|
||||
|
||||
@@ -27,7 +27,7 @@ export default class EmojiPickerPreview extends React.Component {
|
||||
name = emoji.aliases[0];
|
||||
aliases = emoji.aliases;
|
||||
previewImage = (<span className='sprite-preview'><img
|
||||
src='/static/emoji/img_trans.gif'
|
||||
src='/static/images/img_trans.gif'
|
||||
className={' emojisprite-preview emoji-' + emoji.filename + ' '}
|
||||
/></span>);
|
||||
} else {
|
||||
|
||||
@@ -14,14 +14,23 @@ import EmojiPickerCategory from './components/emoji_picker_category.jsx';
|
||||
import EmojiPickerItem from './components/emoji_picker_item.jsx';
|
||||
import EmojiPickerPreview from './components/emoji_picker_preview.jsx';
|
||||
|
||||
import PeopleSpriteSheet from 'images/emoji-sheets/people.png';
|
||||
import NatureSpriteSheet from 'images/emoji-sheets/nature.png';
|
||||
import FoodsSpriteSheet from 'images/emoji-sheets/foods.png';
|
||||
import ActivitySpriteSheet from 'images/emoji-sheets/activity.png';
|
||||
import PlacesSpriteSheet from 'images/emoji-sheets/places.png';
|
||||
import ObjectsSpriteSheet from 'images/emoji-sheets/objects.png';
|
||||
import SymbolsSpriteSheet from 'images/emoji-sheets/symbols.png';
|
||||
import FlagsSpriteSheet from 'images/emoji-sheets/flags.png';
|
||||
|
||||
// This should include all the categories available in Emoji.CategoryNames
|
||||
const CATEGORIES = [
|
||||
'recent',
|
||||
'people',
|
||||
'nature',
|
||||
'food',
|
||||
'foods',
|
||||
'activity',
|
||||
'travel',
|
||||
'places',
|
||||
'objects',
|
||||
'symbols',
|
||||
'flags',
|
||||
@@ -49,6 +58,7 @@ export default class EmojiPicker extends React.Component {
|
||||
// All props are primitives or treated as immutable
|
||||
this.shouldComponentUpdate = PureRenderMixin.shouldComponentUpdate.bind(this);
|
||||
|
||||
this.handlePreload = this.handlePreload.bind(this);
|
||||
this.handleCategoryClick = this.handleCategoryClick.bind(this);
|
||||
this.handleFilterChange = this.handleFilterChange.bind(this);
|
||||
this.handleItemOver = this.handleItemOver.bind(this);
|
||||
@@ -61,7 +71,8 @@ export default class EmojiPicker extends React.Component {
|
||||
this.state = {
|
||||
category: 'recent',
|
||||
filter: '',
|
||||
selected: null
|
||||
selected: null,
|
||||
preloaded: []
|
||||
};
|
||||
}
|
||||
|
||||
@@ -71,6 +82,23 @@ export default class EmojiPicker extends React.Component {
|
||||
requestAnimationFrame(() => {
|
||||
this.searchInput.focus();
|
||||
});
|
||||
beginPreloading();
|
||||
subscribeToPreloads(this.handlePreload);
|
||||
this.handlePreload();
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
unsubscribeFromPreloads(this.handlePreload);
|
||||
}
|
||||
|
||||
handlePreload() {
|
||||
const preloaded = [];
|
||||
for (const category of CATEGORIES) {
|
||||
if (didPreloadCategory(category)) {
|
||||
preloaded.push(category);
|
||||
}
|
||||
}
|
||||
this.setState({preloaded});
|
||||
}
|
||||
|
||||
handleCategoryClick(category) {
|
||||
@@ -139,7 +167,8 @@ export default class EmojiPicker extends React.Component {
|
||||
}
|
||||
}
|
||||
}
|
||||
renderCategory(category, filter) {
|
||||
|
||||
renderCategory(category, isLoaded, filter) {
|
||||
const items = [];
|
||||
let indices = [];
|
||||
let recentEmojis = [];
|
||||
@@ -181,6 +210,7 @@ export default class EmojiPicker extends React.Component {
|
||||
key={'system_' + (category === 'recent' ? 'recent_' : '') + (emoji.name || emoji.aliases[0])}
|
||||
emoji={emoji}
|
||||
category={category}
|
||||
isLoaded={isLoaded}
|
||||
onItemOver={this.handleItemOver}
|
||||
onItemOut={this.handleItemOut}
|
||||
onItemClick={this.handleItemClick}
|
||||
@@ -261,7 +291,7 @@ export default class EmojiPicker extends React.Component {
|
||||
previewImage = (
|
||||
<span>
|
||||
<img
|
||||
src='/static/emoji/img_trans.gif'
|
||||
src='/static/images/img_trans.gif'
|
||||
className={' emojisprite-preview emoji-' + selected.filename + ' '}
|
||||
align='absmiddle'
|
||||
/>
|
||||
@@ -293,9 +323,9 @@ export default class EmojiPicker extends React.Component {
|
||||
|
||||
for (const category of CATEGORIES) {
|
||||
if (category === 'custom') {
|
||||
items.push(this.renderCategory('custom', this.state.filter, this.props.customEmojis));
|
||||
items.push(this.renderCategory('custom', true, this.state.filter, this.props.customEmojis));
|
||||
} else {
|
||||
items.push(this.renderCategory(category, this.state.filter));
|
||||
items.push(this.renderCategory(category, category === 'recent' || this.state.preloaded.indexOf(category) >= 0, this.state.filter));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -357,15 +387,15 @@ export default class EmojiPicker extends React.Component {
|
||||
selected={this.state.category === 'nature'}
|
||||
/>
|
||||
<EmojiPickerCategory
|
||||
category='food'
|
||||
category='foods'
|
||||
icon={
|
||||
<i
|
||||
className='fa fa-cutlery'
|
||||
title={Utils.localizeMessage('emoji_picker.food', 'Food')}
|
||||
title={Utils.localizeMessage('emoji_picker.foods', 'Foods')}
|
||||
/>
|
||||
}
|
||||
onCategoryClick={this.handleCategoryClick}
|
||||
selected={this.state.category === 'food'}
|
||||
selected={this.state.category === 'foods'}
|
||||
/>
|
||||
<EmojiPickerCategory
|
||||
category='activity'
|
||||
@@ -379,15 +409,15 @@ export default class EmojiPicker extends React.Component {
|
||||
selected={this.state.category === 'activity'}
|
||||
/>
|
||||
<EmojiPickerCategory
|
||||
category='travel'
|
||||
category='places'
|
||||
icon={
|
||||
<i
|
||||
className='fa fa-plane'
|
||||
title={Utils.localizeMessage('emoji_picker.travel', 'Travel')}
|
||||
title={Utils.localizeMessage('emoji_picker.places', 'Places')}
|
||||
/>
|
||||
}
|
||||
onCategoryClick={this.handleCategoryClick}
|
||||
selected={this.state.category === 'travel'}
|
||||
selected={this.state.category === 'places'}
|
||||
/>
|
||||
<EmojiPickerCategory
|
||||
category='objects'
|
||||
@@ -459,3 +489,87 @@ export default class EmojiPicker extends React.Component {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
var preloads = {
|
||||
people: {
|
||||
src: PeopleSpriteSheet,
|
||||
didPreload: false
|
||||
},
|
||||
nature: {
|
||||
src: NatureSpriteSheet,
|
||||
didPreload: false
|
||||
},
|
||||
foods: {
|
||||
src: FoodsSpriteSheet,
|
||||
didPreload: false
|
||||
},
|
||||
activity: {
|
||||
src: ActivitySpriteSheet,
|
||||
didPreload: false
|
||||
},
|
||||
places: {
|
||||
src: PlacesSpriteSheet,
|
||||
didPreload: false
|
||||
},
|
||||
objects: {
|
||||
src: ObjectsSpriteSheet,
|
||||
didPreload: false
|
||||
},
|
||||
symbols: {
|
||||
src: SymbolsSpriteSheet,
|
||||
didPreload: false
|
||||
},
|
||||
flags: {
|
||||
src: FlagsSpriteSheet,
|
||||
didPreload: false
|
||||
}
|
||||
};
|
||||
|
||||
var didBeginPreloading = false;
|
||||
|
||||
var preloadCallback = null;
|
||||
|
||||
export function beginPreloading() {
|
||||
if (didBeginPreloading) {
|
||||
return;
|
||||
}
|
||||
didBeginPreloading = true;
|
||||
preloadNextCategory();
|
||||
}
|
||||
|
||||
function preloadNextCategory() {
|
||||
let sheet = null;
|
||||
for (const category of CATEGORIES) {
|
||||
const preload = preloads[category];
|
||||
if (preload && !preload.didPreload) {
|
||||
sheet = preload;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (sheet) {
|
||||
const img = new Image();
|
||||
img.onload = () => {
|
||||
sheet.didPreload = true;
|
||||
if (preloadCallback) {
|
||||
preloadCallback();
|
||||
}
|
||||
preloadNextCategory();
|
||||
};
|
||||
img.src = sheet.src;
|
||||
}
|
||||
}
|
||||
|
||||
export function didPreloadCategory(category) {
|
||||
const preload = preloads[category];
|
||||
return preload && preload.didPreload;
|
||||
}
|
||||
|
||||
function subscribeToPreloads(callback) {
|
||||
preloadCallback = callback;
|
||||
}
|
||||
|
||||
function unsubscribeFromPreloads(callback) {
|
||||
if (callback === preloadCallback) {
|
||||
preloadCallback = null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1335,14 +1335,14 @@
|
||||
"emoji_picker.custom": "Custom",
|
||||
"emoji_picker.emojiPicker": "Emoji Picker",
|
||||
"emoji_picker.flags": "Flags",
|
||||
"emoji_picker.food": "Food",
|
||||
"emoji_picker.foods": "Foods",
|
||||
"emoji_picker.nature": "Nature",
|
||||
"emoji_picker.objects": "Objects",
|
||||
"emoji_picker.people": "People",
|
||||
"emoji_picker.recent": "Recently Used",
|
||||
"emoji_picker.search": "Search",
|
||||
"emoji_picker.symbols": "Symbols",
|
||||
"emoji_picker.travel": "Travel",
|
||||
"emoji_picker.places": "Places",
|
||||
"error.local_storage.help1": "Enable cookies",
|
||||
"error.local_storage.help2": "Turn off private browsing",
|
||||
"error.local_storage.help3": "Use a supported browser (IE 11, Chrome 43+, Firefox 38+, Safari 9, Edge)",
|
||||
|
||||
Двоичные данные
webapp/images/emoji-sheets/activity.png
Обычный файл
|
После Ширина: | Высота: | Размер: 503 KiB |
Двоичные данные
webapp/images/emoji-sheets/custom.png
Обычный файл
|
После Ширина: | Высота: | Размер: 54 KiB |
Двоичные данные
webapp/images/emoji-sheets/flags.png
Обычный файл
|
После Ширина: | Высота: | Размер: 1.0 MiB |
Двоичные данные
webapp/images/emoji-sheets/foods.png
Обычный файл
|
После Ширина: | Высота: | Размер: 577 KiB |
Двоичные данные
webapp/images/emoji-sheets/nature.png
Обычный файл
|
После Ширина: | Высота: | Размер: 1.0 MiB |
Двоичные данные
webapp/images/emoji-sheets/objects.png
Обычный файл
|
После Ширина: | Высота: | Размер: 1.0 MiB |
Двоичные данные
webapp/images/emoji-sheets/people.png
Обычный файл
|
После Ширина: | Высота: | Размер: 1.8 MiB |
Двоичные данные
webapp/images/emoji-sheets/places.png
Обычный файл
|
После Ширина: | Высота: | Размер: 812 KiB |
Двоичные данные
webapp/images/emoji-sheets/symbols.png
Обычный файл
|
После Ширина: | Высота: | Размер: 960 KiB |
Двоичные данные
webapp/images/emoji/0023-20e3.png
|
До Ширина: | Высота: | Размер: 2.3 KiB |
Двоичные данные
webapp/images/emoji/0023-fe0f-20e3.png
Обычный файл
|
После Ширина: | Высота: | Размер: 3.3 KiB |
Двоичные данные
webapp/images/emoji/002a-fe0f-20e3.png
Обычный файл
|
После Ширина: | Высота: | Размер: 3.5 KiB |
Двоичные данные
webapp/images/emoji/0030-20e3.png
|
До Ширина: | Высота: | Размер: 2.3 KiB |
Двоичные данные
webapp/images/emoji/0030-fe0f-20e3.png
Обычный файл
|
После Ширина: | Высота: | Размер: 3.2 KiB |
Двоичные данные
webapp/images/emoji/0031-20e3.png
|
До Ширина: | Высота: | Размер: 2.1 KiB |
Двоичные данные
webapp/images/emoji/0031-fe0f-20e3.png
Обычный файл
|
После Ширина: | Высота: | Размер: 2.3 KiB |
Двоичные данные
webapp/images/emoji/0032-20e3.png
|
До Ширина: | Высота: | Размер: 2.2 KiB |
Двоичные данные
webapp/images/emoji/0032-fe0f-20e3.png
Обычный файл
|
После Ширина: | Высота: | Размер: 3.0 KiB |
Двоичные данные
webapp/images/emoji/0033-20e3.png
|
До Ширина: | Высота: | Размер: 2.3 KiB |
Двоичные данные
webapp/images/emoji/0033-fe0f-20e3.png
Обычный файл
|
После Ширина: | Высота: | Размер: 3.3 KiB |
Двоичные данные
webapp/images/emoji/0034-20e3.png
|
До Ширина: | Высота: | Размер: 2.2 KiB |
Двоичные данные
webapp/images/emoji/0034-fe0f-20e3.png
Обычный файл
|
После Ширина: | Высота: | Размер: 2.7 KiB |
Двоичные данные
webapp/images/emoji/0035-20e3.png
|
До Ширина: | Высота: | Размер: 2.3 KiB |
Двоичные данные
webapp/images/emoji/0035-fe0f-20e3.png
Обычный файл
|
После Ширина: | Высота: | Размер: 3.1 KiB |
Двоичные данные
webapp/images/emoji/0036-20e3.png
|
До Ширина: | Высота: | Размер: 2.3 KiB |
Двоичные данные
webapp/images/emoji/0036-fe0f-20e3.png
Обычный файл
|
После Ширина: | Высота: | Размер: 3.4 KiB |
Двоичные данные
webapp/images/emoji/0037-20e3.png
|
До Ширина: | Высота: | Размер: 2.1 KiB |
Двоичные данные
webapp/images/emoji/0037-fe0f-20e3.png
Обычный файл
|
После Ширина: | Высота: | Размер: 2.5 KiB |
Двоичные данные
webapp/images/emoji/0038-20e3.png
|
До Ширина: | Высота: | Размер: 2.3 KiB |
Двоичные данные
webapp/images/emoji/0038-fe0f-20e3.png
Обычный файл
|
После Ширина: | Высота: | Размер: 3.5 KiB |
Двоичные данные
webapp/images/emoji/0039-20e3.png
|
До Ширина: | Высота: | Размер: 2.3 KiB |
Двоичные данные
webapp/images/emoji/0039-fe0f-20e3.png
Обычный файл
|
После Ширина: | Высота: | Размер: 3.4 KiB |
Двоичные данные
webapp/images/emoji/00a9-fe0f.png
Обычный файл
|
После Ширина: | Высота: | Размер: 2.2 KiB |
Двоичные данные
webapp/images/emoji/00a9.png
|
До Ширина: | Высота: | Размер: 1.6 KiB |
Двоичные данные
webapp/images/emoji/00ae-fe0f.png
Обычный файл
|
После Ширина: | Высота: | Размер: 2.1 KiB |
Двоичные данные
webapp/images/emoji/00ae.png
|
До Ширина: | Высота: | Размер: 1.6 KiB |
Двоичные данные
webapp/images/emoji/1f004-fe0f.png
Обычный файл
|
После Ширина: | Высота: | Размер: 3.9 KiB |
Двоичные данные
webapp/images/emoji/1f004.png
|
До Ширина: | Высота: | Размер: 2.2 KiB |
Двоичные данные
webapp/images/emoji/1f0cf.png
|
До Ширина: | Высота: | Размер: 2.4 KiB После Ширина: | Высота: | Размер: 4.4 KiB |
Двоичные данные
webapp/images/emoji/1f170-fe0f.png
Обычный файл
|
После Ширина: | Высота: | Размер: 3.0 KiB |
Двоичные данные
webapp/images/emoji/1f170.png
|
До Ширина: | Высота: | Размер: 2.2 KiB |
Двоичные данные
webapp/images/emoji/1f171-fe0f.png
Обычный файл
|
После Ширина: | Высота: | Размер: 2.9 KiB |
Двоичные данные
webapp/images/emoji/1f171.png
|
До Ширина: | Высота: | Размер: 2.2 KiB |
Двоичные данные
webapp/images/emoji/1f17e-fe0f.png
Обычный файл
|
После Ширина: | Высота: | Размер: 3.6 KiB |
Двоичные данные
webapp/images/emoji/1f17e.png
|
До Ширина: | Высота: | Размер: 2.3 KiB |
Двоичные данные
webapp/images/emoji/1f17f-fe0f.png
Обычный файл
|
После Ширина: | Высота: | Размер: 2.4 KiB |
Двоичные данные
webapp/images/emoji/1f17f.png
|
До Ширина: | Высота: | Размер: 2.1 KiB |
Двоичные данные
webapp/images/emoji/1f18e.png
|
До Ширина: | Высота: | Размер: 2.5 KiB После Ширина: | Высота: | Размер: 3.7 KiB |
Двоичные данные
webapp/images/emoji/1f191.png
|
До Ширина: | Высота: | Размер: 2.4 KiB После Ширина: | Высота: | Размер: 3.3 KiB |
Двоичные данные
webapp/images/emoji/1f192.png
|
До Ширина: | Высота: | Размер: 2.4 KiB После Ширина: | Высота: | Размер: 3.8 KiB |
Двоичные данные
webapp/images/emoji/1f193.png
|
До Ширина: | Высота: | Размер: 2.2 KiB После Ширина: | Высота: | Размер: 3.2 KiB |
Двоичные данные
webapp/images/emoji/1f194.png
|
До Ширина: | Высота: | Размер: 2.3 KiB После Ширина: | Высота: | Размер: 3.2 KiB |
Двоичные данные
webapp/images/emoji/1f195.png
|
До Ширина: | Высота: | Размер: 2.4 KiB После Ширина: | Высота: | Размер: 3.5 KiB |
Двоичные данные
webapp/images/emoji/1f196.png
|
До Ширина: | Высота: | Размер: 2.4 KiB После Ширина: | Высота: | Размер: 4.0 KiB |
Двоичные данные
webapp/images/emoji/1f197.png
|
До Ширина: | Высота: | Размер: 2.4 KiB После Ширина: | Высота: | Размер: 4.0 KiB |
Двоичные данные
webapp/images/emoji/1f198.png
|
До Ширина: | Высота: | Размер: 2.4 KiB После Ширина: | Высота: | Размер: 4.7 KiB |
Двоичные данные
webapp/images/emoji/1f199.png
|
До Ширина: | Высота: | Размер: 2.4 KiB После Ширина: | Высота: | Размер: 3.5 KiB |
Двоичные данные
webapp/images/emoji/1f19a.png
|
До Ширина: | Высота: | Размер: 2.3 KiB После Ширина: | Высота: | Размер: 3.3 KiB |
Двоичные данные
webapp/images/emoji/1f1e6-1f1e9.png
Обычный файл
|
После Ширина: | Высота: | Размер: 4.0 KiB |
Двоичные данные
webapp/images/emoji/1f1e6-1f1ea.png
Обычный файл
|
После Ширина: | Высота: | Размер: 3.1 KiB |
Двоичные данные
webapp/images/emoji/1f1e6-1f1eb.png
Обычный файл
|
После Ширина: | Высота: | Размер: 3.4 KiB |
Двоичные данные
webapp/images/emoji/1f1e6-1f1ec.png
Обычный файл
|
После Ширина: | Высота: | Размер: 4.4 KiB |
Двоичные данные
webapp/images/emoji/1f1e6-1f1ee.png
Обычный файл
|
После Ширина: | Высота: | Размер: 5.0 KiB |
Двоичные данные
webapp/images/emoji/1f1e6-1f1f1.png
Обычный файл
|
После Ширина: | Высота: | Размер: 4.4 KiB |
Двоичные данные
webapp/images/emoji/1f1e6-1f1f2.png
Обычный файл
|
После Ширина: | Высота: | Размер: 3.6 KiB |
Двоичные данные
webapp/images/emoji/1f1e6-1f1f4.png
Обычный файл
|
После Ширина: | Высота: | Размер: 3.7 KiB |
Двоичные данные
webapp/images/emoji/1f1e6-1f1f6.png
Обычный файл
|
После Ширина: | Высота: | Размер: 3.4 KiB |
Двоичные данные
webapp/images/emoji/1f1e6-1f1f7.png
Обычный файл
|
После Ширина: | Высота: | Размер: 3.9 KiB |
Двоичные данные
webapp/images/emoji/1f1e6-1f1f8.png
Обычный файл
|
После Ширина: | Высота: | Размер: 4.6 KiB |
Двоичные данные
webapp/images/emoji/1f1e6-1f1f9.png
Обычный файл
|
После Ширина: | Высота: | Размер: 3.6 KiB |
Двоичные данные
webapp/images/emoji/1f1e6-1f1fa.png
Обычный файл
|
После Ширина: | Высота: | Размер: 5.5 KiB |
Двоичные данные
webapp/images/emoji/1f1e6-1f1fc.png
Обычный файл
|
После Ширина: | Высота: | Размер: 4.1 KiB |
Двоичные данные
webapp/images/emoji/1f1e6-1f1fd.png
Обычный файл
|
После Ширина: | Высота: | Размер: 4.2 KiB |
Двоичные данные
webapp/images/emoji/1f1e6-1f1ff.png
Обычный файл
|
После Ширина: | Высота: | Размер: 4.1 KiB |
Двоичные данные
webapp/images/emoji/1f1e7-1f1e6.png
Обычный файл
|
После Ширина: | Высота: | Размер: 4.0 KiB |
Двоичные данные
webapp/images/emoji/1f1e7-1f1e7.png
Обычный файл
|
После Ширина: | Высота: | Размер: 3.4 KiB |
Двоичные данные
webapp/images/emoji/1f1e7-1f1e9.png
Обычный файл
|
После Ширина: | Высота: | Размер: 3.4 KiB |
Двоичные данные
webapp/images/emoji/1f1e7-1f1ea.png
Обычный файл
|
После Ширина: | Высота: | Размер: 2.5 KiB |
Двоичные данные
webapp/images/emoji/1f1e7-1f1eb.png
Обычный файл
|
После Ширина: | Высота: | Размер: 3.5 KiB |
Двоичные данные
webapp/images/emoji/1f1e7-1f1ec.png
Обычный файл
|
После Ширина: | Высота: | Размер: 3.4 KiB |
Двоичные данные
webapp/images/emoji/1f1e7-1f1ed.png
Обычный файл
|
После Ширина: | Высота: | Размер: 3.4 KiB |
Двоичные данные
webapp/images/emoji/1f1e7-1f1ee.png
Обычный файл
|
После Ширина: | Высота: | Размер: 5.2 KiB |
Двоичные данные
webapp/images/emoji/1f1e7-1f1ef.png
Обычный файл
|
После Ширина: | Высота: | Размер: 3.0 KiB |
Двоичные данные
webapp/images/emoji/1f1e7-1f1f1.png
Обычный файл
|
После Ширина: | Высота: | Размер: 4.3 KiB |
Двоичные данные
webapp/images/emoji/1f1e7-1f1f2.png
Обычный файл
|
После Ширина: | Высота: | Размер: 5.4 KiB |
Двоичные данные
webapp/images/emoji/1f1e7-1f1f3.png
Обычный файл
|
После Ширина: | Высота: | Размер: 5.3 KiB |
Двоичные данные
webapp/images/emoji/1f1e7-1f1f4.png
Обычный файл
|
После Ширина: | Высота: | Размер: 4.0 KiB |
Двоичные данные
webapp/images/emoji/1f1e7-1f1f6.png
Обычный файл
|
После Ширина: | Высота: | Размер: 3.8 KiB |
Двоичные данные
webapp/images/emoji/1f1e7-1f1f7.png
Обычный файл
|
После Ширина: | Высота: | Размер: 4.8 KiB |
Двоичные данные
webapp/images/emoji/1f1e7-1f1f8.png
Обычный файл
|
После Ширина: | Высота: | Размер: 3.9 KiB |
Двоичные данные
webapp/images/emoji/1f1e7-1f1f9.png
Обычный файл
|
После Ширина: | Высота: | Размер: 5.0 KiB |
Двоичные данные
webapp/images/emoji/1f1e7-1f1fc.png
Обычный файл
|
После Ширина: | Высота: | Размер: 4.2 KiB |
Двоичные данные
webapp/images/emoji/1f1e7-1f1fe.png
Обычный файл
|
После Ширина: | Высота: | Размер: 3.3 KiB |