mirror of
https://github.com/element-hq/element-web
synced 2024-11-27 03:36:07 +03:00
Various fixes and improvements to emojification.
- Use locally hosted emoji - Emojify SenderProfile and m.emote - Add emoji shortcodes as titles
This commit is contained in:
parent
4b8ad3c102
commit
dbbea63227
5 changed files with 83 additions and 6 deletions
|
@ -24,8 +24,39 @@ import escape from 'lodash/escape';
|
|||
import emojione from 'emojione';
|
||||
import classNames from 'classnames';
|
||||
|
||||
emojione.imagePathSVG = 'emojione/svg/';
|
||||
emojione.imageType = 'svg';
|
||||
|
||||
const EMOJI_REGEX = new RegExp(emojione.unicodeRegexp+"+", "gi");
|
||||
|
||||
/* modified from https://github.com/Ranks/emojione/blob/master/lib/js/emojione.js
|
||||
* because we want to include emoji shortnames in title text
|
||||
*/
|
||||
export function unicodeToImage(str) {
|
||||
let replaceWith, unicode, alt;
|
||||
const mappedUnicode = emojione.mapUnicodeToShort();
|
||||
|
||||
str = str.replace(emojione.regUnicode, function(unicodeChar) {
|
||||
if ( (typeof unicodeChar === 'undefined') || (unicodeChar === '') || (!(unicodeChar in emojione.jsEscapeMap)) ) {
|
||||
// if the unicodeChar doesnt exist just return the entire match
|
||||
return unicodeChar;
|
||||
}
|
||||
else {
|
||||
// get the unicode codepoint from the actual char
|
||||
unicode = emojione.jsEscapeMap[unicodeChar];
|
||||
|
||||
// depending on the settings, we'll either add the native unicode as the alt tag, otherwise the shortname
|
||||
alt = (emojione.unicodeAlt) ? emojione.convert(unicode.toUpperCase()) : mappedUnicode[unicode];
|
||||
const title = mappedUnicode[unicode];
|
||||
|
||||
replaceWith = `<img class="emojione" title="${title}" alt="${alt}" src="${emojione.imagePathSVG}${unicode}.svg${emojione.cacheBustParam}"/>`;
|
||||
return replaceWith;
|
||||
}
|
||||
});
|
||||
|
||||
return str;
|
||||
};
|
||||
|
||||
var sanitizeHtmlParams = {
|
||||
allowedTags: [
|
||||
'font', // custom to matrix for IRC-style font coloring
|
||||
|
@ -211,8 +242,7 @@ module.exports = {
|
|||
};
|
||||
}
|
||||
safeBody = sanitizeHtml(body, sanitizeHtmlParams);
|
||||
emojione.imageType = 'svg';
|
||||
safeBody = emojione.unicodeToImage(safeBody);
|
||||
safeBody = unicodeToImage(safeBody);
|
||||
}
|
||||
finally {
|
||||
delete sanitizeHtmlParams.textFilter;
|
||||
|
@ -239,7 +269,6 @@ module.exports = {
|
|||
},
|
||||
|
||||
emojifyText: function(text) {
|
||||
emojione.imageType = 'svg';
|
||||
return {
|
||||
__html: emojione.unicodeToImage(escape(text)),
|
||||
};
|
||||
|
|
|
@ -72,6 +72,7 @@ module.exports.components['views.messages.MFileBody'] = require('./components/vi
|
|||
module.exports.components['views.messages.MImageBody'] = require('./components/views/messages/MImageBody');
|
||||
module.exports.components['views.messages.MVideoBody'] = require('./components/views/messages/MVideoBody');
|
||||
module.exports.components['views.messages.MessageEvent'] = require('./components/views/messages/MessageEvent');
|
||||
module.exports.components['views.messages.SenderProfile'] = require('./components/views/messages/SenderProfile');
|
||||
module.exports.components['views.messages.TextualBody'] = require('./components/views/messages/TextualBody');
|
||||
module.exports.components['views.messages.TextualEvent'] = require('./components/views/messages/TextualEvent');
|
||||
module.exports.components['views.messages.UnknownBody'] = require('./components/views/messages/UnknownBody');
|
||||
|
|
|
@ -19,6 +19,7 @@ var sdk = require('../../index');
|
|||
var dis = require("../../dispatcher");
|
||||
var WhoIsTyping = require("../../WhoIsTyping");
|
||||
var MatrixClientPeg = require("../../MatrixClientPeg");
|
||||
import {emojifyText} from '../../HtmlUtils';
|
||||
|
||||
module.exports = React.createClass({
|
||||
displayName: 'RoomStatusBar',
|
||||
|
@ -259,10 +260,11 @@ module.exports = React.createClass({
|
|||
}
|
||||
|
||||
var typingString = this.state.whoisTypingString;
|
||||
const typingHtml = emojifyText(typingString);
|
||||
if (typingString) {
|
||||
return (
|
||||
<div className="mx_RoomStatusBar_typingBar">
|
||||
{typingString}
|
||||
<span dangerouslySetInnerHTML={typingHtml} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
43
src/components/views/messages/SenderProfile.js
Normal file
43
src/components/views/messages/SenderProfile.js
Normal file
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
Copyright 2015, 2016 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import React from 'react';
|
||||
import {emojifyText} from '../../../HtmlUtils';
|
||||
|
||||
export default function SenderProfile(props) {
|
||||
const {mxEvent} = props;
|
||||
const name = mxEvent.sender ? mxEvent.sender.name : mxEvent.getSender();
|
||||
const {msgtype} = mxEvent.getContent();
|
||||
|
||||
if (msgtype === 'm.emote') {
|
||||
return <span />; // emote message must include the name so don't duplicate it
|
||||
}
|
||||
|
||||
return (
|
||||
<span className="mx_SenderProfile"
|
||||
dangerouslySetInnerHTML={emojifyText(`${name || ''} ${props.aux || ''}`)}
|
||||
onClick={props.onClick}>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
SenderProfile.propTypes = {
|
||||
mxEvent: React.PropTypes.object.isRequired, // event whose sender we're showing
|
||||
aux: React.PropTypes.string, // stuff to go after the sender name, if anything
|
||||
onClick: React.PropTypes.func,
|
||||
};
|
|
@ -23,6 +23,7 @@ var linkify = require('linkifyjs');
|
|||
var linkifyElement = require('linkifyjs/element');
|
||||
var linkifyMatrix = require('../../../linkify-matrix');
|
||||
var sdk = require('../../../index');
|
||||
import {emojifyText} from '../../../HtmlUtils';
|
||||
|
||||
linkifyMatrix(linkify);
|
||||
|
||||
|
@ -200,10 +201,11 @@ module.exports = React.createClass({
|
|||
|
||||
switch (content.msgtype) {
|
||||
case "m.emote":
|
||||
var name = mxEvent.sender ? mxEvent.sender.name : mxEvent.getSender();
|
||||
const name = mxEvent.sender ? mxEvent.sender.name : mxEvent.getSender();
|
||||
const nameHtml = emojifyText(name);
|
||||
return (
|
||||
<span ref="content" className="mx_MEmoteBody mx_EventTile_content">
|
||||
* { name } { body }
|
||||
* <span dangerouslySetInnerHTML={nameHtml} /> { body }
|
||||
{ widgets }
|
||||
</span>
|
||||
);
|
||||
|
|
Loading…
Reference in a new issue