This semester, we developed much of the infrastructure for Concert in a robust, modular way. Adam and I (Colin) will discuss the various aspects of the application that we have been developing since our last presentation at RCOS.
You can see our slides here: https://docs.google.com/present/edit?id=0AVuQWmnCzsgiZGRoeHhqMzRfMjNneGhyMmpmeA&hl=en&authkey=CMa725UD
And watch our presentation here: http://www.youtube.com/watch?v=0-oGVCp5MPA
Frontend:
Modularity:
As always, we strive to maintain consistency and modularity throughout the application. This goal is especially important on the client-side code which will undoubtedly change dramatically in the future.
Loading notifications on UI panels
An example of where this modularity is important is something like loading notifications. If a panel on the user interface needs to have a loading notification, this clearly must not be coded for each panel, but instead just once and re-used for every panel.
Page object
Another example where modularity is useful is when initializing the functionality on a page. Not only can the code for the UI elements on the page be object-oriented, but the page itself can be as well. This allows us to send a string from the server which informs the JavaScript of which page we are on, and from there we can instantiate the proper Page object to initialize all functionality on the page.
CSS:
We have not done too much styling work this semester, as we are waiting until we are happy with a design iteration. We are fairly certain how the interface will be laid out in general (see mockups here), however, so the styling that we have been doing has been to match the layout to these mockups.
Box layout model
The CSS3 box layout model is quite intuitive, and makes many layout configurations extremely easy. The box layout is based on a “flex” model where you can define the ratio between the width/height of a box and its container, and all of the boxes will expand to fit the container based on these ratios automatically. This often eliminates the need to use the float: property, and in turn eliminates the need for clear: both; everywhere. For more information, here is a great resource from Mozilla: http://mzl.la/ijPwMj
Documentation:
We have commented the client-side code to conform to the JSDoc toolkit, which is a JavaScript documentation generator (among other things). Some features of the code have not been recognized automatically, such as class inheritance, but we will keep these documentation standards in mind when developing the client-side code.
Functionality
The client-side functionality has been developing somewhat slowly as the framework is being set up, but the pace is beginning to increase. Setting up such a robust framework ensures that adding new features and functionality in the user interface will be seamless in the future.
Requesting to join collection & managing collection requests:
In Concert, a user can join a “Collection” which is a group of users and audio files/segments. This forms the basis of Concert and is the concept that the user will first grasp when beginning to use the application. It is for this reason that the experiences associated with requesting to join a collection or creating a collection must be as smooth as possible.
Backbone.js
I have been reading about Backbone.js for some time, the buzz about this framework has been difficult to ignore. Recently I recognized the benefit of using Backbone.js (http://bit.ly/hNzNO7), and decided that now is the proper time to integrate it into our application. It is for that reason that I have been re-factoring our code a bit in order to make the functionality that we have implemented thus far work well with Backbone.
Backbone is an extremely powerful framework and provides a few abstractions that allow robust organization of client-side code. I will discuss two of these abstractions, one is the Backbone.Model, and the other is Backbone.View.
Backbone’s “Model” class allows object-oriented access to the data that is represented on your user interface. Much like an ORM which abstracts away the database interaction from your model, Backbone.Model abstracts away the interaction with the server entirely. This allows for code such as the following:
var book = new Backbone.Model({
title: "The Rough Riders",
author: "Theodore Roosevelt"
});
book.save();
When Book.save(); is executed, the server is informed of the new Book object, and there is no need to keep track of where in the JavaScript objects are changing.
Backbone’s “View” abstraction allows a complete decoupling between the data that is represented on the user interface, and the actual data itself. Consider an application where you have a set of data, and it must be displayed in two different ways on the UI. Under a typical architecture, when this data is changed, we would need to go to both of the places where the data is represented and change the representation. With Backbone.View, this is entirely abstracted away and the “view” object, which is any sort of UI component that depends on some data, simply watches the collection of data that may change. When this data is changed, the view elements update themselves based on their render() method, which is ultimately the only thing that needs to be coded.
A single data collection, that is being watched by two different visualizations of the same data.
Consider in our application, where we have a set of “Collections” that the user is a member of. These collections must be displayed on the UI in both the “Manage Collections Panel”, as well as the “Organize Selector”, which allows the user to select a collection to organize.
In our case, we have two views, Manage Collections Panel and an Organize Selector that are watching this CollectionSet.
When something like the following code is run to load the CollectionSet, the two components of the UI will look as follows:
var userCollections = new CollectionSet([
{
name: "[ ]",
userCount: 2
}
]);
userCollections.save();
The Manage Collections Panel when one collection is added to model.
The Organize Selector when one collection is added to the model.
Using Backbone, both of these “views” will be watching the userCollections “CollectionSet”, and when this data is updated, both representations of this data on the UI will automatically be updated based on their render() method:
userCollections.add({
name: "colin group",
userCount: 1
}).save();
The Manage Collections Panel when another collection is added to the set.
The Organize Selector when another collection is added to the set.
This is not all Backbone.js has to offer, and I have yet to look into the other aspects of the framework. It is obvious that utilizing Backbone.js will take a bit of time to set up, but once it is up and running in our application it will save an incredible amount of time.
Event System
In Concert we have the concept of an “event” which is an object which tracks all the various actions taken by members of the application. Whether it be tagging a segment, joining a collection, uploading audio, or anything else, Concert’s back end automatically creates an event object for the corresponding action taken. The point of this process is to allow for a feed of all actions taken - within a specific collection - to be read and followed by other members of the collection.
The concept isn’t exactly novel, as it’s pretty much the same idea as a Facebook notification - people want to know what their friends and members of their communities are up to.
The purpose in Concert is pretty much the same. Events notify users when things they might be interested in happen within the application. Say, for example, my band-mate uploads an audio file that I’ve been waiting for. I can log into Concert and whether or not they uploaded the file will be immediately apparent to me.