2013-08-27 23:59:53 +00:00
"use strict" ;
/ * M a k e u s e r a n d s e t t i n g s a v a i l a b l e f o r e v e r y o n e t h r o u g h r o o t s c o p e .
* /
2015-05-31 03:00:29 +00:00
habitrpg . controller ( "RootCtrl" , [ '$scope' , '$rootScope' , '$location' , 'User' , '$http' , '$state' , '$stateParams' , 'Notification' , 'Groups' , 'Shared' , 'Content' , '$modal' , '$timeout' , 'ApiUrl' , 'Payments' , '$sce' , '$window' , '$filter' ,
function ( $scope , $rootScope , $location , User , $http , $state , $stateParams , Notification , Groups , Shared , Content , $modal , $timeout , ApiUrl , Payments , $sce , $window , $filter ) {
2013-12-11 16:30:39 +00:00
var user = User . user ;
2013-12-17 20:39:57 +00:00
var initSticky = _ . once ( function ( ) {
2013-12-17 21:04:33 +00:00
if ( window . env . IS _MOBILE || User . user . preferences . stickyHeader === false ) return ;
2013-12-17 20:39:57 +00:00
$ ( '.header-wrap' ) . sticky ( { topSpacing : 0 } ) ;
} )
$rootScope . $on ( 'userUpdated' , initSticky ) ;
2014-02-12 01:11:21 +00:00
$rootScope . $on ( '$stateChangeSuccess' ,
function ( event , toState , toParams , fromState , fromParams ) {
2014-02-12 02:02:20 +00:00
if ( ! ! fromState . name ) window . ga && ga ( 'send' , 'pageview' , { page : '/#/' + toState . name } ) ;
2014-11-27 10:32:57 +00:00
// 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 } ) ;
}
2014-02-12 01:11:21 +00:00
} ) ;
2013-09-06 02:33:31 +00:00
$rootScope . User = User ;
2013-12-11 16:30:39 +00:00
$rootScope . user = user ;
2013-12-15 19:11:25 +00:00
$rootScope . moment = window . moment ;
2013-12-18 06:08:18 +00:00
$rootScope . _ = window . _ ;
2013-09-06 02:33:31 +00:00
$rootScope . settings = User . settings ;
2014-01-12 23:05:15 +00:00
$rootScope . Shared = Shared ;
$rootScope . Content = Content ;
2014-01-24 22:19:17 +00:00
$rootScope . env = window . env ;
2014-02-14 00:57:00 +00:00
$rootScope . Math = Math ;
2014-04-08 15:45:47 +00:00
$rootScope . Groups = Groups ;
2014-07-17 20:09:39 +00:00
$rootScope . toJson = angular . toJson ;
2014-11-30 21:01:58 +00:00
$rootScope . Payments = Payments ;
2013-08-27 23:59:53 +00:00
2013-10-28 05:27:07 +00:00
// Angular UI Router
$rootScope . $state = $state ;
$rootScope . $stateParams = $stateParams ;
2013-10-27 00:23:52 +00:00
// indexOf helper
$scope . indexOf = function ( haystack , needle ) {
2013-10-29 19:26:13 +00:00
return haystack && ~ haystack . indexOf ( needle ) ;
2013-10-27 00:23:52 +00:00
}
2013-11-26 22:56:24 +00:00
// styling helpers
$scope . userLevelStyle = function ( user , style ) {
style = style || '' ;
2014-08-10 04:39:47 +00:00
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 )
2013-11-26 22:56:24 +00:00
return style ;
}
2014-08-09 11:11:14 +00:00
$scope . userAdminGlyphiconStyle = function ( user , style ) {
style = style || '' ;
2013-11-28 06:48:48 +00:00
if ( user && user . contributor && user . contributor . level )
2014-08-10 04:39:47 +00:00
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 )
2014-08-09 11:11:14 +00:00
style += ' glyphicon glyphicon-star' ; // moderator
2014-08-10 04:39:47 +00:00
if ( level == 9 )
2014-08-11 20:38:54 +00:00
style += ' glyphicon icon-crown' ; // staff
2013-11-26 22:56:24 +00:00
return style ;
}
2014-08-08 14:03:52 +00:00
$rootScope . playSound = function ( id ) {
2014-09-05 08:45:52 +00:00
if ( ! user . preferences . sound || user . preferences . sound == 'off' ) return ;
2014-08-16 00:13:59 +00:00
var theme = user . preferences . sound ;
2015-02-17 19:53:32 +00:00
var file = 'common/audio/' + theme + '/' + id ;
2014-08-08 14:03:52 +00:00
document . getElementById ( 'oggSource' ) . src = file + '.ogg' ;
document . getElementById ( 'mp3Source' ) . src = file + '.mp3' ;
document . getElementById ( 'sound' ) . load ( ) ;
}
2013-11-16 01:50:41 +00:00
// count pets, mounts collected totals, etc
$rootScope . countExists = function ( items ) { return _ . reduce ( items , function ( m , v ) { return m + ( v ? 1 : 0 ) } , 0 ) }
2015-01-12 00:23:27 +00:00
$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 ) ;
2013-11-23 16:42:47 +00:00
2013-09-06 02:33:31 +00:00
$scope . safeApply = function ( fn ) {
var phase = this . $root . $$phase ;
if ( phase == '$apply' || phase == '$digest' ) {
if ( fn && ( typeof ( fn ) === 'function' ) ) {
fn ( ) ;
}
} else {
this . $apply ( fn ) ;
2013-09-02 01:31:38 +00:00
}
2013-09-06 02:33:31 +00:00
} ;
2013-09-02 01:31:38 +00:00
2013-09-06 02:33:31 +00:00
$rootScope . set = User . set ;
$rootScope . authenticated = User . authenticated ;
2013-08-27 23:59:53 +00:00
2015-04-01 00:38:15 +00:00
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
} ) ;
} ) ;
} ;
2014-02-01 18:19:48 +00:00
// Open a modal from a template expression (like ng-click,...)
// Otherwise use the proper $modal.open
2014-02-10 17:39:01 +00:00
$rootScope . openModal = function ( template , options ) { //controller, scope, keyboard, backdrop){
if ( ! options ) options = { } ;
if ( options . track ) window . ga && ga ( 'send' , 'event' , 'button' , 'click' , options . track ) ;
2015-04-01 00:38:15 +00:00
if ( template === 'newStuff' ) return forceLoadBailey ( template , options ) ;
2014-02-02 15:43:58 +00:00
return $modal . open ( {
2014-02-02 15:06:30 +00:00
templateUrl : 'modals/' + template + '.html' ,
2014-02-10 17:39:01 +00:00
controller : options . controller , // optional
scope : options . scope , // optional
2015-02-09 19:35:41 +00:00
resolve : options . resolve , // optional
2014-02-10 17:39:01 +00:00
keyboard : ( options . keyboard === undefined ? true : options . keyboard ) , // optional
2014-11-27 10:32:57 +00:00
backdrop : ( options . backdrop === undefined ? true : options . backdrop ) , // optional
size : options . size , // optional, 'sm' or 'lg'
windowClass : options . windowClass // optional
2014-02-01 18:19:48 +00:00
} ) ;
}
2013-09-06 02:33:31 +00:00
$rootScope . dismissAlert = function ( ) {
2013-12-16 22:43:16 +00:00
$rootScope . set ( { 'flags.newStuff' : false } ) ;
2013-09-06 02:33:31 +00:00
}
2013-08-28 02:37:56 +00:00
2014-09-07 05:14:58 +00:00
$rootScope . acceptCommunityGuidelines = function ( ) {
$rootScope . set ( { 'flags.communityGuidelinesAccepted' : true } ) ;
}
2013-09-06 02:33:31 +00:00
$rootScope . notPorted = function ( ) {
2014-02-05 22:43:49 +00:00
alert ( window . env . t ( 'notPorted' ) ) ;
2013-09-06 02:33:31 +00:00
}
2013-08-29 02:51:45 +00:00
2013-10-28 19:16:40 +00:00
$rootScope . dismissErrorOrWarning = function ( type , $index ) {
$rootScope . flash [ type ] . splice ( $index , 1 ) ;
}
2013-11-07 19:24:38 +00:00
$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 ) {
2014-10-28 01:33:50 +00:00
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' ) ;
2013-11-07 19:24:38 +00:00
return level + ' ' + contrib . text ;
}
}
2013-10-19 23:15:48 +00:00
$rootScope . charts = { } ;
$rootScope . toggleChart = function ( id , task ) {
var history = [ ] , matrix , data , chart , options ;
switch ( id ) {
case 'exp' :
history = User . user . history . exp ;
2014-07-31 21:56:52 +00:00
$rootScope . charts . exp = ( history . length == 0 ) ? false : ! $rootScope . charts . exp ;
2013-10-19 23:15:48 +00:00
break ;
case 'todos' :
history = User . user . history . todos ;
2014-07-31 21:56:52 +00:00
$rootScope . charts . todos = ( history . length == 0 ) ? false : ! $rootScope . charts . todos ;
2013-10-19 23:15:48 +00:00
break ;
default :
history = task . history ;
2014-07-31 21:56:52 +00:00
$rootScope . charts [ id ] = ( history . length == 0 ) ? false : ! $rootScope . charts [ id ] ;
2013-10-21 18:41:19 +00:00
if ( task && task . _editing ) task . _editing = false ;
2013-10-19 23:15:48 +00:00
}
2015-01-29 20:25:08 +00:00
matrix = [ [ env . t ( 'date' ) , env . t ( 'score' ) ] ] ;
2013-10-19 23:15:48 +00:00
_ . each ( history , function ( obj ) {
2015-01-23 18:19:59 +00:00
matrix . push ( [ moment ( obj . date ) . format ( User . user . preferences . dateFormat . toUpperCase ( ) . replace ( 'YYYY' , 'YY' ) ) , obj . value ] ) ;
2013-10-19 23:15:48 +00:00
} ) ;
data = google . visualization . arrayToDataTable ( matrix ) ;
options = {
2014-02-05 22:43:49 +00:00
title : window . env . t ( 'history' ) ,
2013-10-19 23:15:48 +00:00
backgroundColor : {
fill : 'transparent'
2013-10-19 23:42:29 +00:00
} ,
2014-06-15 08:50:03 +00:00
hAxis : { slantedText : true , slantedTextAngle : 90 } ,
height : 270 ,
2013-10-19 23:42:29 +00:00
width : 300
2013-10-19 23:15:48 +00:00
} ;
chart = new google . visualization . LineChart ( $ ( "." + id + "-chart" ) [ 0 ] ) ;
chart . draw ( data , options ) ;
} ;
2013-11-16 10:22:12 +00:00
2015-05-13 16:19:08 +00:00
$rootScope . getGearArray = function ( set ) {
var flatGearArray = _ . toArray ( Content . gear . flat ) ;
2013-11-16 10:22:12 +00:00
2015-05-13 16:19:08 +00:00
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 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 == 'headAccessory' ) ? window . env . t ( 'headAccessory' ) : ( 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' ) {
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 } } ) ;
}
}
2013-11-16 10:22:12 +00:00
/ *
-- -- -- -- -- -- -- -- -- -- -- --
Spells
-- -- -- -- -- -- -- -- -- -- -- --
* /
$scope . castStart = function ( spell ) {
2014-02-05 22:43:49 +00:00
if ( User . user . stats . mp < spell . mana ) return Notification . text ( window . env . t ( 'notEnoughMana' ) ) ;
2014-02-14 00:57:00 +00:00
2015-01-01 20:31:11 +00:00
if ( spell . immediateUse && User . user . stats . gp < spell . value )
2014-12-31 01:57:24 +00:00
return Notification . text ( 'Not enough gold.' ) ;
2013-11-16 10:22:12 +00:00
$rootScope . applyingAction = true ;
$scope . spell = spell ;
if ( spell . target == 'self' ) {
$scope . castEnd ( null , 'self' ) ;
} else if ( spell . target == 'party' ) {
2013-12-05 18:05:47 +00:00
var party = Groups . party ( ) ;
party = ( _ . isArray ( party ) ? party : [ ] ) . concat ( User . user ) ;
$scope . castEnd ( party , 'party' ) ;
2013-11-16 10:22:12 +00:00
}
}
$scope . castEnd = function ( target , type , $event ) {
2015-06-01 22:38:18 +00:00
if ( ! $rootScope . applyingAction ) return 'No applying action' ;
2013-12-21 02:57:03 +00:00
$event && ( $event . stopPropagation ( ) , $event . preventDefault ( ) ) ;
2014-02-05 22:43:49 +00:00
if ( $scope . spell . target != type ) return Notification . text ( window . env . t ( 'invalidTarget' ) ) ;
2013-11-16 10:22:12 +00:00
$scope . spell . cast ( User . user , target ) ;
2013-12-21 01:52:14 +00:00
User . save ( ) ;
2014-01-22 08:27:55 +00:00
2014-01-22 08:16:52 +00:00
var spell = $scope . spell ;
2014-01-22 08:27:55 +00:00
var targetId = ( type == 'party' || type == 'self' ) ? '' : type == 'task' ? target . id : target . _id ;
$scope . spell = null ;
$rootScope . applyingAction = false ;
2015-01-18 01:43:37 +00:00
$http . post ( ApiUrl . get ( ) + '/api/v2/user/class/cast/' + spell . key + '?targetType=' + type + '&targetId=' + targetId )
2015-06-01 22:38:18 +00:00
. 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 . text ( $filter ( "markdown" ) ( msg ) ) ;
User . sync ( ) ;
} ) ;
2013-11-16 10:22:12 +00:00
}
2014-01-18 21:15:45 +00:00
$rootScope . castCancel = function ( ) {
$rootScope . applyingAction = false ;
$scope . spell = null ;
}
2014-06-29 19:33:40 +00:00
2014-12-29 20:16:25 +00:00
// Because our angular-ui-router uses anchors for urls (/#/options/groups/party), window.location.href=... won't
2014-06-29 19:33:40 +00:00
// reload the page. Perform manually.
$rootScope . hardRedirect = function ( url ) {
window . location . href = url ;
2015-04-15 10:13:54 +00:00
setTimeout ( function ( ) {
window . location . reload ( false ) ;
} ) ;
2014-06-29 19:33:40 +00:00
}
2015-02-04 02:14:16 +00:00
// 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
}
2013-08-29 05:45:19 +00:00
}
2013-09-06 02:33:31 +00:00
] ) ;