Commit 1d38d8af authored by JC Brand's avatar JC Brand

Use twemoji for rendering emojis

parent 6b157eed
...@@ -7709,6 +7709,11 @@ body.reset { ...@@ -7709,6 +7709,11 @@ body.reset {
#conversejs .chatbox { #conversejs .chatbox {
text-align: left; text-align: left;
margin: 0 0.5em; } margin: 0 0.5em; }
#conversejs .chatbox img.emoji {
height: 1.2em;
width: 1.2em;
margin: 0 .05em 0 .1em;
vertical-align: -0.1em; }
@media screen and (max-height: 450px) { @media screen and (max-height: 450px) {
#conversejs .chatbox { #conversejs .chatbox {
margin: 0; margin: 0;
...@@ -7885,8 +7890,9 @@ body.reset { ...@@ -7885,8 +7890,9 @@ body.reset {
background-color: #fff; background-color: #fff;
bottom: 2rem; bottom: 2rem;
box-shadow: -1px -1px 2px 0 rgba(0, 0, 0, 0.4); box-shadow: -1px -1px 2px 0 rgba(0, 0, 0, 0.4);
height: auto;
margin-bottom: 0; margin-bottom: 0;
min-width: 20rem; min-width: 21rem;
position: absolute; position: absolute;
right: 0; right: 0;
top: auto; top: auto;
...@@ -7899,8 +7905,11 @@ body.reset { ...@@ -7899,8 +7905,11 @@ body.reset {
flex-direction: column; } flex-direction: column; }
#conversejs .chatbox .sendXMPPMessage .chat-toolbar li .toolbar-menu a { #conversejs .chatbox .sendXMPPMessage .chat-toolbar li .toolbar-menu a {
color: #578EA9; } color: #578EA9; }
#conversejs .chatbox .sendXMPPMessage .chat-toolbar li .toolbar-menu .emoji-picker-container {
background: white; }
#conversejs .chatbox .sendXMPPMessage .chat-toolbar li .toolbar-menu ul.emoji-picker { #conversejs .chatbox .sendXMPPMessage .chat-toolbar li .toolbar-menu ul.emoji-picker {
overflow: scroll; overflow-y: scroll;
overflow-x: hidden;
padding: 0.5em; } padding: 0.5em; }
#conversejs .chatbox .sendXMPPMessage .chat-toolbar li .toolbar-menu ul li { #conversejs .chatbox .sendXMPPMessage .chat-toolbar li .toolbar-menu ul li {
margin-left: 0; margin-left: 0;
...@@ -7929,7 +7938,7 @@ body.reset { ...@@ -7929,7 +7938,7 @@ body.reset {
justify-content: space-between; } justify-content: space-between; }
#conversejs .chatbox .sendXMPPMessage .chat-toolbar li.toggle-smiley .emoji-toolbar .emoji-category-picker li, #conversejs .chatbox .sendXMPPMessage .chat-toolbar li.toggle-smiley .emoji-toolbar .emoji-category-picker li,
#conversejs .chatbox .sendXMPPMessage .chat-toolbar li.toggle-smiley .emoji-toolbar .emoji-skintone-picker li { #conversejs .chatbox .sendXMPPMessage .chat-toolbar li.toggle-smiley .emoji-toolbar .emoji-skintone-picker li {
padding: 0.2em; padding: 0.25em;
font-size: 20px; } font-size: 20px; }
#conversejs .chatbox .sendXMPPMessage .chat-toolbar li.toggle-smiley .emoji-toolbar .emoji-category-picker li:hover, #conversejs .chatbox .sendXMPPMessage .chat-toolbar li.toggle-smiley .emoji-toolbar .emoji-category-picker li:hover,
#conversejs .chatbox .sendXMPPMessage .chat-toolbar li.toggle-smiley .emoji-toolbar .emoji-skintone-picker li:hover { #conversejs .chatbox .sendXMPPMessage .chat-toolbar li.toggle-smiley .emoji-toolbar .emoji-skintone-picker li:hover {
...@@ -8053,7 +8062,7 @@ body.reset { ...@@ -8053,7 +8062,7 @@ body.reset {
#conversejs.converse-fullscreen .chat-textarea { #conversejs.converse-fullscreen .chat-textarea {
max-height: 15em; } max-height: 15em; }
#conversejs.converse-fullscreen .emoji-picker { #conversejs.converse-fullscreen .emoji-picker {
height: 150px; } height: 200px; }
#conversejs.converse-fullscreen .chatbox { #conversejs.converse-fullscreen .chatbox {
width: 100%; width: 100%;
height: 100%; height: 100%;
...@@ -9270,6 +9279,11 @@ body.reset { ...@@ -9270,6 +9279,11 @@ body.reset {
#conversejs .message.chat-msg .chat-msg__text a { #conversejs .message.chat-msg .chat-msg__text a {
word-wrap: break-word; word-wrap: break-word;
word-break: break-all; } word-break: break-all; }
#conversejs .message.chat-msg .chat-msg__text img.emoji {
height: 1.5em;
width: 1.5em;
margin: 0 .05em 0 .1em;
vertical-align: -0.1em; }
#conversejs .message.chat-msg .chat-msg__text .emojione { #conversejs .message.chat-msg .chat-msg__text .emojione {
margin-bottom: -6px; } margin-bottom: -6px; }
#conversejs .message.chat-msg .chat-msg__media { #conversejs .message.chat-msg .chat-msg__media {
......
This diff is collapsed.
...@@ -608,14 +608,17 @@ domain_placeholder ...@@ -608,14 +608,17 @@ domain_placeholder
The placeholder text shown in the domain input on the registration form. The placeholder text shown in the domain input on the registration form.
emojione_image_path emoji_image_path
------------------- ----------------
* Default: ``'https://cdn.jsdelivr.net/emojione/assets/' + emojioneVersion + '/png/'`` * Default: ``'https://twemoji.maxcdn.com/2/'``
When `use_emojione`_ is set to ``true``, then this is the URL from where PNG image files for When `use_system_emojis`_ is set to ``false``, then this is the URL from where image files for
displaying emojis will be fetched. displaying emojis will be fetched.
If you've run ``make dev``, then these files are also available in ``./node_modules/twemoji/2/``,
which means you can avoid the CDN and host them yourself if you wish.
expose_rid_and_sid expose_rid_and_sid
------------------ ------------------
...@@ -1219,15 +1222,16 @@ Notification will be shown in the following cases: ...@@ -1219,15 +1222,16 @@ Notification will be shown in the following cases:
Requires the `src/converse-notification.js` plugin. Requires the `src/converse-notification.js` plugin.
use_emojione use_system_emojis
------------ -----------------
* Default: ``true`` * Default: ``true``
Determines whether `Emojione <https://www.emojione.com/>`_ should be used to Determines whether emojis should be rendered by the user's system.
render emojis. If set to ``false``, then rendering support will fall back to
the operating system or browser (which might not support emoji). Not all operating systems support (all) emojis. So alternatively you can let
Converse render the emojis with [Twemoji](https://twemoji.twitter.com/).
See also `emojione_image_path`_. See also `emoji_image_path`_.
show_only_online_users show_only_online_users
---------------------- ----------------------
......
...@@ -3531,9 +3531,9 @@ ...@@ -3531,9 +3531,9 @@
} }
}, },
"emojione": { "emojione": {
"version": "3.1.2", "version": "3.1.7",
"resolved": "https://registry.npmjs.org/emojione/-/emojione-3.1.2.tgz", "resolved": "https://registry.npmjs.org/emojione/-/emojione-3.1.7.tgz",
"integrity": "sha1-mR4wyA20sc8V6ssldiCn7c6cbvQ=", "integrity": "sha1-LTxyXGlvF5yd3jrLZVxiHulCmx4=",
"dev": true "dev": true
}, },
"emojis-list": { "emojis-list": {
...@@ -14321,6 +14321,12 @@ ...@@ -14321,6 +14321,12 @@
"integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=",
"dev": true "dev": true
}, },
"twemoji": {
"version": "11.0.1",
"resolved": "https://registry.npmjs.org/twemoji/-/twemoji-11.0.1.tgz",
"integrity": "sha512-Z0bRyZ1yO7cqa69oRhLZWmaLM0e9eeTugUXbnNQY3XPgRHJcSF8PKfp/dx3vHWtz9Y6o8fi3Ryjfpq4vBCeXjA==",
"dev": true
},
"type-check": { "type-check": {
"version": "0.3.2", "version": "0.3.2",
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
......
...@@ -110,6 +110,15 @@ ...@@ -110,6 +110,15 @@
text-align: left; text-align: left;
margin: 0 $chat-gutter; margin: 0 $chat-gutter;
img {
&.emoji {
height: 1.2em;
width: 1.2em;
margin: 0 .05em 0 .1em;
vertical-align: -0.1em;
}
}
@media screen and (max-height: $mobile-landscape-height) { @media screen and (max-height: $mobile-landscape-height) {
margin: 0; margin: 0;
width: $mobile-chat-width; width: $mobile-chat-width;
...@@ -321,8 +330,9 @@ ...@@ -321,8 +330,9 @@
background-color: #fff; background-color: #fff;
bottom: 2rem; bottom: 2rem;
box-shadow: -1px -1px 2px 0 rgba(0, 0, 0, 0.4); box-shadow: -1px -1px 2px 0 rgba(0, 0, 0, 0.4);
height: auto;
margin-bottom: 0; margin-bottom: 0;
min-width: 20rem; min-width: 21rem;
position: absolute; position: absolute;
right: 0; right: 0;
top: auto; top: auto;
...@@ -341,9 +351,13 @@ ...@@ -341,9 +351,13 @@
a { a {
color: $link-color; color: $link-color;
} }
.emoji-picker-container {
background: white;
}
ul { ul {
&.emoji-picker { &.emoji-picker {
overflow: scroll; overflow-y: scroll;
overflow-x: hidden;
padding: 0.5em; padding: 0.5em;
} }
li { li {
...@@ -351,8 +365,6 @@ ...@@ -351,8 +365,6 @@
cursor: pointer; cursor: pointer;
list-style: none; list-style: none;
position: relative; position: relative;
&.emoji-skintone {
}
&.insert-emoji { &.insert-emoji {
padding: 0.2em; padding: 0.2em;
&.picked { &.picked {
...@@ -377,7 +389,6 @@ ...@@ -377,7 +389,6 @@
} }
.emoji-toolbar { .emoji-toolbar {
box-shadow: 0 -1px 1px 0 rgba(0, 0, 0, 0.4); box-shadow: 0 -1px 1px 0 rgba(0, 0, 0, 0.4);
.emoji-category-picker { .emoji-category-picker {
padding-top: 0.5em; padding-top: 0.5em;
ul { ul {
...@@ -390,7 +401,7 @@ ...@@ -390,7 +401,7 @@
.emoji-category-picker, .emoji-category-picker,
.emoji-skintone-picker { .emoji-skintone-picker {
li { li {
padding: 0.2em; padding: 0.25em;
font-size: $font-size-huge; font-size: $font-size-huge;
&:hover { &:hover {
background-color: $highlight-color; background-color: $highlight-color;
......
...@@ -155,6 +155,14 @@ ...@@ -155,6 +155,14 @@
word-wrap: break-word; word-wrap: break-word;
word-break: break-all; word-break: break-all;
} }
img {
&.emoji {
height: 1.5em;
width: 1.5em;
margin: 0 .05em 0 .1em;
vertical-align: -0.1em;
}
}
.emojione { .emojione {
margin-bottom: -6px; margin-bottom: -6px;
} }
......
...@@ -148,7 +148,7 @@ $occupants-padding: 1em; ...@@ -148,7 +148,7 @@ $occupants-padding: 1em;
$fullpage-chat-head-height: 62px !default; $fullpage-chat-head-height: 62px !default;
$fullpage-chat-height: 100vh; $fullpage-chat-height: 100vh;
$fullpage-chat-width: 100%; $fullpage-chat-width: 100%;
$fullpage-emoji-picker-height: 150px !default; $fullpage-emoji-picker-height: 200px !default;
$fullpage-max-chat-textarea-height: 15em!default; $fullpage-max-chat-textarea-height: 15em!default;
$overlayed-chat-head-height: 55px !default; $overlayed-chat-head-height: 55px !default;
......
...@@ -5,9 +5,11 @@ ...@@ -5,9 +5,11 @@
// Licensed under the Mozilla Public License (MPLv2) // Licensed under the Mozilla Public License (MPLv2)
(function (root, factory) { (function (root, factory) {
define(["converse-core", define([
"utils/emoji",
"converse-core",
"bootstrap", "bootstrap",
"emojione", "twemoji",
"xss", "xss",
"templates/chatbox.html", "templates/chatbox.html",
"templates/chatbox_head.html", "templates/chatbox_head.html",
...@@ -28,9 +30,10 @@ ...@@ -28,9 +30,10 @@
"converse-message-view" "converse-message-view"
], factory); ], factory);
}(this, function ( }(this, function (
u,
converse, converse,
bootstrap, bootstrap,
emojione, twemoji,
xss, xss,
tpl_chatbox, tpl_chatbox,
tpl_chatbox_head, tpl_chatbox_head,
...@@ -49,7 +52,6 @@ ...@@ -49,7 +52,6 @@
) { ) {
"use strict"; "use strict";
const { $msg, Backbone, Promise, Strophe, _, b64_sha1, f, sizzle, moment } = converse.env; const { $msg, Backbone, Promise, Strophe, _, b64_sha1, f, sizzle, moment } = converse.env;
const u = converse.env.utils;
converse.plugins.add('converse-chatview', { converse.plugins.add('converse-chatview', {
/* Plugin dependencies are other plugins which might be /* Plugin dependencies are other plugins which might be
...@@ -73,11 +75,11 @@ ...@@ -73,11 +75,11 @@
{ __ } = _converse; { __ } = _converse;
_converse.api.settings.update({ _converse.api.settings.update({
'emojione_image_path': emojione.imagePathPNG, 'emoji_image_path': twemoji.default.base,
'show_send_button': false, 'show_send_button': false,
'show_toolbar': true, 'show_toolbar': true,
'time_format': 'HH:mm', 'time_format': 'HH:mm',
'use_emojione': false, 'use_system_emojis': true,
'visible_toolbar_buttons': { 'visible_toolbar_buttons': {
'call': false, 'call': false,
'clear': true, 'clear': true,
...@@ -85,8 +87,7 @@ ...@@ -85,8 +87,7 @@
'spoiler': true 'spoiler': true
}, },
}); });
emojione.imagePathPNG = _converse.emojione_image_path; twemoji.default.base = _converse.emoji_image_path;
emojione.ascii = true;
function onWindowStateChanged (data) { function onWindowStateChanged (data) {
if (_converse.chatboxviews) { if (_converse.chatboxviews) {
...@@ -122,8 +123,8 @@ ...@@ -122,8 +123,8 @@
_.extend( _.extend(
this.model.toJSON(), { this.model.toJSON(), {
'_': _, '_': _,
'transform': _converse.use_emojione ? emojione.shortnameToImage : emojione.shortnameToUnicode, 'transform': u.getEmojiRenderer(_converse),
'emojis_by_category': u.getEmojisByCategory(_converse, emojione), 'emojis_by_category': u.getEmojisByCategory(_converse),
'toned_emojis': u.getTonedEmojis(_converse), 'toned_emojis': u.getTonedEmojis(_converse),
'skintones': ['tone1', 'tone2', 'tone3', 'tone4', 'tone5'], 'skintones': ['tone1', 'tone2', 'tone3', 'tone4', 'tone5'],
'shouldBeHidden': this.shouldBeHidden 'shouldBeHidden': this.shouldBeHidden
......
...@@ -6,9 +6,9 @@ ...@@ -6,9 +6,9 @@
(function (root, factory) { (function (root, factory) {
define([ define([
"utils/emoji",
"converse-core", "converse-core",
"xss", "xss",
"emojione",
"filesize", "filesize",
"templates/csn.html", "templates/csn.html",
"templates/file_progress.html", "templates/file_progress.html",
...@@ -17,9 +17,9 @@ ...@@ -17,9 +17,9 @@
"templates/message_versions_modal.html", "templates/message_versions_modal.html",
], factory); ], factory);
}(this, function ( }(this, function (
u,
converse, converse,
xss, xss,
emojione,
filesize, filesize,
tpl_csn, tpl_csn,
tpl_file_progress, tpl_file_progress,
...@@ -29,7 +29,6 @@ ...@@ -29,7 +29,6 @@
) { ) {
"use strict"; "use strict";
const { Backbone, _, moment } = converse.env; const { Backbone, _, moment } = converse.env;
const u = converse.env.utils;
converse.plugins.add('converse-message-view', { converse.plugins.add('converse-message-view', {
...@@ -171,7 +170,7 @@ ...@@ -171,7 +170,7 @@
_.partial(u.addMentionsMarkup, _, this.model.get('references'), this.model.collection.chatbox), _.partial(u.addMentionsMarkup, _, this.model.get('references'), this.model.collection.chatbox),
u.addHyperlinks, u.addHyperlinks,
u.renderNewLines, u.renderNewLines,
_.partial(u.addEmoji, _converse, emojione, _) _.partial(u.addEmoji, _converse, _)
)(text); )(text);
} }
u.renderImageURLs(_converse, msg_content).then(() => { u.renderImageURLs(_converse, msg_content).then(() => {
......
...@@ -730,72 +730,6 @@ ...@@ -730,72 +730,6 @@
return frag return frag
}; };
u.addEmoji = function (_converse, emojione, text) {
if (_converse.use_emojione) {
return emojione.toImage(text);
} else {
return emojione.shortnameToUnicode(text);
}
}
u.getEmojisByCategory = function (_converse, emojione) {
/* Return a dict of emojis with the categories as keys and
* lists of emojis in that category as values.
*/
if (_.isUndefined(_converse.emojis_by_category)) {
const emojis = _.values(_.mapValues(emojione.emojioneList, function (value, key, o) {
value._shortname = key;
return value
}));
const tones = [':tone1:', ':tone2:', ':tone3:', ':tone4:', ':tone5:'];
const excluded = [':kiss_ww:', ':kiss_mm:', ':kiss_woman_man:'];
const excluded_substrings = [
':woman', ':man', ':women_', ':men_', '_man_', '_woman_', '_woman:', '_man:'
];
const excluded_categories = ['modifier', 'regional'];
const categories = _.difference(
_.uniq(_.map(emojis, _.partial(_.get, _, 'category'))),
excluded_categories
);
const emojis_by_category = {};
_.forEach(categories, (cat) => {
let list = _.sortBy(_.filter(emojis, ['category', cat]), ['uc_base']);
list = _.filter(
list,
(item) => !_.includes(_.concat(tones, excluded), item._shortname) &&
!_.some(excluded_substrings, _.partial(_.includes, item._shortname))
);
if (cat === 'people') {
const idx = _.findIndex(list, ['uc_base', '1f600']);
list = _.union(_.slice(list, idx), _.slice(list, 0, idx+1));
} else if (cat === 'activity') {
list = _.union(_.slice(list, 27-1), _.slice(list, 0, 27));
} else if (cat === 'objects') {
list = _.union(_.slice(list, 24-1), _.slice(list, 0, 24));
} else if (cat === 'travel') {
list = _.union(_.slice(list, 17-1), _.slice(list, 0, 17));
} else if (cat === 'symbols') {
list = _.union(_.slice(list, 60-1), _.slice(list, 0, 60));
}
emojis_by_category[cat] = list;
});
_converse.emojis_by_category = emojis_by_category;
}
return _converse.emojis_by_category;
};
u.getTonedEmojis = function (_converse) {
_converse.toned_emojis = _.uniq(
_.map(
_.filter(
u.getEmojisByCategory(_converse).people,
(person) => _.includes(person._shortname, '_tone')
),
(person) => person._shortname.replace(/_tone[1-5]/, '')
));
return _converse.toned_emojis;
};
u.isPersistableModel = function (model) { u.isPersistableModel = function (model) {
return model.collection && model.collection.browserStorage; return model.collection && model.collection.browserStorage;
}; };
......
...@@ -91,12 +91,10 @@ const config = { ...@@ -91,12 +91,10 @@ const config = {
"emojione": path.resolve(__dirname, "node_modules/emojione/lib/js/emojione"), "emojione": path.resolve(__dirname, "node_modules/emojione/lib/js/emojione"),
"es6-promise": path.resolve(__dirname, "node_modules/es6-promise/dist/es6-promise.auto"), "es6-promise": path.resolve(__dirname, "node_modules/es6-promise/dist/es6-promise.auto"),
"filesize": path.resolve(__dirname, "node_modules/filesize/lib/filesize"), "filesize": path.resolve(__dirname, "node_modules/filesize/lib/filesize"),
"utils/form": path.resolve(__dirname, "src/utils/form"),
"jed": path.resolve(__dirname, "node_modules/jed/jed"), "jed": path.resolve(__dirname, "node_modules/jed/jed"),
"jquery": path.resolve(__dirname, "src/jquery-stub"), "jquery": path.resolve(__dirname, "src/jquery-stub"),
"lodash": path.resolve(__dirname, "node_modules/lodash/lodash"), "lodash": path.resolve(__dirname, "node_modules/lodash/lodash"),
"lodash.converter": path.resolve(__dirname, "3rdparty/lodash.fp"), "lodash.converter": path.resolve(__dirname, "3rdparty/lodash.fp"),
"utils/muc": path.resolve(__dirname, "src/utils/muc"),
"pluggable": path.resolve(__dirname, "node_modules/pluggable.js/dist/pluggable"), "pluggable": path.resolve(__dirname, "node_modules/pluggable.js/dist/pluggable"),
"punycode": path.resolve(__dirname, "node_modules/urijs/src/punycode"), "punycode": path.resolve(__dirname, "node_modules/urijs/src/punycode"),
"sizzle": path.resolve(__dirname, "node_modules/sizzle/dist/sizzle"), "sizzle": path.resolve(__dirname, "node_modules/sizzle/dist/sizzle"),
...@@ -109,6 +107,9 @@ const config = { ...@@ -109,6 +107,9 @@ const config = {
"snabbdom-style": path.resolve(__dirname, "node_modules/snabbdom/dist/snabbdom-style"), "snabbdom-style": path.resolve(__dirname, "node_modules/snabbdom/dist/snabbdom-style"),
"strophe": path.resolve(__dirname, "node_modules/strophe.js/strophe"), "strophe": path.resolve(__dirname, "node_modules/strophe.js/strophe"),
"strophe.ping": path.resolve(__dirname, "node_modules/strophejs-plugin-ping/strophe.ping"), "strophe.ping": path.resolve(__dirname, "node_modules/strophejs-plugin-ping/strophe.ping"),
"utils/emoji": path.resolve(__dirname, "src/utils/emoji"),
"utils/form": path.resolve(__dirname, "src/utils/form"),
"utils/muc": path.resolve(__dirname, "src/utils/muc"),
"strophe.rsm": path.resolve(__dirname, "node_modules/strophejs-plugin-rsm/strophe.rsm"), "strophe.rsm": path.resolve(__dirname, "node_modules/strophejs-plugin-rsm/strophe.rsm"),
"tovnode": path.resolve(__dirname, "node_modules/snabbdom/dist/tovnode"), "tovnode": path.resolve(__dirname, "node_modules/snabbdom/dist/tovnode"),
"underscore": path.resolve(__dirname, "src/underscore-shim"), "underscore": path.resolve(__dirname, "src/underscore-shim"),
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment