Work on day separators.
* Overrode ``EntryModel.{get,set}`` to return a ``Date`` object and allow you to set the value with either a ``Date`` object, or the JSON date string. * Updated code to reflect the ``EntryModel.timestamp`` data change. * Added ``daysApart`` to calculate calendar days between given ``Date``s * Added ``getEnglishDate`` to return a date description relative to the current day ("Today", "Last year" for example).
This commit is contained in:
parent
1fff94b622
commit
81503112a8
113
www/js/ts.js
113
www/js/ts.js
@ -11,10 +11,40 @@ $(document).ready(function(){
|
|||||||
* - id
|
* - id
|
||||||
* - mark
|
* - mark
|
||||||
* - notes
|
* - notes
|
||||||
* - start
|
* - timestamp
|
||||||
*/
|
*/
|
||||||
TS.EntryModel = Backbone.Model.extend({
|
TS.EntryModel = Backbone.Model.extend({
|
||||||
|
|
||||||
|
get: function(attribute) {
|
||||||
|
if (attribute == "timestamp") {
|
||||||
|
if (!this.timestampDate) {
|
||||||
|
this.timestampDate = new Date(
|
||||||
|
Backbone.Model.prototype.get.call(this, attribute));
|
||||||
|
}
|
||||||
|
return this.timestampDate;
|
||||||
|
} else {
|
||||||
|
return Backbone.Model.prototype.get.call(this, attribute);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
set: function(attributes, options) {
|
||||||
|
var attrsToSet = {}
|
||||||
|
_.each(attributes, function(val, key) {
|
||||||
|
if (key == "timestamp") {
|
||||||
|
if (val instanceof Date) {
|
||||||
|
this.timestampDate = val;
|
||||||
|
attrsToSet.timestamp = dateToJSON(val);
|
||||||
|
} else {
|
||||||
|
this.timestampDate = new Date(val);
|
||||||
|
attrsToSet.timestamp = dateToJSON(this.timestampDate);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
attrsToSet[key] = val;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return Backbone.Model.prototype.set.call(this, attrsToSet, options);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
/* Timeline model.
|
/* Timeline model.
|
||||||
@ -207,7 +237,7 @@ $(document).ready(function(){
|
|||||||
save: function() {
|
save: function() {
|
||||||
this.model.save({
|
this.model.save({
|
||||||
mark: this.$('.mark-input').val(),
|
mark: this.$('.mark-input').val(),
|
||||||
timestamp: this.$('.timestamp-input').val(),
|
timestamp: new Date(this.$('.timestamp-input').val()),
|
||||||
notes: this.$('.notes-input').val()});
|
notes: this.$('.notes-input').val()});
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -250,12 +280,12 @@ $(document).ready(function(){
|
|||||||
* @return the duration between model and nextModel, formatted for
|
* @return the duration between model and nextModel, formatted for
|
||||||
* display: `Xd Yhr Zm`. */
|
* display: `Xd Yhr Zm`. */
|
||||||
formatDuration: function(model, nextModel) {
|
formatDuration: function(model, nextModel) {
|
||||||
var d1 = new Date(model.get('timestamp'));
|
var d1 = model.get('timestamp');
|
||||||
var d2, diff;
|
var d2, diff;
|
||||||
var day, hr, min;
|
var day, hr, min;
|
||||||
|
|
||||||
// if no next model, assume it's an onoing task
|
// if no next model, assume it's an onoing task
|
||||||
if (nextModel) { d2 = new Date(nextModel.get('timestamp')); }
|
if (nextModel) { d2 = nextModel.get('timestamp'); }
|
||||||
else { d2 = new Date(); }
|
else { d2 = new Date(); }
|
||||||
|
|
||||||
diff= d2.getTime() - d1.getTime();
|
diff= d2.getTime() - d1.getTime();
|
||||||
@ -345,7 +375,7 @@ $(document).ready(function(){
|
|||||||
// create the mark. Immediately fetch to get server-side timestamp
|
// create the mark. Immediately fetch to get server-side timestamp
|
||||||
this.collection.create({mark: entryMark,
|
this.collection.create({mark: entryMark,
|
||||||
notes: '',
|
notes: '',
|
||||||
timestamp: getUTCTimestamp()}).fetch();
|
timestamp: new Date()}).fetch();
|
||||||
|
|
||||||
// clear the input for the next entry
|
// clear the input for the next entry
|
||||||
this.$("#new-entry-input").val("");
|
this.$("#new-entry-input").val("");
|
||||||
@ -367,11 +397,23 @@ $(document).ready(function(){
|
|||||||
userExclusions.concat(timelineExclusions),
|
userExclusions.concat(timelineExclusions),
|
||||||
function(exclusion) { return new RegExp(exclusion)} );
|
function(exclusion) { return new RegExp(exclusion)} );
|
||||||
|
|
||||||
|
// clear existing elements in the view container
|
||||||
this.entryContainer.empty();
|
this.entryContainer.empty();
|
||||||
|
|
||||||
|
// last day we have printed a separator for
|
||||||
|
var currentDay = null;
|
||||||
|
var today = new Date();
|
||||||
|
|
||||||
|
// iterate through the collection and render the elements.
|
||||||
for (var i = 0, len = this.collection.length; i < len; i++) {
|
for (var i = 0, len = this.collection.length; i < len; i++) {
|
||||||
var entry = this.collection.at(i);
|
var entry = this.collection.at(i);
|
||||||
var nextEntry = (i + 1 < len ? this.collection.at(i + 1) : null);
|
var nextEntry = (i + 1 < len ? this.collection.at(i + 1) : null);
|
||||||
|
|
||||||
|
if (currentDay != entry.get('timestamp').getDate()) {
|
||||||
|
currentDay = entry.get('timestamp').getDate();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
this.renderOne(entry, nextEntry);
|
this.renderOne(entry, nextEntry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -687,7 +729,7 @@ $(document).ready(function(){
|
|||||||
var timelineDesc = this.$("#new-timeline-desc").val();
|
var timelineDesc = this.$("#new-timeline-desc").val();
|
||||||
this.timelineCollection.create(
|
this.timelineCollection.create(
|
||||||
{id: timelineId, description: timelineDesc,
|
{id: timelineId, description: timelineDesc,
|
||||||
created: getUTCTimestamp()});
|
created: dateToJSON(new Date())});
|
||||||
this.hide();
|
this.hide();
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -705,9 +747,7 @@ $(document).ready(function(){
|
|||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
function getUTCTimestamp() {
|
function dateToJSON(d) {
|
||||||
var d = new Date();
|
|
||||||
|
|
||||||
function pad(n){return n<10 ? '0'+n : n}
|
function pad(n){return n<10 ? '0'+n : n}
|
||||||
|
|
||||||
return d.getUTCFullYear()+'-'
|
return d.getUTCFullYear()+'-'
|
||||||
@ -718,3 +758,58 @@ function getUTCTimestamp() {
|
|||||||
+ pad(d.getUTCSeconds())+'Z';
|
+ pad(d.getUTCSeconds())+'Z';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function daysApart(d1, d2) {
|
||||||
|
var daysInMonth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30];
|
||||||
|
|
||||||
|
days1 = (d1.getFullYear() * 365) + daysInMonth[d1.getMonth()] + d1.getDate();
|
||||||
|
days2 = (d2.getFullYear() * 365) + daysInMonth[d2.getMonth()] + d2.getDate();
|
||||||
|
|
||||||
|
return days1 - days2;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getEnglishDate(d) {
|
||||||
|
if (typeof getEnglishDate.today == 'undefined') {
|
||||||
|
getEnglishDate.today = new Date() };
|
||||||
|
|
||||||
|
var yearDiff = today.getFullYear() - d.getFullYear();
|
||||||
|
var monthDiff = today.getMonth() - d.getMonth();
|
||||||
|
var dayDiff = today.getDate() - d.getDate();
|
||||||
|
|
||||||
|
if (yearDiff > 1) { return capitalize(toWords(yearDiff)) + " years ago."; }
|
||||||
|
else if (yearDiff > 0) { return "Last year"; }
|
||||||
|
else if (monthDiff > 1) {
|
||||||
|
return capitalize(toWords(monthDiff)) + "months ago."; }
|
||||||
|
else if (monthDiff > 0) { return "Last month."; }
|
||||||
|
else if (dayDiff > 0) {
|
||||||
|
// weeks as 7-day periods
|
||||||
|
var weekDiff = Math.ceil(dayDiff / 7)
|
||||||
|
|
||||||
|
// adjust for the hard boundary of the weekend
|
||||||
|
if (today.getDay() > d.getDay()) { weekDiff--; }
|
||||||
|
|
||||||
|
if (weekDiff > 1) {
|
||||||
|
return capitalize(toWords(weekDiff)) + " weeks ago."; }
|
||||||
|
else if (weekDiff > 0) { return "Last week."; }
|
||||||
|
else { return capitalize(toWords(dayDiff)) + " days ago."; }
|
||||||
|
|
||||||
|
} else if (yearDiff < 0 || monthDiff < 0 || daysDiff < 0) {
|
||||||
|
return "In the future."; }
|
||||||
|
else { return "Today."; }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function toWords(i) {
|
||||||
|
if (typeof toWords.words == 'undefined') {
|
||||||
|
toWords.words = ['zero','one','two','three','four', 'five','six',
|
||||||
|
'seven','eight','nine','ten','eleven','twelve',
|
||||||
|
'thirteen', 'fourteen','fifteen','sixteen',
|
||||||
|
'seventeen','eighteen','nineteen' ];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i < 20) { return toWords.words[i]; }
|
||||||
|
else { return i.toString(); }
|
||||||
|
}
|
||||||
|
|
||||||
|
function capitalize(s) {
|
||||||
|
return s.slice(0, 1).toUpperCase() + s.slice(1);
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user