Adjustments to custom day start

This commit is contained in:
Blade Barringer
2015-09-05 15:32:49 -05:00
parent d45602c340
commit 9ce6144fa4
7 changed files with 170 additions and 44 deletions

View File

@@ -39,6 +39,9 @@
"xml": "(XML)",
"json": "(JSON)",
"customDayStart": "Custom Day Start",
"changeCustomDayStart": "Change Custom Day Start?",
"sureChangeCustomDayStart": "Are you sure you want to change your custom day start?",
"nextCron": "WARNING: Your dailies will reset next on <%= time %>.",
"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.",

View File

@@ -66,13 +66,6 @@ api.startOfDay = (options={}) ->
dayStart.subtract({days:1})
dayStart
api.startOfDayAllowsFuture = (options={}) ->
# Use this version to use if you need the result even if the offset would cause today's day start to be in the future.
o = sanitizeOptions(options)
moment(o.now).startOf('day').add({hours:o.dayStart})
api.dayMapping = {0:'su',1:'m',2:'t',3:'w',4:'th',5:'f',6:'s'}
###
@@ -360,18 +353,6 @@ Friendly timestamp
###
api.friendlyTimestamp = (timestamp) -> moment(timestamp).format('MM/DD h:mm:ss a')
###
ISO timestamp
###
api.isoTimestamp = (timestamp) -> moment(timestamp).toISOString()
###
plain timestamp
###
api.momentTimestamp = (timestamp) -> moment(timestamp)
###
Does user have new chat messages?
###

View File

@@ -0,0 +1,109 @@
'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');
});
context('failures', function() {
var tests = {
'blank': '',
'not a whole number': 5.3,
'not a number': 'foo',
'less than 0': -5,
'more than 24': 25
};
for (var test in tests) {
it('returns with an alert if number is ' + test, function() {
scope.openDayStartModal(tests[test]);
expect(rootScope.openModal).to.not.be.called;
expect(window.alert).to.be.calledOnce;
expect(window.alert).to.be.calledWith(env.t('enterNumber'));
});
}
});
context('success', function() {
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

@@ -64,30 +64,25 @@ habitrpg.controller('SettingsCtrl',
$scope.dayStart = User.user.preferences.dayStart;
function updateLastCron(oldDayStart, newDayStart){
var getOldStart = Shared.startOfDayAllowsFuture({ dayStart: oldDayStart});
var getNewStart = Shared.startOfDayAllowsFuture({ dayStart: newDayStart});
var lastCron = User.user.lastCron;
var momentLastCron = Shared.momentTimestamp(lastCron);
var isoNewStart = Shared.isoTimestamp(getNewStart);
alert('Times are oldstart'+Shared.friendlyTimestamp(getOldStart)+' lastcron '+Shared.friendlyTimestamp(lastCron)+' and newstart '+Shared.friendlyTimestamp(getNewStart));
if (getOldStart < momentLastCron && momentLastCron < getNewStart) {
alert('Setting lastcron to '+Shared.friendlyTimestamp(getNewStart));
User.set({ 'lastCron' : isoNewStart});
}
};
$scope.openDayStartModal = function(dayStart) {
var flooredDayStart = Math.floor(dayStart);
$scope.saveDayStart = function(varDayStart) {
var oldDayStart = User.user.preferences.dayStart;
var newDayStart = varDayStart;
if ( newDayStart != Math.floor(newDayStart) || newDayStart < 0 || newDayStart > 24 ) {
newDayStart = 0;
if (dayStart !== flooredDayStart || dayStart < 0 || dayStart > 24 ) {
return alert(window.env.t('enterNumber'));
}
updateLastCron( oldDayStart, newDayStart);
User.set({'preferences.dayStart': Math.floor(newDayStart)});
}
$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;
@@ -210,5 +205,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

@@ -90,10 +90,16 @@ script(type='text/ng-template', id='partials/options.settings.settings.html')
h5=env.t('customDayStartInfo1')
a(ng-click='showCustomDayStartInfo = !showCustomDayStartInfo') {{!showCustomDayStartInfo ? env.t('showMoreMore') : env.t('showMoreLess')}}
h5(ng-if='showCustomDayStartInfo')!=env.t('customDayStartInfo4')
.form-group
.input-group
input.form-control(type='number', min='0', max='23', ng-model='dayStart', ng-blur='saveDayStart(dayStart)')
span.input-group-addon= ':00 (' + env.t('24HrClock') + ')'
.form-horizontal
.form-group
.col-sm-7
.input-group
input.form-control(type='number', min='0', max='23', ng-model='dayStart')
.input-group-addon= ':00 (' + env.t('24HrClock') + ')'
.col-sm-5
br.visible-xs
button.btn.btn-block.btn-primary(ng-click='openDayStartModal(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,15 @@
.text-center
.modal-header
h3=env.t('changeCustomDayStart')
.modal-body
.alert.alert-danger
p=env.t('nextCron', {time: '{{nextCron | date: "M/d/yy \'@\' h:mm a"}}'})
p=env.t('sureChangeCustomDayStart')
.alert.alert-info
div last cron {{user.lastCron}}
.modal-footer
a.btn.btn-default(ng-click='$close()')=env.t('close')
a.btn.btn-danger(ng-click='saveDayStart(); $close()')=env.t('confirm')