Handling Change of Password of SUSI.AI Account

In this blog, we will talk about a very special case, where the user changes his password to his current one only, in other words, the user enters the same password in both current password and new password. This case is now being handled by SUSI.AI server.

Considering the example of SUSI.AI Web Chat, we have following dialog when the user tries to change his/her password:

Here the user can add his/her current password and new password. When the new password meets the minimum conditions (minimum 6 characters), then the user can press CHANGE button.

We make ajax call to the server with the following endpoint:

BASE_URL+'/aaa/changepassword.json?'+
            'changepassword=' + email +
            '&password=' + this.state.passwordValue +
            '&newpassword=' + this.state.newPasswordValue +
            '&access_token='+cookies.get('loggedIn');

Here we have 4 parameters:

  • changepassword: This takes the email of the current user
  • password: This is the password of the current user, which is saved in the state named “passwordValue”
  • newpassword: This is the new password which the user enters
  • access_token: These are access tokens which are fetched from cookies. These are defined on login and are deleted on logout.

This is now handled on the server by a file named PasswordChangeService.java. Here we have to check whether the newpassword and password matches or not.

In this file, we have a function named serviceImpl with return type ServiceResponse and takes in an argument: Query post (Query is the return type). The query is not the only argument, Please read from the file from resources mentioned below for all the argument. To handle our case we just need to work with the post.

We extract the password, newpassword and email as follows:

String useremail = post.get("changepassword", null);
String password = post.get("password", null);
String newpassword = post.get("newpassword",null);

So to simply handle the case where password and newpassword matches, we define an if block in java and compare these two parameters as follows:

if(password.equals(newpassword)){
            result.put("message", "Your current password and new password matches");
            result.put("accepted", false);
            return new ServiceResponse(result);
}

Here we put the message as “Your current password and new password matches” and make the accepted flag of result JSON as false. After this, we return the ServiceResponse.

Now in our web chat client, the ajax call is as follows:

$.ajax({
                url: changePasswordEndPoint,
                dataType: 'jsonp',
                crossDomain: true,
                timeout: 3000,
                async: false,
                statusCode: {
                    422: function() {
                      let msg = 'Invalid Credentials. Please check your Email or Password.';
                      let state = this.state;
                      state.msg = msg;
                      this.setState(state);
                    }
                },
                success: function (response) {
                    let msg = response.message+'\n Please login again.';
                    let state = this.state;
                    state.msg = msg;
                    state.success = true;
                    state.msgOpen = true;
                    this.setState(state);
                }.bind(this),
                error: function(jqXHR, textStatus, errorThrown) {
                    let msg = 'Failed. Try Again';
                    if (status === 'timeout') {
                      msg = 'Please check your internet connection';
                    }
                    let state = this.state;
                    state.msg = msg;
                    state.msgOpen = true;
                    this.setState(state);
                }.bind(this)
            });

In our success method of ajax call,  we receive the JSON response in a variable named response and store this in the state in variable msg and set the state of success equal to true. We then use the state and message to handle accordingly.

Our JSON object when both password and new password are same:

So this is how clients can handle accordingly to the message received from the server instead of doing this on their own end.

Resources

Continue ReadingHandling Change of Password of SUSI.AI Account

Change Background of Message Section in SUSI.AI Web Chat

In SUSI.AI Web Chat we pay special attentions to the UI to make it easy to use and attract more users. Many chat apps offer users customization such as changing the colors and background. As this is very popular we decided to give the option to customize the background of message section of SUSI.AI web chat. The UI of the message section had a default gray background which could not be modified by the user. The goal was now to allow the user to customize the look of his or her own client starting with the background of the message section.

We added the settings to change the background image to Custom theme menu which occurs only when the user is logged in.The option looks like this:

User can add URL of any image of his/her choice and it will be set as the background of message section.
Now let’s take a look at the implementation of this option. We added messageBackgroundImage to our state of message section and initialised it to ‘ ’ (empty string). The TextField component looks like this:

<TextField
   name="messageImg"
   style={{display:component.component==='body'?'block':'none'}}
   ref={(input) => { this.backImage = input }}
   onChange={
     (e,value)=>
     this.handleChangeMessageBackground(value) }
    value={this.state.messageBackgroundImage}
    floatingLabelText="Message Background Image URL"
 />

OnChange method handles the input URL and this calls the function handleChangeMessageBackground. This function is having following implementation:

handleChangeMessageBackground(backImage){
    this.setState({messageBackgroundImage:backImage});
  }

It sets the messageBackgroundImage equal to the URL entered by the user. Now to change the background of message section we made a custom React style object messageBackgroundStyles:

const messageBackgroundStyles = {
        backgroundImage: `url(${this.state.messageBackgroundImage})`,
        backgroundRepeat: 'no-repeat',
        backgroundSize: '100% 100%'
    }

In the above object,

backgroundImage: sets the message section background to the image on URL entered by user

backgroundImage: Does not allows to the image to be repeated.

backgroundSize: Fills the entire message section with the background image.

Now this style was added to the component of message section :

<div className='message-section'>
     <ul
      className='message-list'
      ref={(c) => { this.messageList = c; }}
      style={messageBackgroundStyles}> // Styles added
       // Some relevant code    
      </ul>
</div>

Now we have following UI, where the user can modify the message section background with image of his or her own choice. User can add any image as background of message section by adding appropriate URL. The image will cover the entire message section without repeating itself.

Background Image source:link

This gives our user custom look according to his/her own choice.

Resources

Testing Link

http://chat.susi.ai

Background Image source of featured image : link

Continue ReadingChange Background of Message Section in SUSI.AI Web Chat

Teaching Susi

In this blog post, I’ll explain how you can add a skill to SUSI.

Skills to be added in this tutorial:

  1. Ask SUSI for conversion of decimal into Binary .
  2. Ask SUSI to tell a quote.
  3. Skill development in SUSI is very interesting and easy. A comprehensive guide for skill development can be found here.

We have a Susi Skill development environment based on an Etherpad. Are you unaware what an Etherpad is? It is a blank web page where you can just put in your text and everyone can collaborate.

Here is a screenshot of what etherpad looks like:

  • open http://dream.susi.ai
  • name a dream (just pick a name for your tests in lower case letters)
  • the etherpad is filled with a welcome message, just delete the content completely

Ask SUSI for conversion of decimal into Binary

“*” here represents any decimal number number.Suppose we enter a decimal number and want susi to return it’s binary equivalent. So to make our skill, first of all we should form a general query.

Query: Convert * into binary or * in binary

After defining our query we want susi to reply with relevant answer.

For taking out the conversion from decimal to binary we can use JavaScript.

We define Javascript syntax in etherpad as follows :

!javascript:Binary for $1$ = $!$
(+$1$).toString(2);
eol

Explanation :

!javascript” allows us to print like javascript console. We can add JavaScript code by using this and do mathematical calculations to convert our decimal into binary.

“Binary for $1$ = $!$”  represents output format where $1$ stores the value in “*” in query given by user to susi. $!$ will print the result of javascript code below.

“(+$1$).toString(2);” This is a single line javascript code while converts value in “$1$” to binary, It’s output is reflected in “$!$”

“eol” represents end of line, which signifies our code for skill is finished.

In etherpad our skill would look like :

“#” – used for commenting out lines in skill

#The following code returns binary equivalent of a decimal number given by user

convert * into binary || binary of *
!javascript:Binary for $1$ = $!$
(+$1$).toString(2);
eol

Screenshot:

Ask SUSI to tell a quote

We can use external API’s for providing answer to user’s query. The external API used for telling the quote is Quotes Rest API created by They Said So. It offers a very good quotes platform and also the quotes are not repeated when several requests are made continuously.

We need a query for our skill.

Query: Tell me a quote.

Now let’s say that we use this JSON response for fetching quote data.

Our JSON object looks like:

{
 success: {
  total: 1
 },
contents: {
quotes: [
{
quote: "Let our advance worrying become advance thinking and planning.",
length: "62",
author: "Winston Churchill",
tags: [
"anxiety",
"inspire",
"planning",
"time-management"
],
category: "inspire",
date: "2017-05-31",
permalink: "https://theysaidso.com/quote/o3aMOSUwOPqUnJv9YyfYHweF/winston-churchill-let-our-advance-worrying-become-advance-thinking-and-planning",
title: "Inspiring Quote of the day",
background: "https://theysaidso.com/img/bgs/man_on_the_mountain.jpg",
id: "o3aMOSUwOPqUnJv9YyfYHweF"
}
],
copyright: "2017-19 theysaidso.com"
}
}

Now we are interested in getting value corresponding to  quotes key, which takes the path:  “path”:”$.contents.quotes“.

We make output query as follows:

!console:$quote$
     {
        "url" : "http://quotes.rest/qod.json",
        "path":"$.contents.quotes"
      }
eol

Explanation :

“!console” prints the output and this is returned by SUSI.AI.

$quote$” is the key whose value will be printed from parsed JSON.It contains our quote and this is a random quote. This is the string which will be responded by SUSI.AI

“url” generated JSON response from external API.

“path” is parsing path of JSON object which we follow for getting correct response.

Our skill will look like:

tell me a quote
!console:$quote$
     {
        "url" : "http://quotes.rest/qod.json",
        "path":"$.contents.quotes"
      }
eol

Screenshot :

Resources:

Continue ReadingTeaching Susi

Implementation of Responsive SUSI Web Chat Search Bar

When we were building the first phase of the SUSI Web Chat Application we didn’t consider about  the responsiveness as a main goal. The main thing we needed was a working application. This changed at a later stage. In this post I’m going to emphasize how we implemented the responsive design and problems we met while we were developing the design.

When we were moving to Material-UI from static HTML CSS we were able to make most of the parts responsive. As an example App-bar of the application. We added App-bar like as follows: We made a separate component for App-bar and it includes the “searchfield” element. Material-UI app bar handles the responsiveness for some extent. We have to handle responsiveness of other sub-parts of the app bar manually.

In “TopBar.react.js” I returned marterial-ui <Toolbar> element like this.

<Toolbar>
                <ToolbarGroup >
                </ToolbarGroup>
                <ToolbarGroup lastChild={true}> //inside of this we have to include other components of the top bar inside this element

                </ToolbarGroup>
             </Toolbar>

We have to add the search button inside the element.
In this we added search component.

This field has the ability to expand and collapse like this.

It looks good. But it appears on mobile screen in a different way. This is how it appears on mobile devices.

So we wanted to hide the SUSI logo on small sized screens. For that we wrote medial queries like this.

@media only screen and (max-width: 860px){
 .app-bar-search{
   background-image: none;
 }
 .search{
   width: 100px !important;
 }
}

Even in smaller screens it appears like this.

To avoid that we minimized the width of the search bar in different screen sizes using media queries .

@media only screen and (max-width: 480px){
 .search{
   width: 100px !important;
 }
}
@media only screen and (max-width: 360px){
 .search{
   width: 65px !important;
 }
}

But in even smaller screens it still appears in the same way. We can’t show the search bar on small screens because the screen size is not enough to show the search bar.
So we wrote another media query to hide all the elements of search component in small screens except close button. Because when we collapse the screen on search mode it hides all the search components and messagecomposer. To take it back to the chat mode we have to enable the close button on smaller screens.

@media only screen and (max-width: 300px){
 .displayNone{
   display: none !important;
 }
 .displayCloseNone{
     position: relative;
     top:6px  !important;
 }
}

We have to define these two classes in “SearchField.react.js” file.

<IconButton className='displayNone'
                   <SearchIcon />
               </IconButton>
               <TextField  name='search'
                   className='search displayNone'
                   placeholder="Search..."/>
               <IconButton className='displayNone'>
                   <UpIcon />
               </IconButton>
               <IconButton className='displayNone'>
                   <DownIcon />
               </IconButton>
               <IconButton className='displayCloseNone'>
                   <ExitIcon />
               </IconButton>

Since we have “Codacy” integrated into our Github Repository we have to change Codacy rules because we used “!important” in media queries to override inline style which comes from Material-UI.
To change codacy rules we can simply login to the codacy and select the “code pattern ” button from the column left side.

It shows the list of rules that Codacy checks. And you can see the “!important” rule under CSSlint category like this.

Just uncheck it. Then codacy will not check your source code for “!important” attributes.

Resources
Configuring Codacy: Use Your Own Conventions: https://blog.codacy.com/configuring-codacy-use-your-own-conventions-9272bee5dcdb
Media queries: https://www.w3schools.com/css/css_rwd_mediaqueries.asp

Continue ReadingImplementation of Responsive SUSI Web Chat Search Bar

Implementing Wallpapers in React JS SUSI Web Chat Application

The different SUSI AI clients need to match in their feature set. One feature that was missing in the React JS SUSI Web Chat application was the ability for users to change the application wallpaper or background. This is how we implemented it on SUSI Web Chat.
Firstly we added a text field after the circle picker that change the color of the Application body. Because there should be a place to add the wallpaper image URL. Added that text field like this.

   const components = componentsList.map((component) => {
       return

key={component.id} className=‘circleChoose’>

Change color of {component.name}:

 

         color={component} width={'100%'}
         onChangeComplete={ this.handleChangeComplete.bind(this,
         component.component) }
         onChange={this.handleColorChange.bind(this,component.id)}>
       

CirclePicker shows the circular color picker to choose the colors for each component of the application.

        
         name="backgroundImg"
         style={{display:component.component==='body'?'block':'none'}}
         onChange={
           (e,value)=>
           this.handleChangeBackgroundImage(value) }
         value={this.state.bodyBackgroundImage}
          floatingLabelText="Body Background Image URL" />
       

})

In ’TextField’ I have checked below condition whether to display or not to display the text field after the ‘body’ color picker.

style={{display:component.component==='body'?'block':'none'}}

To apply changes as soon as the user enters the image url, we refer the value of the ‘TextField’ and pass it into the ‘handleChangeBackgroundImage()’ function as ‘value’ on change like this.

         onChange={
           (e,value)=>
           this.handleChangeBackgroundImage(value) }

In ‘‘handleChangeBackgroundImage()’ function we change the state of the application and background of the application like this.

  handleChangeBackgroundImage(backImage){
   document.body.style.setProperty('background-image', 'url('+ backImage+')');
   document.body.style.setProperty('background-repeat', 'no-repeat');
   document.body.style.setProperty('background-size', 'cover');
   this.setState({bodyBackgroundImage:backImage});
 }

In here ‘document.body.style.setProperty’ we change the style of the application’s ‘’ tag. This is how wallpapers are changing on SUSI Web Chat Application.

Resources:

React Refs: https://facebook.github.io/react/docs/refs-and-the-dom.html

Refer Value from text field: https://stackoverflow.com/questions/43960183/material-ui-component-reference-does-not-work

Continue ReadingImplementing Wallpapers in React JS SUSI Web Chat Application

Communicate between Child and Parent Components in React JS of SUSI Web Chat

When we were developing SUSI AI web chat  some components became huge. So the team wanted to break some components into parts. Since the Login dialog-box is used in several  places we decided to make a separate component for Login Dialog-box. In this post I am discussing how we implemented the feature as a separate component and how we have changed the state of the parent component of the child component.

Login Dialog-box contains all the things of the login dialog-box component.

Child-component (Login Dialog-box component) is here:

This method executes the ‘switchDialog’ function of the parent component.

export default class LoginDialog extends React.Component {

   handleClose = () => {
      this.props.switchDialog(false);
   };

   render() {
       this.state = { open: this.props.open }
       const actions = <RaisedButton
           label="Cancel"
           backgroundColor={
               UserPreferencesStore.getTheme() === 'light' ? '#607D8B' : '#19314B'}
           labelColor="#fff"
           width='200px'
           keyboardFocused={true}
           onTouchTap={this.handleClose}
       />;

       return (
           <Dialog
               actions={actions}
               modal={false}
               open={this.props.open}
               autoScrollBodyContent={true}
               bodyStyle={bodyStyle}
               contentStyle={{ width: '35%', minWidth: '300px' }}
               onRequestClose={this.handleClose}>
               <Login {...this.props} />
           </Dialog>
       );
   }

};

In this part we validate property types that has passed from the parent component.

LoginDialog.propTypes = {
   open: PropTypes.bool,
   switchDialog: PropTypes.func
};

In render() method I have returned the element.
To open and close dialog we have to communicate with parent component. We can send an instruction as an attribute of the element and we can refer it inside the element as “props”. This is how I have sent an instruction to the child element.
Parent-component:
‘handleOpen’ function opens the dialog when user hit on the login button.

   handleOpen = () => {
       this.setState({ open: true });
   };

‘switchDialog’ function is using for change the state of parent component from child Component (Login Dialog-box component).

   switchDialog=(dialogState)=>{
       this.setState({open:dialogState});
   };

   render() {

       const styles = {
           'margin': '60px auto',
           'width': '100%',
           'padding': '20px',
           'textAlign': 'center'
       }

       return (
           <div className="signUpForm">
               <Paper zDepth={1} style={styles}>
                   <h1>Sign Up with SUSI</h1>
                   <form onSubmit={this.handleSubmit}>
                       <div>
                           <h4>If you have an Account Please Login</h4>
                           <RaisedButton
                               onTouchTap={this.handleOpen}
                               label='Login'
                               backgroundColor={
                                   UserPreferencesStore.getTheme()==='light'
                                   ? '#607D8B' : '#19314B'}
                               labelColor="#fff" />
                       </div>
                   </form>
               </Paper>

               <LoginDialog {...this.props} open={this.state.open} switchDialog={this.switchDialog} />
           </div>
       );
   };

To open and close the dialog-box we have to send the state of the parent component to child component. To close the dialog-box we have to update the parent component’s state from child component.

To change the parent component’s state we have used this in element.

switchDialog={this.switchDialog}

To send the state to the child component we used this.

open={this.state.open}

To send other properties to the element we used this.

{...this.props}

After closing the dialog-box it calls this method and it updates the state of the parent component.

handleClose = () => {
      this.props.switchDialog(false);
};

This is how we can communicate between child and parent components using react.

Resources:

Component Communication: http://andrewhfarmer.com/component-communication/
Material UI Dialogs: http://www.material-ui.com/#/components/dialog

Continue ReadingCommunicate between Child and Parent Components in React JS of SUSI Web Chat

Detecting password strength in SUSI.AI Web Chat SignUp

Every SignUp page contains a field to enter a password, but it should not be just a dumb component that takes input and saves it on server. A password field on a SignUp page should tell how weak or strong the password is. We decided to implement this in our SUSI.AI Web Chat SignUp Page.

Our SignUp page look like this:

After entering a valid email, user needs to enter the password. It shows that minimum 6 character are required:

We have the following div for our Password Field :

<PasswordField
  name="password"
  style={fieldStyle}
  value={this.state.passwordValue}
  onChange={this.handleChange}
  errorText={this.passwordErrorMessage}
  floatingLabelText="Password" />

In our OnChange Method we need to check the strength of password once the six character limit is crossed and display the strength visually.

We have used Dropbox’s zxcvbn library for the purpose of getting the strength of password.

Major reasons of choosing this library are :

  • Flexibility : It allows different passwords as long as certain level of complexity is matched.
  • Usability : It is very easy use and gives instant feedback. This helps user towards less guessable passwords.

For installing this library :

 npm -S install zxcvbn

For importing this:

import zxcvbn from 'zxcvbn';

Now in our OnChange Method:

handleChange = (event) => {
        let email;
        let password;
        let confirmPassword;
        let serverUrl;
        let state = this.state
      // Checking if event is password
        if (event.target.name === 'password') {
            password = event.target.value;
            let validPassword = password.length >= 6;
            state.passwordValue=password;
            state.passwordError = !(password && validPassword);
            if(validPassword) {
              //getting strength of password from zxcvbn
              let result = zxcvbn(password);
              state.passwordScore=result.score;
              let strength = [
                'Worst',
                'Bad',
                'Weak',
                'Good',
                'Strong'
              ];
              state.passwordStrength=strength[result.score];
            }
            else {
              state.passwordStrength='';
              state.passwordScore=-1;
            }
        }

Explanation:

In the above method result variable gets the strength of password and result.score gives us the score of password in terms of an integer and according to which we have made an array to get result in remarks corresponding to score. We have remarks like Good, Strong, etc.

Initially we have set the score to -1 to know that user has not entered the password yet. Once user has entered password the score changes.
Then we made a wrapper class to help css format the color of remark and display a meter (determining password strength) with corresponding length and color. We have used template strings to make our wrapper class. This helps us in having different names of wrapper class according to the score of the password.

// using Template Strings(look at resources for more info)
const PasswordClass=[`is-strength-${this.state.passwordScore}`];

Then we wrapped our Password field in div with className = “PasswordClass”.

<div className={PasswordClass.join(' ')}>
        <PasswordField
            name="password"
            style={fieldStyle}
            value={this.state.passwordValue}
            onChange={this.handleChange}
            errorText={this.passwordErrorMessage}
            floatingLabelText="Password" />
            <div className="ReactPasswordStrength-strength-bar" />
<div>

All that was left to was add css code corresponding to every score. For example for score=3, the following css was made:

.is-strength-3 { color: #57B8FF; }

.ReactPasswordStrength-strength-bar {
  box-sizing: border-box;
  height: 2px;
  position: relative; top: 1px; right: 1px;
  transition: width 300ms ease-out;
}

.is-strength--1 .ReactPasswordStrength-strength-bar {
  background: #D1462F;
  display: none;
}
// if strength = -1 then setting display of block equals to none
.is-strength--1 .ReactPasswordStrength-strength-bar {
  background: #D1462F;
  display: none;
}

.is-strength-3 .ReactPasswordStrength-strength-bar {
  background: #57B8FF; //Changing color according to password’s strength
  width: 192px; //Changing width according to password’s strength
  display: block;
}

After successfully implementing all these features, We had following SignUP page:

Resources:

1)Dropbox’s library(ZXVBN): https://github.com/dropbox/zxcvbn

2)Template Strings(Used here for making wrapping class of Password Field): https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Template_literals

Test Link:

This can be tested here.

Continue ReadingDetecting password strength in SUSI.AI Web Chat SignUp

Adding Emoji Support in SUSI Web Chat

SUSI.AI web chat sometimes, renders responses which contains emojis. We cannot rely on browser’s capability to render these emojis. The Problem is, that the default support for emojis of browsers does not offer a great variety of emojis to be rendered. The solution we implemented in the SUSI.AI web chat is to make use of a npm package to support our need for displaying emojis.

There were many options to choose from. For example :

Comparison between emoji packages :

Property Twemoji React-easy-emoji React-twemoji React-emojione
Built by Twitter Appfigures ZxMYS Pladaria
Usage Can be used as an object with function parse: twemoji.parse() Can be used as function: emoji() It is a simple wrapper for Twemoji.Can be used as component: <Twemoji> Can be used as function: emojify() or component: <Emojify>
Conversion compatibility Provides standard Unicode emoji support across all platforms Parse only basic emojis.Doesn’t parse emoji names like 🙂 and emoticons like 🙂 Convert emoji characters to Twemoji images Converts shortnames, unicode and ASCII smileys into renderable emojis
Dependencies None loot-web-kit lodash, prop-types, twemoji None

After detailed analysis of the above mentioned packages, we decided to go with React-emojione.

The major reasons are :

  • It is very easy to use.
  • It has no dependencies.
  • It can convert shortnames, unicode and ASCII symbols properly.
  • It can be used as both function and component, which diversifies its usage.

Installation:

npm install -S react-emojione

Basic usage (as function)

import {emojify} from 'react-emojione';
 
ReactDOM.render(
    <div>
        {emojify(':p')}
    </div>,
    document.body
);

Basic usage (as component)

import Emojify from 'react-emojione';
 
ReactDOM.render(
    <Emojify>
        <span>:p</span>
    </Emojify>,
    document.body
);

Some notes about the <Emojify> component:

  • If it has a single child, it won’t be wrapped
  • Otherwise it will be wrapped with a <span>

Difference between component and function?

Functional Stateless Components are just a ‘dumb’ function that takes props as an input. They do not have any state or methods. Just (props) => { return <span>content</span>; }

Class components can have state, variables, methods etc.

Now we needed our react app to render emojis. Our component named MessageListItem.react renders all the text and images of response.

There is a function called imageParse in this component. We use this function to parse our emojis.

Screenshot of SUSI Web Chat

Emoji’s like (:p) are now rendered properly

The implementation is as follows :

function imageParse(stringWithLinks){
  let replacePattern = new RegExp([
                      '((?:https?:\\/\\/)(?:[a-zA-Z]{1}',
                      '(?:[\\w-]+\\.)+(?:[\\w]{2,5}))',
                      '(?::[\\d]{1,5})?\\/(?:[^\\s/]+\\/)',
                      '*(?:[^\\s]+\\.(?:jpe?g|gif|png))',
                      '(?:\\?\\w+=\\w+(?:&\\w+=\\w+)*)?)'
                      ].join(''),'gim');
  let splits = stringWithLinks.split(replacePattern);
  let result = [];
  splits.forEach((item,key)=>{
    let checkmatch = item.match(replacePattern);
    if(checkmatch){
      result.push(
        <img key={key} src={checkmatch}
            style={{width:'95%',height:'auto'}} alt=''/>)
    }
    else{
      result.push(<Emojify  key={key}>{item}</Emojify>);
    }
  });
  return result;
}

Here we put {item} inside <Emojify> tag to render all the emoji’s present inside {item}.

This parses all emojis regardless of browser support. This package fulfills all our needs in this case.

Resources:

react-emojione package: https://www.npmjs.com/package/react-emojione

Testing link: SUSI.AI (Web Chat): http://chat.susi.ai/

Continue ReadingAdding Emoji Support in SUSI Web Chat

Adding Snackbar to undo recent change in theme of SUSI.AI Web Chat

SUSI.AI Web Chat has two primary themes: Light and Dark. The user can switch between these two from settings, but what if the user does not prefer the theme change. He/She has to repeat the entire process of Going to Settings -> Selecting another theme -> saving it. To enable the user to instantly change the theme, we decided to add snackbar on theme change.

What is Snackbar ?

Snackbar contains info regarding the operation just performed and it displays them in a visual format. Snackbar can also have a button like “Undo” to revert the recent operation just made.

It appears at the bottom of screen by default. A simple snackbar looks like this:

Now we needed this to pop-up, whenever the theme is changed. When a user changes theme we run a function named “implementSettings” which checks what the theme is changed to.

The method is:

implementSettings = (values) => {
    this.setState({showSettings: false});
    if(values.theme!==this.state.currTheme){
      this.setState({SnackbarOpen: true});
    }
    this.changeTheme(values.theme);
    this.changeEnterAsSend(values.enterAsSend);
    setTimeout(() => {
       this.setState({
           SnackbarOpen: false
       });
   }, 2500);
  }

The argument values is an object that contains all the change that user has made in settings. Here values.theme contains the value of theme user selected from settings. We first check if the theme is same as the current one if so, we do nothing. If the theme is different from current, then we update the theme by calling this.changeTheme(values.theme) and also initiate snackbar by setting SnackbarOpen to open.

The snackbar component looks like:

<Snackbar
     open={this.state.SnackbarOpen}
     message={'Theme Changed'}
     action="undo"
     autoHideDuration={4000}
     onActionTouchTap={this.handleActionTouchTap}
     onRequestClose={this.handleRequestClose}
/>

This appears on the screen as follows :

Now if a user wants to change the theme instantly he/she can press the undo button. For this undo button, we have a method handleActionTouchTap. In this method, we change the theme back to previous one. The method is implemented in the following manner:

handleActionTouchTap = () => {
    this.setState({
      SnackbarOpen: false,
    });
    switch(this.state.currTheme){
      case 'light': {
          this.changeTheme('dark');
          break;
      }
      case 'dark': {
          this.changeTheme('light');
          break;
      }
      default: {
          // do nothing
      }
    }
  };

The above method is pretty self-explanatory which checks the current theme(“light” or “dark”) and then revert it. We also change the state of SnackbarOpen to “false” so that on clicking “UNDO” button, the theme changes back to previous one and the snackbar closes.Now user is having an option of instantly changing back to previous theme.

Resources:

Testing Link:

http://chat.susi.ai/

Continue ReadingAdding Snackbar to undo recent change in theme of SUSI.AI Web Chat

Test SUSI Web App with Facebook Jest

Jest is used by Facebook to test all Javascript codes specially React code snippets. If you need to setup jest on your react application you can follow up these simple steps. But if your React application is made with “create-react-app”, you do not need to setup jest manually. Because it comes with Jest. You can run test using “react-scripts” node module.

Since SUSI chat is made with “create-react-app” we do not need to install and run Jest directly. We executed our test cases using “npm test” it executes “react-scripts test” command. It executes all “.js” files under “__tests__” folders. And all other files with “.spec.js” and “.test.js” suffixes.

React apps that are made from “create-react-app” come with sample test case (smoke test) and that checks whether whole application is built correctly or not. If it passes the smoke test then it starts to run further test cases.

import React from 'react';
import ReactDOM from 'react-dom';
import ChatApp from '../../components/ChatApp.react';
it('renders without crashing', () => {
 const div = document.createElement('div');
 ReactDOM.render( < ChatApp / > , div);
});

This checks all components which are inside of the “<ChatApp />” component and it check whether all these components integrate correctly or not.

If we need to check only one component in isolated environment. We can use shallow rendering API. we have used shallow rendering API to check each and every component in isolated environment.

We have to install enzyme and test renderer before use it.

npm install --save-dev enzyme react-test-renderer

import React from 'react';
import MessageSection from '../../components/MessageSection.react';
import { shallow } from 'enzyme';
it('render MessageListItem without crashing',()=>{
  shallow(<MessageSection />);
})

This test case tests only the “MessageListItem”, not its child components.

After executing “npm test” you will get the passed and failed number of test cases.

If you need to see the coverage you can see it without installing additional dependencies.

You just need to run this.

npm test -- --coverage

It will show the output like this.

This view shows how many lines, functions, statements, branches your program has and this shows how much of those covered from the test cases you have.

If we are going to write new test cases for susi chat, we have to make separate file in “__tests__” folder and name it with corresponding file name that we are going to test.

it('your test case description',()=>{
 //test what you need 
})

Normally test cases looks like this.in test cases you can use “test” instead of “it” .after test case description, there is a fat arrow function. In side this fat arrow function you can add what you need to test

In below example I have compared returned value of the function with static value.

function funcName(){
 return 1;
}

it('your test case description',()=>{
 expect(funcName()).toBe(1);
})

You have to add your function/variable that need to be tested into “expect()” and value you expect from that function or variable into “toBe()”.  Instead of “toBe()” you can use different functions according to your need.

If you have a long list of test cases you can group them ( using describe()).

describe('my beverage', () => {
  test('is delicious', () => {
    expect(myBeverage.delicious).toBeTruthy();
  });

  test('is not sour', () => {
    expect(myBeverage.sour).toBeFalsy();
  });
});

This post covers only few things of testing . You can learn more about jest testing from official documentation here.

Continue ReadingTest SUSI Web App with Facebook Jest