From 55a8eef3e156e992ac03fcd2e09ab306527ecfcd Mon Sep 17 00:00:00 2001 From: Travis Date: Tue, 20 Dec 2016 17:52:18 -0800 Subject: [PATCH] Fixing Duplicate tasks showing up after joining a challenge (#7787) * fix: prevents double joining challenge by quickly hitting join button on challenge twice. fixes #7730 * Fixing client side parameter updates. --- website/client-old/js/controllers/challengesCtrl.js | 2 ++ website/server/models/challenge.js | 7 +++++-- website/views/options/social/challenges.jade | 2 +- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/website/client-old/js/controllers/challengesCtrl.js b/website/client-old/js/controllers/challengesCtrl.js index a50f7a4aa3..a465d203e8 100644 --- a/website/client-old/js/controllers/challengesCtrl.js +++ b/website/client-old/js/controllers/challengesCtrl.js @@ -320,6 +320,7 @@ habitrpg.controller("ChallengesCtrl", ['$rootScope','$scope', 'Shared', 'User', */ $scope.join = function (challenge) { + challenge._joiningInProgress = true; Challenges.joinChallenge(challenge._id) .then(function (response) { User.user.challenges.push(challenge._id); @@ -329,6 +330,7 @@ habitrpg.controller("ChallengesCtrl", ['$rootScope','$scope', 'Shared', 'User', .then(function (response) { var tasks = response.data.data; User.syncUserTasks(tasks); + challenge._joiningInProgress = false; }); } diff --git a/website/server/models/challenge.js b/website/server/models/challenge.js index e4c26c6f5f..4a317f45f3 100644 --- a/website/server/models/challenge.js +++ b/website/server/models/challenge.js @@ -79,8 +79,11 @@ schema.methods.syncToUser = async function syncChallengeToUser (user) { challenge.shortName = challenge.shortName || challenge.name; // Add challenge to user.challenges - if (!_.contains(user.challenges, challenge._id)) user.challenges.push(challenge._id); - + if (!_.contains(user.challenges, challenge._id)) { + // using concat because mongoose's protection against concurrent array modification isn't working as expected. + // see https://github.com/HabitRPG/habitrpg/pull/7787#issuecomment-232972394 + user.challenges = user.challenges.concat([challenge._id]); + } // Sync tags let userTags = user.tags; let i = _.findIndex(userTags, {id: challenge._id}); diff --git a/website/views/options/social/challenges.jade b/website/views/options/social/challenges.jade index 8f40c9c22d..4f8998bae1 100644 --- a/website/views/options/social/challenges.jade +++ b/website/views/options/social/challenges.jade @@ -202,7 +202,7 @@ script(type='text/ng-template', id='partials/options.social.challenges.html') a.btn.btn-sm.btn-danger(ng-show='isUserMemberOf(challenge)', ng-click='clickLeave(challenge, $event)') span.glyphicon.glyphicon-ban-circle =env.t('leave') - a.btn.btn-sm.btn-success(ng-hide='isUserMemberOf(challenge)', ng-click='join(challenge)') + a.btn.btn-sm.btn-success(ng-hide='isUserMemberOf(challenge)', ng-click='join(challenge)', ng-disabled='challenge._joiningInProgress') span.glyphicon.glyphicon-ok =env.t('join') a.accordion-toggle(id="{{challenge._id}}" ng-click='toggle(challenge._id)')