diff --git a/res/css/views/verification/_VerificationShowSas.scss b/res/css/views/verification/_VerificationShowSas.scss index 32ccf6b0bb..a0da7e2539 100644 --- a/res/css/views/verification/_VerificationShowSas.scss +++ b/res/css/views/verification/_VerificationShowSas.scss @@ -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; +} diff --git a/src/HtmlUtils.js b/src/HtmlUtils.js index 371804725d..2e08c059eb 100644 --- a/src/HtmlUtils.js +++ b/src/HtmlUtils.js @@ -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]; - replaceWith = `${alt}`; + if (addAlt) { + const alt = (emojione.unicodeAlt) ? emojione.convert(unicode.toUpperCase()) : mappedUnicode[unicode]; + replaceWith = `${alt}`; + } else { + replaceWith = ``; + } return replaceWith; } }); @@ -508,9 +514,9 @@ export function bodyToHtml(content, highlights, opts={}) { { strippedBody }; } -export function emojifyText(text) { +export function emojifyText(text, addAlt) { return { - __html: unicodeToImage(escape(text)), + __html: unicodeToImage(escape(text), addAlt), }; } diff --git a/src/components/views/elements/EmojiText.js b/src/components/views/elements/EmojiText.js index 9fb650b2c3..b7f3e45321 100644 --- a/src/components/views/elements/EmojiText.js +++ b/src/components/views/elements/EmojiText.js @@ -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, }; diff --git a/src/components/views/verification/VerificationShowSas.js b/src/components/views/verification/VerificationShowSas.js index 0224571d9e..bca68e92d3 100644 --- a/src/components/views/verification/VerificationShowSas.js +++ b/src/components/views/verification/VerificationShowSas.js @@ -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
-

{_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) =>

+
+ {emoji[0]} +
+
+ {_t(capFirst(emoji[1]))} +
+
, + ); + sasDisplay =
+ {emojiBlocks} +
; + 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) => + {num} + ); + sasDisplay =
+ {numberBlocks} +
; + sasCaption = _t( "Verify this user by confirming the following number appears on their screen.", - )}

+ ); + } else { + return
+ {_t("Unable to find a supported verification method.")} + +
; + } + + return
+

{sasCaption}

{_t( "For maximum security, we recommend you do this in person or use another " + "trusted means of communication.", )}

-
- {this.props.sas} -
+ {sasDisplay} ; } } + +// 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"); diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 621a00066a..c2f19cbdd2 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -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",