From 30437e158ebc7dd1913cff4d05007a110c7c1ca2 Mon Sep 17 00:00:00 2001 From: Keith Holliday Date: Fri, 7 Jul 2017 12:14:36 -0600 Subject: [PATCH 1/4] Added check to prevent double cron (#8854) * Added check to prevent double cron * Added then and fix style issues --- .../client-old/js/controllers/notificationCtrl.js | 15 +++++++++++++-- website/client-old/js/services/userServices.js | 2 +- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/website/client-old/js/controllers/notificationCtrl.js b/website/client-old/js/controllers/notificationCtrl.js index 7dc2e3a033..2aaeed4be6 100644 --- a/website/client-old/js/controllers/notificationCtrl.js +++ b/website/client-old/js/controllers/notificationCtrl.js @@ -3,6 +3,8 @@ habitrpg.controller('NotificationCtrl', ['$scope', '$rootScope', 'Shared', 'Content', 'User', 'Guide', 'Notification', 'Analytics', 'Achievement', 'Social', 'Tasks', function ($scope, $rootScope, Shared, Content, User, Guide, Notification, Analytics, Achievement, Social, Tasks) { + var isRunningYesterdailies = false; + $rootScope.$watch('user', function (after, before) { runYesterDailies(); }); @@ -12,6 +14,8 @@ habitrpg.controller('NotificationCtrl', }); function runYesterDailies() { + if (isRunningYesterdailies) return; + var userLastCron = moment(User.user.lastCron).local(); var userDayStart = moment().startOf('day').add({ hours: User.user.preferences.dayStart }); @@ -20,6 +24,8 @@ habitrpg.controller('NotificationCtrl', if (!Boolean(dailys) || dailys.length === 0) return; + isRunningYesterdailies = true; + var yesterDay = moment().subtract('1', 'day').startOf('day').add({ hours: User.user.preferences.dayStart }); var yesterDailies = []; dailys.forEach(function (task) { @@ -31,7 +37,9 @@ habitrpg.controller('NotificationCtrl', }); if (yesterDailies.length === 0) { - User.runCron(); + User.runCron().then(function () { + isRunningYesterdailies = false; + }); return; }; @@ -61,7 +69,10 @@ habitrpg.controller('NotificationCtrl', }); $scope.ageDailies = function () { - User.runCron(); + User.runCron() + .then(function () { + isRunningYesterdailies = false; + }); }; }], }); diff --git a/website/client-old/js/services/userServices.js b/website/client-old/js/services/userServices.js index 7d12ee0c3e..5ba7b008c4 100644 --- a/website/client-old/js/services/userServices.js +++ b/website/client-old/js/services/userServices.js @@ -418,7 +418,7 @@ angular.module('habitrpg') }, runCron: function () { - $http({ + return $http({ method: "POST", url: 'api/v3/cron', }) From b3f9fd09c6e3209c8c9d0a2adad9930edace0067 Mon Sep 17 00:00:00 2001 From: Keith Holliday Date: Fri, 7 Jul 2017 13:35:26 -0600 Subject: [PATCH 2/4] Check for app loading instead of daily count (#8856) --- website/client-old/js/controllers/notificationCtrl.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/client-old/js/controllers/notificationCtrl.js b/website/client-old/js/controllers/notificationCtrl.js index 2aaeed4be6..e66be981f3 100644 --- a/website/client-old/js/controllers/notificationCtrl.js +++ b/website/client-old/js/controllers/notificationCtrl.js @@ -22,7 +22,7 @@ habitrpg.controller('NotificationCtrl', if (!User.user.needsCron) return; var dailys = User.user.dailys; - if (!Boolean(dailys) || dailys.length === 0) return; + if (!$rootScope.appLoaded) return; isRunningYesterdailies = true; From 3fa0b72ffee8d8199d4274fb44d978844c18687b Mon Sep 17 00:00:00 2001 From: Keith Holliday Date: Fri, 7 Jul 2017 19:46:54 -0600 Subject: [PATCH 3/4] Added assumption when no time is supplied (#8855) * Added assumption when no time is supplied * Changed format of date * Set now options when date is specified --- .../integration/tasks/GET-tasks_user.test.js | 27 ++++++++++++++++++- website/common/script/cron.js | 1 + website/server/libs/taskManager.js | 21 ++++++++++++--- 3 files changed, 45 insertions(+), 4 deletions(-) diff --git a/test/api/v3/integration/tasks/GET-tasks_user.test.js b/test/api/v3/integration/tasks/GET-tasks_user.test.js index 87af87d7a5..318bf29168 100644 --- a/test/api/v3/integration/tasks/GET-tasks_user.test.js +++ b/test/api/v3/integration/tasks/GET-tasks_user.test.js @@ -130,7 +130,8 @@ describe('GET /tasks/user', () => { }); it('returns dailies with isDue for the date specified', async () => { - let startDate = moment().subtract('1', 'days').toDate(); + // @TODO Add required format + let startDate = moment().subtract('1', 'days').toISOString(); let createdTasks = await user.post('/tasks/user', [ { text: 'test daily', @@ -150,4 +151,28 @@ describe('GET /tasks/user', () => { expect(dailys2[0]._id).to.equal(createdTasks._id); expect(dailys2[0].isDue).to.be.true; }); + + it('returns dailies with isDue for the date specified and will add CDS offset if time is not supplied', async () => { + await user.update({ + 'preferences.dayStart': 7, + }); + let startDate = moment().subtract('4', 'days').startOf('day').toISOString(); + await user.post('/tasks/user', [ + { + text: 'test daily', + type: 'daily', + startDate, + frequency: 'daily', + everyX: 2, + }, + ]); + + let today = moment().format('YYYY-MM-DD'); + let dailys = await user.get(`/tasks/user?type=dailys&dueDate=${today}`); + expect(dailys[0].isDue).to.be.true; + + let yesterday = moment().subtract('1', 'days').format('YYYY-MM-DD'); + let dailys2 = await user.get(`/tasks/user?type=dailys&dueDate=${yesterday}`); + expect(dailys2[0].isDue).to.be.false; + }); }); diff --git a/website/common/script/cron.js b/website/common/script/cron.js index 5ee846ecd6..fa1f2a388b 100644 --- a/website/common/script/cron.js +++ b/website/common/script/cron.js @@ -101,6 +101,7 @@ export function shouldDo (day, dailyTask, options = {}) { } let o = sanitizeOptions(options); let startOfDayWithCDSTime = startOfDay(defaults({ now: day }, o)); + // The time portion of the Start Date is never visible to or modifiable by the user so we must ignore it. // Therefore, we must also ignore the time portion of the user's day start (startOfDayWithCDSTime), otherwise the date comparison will be wrong for some times. // NB: The user's day start date has already been converted to the PREVIOUS day's date if the time portion was before CDS. diff --git a/website/server/libs/taskManager.js b/website/server/libs/taskManager.js index e9bcc4f2d2..bbf67fd03f 100644 --- a/website/server/libs/taskManager.js +++ b/website/server/libs/taskManager.js @@ -26,10 +26,21 @@ async function _validateTaskAlias (tasks, res) { export function setNextDue (task, user, dueDateOption) { if (task.type !== 'daily') return; + let now = moment().toDate(); let dateTaskIsDue = Date.now(); - if (dueDateOption) dateTaskIsDue = moment(dueDateOption); + if (dueDateOption) { + dateTaskIsDue = moment(dueDateOption); + // If not time is supplied. Let's assume we want start of Custom Day Start day. + if (dateTaskIsDue.hour() === 0 && dateTaskIsDue.minute() === 0 && dateTaskIsDue.second() === 0 && dateTaskIsDue.millisecond() === 0) { + dateTaskIsDue.add(user.preferences.dayStart, 'hours'); + } + + now = dateTaskIsDue; + } + let optionsForShouldDo = user.preferences.toObject(); + optionsForShouldDo.now = now; task.isDue = shared.shouldDo(dateTaskIsDue, task, optionsForShouldDo); optionsForShouldDo.nextDue = true; let nextDue = shared.shouldDo(dateTaskIsDue, task, optionsForShouldDo); @@ -176,6 +187,12 @@ export async function getTasks (req, res, options = {}) { let tasks = await mQuery.exec(); + if (dueDate) { + tasks.forEach((task) => { + setNextDue(task, user, dueDate); + }); + } + // Order tasks based on tasksOrder if (type && type !== 'completedTodos' && type !== '_allCompletedTodos') { let order = owner.tasksOrder[type]; @@ -190,8 +207,6 @@ export async function getTasks (req, res, options = {}) { } else { orderedTasks[i] = task; } - - if (dueDate) setNextDue(task, user, dueDate); }); // Remove empty values from the array and add any unordered task From 5055a57ae938172ad14c3ef216131647d6c3146f Mon Sep 17 00:00:00 2001 From: Sabe Jones Date: Sat, 8 Jul 2017 01:48:50 +0000 Subject: [PATCH 4/4] 3.101.1 --- npm-shrinkwrap.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index 1460da60e1..d40517fa19 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -1,6 +1,6 @@ { "name": "habitica", - "version": "3.101.0", + "version": "3.101.1", "dependencies": { "@gulp-sourcemaps/map-sources": { "version": "1.0.0", diff --git a/package.json b/package.json index dedc8aee2b..8f7d4d3424 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "habitica", "description": "A habit tracker app which treats your goals like a Role Playing Game.", - "version": "3.101.0", + "version": "3.101.1", "main": "./website/server/index.js", "dependencies": { "@slack/client": "^3.8.1",