Implementing Predefined Color Themes in loklak Media Wall

Loklak media wall provides predefined color theme buttons which can be used to directly switch to day or night mode. It is important that the colors of the components are updated instantly with a click of a button. To implement pre-defined color options, we should, first, choose a set of color combinations which should be updated on the concerned divisions of the templates. These set of colors should be stored as an object (same interface) and the current state should be updated with this object when another theme is requested. In this blog, I will explain how to implement predefined theme options and how to add a new theme in media wall. Working Media Wall can provide plenty of themes to help the user to choose a theme of their choice. Loklak media wall currently provides two themes, i.e.,  dark and light themes to provide a contrasting variety of themes at first. Ngrx structure makes it easy to add a predefined themes to the media wall. Let’s see how to add a theme to media wall and see it in action. Adding ngrx structure The first task is to create actions which will be dispatched from the Angular components to update the media wall. Depending on the action dispatched, state properties will change and when passed to the template, will update the media wall with the requested theme. There is no need of payload since the color options for all the themes are stored already as a reducer variable which will be updated directly to the media wall state. export class WallLightThemeChangeAction implements Action { type = ActionTypes.WALL_LIGHT_THEME_CHANGE;constructor(public payload: '') { } }export class WallDarkThemeChangeAction implements Action { type = ActionTypes.WALL_DARK_THEME_CHANGE;constructor(public payload: '') { } } Next, we have to update reducer functions for the corresponding actions so that the state properties change according to the actions and wall is updated. For color options, we have an interface defined for color options. For a particular type of theme, we have to adjust interface and just have to update state with the personalised theme state. As the default theme is set to light theme, we have to update state to the initial state when user requests for  light theme case mediaWallCustomAction.ActionTypes.WALL_DARK_THEME_CHANGE: { state = { wallHeader: { backgroundColor: '#243447', fontColor: '#FFFFFF' }, wallBackground: { backgroundColor: '#2C4158' }, wallCard: { fontColor: '#FFFFFF', backgroundColor: '#1B2836', accentColor: '#1c94e0' } } return state; }case mediaWallCustomAction.ActionTypes.WALL_LIGHT_THEME_CHANGE: { state = initialState;return state; } Component and Template Component Now, we need to define an array of the string value of colors corresponding to a particular theme. These corresponding theme colors will be displayed in a form of color picker to the user through looping in the template. Whenever user requests for a particular theme, at first, the variable currentTheme is updated with the theme color. Next, the action is dispatched according to the selected theme from the method installTheme(). export class MediaWallMenuComponent implements OnInit, OnDestroy { . . public currentTheme: string; public themes = [ '#FFFFFF', '#333' ];public…

Continue ReadingImplementing Predefined Color Themes in loklak Media Wall

Using The Dark and Light Theme in SUSI iOS

SUSI being an AI for interactive chat bots, provides answers to the users in the intelligent way. So, to make the SUSI iOS app more user friendly, the option of switching between themes was introduced. This also enables the user switch between themes based on the environment around. Any user can switch between the light and dark themes easily from the settings. We start by declaring an enum called `theme` which contains two strings namely, dark and light. enum theme: String {     case light     case dark } We can update the color scheme based on the theme selected very easily by checking the currently active theme and based on that check, we update the color scheme. To check the currently active theme, we define a variable in the `AppDelegate` which holds the value. var activeTheme: String? Below is the way the color scheme of the LoginViewController is set. var activeTheme: String?func setupTheme() { let image = UIImage(named: ControllerConstants.susi)?.withRenderingMode(.alwaysTemplate) susiLogo.image = image susiLogo.tintColor = .white UIApplication.shared.statusBarStyle = .lightContent let activeTheme = AppDelegate().activeTheme if activeTheme == theme.light.rawValue { view.backgroundColor = UIColor.lightThemeBackground() } else if activeTheme == theme.dark.rawValue { view.backgroundColor = UIColor.darkThemeBackground() } } Here, we first get the image and set the rendering mode to `alwaysTemplate` so that we can change the tint color of the image. Next, we assign the image to the `IBOutlet` and change the tint color to `white`. We also change the status bar style to `lightContent`. Next, we check the active theme and change the view’s background color accordingly. For this method to execute, we call it inside, `viewDidLoad` so that the theme loads up as the view loads. Next, lets add this option of switching between themes inside the `SettingsViewController`. We add a cell with `titleLabel` as `Change Theme` and use the collectionView’s delegate method of `didSelect` to show an alert. This alert contains three options, Dark theme, Light Theme and Cancel. Let’s code that method which presents the alert. func themeToggleAlert() { let imageDialog = UIAlertController(title: ControllerConstants.toggleTheme, message: nil, preferredStyle: UIAlertControllerStyle.alert) imageDialog.addAction(UIAlertAction(title: theme.dark.rawValue.capitalized, style: .default, handler: { (_: UIAlertAction!) in imageDialog.dismiss(animated: true, completion: nil) AppDelegate().activeTheme = theme.dark.rawValue self.settingChanged(sender: self.imagePicker) self.setupTheme() })) imageDialog.addAction(UIAlertAction(title: theme.light.rawValue.capitalized, style: .default, handler: { (_: UIAlertAction!) in imageDialog.dismiss(animated: true, completion: nil) AppDelegate().activeTheme = theme.light.rawValue self.settingChanged(sender: self.imagePicker) self.setupTheme() })) imageDialog.addAction(UIAlertAction(title: ControllerConstants.dialogCancelAction, style: .cancel, handler: { (_: UIAlertAction!) in imageDialog.dismiss(animated: true, completion: nil) })) self.present(imageDialog, animated: true, completion: nil) } Here, we assign the alert view’s title and add 3 actions and their respective completion handlers. If we see inside these completion handlers, we can notice that we first dismiss the alert followed by updating the activeTheme variable in AppDelegate and call the `settingChanged` function which updates the user’s settings on the server. Finally, we update the color scheme. Now, if we build and run the app and change the theme from the settings, we will notice that on returning to the chat view, the color scheme is not updated. The reason here is that we are setting up the theme on…

Continue ReadingUsing The Dark and Light Theme in SUSI iOS

Use of Flux Architecture to Switch between Themes in SUSI Web Chat

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…

Continue ReadingUse of Flux Architecture to Switch between Themes in SUSI Web Chat

Implementing Themes in Angular JS for Susper

Adding themes to any website, makes it more interesting to use, and also helps customize the website according to personal preferences. This blog deals with how we implemented themes in Susper. Susper offers the following themes Default Dark Basic Contrast Terminal This is how some of the themes look Dark: Contrast:   Terminal: Lets go through a step by step guide how to implement this: Add a Themes service  (In app/src/theme.service.ts in Susper) Here is the code snippet: import { Injectable } from '@angular/core'; @Injectable() export class ThemeService { public titleColor: string; public linkColor: string; public descriptionColor: string; public backgroundColor: string; constructor() { } }  Create a component for themes, and define functions for various themes in the .ts file.(src/app/theme/theme.component.ts in Susper) Here is the example code: import { Component, OnInit } from '@angular/core'; import { ThemeService } from '../theme.service';@Component({ selector: 'app-theme', templateUrl: './theme.component.html', styleUrls: ['./theme.component.css'] }) export class ThemeComponent implements OnInit {constructor( private themeService: ThemeService ) { }ngOnInit() { }darkTheme() { this.themeService.backgroundColor = '#FFFFFF'; this.themeService.titleColor = '#050404'; this.themeService.linkColor = '#7E716E'; this.themeService.descriptionColor = '#494443'; } defaultTheme() { this.themeService.backgroundColor = '#FFFFFF'; this.themeService.titleColor = '#1a0dab'; this.themeService.linkColor = '#006621'; this.themeService.descriptionColor = '#545454'; } basicTheme() { this.themeService.backgroundColor = '#FFFFFF'; this.themeService.titleColor = '#1a0dab'; this.themeService.linkColor = '#494443'; this.themeService.descriptionColor = '#7E716E'; } In the above code, the first few lines  include the constructor, which defines the theme service, and include a default function that runs as soon as the page is initialized. We then see three kinds of themes implemented, dark, default and contrast. Let us examine the darkTheme: darkTheme() { this.themeService.backgroundColor = '#FFFFFF'; this.themeService.titleColor = '#050404'; this.themeService.linkColor = '#7E716E'; this.themeService.descriptionColor = '#494443'; } The first line sets the background color of the screen(to white). The second line is used to set the color of all the titles of the search results The third line is used to set the link/url color The fourth line sets the description color   Link the appropriate attributes in your html pages, using [style.’css-attribute’] class="title"> class="title-pointer" href="{{item.link}}" [style.color]="themeService.titleColor">{{item.title}} (src/app/results/results.component.html in Susper) Following this example, you can link different parts of the html file to the attributes in your theme service and you are done! If implementing this in a project like Susper, a few points of caution: Make sure you write your spec.ts file well, and add your component for proper compilation and testing. Do not forget to import the service into any component before you use it in its html files. Resources  This tutorial, provides a great insight into how such services work: https://angular.io/tutorial/toh-pt4 If you wish to implement this, using the help of components, this bit in stack overflow might help: https://stackoverflow.com/questions/37363121/get-and-update-a-string-through-a-service-in-angular-2

Continue ReadingImplementing Themes in Angular JS for Susper

Using custom themes with Yaydoc to build documentation

What is Yaydoc? Yaydoc aims to be a one stop solution for all your documentation needs. It is continuously integrated to your repository and builds the site on each commit. One of it's primary aim is to minimize user configuration. It is currently in active development. Why Themes? Themes gives the user ability to generate visually different sites with the same markup documents without any configuration. It is one of the many features Yaydoc inherits from sphinx. Now sphinx comes with 10 built in themes but there are much more custom themes available on PyPI, the official Python package repository. To use these custom themes, sphinx requires some setup. But Yaydoc being an automated system needs to performs those tasks automatically. To use a custom theme which has been installed, sphinx needs to know the name of the theme and where to find it. We do that by specifying two variables in the sphinx configuration file. html_theme and html_theme_path respectively. Custom themes provide a method that can be called to get the html_theme_path of the theme. Usually that method is named get_html_theme_path . But that is not always the case. We have no way find the appropriate method automatically. So how do we get the path of an installed theme just by it’s name and how do we add it to the generated configuration file. The configuration file is generated by the sphinx-quickstart command which Yaydoc uses to initialize the documentation directory. We can override the default generated files by providing our own project templates. The templates are based on the Jinja2 template engine. Firstly, I replaced html_theme = ‘alabaster’ With html_theme = ‘{{ html_theme }}’ This provides us the ability to pass the name of the theme as a parameter to sphinx-quickstart. Now the user has an option to choose between 10 built-in themes. For custom themes however there is a different story. I had to solve two major issues. The name of the package and the theme may differ. We also need the absolute path to the theme. The following code snippet solves the above mentioned problems. {% if html_theme in (['alabaster', 'classic', 'sphinxdoc', 'scrolls', 'agogo', 'traditional', 'nature', 'haiku', 'pyramid', 'bizstyle']) %} # Theme is builtin. Just set the name html_theme = '{{ html_theme }}' {% else %} # Theme is a custom python package. Lets install it. import pip exitcode = pip.main(['install', '{{ html_theme }}']) if exitcode: # Non-zero exit code print("""{0} is not available on pypi. Please ensure the theme can be installed using 'pip install {0}'.""".format('{{ html_theme }}'), file=sys.stderr) else: import {{ html_theme }} def get_path_to_theme(): package_path = os.path.dirname({{ html_theme }}.__file__) for root, dirs, files in os.walk(package_path): if 'theme.conf' in files: return root path_to_theme = get_path_to_theme() if path_to_theme is None: print("\n{0} does not appear to be a sphinx theme.".format('{{ html_theme }}'), file=sys.stderr) html_theme = 'alabaster' else: html_theme = os.path.basename(path_to_theme) html_theme_path = [os.path.abspath(os.path.join(path_to_theme, os.pardir))] {% endif %} It performs the following tasks in order: It first checks if the provided theme is one of the built…

Continue ReadingUsing custom themes with Yaydoc to build documentation

SASS for the theme based concept

Until yesterday, I was exploring all around the internet, to find the best possible way for the theme concept in the web app. The theme concept allows an organizer to choose the theme for the web app from the set of provided themes. After some time, I realised that this awesomeness to the web app can be added by using Syntactically Awesome Stylesheets. How SASS supports the theme concept?   In the web app, a folder name _scss is added which has the directory structure as shown There is a file _config.scss inside the _base folder that includes the SASS variables which are used in all the files after importing it. Each of the SASS variables uses a flag !default at the end, which means it can be overwritten in any other file. This property of SASS leads to the theme concept. //_.config.scss @charset "UTF-8"; // Colors $black: #000; $white: #fff; $red: #e2061c; $gray-light: #c9c8c8; $gray: #838282; $gray-dark: #333333; $blue: #253652; // Corp-Colors $corp-color: $white !default; $corp-color-dark: darken($corp-color, 15%) !default; $corp-color-second: $red !default; $corp-color-second-dark: darken($corp-color-second, 15%) !default; // Fontbasic $base-font-size: 1.8 !default; $base-font-family: Helvetica, Arial, Sans-Serif !default; $base-font-color: $gray-dark !default; // Border $base-border-radius: 2px !default; $rounded-border-radius: 50% !default; $base-border-color: $gray !default; The main file that includes all the required style is the application.scss. Here, $corp-color takes default value from  _config.scss. It can be overwritten by the themes. //application.scss @charset 'UTF-8'; // 1.Base @import '_base/_config.scss'; /* Offsets for fixed navbar */ body { margin-top: 50px; background-color:$corp-color !important; } Making a light theme    The light theme will overwrite the $corp-color value to $gray-light which is defined in _config.scss. This will change the background-color defined in application.scss to #c9c8c8. So, in this way a light theme is generated. The similar approach can be followed to generate the dark theme. //_light.scss @charset 'UTF-8'; @import '../../_base/config'; // 1.Overwrite stuff $corp-color: $gray-light; @import '../../application'; Making a dark theme    //_dark.scss @charset 'UTF-8'; @import '../../_base/config'; // 1.Overwrite stuff $corp-color: $gray; @import '../../application'; How to compile the CSS from SASS files ?   We can easily compile these SASS files by using command sass /path/application.scss /path/schedule.css For generating light theme and dark theme: sass /path/_light.scss  /path/schedule.css sass /path/_dark.scss  /path/schedule.css Optimization of Code   SASS is very powerful for optimizing the code. It allows the concepts such as nesting, mixins which reduce the line of code. I have rewritten schedule.css into application.scss to make it more optimized. /* Adjustments for smaller screens */ @media (min-width: 450px) { body { font-size: 14px } .session { &-list{ .label{ font-size: 90%; padding: .2em .6em .3em; } } &-title { float:left; width: 75%; } &-location { float: right; width: 25%; text-align: right; } } } Further Exploration   This is one of the ways to deal with the SASS structure, but there are other resources that can be helpful in dealing with SASS projects. Breakpoint Octopress Also, check out, Jeremy Hexon article here.

Continue ReadingSASS for the theme based concept