diff --git a/public/js/app.js b/public/js/app.js index 914f0437f0..c642aea407 100644 --- a/public/js/app.js +++ b/public/js/app.js @@ -1,23 +1,5 @@ "use strict"; -window.env = window.env || {}; //FIX tests - -if(window.env.language && window.env.language.momentLang && window.env.language.momentLangCode){ - var head = document.getElementsByTagName('head')[0]; - var script = document.createElement('script'); - script.type = 'text/javascript'; - script.text = window.env.language.momentLang; - head.appendChild(script); - moment.lang(window.env.language.momentLangCode); -} - -window.env.t = function(stringName, vars){ - var string = window.env.translations[stringName]; - if(!string) return window._.template(window.env.translations.stringNotFound, {string: stringName}); - - return vars === undefined ? string : window._.template(string, vars); -} - window.habitrpg = angular.module('habitrpg', ['ngResource', 'ngSanitize', 'userServices', 'groupServices', 'memberServices', 'challengeServices', 'authServices', 'notificationServices', 'guideServices', 'authCtrl', @@ -225,10 +207,10 @@ window.habitrpg = angular.module('habitrpg', function error(response) { //var status = response.status; response.data = (response.data.err) ? response.data.err : response.data; - if (response.status == 0) response.data = 'Server currently unreachable.'; - if (response.status == 500) response.data += ' (see Chrome console for more details).'; + if (response.status == 0) response.data = window.env.t('serverUnreach'); + if (response.status == 500) response.data += window.env.t('seeConsole'); - var error = response.status == 0 ? response.data : ('Error ' + response.status + ': ' + response.data); + var error = response.status == 0 ? response.data : (window.env.t('error') + ' ' + response.status + ': ' + response.data); $rootScope.$broadcast('responseError', error); console.log(arguments); return $q.reject(response); diff --git a/public/js/controllers/authCtrl.js b/public/js/controllers/authCtrl.js index 1312b40d35..77a297ebb2 100644 --- a/public/js/controllers/authCtrl.js +++ b/public/js/controllers/authCtrl.js @@ -13,7 +13,7 @@ angular.module('authCtrl', []) $scope.useUUID = false; $scope.toggleUUID = function() { if (showedFacebookMessage === false) { - alert("Until we add Facebook, use your UUID and API Token to log in (found at https://habitrpg.com > Options > Settings)."); + alert(window.env.t('untilNoFace')); showedFacebookMessage = true; } $scope.useUUID = !$scope.useUUID; @@ -32,11 +32,11 @@ angular.module('authCtrl', []) function errorAlert(data, status, headers, config) { if (status === 0) { - $window.alert("Server not currently reachable, try again later"); + $window.alert(window.env.t('noReachServer')); } else if (!!data && !!data.err) { $window.alert(data.err); } else { - $window.alert("ERROR: " + status); + $window.alert(window.env.t('errorUpCase') + status); } }; @@ -81,7 +81,7 @@ angular.module('authCtrl', []) $scope.passwordReset = function(email){ $http.post(API_URL + '/api/v2/user/reset-password', {email:email}) .success(function(){ - alert('New password sent.'); + alert(window.env.t('newPassSent')); }) .error(function(data){ alert(data.err); diff --git a/public/js/controllers/challengesCtrl.js b/public/js/controllers/challengesCtrl.js index 8c1cd05a57..979fa0e3a6 100644 --- a/public/js/controllers/challengesCtrl.js +++ b/public/js/controllers/challengesCtrl.js @@ -44,11 +44,11 @@ habitrpg.controller("ChallengesCtrl", ['$rootScope','$scope', 'Shared', 'User', * Save */ $scope.save = function(challenge) { - if (!challenge.group) return alert('Please select group'); + if (!challenge.group) return alert(window.env.t('selectGroup')); var isNew = !challenge._id; challenge.$save(function(_challenge){ if (isNew) { - Notification.text('Challenge Created'); + Notification.text(window.env.t('challengeCreated')); $state.go('options.social.challenges.detail', {cid: _challenge._id}); $scope.discard(); $scope.challenges = Challenges.Challenge.query(); @@ -85,14 +85,14 @@ habitrpg.controller("ChallengesCtrl", ['$rootScope','$scope', 'Shared', 'User', $scope.closingChal = undefined; } $scope["delete"] = function(challenge) { - if (!confirm("Delete challenge, are you sure?")) return; + if (!confirm(window.env.t('sureDelCha'))) return; challenge.$delete(function(){ $scope.popoverEl.popover('destroy'); backToChallenges(); }); }; $scope.selectWinner = function(challenge) { - if (!confirm("Are you sure?")) return; + if (!confirm(window.env.t('youSure'))) return; challenge.$close({uid:challenge.winner}, function(){ $scope.popoverEl.popover('destroy'); backToChallenges(); @@ -106,7 +106,7 @@ habitrpg.controller("ChallengesCtrl", ['$rootScope','$scope', 'Shared', 'User', html: true, placement: 'right', trigger: 'manual', - title: 'Close challenge and...', + title: window.env.t('closeCha'), content: html }).popover('show'); @@ -140,7 +140,7 @@ habitrpg.controller("ChallengesCtrl", ['$rootScope','$scope', 'Shared', 'User', }; $scope.removeTask = function(list, $index) { - if (!confirm("Are you sure you want to delete this task?")) return; + if (!confirm(window.env.t('sureDelete'))) return; //TODO persist // User.log({op: "delTask", data: task}); list.splice($index, 1); @@ -185,13 +185,13 @@ habitrpg.controller("ChallengesCtrl", ['$rootScope','$scope', 'Shared', 'User', $scope.selectedChal = chal; $scope.popoverEl = $($event.target); var html = $compile( - 'Remove Tasks
\nKeep Tasks
\nCancel
' + '' + window.env.t('removeTasks') + '
\n' + window.env.t('keepTasks') + '
\n' + window.env.t('cancel') + '
' )($scope); $scope.popoverEl.popover('destroy').popover({ html: true, placement: 'top', trigger: 'manual', - title: 'Leave challenge and...', + title: window.env.t('leaveCha'), content: html }).popover('show'); } diff --git a/public/js/controllers/groupsCtrl.js b/public/js/controllers/groupsCtrl.js index c3910a9030..3b259c3019 100644 --- a/public/js/controllers/groupsCtrl.js +++ b/public/js/controllers/groupsCtrl.js @@ -34,7 +34,7 @@ habitrpg.controller("GroupsCtrl", ['$scope', '$rootScope', 'Shared', 'Groups', ' } $scope.removeMember = function(group, member, isMember){ - var yes = confirm("Do you really want to remove this member from the party?") + var yes = confirm(window.env.t('sureKick')) if(yes){ Groups.Group.removeMember({gid: group._id, uuid: member._id }, undefined, function(){ if(isMember){ @@ -180,7 +180,7 @@ habitrpg.controller("GroupsCtrl", ['$scope', '$rootScope', 'Shared', 'Groups', ' $scope.likeChatMessage = function(group,message) { if (message.uuid == User.user._id) - return Notification.text("Can't like your own message. Don't be that person."); + return Notification.text(window.env.t('foreverAlone')); if (!message.likes) message.likes = {}; if (message.likes[User.user._id]) { delete message.likes[User.user._id]; @@ -198,10 +198,10 @@ habitrpg.controller("GroupsCtrl", ['$scope', '$rootScope', 'Shared', 'Groups', ' // List of Ordering options for the party members list $scope.partyOrderChoices = { - 'level': 'Sort by Level', - 'random': 'Sort randomly', - 'pets': 'Sort by number of pets', - 'party_date_joined': 'Sort by Party date joined', + 'level': window.env.t('sortLevel'), + 'random': window.env.t('sortRandom'), + 'pets': window.env.t('sortPets'), + 'party_date_joined': window.env.t('sortJoined'), }; }]) @@ -221,7 +221,7 @@ habitrpg.controller("GroupsCtrl", ['$scope', '$rootScope', 'Shared', 'Groups', ' $scope.create = function(group){ if (User.user.balance < 1) return $rootScope.openModal('buyGems'); - if (confirm("Create Guild for 4 Gems?")) { + if (confirm(window.env.t('confirmGuild'))) { group.$save(function(saved){ User.user.balance--; $scope.groups.guilds.push(saved); @@ -284,14 +284,14 @@ habitrpg.controller("GroupsCtrl", ['$scope', '$rootScope', 'Shared', 'Groups', ' }), '_id'); if (_.intersection(challenges, User.user.challenges).length > 0) { html = $compile( - 'Remove Tasks
\nKeep Tasks
\nCancel
' + '' + window.env.t('removeTasks') + '
\n' + window.env.t('keepTasks') + '
\n' + window.env.t('cancel') + '
' )($scope); - title = "Leave group challenges and..."; + title = window.env.t('leaveGroupCha'); } else { html = $compile( - 'Confirm
\nCancel
' + '' + window.env.t('confirm') + '
\n' + window.env.t('cancel') + '
' )($scope); - title = "Leave group?" + title = window.env.t('leaveGroup') } $scope.popoverEl.popover('destroy').popover({ html: true, @@ -358,14 +358,14 @@ habitrpg.controller("GroupsCtrl", ['$scope', '$rootScope', 'Shared', 'Groups', ' }), '_id'); if (_.intersection(challenges, User.user.challenges).length > 0) { html = $compile( - 'Remove Tasks
\nKeep Tasks
\nCancel
' + '' + window.env.t('removeTasks') + '
\n' + window.env.t('keepTasks') + '
\n' + window.env.t('cancel') + '
' )($scope); - title = "Leave party challenges and..."; + title = window.env.t('leavePartyCha'); } else { html = $compile( - 'Confirm
\nCancel
' + '' + window.env.t('confirm') + '
\n' + window.env.t('cancel') + '
' )($scope); - title = "Leave party?"; + title = window.env.t('leaveParty'); } $scope.popoverEl.popover('destroy').popover({ html: true, @@ -383,8 +383,8 @@ habitrpg.controller("GroupsCtrl", ['$scope', '$rootScope', 'Shared', 'Groups', ' } $scope.questAbort = function(){ - if (!confirm("Are you sure you want to abort this mission? It will abort it for everyone in your party, all progress will be lost.")) return; - if (!confirm("Are you double sure? Make sure they won't hate you forever!")) return; + if (!confirm(window.env.t('sureAbort'))) return; + if (!confirm(window.env.t('doubleSureAbort'))) return; $rootScope.party.$questAbort(); } } diff --git a/public/js/controllers/inventoryCtrl.js b/public/js/controllers/inventoryCtrl.js index 96f81644aa..24b97a3cba 100644 --- a/public/js/controllers/inventoryCtrl.js +++ b/public/js/controllers/inventoryCtrl.js @@ -79,7 +79,7 @@ habitrpg.controller("InventoryCtrl", ['$rootScope', '$scope', '$window', 'User', } $scope.hatch = function(egg, potion){ - if (!$window.confirm('Hatch a ' + potion.key + ' ' + egg.key + '?')) return; + if (!$window.confirm(window.env.t('hatchAPot', {potion: potion.key, egg: egg.key}))) return; user.ops.hatch({params:{egg:egg.key, hatchingPotion:potion.key}}); $scope.selectedEgg = null; $scope.selectedPotion = null; @@ -87,9 +87,11 @@ habitrpg.controller("InventoryCtrl", ['$rootScope', '$scope', '$window', 'User', $scope.purchase = function(type, item){ var gems = User.user.balance * 4; + if(gems < item.value) return $rootScope.openModal('buyGems'); - var string = (type == 'hatchingPotion') ? 'hatching potion' : type; // give hatchingPotion a space - var message = "Buy this " + string + " with " + item.value + " of your " + gems + " Gems?" + var string = (type == 'hatchingPotions') ? 'hatching potion' : (type == 'eggs') ? 'egg' : (type == 'quests') ? 'quest' : (item.key == 'Saddle') ? 'saddle' : (type == 'special') ? item.key : type; // this is ugly but temporary, once the purchase modal is done this will be removed + 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}}); } @@ -102,8 +104,8 @@ habitrpg.controller("InventoryCtrl", ['$rootScope', '$scope', '$window', 'User', if ($scope.selectedFood) { var food = $scope.selectedFood if (food.key == 'Saddle') { - if (!$window.confirm('Saddle ' + pet + '?')) return; - } else if (!$window.confirm('Feed ' + petDisplayName + ' '+ food.article + food.text + '?')) { + if (!$window.confirm(window.env.t('useSaddle', {pet: pet}))) return; + } else if (!$window.confirm(window.env.t('feedPet', {name: petDisplayName, article: food.article, text: food.text}))) { return; } User.user.ops.feed({params:{pet: pet, food: food.key}}); @@ -123,9 +125,9 @@ habitrpg.controller("InventoryCtrl", ['$rootScope', '$scope', '$window', 'User', var item = Content.quests[quest]; var completedPrevious = !item.previous || (User.user.achievements.quests && User.user.achievements.quests[item.previous]); if (!completedPrevious) - return alert("You must first complete " + $rootScope.Content.quests[item.previous].text + '.'); + return alert(window.env.t('mustComplete', {quest: $rootScope.Content.quests[item.previous].text})); if (item.lvl && item.lvl > user.stats.lvl) - return alert("You must be level " + item.lvl + '.'); + return alert(window.env.t('mustLevel', {level: item.lvl})); $rootScope.selectedQuest = item; $rootScope.openModal('showQuest', 'InventoryCtrl'); } @@ -141,7 +143,7 @@ habitrpg.controller("InventoryCtrl", ['$rootScope', '$scope', '$window', 'User', $scope.buyQuest = function(quest) { var item = Content.quests[quest]; if (item.lvl && item.lvl > user.stats.lvl) - return alert("You must be level " + item.lvl + ' to buy this quest!'); + return alert(window.env.t('mustLvlQuest', {level: item.lvl})); var completedPrevious = !item.previous || (User.user.achievements.quests && User.user.achievements.quests[item.previous]); if (!completedPrevious) return $scope.purchase("quests", item); diff --git a/public/js/controllers/notificationCtrl.js b/public/js/controllers/notificationCtrl.js index 8e568206e4..fa2c69bf0e 100644 --- a/public/js/controllers/notificationCtrl.js +++ b/public/js/controllers/notificationCtrl.js @@ -30,7 +30,7 @@ habitrpg.controller('NotificationCtrl', if ((money > 0) && !!bonus) { if (bonus < 0.01) bonus = 0.01; - Notification.text("+ " + Notification.coins(bonus) + " Streak Bonus!"); + Notification.text("+ " + Notification.coins(bonus) + window.env.t('streakCoins')); delete User.user._tmp.streakBonus; } }); diff --git a/public/js/controllers/rootCtrl.js b/public/js/controllers/rootCtrl.js index 8bd97d6270..f950545e92 100644 --- a/public/js/controllers/rootCtrl.js +++ b/public/js/controllers/rootCtrl.js @@ -81,7 +81,7 @@ habitrpg.controller("RootCtrl", ['$scope', '$rootScope', '$location', 'User', '$ } $rootScope.notPorted = function(){ - alert("This feature is not yet ported from the original site."); + alert(window.env.t('notPorted')); } $rootScope.dismissErrorOrWarning = function(type, $index){ @@ -93,11 +93,11 @@ habitrpg.controller("RootCtrl", ['$scope', '$rootScope', '$location', 'User', '$ key: window.env.STRIPE_PUB_KEY, address: false, amount: 500, - name: subscription ? "Subscribe" : "Checkout", + name: subscription ? window.env.t('subscribe') : window.env.t('checkout'), description: subscription ? - "Buy gems with Gold, No Ads, Support the Devs" : - "20 Gems, No Ads, Support the Devs", - panelLabel: subscription ? "Subscribe" : "Checkout", + window.env.t('buySubsText') : + window.env.t('buyCheckText'), + panelLabel: subscription ? window.env.t('subscribe') : window.env.t('checkout'), token: function(data) { var url = '/api/v2/user/buy-gems'; if (subscription) url += '?plan=basic_earned'; @@ -114,7 +114,7 @@ habitrpg.controller("RootCtrl", ['$scope', '$rootScope', '$location', 'User', '$ } $scope.cancelSubscription = function(){ - if (!confirm("Are you sure you want to cancel your subscription?")) return; + if (!confirm(window.env.t('sureCancelSub'))) return; //TODO use Stripe API to keep subscription till end of their month $http.post('/api/v2/user/cancel-subscription').success(function(){ window.location.reload(true); @@ -126,7 +126,7 @@ habitrpg.controller("RootCtrl", ['$scope', '$rootScope', '$location', 'User', '$ if (backer && backer.npc) return backer.npc; var l = contrib && contrib.level; if (l && l > 0) { - var level = (l < 3) ? 'Friend' : (l < 5) ? 'Elite' : (l < 7) ? 'Champion' : (l < 8) ? 'Legendary' : 'Heroic'; + 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') : window.env.t('heroic'); return level + ' ' + contrib.text; } } @@ -154,7 +154,7 @@ habitrpg.controller("RootCtrl", ['$scope', '$rootScope', '$location', 'User', '$ }); data = google.visualization.arrayToDataTable(matrix); options = { - title: 'History', + title: window.env.t('history'), backgroundColor: { fill: 'transparent' }, @@ -172,7 +172,7 @@ habitrpg.controller("RootCtrl", ['$scope', '$rootScope', '$location', 'User', '$ ------------------------ */ $scope.castStart = function(spell) { - if (User.user.stats.mp < spell.mana) return Notification.text("Not enough mana."); + if (User.user.stats.mp < spell.mana) return Notification.text(window.env.t('notEnoughMana')); $rootScope.applyingAction = true; $scope.spell = spell; if (spell.target == 'self') { @@ -187,7 +187,7 @@ habitrpg.controller("RootCtrl", ['$scope', '$rootScope', '$location', 'User', '$ $scope.castEnd = function(target, type, $event){ if (!$rootScope.applyingAction) return; $event && ($event.stopPropagation(),$event.preventDefault()); - if ($scope.spell.target != type) return Notification.text("Invalid target"); + if ($scope.spell.target != type) return Notification.text(window.env.t('invalidTarget')); $scope.spell.cast(User.user, target); User.save(); @@ -198,11 +198,11 @@ habitrpg.controller("RootCtrl", ['$scope', '$rootScope', '$location', 'User', '$ $http.post('/api/v2/user/class/cast/'+spell.key+'?targetType='+type+'&targetId='+targetId) .success(function(){ - var msg = "You cast " + spell.text; + var msg = window.env.t('youCast', {spell: spell.text}); switch (type) { - case 'task': msg += ' on ' + target.text + '.';break; - case 'user': msg += ' on ' + target.profile.name + '.';break; - case 'party': msg += ' for the Party.';break; + 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); }); diff --git a/public/js/controllers/settingsCtrl.js b/public/js/controllers/settingsCtrl.js index 9d56526bd5..1bce807c7a 100644 --- a/public/js/controllers/settingsCtrl.js +++ b/public/js/controllers/settingsCtrl.js @@ -38,7 +38,7 @@ habitrpg.controller('SettingsCtrl', var dayStart = +User.user.preferences.dayStart; if (_.isNaN(dayStart) || dayStart < 0 || dayStart > 24) { dayStart = 0; - return alert('Please enter a number between 0 and 24'); + return alert(window.env.t('enterNumber')); } User.set({'preferences.dayStart': dayStart}); } @@ -65,11 +65,11 @@ habitrpg.controller('SettingsCtrl', $scope.changePassword = function(changePass){ if (!changePass.oldPassword || !changePass.newPassword || !changePass.confirmNewPassword) { - return alert("Please fill out all fields"); + return alert(window.env.t('fillAll')); } $http.post(API_URL + '/api/v2/user/change-password', changePass) .success(function(){ - alert("Password successfully changed"); + alert(window.env.t('passSuccess')); $scope.changePass = {}; }) .error(function(data){ diff --git a/public/js/controllers/tasksCtrl.js b/public/js/controllers/tasksCtrl.js index 5dd8fc9369..1bde5c0bed 100644 --- a/public/js/controllers/tasksCtrl.js +++ b/public/js/controllers/tasksCtrl.js @@ -38,7 +38,7 @@ habitrpg.controller("TasksCtrl", ['$scope', '$location', 'User','Notification', }; $scope.removeTask = function(list, $index) { - if (!confirm("Are you sure you want to delete this task?")) return; + if (!confirm(window.env.t('sureDelete'))) return; User.user.ops.deleteTask({params:{id:list[$index].id}}) }; diff --git a/public/js/controllers/userCtrl.js b/public/js/controllers/userCtrl.js index 43abc3e327..43c1996296 100644 --- a/public/js/controllers/userCtrl.js +++ b/public/js/controllers/userCtrl.js @@ -18,7 +18,7 @@ habitrpg.controller("UserCtrl", ['$rootScope', '$scope', '$location', 'User', '$ $scope.changeClass = function(klass){ if (!klass) { - if (!confirm("Are you sure? This will reset your character's class and allocated points (you'll get them all back to re-allocate), and costs 3 gems")) + if (!confirm(window.env.t('sureReset'))) return; return User.user.ops.changeClass({}); } @@ -52,10 +52,10 @@ habitrpg.controller("UserCtrl", ['$rootScope', '$scope', '$location', 'User', '$ var cost = fullSet ? 1.25 : 0.5; // 5G per set, 2G per individual if (fullSet) { - if (confirm("Purchase for 5 Gems?") !== true) return; + if (confirm(window.env.t('purchaseFor5')) !== true) return; if (User.user.balance < cost) return $rootScope.openModal('buyGems'); } else if (!User.user.fns.dotGet('purchased.' + path)) { - if (confirm("Purchase for 2 Gems?") !== true) return; + if (confirm(window.env.t('purchaseFor2')) !== true) return; if (User.user.balance < cost) return $rootScope.openModal('buyGems'); } User.user.ops.unlock({query:{path:path}}) diff --git a/public/js/directives/directives.js b/public/js/directives/directives.js index 2d36fea375..7a8e9d71fd 100644 --- a/public/js/directives/directives.js +++ b/public/js/directives/directives.js @@ -26,7 +26,7 @@ habitrpg.directive('habitrpgAdsense', function() { template: '
', link: function ($scope, element, attrs) {} } -}) +}); habitrpg.directive('whenScrolled', function() { return function(scope, elm, attr) { @@ -85,21 +85,21 @@ habitrpg scope.main = attrs.main; $rootScope.lists = [ { - header: env.t('habits'), + header: window.env.t('habits'), type: 'habit', - placeHolder: env.t('newHabit') + placeHolder: window.env.t('newHabit') }, { - header: env.t('dailies'), + header: window.env.t('dailies'), type: 'daily', - placeHolder: env.t('newDaily') + placeHolder: window.env.t('newDaily') }, { - header: env.t('todos'), + header: window.env.t('todos'), type: 'todo', - placeHolder: env.t('newTodo') + placeHolder: window.env.t('newTodo') }, { - header: env.t('rewards'), + header: window.env.t('rewards'), type: 'reward', - placeHolder: env.t('newReward') + placeHolder: window.env.t('newReward') } ]; diff --git a/public/js/env.js b/public/js/env.js new file mode 100644 index 0000000000..8a6611cd90 --- /dev/null +++ b/public/js/env.js @@ -0,0 +1,20 @@ +"use strict"; + +window.env = window.env || {}; //FIX tests + +// If Moment.js is loaded, +if(window.moment && window.env.language && window.env.language.momentLang && window.env.language.momentLangCode){ + var head = document.getElementsByTagName('head')[0]; + var script = document.createElement('script'); + script.type = 'text/javascript'; + script.text = window.env.language.momentLang; + head.appendChild(script); + window.moment.lang(window.env.language.momentLangCode); +} + +window.env.t = function(stringName, vars){ + var string = window.env.translations[stringName]; + if(!string) return window._.template(window.env.translations.stringNotFound, {string: stringName}); + + return vars === undefined ? string : window._.template(string, vars); +} \ No newline at end of file diff --git a/public/js/services/authServices.js b/public/js/services/authServices.js index d1667c959a..9e55d7af32 100644 --- a/public/js/services/authServices.js +++ b/public/js/services/authServices.js @@ -32,7 +32,7 @@ factory('Facebook', $http.post(API_URL + '/api/v2/user/auth/facebook', data).success(function(data, status, headers, config) { User.authenticate(data.id, data.token, function(err) { if (!err) { - alert('Login successful!'); + alert(window.env.t('loginSuccess')); $location.path("/habit"); } }); diff --git a/public/js/services/guideServices.js b/public/js/services/guideServices.js index c512c72e23..40c4dd9131 100644 --- a/public/js/services/guideServices.js +++ b/public/js/services/guideServices.js @@ -18,58 +18,58 @@ angular.module('guideServices', []). var tourSteps = [ { element: ".main-herobox", - title: "Welcome to HabitRPG", - content: "Welcome to HabitRPG, a habit-tracker which treats your goals like a Role Playing Game. I'm Justin, your guide!", + title: window.env.t('welcomeHabit'), + content: window.env.t('welcomeHabitT1') + "Justin," + window.env.t('welcomeHabitT2'), }, { element: ".main-herobox", - title: "Your Avatar", - content: "This is your avatar. It represents you in the world of Habitica. As you accomplish goals, your avatar will gain levels, earn gold, and equip itself for further challenges ahead.", + title: window.env.t('yourAvatar'), + content: window.env.t('yourAvatarText'), }, { element: ".main-herobox", - title: "Avatar Customization", - content: "You can customize your avatar by clicking anywhere in this box. Change your body type, hair color, skin color, and more from this menu. You can also find a number of HabitRPG's exciting social features by clicking through tabs on the customization page.", + title: window.env.t('avatarCustom'), + content: window.env.t('avatarCustomText'), }, { element: "#bars", - title: "Hit Points", - content: "The red bar tracks your avatar's health points. Whenever you fail to meet a goal, you take damage and lose health. If your health bar reaches zero, you die. Dying results in the loss of one level, all your gold, and a piece of equipment.", + title: window.env.t('hitPoints'), + content: window.env.t('hitPointsText'), }, { element: "#bars", - title: "Experience Points", - content: "The yellow bar tracks your avatar's experience points. Whenever you succeed in achieving a goal, you gain both gold and experience. When your experience bar maxes out, you gain a level. Gaining levels is how you unlock new and exciting features on HabitRPG.", + title: window.env.t('expPoints'), + content: window.env.t('expPointsText'), }, { element: "ul.habits", - title: "Types of Goals", - content: "HabitRPG allows you to track your goals in three different ways. These goals are categorized in columns as Habits, Dailies, or To-Dos.", + title: window.env.t('typeGoals'), + content: window.env.t('typeGoalsText'), placement: "top" }, { element: "ul.habits", - title: "Habits", - content: "Habits are goals that you constantly track. They can be given plus or minus values, allowing you to gain experience and gold for good habits or lose health for bad ones.", + title: window.env.t('habits'), + content: window.env.t('tourHabits'), placement: "top" }, { element: "ul.dailys", - title: "Dailies", - content: "Dailies are goals that you want to complete once a day. Checking off a daily reaps experience and gold. Failing to check off your daily before the day resets results in a loss of health. You can change your day start settings from the options menu.", + title: window.env.t('dailies'), + content: window.env.t('tourDailies'), placement: "top" }, { element: "ul.todos", - title: "To-Dos", - content: "To-Dos are one-off goals that you can get to eventually. While it is possible to set a deadline on a to-do, they are not required. To-Dos make for a quick and easy way to gain experience.", + title: window.env.t('todos'), + content: window.env.t('tourTodos'), placement: "top" }, { element: "ul.main-list.rewards", - title: "Rewards", - content: "All that gold you earned will allow you to reward yourself with either custom or in-game prizes. Buy them liberally – rewarding yourself is integral in forming good habits.", + title: window.env.t('rewards'), + content: window.env.t('tourRewards'), placement: "top" }, { element: "ul.habits li:first-child", - title: "Hover over comments", - content: "You can add comments to your tasks by clicking the edit icon. Hover over each task's comment for more details about how HabitRPG works. When you're ready to get started, you can delete the existing tasks and add your own.", + title: window.env.t('hoverOver'), + content: window.env.t('hoverOverText'), placement: "right" }, { element: "ul.habits li:first-child", - title: "Unlock New Features", - content: "That's all you need to know for now, but I'll be back as you level up to let you know about new features you've unlocked. Each new feature will give you more incentives to accomplish your goals. Find out more at the HabitRPG Wiki or let yourself be surprised. Good luck!", + title: window.env.t('unlockFeatures'), + content: window.env.t('unlockFeaturesT1') + "" + window.env.t('habitWiki') + "" + window.env.t('unlockFeaturesT2'), placement: "right" } ]; @@ -96,7 +96,7 @@ angular.module('guideServices', []). var showPopover = function(selector, title, html, placement) { if (!placement) placement = 'bottom'; $(selector).popover('destroy'); - var button = ""; + var button = ""; html = "
" + html + '
' + button + '
'; $(selector).popover({ title: title, @@ -109,19 +109,19 @@ angular.module('guideServices', []). $rootScope.$watch('user.flags.customizationsNotification', function(after, before) { if (alreadyShown(before, after)) return; - showPopover('.main-herobox', 'Customize Your Avatar', "Click your avatar to customize your appearance.", 'bottom'); + showPopover('.main-herobox', window.env.t('customAvatar'), window.env.t('customAvatarText'), 'bottom'); }); $rootScope.$watch('user.flags.itemsEnabled', function(after, before) { if (alreadyShown(before, after)) return; - var html = "Congratulations, you have unlocked the Item Store! You can now buy weapons, armor, potions, etc. Read each item's comment for more information."; - showPopover('div.rewards', 'Item Store Unlocked', html, 'left'); + var html = window.env.t('storeUnlockedText'); + showPopover('div.rewards', window.env.t('storeUnlocked'), html, 'left'); }); $rootScope.$watch('user.flags.partyEnabled', function(after, before) { if (alreadyShown(before, after)) return; - var html = "Be social, join a party and play Habit with your friends! You'll be better at your habits with accountability partners. Click User -> Options -> Party, and follow the instructions. LFG anyone?"; - showPopover('.user-menu', 'Party System', html, 'bottom'); + var html = window.env.t('partySysText'); + showPopover('.user-menu', window.env.t('partySys'), html, 'bottom'); }); $rootScope.$watch('user.flags.dropsEnabled', function(after, before) { @@ -152,8 +152,8 @@ angular.module('guideServices', []). $timeout(function(){tour.goTo(0)}); }), element: '.equipment-tab', - title: "Class Gear", - content: "First: don't panic! Your old gear is in your inventory, and you're now wearing your apprentice " + User.user.stats.class + " equipment. Wearing your class's gear grants you a 50% bonus to stats. However, feel free to switch back to your old gear." + title: window.env.t('classGear'), + content: window.env.t('classGearText', {klass: User.user.stats.class}) }, { path: '/#/options/profile/stats', @@ -161,21 +161,21 @@ angular.module('guideServices', []). $timeout(function(){tour.goTo(1)}); }), element: ".allocate-stats", - title: "Stats", - content: "These are your class's stats, they affect the game-play. Each time you level up, you get one point to allocate to particular stat. Hover over each stat for more information.", + title: window.env.t('stats'), + content: window.env.t('classStats'), }, { element: ".auto-allocate", - title: "Auto Allocate", + title: window.env.t('autoAllocate'), placement: 'left', - content: "If 'automatic allocation' is checked, your avatar gains stats automatically based on your tasks' attributes, which you can find in TASK > Edit > Advanced > Attributes. Eg, if you hit the gym often, and your 'Gym' Daily is set to 'Physical', you'll gain STR automatically.", + content: window.env.t('autoAllocateText'), }, { element: ".meter.mana", - title: "Spells", - content: "You can now unlock class-specific spells. You'll see your first at level 11. Your mana replenishes 10 points per day, plus 1 point per completed To-Do." + title: window.env.t('spells'), + content: window.env.t('spellsText') + "" + window.env.t('toDo') + "." }, { orphan: true, - title: "Read More", - content: "For more information on the class-system, see Wikia." + title: window.env.t('readMore'), + content: window.env.t('moreClass') + "Wikia." } ]; _.each(tourSteps, function(step){ diff --git a/public/js/services/notificationServices.js b/public/js/services/notificationServices.js index 3b6cb82284..323f542d92 100644 --- a/public/js/services/notificationServices.js +++ b/public/js/services/notificationServices.js @@ -45,11 +45,11 @@ angular.module("notificationServices", []) coins: coins, hp: function(val) { // don't show notifications if user dead - growl("  " + sign(val) + " " + round(val) + " HP", 'hp'); + growl("  " + sign(val) + " " + round(val) + " " + window.env.t('hp'), 'hp'); }, exp: function(val) { if (val < -50) return; // don't show when they level up (resetting their exp) - growl("  " + sign(val) + " " + round(val) + " XP", 'xp'); + growl("  " + sign(val) + " " + round(val) + " " + window.env.t('xp'), 'xp'); }, gp: function(val, bonus) { growl(sign(val) + " " + coins(val - bonus), 'gp'); @@ -58,19 +58,19 @@ angular.module("notificationServices", []) growl(val); }, lvl: function(){ - growl('  Level Up!', 'lvl'); + growl(' ' + window.env.t('levelUp'), 'lvl'); }, death: function(){ - growl("  Respawn!", "death"); + growl(" " + window.env.t('respawn'), "death"); }, error: function(error){ growl("  " + error, "danger"); }, mp: function(val) { - growl("  " + sign(val) + " " + round(val) + " MP", 'mp'); + growl("  " + sign(val) + " " + round(val) + " " + window.env.t('mp'), 'mp'); }, crit: function(val) { - growl("  Critical Hit! Bonus: " + Math.round(val) + "%", 'crit'); + growl(" " + window.env.t('critBonus') + Math.round(val) + "%", 'crit'); }, drop: function(val) { growl("  " + val, 'drop'); diff --git a/public/manifest.json b/public/manifest.json index 59fcf38367..142fc83361 100644 --- a/public/manifest.json +++ b/public/manifest.json @@ -32,6 +32,8 @@ "bower_components/habitrpg-shared/dist/habitrpg-shared.js", + "js/env.js", + "js/app.js", "js/services/sharedServices.js", "js/services/authServices.js", @@ -78,6 +80,7 @@ "bower_components/bootstrap/dist/js/bootstrap.js", "bower_components/angular-loading-bar/build/loading-bar.js", + "js/env.js", "js/static.js", "js/services/notificationServices.js", "bower_components/habitrpg-shared/script/userServices.js", diff --git a/src/middleware.js b/src/middleware.js index 4450133f01..edda3917a5 100644 --- a/src/middleware.js +++ b/src/middleware.js @@ -113,12 +113,12 @@ var getManifestFiles = function(page){ var translations = {}; var loadTranslations = function(locale){ - var files = require(path.join(__dirname, "/../node_modules/habitrpg-shared/locales/", locale, 'app.json')).files; + var files = fs.readdirSync(path.join(__dirname, "/../node_modules/habitrpg-shared/locales/", locale)); translations[locale] = {}; _.each(files, function(file){ _.merge(translations[locale], require(path.join(__dirname, "/../node_modules/habitrpg-shared/locales/", locale, file))); }); -} +}; // First fetch english so we can merge with missing strings in other languages loadTranslations('en'); @@ -193,7 +193,11 @@ module.exports.locals = function(req, res, next) { getUserLanguage(req, function(err, language){ if(err) return res.json(500, {err: err}); - language.momentLang = (momentLangs[language.code] || undefined); + var isStaticPage = req.url.split('/')[1] === 'static'; // If url contains '/static/' + console.log(isStaticPage) + + // Load moment.js language file only when not on static pages + language.momentLang = ((!isStaticPage && momentLangs[language.code])|| undefined); res.locals.habitrpg = { NODE_ENV: nconf.get('NODE_ENV'), @@ -205,6 +209,7 @@ module.exports.locals = function(req, res, next) { getBuildUrl: getBuildUrl, avalaibleLanguages: avalaibleLanguages, language: language, + isStaticPage: isStaticPage, translations: translations[language.code], t: function(stringName, vars){ var string = translations[language.code][stringName]; diff --git a/src/routes/pages.js b/src/routes/pages.js index 1458a6f7ca..8ad551a8b9 100644 --- a/src/routes/pages.js +++ b/src/routes/pages.js @@ -18,9 +18,7 @@ router.get('/', middleware.locals, function(req, res) { // -------- Marketing -------- router.get('/static/front', middleware.locals, function(req, res) { - var env = res.locals.habitrpg; - env.isFrontPage = true; - res.render('static/front', {env: env}); + res.render('static/front', {env: res.locals.habitrpg}); }); router.get('/static/privacy', middleware.locals, function(req, res) { diff --git a/views/options/social/tavern.jade b/views/options/social/tavern.jade index 8eff0f5401..2f83b3bd33 100644 --- a/views/options/social/tavern.jade +++ b/views/options/social/tavern.jade @@ -66,7 +66,7 @@ table.table.table-striped tr td - a.label.label-contributor-1(ng-click='toggleUserTier($event)')=env.t('friendBadge') + a.label.label-contributor-1(ng-click='toggleUserTier($event)')=env.t('friend') + ' (1-2)' div(style='display:none;') p span.achievement.achievement-firefox @@ -77,7 +77,7 @@ !=env.t('friendSecond') tr td - a.label.label-contributor-3(ng-click='toggleUserTier($event)')=env.t('eliteBadge') + a.label.label-contributor-3(ng-click='toggleUserTier($event)')=env.t('elite') + ' (3-4)' div(style='display:none;') p span.shop-sprite.item-img(class='shop_head_special_1') @@ -88,7 +88,7 @@ !=env.t('eliteFourth') tr td - a.label.label-contributor-5(ng-click='toggleUserTier($event)')=env.t('championBadge') + a.label.label-contributor-5(ng-click='toggleUserTier($event)')=env.t('champion') + ' (5-6)' div(style='display:none;') p span.shop-sprite.item-img(class='shop_shield_special_1') @@ -99,13 +99,13 @@ !=env.t('championSixth') tr td - a.label.label-contributor-7(ng-click='toggleUserTier($event)')=env.t('legendaryBadge') + a.label.label-contributor-7(ng-click='toggleUserTier($event)')=env.t('legendary') + ' (7)' div(style='display:none;') p !=env.t('legSeventh') tr td - a.label.label-contributor-8(ng-click='toggleUserTier($event)')=env.t('heroicBadge') + a.label.label-contributor-8(ng-click='toggleUserTier($event)')=env.t('heroic') div(style='display:none;') p=env.t('heroicText') tr diff --git a/views/shared/footer.jade b/views/shared/footer.jade index 231ab211e0..c7a9644470 100644 --- a/views/shared/footer.jade +++ b/views/shared/footer.jade @@ -10,8 +10,8 @@ footer.footer(ng-controller='FooterCtrl') a(href='https://play.google.com/store/apps/details?id=com.ocdevel.habitrpg', target='_blank')=env.t('mobileAndroid') .col-sm-3 h4=env.t('footerCompany') - ul.list-unstyled.list-unstyled - if (!env.isFrontPage) + ul.list-unstyled + if (!env.isStaticPage) li .btn.btn-small.btn-success(ng-click='openModal("buyGems")') span.glyphicon.glyphicon-heart