Writing mime-type handlers in Angular

week15gsoc1

Developing a collaboration platform like sTeam web interface requires careful introspection while rolling out features that involve dealing with media. Any collaboration platform must support as many mime-types as possible, The REST API for sTeam written in pike offers us with the feasibilty of knowing the type of file or mime-type in the response object.
sTeam inbuilt has a mechanism which helps in detecting the mime-type of the file. So the same concept has been extended to the rest api in order to get the mime-type combined in the response object.

The first question that arrives at any user’s mind is what are the mime-types should i support, well basically there are couple of mime-types that can or could be considered in the category of compulsory mime-types that are ought to be supported if you wish to have media content on your application. Let us have a look at the popular or well known mime-types :

  • Text
  • PDF’s
  • Image
  • Audio
  • Video

What if we donot catch the mime-type ?
This is basically a classic question that has the most easiest answer, just ensure that the mime-types which your handler is unable to catch pass them with a flag saying that it is an unknown mime-type. So let us have a look at how it is done :


angular.module('steam')

.controller('workspaceDetailedCtrl', ['$http', '$scope', 'handler', 'localStorageService', 'PDFViewerService', '$sce',
 function ($http, $scope, handler, localStorageService, pdf, $sce) {
  $scope.dataSrc = localStorageService.get('baseurl') + 'home/' + localStorageService.get('currentObjPath')

  $scope.mimeTypeHandler = function () {
    if(localStorageService.get('currentObjMimeType') == 'application/x-unknown-content-type') {
      return 'unknown'
    } else if (localStorageService.get('currentObjMimeType').match(/image\/*/)) {
      return 'image'
    } else if (localStorageService.get('currentObjMimeType') == 'application/pdf') {
      return 'pdf'
    } else if (localStorageService.get('currentObjMimeType').match(/audio\/*/)) {
      return 'audio'
    } else if (localStorageService.get('currentObjMimeType').match(/video\/*/)) {
      return 'video'
    } else if (localStorageService.get('currentObjMimeType').match(/text\/*/) ||
      localStorageService.get('currentObjMimeType') == 'application/x-javascript' ||
      localStorageService.get('currentObjMimeType') == 'application/x-pike') {
      return 'text'
    } else { return 'notfound' }
  }


The best approach for writing a mime-type handler for your application would be :

  • Have a controller that has a function declared for doing the specific operation and pass the mimetype for the object that which you identify, so that the handler can simplify your job in just returning the type of your file
  • Ensure that as many well known mime-types are supported and for the case of new mime-types that depend for specific application just add them to the if...else block
  • Make it a point to catch all the unknown mime-types because when an unknown mime-type is not declared in your handler the browser tends to download the file directly instead of opening the same in your application

NOTE : The service provider localStorageService is very helpful if you have an application that needs to store some data on the user’s/client’s end. So while the user logs into the web interface , localStorageService sets the userpath, objectmimepath and everything else in order to complete the functionality of the application. So gotcha here is that when you have a situation like this localStorageService0 can be useful, since we can both set the data and get the data. Once the user logs out the data is cleared.

Thats it folks,
Happy Hacking !!

 

Managing multiple states with ui.router

week14gsoc1

Most of the angular applications today have an application router for dealing with the routes of the application. So the web interface for sTeam had the usage of ui.router a library for helping people write routers for complex and big applications. So before i contextualize the usage of ui.router and also give an essence of how routing works with ui.router let us just have a look at the syntax :


angular.module('steam', 'ui.router')

.config(['$locationProvider', '$stateProvider', '$urlRouterProvider', '$provide',
  function ($locationProvider, $stateProvider, $urlRouterProvider, $provide) {

.state('state_name', {
  url: '/route_goes_here',
  templateUrl: '/path_to/templates_go_here.html',
  controller: 'controller_comes_here',
  requireLogin: false || true // depending on the requirement
 })

}])

In the above snippet we can see how to initialize a bare minimum router for an angular application. But to use the ui.router for couple of routes is very much not using the router to the fullest of the features.What are states ?
$state is nothing but a service which is part of the ui.router module. So it can be considered as a service that is responsible for transitioning states accordingly from one state to another. There are many types of states that we can deal with while writing a router for a complex application that deals with multiple and nested states.

  • parent State
  • sibling State
  • grand child state

The parent states generally go with the normal implementation, all we have to use is the state name while declaring the state. But things are not same with sibling state and grandchild state. Let us have a look as to how things are different with them :


// sibling state
.state('^.sibling_name_goes_here', {
  url: '^/route_goes_here',
  templateUrl: '/path_to/templates_go_here.html',
  controller: 'controller_comes_here',
  requireLogin: false || true // depending on the requirement
 })

// grand child state
.state('^.sibling_name_goes_here.grandchild_name_goes_here', {
  url: '^/route_goes_here/:path',
  templateUrl: '/path_to/templates_go_here.html',
  controller: 'controller_comes_here',
  requireLogin: false || true // depending on the requirement
 })

How should multiple routes be handled and how should views be added to the config ?
As explained in my previous article there is a way to use the ui-view in order to write reusable components for the angular application. So let us have a look at how views are to be added to the router’s config :


// state with views
.state('state_name_goes_here', {
  url: '/route_goes_here',
  requireLogin: true || false, // depending on the requirement
  views: {
    'view_name_goes_here': {
      templateUrl: '/path_to/templates_go_here.html',
      controller: 'controller_name_goes_here'
    },
    'view_name_goes_here': {
      templateUrl: '/path_to/templates_go_here.html',
      controller: 'controller_name_goes_here'
    },
    'view_name_goes_here': {
      templateUrl: '/path_to/templates_go_here.html',
      controller: 'controller_name_goes_here'
    }
  }
})

NOTE : We can have the possibility of an application that has a silbing route and all the routes of the parent route are inherited to the sibling route. Enabling this to happen is the beauty of ui.routerNow taking the above syntax we can just add more and more states to the config. It is pretty much that easy to write router config for an application dealing with multiple states. Therefore taking this ahead we can write application router’s for applications that need to handle many routes, but the point here is to understand the point of how the ui.router can be leveraged to the maximum in order to take the best of its features.

Thats it folks,
Happy Hacking !!

Nested views and templates in Angular

week13gsoc1

sTeam web interface is a perfect example of an Angular application that has multiple views to deal with. The router for sTeam is built using ui.router, which is a classic library for dealing with applications that might have a combination of both parent and child routes that are ought to be reused.

What is the difference between ui-view and ng-view ?
Generally we often get confused with the concept of view when it is used with a router and when it is used inside for injecting templates. The concept of view is simple, it acts like a small placeholder so that we can co-relate or place particular piece of DOM in a required location.
So to understand this better and clear the confusion we must first know how views and templates work. So the web interface for sTeam uses ui.router as a result the concept of ui-view differs from ng-view.
Both of these afore mentioned have different service provides while ui-view belongs to ui.router, ng-view belongs to the default angular’s ngRouter

How do we implement them ?
We must understand that we have three things involved while writing views using ui.router. Let us look at them carefully

  • router
  • template
  • view

Let us suppose the below is an example of the view that contains the configuration in the router


.state('workarea.list', {
  url: '^/room/:path',
  requireLogin: true,
  views: {
    'options': {
      templateUrl: '/views/options.html',
      controller: 'optionsCtrl'
    },
    'workspaceList': {
      templateUrl: '/views/workspaceList.html',
      controller: 'workspaceListCtrl'
    },
    'comments': {
      templateUrl: '/views/comments.html',
      controller: 'commentsCtrl'
    }
  }
})

Let us now have a look at the html


  div class="row"
    div class="col-lg-2"
    div
    div class="col-lg-10"
      legend class="text-left">Comments
      legend
      form class="form-horizontal"
        div class="form-group"
          div class="col-sm-10"
            input class="form-control" type="text" ng-model="commentContent" required id="searchMe"
            span
            span
          div
          div class="col-sm-2"
            button type="button" class="btn btn-primary" ng-click="addComment();">Submit
            button
          div
          div
            ul id="comments"
          
        ul
      div
    div
  form
div
div

Now since we have the html written, we can use the same in the same state that which we have declared in the router we are ready to use the view. Let us observe how should the route be used :


div ui-view="comments" div

So if we carefully observe the ui-view attribute we can see that the name of the view is being written, so accordingly we must declare the name in that place in order to use that view.

Thats it folks,
Happy Hacking !!

Integrating textAngular to Angular applications

week12gsoc1

In the previous article we have seen how handling different mime types is important, So while extending that discussion one might think what is the case of files that come under a completely different aspect, As in scripts, documents etc have dynamic operations that are performed over them.
sTeam's old web interface gave the user the provision for creating and editing the documents within the interface. So in short the user had complete control over the documents as he didn’t have to go through complex process for altering documents that which are stored in his/her playground.

The sTeam web interface has a controller in the workspace called workspaceDetailedCtrl which basically comprises of a function called mimeTypeHandler that helps in matching the mime-type and performing the required action if it matches a particular mime type. So let us have a look as to how should one design such things;


$scope.mimeTypeHandler = function () {
	if(localStorageService.get('currentObjMimeType') == 'application/x-unknown-content-type') {
		return 'unknown'
	}
	else if (localStorageService.get('currentObjMimeType').match(/image\/*/)) {
		return 'image'
	}
	else if (localStorageService.get('currentObjMimeType') == 'application/pdf') {
		return 'pdf'
	}
	else if (localStorageService.get('currentObjMimeType').match(/audio\/*/)) {
		return 'audio'
	}
	else if (localStorageService.get('currentObjMimeType').match(/video\/*/)) {
		return 'video'
	}
	else if (localStorageService.get('currentObjMimeType').match(/text\/*/) ||
		localStorageService.get('currentObjMimeType') == 'application/x-javascript' ||
		localStorageService.get('currentObjMimeType') == 'application/x-pike') {
		return 'text'
	}
	else { return 'notfound' }
}

So before we go and understand about developing a text editor let us understand the library that is used for developing it. textAngular is the library that which is used for developing the text editor, although there are many options textAngular proves to be a minimal text editing development source that can be easily setup and broadly configured.

We all know that a text editor must have the following things necessarily :

  • It must support basic formatting options and must extend feasibility to make changes to the document in a easier way
  • Enabling live preview in order to see the changes made to the document instantly
  • Supporting indentation options for documents which are identified as scripts

We might feel that the technicalities are important apart from these notions, but it is important to have these in place along with the technicalities.

Let us observe the syntax and usage of text angular.


angular.module('steam')

  .controller('workSpaceEditorCtrl', ['$scope', 'handler', 'localStorageService', 'textAngularManager', '$document',
   function ($scope, handler, localStorageService, textAngularManager, $document) {
    $scope.data = {
      empty: 'Please enter text',
      full: ''
    }
    $scope.editable = true;
    $scope.content = $scope.data.empty;

    $scope.allh1 = function() {
      textAngularManager.updateToolDisplay('h1', {
        buttontext: 'Heading 1'
      });
    }

    $scope.allh2 = function() {
      textAngularManager.updateToolDisplay('h2', {
        buttontext: 'Heading 2'
      });
    }

    $scope.allh3 = function() {
      textAngularManager.updateToolDisplay('h3', {
        buttontext: 'Heading 3'
      });
    }

    $scope.allh4 = function() {
      textAngularManager.updateToolDisplay('h4', {
        buttontext: 'Heading 4'
      });
    }

    $scope.allh5 = function() {
      textAngularManager.updateToolDisplay('h5', {
        buttontext: 'Heading 5'
      });
    }

    $scope.allh6 = function() {
      textAngularManager.updateToolDisplay('h6', {
        buttontext: 'Heading 6'
      });
    }

    $scope.submit = function () {
      console.log("The document has been submitted");
    }
    $scope.clear = function () {
      console.log("The document has been reset");
      $scope.data = {
        orightml: $scope.content
      }
    }
    $scope.resetEditor = function () {
      textAngularManager.resetToolsDisplay();
    }
  }])

So if we observe we can see that there is a service called textAngularManager which is needed for customizing the text editor. There are a few things that are to be looked upon while customizing the editor.

  • We can totally customize the text editor’s options as well as the appearence of the text editor
  • We can give scope for customized functions that could be part of the controller. Observe the above code snippet where functions like resetEditor etc are customized to the needs of the application
  • Finally We can add more options to the text editor using the textAngular service in order to make it better

After all the customizations and changes Here is how it looks:

week12gsoc2

Source : click here

Thats it folks,
Happy Hacking !!

Developing a pdf viewer in AngularJs

week11gsoc1

Handling different mime types and giving support to them is quite important when a collaboration platform is being developed. Previously sTeam web UI had essential components like :

  • image viewer
  • audio player
  • video player

So in the process of developing new components and adding support for different mime types a PDF viewer grew out as a possibility. So the concept of a PDF viewer is quite simple, it just helps you to display, control all the files that come with the mime-type application/pdf.

The process as a whole is quite simple in developing the pdf viewer. Let us have a look at the process;

  • We have to utilize the PDFViewerService in order to build the PDF viewer
  • The configuration variables are pretty much few in number, although it is very necessary to look after what URI is being passed to the pdfURL variable as it is solely responsible for loading the content from the file.
  • Using the pdf viewer instance is pretty much simple as we have to declare the instance viewer first and then use the same $scope.instance for performing operations like :
    1. Going to the next page
    2. Going to the prev page
    3. Going to a particular page
    4. Displaying the total number of pages loaded
    5. Displaying the progress of the loaded files
  • Lastly there is one important thing to be noted, ngPDFViewer is comparitively a light weight library that could be used for development of a PDF viewer although when the application is bloated with large sized PDF’s it takes couple of seconds to load the PDF. A smart move here would be using the $scope.currentPages and $scope.totalPages in order to make a small calculation and display it at the users end as to how much percentage of the file is loaded.

angular.module('steam', [ 'ngPDFViewer' ])
.controller('workspaceDetailedCtrl', [ '$scope', 'PDFViewerService', function($scope, pdf) {
  $scope.pdfURL = "test.pdf"
  $scope.instance = pdf.Instance("viewer")

  $scope.nextPage = function() {
    $scope.instance.nextPage()
  }
  $scope.prevPage = function() {
    $scope.instance.prevPage()
  }
  $scope.gotoPage = function(page) {
    $scope.instance.gotoPage(page)
  }
  $scope.pageLoaded = function(curPage, totalPages) {
    $scope.currentPage = curPage
    $scope.totalPages = totalPages
  }
  $scope.loadProgress = function(loaded, total, state) {
    console.log('loaded =', loaded, 'total =', total, 'state =', state)
  }
}]);

Here is the final outcome of it:

week11gsoc2

week11gsoc3

Source : click here

Thats it folks,
Happy Hacking !!

Unit testing angular applications with jasmine

week10gsoc1

In the previous article i have addressed about writing tests with frisby. Frisby is helpful in writing tests for angular applications that have active communications involving RESTful api’s. So more or less frisby is helpful as an API testing tool.

The sTeam web interface actively talks to a REST api written in pike along with controllers that make the entire application a complete collaboration platform. So in order to test the working ability of individual units of code, it was necessary to have unit tests written for the application.

What is unit testing really ?
In order to validate different segments of the same code base or isolated parts of the code base we have a testing mechanism called Unit testing which extends the afore mentioned idea of having individual or isolated pieces of code that constitute as units that are tested and ensured that they are working properly.
NOTE: It is always a good practice to write unit tests for your code base in order to ensure that all the individual segments as well as the entire code base is working without flaws.

What is jasmine and how is it related ?
Jasmine is a unit testing framework which is helpful in writing unit tests for applications and it is combined with a test runner called Karma in order to run/execute the tests so written. Now to put things in a simpler perspective, jasmine is test framework which we are going to use, but to run these tests so written we must a test runner that shall execute and give us the outcome of the tests so written with the help of the afore mentioned framework.
NOTE: Jasmine has its own syntax and code conventions.

Is it really going to help ?
Yes, let me give an example to illustrate the effect of writing unit tests. Let’s suppose we have an angular application and it involves controllers, directives etc etc. Now in order to quantify that communication is happening between all the components and the process as a whole is not broken we must first ensure that in the chain of communication the previous functionalities are not effecting components that are connected further and also whilst validating that the code is not breaking there has to be some proof to support the quantification which we before established. Therefore writing unit tests will help us to prove all of that.

Syntax and style :


'use strict';

describe('controllers', function(){

  beforeEach(module('sTeam.controllers'));

  it('should ....', inject(function() {
    // here the test specs go
  }));

  it('should ....', inject(function() {
    // here the test specs go
  }));
});

Let’s go ahead and test a real directive


'use strict';

describe('directives', function() {

  beforeEach(module('sTeam.directives'));

  describe('fileModel', function() {
    it('Must give the flag whether the file upload directive is working or not', function() {
      module(function($provide) {
        $provide.value('model', 'attrs.fileModel');
      });
      inject(function($compile, $rootScope) {
        var DOM = $compile("the html goes here")($rootScope);
    	$rootScope.$digest();
    	expect(element.status()).toEqual('something');
      });
    });
  });
});

Basically in the above example we are testing a unit of the sTeam web interface, a file uploader. It is basically a directive written in order to upload files to the web interface.

So the unit test comprises of a function called $inject which is responsible for injected the DOM code which we wish to test, and then compile the HTML. So after compiling the HTML we have a function called expect which is used for checking whether the desired output is obtained in the DOM or not.

Source : fileModel.js

Thats it folks,
Happy Hacking !!

Angular API testing with frisby and jasmine-node

week9gsoc1

sTeam-web-UI is an application written in angular. So the application relies on sTeam's existing REST api which is written in pike. Since there are a lot of API calls and actions involved ensuring that the application is making proper API calls and getting proper responses is crucial. In order to go ahead with the API testing there are two important things to be know about first.

  • frisby
  • jasmine

What is frisby ?

“Frisby is a REST API testing framework built on node.js and Jasmine that makes testing API endpoints easy, fast, and fun. Read below for a quick overview, or check out the API documentation.”

What is Jasmine ?

“Jasmine is a Behavior Driven Development testing framework for JavaScript. It does not rely on browsers, DOM, or any JavaScript framework. Thus it’s suited for websites, Node.js projects, or anywhere that JavaScript can run.”

The api methods present in frisby can be categorized into :

  • Expectations
  • Helpers
  • Headers
  • Inspectors

So let me show couple of tests that are written with the help of frisby for the sTeam's web interface.

Checking the Home directory of the user :


frisby.create('Request `/home` returns proper JSON')
  .get(config.baseurl + 'rest.pike?request=/home')
  .expectStatus(200)
  .expectJSON({
    'request': '/home',
    'request-method': 'GET',
    'me': objUnit.testMeObj,
    'inventory': function (val) {
      val.forEach(function (e) {
        objUnit.testInventoryObj(e)
      })
    }
  })
.toss()

Checking the container of the user :


frisby.create('Request `/home/:user` returns proper JSON')
  .get(config.baseurl + 'rest.pike?request=/home/akhilhector/container')
  .expectStatus(200)
  .expectJSON({
    'request': '/akhilhector',
    'request-method': 'GET',
    'me': objUnit.testMeObj,
    'inventory': function (val) {
      val.forEach(function (e) {
        objUnit.testInventoryObj(e)
      })
    }
  })
.toss()

Accessing the file in the user’s workarea :


frisby.create('Request `/home/:user/:container/:filename` returns proper JSON')
  .get(config.baseurl + 'rest.pike?request=//home/akhilhector/playground-hector/icon1.png')
  .expectStatus(200)
  .expectJSON({
    'request': '/akhilhector/playground-hector/icon1.png',
    'request-method': 'GET',
    'me': objUnit.testMeObj,
    'inventory': function (val) {
      val.forEach(function (e) {
        objUnit.testInventoryObj(e)
      })
    }
  })
.toss()

Observing the above three modules, each of them are different from one another. We have to understand that depending on the API the request payload must be sent. So for suppose the API needs authentication headers to be sent then we need to use the proper helper methods of frisby in order to send the same.
The .get() can be substituted with put, post, delete. Basically all the frisby tests start with frisby.create with a description of the test followed by one of get, post, put, delete, or head, and ending with toss to generate the resulting response.
Apart from the request payload there is an interesting thing with the helper method expectJSON, it is used for testing the given path or full JSON response of the specified length. In order to use expectJSON we must pass the path as the primary argument and the JSON as the second argument.
The expectStatus helper method is pretty straightforward. It helps us in determining the HTTP Status code equivalent of the request so made.

NOTE While writing the tests it is better to put all the config in one place and use that config variable for all the operations.

Thats it folks,
Happy Hacking !!

Developing Image Viewer in Angular JS

week8gsoc0

In the previous article i have addressed about developing audio and video players for sTeam. To know more about developing audio and video players, click here. This article is an extension to the previous one, as to how one could develop image viewer in angular.
Since sTeam is a collaboration platform there was the necessity of having an image viewer. So in angular bootstrapLightbox is very useful in building image viewers, galleries, sliders etc.

Implementation Strategy :
There are basically two things involved in developing this;

The Controller

angular.module('steam', [ 'bootstrapLightbox', 'ui.bootstrap' ])
  .controller('steamImageViewer', ['$scope', 'Lightbox', function($scope, Lightbox) {
    $scope.images = [
    {
      'url': 'https://societyserver.org/home/akhilhector/playground%20-%20hector/icon1.png',
      'title': 'icon1.png'
    },
    {
      'url': 'https://societyserver.org/home/akhilhector/playground%20-%20hector/icon3.jpg',
      'title': 'icon3.jpg'
    },
    {
      'url': 'https://societyserver.org/home/akhilhector/playground%20-%20hector/icon4.png',
      'title': 'icon4.png'
    },
    {
      'url': 'https://societyserver.org/home/akhilhector/playground%20-%20hector/icon4.jpg',
      'title': 'icon4.jpg'
    }
    ];
    $scope.imageViewer = function (index) {
      Lightbox.openModal($scope.images, index);
    };
  }]);

Observe the controller over here, we pass an array of images or a single image to an array object and then we use the same for our DOM. Options like URL, Title, and Thumbnail can be passed in the same object. In the same controller we need to write another function that uses the LightBox service in order to open a modal and serve the image which was passed as an URL. So the modal displays whatever source is being passed as an argument. Also if we are using a REST api for retrieving the images then we can have a we can have similar array object that stores all the information recieved from the api response. In order to better this, there can be a mime-handler written so that if an unknown/unsupported mime type is being requested for, then an error can be popped.

The HTML

<div class="row" ng-controller="steamImageViewer">
    <div class="col-md-12" ng-repeat="image in images">
        <div class="roomItem">
            <div class="roomItemIcon roomItemBlue"><i class="fa fa-image"></i>
            </div>
            <div class="itemText"> {{image.title}} <a href="#" ng-click="imageViewer($index)">view</a>
            </div>
        </div>
    </div>
</div>

The above DOM seems pretty straight forward, we use the help of the function which we previously wrote in the controller in order to get the data. So as soon as we click the Lightbox modal fires and displays the image. It is to be observed that this implementation goes with consideration that there are an array of images that are ought to be retrieved, but the same logic wouldn’t be fruitful for displaying a single image. In order to acheive that we can pass the image object to the $scope and use the same for displaying the image. And minor changes in the HTML will help displaying a single image instead of an array of images.

So here is how it looks :

week8gsoc3

week8gsoc2

week8gsoc1

Thats it folks,
Happy Hacking !!

Developing Audio & Video Player in Angular JS | sTeam-web-UI | sTeam

week7gsoc1

sTeam web interface, part of sTeam is a collaboration platform so there was the need to support media. In any collaboration platform support for basic/diverse MIME types is necessary. In angular ngVideo and ngAudio are two good packages that are helpful in building audio and video players for any angular application. So let us see how to go ahead with things while implementing media players.
Controllers and the template :

Using ngAudio

angular.module('steam', [ 'ngAudio' ])
.value("songRemember",{})
.controller('sTeamaudioResource', function($scope, ngAudio) {
$scope.audios = [
ngAudio.load('audio/test.mp3'),
]
})
.controller('sTeamaudioPlayer', ['$scope', 'ngAudio', 'songRemember', function($scope, ngAudio,
songRemember) {
var url = 'test.mp3';
if (songRemember[url]) {
$scope.audio = songRemember[url];
} else {
$scope.audio = ngAudio.load(url);
$scope.audio.volume = 0.8;
songRemember[url] = $scope.audio;
}
}]);

  • First create a controller for storing the resources.Store the items in an array or an object. Note the point storing the images in an Array or an Object depends on your use case, but make sure that you are calling the resources correctly.
  • Now create another controller which handles the control of the audio player.This controller should be responsible for handling the URI’s of the media.
  • In the second controller which we create we must add some config to give support to controls in the front end, things like progress of the media, volume, name of the media etc. These are essentially important for the front end. So each resource loaded to the audio player must have all the above listed controls and information.

Below is the screenshot of the audio player

week7gsoc2

Using ngVideo

angular.module('steam', [ 'ngVideo' ])
.controller('sTeamvideoPlayer', ['$scope', '$timeout', 'video', function($scope, $timeout, video) {
$scope.interface = {};
$scope.playlistopen = false;
$scope.videos = {
test1: "test1.mp4",
test2: "test2.mp4"
};
$scope.$on('$videoReady', function videoReady() {
$scope.interface.options.setAutoplay(true);
});
$scope.playVideo = function playVideo(sourceUrl) {
video.addSource('mp4', sourceUrl, true);
}
$scope.getVideoName = function getVideoName(videoModel) {
switch (videoModel.src) {
case ($scope.videos.test1): return "test1";
case ($scope.videos.test2): return "test2";
default: return "Unknown Video";
}
}
video.addSource('mp4', $scope.videos.test1);
video.addSource('mp4', $scope.videos.test2);
}]);

  • Developing the video player is quite the same as developing the audio player but this involves some extra configurations that are ought to be considered. Things like autoplay, giving the scope for playing the video on full screen etc. If keenly looked these are just additional configuration which you are trying to add in order to make your video player more efficient.
  • Firstly we must have the $on($videoReady) event written in order to autoplay the list of videos in the default playlist
  • Moving on, there are couple of controls which are to be given to the video player. Using the method getVideoName we can bind the video source to the title/name of the video.
  • The video service provider must be used for adding the video Sources, and it must be noted that the mp4 can be altered in order to play mp3 files or video files of different format. Before using other video format, make a note of checking the list of video files supported by ngVideo.

Below is the screenshot of the video player

week7gsoc3

Thats it folks,
Happy Hacking !!

Drag and Drop directives in Angular Js | sTeam-web-UI | sTeam

week6gsoc1

The recent developments with the sTeam web interface, involved me writing drag and drop directives for giving scope to drag/move movements in the workarea and the workspace. The concept here is providing user with the feasibility to arrange rooms/documents swiftly and easily.

The idea behind it :
So, in sTeam-web-UI the concept of rooms/documents is implemented using the workareaCtrl. After creating a document/room the created objects appear in the workarea. So in the future, the items in the work area can be sorted and searched for; But adding the scope for drag movements to the web interface makes the the UI/UX to be commendable.

Implementation strategy :
Firstly we need to create directives in angular that can support the actions which when triggered in the front end must result in relative change. So in order to link those actions we must write directives which properly catch the emitted events.

The drag Objective
The way around for implementing the drag objective is to get the element which is selected for the drag option and then emit the event in order to complete the drag action. So we have to go the traditional way for working our way around with this.

// get the element first
angular.element(element).attr("isDraggable": true)
var id = angular.element(element).attr("id")
if(!id) {
id = uuid.create()
angular.element(element).attr("id", id)
}

Now we emit the events.

// emit events
element.bind("startDrag", function (send) {
data.originalEvent.dataTransfer.setData('text', id);
console.log("Starting to drag")
$rootScope.emit("STEAM-DRAG-STRT")
});
element.bind("stopDrag", function (send) {
console.log('Stopping to drag')
$rootScope.emit("STEAM-DRAG-STOP")
});

If we observe the element capturing part, we are just taking the id’s of the elements which are in the DOM and then we bind the respective element with an action, be it startDrag or stopDrag the idea here is to store the id of the element and bind respective action/event to it.

The drop Objective
Before we understand how the drop directive is written there has to be some clarity given on how should we go ahead in writing the directive. The drag and drop directives which when implemented should be carefully monitered since the entire process is interlinked. So the elements must be properly caught and the respective events must be properly binded. While testing we should check if the events are emitting proper actions to the elements or not.

$rootScope.$on("STEAM-DRAG-STRT", function () {
var domelm = document.getElementById(id);
angular.element(domelm).addClass("drag-target");
});
$rootScope.$on("STEAM-DRAG-STOP", function () {
var domelm = document.getElementById(id);
angular.element(domelm).removeClass("drag-target");
angular.element(domelm).removeClass("drag-over");
});

There are alternatives to replicate this mechanism in jQuery and also plain Javascript. But the efficacy of the implementation comes to play only when the DOM can be played with easily.

Thats it folks,
Happy Hacking !!