The goal of accounts.susi is to implement all settings from different clients at a single place where user can change their android, iOS or webclient settings altogether and changes should be implemented directly on the susi server and hence the respective clients. This post focuses on how webclient settings are implemented on accounts.susi. SUSI.AI follows the accounting model across all clients and every settings of a user are stores at a single place in the accounting model itself. These are stored in a json object format and can be fetched directly from the ListUserSettings.json endpoint of the server.
Whenever a user login through the accounts, after login they are redirected to the settings page which fetches all webclient settings of the user from the server by making an api request at the ListUserSettings endpoint. This request contains only one parameter namely the access token of the logged in user. This authenticates the user identity and after the request is successful the server sends the response json object to the client. Below snippet of code demonstrate the ajax request send to the api.
apiCall = () => { $.ajax({ url: url, type: 'GET', dataType: 'jsonp', statusCode: { 404: function(xhr) { if (window.console) { console.log(xhr.responseText); } console.log('Error 404: Resources not found!'); document.location.reload(); }, 503: function(xhr) { if (window.console) { console.log(xhr.responseText); } console.log('Error 503: Server not responding!'); document.location.reload(); }, }, crossDomain: true, timeout: 3000, async: false, success: function(response) { if (response.settings.prefLanguage !== '') { this.setState({ PrefLanguage: response.settings.prefLanguage, }); } this.setState({ dataFetched: true, UserName: response.settings.userName, TimeZone: response.settings.timeZone, CountryCode: response.settings.countryCode, CountryDialCode: response.settings.countryDialCode, PhoneNo: response.settings.phoneNo, EnterAsSend: response.settings.enterAsSend, MicInput: response.settings.micInput, theme: response.settings.theme, SpeechOutput: response.settings.speechOutput, SpeechOutputAlways: response.settings.speechOutputAlways, }); }.bind(this), error: function(errorThrown) { console.log(errorThrown); }, }); };
The function apiCall() above is called everytime the Settings is rendered by the below if statement
if (!this.state.dataFetched && cookies.get('loggedIn')) { this.apiCall(); }
Whenever the page reloads the default value of dataFetched key of the state of the settings component is set to false and when the user is loggedIn and dataFetched is set false the if statement is executed and the apiCall() function is called which sends the request to server to get the desired settings. The list of all settings are received by the client in form of json format and values are then set to the variables in the state, which in turn is reflected on the screen.
The settings are divided in different categories placed in different tabs in left menu bar and the settings div on the right displays the current settings of the tab. Everytime a tab is selected the value of the currentSettings variable changes and from the code below we can see that the html of the settings div contains only currentSettings variable and its code is generated according to the current selected tab. This helps us avoiding multiple pages or html tags for every tab in the settings.
We can see from the above code that the
<Paper className="settings">className="currentSettings"> {currentSetting}style={submitButton}> {this.state.selectedSetting === 'Password' ? ( '' ) : ( label="save changes" backgroundColor="#4285F4" labelColor="#fff" disabled={!this.state.settingsChanged} onTouchTap={this.handleSave} /> )}</div> </Paper>
Save changes button is available for all tabs instead of the password tab. This is because the password tab provides the option to change our account password and its value is not stored in the ListUserSettings.json where all secondary user settings are stored but to change password we need a different api call to change our password.
Also the save changes button is disabled by default and is enabled only when the user changes the value something. This is decided by settingsChanged key of the state. Whenever its value is true therefore the value of !this.state.settingsChanged is false and hence the button is enabled. When the button is enabled we can save the changes to server by submitting them by the button. When the button is clicked the this.handleSave call is made to the function which slice the state object of the component and create a ‘vals’ object which contains the updated values of settings. This object is passed to the server along with the access token parameter through the ajax request to the changeUserSettings endpoint of the server.
/aaa/changeUserSettings.json
Resources
- react – https://reactjs.org/
- Actions (redux) – https://redux.js.org/basics/actions
- Ajax request – https://www.w3schools.com/xml/ajax_xmlhttprequest_send.asp