Merge pull request #2596 from matrix-org/dbkr/emoji_sas

Change SAS to decimal / emoji
This commit is contained in:
David Baker 2019-02-08 16:46:43 +00:00 committed by GitHub
commit 2cd25e0077
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 224 additions and 18 deletions

View file

@ -14,9 +14,35 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
.mx_VerificationShowSas_sas {
.mx_VerificationShowSas_decimalSas {
text-align: center;
font-weight: bold;
padding-left: 3px;
padding-right: 3px;
}
.mx_VerificationShowSas_decimalSas span {
margin-left: 5px;
margin-right: 5px;
}
.mx_VerificationShowSas_emojiSas {
text-align: center;
}
.mx_VerificationShowSas_emojiSas_block {
display: inline-block;
margin-left: 15px;
margin-right: 15px;
text-align: center;
margin-bottom: 20px;
}
.mx_VerificationShowSas_emojiSas_emoji {
font-size: 48px;
}
.mx_VerificationShowSas_emojiSas_label {
text-align: center;
font-weight: bold;
}

View file

@ -68,8 +68,10 @@ export function containsEmoji(str) {
/* modified from https://github.com/Ranks/emojione/blob/master/lib/js/emojione.js
* because we want to include emoji shortnames in title text
*/
function unicodeToImage(str) {
let replaceWith; let unicode; let alt; let short; let fname;
function unicodeToImage(str, addAlt) {
if (addAlt === undefined) addAlt = true;
let replaceWith; let unicode; let short; let fname;
const mappedUnicode = emojione.mapUnicodeToShort();
str = str.replace(emojione.regUnicode, function(unicodeChar) {
@ -84,10 +86,14 @@ function unicodeToImage(str) {
fname = emojione.emojioneList[short].fname;
// 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];
if (addAlt) {
const alt = (emojione.unicodeAlt) ? emojione.convert(unicode.toUpperCase()) : mappedUnicode[unicode];
replaceWith = `<img class="mx_emojione" title="${title}" alt="${alt}" src="${emojione.imagePathSVG}${fname}.svg${emojione.cacheBustParam}"/>`;
} else {
replaceWith = `<img class="mx_emojione" src="${emojione.imagePathSVG}${fname}.svg${emojione.cacheBustParam}"/>`;
}
return replaceWith;
}
});
@ -508,9 +514,9 @@ export function bodyToHtml(content, highlights, opts={}) {
<span className={className} dir="auto">{ strippedBody }</span>;
}
export function emojifyText(text) {
export function emojifyText(text, addAlt) {
return {
__html: unicodeToImage(escape(text)),
__html: unicodeToImage(escape(text), addAlt),
};
}

View file

@ -20,12 +20,12 @@ import PropTypes from 'prop-types';
import {emojifyText, containsEmoji} from '../../../HtmlUtils';
export default function EmojiText(props) {
const {element, children, ...restProps} = props;
const {element, children, addAlt, ...restProps} = props;
// fast path: simple regex to detect strings that don't contain
// emoji and just return them
if (containsEmoji(children)) {
restProps.dangerouslySetInnerHTML = emojifyText(children);
restProps.dangerouslySetInnerHTML = emojifyText(children, addAlt);
return React.createElement(element, restProps);
} else {
return React.createElement(element, restProps, children);
@ -39,4 +39,5 @@ EmojiText.propTypes = {
EmojiText.defaultProps = {
element: 'span',
addAlt: true,
};

View file

@ -17,13 +17,17 @@ limitations under the License.
import React from 'react';
import PropTypes from 'prop-types';
import sdk from '../../../index';
import { _t } from '../../../languageHandler';
import { _t, _td } from '../../../languageHandler';
function capFirst(s) {
return s.charAt(0).toUpperCase() + s.slice(1);
}
export default class VerificationShowSas extends React.Component {
static propTypes = {
onDone: PropTypes.func.isRequired,
onCancel: PropTypes.func.isRequired,
sas: PropTypes.string.isRequired,
sas: PropTypes.object.isRequired,
}
constructor() {
@ -32,17 +36,55 @@ export default class VerificationShowSas extends React.Component {
render() {
const DialogButtons = sdk.getComponent('views.elements.DialogButtons');
return <div className="mx_VerificationShowSas">
<p>{_t(
const EmojiText = sdk.getComponent('views.elements.EmojiText');
let sasDisplay;
let sasCaption;
if (this.props.sas.emoji) {
const emojiBlocks = this.props.sas.emoji.map(
(emoji, i) => <div className="mx_VerificationShowSas_emojiSas_block" key={i}>
<div className="mx_VerificationShowSas_emojiSas_emoji">
<EmojiText addAlt={false}>{emoji[0]}</EmojiText>
</div>
<div className="mx_VerificationShowSas_emojiSas_label">
{_t(capFirst(emoji[1]))}
</div>
</div>,
);
sasDisplay = <div className="mx_VerificationShowSas_emojiSas">
{emojiBlocks}
</div>;
sasCaption = _t(
"Verify this user by confirming the following emoji appear on their screen.",
);
} else if (this.props.sas.decimal) {
const numberBlocks = this.props.sas.decimal.map((num, i) => <span key={i}>
{num}
</span>);
sasDisplay = <div className="mx_VerificationShowSas_decimalSas">
{numberBlocks}
</div>;
sasCaption = _t(
"Verify this user by confirming the following number appears on their screen.",
)}</p>
);
} else {
return <div>
{_t("Unable to find a supported verification method.")}
<DialogButtons
primaryButton={_t('Cancel')}
hasCancel={false}
onPrimaryButtonClick={this.props.onCancel}
/>
</div>;
}
return <div className="mx_VerificationShowSas">
<p>{sasCaption}</p>
<p>{_t(
"For maximum security, we recommend you do this in person or use another " +
"trusted means of communication.",
)}</p>
<div className="mx_VerificationShowSas_sas">
{this.props.sas}
</div>
{sasDisplay}
<DialogButtons onPrimaryButtonClick={this.props.onDone}
primaryButton={_t("Continue")}
hasCancel={true}
@ -51,3 +93,69 @@ export default class VerificationShowSas extends React.Component {
</div>;
}
}
// List of Emoji strings from the js-sdk, for i18n
_td("Dog");
_td("Cat");
_td("Lion");
_td("Horse");
_td("Unicorn");
_td("Pig");
_td("Elephant");
_td("Rabbit");
_td("Panda");
_td("Rooster");
_td("Penguin");
_td("Turtle");
_td("Fish");
_td("Octopus");
_td("Butterfly");
_td("Flower");
_td("Tree");
_td("Cactus");
_td("Mushroom");
_td("Globe");
_td("Moon");
_td("Cloud");
_td("Fire");
_td("Banana");
_td("Apple");
_td("Strawberry");
_td("Corn");
_td("Pizza");
_td("Cake");
_td("Heart");
_td("Smiley");
_td("Robot");
_td("Hat");
_td("Glasses");
_td("Spanner");
_td("Santa");
_td("Thumbs up");
_td("Umbrella");
_td("Hourglass");
_td("Clock");
_td("Gift");
_td("Light bulb");
_td("Book");
_td("Pencil");
_td("Paperclip");
_td("Scisors");
_td("Padlock");
_td("Key");
_td("Hammer");
_td("Telephone");
_td("Flag");
_td("Train");
_td("Bicycle");
_td("Aeroplane");
_td("Rocket");
_td("Trophy");
_td("Ball");
_td("Guitar");
_td("Trumpet");
_td("Bell");
_td("Anchor");
_td("Headphones");
_td("Folder");
_td("Pin");

View file

@ -333,10 +333,75 @@
"You've successfully verified this user.": "You've successfully verified this user.",
"Secure messages with this user are end-to-end encrypted and not able to be read by third parties.": "Secure messages with this user are end-to-end encrypted and not able to be read by third parties.",
"Got It": "Got It",
"Verify this user by confirming the following emoji appear on their screen.": "Verify this user by confirming the following emoji appear on their screen.",
"Verify this user by confirming the following number appears on their screen.": "Verify this user by confirming the following number appears on their screen.",
"Unable to find a supported verification method.": "Unable to find a supported verification method.",
"For maximum security, we recommend you do this in person or use another trusted means of communication.": "For maximum security, we recommend you do this in person or use another trusted means of communication.",
"To continue, click on each pair to confirm it's correct.": "To continue, click on each pair to confirm it's correct.",
"Continue": "Continue",
"Dog": "Dog",
"Cat": "Cat",
"Lion": "Lion",
"Horse": "Horse",
"Unicorn": "Unicorn",
"Pig": "Pig",
"Elephant": "Elephant",
"Rabbit": "Rabbit",
"Panda": "Panda",
"Rooster": "Rooster",
"Penguin": "Penguin",
"Turtle": "Turtle",
"Fish": "Fish",
"Octopus": "Octopus",
"Butterfly": "Butterfly",
"Flower": "Flower",
"Tree": "Tree",
"Cactus": "Cactus",
"Mushroom": "Mushroom",
"Globe": "Globe",
"Moon": "Moon",
"Cloud": "Cloud",
"Fire": "Fire",
"Banana": "Banana",
"Apple": "Apple",
"Strawberry": "Strawberry",
"Corn": "Corn",
"Pizza": "Pizza",
"Cake": "Cake",
"Heart": "Heart",
"Smiley": "Smiley",
"Robot": "Robot",
"Hat": "Hat",
"Glasses": "Glasses",
"Wrench": "Wrench",
"Santa": "Santa",
"Thumbs up": "Thumbs up",
"Umbrella": "Umbrella",
"Hourglass": "Hourglass",
"Clock": "Clock",
"Gift": "Gift",
"Light bulb": "Light bulb",
"Book": "Book",
"Pencil": "Pencil",
"Paperclip": "Paperclip",
"Scisors": "Scisors",
"Padlock": "Padlock",
"Key": "Key",
"Hammer": "Hammer",
"Telephone": "Telephone",
"Flag": "Flag",
"Train": "Train",
"Bicycle": "Bicycle",
"Aeroplane": "Aeroplane",
"Rocket": "Rocket",
"Trophy": "Trophy",
"Ball": "Ball",
"Guitar": "Guitar",
"Trumpet": "Trumpet",
"Bell": "Bell",
"Anchor": "Anchor",
"Headphones": "Headphones",
"Folder": "Folder",
"Pin": "Pin",
"Failed to upload profile picture!": "Failed to upload profile picture!",
"Upload new:": "Upload new:",
"No display name": "No display name",