While we were developing the SUSI Web Chat we got a requirement to build a dark theme. And to build a way that user can switch between dark and light theme.
SUSI Web Chat application is made according to the Flux architecture, So we had to build sub components according to that architecture.
What is flux:
Flux is not a framework. It is an Architecture/pattern that we can use to build applications using react and some other frameworks. Below figure shows the way how that architecture works and how it communicate.
How flux works:
Flux has four types of components. Those are views, actions, dispatcher and stores. We use JSX to build and integrate views into our JavaScript code.
When someone triggers an event from view, it triggers an action and that action sends particular action details such as Actiontype, action name and data to dispatcher. Dispatcher broadcasts those details to every store which are registered with the particular dispatcher. That means every store gets all the action details and data which are broadcasting from dispatchers which they are registered.
Let’s say we have triggered an action from view that is going to change the value of the store. Those action details are coming to dispatcher. Then dispatcher broadcasts those data to every store that registered with it. Matching action will trigger and update its value. If there is any change happened in store, view automatically updates corresponding view.
How themes are changing:
We have a store called “SettingStore.js”. This “SettingStore” contains theme values like current theme. We store other settings of the application such as: Mic input settings, Custom server details, Speech Output details, Default Language, etc.it is responsible to provide these details to corresponding view.
let CHANGE_EVENT = 'change'; class SettingStore extends EventEmitter { constructor() { super(); this.theme = true; }
We use “this.theme = true” in constructor to switch light theme as the default theme.
getTheme() { //provides current value of theme return this.theme; }
This method returns the value of the current theme when it triggers.
changeTheme(themeChanges) { this.theme = !this.theme; this.emit(CHANGE_EVENT); }
We use “changeTheme” method to change the selected theme.
handleActions(action) { switch (action.type) { case ActionTypes.THEME_CHANGED: { this.changeTheme(action.theme); break; } default: { // do nothing } } } }
This switch case is the place that store gets actions distributed from the dispatcher and executes relevant method.
const settingStore = new SettingStore(); ChatAppDispatcher.register(settingStore.handleActions.bind(settingStore)); export default settingStore;
Here we registered our store(SettingStore) to “ChatAppDispatcher” .
This is how Store works.
Now we need to get the default light theme to the view. For that we have to call ”getTheme()” function. We can use the value it returns to update the state of the application.
Now we are going to change the theme. To do that we have to trigger “changeTheme” method of “Settingstrore” from view ( MessageSection.react.js ).
We trigger below method on click of the “Change Theme” button. It triggers the action called “themeChanged”.
themeChanger(event) {
Actions.themeChanged(!this.state.darkTheme);
}
Previous method executes “themeChanged()” function of the actions.js file.
export function themeChanged(theme) { ChatAppDispatcher.dispatch({ type: ActionTypes.THEME_CHANGED, theme //data came from parameter }); };
In above function we collect data from the view and send those data, method details to dispatcher.
Dispatcher sends those details to each and every registered store. In our case we have “SettingStore” and update the state to new dark theme.
This is how themes are changing in SUSI AI Web Chat application. Check this link to see the preview.
Resources:
- Read About Flux: https://facebook.github.io/flux/
- GitHub repository: https://github.com/fossasia/chat.susi.ai
- Live Web Chat: http://chat.susi.ai/