305 lines
10 KiB
JavaScript
305 lines
10 KiB
JavaScript
// Generated by CoffeeScript 1.6.3
|
|
(function() {
|
|
var amazonAffiliate, googleAnalytics, googleCharts, growlNotification, initStickyHeader, loadJavaScripts, moment, setupGrowlNotifications, setupSortable, setupTooltips, setupTour, _;
|
|
|
|
_ = require('lodash');
|
|
|
|
moment = require('moment');
|
|
|
|
/*
|
|
Loads JavaScript files from public/vendor/*
|
|
Use require() to min / concatinate for faster page load
|
|
*/
|
|
|
|
|
|
loadJavaScripts = function(model) {
|
|
/*
|
|
Internal Scripts
|
|
*/
|
|
|
|
require("../vendor/jquery-ui-1.10.2/jquery-1.9.1.js");
|
|
require("../vendor/jquery.cookie.min.js");
|
|
require("../vendor/bootstrap/js/bootstrap.min.js");
|
|
require("../vendor/jquery.bootstrap-growl.min.js");
|
|
require("../vendor/datepicker/js/bootstrap-datepicker");
|
|
require("../vendor/bootstrap-tour/bootstrap-tour");
|
|
if (!(model.get('_mobileDevice') === true)) {
|
|
require("../vendor/jquery-ui-1.10.2/ui/jquery.ui.core.js");
|
|
require("../vendor/jquery-ui-1.10.2/ui/jquery.ui.widget.js");
|
|
require("../vendor/jquery-ui-1.10.2/ui/jquery.ui.mouse.js");
|
|
require("../vendor/jquery-ui-1.10.2/ui/jquery.ui.sortable.js");
|
|
return require("../vendor/sticky");
|
|
}
|
|
};
|
|
|
|
/*
|
|
Setup jQuery UI Sortable
|
|
*/
|
|
|
|
|
|
setupSortable = function(model) {
|
|
if (!(model.get('_mobileDevice') === true)) {
|
|
return ['habit', 'daily', 'todo', 'reward'].forEach(function(type) {
|
|
return $("ul." + type + "s").sortable({
|
|
dropOnEmpty: false,
|
|
cursor: "move",
|
|
items: "li",
|
|
scroll: true,
|
|
axis: 'y',
|
|
update: function(e, ui) {
|
|
var domId, id, item, to;
|
|
item = ui.item[0];
|
|
domId = item.id;
|
|
id = item.getAttribute('data-id');
|
|
to = $("ul." + type + "s").children().index(item);
|
|
return model.at("_" + type + "List").pass({
|
|
ignore: domId
|
|
}).move({
|
|
id: id
|
|
}, to);
|
|
}
|
|
});
|
|
});
|
|
}
|
|
};
|
|
|
|
setupTooltips = module.exports.setupTooltips = function() {
|
|
$('[rel=tooltip]').tooltip();
|
|
$('[rel=popover]').popover();
|
|
$('.popover-auto-show').popover('show');
|
|
return $('.priority-multiplier-help').popover({
|
|
title: "How difficult is this task?",
|
|
trigger: "hover",
|
|
content: "This multiplies its point value. Use sparingly, rely instead on our organic value-adjustment algorithms. But some tasks are grossly more valuable (Write Thesis vs Floss Teeth). Click for more info."
|
|
});
|
|
};
|
|
|
|
setupTour = function(model) {
|
|
var tour, tourSteps;
|
|
tourSteps = [
|
|
{
|
|
element: ".main-herobox",
|
|
title: "Welcome to HabitRPG",
|
|
content: "Welcome to HabitRPG, a habit-tracker which treats your goals like a Role Playing Game."
|
|
}, {
|
|
element: "#bars",
|
|
title: "Achieve goals and level up",
|
|
content: "As you accomplish goals, you level up. If you fail your goals, you lose hit points. Lose all your HP and you die."
|
|
}, {
|
|
element: "ul.habits",
|
|
title: "Habits",
|
|
content: "Habits are goals that you constantly track.",
|
|
placement: "bottom"
|
|
}, {
|
|
element: "ul.dailys",
|
|
title: "Dailies",
|
|
content: "Dailies are goals that you want to complete once a day.",
|
|
placement: "bottom"
|
|
}, {
|
|
element: "ul.todos",
|
|
title: "Todos",
|
|
content: "Todos are one-off goals which need to be completed eventually.",
|
|
placement: "bottom"
|
|
}, {
|
|
element: "ul.rewards",
|
|
title: "Rewards",
|
|
content: "As you complete goals, you earn gold to buy rewards. Buy them liberally - rewards are integral in forming good habits.",
|
|
placement: "bottom"
|
|
}, {
|
|
element: "ul.habits li:first-child",
|
|
title: "Hover over comments",
|
|
content: "Different task-types have special properties. Hover over each task's comment for more information. When you're ready to get started, delete the existing tasks and add your own.",
|
|
placement: "right"
|
|
}
|
|
];
|
|
$('.main-herobox').popover('destroy');
|
|
tour = new Tour();
|
|
tourSteps.forEach(function(step) {
|
|
return tour.addStep(_.defaults(step, {
|
|
html: true
|
|
}));
|
|
});
|
|
if (isNaN(tour._current)) {
|
|
tour._current = 0;
|
|
}
|
|
return tour.start();
|
|
};
|
|
|
|
initStickyHeader = function(model) {
|
|
return $('.header-wrap').sticky({
|
|
topSpacing: 0
|
|
});
|
|
};
|
|
|
|
growlNotification = module.exports.growlNotification = function(html, type) {
|
|
return $.bootstrapGrowl(html, {
|
|
ele: '#notification-area',
|
|
type: type,
|
|
top_offset: 20,
|
|
align: 'right',
|
|
width: 250,
|
|
delay: 3000,
|
|
allow_dismiss: true,
|
|
stackup_spacing: 10
|
|
});
|
|
};
|
|
|
|
/*
|
|
Sets up "+1 Exp", "Level Up", etc notifications
|
|
*/
|
|
|
|
|
|
setupGrowlNotifications = function(model) {
|
|
var showCoins, statsNotification, user;
|
|
if (typeof jQuery === "undefined" || jQuery === null) {
|
|
return;
|
|
}
|
|
user = model.at('_user');
|
|
statsNotification = function(html, type) {
|
|
if (user.get('stats.lvl') === 0) {
|
|
return;
|
|
}
|
|
return growlNotification(html, type);
|
|
};
|
|
user.on('set', 'stats.hp', function(captures, args) {
|
|
var num, rounded;
|
|
num = captures - args;
|
|
rounded = Math.abs(num.toFixed(1));
|
|
if (num < 0) {
|
|
return statsNotification("<i class='icon-heart'></i> - " + rounded + " HP", 'hp');
|
|
} else if (num > 0) {
|
|
return statsNotification("<i class='icon-heart'></i> + " + rounded + " HP", 'hp');
|
|
}
|
|
});
|
|
user.on('set', 'stats.exp', function(captures, args, isLocal, silent) {
|
|
var num, rounded;
|
|
if (silent == null) {
|
|
silent = false;
|
|
}
|
|
num = captures - args;
|
|
rounded = Math.abs(num.toFixed(1));
|
|
if (num < 0 && num > -50) {
|
|
return statsNotification("<i class='icon-star'></i> - " + rounded + " XP", 'xp');
|
|
} else if (num > 0) {
|
|
return statsNotification("<i class='icon-star'></i> + " + rounded + " XP", 'xp');
|
|
}
|
|
});
|
|
/*
|
|
Show "+ 5 {gold_coin} 3 {silver_coin}"
|
|
*/
|
|
|
|
showCoins = function(money) {
|
|
var absolute, gold, silver;
|
|
absolute = Math.abs(money);
|
|
gold = Math.floor(absolute);
|
|
silver = Math.floor((absolute - gold) * 100);
|
|
if (gold && silver > 0) {
|
|
return "" + gold + " <i class='icon-gold'></i> " + silver + " <i class='icon-silver'></i>";
|
|
} else if (gold > 0) {
|
|
return "" + gold + " <i class='icon-gold'></i>";
|
|
} else if (silver > 0) {
|
|
return "" + silver + " <i class='icon-silver'></i>";
|
|
}
|
|
};
|
|
user.on('set', 'stats.gp', function(captures, args) {
|
|
var bonus, money, sign;
|
|
money = captures - args;
|
|
if (!money) {
|
|
return;
|
|
}
|
|
sign = money < 0 ? '-' : '+';
|
|
statsNotification("" + sign + " " + (showCoins(money)), 'gp');
|
|
bonus = model.get('_streakBonus');
|
|
if ((money > 0) && !!bonus) {
|
|
if (bonus < 0.01) {
|
|
bonus = 0.01;
|
|
}
|
|
statsNotification("+ " + (showCoins(bonus)) + " Streak Bonus!");
|
|
return model.del('_streakBonus');
|
|
}
|
|
});
|
|
user.on('set', 'items.*', function(item, after, before) {
|
|
if ((item === 'armor' || item === 'weapon' || item === 'shield' || item === 'head') && parseInt(after) < parseInt(before)) {
|
|
if (item === 'head') {
|
|
item = 'helm';
|
|
}
|
|
return statsNotification("<i class='icon-death'></i> Respawn!", "death");
|
|
}
|
|
});
|
|
return user.on('set', 'stats.lvl', function(captures, args) {
|
|
if (captures > args) {
|
|
return statsNotification('<i class="icon-chevron-up"></i> Level Up!', 'lvl');
|
|
}
|
|
});
|
|
};
|
|
|
|
module.exports.resetDom = function(model) {
|
|
window.DERBY.app.dom.clear();
|
|
return window.DERBY.app.view.render(model, window.DERBY.app.view._lastRender.ns, window.DERBY.app.view._lastRender.context);
|
|
};
|
|
|
|
googleAnalytics = function(model) {
|
|
if (model.flags.nodeEnv === 'production') {
|
|
window._gaq = [["_setAccount", "UA-33510635-1"], ["_setDomainName", "habitrpg.com"], ["_trackPageview"]];
|
|
return $.getScript(("https:" === document.location.protocol ? "https://ssl" : "http://www") + ".google-analytics.com/ga.js");
|
|
}
|
|
};
|
|
|
|
amazonAffiliate = function(model) {
|
|
if (model.get('_loggedIn') && (model.get('_user.flags.ads') !== 'hide')) {
|
|
return $.getScript('//wms.assoc-amazon.com/20070822/US/js/link-enhancer-common.js?tag=ha0d2-20').fail(function() {
|
|
return $('body').append('<img src="//wms.assoc-amazon.com/20070822/US/img/noscript.gif?tag=ha0d2-20" alt="" />');
|
|
});
|
|
}
|
|
};
|
|
|
|
googleCharts = function() {
|
|
return $.getScript("//www.google.com/jsapi", function() {
|
|
return google.load("visualization", "1", {
|
|
packages: ["corechart"],
|
|
callback: function() {}
|
|
});
|
|
});
|
|
};
|
|
|
|
module.exports.app = function(appExports, model, app) {
|
|
loadJavaScripts(model);
|
|
if (!model.get('_mobileDevice')) {
|
|
setupGrowlNotifications(model);
|
|
}
|
|
return app.on('render', function(ctx) {
|
|
if (!model.get('_mobileDevice')) {
|
|
setupTooltips(model);
|
|
initStickyHeader(model);
|
|
setupSortable(model);
|
|
setupTour(model);
|
|
}
|
|
$('.datepicker').datepicker({
|
|
autoclose: true,
|
|
todayBtn: true
|
|
}).on('changeDate', function(ev) {
|
|
return model.at(ev.target).set('date', moment(ev.date).format('MM/DD/YYYY'));
|
|
});
|
|
/*
|
|
External Scripts
|
|
JS files not needed right away (google charts) or entirely optional (analytics)
|
|
Each file getsload asyncronously via $.getScript, so it doesn't bog page-load
|
|
These need to be handled in app.on('render'), see https://groups.google.com/forum/?fromgroups=#!topic/derbyjs/x8FwdTLEuXo
|
|
*/
|
|
|
|
$.getScript('//checkout.stripe.com/v2/checkout.js');
|
|
if (!(model.get('_mobileDevice') === true)) {
|
|
$.getScript("//s7.addthis.com/js/250/addthis_widget.js#pubid=lefnire");
|
|
googleCharts();
|
|
}
|
|
googleAnalytics(model);
|
|
return amazonAffiliate(model);
|
|
});
|
|
};
|
|
|
|
}).call(this);
|
|
|
|
/*
|
|
//@ sourceMappingURL=browser.map
|
|
*/
|