Add EmojiText component for emoji replacement.

This commit is contained in:
Aviral Dasgupta 2016-08-10 00:31:51 +05:30
parent dbbea63227
commit 09e8a45cde
10 changed files with 59 additions and 38 deletions

View file

@ -19,7 +19,7 @@ var sdk = require('../../index');
var dis = require("../../dispatcher"); var dis = require("../../dispatcher");
var WhoIsTyping = require("../../WhoIsTyping"); var WhoIsTyping = require("../../WhoIsTyping");
var MatrixClientPeg = require("../../MatrixClientPeg"); var MatrixClientPeg = require("../../MatrixClientPeg");
import {emojifyText} from '../../HtmlUtils'; import EmojiText from '../views/elements/EmojiText';
module.exports = React.createClass({ module.exports = React.createClass({
displayName: 'RoomStatusBar', displayName: 'RoomStatusBar',
@ -260,11 +260,10 @@ module.exports = React.createClass({
} }
var typingString = this.state.whoisTypingString; var typingString = this.state.whoisTypingString;
const typingHtml = emojifyText(typingString);
if (typingString) { if (typingString) {
return ( return (
<div className="mx_RoomStatusBar_typingBar"> <div className="mx_RoomStatusBar_typingBar">
<span dangerouslySetInnerHTML={typingHtml} /> <EmojiText>{typingString}</EmojiText>
</div> </div>
); );
} }

View file

@ -18,7 +18,7 @@ limitations under the License.
var React = require('react'); var React = require('react');
var AvatarLogic = require("../../../Avatar"); var AvatarLogic = require("../../../Avatar");
import {emojifyText} from '../../../HtmlUtils'; import EmojiText from '../../views/elements/EmojiText';
module.exports = React.createClass({ module.exports = React.createClass({
displayName: 'BaseAvatar', displayName: 'BaseAvatar',
@ -142,15 +142,13 @@ module.exports = React.createClass({
} = this.props; } = this.props;
if (imageUrl === this.state.defaultImageUrl) { if (imageUrl === this.state.defaultImageUrl) {
var initialLetter = emojifyText(this._getInitialLetter(name)); const initialLetter = this._getInitialLetter(name);
return ( return (
<span className="mx_BaseAvatar" {...otherProps}> <span className="mx_BaseAvatar" {...otherProps}>
<span className="mx_BaseAvatar_initial" aria-hidden="true" <EmojiText className="mx_BaseAvatar_initial" aria-hidden="true"
style={{ fontSize: (width * 0.65) + "px", style={{ fontSize: (width * 0.65) + "px",
width: width + "px", width: width + "px",
lineHeight: height + "px" }} lineHeight: height + "px" }}>{initialLetter}</EmojiText>
dangerouslySetInnerHTML={initialLetter}>
</span>
<img className="mx_BaseAvatar_image" src={imageUrl} <img className="mx_BaseAvatar_image" src={imageUrl}
alt="" title={title} onError={this.onError} alt="" title={title} onError={this.onError}
width={width} height={height} /> width={width} height={height} />

View file

@ -0,0 +1,33 @@
/*
Copyright 2016 Aviral Dasgupta
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.
*/
import React from 'react';
import {emojifyText} from '../../../HtmlUtils';
export default function EmojiText(props) {
const {element, children, ...restProps} = props;
restProps.dangerouslySetInnerHTML = emojifyText(children);
return React.createElement(element, restProps);
}
EmojiText.propTypes = {
element: React.PropTypes.string,
children: React.PropTypes.string.isRequired,
};
EmojiText.defaultProps = {
element: 'span',
};

View file

@ -17,7 +17,7 @@
'use strict'; 'use strict';
import React from 'react'; import React from 'react';
import {emojifyText} from '../../../HtmlUtils'; import EmojiText from '../elements/EmojiText';
export default function SenderProfile(props) { export default function SenderProfile(props) {
const {mxEvent} = props; const {mxEvent} = props;
@ -29,10 +29,8 @@ export default function SenderProfile(props) {
} }
return ( return (
<span className="mx_SenderProfile" <EmojiText className="mx_SenderProfile"
dangerouslySetInnerHTML={emojifyText(`${name || ''} ${props.aux || ''}`)} onClick={props.onClick}>{`${name || ''} ${props.aux || ''}`}</EmojiText>
onClick={props.onClick}>
</span>
); );
} }

View file

@ -23,7 +23,7 @@ var linkify = require('linkifyjs');
var linkifyElement = require('linkifyjs/element'); var linkifyElement = require('linkifyjs/element');
var linkifyMatrix = require('../../../linkify-matrix'); var linkifyMatrix = require('../../../linkify-matrix');
var sdk = require('../../../index'); var sdk = require('../../../index');
import {emojifyText} from '../../../HtmlUtils'; import EmojiText from '../../views/elements/EmojiText';
linkifyMatrix(linkify); linkifyMatrix(linkify);
@ -202,10 +202,9 @@ module.exports = React.createClass({
switch (content.msgtype) { switch (content.msgtype) {
case "m.emote": case "m.emote":
const name = mxEvent.sender ? mxEvent.sender.name : mxEvent.getSender(); const name = mxEvent.sender ? mxEvent.sender.name : mxEvent.getSender();
const nameHtml = emojifyText(name);
return ( return (
<span ref="content" className="mx_MEmoteBody mx_EventTile_content"> <span ref="content" className="mx_MEmoteBody mx_EventTile_content">
* <span dangerouslySetInnerHTML={nameHtml} /> { body } * <EmojiText>{name}</EmojiText> { body }
{ widgets } { widgets }
</span> </span>
); );

View file

@ -19,7 +19,7 @@ limitations under the License.
var React = require('react'); var React = require('react');
var TextForEvent = require('../../../TextForEvent'); var TextForEvent = require('../../../TextForEvent');
import {emojifyText} from '../../../HtmlUtils'; import EmojiText from '../elements/EmojiText';
module.exports = React.createClass({ module.exports = React.createClass({
displayName: 'TextualEvent', displayName: 'TextualEvent',
@ -33,11 +33,8 @@ module.exports = React.createClass({
render: function() { render: function() {
var text = TextForEvent.textForEvent(this.props.mxEvent); var text = TextForEvent.textForEvent(this.props.mxEvent);
if (text == null || text.length === 0) return null; if (text == null || text.length === 0) return null;
let textHTML = emojifyText(TextForEvent.textForEvent(this.props.mxEvent));
return ( return (
<div className="mx_TextualEvent" dangerouslySetInnerHTML={textHTML}> <EmojiText element="div" className="mx_TextualEvent">{text}</EmojiText>
</div>
); );
}, },
}); });

View file

@ -20,7 +20,7 @@ var React = require('react');
var MatrixClientPeg = require('../../../MatrixClientPeg'); var MatrixClientPeg = require('../../../MatrixClientPeg');
var sdk = require('../../../index'); var sdk = require('../../../index');
import {emojifyText} from '../../../HtmlUtils'; import EmojiText from '../elements/EmojiText';
var PRESENCE_CLASS = { var PRESENCE_CLASS = {
@ -103,7 +103,7 @@ module.exports = React.createClass({
var mainClassName = "mx_EntityTile "; var mainClassName = "mx_EntityTile ";
mainClassName += presenceClass + (this.props.className ? (" " + this.props.className) : ""); mainClassName += presenceClass + (this.props.className ? (" " + this.props.className) : "");
var nameEl; var nameEl;
let nameHTML = emojifyText(this.props.name); const {name} = this.props;
if (this.state.hover && !this.props.suppressOnHover) { if (this.state.hover && !this.props.suppressOnHover) {
var activeAgo = this.props.presenceLastActiveAgo ? var activeAgo = this.props.presenceLastActiveAgo ?
@ -114,7 +114,7 @@ module.exports = React.createClass({
nameEl = ( nameEl = (
<div className="mx_EntityTile_details"> <div className="mx_EntityTile_details">
<img className="mx_EntityTile_chevron" src="img/member_chevron.png" width="8" height="12"/> <img className="mx_EntityTile_chevron" src="img/member_chevron.png" width="8" height="12"/>
<div className="mx_EntityTile_name_hover" dangerouslySetInnerHTML={nameHTML}></div> <EmojiText element="div" className="mx_EntityTile_name_hover">{name}</EmojiText>
<PresenceLabel activeAgo={ activeAgo } <PresenceLabel activeAgo={ activeAgo }
currentlyActive={this.props.presenceCurrentlyActive} currentlyActive={this.props.presenceCurrentlyActive}
presenceState={this.props.presenceState} /> presenceState={this.props.presenceState} />
@ -123,8 +123,7 @@ module.exports = React.createClass({
} }
else { else {
nameEl = ( nameEl = (
<div className="mx_EntityTile_name" dangerouslySetInnerHTML={nameHTML}> <EmojiText element="div" className="mx_EntityTile_name">{name}</EmojiText>
</div>
); );
} }

View file

@ -32,7 +32,7 @@ var Modal = require("../../../Modal");
var sdk = require('../../../index'); var sdk = require('../../../index');
var UserSettingsStore = require('../../../UserSettingsStore'); var UserSettingsStore = require('../../../UserSettingsStore');
var createRoom = require('../../../createRoom'); var createRoom = require('../../../createRoom');
import {emojifyText} from '../../../HtmlUtils'; import EmojiText from '../elements/EmojiText';
module.exports = React.createClass({ module.exports = React.createClass({
displayName: 'MemberInfo', displayName: 'MemberInfo',
@ -637,7 +637,7 @@ module.exports = React.createClass({
</div> </div>
} }
let memberNameHTML = emojifyText(this.props.member.name); const memberName = this.props.member.name;
var MemberAvatar = sdk.getComponent('avatars.MemberAvatar'); var MemberAvatar = sdk.getComponent('avatars.MemberAvatar');
var PowerSelector = sdk.getComponent('elements.PowerSelector'); var PowerSelector = sdk.getComponent('elements.PowerSelector');
@ -648,7 +648,7 @@ module.exports = React.createClass({
<MemberAvatar onClick={this.onMemberAvatarClick} member={this.props.member} width={48} height={48} /> <MemberAvatar onClick={this.onMemberAvatarClick} member={this.props.member} width={48} height={48} />
</div> </div>
<h2 dangerouslySetInnerHTML={memberNameHTML}></h2> <EmojiText element="h2">{memberNameHTML}</EmojiText>
<div className="mx_MemberInfo_profile"> <div className="mx_MemberInfo_profile">
<div className="mx_MemberInfo_profileField"> <div className="mx_MemberInfo_profileField">

View file

@ -24,7 +24,7 @@ var Modal = require("../../../Modal");
var linkify = require('linkifyjs'); var linkify = require('linkifyjs');
var linkifyElement = require('linkifyjs/element'); var linkifyElement = require('linkifyjs/element');
var linkifyMatrix = require('../../../linkify-matrix'); var linkifyMatrix = require('../../../linkify-matrix');
import {emojifyText} from '../../../HtmlUtils'; import EmojiText from '../elements/EmojiText';
linkifyMatrix(linkify); linkifyMatrix(linkify);
@ -212,13 +212,12 @@ module.exports = React.createClass({
roomName = this.props.room.name; roomName = this.props.room.name;
} }
let roomNameHTML = emojifyText(roomName);
name = name =
<div className="mx_RoomHeader_name" onClick={this.props.onSettingsClick}> <div className="mx_RoomHeader_name" onClick={this.props.onSettingsClick}>
<div className={ "mx_RoomHeader_nametext " + (settingsHint ? "mx_RoomHeader_settingsHint" : "") } title={ roomName } dangerouslySetInnerHTML={roomNameHTML}></div> <EmojiText element="div" className={ "mx_RoomHeader_nametext " + (settingsHint ? "mx_RoomHeader_settingsHint" : "") } title={ roomName }>{roomName}</EmojiText>
{ searchStatus } { searchStatus }
</div> </div>;
} }
if (can_set_room_topic) { if (can_set_room_topic) {

View file

@ -22,7 +22,7 @@ var dis = require("../../../dispatcher");
var MatrixClientPeg = require('../../../MatrixClientPeg'); var MatrixClientPeg = require('../../../MatrixClientPeg');
var sdk = require('../../../index'); var sdk = require('../../../index');
var ContextualMenu = require('../../structures/ContextualMenu'); var ContextualMenu = require('../../structures/ContextualMenu');
import {emojifyText} from '../../../HtmlUtils'; import EmojiText from '../elements/EmojiText';
module.exports = React.createClass({ module.exports = React.createClass({
displayName: 'RoomTile', displayName: 'RoomTile',
@ -196,13 +196,12 @@ module.exports = React.createClass({
'mx_RoomTile_badgeShown': this.props.highlight || (notificationCount > 0 && !this.state.areNotifsMuted) || this.state.badgeHover || this.state.menu, 'mx_RoomTile_badgeShown': this.props.highlight || (notificationCount > 0 && !this.state.areNotifsMuted) || this.state.badgeHover || this.state.menu,
}); });
let nameHTML = emojifyText(name);
if (this.props.selected) { if (this.props.selected) {
let nameSelected = <span dangerouslySetInnerHTML={nameHTML}></span>; let nameSelected = <EmojiText>{name}</EmojiText>;
label = <div title={ name } className={ nameClasses }>{ nameSelected }</div>; label = <div title={ name } className={ nameClasses }>{ nameSelected }</div>;
} else { } else {
label = <div title={ name } className={ nameClasses } dangerouslySetInnerHTML={nameHTML}></div>; label = <EmojiText element="div" title={ name } className={ nameClasses }>{name}</EmojiText>;
} }
} }
else if (this.state.hover) { else if (this.state.hover) {