2011-04-15 13:26:55 -05:00
|
|
|
// TimeStamper namespace
|
|
|
|
var TS = {};
|
2011-03-16 07:39:09 -05:00
|
|
|
|
2011-03-01 18:00:51 -06:00
|
|
|
/* Setup after the document is ready for manipulation. */
|
2011-03-01 08:23:51 -06:00
|
|
|
$(document).ready(function(){
|
2011-02-24 07:29:30 -06:00
|
|
|
|
2011-04-15 13:26:55 -05:00
|
|
|
// ======== DEFINE MODELS ========//
|
2011-03-01 08:23:51 -06:00
|
|
|
|
2011-04-15 13:26:55 -05:00
|
|
|
/* Entry model.
|
|
|
|
* Attributes
|
|
|
|
* - id
|
|
|
|
* - mark
|
|
|
|
* - notes
|
|
|
|
* - start
|
|
|
|
*/
|
2011-04-20 09:40:54 -05:00
|
|
|
TS.EntryModel = Backbone.Model.extend({
|
2011-03-08 18:02:33 -06:00
|
|
|
|
2011-04-15 13:26:55 -05:00
|
|
|
});
|
2011-03-01 18:00:51 -06:00
|
|
|
|
2011-04-15 13:26:55 -05:00
|
|
|
/* Timeline model.
|
|
|
|
* Attributes:
|
|
|
|
* - id
|
2011-05-03 12:50:03 -05:00
|
|
|
* - description
|
2011-04-15 13:26:55 -05:00
|
|
|
* - created
|
|
|
|
*/
|
2011-04-20 09:40:54 -05:00
|
|
|
TS.TimelineModel = Backbone.Model.extend({
|
2011-03-01 18:00:51 -06:00
|
|
|
|
2011-04-15 13:26:55 -05:00
|
|
|
});
|
2011-03-01 08:23:51 -06:00
|
|
|
|
2011-04-15 13:26:55 -05:00
|
|
|
/* User model.
|
|
|
|
* Attributes:
|
|
|
|
* - username
|
|
|
|
* - fullname
|
|
|
|
* - email
|
|
|
|
* - join_date
|
|
|
|
*/
|
2011-04-20 09:40:54 -05:00
|
|
|
TS.UserModel = Backbone.Model.extend({
|
2011-04-27 14:11:54 -05:00
|
|
|
url: function() { return '/ts_api/users/' + this.get('id'); },
|
2011-03-01 08:23:51 -06:00
|
|
|
|
2011-04-27 14:11:54 -05:00
|
|
|
initialize: function(attrs, options) {
|
|
|
|
_.bind(this, 'url');
|
|
|
|
}
|
2011-04-15 13:26:55 -05:00
|
|
|
});
|
2011-03-01 08:23:51 -06:00
|
|
|
|
2011-04-15 13:26:55 -05:00
|
|
|
TS.EntryList = Backbone.Collection.extend({
|
2011-04-20 09:40:54 -05:00
|
|
|
model: TS.EntryModel,
|
2011-04-15 13:26:55 -05:00
|
|
|
|
|
|
|
comparator: function(entry) { return entry.get('timestamp'); },
|
2011-03-01 18:00:51 -06:00
|
|
|
|
2011-04-20 09:40:54 -05:00
|
|
|
initialize: function(model, options) {
|
|
|
|
if (options.timeline == undefined) {
|
|
|
|
throw "Cannot create an EntryList without a TimelineModel reference."
|
|
|
|
} else { this.timeline = options.timeline; }
|
|
|
|
|
|
|
|
_.bindAll(this, "url");
|
2011-03-01 08:23:51 -06:00
|
|
|
},
|
2011-03-01 18:00:51 -06:00
|
|
|
|
2011-04-15 13:26:55 -05:00
|
|
|
url: function() {
|
2011-05-03 12:50:03 -05:00
|
|
|
return "/ts_api/entries/" + this.timeline.get('user_id') + "/" + this.timeline.get('id');
|
2011-04-15 13:26:55 -05:00
|
|
|
}
|
|
|
|
});
|
2011-03-01 18:00:51 -06:00
|
|
|
|
2011-04-15 13:26:55 -05:00
|
|
|
TS.TimelineList = Backbone.Collection.extend({
|
2011-04-20 09:40:54 -05:00
|
|
|
model: TS.TimelineModel,
|
|
|
|
|
|
|
|
initialize: function(models, options) {
|
|
|
|
if (options.user == undefined) {
|
|
|
|
throw "Cannot create a TimelineList without a UserModel reference.";
|
|
|
|
} else { this.user = options.user; }
|
|
|
|
|
|
|
|
_.bindAll(this, 'url');
|
|
|
|
},
|
2011-03-01 18:00:51 -06:00
|
|
|
|
2011-04-27 16:59:33 -05:00
|
|
|
comparator: function(timeline) {
|
|
|
|
return timeline.get('id');
|
|
|
|
},
|
|
|
|
|
2011-04-15 13:26:55 -05:00
|
|
|
url: function() {
|
2011-04-20 09:40:54 -05:00
|
|
|
return "/ts_api/timelines/" + this.user.get('id');
|
2011-04-15 13:26:55 -05:00
|
|
|
}
|
|
|
|
});
|
2011-03-01 18:00:51 -06:00
|
|
|
|
2011-03-01 08:23:51 -06:00
|
|
|
|
2011-04-15 13:26:55 -05:00
|
|
|
// ======== DEFINE VIEWS ========//
|
2011-03-01 08:23:51 -06:00
|
|
|
|
2011-04-15 13:26:55 -05:00
|
|
|
/* Entry view
|
|
|
|
*/
|
|
|
|
TS.EntryView = Backbone.View.extend({
|
2011-03-01 08:23:51 -06:00
|
|
|
|
2011-04-20 09:40:54 -05:00
|
|
|
model: TS.EntryModel,
|
2011-03-01 08:23:51 -06:00
|
|
|
|
2011-05-03 12:50:03 -05:00
|
|
|
className: 'entry',
|
|
|
|
|
2011-04-15 13:26:55 -05:00
|
|
|
events: {
|
|
|
|
"dblclick div.mark" : "editMark",
|
|
|
|
"dblclick div.timestamp" : "editTimestamp",
|
2011-04-27 14:11:54 -05:00
|
|
|
"keypress .mark-input" : "updateOnEnter",
|
2011-04-15 13:26:55 -05:00
|
|
|
"keypress .timestamp-input" : "updateOnEnter"
|
|
|
|
},
|
2011-03-01 18:00:51 -06:00
|
|
|
|
2011-04-15 13:26:55 -05:00
|
|
|
initialize: function() {
|
2011-04-27 16:59:33 -05:00
|
|
|
_.bindAll(this, 'render', 'close', 'editTImestamp',
|
|
|
|
'editMark', 'updateOnEnter');
|
2011-04-15 13:26:55 -05:00
|
|
|
this.model.bind('change', this.render);
|
|
|
|
this.model.view = this;
|
2011-03-01 08:23:51 -06:00
|
|
|
},
|
2011-03-01 18:00:51 -06:00
|
|
|
|
2011-04-15 13:26:55 -05:00
|
|
|
render: function() {
|
2011-05-03 12:50:03 -05:00
|
|
|
$(this.el).html(ich.entryTemplate(this.model.toJSON()));
|
2011-04-15 13:26:55 -05:00
|
|
|
return this;
|
|
|
|
},
|
2011-03-01 08:23:51 -06:00
|
|
|
|
2011-04-15 13:26:55 -05:00
|
|
|
editMark: function() {
|
|
|
|
$(this.el).addClass('edit-mark');
|
|
|
|
this.$('.mark-input').focus();
|
|
|
|
return this;
|
|
|
|
},
|
2011-03-01 18:00:51 -06:00
|
|
|
|
2011-04-15 13:26:55 -05:00
|
|
|
editTimestamp: function() {
|
|
|
|
$(this.el).addClass('edit-timestamp');
|
|
|
|
this.$('timestamp-input').focus();
|
|
|
|
return this;
|
|
|
|
},
|
2011-03-01 18:00:51 -06:00
|
|
|
|
2011-04-15 13:26:55 -05:00
|
|
|
close: function() {
|
|
|
|
this.model.save({
|
|
|
|
mark: this.$('.mark-input').val(),
|
|
|
|
timestamp: this.$('.timestamp-input').val()});
|
|
|
|
$(this.el).removeClass('edit-mark edit-timestamp');
|
2011-05-03 12:50:03 -05:00
|
|
|
this.render();
|
2011-03-03 17:05:30 -06:00
|
|
|
},
|
|
|
|
|
2011-04-15 13:26:55 -05:00
|
|
|
updateOnEnter: function(e) {
|
|
|
|
if(e.keyCode == 13) this.close();
|
2011-03-01 08:23:51 -06:00
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2011-04-20 09:40:54 -05:00
|
|
|
TS.EntryListView = Backbone.View.extend({
|
|
|
|
|
2011-04-27 16:59:33 -05:00
|
|
|
el: $("#entry-list"),
|
|
|
|
|
|
|
|
events: {
|
2011-05-03 12:50:03 -05:00
|
|
|
"keypress #new-entry-input" : "createNewEntryOnEnter"
|
2011-04-27 16:59:33 -05:00
|
|
|
},
|
2011-04-20 09:40:54 -05:00
|
|
|
|
|
|
|
initialize: function() {
|
2011-04-27 16:59:33 -05:00
|
|
|
_.bindAll(this, 'addOne', 'createNewEntry', 'render');
|
2011-04-20 09:40:54 -05:00
|
|
|
this.collection.bind('add', this.addOne);
|
|
|
|
this.collection.bind('refresh', this.render);
|
|
|
|
this.collection.view = this;
|
2011-04-27 16:59:33 -05:00
|
|
|
this.entryContainer = this.$("#entries")
|
2011-04-20 09:40:54 -05:00
|
|
|
},
|
|
|
|
|
|
|
|
addOne: function(entry) {
|
2011-04-27 16:59:33 -05:00
|
|
|
if (!entry.view) { new TS.EntryView({model: entry}); }
|
|
|
|
this.entryContainer.prepend(entry.view.render().el);
|
|
|
|
},
|
|
|
|
|
2011-05-03 12:50:03 -05:00
|
|
|
createNewEntryOnEnter: function(e) {
|
|
|
|
|
|
|
|
if (e.keyCode == 13) {
|
|
|
|
|
|
|
|
// grab the mark data
|
|
|
|
var entryMark = this.$("#new-entry-input").val();
|
|
|
|
|
|
|
|
// create the mark. Immediately fetch to get server-side timestamp
|
|
|
|
this.collection.create({mark: entryMark,
|
|
|
|
notes: '',
|
|
|
|
timestamp: getUTCTimestamp()}).fetch();
|
|
|
|
}
|
2011-04-20 09:40:54 -05:00
|
|
|
},
|
|
|
|
|
|
|
|
render: function() {
|
2011-04-27 16:59:33 -05:00
|
|
|
this.entryContainer.empty();
|
2011-04-20 09:40:54 -05:00
|
|
|
this.collection.each(this.addOne);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2011-05-03 12:50:03 -05:00
|
|
|
TS.TimelineListView = Backbone.View.extend({
|
2011-04-15 13:26:55 -05:00
|
|
|
el: $("#timeline"),
|
2011-03-07 16:43:40 -06:00
|
|
|
|
2011-05-03 12:50:03 -05:00
|
|
|
collection: TS.TimelineList,
|
2011-03-07 16:43:40 -06:00
|
|
|
|
2011-04-15 13:26:55 -05:00
|
|
|
events: {
|
|
|
|
"dblclick .timeline-id" : "editId",
|
|
|
|
"dblclick .timeline-desc" : "editDesc",
|
|
|
|
"keypress .timeline-id-input" : "updateOnEnter",
|
|
|
|
"keypress .timeline-desc-input" : "updateOnEnter"
|
|
|
|
},
|
2011-03-07 16:43:40 -06:00
|
|
|
|
2011-05-03 12:50:03 -05:00
|
|
|
initialize: function(options) {
|
|
|
|
_.bindAll(this, 'render', 'renderOne', 'editId',
|
|
|
|
'editDesc', 'updateOnEnter');
|
|
|
|
|
|
|
|
if (options.initialTimelineId == undefined) {
|
|
|
|
throw "Can not create a TimelineListView without an initial timeline."
|
|
|
|
} else {
|
|
|
|
this.selected = this.collection.get(options.initialTimelineId);
|
|
|
|
}
|
|
|
|
|
|
|
|
this.collection.bind('add', this.renderOne);
|
|
|
|
this.collection.bind('refresh', this.render);
|
|
|
|
},
|
|
|
|
|
|
|
|
renderOne: function(timeline) {
|
|
|
|
this.$('.drop-menu-items').append(
|
|
|
|
ich.timelineLinkTemplate(timeline.toJSON()));
|
2011-04-15 13:26:55 -05:00
|
|
|
},
|
2011-03-07 16:43:40 -06:00
|
|
|
|
2011-04-15 13:26:55 -05:00
|
|
|
render: function() {
|
2011-05-03 12:50:03 -05:00
|
|
|
// render the basic template
|
|
|
|
$(this.el).html(ich.timelineTemplate(this.selected.toJSON()));
|
|
|
|
|
|
|
|
// render the selection list
|
|
|
|
_.each(this.collection.without([this.selected]), this.renderOne);
|
2011-04-15 13:26:55 -05:00
|
|
|
},
|
2011-03-07 16:43:40 -06:00
|
|
|
|
2011-04-15 13:26:55 -05:00
|
|
|
editId: function() {
|
|
|
|
$(this.el).addClass('edit-id');
|
|
|
|
this.$('.timeline-id-input').focus();
|
|
|
|
return this;
|
|
|
|
},
|
2011-03-07 16:43:40 -06:00
|
|
|
|
2011-04-15 13:26:55 -05:00
|
|
|
editDesc: function() {
|
|
|
|
$(this.el).addClass('edit-desc');
|
|
|
|
this.$('.timeline-desc-input').focus();
|
|
|
|
return this;
|
2011-04-27 14:11:54 -05:00
|
|
|
},
|
2011-04-15 13:26:55 -05:00
|
|
|
|
|
|
|
close: function() {
|
2011-05-03 12:50:03 -05:00
|
|
|
this.selected.save({
|
|
|
|
id: this.$('.timeline-id-input').val(),
|
|
|
|
description: this.$('.timeline-desc-input').val()});
|
|
|
|
$(this.el).removeClass('edit-id edit-desc');
|
|
|
|
this.render();
|
2011-04-15 13:26:55 -05:00
|
|
|
},
|
2011-03-07 16:43:40 -06:00
|
|
|
|
2011-04-15 13:26:55 -05:00
|
|
|
updateOnEnter: function(e) {
|
|
|
|
if (e.keyCode == 13) this.close();
|
|
|
|
}
|
2011-04-27 16:59:33 -05:00
|
|
|
|
|
|
|
});
|
|
|
|
|
2011-04-15 13:26:55 -05:00
|
|
|
TS.UserView = Backbone.View.extend({
|
|
|
|
|
2011-04-27 14:11:54 -05:00
|
|
|
el: $("#user"),
|
2011-03-07 16:43:40 -06:00
|
|
|
|
2011-04-20 09:40:54 -05:00
|
|
|
model: TS.UserModel,
|
2011-03-07 16:43:40 -06:00
|
|
|
|
2011-04-15 13:26:55 -05:00
|
|
|
events: {
|
|
|
|
'dblclick .fullname': 'editFullname',
|
|
|
|
'keypress .fullname-input': 'updateOnEnter'
|
|
|
|
},
|
2011-03-07 16:43:40 -06:00
|
|
|
|
2011-04-15 13:26:55 -05:00
|
|
|
initialize: function() {
|
2011-04-20 09:40:54 -05:00
|
|
|
_.bindAll(this, 'render', 'close', 'editFullname', 'updateOnEnter');
|
2011-04-15 13:26:55 -05:00
|
|
|
this.model.bind('change', this.render);
|
|
|
|
this.model.view = this;
|
|
|
|
},
|
2011-03-07 16:43:40 -06:00
|
|
|
|
2011-04-15 13:26:55 -05:00
|
|
|
render: function() {
|
2011-05-03 12:50:03 -05:00
|
|
|
$(this.el).html(ich.userTemplate(this.model.toJSON()));
|
2011-04-20 09:40:54 -05:00
|
|
|
return this;
|
2011-04-15 13:26:55 -05:00
|
|
|
},
|
2011-03-07 16:43:40 -06:00
|
|
|
|
2011-04-15 13:26:55 -05:00
|
|
|
editFullname: function() {
|
2011-05-03 12:50:03 -05:00
|
|
|
$(this.el).addClass('edit-fullname');
|
2011-04-15 13:26:55 -05:00
|
|
|
this.$('.fullname-input').focus();
|
|
|
|
return this;
|
|
|
|
},
|
2011-03-07 16:43:40 -06:00
|
|
|
|
2011-04-15 13:26:55 -05:00
|
|
|
close: function() {
|
2011-05-03 12:50:03 -05:00
|
|
|
this.model.set({name: this.$('fullname-input').val()});
|
2011-04-15 13:26:55 -05:00
|
|
|
this.model.save();
|
2011-05-03 12:50:03 -05:00
|
|
|
$(this.el).removeClass('edit-fullname');
|
2011-04-15 13:26:55 -05:00
|
|
|
},
|
2011-03-07 16:43:40 -06:00
|
|
|
|
2011-04-15 13:26:55 -05:00
|
|
|
updateOnEnter: function(e) {
|
2011-05-03 12:50:03 -05:00
|
|
|
if (e.keyCode == 13) this.close();
|
2011-04-15 13:26:55 -05:00
|
|
|
}
|
|
|
|
});
|
2011-03-07 16:43:40 -06:00
|
|
|
|
2011-04-27 14:11:54 -05:00
|
|
|
TS.AppView = Backbone.View.extend({
|
|
|
|
|
|
|
|
el: $("body"),
|
|
|
|
|
|
|
|
events: {
|
2011-05-03 12:50:03 -05:00
|
|
|
'click #timeline .drop-menu-items a': 'selectTimeline'
|
2011-04-27 14:11:54 -05:00
|
|
|
},
|
|
|
|
|
|
|
|
initialize: function() {
|
2011-05-03 12:50:03 -05:00
|
|
|
|
|
|
|
_.bindAll(this, 'initializeViews', 'loadInitialData');
|
|
|
|
|
|
|
|
appThis = this;
|
|
|
|
|
|
|
|
// create the login dialog
|
|
|
|
this.loginDialog = new TS.LoginView
|
|
|
|
|
|
|
|
if (window.bootstrap) { this.initializeData(window.bootstrap()) }
|
|
|
|
else {
|
|
|
|
// this is async (waiting for user input)
|
|
|
|
this.loginDialog.authenticate(function() {
|
|
|
|
appThis.initializeData(appThis.loadInitialData())});
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
initializeData: function(data) {
|
|
|
|
|
|
|
|
// create user data
|
|
|
|
this.user = {};
|
|
|
|
this.user.model = new TS.UserModel(data.user);
|
|
|
|
this.user.view = new TS.UserView({model: this.user.model});
|
|
|
|
|
|
|
|
// create timeline models from the bootstrapped data
|
|
|
|
var tlModels = _.map(data.timelines, function(timeline) {
|
|
|
|
return new TS.TimelineModel(timeline);
|
|
|
|
});
|
|
|
|
|
|
|
|
// create the timeline list collection
|
|
|
|
this.timelines = {};
|
|
|
|
this.timelines.collection = new TS.TimelineList(
|
|
|
|
tlModels, {user: this.user.model});
|
|
|
|
this.timelines.view = new TS.TimelineListView(
|
|
|
|
{collection: this.timelines.collection,
|
|
|
|
initialTimelineId: data.initialTimelineId});
|
|
|
|
|
|
|
|
// create entry models from the bootstrapped data
|
|
|
|
var entryModels = _.map(data.entries, function(entry) {
|
|
|
|
return new TS.EntryModel(entry);
|
|
|
|
});
|
|
|
|
|
|
|
|
// create the entry collection
|
|
|
|
this.entries = {};
|
|
|
|
this.entries.collection = new TS.EntryList(entryModels,
|
|
|
|
{timeline: this.timelines.view.selected});
|
|
|
|
this.entries.view = new TS.EntryListView(
|
|
|
|
{collection: this.entries.collection});
|
|
|
|
|
|
|
|
// render views
|
|
|
|
this.user.view.render();
|
|
|
|
this.timelines.view.render();
|
|
|
|
this.entries.view.render();
|
|
|
|
|
|
|
|
|
2011-04-27 14:11:54 -05:00
|
|
|
},
|
|
|
|
|
2011-05-03 12:50:03 -05:00
|
|
|
loadInitialData: function() {
|
|
|
|
// assume we are authenticated
|
|
|
|
|
2011-05-06 17:45:56 -05:00
|
|
|
var username = $("#username-input").val(); // hackish
|
2011-05-03 12:50:03 -05:00
|
|
|
var data = jQuery.parseJSON($.ajax({
|
|
|
|
url: '/ts_api/app/user_summary/' + username,
|
|
|
|
async: false}).responseText);
|
|
|
|
|
|
|
|
data.initialTimelineId = data.timelines[0].id;
|
|
|
|
data.entries = jQuery.parseJSON($.ajax({
|
|
|
|
url: '/ts_api/entries/' + username + '/' +
|
|
|
|
data.initialTimelineId,
|
|
|
|
async: false}).responseText);
|
|
|
|
|
|
|
|
return data;
|
2011-04-27 14:11:54 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
});
|
|
|
|
|
2011-05-03 12:50:03 -05:00
|
|
|
TS.LoginView = Backbone.View.extend({
|
2011-05-06 17:45:56 -05:00
|
|
|
el: $("#login"),
|
|
|
|
|
|
|
|
events: {
|
|
|
|
"keypress #password-input" : "loginOnEnter",
|
|
|
|
"click #login-button a" : "doLogin"
|
|
|
|
},
|
2011-04-27 14:11:54 -05:00
|
|
|
|
2011-05-03 12:50:03 -05:00
|
|
|
initialize: function() {
|
2011-05-06 17:45:56 -05:00
|
|
|
_.bindAll(this, 'authenticate', 'doLogin', 'hide', 'loginOnEnter',
|
|
|
|
'show');
|
2011-05-03 12:50:03 -05:00
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
action: function() {},
|
2011-03-08 18:02:33 -06:00
|
|
|
|
2011-05-03 12:50:03 -05:00
|
|
|
authenticate: function(nextAction) {
|
|
|
|
this.action = nextAction;
|
2011-05-06 17:45:56 -05:00
|
|
|
this.show();
|
2011-04-15 13:26:55 -05:00
|
|
|
},
|
2011-03-07 16:43:40 -06:00
|
|
|
|
2011-05-03 12:50:03 -05:00
|
|
|
doLogin: function(){
|
|
|
|
var viewThis = this;
|
2011-05-06 17:45:56 -05:00
|
|
|
var name = this.$("#username-input");
|
|
|
|
var pwd = $("#password-input");
|
2011-05-03 12:50:03 -05:00
|
|
|
|
|
|
|
// call the API via AJAX
|
|
|
|
$.ajax({
|
|
|
|
url: "/ts_api/login",
|
|
|
|
processData: false,
|
|
|
|
data: JSON.stringify({username: name.val(), password: pwd.val()}),
|
|
|
|
type: "POST",
|
|
|
|
async: false,
|
|
|
|
|
|
|
|
error: function(jqXHR, textStatus, error) {
|
|
|
|
// assuming bad credentials (possible server error or bad request,
|
|
|
|
// we should check that, FIXME
|
|
|
|
var tips = $(".validate-tips");
|
|
|
|
tips.text("Incorrect username/password combination.");
|
|
|
|
tips.slideDown();
|
|
|
|
},
|
|
|
|
|
|
|
|
success: function(data, textStatus, jqXHR) {
|
2011-05-06 17:45:56 -05:00
|
|
|
viewThis.hide();
|
|
|
|
viewThis.action();
|
2011-05-03 12:50:03 -05:00
|
|
|
}
|
|
|
|
});
|
2011-05-06 17:45:56 -05:00
|
|
|
},
|
|
|
|
|
|
|
|
hide: function() { $(this.el).addClass('hidden'); },
|
|
|
|
|
|
|
|
show: function() {
|
|
|
|
$(this.el).removeClass('hidden');
|
|
|
|
this.$("#username-input").focus();
|
|
|
|
},
|
|
|
|
|
|
|
|
loginOnEnter: function(e) {
|
|
|
|
if (e.keyCode == 13) { this.doLogin(); }
|
2011-05-03 12:50:03 -05:00
|
|
|
}
|
|
|
|
});
|
2011-04-20 09:40:54 -05:00
|
|
|
|
2011-05-03 12:50:03 -05:00
|
|
|
TS.app = new TS.AppView;
|
2011-04-20 09:40:54 -05:00
|
|
|
|
2011-05-03 12:50:03 -05:00
|
|
|
})
|
2011-04-20 09:40:54 -05:00
|
|
|
|
2011-05-03 12:50:03 -05:00
|
|
|
function getUTCTimestamp() {
|
|
|
|
var d = new Date();
|
2011-04-20 09:40:54 -05:00
|
|
|
|
2011-05-03 12:50:03 -05:00
|
|
|
function pad(n){return n<10 ? '0'+n : n}
|
2011-04-20 09:40:54 -05:00
|
|
|
|
2011-05-03 12:50:03 -05:00
|
|
|
return d.getUTCFullYear()+'-'
|
|
|
|
+ pad(d.getUTCMonth()+1)+'-'
|
|
|
|
+ pad(d.getUTCDate())+'T'
|
|
|
|
+ pad(d.getUTCHours())+':'
|
|
|
|
+ pad(d.getUTCMinutes())+':'
|
|
|
|
+ pad(d.getUTCSeconds())+'Z';
|
2011-03-07 16:43:40 -06:00
|
|
|
}
|
2011-05-03 12:50:03 -05:00
|
|
|
|