Merge pull request #5890 from HabitRPG/change_custom_day_start

Change custom day start to ask for confirmation and prevent immediate cron
This commit is contained in:
Blade Barringer 2015-09-06 13:28:04 -05:00
commit 9896851001
6 changed files with 161 additions and 19 deletions

View file

@ -39,9 +39,10 @@
"xml": "(XML)",
"json": "(JSON)",
"customDayStart": "Custom Day Start",
"24HrClock": "24Hr Clock",
"customDayStartInfo1": "Habitica defaults to check and reset your Dailies at midnight in your own time zone each day. It is recommended that you read the following information before changing it: ",
"customDayStartInfo4": "<strong>Complete all your Dailies before changing the Custom Day Start</strong> or <a href='http://habitica.wikia.com/wiki/Rest_in_the_Inn' target='_blank'>Rest in the Inn</a> that day. Changing your Custom Day Start may cause <a href='http://habitica.wikia.com/wiki/Cron' target='_blank'>Cron</a> to run immediately, but after the first day it works as expected.<br><br><strong>Allow a window of two hours for the change to take effect.</strong> For example, if it is currently set to 0 (midnight), change it before 10pm; if you want to set it to 9pm, change it before 7pm.<br><br>Enter an hour from 0 to 23 (it uses a 24 hour clock). Typing is more effective than arrow keys. Once set, reload the page to confirm that the new value is being displayed.",
"changeCustomDayStart": "Change Custom Day Start?",
"sureChangeCustomDayStart": "Are you sure you want to change your custom day start?",
"nextCron": "Your Dailies will next reset the first time you use Habitica after <%= time %>. Make sure you have completed your Dailies before this time!",
"customDayStartInfo1": "Habitica defaults to check and reset your Dailies at midnight in your own time zone each day. You can customize that time here.",
"misc": "Misc",
"showHeader": "Show Header",
"changePass": "Change Password",

View file

@ -0,0 +1,86 @@
'use strict';
describe('Settings Controller', function() {
var rootScope, scope, user, User, ctrl;
beforeEach(function() {
module(function($provide) {
user = specHelper.newUser();
User = {
set: sandbox.stub(),
user: user
};
$provide.value('User', User);
$provide.value('Guide', sandbox.stub());
});
inject(function(_$rootScope_, _$controller_) {
scope = _$rootScope_.$new();
rootScope = _$rootScope_;
// Load RootCtrl to ensure shared behaviors are loaded
_$controller_('RootCtrl', {$scope: scope, User: User});
ctrl = _$controller_('SettingsCtrl', {$scope: scope, User: User});
});
});
describe('#openDayStartModal', function() {
beforeEach(function() {
sandbox.stub(rootScope, 'openModal');
sandbox.stub(window, 'alert');
});
it('opens the day start modal', function() {
scope.openDayStartModal(5);
expect(rootScope.openModal).to.be.calledOnce;
expect(rootScope.openModal).to.be.calledWith('change-day-start', {scope: scope});
});
it('sets nextCron variable', function() {
expect(scope.nextCron).to.not.exist;
scope.openDayStartModal(5);
expect(scope.nextCron).to.exist;
});
it('calculates the next time cron will run', function() {
var fakeCurrentTime = new Date(2013, 3, 1, 3, 12).getTime();
var expectedTime = new Date(2013, 3, 1, 5, 0, 0).getTime();
sandbox.useFakeTimers(fakeCurrentTime);
scope.openDayStartModal(5);
expect(scope.nextCron).to.eq(expectedTime);
});
it('calculates the next time cron will run and adds a day if cron would have already passed', function() {
var fakeCurrentTime = new Date(2013, 3, 1, 8, 12).getTime();
var expectedTime = new Date(2013, 3, 2, 5, 0, 0).getTime();
sandbox.useFakeTimers(fakeCurrentTime);
scope.openDayStartModal(5);
expect(scope.nextCron).to.eq(expectedTime);
});
});
describe('#saveDayStart', function() {
it('updates user\'s custom day start and last cron', function() {
var fakeCurrentTime = new Date(2013, 3, 1, 8, 12).getTime();
var expectedTime = fakeCurrentTime;
sandbox.useFakeTimers(fakeCurrentTime);
scope.dayStart = 5;
scope.saveDayStart();
expect(User.set).to.be.calledOnce;
expect(User.set).to.be.calledWith({
'preferences.dayStart': 5,
'lastCron': expectedTime
});
});
});
});

View file

@ -62,14 +62,21 @@ habitrpg.controller('SettingsCtrl',
User.set({'flags.newStuff':true});
}
$scope.saveDayStart = function(){
var dayStart = +User.user.preferences.dayStart;
if (_.isNaN(dayStart) || dayStart < 0 || dayStart > 24) {
dayStart = 0;
return alert(window.env.t('enterNumber'));
}
User.set({'preferences.dayStart': dayStart});
}
$scope.dayStart = User.user.preferences.dayStart;
$scope.openDayStartModal = function(dayStart) {
$scope.dayStart = +dayStart;
$scope.nextCron = _calculateNextCron();
$rootScope.openModal('change-day-start', { scope: $scope });
};
$scope.saveDayStart = function() {
User.set({
'preferences.dayStart': Math.floor($scope.dayStart),
'lastCron': +new Date
});
};
$scope.language = window.env.language;
$scope.avalaibleLanguages = window.env.avalaibleLanguages;
@ -192,5 +199,18 @@ habitrpg.controller('SettingsCtrl',
subs["google_6mo"].discount = false;
});
}
function _calculateNextCron() {
$scope.dayStart;
var nextCron = moment().hours($scope.dayStart).minutes(0).seconds(0).milliseconds(0);
var currentHour = moment().format('H');
if (currentHour >= $scope.dayStart) {
nextCron = nextCron.add(1, 'day');;
}
return +nextCron.format('x');
}
}
]);

View file

@ -39,9 +39,14 @@ script(type='text/ng-template', id='partials/options.settings.settings.html')
strong
!=env.t('helpWithTranslation')
hr
.form-horizontal
h5=env.t('dateFormat')
select.form-control(ng-model='user.preferences.dateFormat', ng-options='DF for DF in availableFormats', ng-change='set({"preferences.dateFormat": user.preferences.dateFormat})')
hr
.checkbox
label
input(type='checkbox', ng-click='hideHeader() ', ng-checked='user.preferences.hideHeader!==true')
@ -71,19 +76,34 @@ script(type='text/ng-template', id='partials/options.settings.settings.html')
input(type='checkbox', ng-model='user.preferences.displayInviteToPartyWhenPartyIs1', ng-change='set({"preferences.displayInviteToPartyWhenPartyIs1": user.preferences.displayInviteToPartyWhenPartyIs1 ? true : false})')
span.hint(popover-trigger='mouseenter', popover-placement='right', popover=env.t('displayInviteToPartyWhenPartyIs1'))=env.t('displayInviteToPartyWhenPartyIs1')
// button.btn.btn-default(ng-click='showTour()', popover-placement='right', popover-trigger='mouseenter', popover=env.t('restartTour'))= env.t('showTour')
hr
button.btn.btn-default(ng-click='showBailey()', popover-trigger='mouseenter', popover-placement='right', popover=env.t('showBaileyPop'))= env.t('showBailey')
button.btn.btn-default(ng-click='openRestoreModal()', popover-trigger='mouseenter', popover-placement='right', popover=env.t('fixValPop'))= env.t('fixVal')
button.btn.btn-default(ng-if='user.preferences.disableClasses==true', ng-click='user.ops.changeClass({})', popover-trigger='mouseenter', popover-placement='right', popover=env.t('enableClassPop'))= env.t('enableClass')
div.alert.alert-warning(style='padding:2px;margin-top:7px')
h5=env.t('customDayStart')
h5=env.t('customDayStartInfo1')
a(ng-click='showCustomDayStartInfo = !showCustomDayStartInfo') {{!showCustomDayStartInfo ? env.t('showMoreMore') : env.t('showMoreLess')}}
h5(ng-if='showCustomDayStartInfo')!=env.t('customDayStartInfo4')
hr
h5=env.t('customDayStart')
alert.alert-warning=env.t('customDayStartInfo1')
.form-horizontal
.form-group
.input-group
input.form-control(type='number', min='0', max='23', ng-model='user.preferences.dayStart', ng-blur='saveDayStart()')
span.input-group-addon= ':00 (' + env.t('24HrClock') + ')'
.col-sm-7
select.form-control(ng-model='dayStart')
- var number = 0
while number < 24
- var value = number
- var meridian = number < 12 ? 'AM' : 'PM'
- var hour = number++ % 12
option(value=value) #{hour ? hour : 12}:00 #{meridian}
.col-sm-5
br.visible-xs
button.btn.btn-block.btn-primary(ng-click='openDayStartModal(dayStart)',
ng-disabled='dayStart == user.preferences.dayStart')
| Save Custom Day Start
.personal-options.col-md-6
.panel.panel-default

View file

@ -14,3 +14,7 @@ include ./limited
include ./invite-friends
include ./welcome.jade
include ./low-health.jade
//- Settings
script(type='text/ng-template', id='modals/change-day-start.html')
include ./settings/change-day-start.jade

View file

@ -0,0 +1,11 @@
.text-center
.modal-header
h3=env.t('changeCustomDayStart')
.modal-body
p!=env.t('nextCron', {time: '<strong class="text-danger">{{::nextCron | date: user.preferences.dateFormat + " @ h:mm a"}}</strong>'})
.modal-footer
p.pull-left-sm=env.t('sureChangeCustomDayStart')
a.btn.btn-default(ng-click='$close()')=env.t('close')
a.btn.btn-primary(ng-click='saveDayStart(); $close()')=env.t('confirm')