Files
habitica/website/public/js/controllers/rootCtrl.js
sablecliff ebcfa849a2 implemented the object and checking function to retrieve objects from it.
At the moment it is only one instance in the rootCtrl.js file but once shown to work and in the proper setout the change will be propograted.
2015-06-25 11:46:19 +10:00

330 lines
14 KiB
JavaScript

"use strict";
/* Make user and settings available for everyone through root scope.
*/
habitrpg.controller("RootCtrl", ['$scope', '$rootScope', '$location', 'User', '$http', '$state', '$stateParams', 'Notification', 'Groups', 'Shared', 'Content', '$modal', '$timeout', 'ApiUrl', 'Payments','$sce','$window','Analytics',
function($scope, $rootScope, $location, User, $http, $state, $stateParams, Notification, Groups, Shared, Content, $modal, $timeout, ApiUrl, Payments, $sce, $window, Analytics) {
var user = User.user;
var initSticky = _.once(function(){
if (window.env.IS_MOBILE || User.user.preferences.stickyHeader === false) return;
$('.header-wrap').sticky({topSpacing:0});
})
$rootScope.$on('userUpdated',initSticky);
$rootScope.$on('$stateChangeSuccess',
function(event, toState, toParams, fromState, fromParams){
if (!!fromState.name) Analytics.track({'hitType':'pageview','eventCategory':'navigation','eventAction':'navigate','page':'/#/'+toState.name});
// clear inbox when entering or exiting inbox tab
if (fromState.name=='options.social.inbox' || toState.name=='options.social.inbox') {
User.user.ops.update && User.set({'inbox.newMessages':0});
}
});
$rootScope.User = User;
$rootScope.user = user;
$rootScope.moment = window.moment;
$rootScope._ = window._;
$rootScope.settings = User.settings;
$rootScope.Shared = Shared;
$rootScope.Content = Content;
$rootScope.Analytics = Analytics;
$rootScope.env = window.env;
$rootScope.Math = Math;
$rootScope.Groups = Groups;
$rootScope.toJson = angular.toJson;
$rootScope.Payments = Payments;
// Angular UI Router
$rootScope.$state = $state;
$rootScope.$stateParams = $stateParams;
// indexOf helper
$scope.indexOf = function(haystack, needle){
return haystack && ~haystack.indexOf(needle);
}
// styling helpers
$scope.userLevelStyle = function(user,style){
style = style || '';
var npc = (user && user.backer && user.backer.npc) ? user.backer.npc : '';
var level = (user && user.contributor && user.contributor.level) ? user.contributor.level : '';
style += $scope.userLevelStyleFromLevel(level,npc,style)
return style;
}
$scope.userAdminGlyphiconStyle = function(user,style){
style = style || '';
if(user && user.contributor && user.contributor.level)
style += $scope.userAdminGlyphiconStyleFromLevel(user.contributor.level,style)
return style;
}
$scope.userLevelStyleFromLevel = function(level,npc,style){
style = style || '';
if(npc)
style += ' label-npc';
if(level)
style += ' label-contributor-'+level;
return style;
}
$scope.userAdminGlyphiconStyleFromLevel = function(level,style){
style = style || '';
if(level)
if(level==8)
style += ' glyphicon glyphicon-star'; // moderator
if(level==9)
style += ' glyphicon icon-crown'; // staff
return style;
}
$rootScope.playSound = function(id){
if (!user.preferences.sound || user.preferences.sound == 'off') return;
var theme = user.preferences.sound;
var file = 'common/audio/' + theme + '/' + id;
document.getElementById('oggSource').src = file + '.ogg';
document.getElementById('mp3Source').src = file + '.mp3';
document.getElementById('sound').load();
}
// count pets, mounts collected totals, etc
$rootScope.countExists = function(items) {return _.reduce(items,function(m,v){return m+(v?1:0)},0)}
$rootScope.petCount = Shared.countPets($rootScope.countExists(User.user.items.pets), User.user.items.pets);
$rootScope.mountCount = Shared.countMounts($rootScope.countExists(User.user.items.mounts), User.user.items.mounts);
$scope.safeApply = function(fn) {
var phase = this.$root.$$phase;
if(phase == '$apply' || phase == '$digest') {
if(fn && (typeof(fn) === 'function')) {
fn();
}
} else {
this.$apply(fn);
}
};
$rootScope.set = User.set;
$rootScope.authenticated = User.authenticated;
var forceLoadBailey = function(template, options) {
$http.get('/new-stuff.html')
.success(function(data) {
$rootScope.latestBaileyMessage = $sce.trustAsHtml(data);
$modal.open({
templateUrl: 'modals/' + template + '.html',
controller: options.controller, // optional
scope: options.scope, // optional
resolve: options.resolve, // optional
keyboard: (options.keyboard === undefined ? true : options.keyboard), // optional
backdrop: (options.backdrop === undefined ? true : options.backdrop), // optional
size: options.size, // optional, 'sm' or 'lg'
windowClass: options.windowClass // optional
});
});
};
// Open a modal from a template expression (like ng-click,...)
// Otherwise use the proper $modal.open
$rootScope.openModal = function(template, options){//controller, scope, keyboard, backdrop){
if (!options) options = {};
if (options.track) Analytics.track(_.merge(options.track,{'hitType':'event','eventCategory':'button','eventAction':'click'}));
if(template === 'newStuff') return forceLoadBailey(template, options);
return $modal.open({
templateUrl: 'modals/' + template + '.html',
controller: options.controller, // optional
scope: options.scope, // optional
resolve: options.resolve, // optional
keyboard: (options.keyboard === undefined ? true : options.keyboard), // optional
backdrop: (options.backdrop === undefined ? true : options.backdrop), // optional
size: options.size, // optional, 'sm' or 'lg'
windowClass: options.windowClass // optional
});
}
$rootScope.dismissAlert = function() {
$rootScope.set({'flags.newStuff':false});
}
$rootScope.acceptCommunityGuidelines = function() {
$rootScope.set({'flags.communityGuidelinesAccepted':true});
}
$rootScope.notPorted = function(){
alert(window.env.t('notPorted'));
}
$rootScope.dismissErrorOrWarning = function(type, $index){
$rootScope.flash[type].splice($index, 1);
}
$scope.contribText = function(contrib, backer){
if (!contrib && !backer) return;
if (backer && backer.npc) return backer.npc;
var l = contrib && contrib.level;
if (l && l > 0) {
var level = (l < 3) ? window.env.t('friend') : (l < 5) ? window.env.t('elite') : (l < 7) ? window.env.t('champion') : (l < 8) ? window.env.t('legendary') : (l < 9) ? window.env.t('guardian') : window.env.t('heroic');
return level + ' ' + contrib.text;
}
}
$rootScope.charts = {};
$rootScope.toggleChart = function(id, task) {
var history = [], matrix, data, chart, options;
switch (id) {
case 'exp':
history = User.user.history.exp;
$rootScope.charts.exp = (history.length == 0) ? false : !$rootScope.charts.exp;
break;
case 'todos':
history = User.user.history.todos;
$rootScope.charts.todos = (history.length == 0) ? false : !$rootScope.charts.todos;
break;
default:
history = task.history;
$rootScope.charts[id] = (history.length == 0) ? false : !$rootScope.charts[id];
if (task && task._editing) task._editing = false;
}
matrix = [[env.t('date'), env.t('score')]];
_.each(history, function(obj) {
matrix.push([moment(obj.date).format(User.user.preferences.dateFormat.toUpperCase().replace('YYYY','YY') ), obj.value]);
});
data = google.visualization.arrayToDataTable(matrix);
options = {
title: window.env.t('history'),
backgroundColor: {
fill: 'transparent'
},
hAxis: {slantedText:true, slantedTextAngle: 90},
height:270,
width:300
};
chart = new google.visualization.LineChart($("." + id + "-chart")[0]);
chart.draw(data, options);
};
$rootScope.getGearArray = function(set){
var flatGearArray = _.toArray(Content.gear.flat);
var filteredArray = _.where(flatGearArray, {gearSet: set});
return filteredArray;
}
$rootScope.purchase = function(type, item){
if (type == 'special') return User.user.ops.buySpecialSpell({params:{key:item.key}});
var gems = User.user.balance * 4;
var equipmentList = {
'weapon': window.env.t('weapon'),
'armor' : window.env.t('armor'),
'head' : window.env.t('headgear'),
'shield' : window.env.t('offhand'),
'back' : window.env.t('back'),
'body' : window.env.t('body'),
'headAccessory' : window.env.t('headAccessory'),
'eyewear' : window.env.t('eyewear'),
'hatchingPotions' : window.env.t('hatchingPotion'),
'eggs' : window.env.t('eggSingular'),
'quests' : window.env.t('quest'),
'Saddle' : window.env.t('foodSaddleText').toLowerCase()
};
var string = (type in equipmentList) ? string = equipmentList.type : string = type;
// var string = (type == 'weapon') ? window.env.t('weapon') : (type == 'armor') ? window.env.t('armor') : (type == 'head') ? window.env.t('headgear') : (type == 'shield') ? window.env.t('offhand') : (type == 'back') ? window.env.t('back') : (type == 'body') ? window.env.t('body') : (type == 'headAccessory') ? window.env.t('headAccessory') : (type == 'eyewear') ? window.env.t('eyewear') : (type == 'hatchingPotions') ? window.env.t('hatchingPotion') : (type == 'eggs') ? window.env.t('eggSingular') : (type == 'quests') ? window.env.t('quest') : (item.key == 'Saddle') ? window.env.t('foodSaddleText').toLowerCase() : type; // FIXME this is ugly but temporary, once the purchase modal is done this will be removed
var price = ((((item.specialClass == "wizard") && (item.type == "weapon")) || item.gearSet == "animal") + 1);
if (type == 'weapon' || type == 'armor' || type == 'head' || type == 'shield' || type == 'headAccessory' || type == 'body' || type == 'back' || type == 'eyewear' ) {
if (User.user.items.gear.owned[item.key]) {
if (User.user.preferences.costume) return User.user.ops.equip({params:{type: 'costume', key: item.key}});
else {
return User.user.ops.equip({params:{type: 'equipped', key: item.key}})
}
}
if (gems < price) return $rootScope.openModal('buyGems');
var message = window.env.t('buyThis', {text: string, price: price, gems: gems})
if($window.confirm(message))
User.user.ops.purchase({params:{type:"gear",key:item.key}});
} else {
if(gems < item.value) return $rootScope.openModal('buyGems');
var message = window.env.t('buyThis', {text: string, price: item.value, gems: gems})
if($window.confirm(message))
User.user.ops.purchase({params:{type:type,key:item.key}});
}
}
/*
------------------------
Spells
------------------------
*/
$scope.castStart = function(spell) {
if (User.user.stats.mp < spell.mana) return Notification.text(window.env.t('notEnoughMana'));
if (spell.immediateUse && User.user.stats.gp < spell.value)
return Notification.text('Not enough gold.');
$rootScope.applyingAction = true;
$scope.spell = spell;
if (spell.target == 'self') {
$scope.castEnd(null, 'self');
} else if (spell.target == 'party') {
var party = Groups.party();
party = (_.isArray(party) ? party : []).concat(User.user);
$scope.castEnd(party, 'party');
}
}
$scope.castEnd = function(target, type, $event){
if (!$rootScope.applyingAction) return 'No applying action';
$event && ($event.stopPropagation(),$event.preventDefault());
if ($scope.spell.target != type) return Notification.text(window.env.t('invalidTarget'));
$scope.spell.cast(User.user, target);
User.save();
var spell = $scope.spell;
var targetId = (type == 'party' || type == 'self') ? '' : type == 'task' ? target.id : target._id;
$scope.spell = null;
$rootScope.applyingAction = false;
$http.post(ApiUrl.get() + '/api/v2/user/class/cast/'+spell.key+'?targetType='+type+'&targetId='+targetId)
.success(function(){
var msg = window.env.t('youCast', {spell: spell.text()});
switch (type) {
case 'task': msg = window.env.t('youCastTarget', {spell: spell.text(), target: target.text});break;
case 'user': msg = window.env.t('youCastTarget', {spell: spell.text(), target: target.profile.name});break;
case 'party': msg = window.env.t('youCastParty', {spell: spell.text()});break;
}
Notification.markdown(msg);
User.sync();
});
}
$rootScope.castCancel = function(){
$rootScope.applyingAction = false;
$scope.spell = null;
}
// Because our angular-ui-router uses anchors for urls (/#/options/groups/party), window.location.href=... won't
// reload the page. Perform manually.
$rootScope.hardRedirect = function(url){
window.location.href = url;
setTimeout(function() {
window.location.reload(false);
});
}
// Universal method for sending HTTP methods
$rootScope.http = function(method, route, data, alertMsg){
$http[method](ApiUrl.get() + route, data).success(function(){
if (alertMsg) Notification.text(window.env.t(alertMsg));
User.sync();
});
// error will be handled via $http interceptor
}
}
]);