Skip to content

Commit

Permalink
Add Content to the Frontend.
Browse files Browse the repository at this point in the history
Move the random text into a proper Content class and hook it up to the field with lots of events.

Content now renders (after 1 second mock loading period) into a field to be displayed for a random duration between 0-10 seconds.  After the duration is up a new piece of content is loaded and the process repeats forever.  This is all still using the sample text content.
  • Loading branch information
bamnet committed Feb 23, 2012
1 parent a9ba8a3 commit e59c751
Show file tree
Hide file tree
Showing 2 changed files with 216 additions and 11 deletions.
153 changes: 153 additions & 0 deletions public/frontend_js/content.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
goog.provide('concerto.frontend.Content');
goog.provide('concerto.frontend.Content.EventType');

goog.require('goog.async.Delay');
goog.require('goog.date.Date');
goog.require('goog.events');
goog.require('goog.events.Event');
goog.require('goog.events.EventTarget');
goog.require('goog.text.LoremIpsum');



/**
* Content being shown on a screen.
* @param {number=} opt_duration The duration the content should be shown for.
* @constructor
* @extends {goog.events.EventTarget}
*/
concerto.frontend.Content = function(opt_duration) {
this.duration = opt_duration || 10;
goog.events.EventTarget.call(this);
};
goog.inherits(concerto.frontend.Content, goog.events.EventTarget);


/**
* Start loading a piece of content.
* Construct a div for the piece of content, request the
* timers be setup to handle the duration, and start pre-loading
* any content necessary.
*
* This dispatches the START_LOAD event.
*/
concerto.frontend.Content.prototype.load = function() {
this.div_ = goog.dom.createDom('div');
this.start_ = new goog.date.Date();

this.setupTimer();

this.dispatchEvent(concerto.frontend.Content.EventType.START_LOAD);

// HACK HACK HACK
var generator = new goog.text.LoremIpsum();
goog.dom.setTextContent(this.div_, generator.generateParagraph());
setTimeout(goog.bind(this.finishLoad, this), 1000);
// END HACK HACK HACK
};


/**
* Finish loading the content.
*
* This dispatches the FINISH_LOAD event.
*/
concerto.frontend.Content.prototype.finishLoad = function() {
this.end_ = goog.date.Date();
this.dispatchEvent(concerto.frontend.Content.EventType.FINISH_LOAD);
};


/**
* Prepare the content for rendering.
* After this stage we can assume the content is being shown in
* the field in some capacity.
*
* This dispatches the START_RENDER event.
*
* @return {Object} HTML div with the rendered content.
*/
concerto.frontend.Content.prototype.render = function() {
this.dispatchEvent(concerto.frontend.Content.EventType.START_RENDER);
return this.div_;
};


/**
* Setup the content timer.
* Create the content timer and set it to call the start method
* when the COMPLETE_RENDER event is dispatched.
*/
concerto.frontend.Content.prototype.setupTimer = function() {
var duration = this.duration * 1000;
this.timer_ = new goog.async.Delay(this.finishTimer, duration, this);

goog.events.listen(this,
concerto.frontend.Content.EventType.COMPLETE_RENDER,
this.startTimer, false, this);
};


/**
* Start the content timer.
*/
concerto.frontend.Content.prototype.startTimer = function() {
this.timer_.start();
};


/**
* The content timer has finished.
* Tell everyone that the content timer is up and they should
* stop displaying this piece of content.
*
* This dispatches the DISPLAY_END event.
*/
concerto.frontend.Content.prototype.finishTimer = function() {
this.dispatchEvent(concerto.frontend.Content.EventType.DISPLAY_END);
};


/**
* The events fired by the content.
* @enum {string} The event types for the content.
*/
concerto.frontend.Content.EventType = {
/**
* Fired when a content starts loading.
*/
START_LOAD: goog.events.getUniqueId('start_load'),

/**
* Fired when a content finishes loading.
*/
FINISH_LOAD: goog.events.getUniqueId('finish_load'),

/**
* Fired when a piece of content starts being rendered
* into the field.
*/
START_RENDER: goog.events.getUniqueId('start_render'),

/**
* Fired when a piece of content completes rendering into
* the field.
*/
COMPLETE_RENDER: goog.events.getUniqueId('complete_render'),

/**
* Fired when a piece of content is being de-rendered.
*/
STOP_RENDER: goog.events.getUniqueId('stop_render'),

/**
* Fired when a piece of content is no longer being rendered
* anywhere on the field.
*/
FINISH_RENDER: goog.events.getUniqueId('finish_render'),

/**
* Fired when a piece of content should no longer be displayed.
*/
DISPLAY_END: goog.events.getUniqueId('display_end')
};
74 changes: 63 additions & 11 deletions public/frontend_js/field.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
goog.provide('concerto.frontend.Field');

goog.require('concerto.frontend.Content');
goog.require('goog.dom');
goog.require('goog.events');
goog.require('goog.events.EventTarget');
goog.require('goog.style');
goog.require('goog.text.LoremIpsum');



Expand All @@ -12,14 +14,20 @@ goog.require('goog.text.LoremIpsum');
* @param {!concerto.frontend.Position} position The position that owns this.
* @param {number} id The field ID number.
* @constructor
* @extends {goog.events.EventTarget}
*/
concerto.frontend.Field = function(position, id) {
this.position = position;
this.id = id;

this.prev_content_ = null;
this.current_content_ = null;
this.next_content_ = null;

this.createDiv();
goog.dom.setTextContent(this.div_, this.junkText(4));
this.loadContent();
};
goog.inherits(concerto.frontend.Field, goog.events.EventTarget);


/**
Expand All @@ -36,15 +44,59 @@ concerto.frontend.Field.prototype.createDiv = function() {


/**
* Generate some filler text.
* @param {number} length Number of paragraphs.
* @return {string} Random text.
* Load a new piece of content for a field.
* Create a new piece of content, associate it with the required events
* and then start loading it.
*/
concerto.frontend.Field.prototype.loadContent = function() {
var random_duration = Math.floor(Math.random() * 11);
this.next_content_ = new concerto.frontend.Content(random_duration);

// When the content is loaded, we show it in the field,
goog.events.listen(this.next_content_,
concerto.frontend.Content.EventType.FINISH_LOAD,
this.showContent, false, this);

// When the content has been shown for too long load a new one.
goog.events.listen(this.next_content_,
concerto.frontend.Content.EventType.DISPLAY_END,
this.loadContent, false, this);

// Actually load that piece of content.
this.next_content_.load();
};


/**
* Start showing the new piece of content in a field.
* Triggered when the content has finished loading,
* we remove the current piece of content and replace it
* with the new one.
*/
concerto.frontend.Field.prototype.junkText = function(length) {
var x = '';
var generator = new goog.text.LoremIpsum();
for (var i = 0; i < length; i++) {
x += generator.generateParagraph();
concerto.frontend.Field.prototype.showContent = function() {
// Get the HTML from the next piece of content we'll be
// inserting into the field.
var new_div = this.next_content_.render();

// If there is currently content in the field, signal
// that it should stop rendering and remove it from the dom.
// When it is fully removed we signal it has finished rendering.
if (goog.isDefAndNotNull(this.current_content_)) {
this.current_content_.dispatchEvent(
concerto.frontend.Content.EventType.STOP_RENDER);
this.prev_content_ = this.current_content_;
goog.dom.removeChildren(this.div_);
this.current_content_.dispatchEvent(
concerto.frontend.Content.EventType.FINISH_RENDER);
}
return x;

// Promote the new piece of content to the current piece of content.
this.current_content_ = this.next_content_;
this.next_content_ = null;

// Insert the new piece of content into the field,
// and signal it has completed rendering.
goog.dom.appendChild(this.div_, new_div);
this.current_content_.dispatchEvent(
concerto.frontend.Content.EventType.COMPLETE_RENDER);
};

0 comments on commit e59c751

Please sign in to comment.