replace emojione with twemoji. completely untested & debugged & unoptimised
This commit is contained in:
parent
7a244b85c1
commit
dc72641264
30 changed files with 103 additions and 343 deletions
|
@ -256,8 +256,6 @@ export default class Autocomplete extends React.Component {
|
|||
}
|
||||
|
||||
render() {
|
||||
const EmojiText = sdk.getComponent('views.elements.EmojiText');
|
||||
|
||||
let position = 1;
|
||||
const renderedCompletions = this.state.completions.map((completionResult, i) => {
|
||||
const completions = completionResult.completions.map((completion, i) => {
|
||||
|
@ -282,7 +280,7 @@ export default class Autocomplete extends React.Component {
|
|||
|
||||
return completions.length > 0 ? (
|
||||
<div key={i} className="mx_Autocomplete_ProviderSection">
|
||||
<EmojiText element="div" className="mx_Autocomplete_provider_name">{ completionResult.provider.getName() }</EmojiText>
|
||||
<div className="mx_Autocomplete_provider_name">{ completionResult.provider.getName() }</div>
|
||||
{ completionResult.provider.renderCompletions(completions) }
|
||||
</div>
|
||||
) : null;
|
||||
|
|
|
@ -111,7 +111,6 @@ const EntityTile = React.createClass({
|
|||
let nameEl;
|
||||
const {name} = this.props;
|
||||
|
||||
const EmojiText = sdk.getComponent('elements.EmojiText');
|
||||
if (!this.props.suppressOnHover) {
|
||||
const activeAgo = this.props.presenceLastActiveAgo ?
|
||||
(Date.now() - (this.props.presenceLastTs - this.props.presenceLastActiveAgo)) : -1;
|
||||
|
@ -128,24 +127,24 @@ const EntityTile = React.createClass({
|
|||
}
|
||||
nameEl = (
|
||||
<div className="mx_EntityTile_details">
|
||||
<EmojiText element="div" className="mx_EntityTile_name" dir="auto">
|
||||
<div className="mx_EntityTile_name" dir="auto">
|
||||
{ name }
|
||||
</EmojiText>
|
||||
</div>
|
||||
{presenceLabel}
|
||||
</div>
|
||||
);
|
||||
} else if (this.props.subtextLabel) {
|
||||
nameEl = (
|
||||
<div className="mx_EntityTile_details">
|
||||
<EmojiText element="div" className="mx_EntityTile_name" dir="auto">
|
||||
<div className="mx_EntityTile_name" dir="auto">
|
||||
{name}
|
||||
</EmojiText>
|
||||
</div>
|
||||
<span className="mx_EntityTile_subtext">{this.props.subtextLabel}</span>
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
nameEl = (
|
||||
<EmojiText element="div" className="mx_EntityTile_name" dir="auto">{ name }</EmojiText>
|
||||
<div className="mx_EntityTile_name" dir="auto">{ name }</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -674,14 +674,13 @@ module.exports = withMatrixClient(React.createClass({
|
|||
|
||||
switch (this.props.tileShape) {
|
||||
case 'notif': {
|
||||
const EmojiText = sdk.getComponent('elements.EmojiText');
|
||||
const room = this.props.matrixClient.getRoom(this.props.mxEvent.getRoomId());
|
||||
return (
|
||||
<div className={classes}>
|
||||
<div className="mx_EventTile_roomName">
|
||||
<EmojiText element="a" href={permalink} onClick={this.onPermalinkClicked}>
|
||||
<a href={permalink} onClick={this.onPermalinkClicked}>
|
||||
{ room ? room.name : '' }
|
||||
</EmojiText>
|
||||
</a>
|
||||
</div>
|
||||
<div className="mx_EventTile_senderDetails">
|
||||
{ avatar }
|
||||
|
|
|
@ -978,7 +978,6 @@ module.exports = withMatrixClient(React.createClass({
|
|||
}
|
||||
|
||||
const GeminiScrollbarWrapper = sdk.getComponent("elements.GeminiScrollbarWrapper");
|
||||
const EmojiText = sdk.getComponent('elements.EmojiText');
|
||||
|
||||
let backButton;
|
||||
if (this.props.member.roomId) {
|
||||
|
@ -993,7 +992,7 @@ module.exports = withMatrixClient(React.createClass({
|
|||
<div className="mx_MemberInfo_name">
|
||||
{ backButton }
|
||||
{ e2eIconElement }
|
||||
<EmojiText element="h2">{ memberName }</EmojiText>
|
||||
<h2>{ memberName }</h2>
|
||||
</div>
|
||||
{ avatarElement }
|
||||
<div className="mx_MemberInfo_container">
|
||||
|
|
|
@ -51,10 +51,9 @@ import ContentMessages from '../../../ContentMessages';
|
|||
|
||||
import {MATRIXTO_URL_PATTERN} from '../../../linkify-matrix';
|
||||
|
||||
import {
|
||||
asciiRegexp, unicodeRegexp, shortnameToUnicode,
|
||||
asciiList, mapUnicodeToShort, toShort,
|
||||
} from 'emojione';
|
||||
import EMOJIBASE from 'emojibase-data/en/compact.json';
|
||||
import EMOTICON_REGEX from 'emojibase-regex/emoticon';
|
||||
|
||||
import SettingsStore, {SettingLevel} from "../../../settings/SettingsStore";
|
||||
import {makeUserPermalink} from "../../../matrix-to";
|
||||
import ReplyPreview from "./ReplyPreview";
|
||||
|
@ -63,9 +62,7 @@ import ReplyThread from "../elements/ReplyThread";
|
|||
import {ContentHelpers} from 'matrix-js-sdk';
|
||||
import AccessibleButton from '../elements/AccessibleButton';
|
||||
|
||||
const EMOJI_UNICODE_TO_SHORTNAME = mapUnicodeToShort();
|
||||
const REGEX_EMOJI_WHITESPACE = new RegExp('(?:^|\\s)(' + asciiRegexp + ')\\s$');
|
||||
const EMOJI_REGEX = new RegExp(unicodeRegexp, 'g');
|
||||
const REGEX_EMOJI_WHITESPACE = new RegExp('(?:^|\\s)(' + EMOTICON_REGEX + ')\\s$');
|
||||
|
||||
const TYPING_USER_TIMEOUT = 10000; const TYPING_SERVER_TIMEOUT = 30000;
|
||||
|
||||
|
@ -273,9 +270,8 @@ export default class MessageComposerInput extends React.Component {
|
|||
case 'emoji':
|
||||
// XXX: apparently you can't return plain strings from serializer rules
|
||||
// until https://github.com/ianstormtaylor/slate/pull/1854 is merged.
|
||||
// So instead we temporarily wrap emoji from RTE in an arbitrary tag
|
||||
// (<b/>). <span/> would be nicer, but in practice it causes CSS issues.
|
||||
return <b>{ obj.data.get('emojiUnicode') }</b>;
|
||||
// So instead we temporarily wrap emoji from RTE in a span.
|
||||
return <span>{ obj.data.get('emojiUnicode') }</span>;
|
||||
}
|
||||
return this.renderNode({
|
||||
node: obj,
|
||||
|
@ -375,7 +371,6 @@ export default class MessageComposerInput extends React.Component {
|
|||
const html = HtmlUtils.bodyToHtml(payload.event.getContent(), null, {
|
||||
forComposerQuote: true,
|
||||
returnString: true,
|
||||
emojiOne: false,
|
||||
});
|
||||
const fragment = this.html.deserialize(html);
|
||||
// FIXME: do we want to put in a permalink to the original quote here?
|
||||
|
@ -540,10 +535,7 @@ export default class MessageComposerInput extends React.Component {
|
|||
// The first matched group includes just the matched plaintext emoji
|
||||
const emojiMatch = REGEX_EMOJI_WHITESPACE.exec(text.slice(0, currentStartOffset));
|
||||
if (emojiMatch) {
|
||||
// plaintext -> hex unicode
|
||||
const emojiUc = asciiList[emojiMatch[1]];
|
||||
// hex unicode -> shortname -> actual unicode
|
||||
const unicodeEmoji = shortnameToUnicode(EMOJI_UNICODE_TO_SHORTNAME[emojiUc]);
|
||||
const unicodeEmoji = EMOJIBASE.find(e => e.emoticon && e.emoticon.contains(emoijMatch[1]));
|
||||
|
||||
const range = Range.create({
|
||||
anchor: {
|
||||
|
@ -561,54 +553,6 @@ export default class MessageComposerInput extends React.Component {
|
|||
}
|
||||
}
|
||||
|
||||
// emojioneify any emoji
|
||||
let foundEmoji;
|
||||
do {
|
||||
foundEmoji = false;
|
||||
|
||||
for (const node of editorState.document.getTexts()) {
|
||||
if (node.text !== '' && HtmlUtils.containsEmoji(node.text)) {
|
||||
let match;
|
||||
EMOJI_REGEX.lastIndex = 0;
|
||||
while ((match = EMOJI_REGEX.exec(node.text)) !== null) {
|
||||
const range = Range.create({
|
||||
anchor: {
|
||||
key: node.key,
|
||||
offset: match.index,
|
||||
},
|
||||
focus: {
|
||||
key: node.key,
|
||||
offset: match.index + match[0].length,
|
||||
},
|
||||
});
|
||||
const inline = Inline.create({
|
||||
type: 'emoji',
|
||||
data: { emojiUnicode: match[0] },
|
||||
});
|
||||
change = change.insertInlineAtRange(range, inline);
|
||||
editorState = change.value;
|
||||
|
||||
// if we replaced an emoji, start again looking for more
|
||||
// emoji in the new editor state since doing the replacement
|
||||
// will change the node structure & offsets so we can't compute
|
||||
// insertion ranges from node.key / match.index anymore.
|
||||
foundEmoji = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} while (foundEmoji);
|
||||
|
||||
// work around weird bug where inserting emoji via the macOS
|
||||
// emoji picker can leave the selection stuck in the emoji's
|
||||
// child text. This seems to happen due to selection getting
|
||||
// moved in the normalisation phase after calculating these changes
|
||||
if (editorState.selection.anchor.key &&
|
||||
editorState.document.getParent(editorState.selection.anchor.key).type === 'emoji') {
|
||||
change = change.moveToStartOfNextText();
|
||||
editorState = change.value;
|
||||
}
|
||||
|
||||
if (this.props.onInputStateChanged && editorState.blocks.size > 0) {
|
||||
let blockType = editorState.blocks.first().type;
|
||||
// console.log("onInputStateChanged; current block type is " + blockType + " and marks are " + editorState.activeMarks);
|
||||
|
@ -1295,7 +1239,7 @@ export default class MessageComposerInput extends React.Component {
|
|||
// Move selection to the end of the selected history
|
||||
const change = editorState.change().moveToEndOfNode(editorState.document);
|
||||
|
||||
// We don't call this.onChange(change) now, as fixups on stuff like emoji
|
||||
// We don't call this.onChange(change) now, as fixups on stuff like pills
|
||||
// should already have been done and persisted in the history.
|
||||
editorState = change.value;
|
||||
|
||||
|
@ -1473,20 +1417,8 @@ export default class MessageComposerInput extends React.Component {
|
|||
</a>;
|
||||
}
|
||||
}
|
||||
case 'emoji': {
|
||||
const { data } = node;
|
||||
const emojiUnicode = data.get('emojiUnicode');
|
||||
const uri = RichText.unicodeToEmojiUri(emojiUnicode);
|
||||
const shortname = toShort(emojiUnicode);
|
||||
const className = classNames('mx_emojione', {
|
||||
mx_emojione_selected: isSelected,
|
||||
});
|
||||
const style = {};
|
||||
if (props.selected) style.border = '1px solid blue';
|
||||
return <img className={ className } src={ uri }
|
||||
title={ shortname } alt={ emojiUnicode } style={style}
|
||||
/>;
|
||||
}
|
||||
case 'emoji':
|
||||
return data.get('emojiUnicode');
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -66,13 +66,12 @@ export default class ReplyPreview extends React.Component {
|
|||
if (!this.state.event) return null;
|
||||
|
||||
const EventTile = sdk.getComponent('rooms.EventTile');
|
||||
const EmojiText = sdk.getComponent('views.elements.EmojiText');
|
||||
|
||||
return <div className="mx_ReplyPreview">
|
||||
<div className="mx_ReplyPreview_section">
|
||||
<EmojiText element="div" className="mx_ReplyPreview_header mx_ReplyPreview_title">
|
||||
<div className="mx_ReplyPreview_header mx_ReplyPreview_title">
|
||||
{ '💬 ' + _t('Replying') }
|
||||
</EmojiText>
|
||||
</div>
|
||||
<div className="mx_ReplyPreview_header mx_ReplyPreview_cancel">
|
||||
<img className="mx_filterFlipColor" src={require("../../../../res/img/cancel.svg")} width="18" height="18"
|
||||
onClick={cancelQuoting} />
|
||||
|
|
|
@ -147,7 +147,6 @@ module.exports = React.createClass({
|
|||
|
||||
render: function() {
|
||||
const RoomAvatar = sdk.getComponent("avatars.RoomAvatar");
|
||||
const EmojiText = sdk.getComponent('elements.EmojiText');
|
||||
|
||||
let searchStatus = null;
|
||||
let cancelButton = null;
|
||||
|
@ -191,10 +190,10 @@ module.exports = React.createClass({
|
|||
roomName = this.props.room.name;
|
||||
}
|
||||
|
||||
const emojiTextClasses = classNames('mx_RoomHeader_nametext', { mx_RoomHeader_settingsHint: settingsHint });
|
||||
const textClasses = classNames('mx_RoomHeader_nametext', { mx_RoomHeader_settingsHint: settingsHint });
|
||||
const name =
|
||||
<div className="mx_RoomHeader_name" onClick={this.props.onSettingsClick}>
|
||||
<EmojiText dir="auto" element="div" className={emojiTextClasses} title={roomName}>{ roomName }</EmojiText>
|
||||
<div dir="auto" className={textClasses} title={roomName}>{ roomName }</div>
|
||||
{ searchStatus }
|
||||
</div>;
|
||||
|
||||
|
|
|
@ -342,7 +342,6 @@ module.exports = React.createClass({
|
|||
badge = <div className={badgeClasses}>{ badgeContent }</div>;
|
||||
}
|
||||
|
||||
const EmojiText = sdk.getComponent('elements.EmojiText');
|
||||
let label;
|
||||
let subtextLabel;
|
||||
let tooltip;
|
||||
|
@ -354,14 +353,7 @@ module.exports = React.createClass({
|
|||
});
|
||||
|
||||
subtextLabel = subtext ? <span className="mx_RoomTile_subtext">{ subtext }</span> : null;
|
||||
|
||||
if (this.state.selected) {
|
||||
const nameSelected = <EmojiText>{ name }</EmojiText>;
|
||||
|
||||
label = <div title={name} className={nameClasses} dir="auto">{ nameSelected }</div>;
|
||||
} else {
|
||||
label = <EmojiText element="div" title={name} className={nameClasses} dir="auto">{ name }</EmojiText>;
|
||||
}
|
||||
label = <div title={name} className={nameClasses} dir="auto">{ nameSelected }</div>;
|
||||
} else if (this.state.hover) {
|
||||
const Tooltip = sdk.getComponent("elements.Tooltip");
|
||||
tooltip = <Tooltip className="mx_RoomTile_tooltip" label={this.props.room.name} dir="auto" />;
|
||||
|
|
|
@ -212,15 +212,13 @@ module.exports = React.createClass({
|
|||
return (<div className="mx_WhoIsTypingTile_empty" />);
|
||||
}
|
||||
|
||||
const EmojiText = sdk.getComponent('elements.EmojiText');
|
||||
|
||||
return (
|
||||
<li className="mx_WhoIsTypingTile">
|
||||
<div className="mx_WhoIsTypingTile_avatars">
|
||||
{ this._renderTypingIndicatorAvatars(usersTyping, this.props.whoIsTypingLimit) }
|
||||
</div>
|
||||
<div className="mx_WhoIsTypingTile_label">
|
||||
<EmojiText>{ typingString }</EmojiText>
|
||||
{ typingString }
|
||||
</div>
|
||||
</li>
|
||||
);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue