diff --git a/common/locales/en/rebirth.json b/common/locales/en/rebirth.json
index 9e450f78f4..7ff4b9c349 100644
--- a/common/locales/en/rebirth.json
+++ b/common/locales/en/rebirth.json
@@ -23,5 +23,6 @@
"rebirthOrb100": "Used an Orb of Rebirth to start over after attaining Level 100 or higher",
"rebirthPop": "Begin a new character at Level 1 while retaining achievements, collectibles, and tasks with history.",
"rebirthName": "Orb of Rebirth",
- "reborn": "Reborn, max level <%= reLevel %>"
+ "reborn": "Reborn, max level <%= reLevel %>",
+ "confirmReborn": "Are you sure?"
}
diff --git a/common/locales/en/tasks.json b/common/locales/en/tasks.json
index f3d677f6a5..a8e2fed982 100644
--- a/common/locales/en/tasks.json
+++ b/common/locales/en/tasks.json
@@ -90,6 +90,7 @@
"fortifyPop": "Return all tasks to neutral value (yellow color), and restore all lost Health.",
"fortify": "Fortify",
"fortifyText": "Fortify will return all your tasks to a neutral (yellow) state, as if you'd just added them, and top your Health off to full. This is great if all your red tasks are making the game too hard, or all your blue tasks are making the game too easy. If starting fresh sounds much more motivating, spend the Gems and catch a reprieve!",
+ "confirmFortify": "Are you sure?",
"sureDelete": "Are you sure you want to delete the <%= taskType %> with the text \"<%= taskText %>\"?",
"streakCoins": "Streak Bonus!",
"pushTaskToTop": "Push task to top. Hold ctrl or cmd to push to bottom.",
diff --git a/test/spec/controllers/settingsCtrlSpec.js b/test/spec/controllers/settingsCtrlSpec.js
index 2950b235d6..858ca14180 100644
--- a/test/spec/controllers/settingsCtrlSpec.js
+++ b/test/spec/controllers/settingsCtrlSpec.js
@@ -10,6 +10,12 @@ describe('Settings Controller', function() {
set: sandbox.stub(),
user: user
};
+
+ User.user.ops = {
+ reroll: sandbox.stub(),
+ rebirth: sandbox.stub(),
+ };
+
$provide.value('User', User);
$provide.value('Guide', sandbox.stub());
});
@@ -83,4 +89,81 @@ describe('Settings Controller', function() {
});
});
});
+
+ describe('#reroll', function() {
+ beforeEach(function() {
+ scope.clickReroll(document.createElement('div'));
+ });
+
+ it('destroys the previous popover if it exists', function() {
+ expect(scope.popoverEl).to.exist;
+ sandbox.spy($.fn, 'popover');
+ scope.reroll(false);
+
+ $.fn.popover.should.have.been.calledWith('destroy');
+ });
+
+ it('doesn\'t call reroll when not confirmed', function() {
+ scope.reroll(false);
+ user.ops.reroll.should.not.have.been.called;
+ });
+
+ it('calls reroll on the user when confirmed and navigates to tasks', function() {
+ sandbox.stub(rootScope.$state, 'go');
+ scope.reroll(true);
+
+ user.ops.reroll.should.have.been.calledWith({});
+ rootScope.$state.go.should.have.been.calledWith('tasks');
+ });
+ });
+
+ describe('#clickReroll', function() {
+ it('displays a confirmation popover for the user', function() {
+ sandbox.spy($.fn, 'popover');
+ scope.clickReroll(document.createElement('div'));
+
+ $.fn.popover.should.have.been.calledWith('destroy');
+ $.fn.popover.should.have.been.called;
+ $.fn.popover.should.have.been.calledWith('show');
+ });
+ });
+
+ describe('#rebirth', function() {
+ beforeEach(function() {
+ scope.clickRebirth(document.createElement('div'));
+ });
+
+ it('destroys the previous popover if it exists', function() {
+ expect(scope.popoverEl).to.exist;
+ sandbox.spy($.fn, 'popover');
+ scope.rebirth(false);
+
+ $.fn.popover.should.have.been.calledWith('destroy');
+ });
+
+ it('doesn\'t call rebirth when not confirmed', function() {
+ scope.rebirth(false);
+ user.ops.rebirth.should.not.have.been.called;
+ });
+
+ it('calls rebirth on the user when confirmed and navigates to tasks', function() {
+ sandbox.stub(rootScope.$state, 'go');
+ scope.rebirth(true);
+
+ user.ops.rebirth.should.have.been.calledWith({});
+ rootScope.$state.go.should.have.been.calledWith('tasks');
+ });
+ });
+
+ describe('#clickRebirth', function() {
+ it('displays a confirmation popover for the user', function() {
+ sandbox.spy($.fn, 'popover');
+ scope.clickRebirth(document.createElement('div'));
+
+ $.fn.popover.should.have.been.calledWith('destroy');
+ $.fn.popover.should.have.been.called;
+ $.fn.popover.should.have.been.calledWith('show');
+ });
+ });
+
});
diff --git a/website/public/js/controllers/guildsCtrl.js b/website/public/js/controllers/guildsCtrl.js
index 020ebbe956..4c9259eaf8 100644
--- a/website/public/js/controllers/guildsCtrl.js
+++ b/website/public/js/controllers/guildsCtrl.js
@@ -57,27 +57,29 @@ habitrpg.controller("GuildsCtrl", ['$scope', 'Groups', 'User', 'Challenges', '$r
$scope.popoverEl = $($event.target);
var html, title;
Challenges.Challenge.query(function(challenges) {
- challenges = _.pluck(_.filter(challenges, function(c) {
- return c.group._id == group._id;
- }), '_id');
- if (_.intersection(challenges, User.user.challenges).length > 0) {
- html = $compile(
- '' + window.env.t('removeTasks') + '
\n' + window.env.t('keepTasks') + '
\n' + window.env.t('cancel') + '
'
- )($scope);
- title = window.env.t('leaveGroupCha');
- } else {
- html = $compile(
- '' + window.env.t('confirm') + '
\n' + window.env.t('cancel') + '
'
- )($scope);
- title = window.env.t('leaveGroup')
- }
- $scope.popoverEl.popover('destroy').popover({
+ challenges = _.pluck(_.filter(challenges, function(c) {
+ return c.group._id == group._id;
+ }), '_id');
+
+ if (_.intersection(challenges, User.user.challenges).length > 0) {
+ html = $compile(
+ '' + window.env.t('removeTasks') + '
\n' + window.env.t('keepTasks') + '
\n' + window.env.t('cancel') + '
'
+ )($scope);
+ title = window.env.t('leaveGroupCha');
+ } else {
+ html = $compile(
+ '' + window.env.t('confirm') + '
\n' + window.env.t('cancel') + '
'
+ )($scope);
+ title = window.env.t('leaveGroup')
+ }
+
+ $scope.popoverEl.popover('destroy').popover({
html: true,
placement: 'top',
trigger: 'manual',
- title: title,
+ title: title,
content: html
- }).popover('show');
+ }).popover('show');
});
}
diff --git a/website/public/js/controllers/settingsCtrl.js b/website/public/js/controllers/settingsCtrl.js
index e785c7c02e..32f30290bf 100644
--- a/website/public/js/controllers/settingsCtrl.js
+++ b/website/public/js/controllers/settingsCtrl.js
@@ -2,8 +2,8 @@
// Make user and settings available for everyone through root scope.
habitrpg.controller('SettingsCtrl',
- ['$scope', 'User', '$rootScope', '$http', 'ApiUrl', 'Guide', '$location', '$timeout', 'Content', 'Notification', 'Shared',
- function($scope, User, $rootScope, $http, ApiUrl, Guide, $location, $timeout, Content, Notification, Shared) {
+ ['$scope', 'User', '$rootScope', '$http', 'ApiUrl', 'Guide', '$location', '$timeout', 'Content', 'Notification', 'Shared', '$compile',
+ function($scope, User, $rootScope, $http, ApiUrl, Guide, $location, $timeout, Content, Notification, Shared, $compile) {
// FIXME we have this re-declared everywhere, figure which is the canonical version and delete the rest
// $scope.auth = function (id, token) {
@@ -90,14 +90,54 @@ habitrpg.controller('SettingsCtrl',
$scope.availableFormats = ['MM/dd/yyyy','dd/MM/yyyy', 'yyyy/MM/dd'];
- $scope.reroll = function(){
- User.user.ops.reroll({});
- $rootScope.$state.go('tasks');
+ $scope.reroll = function(confirm){
+ $scope.popoverEl.popover('destroy')
+
+ if (confirm) {
+ User.user.ops.reroll({});
+ $rootScope.$state.go('tasks');
+ }
}
- $scope.rebirth = function(){
- User.user.ops.rebirth({});
- $rootScope.$state.go('tasks');
+ $scope.clickReroll = function($event){
+ $scope.popoverEl = $($event.target);
+
+ var html = $compile(
+ '' + window.env.t('confirm') + '
\n' + window.env.t('cancel') + '
'
+ )($scope);
+
+ $scope.popoverEl.popover('destroy').popover({
+ html: true,
+ placement: 'top',
+ trigger: 'manual',
+ title: window.env.t('confirmFortify'),
+ content: html
+ }).popover('show');
+ }
+
+ $scope.rebirth = function(confirm){
+ $scope.popoverEl.popover('destroy')
+
+ if (confirm) {
+ User.user.ops.rebirth({});
+ $rootScope.$state.go('tasks');
+ }
+ }
+
+ $scope.clickRebirth = function($event){
+ $scope.popoverEl = $($event.target);
+
+ var html = $compile(
+ '' + window.env.t('confirm') + '
\n' + window.env.t('cancel') + '
'
+ )($scope);
+
+ $scope.popoverEl.popover('destroy').popover({
+ html: true,
+ placement: 'top',
+ trigger: 'manual',
+ title: window.env.t('confirmReborn'),
+ content: html
+ }).popover('show');
}
$scope.changeUser = function(attr, updates){
diff --git a/website/views/shared/modals/rebirth.jade b/website/views/shared/modals/rebirth.jade
index 7870727027..1c61c780c3 100644
--- a/website/views/shared/modals/rebirth.jade
+++ b/website/views/shared/modals/rebirth.jade
@@ -46,7 +46,7 @@ script(type='text/ng-template', id='modals/rebirth.html')
a.btn.btn-success(ng-click='openModal("buyGems",{track:"Gems > Rebirth"})')=env.t('buyMoreGems')
span.gem-cost=env.t('notEnoughGems')
span(ng-if='user.balance >= 2 || user.stats.lvl >= 100', ng-controller='SettingsCtrl')
- a.btn.btn-danger(ng-click='$close(); rebirth()')=env.t('beReborn')
+ a.btn.btn-danger(ng-click='clickRebirth($event)')=env.t('beReborn')
span.gem-cost(ng-if='user.stats.lvl < 100')
| 8
=env.t('gems')
diff --git a/website/views/shared/modals/reroll.jade b/website/views/shared/modals/reroll.jade
index 5d05124385..9fc3ce55ec 100644
--- a/website/views/shared/modals/reroll.jade
+++ b/website/views/shared/modals/reroll.jade
@@ -12,7 +12,7 @@ script(type='text/ng-template', id='modals/reroll.html')
a.btn.btn-success(ng-click='openModal("buyGems",{track:"Gems > Reroll"})')=env.t('buyMoreGems')
span.gem-cost=env.t('notEnoughGems')
span(ng-if='user.balance >= 1', ng-controller='SettingsCtrl')
- a.btn.btn-danger(ng-click='$close(); reroll()')=env.t('fortify')
+ a.btn.btn-danger(ng-click='clickReroll($event)')=env.t('fortify')
span.gem-cost
| 4
= env.t('gems')