Merge branch 'develop' into TheHollidayInn-challenges-owner-filter

This commit is contained in:
Blade Barringer
2015-06-13 18:23:51 -05:00
909 changed files with 24149 additions and 14914 deletions

View File

@@ -15,11 +15,13 @@ angular.module('habitrpg')
var runAuth = function(id, token) {
User.authenticate(id, token, function(err) {
if(!err) $scope.registrationInProgress = false;
$window.location.href = ('/' + window.location.hash);
});
};
function errorAlert(data, status, headers, config) {
$scope.registrationInProgress = false;
if (status === 0) {
$window.alert(window.env.t('noReachServer'));
} else if (!!data && !!data.err) {
@@ -29,6 +31,8 @@ angular.module('habitrpg')
}
};
$scope.registrationInProgress = false;
$scope.register = function() {
/*TODO highlight invalid inputs
we have this as a workaround for https://github.com/HabitRPG/habitrpg-mobile/issues/64
@@ -36,10 +40,22 @@ angular.module('habitrpg')
var scope = angular.element(document.getElementById('registrationForm')).scope();
if (scope.registrationForm.$invalid) return;
$scope.registrationInProgress = true;
var url = ApiUrl.get() + "/api/v2/register";
if($rootScope.selectedLanguage) url = url + '?lang=' + $rootScope.selectedLanguage.code;
$http.post(url, scope.registerVals).success(function(data, status, headers, config) {
runAuth(data.id, data.apiToken);
if (status == 200) {
mixpanel.alias(data._id);
if (data.auth.facebook) {
mixpanel.register({'authType':'facebook','email':data.auth.facebook._json.email})
} else {
mixpanel.register({'authType':'email','email':data.auth.local.email})
}
mixpanel.register({'UUID':data._id,'language':data.preferences.language});
mixpanel.track('Registration');
}
}).error(errorAlert);
};
@@ -51,6 +67,11 @@ angular.module('habitrpg')
$http.post(ApiUrl.get() + "/api/v2/user/auth/local", data)
.success(function(data, status, headers, config) {
runAuth(data.id, data.token);
if (status == 200) {
mixpanel.identify(data.id);
mixpanel.register({'UUID':data._id});
mixpanel.track('Login');
}
}).error(errorAlert);
};
@@ -115,13 +136,18 @@ angular.module('habitrpg')
// ------ Social ----------
hello.init({
facebook : window.env.FACEBOOK_KEY,
facebook : window.env.FACEBOOK_KEY
});
$scope.socialLogin = function(network){
hello(network).login({scope:'email'}).then(function(auth){
$http.post(ApiUrl.get() + "/api/v2/user/auth/social", auth)
.success(function(data, status, headers, config) {
if (status == 200) {
mixpanel.identify(data.id);
mixpanel.register({'UUID':data._id});
mixpanel.track('Login');
}
runAuth(data.id, data.token);
}).error(errorAlert);
}, function( e ){

View File

@@ -94,15 +94,14 @@ habitrpg.controller("ChallengesCtrl", ['$rootScope','$scope', 'Shared', 'User',
challenge.$save(function(_challenge){
if (isNew) {
Notification.text(window.env.t('challengeCreated'));
$state.go('options.social.challenges.detail', {cid: _challenge._id});
$scope.discard();
$scope.challenges = Challenges.Challenge.query();
$state.transitionTo('options.social.challenges.detail', {cid: challenge._id}, {
reload: true, inherit: false, notify: true
});
User.sync();
} else {
// TODO figure out a more elegant way about this
//challenge._editing = false;
challenge._locked = true;
getChallenges();
$state.transitionTo('options.social.challenges.detail', {cid: challenge._id}, {
reload: true, inherit: false, notify: true
});
}
});
};
@@ -126,19 +125,27 @@ habitrpg.controller("ChallengesCtrl", ['$rootScope','$scope', 'Shared', 'User',
$scope.challenges = Challenges.Challenge.query();
User.log({});
}
$scope.cancelClosing = function() {
$scope.cancelClosing = function(challenge) {
$scope.popoverEl.popover('destroy');
$scope.popoverEl = undefined;
$scope.closingChal = undefined;
challenge.winner = undefined;
}
$scope["delete"] = function(challenge) {
if (!confirm(window.env.t('sureDelCha'))) return;
var warningMsg;
if(challenge.group._id == 'habitrpg') {
warningMsg = window.env.t('sureDelChaTavern');
} else {
warningMsg = window.env.t('sureDelCha');
}
if (!confirm(warningMsg)) return;
challenge.$delete(function(){
$scope.popoverEl.popover('destroy');
backToChallenges();
});
};
$scope.selectWinner = function(challenge) {
if (!challenge.winner) return;
if (!confirm(window.env.t('youSure'))) return;
challenge.$close({uid:challenge.winner}, function(){
$scope.popoverEl.popover('destroy');

View File

@@ -5,6 +5,7 @@ habitrpg.controller("FiltersCtrl", ['$scope', '$rootScope', 'User', 'Shared',
var user = User.user;
$scope._editing = false;
$scope._newTag = {name:''};
$scope.filterQuery = '';
var tagsSnap; // used to compare which tags need updating
@@ -30,6 +31,11 @@ habitrpg.controller("FiltersCtrl", ['$scope', '$rootScope', 'User', 'Shared',
// User.save();
};
$scope.updateTaskFilter = function(){
user.filterQuery = $scope.filterQuery;
};
$scope.updateTaskFilter();
$scope.createTag = function() {
User.user.ops.addTag({body:{name:$scope._newTag.name, id:Shared.uuid()}});
$scope._newTag.name = '';

View File

@@ -28,7 +28,7 @@ function($scope, $rootScope, User, $http, Notification, ApiUrl) {
// Google Analytics, only in production
if (window.env.NODE_ENV === 'production') {
// Get experiments API
$.getScript('//www.google-analytics.com/cx/api.js?experiment=pi26hZ3rRFaEPNiKqXbhqA', function(){
$.getScript('//www.google-analytics.com/cx/api.js?experiment=t-AFggRWQnuJ6Teck_x1-Q', function(){
$rootScope.variant = cxApi.chooseVariation();
$rootScope.$apply();

View File

@@ -23,6 +23,12 @@ habitrpg.controller("GroupsCtrl", ['$scope', '$rootScope', 'Shared', 'Groups', '
return _.detect(Groups.myGuilds(), function(g) { return g._id === group._id });
}
// Similarly, if we're dealing with the user's current party, return true.
if(group.type === 'party') {
var currentParty = Groups.party();
if(currentParty._id && currentParty._id === group._id) return true;
}
if (!group.members) return false;
var memberIds = _.map(group.members, function(x){return x._id});
return ~(memberIds.indexOf(userid));
@@ -214,6 +220,23 @@ habitrpg.controller("GroupsCtrl", ['$scope', '$rootScope', 'Shared', 'Groups', '
$scope.usernames = [];
}
$scope.filterUser = function(msg) {
if (!$scope.query || !msg.user) {
return false;
}
// Ignore casing when checking for username
var user = msg.user.toLowerCase();
var text = $scope.query.text.toLowerCase();
return user.indexOf(text) == 0;
}
$scope.performCompletion = function(msg) {
$scope.autoComplete(msg);
$scope.query = null;
}
$scope.addNewUser = function(user) {
if($.inArray(user.user,$scope.usernames) == -1) {
user.username = user.user;
@@ -297,6 +320,11 @@ habitrpg.controller("GroupsCtrl", ['$scope', '$rootScope', 'Shared', 'Groups', '
}
$scope.message.content = '';
$scope._sending = false;
if (group.privacy == 'public'){
mixpanel.track('Group Chat',{'groupType':group.type,'privacy':group.privacy,'groupName':group.name,'message':message})
} else {
mixpanel.track('Group Chat',{'groupType':group.type,'privacy':group.privacy})
}
}, function(err){
$scope._sending = false;
});
@@ -344,7 +372,25 @@ habitrpg.controller("GroupsCtrl", ['$scope', '$rootScope', 'Shared', 'Groups', '
});
});
}
}
};
$scope.copyToDo = function(message) {
var taskNotes = env.t("messageWroteIn", {
user: message.uuid == 'system'
? 'system'
: '[' + message.user + '](' + env.BASE_URL + '/static/front/#?memberId=' + message.uuid + ')',
group: '[' + $scope.group.name + '](' + window.location.href + ')'
});
var newScope = $scope.$new();
newScope.text = message.text;
newScope.notes = taskNotes;
$rootScope.openModal('copyChatToDo',{
controller:'CopyMessageModalCtrl',
scope: newScope
});
};
$scope.sync = function(group){
group.$get();
@@ -390,6 +436,8 @@ habitrpg.controller("GroupsCtrl", ['$scope', '$rootScope', 'Shared', 'Groups', '
if (confirm(window.env.t('confirmGuild'))) {
group.$save(function(saved){
if (saved.privacy == 'public') {mixpanel.track('Join Group',{'owner':true,'groupType':'guild','privacy':saved.privacy,'groupName':saved.name})}
else {mixpanel.track('Join Group',{'owner':true,'groupType':'guild','privacy':saved.privacy})}
$rootScope.hardRedirect('/#/options/groups/guilds/' + saved._id);
});
}
@@ -404,6 +452,8 @@ habitrpg.controller("GroupsCtrl", ['$scope', '$rootScope', 'Shared', 'Groups', '
}
group.$join(function(joined){
if (joined.privacy == 'public') {mixpanel.track('Join Group',{'owner':false,'groupType':'guild','privacy':joined.privacy,'groupName':joined.name})}
else {mixpanel.track('Join Group',{'owner':false,'groupType':'guild','privacy':joined.privacy})}
$rootScope.hardRedirect('/#/options/groups/guilds/' + joined._id);
})
}
@@ -469,6 +519,7 @@ habitrpg.controller("GroupsCtrl", ['$scope', '$rootScope', 'Shared', 'Groups', '
$scope.create = function(group){
group.$save(function(){
mixpanel.track('Join Group',{'owner':true,'groupType':'party','privacy':'private'});
$rootScope.hardRedirect('/#/options/groups/party');
});
}
@@ -476,6 +527,7 @@ habitrpg.controller("GroupsCtrl", ['$scope', '$rootScope', 'Shared', 'Groups', '
$scope.join = function(party){
var group = new Groups.Group({_id: party.id, name: party.name});
group.$join(function(){
mixpanel.track('Join Group',{'owner':false,'groupType':'party','privacy':'private'});
$rootScope.hardRedirect('/#/options/groups/party');
});
}
@@ -549,3 +601,20 @@ habitrpg.controller("GroupsCtrl", ['$scope', '$rootScope', 'Shared', 'Groups', '
}
}
])
.controller("CopyMessageModalCtrl", ['$scope', 'User', 'Notification',
function($scope, User, Notification){
$scope.saveTodo = function() {
var newTask = {
text: $scope.text,
type: 'todo',
notes: $scope.notes
};
User.user.ops.addTask({body:newTask});
Notification.text(window.env.t('messageAddedAsToDo'));
$scope.$close();
}
}
]);

View File

@@ -1,7 +1,7 @@
"use strict";
habitrpg.controller("HeaderCtrl", ['$scope', 'Groups', 'User',
function($scope, Groups, User) {
habitrpg.controller("HeaderCtrl", ['$scope', 'Groups', 'User', '$location', '$rootScope',
function($scope, Groups, User, $location, $rootScope) {
$scope.Math = window.Math;
$scope.user = User.user;
@@ -16,6 +16,19 @@ habitrpg.controller("HeaderCtrl", ['$scope', 'Groups', 'User',
$scope.$watch('user.party.orderAscending', triggerResort);
});
$scope.inviteOrStartParty = function(group) {
if (group.type === "party") {
$rootScope.openModal('invite-friends', {
controller:'InviteToGroupCtrl',
resolve: {
injectedGroup: function(){ return group; }
}
});
} else {
$location.path("/options/groups/party");
}
}
function resortParty() {
var result = _.sortBy(
_.filter($scope.party.members, function(member){

View File

@@ -103,26 +103,6 @@ habitrpg.controller("InventoryCtrl",
}
}
$scope.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; // this is ugly but temporary, once the purchase modal is done this will be removed
if (type == 'weapon' || type == 'armor' || type == 'head' || type == 'shield' || type == 'headAccessory') {
if (gems < ((item.specialClass == "wizard") && (item.type == "weapon")) + 1) return $rootScope.openModal('buyGems');
var message = window.env.t('buyThis', {text: string, price: ((item.specialClass == "wizard") && (item.type == "weapon")) + 1, 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}});
}
}
$scope.choosePet = function(egg, potion){
var petDisplayName = env.t('petName', {
potion: Content.hatchingPotions[potion] ? Content.hatchingPotions[potion].text() : potion,
@@ -200,6 +180,7 @@ habitrpg.controller("InventoryCtrl",
$rootScope.selectedQuest = undefined;
}
$scope.questInit = function(){
mixpanel.track("Quest",{"owner":true,"response":"accept","questName":$scope.selectedQuest.key});
$rootScope.party.$questAccept({key:$scope.selectedQuest.key}, function(){
$rootScope.party.$get();
});

View File

@@ -87,6 +87,7 @@ habitrpg.controller('NotificationCtrl',
Notification.drop(User.user._tmp.drop.dialog);
}
$rootScope.playSound('Item_Drop');
mixpanel.track("Acquire Item",{'itemName':after.key,'acquireMethod':'Drop'})
});
$rootScope.$watch('user.achievements.streak', function(after, before){
@@ -100,9 +101,14 @@ habitrpg.controller('NotificationCtrl',
}
});
$rootScope.$watch('user.achievements.ultimateGear', function(after, before){
if (after === before || after !== true) return;
$rootScope.$watch('user.achievements.ultimateGearSets', function(after, before){
if (_.isEqual(after,before) || !_.contains(User.user.achievements.ultimateGearSets, true)) return;
$rootScope.openModal('achievements/ultimateGear');
}, true);
$rootScope.$watch('user.flags.armoireEmpty', function(after,before){
if (before == undefined || after == before || after == false) return;
$rootScope.openModal('armoireEmpty');
});
$rootScope.$watch('user.achievements.rebirths', function(after, before){

View File

@@ -3,8 +3,8 @@
/* 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',
function($scope, $rootScope, $location, User, $http, $state, $stateParams, Notification, Groups, Shared, Content, $modal, $timeout, ApiUrl, Payments,$sce) {
habitrpg.controller("RootCtrl", ['$scope', '$rootScope', '$location', 'User', '$http', '$state', '$stateParams', 'Notification', 'Groups', 'Shared', 'Content', '$modal', '$timeout', 'ApiUrl', 'Payments','$sce','$window',
function($scope, $rootScope, $location, User, $http, $state, $stateParams, Notification, Groups, Shared, Content, $modal, $timeout, ApiUrl, Payments, $sce, $window) {
var user = User.user;
var initSticky = _.once(function(){
@@ -201,7 +201,40 @@ habitrpg.controller("RootCtrl", ['$scope', '$rootScope', '$location', 'User', '$
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 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}});
}
}
/*
------------------------
@@ -226,7 +259,7 @@ habitrpg.controller("RootCtrl", ['$scope', '$rootScope', '$location', 'User', '$
}
$scope.castEnd = function(target, type, $event){
if (!$rootScope.applyingAction) return;
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);
@@ -238,17 +271,16 @@ habitrpg.controller("RootCtrl", ['$scope', '$rootScope', '$location', 'User', '$
$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.text(msg);
User.sync();
});
.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(){

View File

@@ -20,7 +20,7 @@ habitrpg.controller('SettingsCtrl',
var mapPrefToEmailString = {
'importantAnnouncements': 'inactivityEmails'
};
// If ?unsubFrom param is passed with valid email type,
// automatically unsubscribe users from that email and
// show an alert
@@ -42,7 +42,7 @@ habitrpg.controller('SettingsCtrl',
User.set({"preferences.stickyHeader":false});
$rootScope.$on('userSynced', function(){
window.location.reload();
});
});
}
}
@@ -144,7 +144,7 @@ habitrpg.controller('SettingsCtrl',
$http.post(ApiUrl.get() + '/api/v2/user/coupon/' + code).success(function(res,code){
if (code!==200) return;
User.sync();
Notification.text('Coupon applied! Check your inventory');
Notification.text(env.t('promoCodeApplied'));
});
}
$scope.generateCodes = function(codes){

View File

@@ -5,6 +5,10 @@ habitrpg.controller("TasksCtrl", ['$scope', '$rootScope', '$location', 'User','N
$scope.obj = User.user; // used for task-lists
$scope.user = User.user;
$scope.armoireCount = function(gear) {
return Shared.countArmoire(gear);
};
$scope.score = function(task, direction) {
switch (task.type) {
case 'reward':
@@ -15,13 +19,14 @@ habitrpg.controller("TasksCtrl", ['$scope', '$rootScope', '$location', 'User','N
break;
case 'todo':
$rootScope.playSound('ToDo');
Guide.goto('intro', 1);
break;
default:
if (direction === 'down') $rootScope.playSound('Minus_Habit');
else if (direction === 'up') $rootScope.playSound('Plus_Habit');
}
User.user.ops.score({params:{id: task.id, direction:direction}})
User.user.ops.score({params:{id: task.id, direction:direction}});
mixpanel.register({'Gold':Math.floor(User.user.stats.gp),'Health':Math.ceil(User.user.stats.hp),'Experience':Math.floor(User.user.stats.exp),'Level':User.user.stats.lvl,'Mana':Math.floor(User.user.stats.mp),'Class':User.user.stats.class,'subscription':User.user.purchased.plan.planId,'contributorLevel':User.user.contributor.level,'UUID':User.user._id});
mixpanel.track('Score Task',{'taskType':task.type,'direction':direction});
};
function addTask(addTo, listDef, task) {
@@ -127,6 +132,19 @@ habitrpg.controller("TasksCtrl", ['$scope', '$rootScope', '$location', 'User','N
*/
$scope._today = moment().add({days: 1});
/*
------------------------
Dailies
------------------------
*/
$scope.openDatePicker = function($event, task) {
$event.preventDefault();
$event.stopPropagation();
task._isDatePickerOpen = !task._isDatePickerOpen;
}
/*
------------------------
Checklists
@@ -192,7 +210,7 @@ habitrpg.controller("TasksCtrl", ['$scope', '$rootScope', '$location', 'User','N
------------------------
*/
$scope.$watch('user.items.gear.equipped', function(){
$scope.$watchGroup(['user.items.gear.owned', 'user.flags.armoireEnabled'], function(){
$scope.itemStore = Shared.updateStore(User.user);
},true);
@@ -212,7 +230,7 @@ habitrpg.controller("TasksCtrl", ['$scope', '$rootScope', '$location', 'User','N
$scope.shouldShow = function(task, list, prefs){
if (task._editing) // never hide a task while being edited
return true;
var shouldDo = task.type == 'daily' ? habitrpgShared.shouldDo(new Date, task.repeat, prefs) : true;
var shouldDo = task.type == 'daily' ? habitrpgShared.shouldDo(new Date, task, prefs) : true;
switch (list.view) {
case "yellowred": // Habits
return task.value < 1;