Adding Tweet Streaming Feature in World Mood Tracker loklak App

The World Mood Tracker was added to loklak apps with the feature to display aggregated data from the emotion classifier of loklak server. The next step in the app was adding the feature to display the stream of Tweets from a country as they are discovered by loklak. With the addition of stream servlet in loklak, it was possible to utilise it in this app. In this blog post, I will be discussing the steps taken while adding to introduce this feature in World Mood Tracker app. Props for WorldMap component The WorldMap component holds the view for the map displayed in the app. This is where API calls to classifier endpoint are made and results are displayed on the map. In order to display tweets on clicking a country, we need to define react props so that methods from higher level components can be called. In order to enable props, we need to change the constructor for the component - export default class WorldMap extends React.Component { constructor(props) { super(props); ... } ... } [SOURCE] We can now pass the method from parent component to enable streaming and other components can close the stream by using props in them - export default class WorldMoodTracker extends React.Component { ... showStream(countryName, countryCode) { /* Do something to enable streaming component */ ... } render() { return ( ... <WorldMap showStream={this.showStream}/> ... ) } } [SOURCE] Defining Actions on Clicking Country Map As mentioned in an earlier blog post, World Mood Tracker uses Datamaps to visualize data on a map. In order to trigger a piece of code on clicking a country, we can use the "done" method of the Datamaps instance. This is where we use the props passed earlier - done: function(datamap) { datamap.svg.selectAll('.datamaps-subunit').on('click', function (geography) { props.showStream(geography.properties.name, reverseCountryCode(geography.id)); }) } [SOURCE] The name and ID for the country will be used to display name and make API call to stream endpoint respectively. The StreamOverlay Component The StreamOverlay components hold all the utilities to display the stream of Tweets from loklak. This component is used from its parent components whose state holds info about displaying this component - export default class WorldMoodTracker extends React.Component { ... getStreamOverlay() { if (this.state.enabled) { return (<StreamOverlay show={true} channel={this.state.channel} country={this.state.country} onClose={this.onOverlayClose}/>); } } render() { return ( ... {this.getStreamOverlay()} ... ) } } [SOURCE] The corresponding props passed are used to render the component and connect to the stream from loklak server. Creating Overlay Modal On clicking the map, an overlay is shown. To display this overlay, react-overlays is used. The Modal component offered by the packages provides a very simple interface to define the design and interface of the component, including style, onclose hook, etc. import {Modal} from 'react-overlays'; <Modal aria-labelledby='modal-label' style={modalStyle} backdropStyle={backdropStyle} show={true} onHide={this.close}> <div style={dialogStyle()}> ... </div> </Modal> [SOURCE] It must be noted that modalStyle and backdropStyle are React style objects. Dialog Style The dialog style is defined to provide some space at the top, clicking where, the overlay is closed.…

Continue ReadingAdding Tweet Streaming Feature in World Mood Tracker loklak App

Loklak Timeline Using Sphinx Extension In Yaydoc

In Yaydoc, I decided to add option, to show show the twitter timeline which showthe latest twitter feed. But I wanted to implement it using loklak instead of twitter embedded plugin. I started to search for an embedded plugin that exists for loklak. There is no such plugin, hence I built my own plugin. You can see the source code here. Now that I have the plugin, the next phase is to add the plugin to the documentation. Adding the plugin by appending the plugin code to HTML is not viable. Therefore I decided to make Directive for Sphinx which adds a timeline based on the query parameter which user provides. In order to make a Directive, I had to make a Sphinx extension which creates a timeline Directive. The Directive has to look like this .. timeline :: fossasia from docutils import nodes from docutils.parsers import rst class timeline(nodes.General, nodes.Element): pass def visit(self, node): tag=u''' ''' .format(node.display_name) self.body.append(tag) self.visit_admonition(node) def depart(self, node): self.depart_admonition(node) class TimelineDirective(rst.Directive): name = 'timeline' node_class = timeline has_content = True required_argument = 1 optional_argument = 0 final_argument_whitespace = False option_spec = {} def run(self): node = self.node_class() node.display_name = self.content[0] return [node] def setup(app): app.add_javascript("https://cdn.rawgit.com/fossasia/loklak-timeline-plugin/master/plugi n.js") app.add_node(timeline, html=(visit, depart)) app.add_directive('timeline', TimelineDirective) We have to create an empty class for Nodes that inherits`Node.General` and `Node.Elements`. This class is used for storing the value which will be passed by the directive. I wrote a `Visit` function which executes when sphinx visits the `timeline` directive. `Visit` function basically appends the necessary html code needed to render the twitter timeline. Then I created TimelineDirective class which inherits rst.Directive. In that class, I defined a run method which read the argument from the directive and passed it to the node. Finally I defined a setup method which adds the loklak-timeline-plugin js to the render html node, and directive to the sphinx. Setup function has to be defined, in order to detect module as an extension by the sphinx. Resources: Sphinx official extension tutorial Better Documentation Through Automation: Creating Sphinx Extension - Doug Hellmann

Continue ReadingLoklak Timeline Using Sphinx Extension In Yaydoc

Hiding the Scrollbar in HTML in the loklak Media Wall

Loklak media wall needs to provide an appealing view to the user. The issue of visibility of scrollbars appeared on the browsers which uses webkit as a browser engine, for example, Google chrome and some others. This issue caused problems like shifting of elements when scrollbars are visible, bad UI. The task was to hide the scrollbars completely from the application while still making overflow of web page resources available by scrolling. In this blog, I explain how to hide scrollbars from a webpage and still making scrolling available for the user. Procedure   Removing scrollbars from the body division: By default, the <body> tag has the style property overflow:auto which makes overflow available automatically if web page resources exceed the current page dimensions. Therefore, to hide scrollbar from the body, we need to hide the overflow using overflow:hidden. body { overflow: hidden; }   Creating a child wrapper division for the body: Since body now doesn’t provide scrolling available for the web page, we need to create a wrapper division for the web page for which scrolling would be available, however, scrollbars would not be visible. The idea behind this step is that wrapper division would now act as a wrapper for the web page and if there is some overflow of web page resources, scrolling can be performed from the child division (for which scrollbar can be hidden) instead of parent division.   The wrapper division needs to be a block which should occupy total web page available and CSS property overflow should be set to auto. div.wrapper { display: block; width: 100%; height: 100%; overflow: auto; }   Hiding scrollbars from the wrapper division: The browsers which uses webkit as the browser engines provides scrollbar to every DOM element as webkit-scrollbar which can be customized according to our need. We can now turn scrollbar background to transparent or either set width to 0. Now, since problem of shifting of DOM elements exists, we can need to set width to 0. .wrapper::-webkit-scrollbar { width: 0px; }   Blocking Scroll Blocks: For Angular Material Dialog box, same problem exists since Scroll blocks sets the CSS property of HTML to scroll. This causes the whole  html element to have a scroll. For the same, we can set overflow to hidden by using \deep\ tag to change CSS property deeply of different component of Angular project. /deep/ html.cdk-global-scrollblock { overflow: hidden; } References Stack Overflow Answer to hide Scroll bars: https://stackoverflow.com/questions/16670931/hide-scroll-bar-but-while-still-being-able-to-scroll Reference to ::webkit-scrollbar  pseudo element: https://developer.mozilla.org/en-US/docs/Web/CSS/::-webkit-scrollbar

Continue ReadingHiding the Scrollbar in HTML in the loklak Media Wall

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

Improving Loklak apps site

In this blog I will be describing some of the recent improvements made to the Loklak apps site. A new utility script has been added to automatically update the loklak app wall after a new app has been made. Invalid app query in app details page has been handled gracefully. A proper message is shown when a user enters an invalid app name in the url of the details page. Tests has been added for details page. Developing updatewall script This is a small utility script to update Loklak wall in order to expose a newly created app or update an existing app. Before moving into the working of this script let us discuss how Loklak apps site tracks all the apps and their details. In the root of the project there is a file names apps.json. This file contains an aggregation of all the app.json files present in the individual apps. Now when the site is loaded, index.html loads the Javascript code present in app_list.js. This app_list.js file makes an ajax call to root apps.json files, loads all the app details in a list and attaches this list to the AngularJS scope variable. After this the app wall consisting of various app details is rendered using html. So whenever a new app is created, in order to expose the app on the wall, the developer needs to copy the contents of the application’s app.json and paste it in the root apps.json file. This is quite tedious on the part of the developer as for making a new app he will first have to know how the site works which is not all directly related to his development work. Next, whenever he updates the app.json of his app, he needs to again update apps.json file with the new data. This newly added script (updatewall) automates this entire process. After creating a new app all that the developer needs to do is run this script from within his app directory and the app wall will be updated automatically. Now, let us move into the working of this script. The basic workflow of the updatewall script can be described as follows. The script loads the json data present in the app.json file of the app under consideration. Next it loads the json data present in the root apps.json file. if __name__ == '__main__': #open file containg json object json_list_file = open(PATH_TO_ROOT_JSON, 'r') #load json object json_list = json.load(json_list_file, object_pairs_hook=OrderedDict) json_list_file.close() app_json_file = open(PATH_TO_APP_JSON, 'r') app_json = json.load(app_json_file, object_pairs_hook=OrderedDict) app_json_file.close() #method to update Loklak app wall expose_app(json_list, app_json) When we are loading the json data we are using object_pairs_hook in order to load the data into an OrderedDict rather than a normal python dictionary. We are doing this so that the order of the dictionary items are maintained. Once the data is loaded we invoke the expose method. def expose_app(json_list, app_json): #if app is already present in list then fetch that app app = getAppIfPesent(json_list, app_json) #if app is not present then add…

Continue ReadingImproving Loklak apps site

Using Protractor for UI Tests in Angular JS for Loklak Apps Site

Loklak apps site’s home page and app details page have sections where data is dynamically loaded from external javascript and json files. Data is fetched from json files using angular js, processed and then rendered to the corresponding views by controllers. Any erroneous modification to the controller functions might cause discrepancies in the frontend. Since Loklak apps is a frontend project, any bug in the home page or details page will lead to poor UI/UX. How do we deal with this? One way is to write unit tests for the various controller functions and check their behaviours. Now how do we test the behaviours of the site. Most of the controller functions render something on the view. One thing we can do is simulate the various browser actions and test site against known, accepted behaviours with Protractor. What is Protractor Protractor is end to end test framework for Angular and AngularJS apps. It runs tests against our app running in browser as if a real user is interacting with our browser. It uses browser specific drivers to interact with our web application as any user would. Using Protractor to write tests for Loklak apps site First we need to install Protractor and its dependencies. Let us begin by creating an empty json file in the project directory using the following command. echo {} > package.json Next we will have to install Protractor. The above command installs protractor and webdriver-manager. After this we need to get the necessary binaries to set up our selenium server. This can be done using the following. ./node_modules/protractor/bin/webdriver-manager update ./node_modules/protractor/bin/webdriver-manager start Let us tidy up things a bit. We will include these commands in package.json file under scripts section so that we can shorten our commands. Given below is the current state of package.json { "scripts": { "start": "./node_modules/http-server/bin/http-server", "update-driver": "./node_modules/protractor/bin/webdriver-manager update", "start-driver": "./node_modules/protractor/bin/webdriver-manager start", "test": "./node_modules/protractor/bin/protractor conf.js" }, "dependencies": { "http-server": "^0.10.0", "protractor": "^5.1.2" } } The package.json file currently holds our dependencies and scripts. It contains command for starting development server, updating webdriver and starting webdriver (mentioned just before this) and command to run test. Next we need to include a configuration file for protractor. The configuration file should contain the test framework to be used, the address at which selenium is running and path to specs file. // conf.js exports.config = { framework: "jasmine", seleniumAddress: "http://localhost:4444/wd/hub", specs: ["tests/home-spec.js"] }; We have set the framework as jasmine and selenium address as http://localhost:4444/wd/hub. Next we need to define our actual file. But before writing tests we need to find out what are the things that we need to test. We will mostly be testing dynamic content loaded by Javascript files. Let us define a spec. A spec is a collection of tests. We will start by testing the category name. Initially when the page loads it should be equal to All apps. Next we test the top right hand side menu which is loaded by javascript using topmenu.json file. it("should have a category name", function()…

Continue ReadingUsing Protractor for UI Tests in Angular JS for Loklak Apps Site

Snackbar for Error Handling in Twitter Followers Insight loklak App

In this blog post am going to explain how the Twitter Followers Insight app handles error which occurs when when no query is passed to the “Search” function i.e., when the search is proceeded with an empty query. How to handle the Exception In such cases, I have used SNACKBAR / TOAST. Snackbar / Toast is used to popup an error notification on the screen when an exception occurs. Script for Snackbar / Toast: In the below script, initially the error is set to null i.e., no error. The “showError” function is which is being called when there occurs a situation of no query or an empty query. The function below helps to show an error popup which only shows till a time limit. $scope.error = null; $scope.showError = function() { $(".snackbar").addClass("show"); setTimeout(function(){ $(".snackbar").removeClass("show") }, 3000); }   In this script, it checks whether the query passed is undefined or empty. If yes, then the error message which was null earlier is changed and that error is showed up on the screen to the end user. Snackbars animate upwards from the edge of the screen. if ($scope.query === '' || $scope.query === undefined) { $scope.spinner = false; $scope.error = "Please enter a valid Username"; $scope.showError(); return; }   Resources: More about Snackbar at: https://material.io/guidelines/components/snackbars-toasts.html# How to use Snackbar at: https://kimsereyblog.blogspot.in/2016/11/how-to-use-snackbar-api-in.html Tutorial about Snackbar at: https://www.w3schools.com/howto/howto_js_snackbar.asp

Continue ReadingSnackbar for Error Handling in Twitter Followers Insight loklak App

Updating the UI of the generator form in Open Event Webapp

The design of the generator form in Open Event Webapp has been kept very simple and there have been minor modifications to it over time. In keeping up with the changes made to the front page of the other apps, there was a need to modify the UI of the generator and add some new elements to it. This is the related issue for it. The whole work can be seen here. There were three main parts to it: Add a top bar similar to the Open Event Frontend Add a pop-up menu bar similar to the one shown in Google/Susper Add a version deployment link at the bottom of the page like the one shown in staging.loklak.org.   Implementing the top-bar and the pop-up menu bar The first task was to introduce a top-bar and a pop-up menu bar in Generator. The top-bar would contain the text Open Event Webapp Generator and an icon button on the right side of it which would show a pop-up menu. The pop-up menu would contain a number of icons which would link to different pages like FOSSASIA blogs and it’s official website, different projects like loklak, SUSI and Eventyay and also to the Webapp Project Readme and issues page. Creating a top navbar is easy but the pop-up menu is a comparatively tougher. The first step was to gather the gather the small images of the different services. Since this feature had already been implemented in Susper project, we just copied all the icon images from there and copy it into a folder named icons in the open event webapp. Then we create a custom menu div which would hold all the different icons and present it an aesthetic manner. Write the HTML code for the menu and then CSS to decorate and position it! Also, we have to create a click event handler on the pop-up menu button for toggling the menu on and off. Here is an excerpt of the code. The whole file can be seen here <div class="custom-navbar"> <a href='.' class="custom-navtitle"> <strong>Open Event Webapp Generator</strong> <!-- Navbar Title --> </a> <div class="custom-menubutton"> <i class="glyphicon glyphicon-th"></i> <!-- Pop-up Menu button --> </div> <div class="custom-menu"> <!-- Custom pop-up menu containing different links --> <div class="custom-menu-item"> <a class="custom-icon" href="http://github.com/fossasia/open-event-webapp" target="_blank"><img src="./icons/code.png"> <p class="custom-title">Code</p></a> </div> <!-- Code for other links to different projects--> </div> </div> Here is a screenshot of how the top-bar and the pop-up menu looks! Adding version deployment info to the bottom The next task was to add a footer to the page which would contain the version deployment info. The user can click on that link and we can then be taken to the latest version of the code which is currently deployed. To show the version info, we make use of the Github API. We need to get the hash of the latest commit made on the development branch. We send an API request to the Github requesting for the latest hash and then dynamically add the info and the link received to the footer. The user can then click on that…

Continue ReadingUpdating the UI of the generator form in Open Event Webapp

Twitter Followers Insight App for loklak Apps Site

Twitter Followers Insight, is an app for checking the followers and following lists of an account and as we click on a name, the chain continues. The app also helps to visualize the data, which is returned from the loklak user information API, where it shows the distribution of followers and following across the world in the form of pie chart. Related issue: https://github.com/fossasia/apps.loklak.org/pull/291 Developing the App In the initial stage of the app, the main challenge faced was to implement the clickable feature i.e., make the name of the users in the list which gets displayed should be clickable which navigates to the next list to display as the query changes. Well this was tricky but easy to solve as I had to take the Angular JS with input parameter. Script for storing and displaying the data: The script below shows how to details are being fetched from the JSON object which is returned by the loklak Userdata API. The data or details is then being stored into an list/array which is a scope variable. The array is then iterated in a particular fashion how I want to get it displayed. Storing the data: for (var i = 0; i < followers.length; i++) { user = followers[i].screen_name; name = followers[i].name; followers_count = followers[i].followers_count; pic = followers[i].profile_image_url; followers_loc.push(followers[i].location_country); followerslist.push([user, pic, name, followers_count]); }   The below script shows how the array i.e., showed in the above code, being used and iterated over. Here in this script I used a “ng-repeat” angular function where the list/array is iterated till the limit. The script also display in which order the data is getting displayed on the screen. The clickable feature is set in the “ng-click” angular function, where we are calling the Search function with query as the input parameter. Displaying the data with clickable feature: <ul class="gallery-container" > <li class="gallery-item" style="list-style-type: none;" ng-repeat="value in followersStatus | limitTo: limitFollowers"> <a href ng-click="Search(value[0])"> class="item-image"> src="{{ value[1] }}" style="height: 94px;width: 94px" /> class="item-desc"> class="item-name"> {{ value[2] }} class="item-handle"> @{{ value[0] }} class="item-followers"> class="item-label">Followers: class="item-content">{{ value[3] }} </div> </a> </li> </ul>   Visualizing Followers and Following data using Pie Chart In this app, the data of user’s followers and following is visualized on the basis of the location they live in. This data is visualized in the form of pie chart using Highcharts. Script for displaying pie chart: $('.pie-chart').highcharts({ chart: { plotBackgroundColor: null, plotBorderWidth: null, plotShadow: false, type: 'pie' }, title: { text: "Followers" }, tooltip: { pointFormat: '{series.name}: <b>{point.percentage:.1f}%</b>' }, plotOptions: { pie: { allowPointSelect: true, cursor: 'pointer', dataLabels: { enabled: true, format : '', style: { color: (Highcharts.theme && Highcharts.theme.contrastTextColor) || 'black' } } } }, series: [{ name: "Followers", colorByPoint: true, data: $scope.locations }] });   Resources Learn more about AngularJS here. Learn more about Highcharts here. Learn more about Loklak API here.

Continue ReadingTwitter Followers Insight App for loklak Apps Site