Skip to content

Commit

Permalink
PRs 2017/04/07 - 2017/04/14 (HabitRPG#8691)
Browse files Browse the repository at this point in the history
* Issue 8432: Pre-test for initial fix

* Add failing test, seeking help/advice

* Fixes achievements injection. Now trying with Guide

* Fixes tests

* Remoed logging

* Mock ENV function

* Removes test focus

* Remove Beat Master unlock for Rebirth

* Special message when complete all check-in prizes

* Updated comment

* fix(test): unpend party cap test

* remove wrong subscriptions from gift modal

* edit the new issue template to emphasise that the Report a Bug guild should be used first (HabitRPG#8659)

* fix(translation): resolve merge conflict

* fix(news): merge conflict

* Added email invite limit (HabitRPG#8664)

* Added email invite limit

* change error message for sending too many invitations to instruct them to email us

* fix test error message to use variable in locales string

* add comment to warn about keeping INVITES_LIMIT low

If INVITES_LIMIT is allowed to be greater than MAX_EMAIL_INVITES_BY_USER
then the inviter can send more than MAX_EMAIL_INVITES_BY_USER invitations
at once.

* Fix for automatic allocation not persisting HabitRPG#8641 (HabitRPG#8661)

* Fixed text of check-in prize when it is a set of backgrounds (HabitRPG#8599)

* Fixed text of check-in prize when it is a set of backgrounds

* Use existing i18n string for BGs name

* Added user.preferences.language as second parameter

* fix Shiny Seeds info about achievement (not given to caster) (HabitRPG#8679)

Ref: https://habitica.slack.com/archives/C02RK7DKF/p1492032261365388

* Release mergeback v3.86.0 (HabitRPG#8685)

* 3.85.0

* New User Tasks for Mobile (HabitRPG#8682)

* feat(mobile): different default tasks

* fix(linting): missing space

* fix(user): correct client type logic

* test(integration): tasks by platform

* fix(test): remove only

* test(user): deeper checks on tasks

* refactor(test): whitespace for readability

* feat(subs): Jackalope Pets (HabitRPG#8684)

* chore(sprites): compile

* chore(i18n): update locales

* 3.86.0
  • Loading branch information
SabreCat authored Apr 21, 2017
1 parent 0c3f407 commit 7df10d5
Show file tree
Hide file tree
Showing 12 changed files with 146 additions and 65 deletions.
12 changes: 5 additions & 7 deletions .github/ISSUE_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -1,21 +1,19 @@
[//]: # (Before logging this issue, look through common problems at https://github.com/HabitRPG/habitrpg/issues If you find your issue there, read at least the first post to see if there is a workaround for you)
[//]: # (Before logging this issue, please post to the Report a Bug guild from the Habitica website's Help menu. Most bugs can be handled quickly there. If a GitHub issue is needed, you will be advised of that by a moderator or staff member -- a player with a dark blue or purple name. It is recommended that you don't create a new issue unless advised to.)

[//]: # (Github is primarily used for reporting bugs. If you have a feature request, use "Help > Request a Feature" so that the feature request can be vetted by the larger Habitica community)
[//]: # (Bugs in the mobile apps can also be reported there.)

[//]: # (To report a bug in one of the mobile apps, please report it in the correct repository. Android: https://github.com/HabitRPG/habitrpg-android, iOS: https://github.com/HabitRPG/habitrpg-ios)
[//]: # (If you have a feature request, use "Help > Request a Feature", not GitHub or the Report a Bug guild.)

[//]: # (For more guidelines see https://github.com/HabitRPG/habitrpg/issues/2760)

[//]: # (Fill out relevant information - UUID is found in Settings -> API)
General Info
### General Info
* UUID:
* Browser:
* OS:

### Description
[//]: # (Describe bug in detail here. Include pictures if helpful.)


[//]: # (Describe bug in detail here. Include screenshots if helpful.)

#### Console Errors
[//]: # (Include any JavaScript console errors here.)
Expand Down
69 changes: 69 additions & 0 deletions test/client-old/spec/controllers/userCtrlSpec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
'use strict';

describe('User Controller', function() {
var $rootScope, $window, User, shared, scope, ctrl, content;

beforeEach(function() {
module(function ($provide) {
var user = specHelper.newUser();
User = {user: user}
$provide.value('Guide', sandbox.stub());
$provide.value('User', User);
$provide.value('Achievement', sandbox.stub());
$provide.value('Social', sandbox.stub());
$provide.value('Shared', {
achievements: {
getAchievementsForProfile: sandbox.stub()
},
shops: {
getBackgroundShopSets: sandbox.stub()
}
});
$provide.value('Content', {
loginIncentives: sandbox.stub()
})
});

inject(function($rootScope, $controller, User, Content) {
scope = $rootScope.$new();
content = Content;
$controller('RootCtrl', { $scope: scope, User: User});
ctrl = $controller('UserCtrl', { $scope: scope, User: User, $window: $window});
});
});

describe('getProgressDisplay', function() {

beforeEach(() => {
sandbox.stub(window.env, 't');
window.env.t.onFirstCall().returns('Progress until next');
});

it('should return initial progress', function() {
scope.profile.loginIncentives = 0;
content.loginIncentives = [{
nextRewardAt: 1,
reward: true
}];
var actual = scope.getProgressDisplay();
expect(actual.trim()).to.eql('Progress until next 0/1');
});

it('should return progress between next reward and current reward', function() {
scope.profile.loginIncentives = 1;
content.loginIncentives = [{
nextRewardAt: 1,
reward: true
}, {
prevRewardAt: 0,
nextRewardAt: 2,
reward: true
}, {
prevRewardAt: 1,
nextRewardAt: 3
}];
var actual = scope.getProgressDisplay();
expect(actual.trim()).to.eql('Progress until next 0/1');
});
});
});
4 changes: 3 additions & 1 deletion website/client-old/js/controllers/userCtrl.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"use strict";

habitrpg.controller("UserCtrl", ['$rootScope', '$scope', '$location', 'User', '$http', '$state', 'Guide', 'Shared', 'Content', 'Stats', 'Social', 'Costume',
habitrpg.controller('UserCtrl', ['$rootScope', '$scope', '$location', 'User', '$http', '$state', 'Guide', 'Shared', 'Content', 'Stats', 'Social', 'Costume',
function($rootScope, $scope, $location, User, $http, $state, Guide, Shared, Content, Stats, Social, Costume) {
$scope.profile = User.user;

Expand Down Expand Up @@ -102,6 +102,8 @@ habitrpg.controller("UserCtrl", ['$rootScope', '$scope', '$location', 'User', '$
if (!currentLoginDay) return env.t('moreIncentivesComingSoon');
var nextRewardAt = currentLoginDay.nextRewardAt;
if (!nextRewardAt) return env.t('moreIncentivesComingSoon');
// if we are on a reward day, let's show progress relative to this
if (currentLoginDay.reward) currentLoginDay.prevRewardKey = $scope.profile.loginIncentives;
if (!currentLoginDay.prevRewardKey) currentLoginDay.prevRewardKey = 0;
return env.t('checkinProgressTitle') + ' ' + ($scope.profile.loginIncentives - currentLoginDay.prevRewardKey) + '/' + (nextRewardAt - currentLoginDay.prevRewardKey);
};
Expand Down
1 change: 1 addition & 0 deletions website/client-old/js/services/notificationServices.js
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ angular.module("habitrpg").factory("Notification",
modalScope.data = rewardData;
var nextRewardKey = Shared.content.loginIncentives[user.loginIncentives].nextRewardAt;
modalScope.nextReward = Shared.content.loginIncentives[nextRewardKey];
modalScope.MAX_INCENTIVES = Shared.constants.MAX_INCENTIVES;
modalScope.user = user;
// modalScope.loadWidgets = Social.loadWidgets;
modalScope.loadWidgets = loadWidgets;
Expand Down
3 changes: 2 additions & 1 deletion website/common/locales/en/loginIncentives.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,6 @@
"totalCheckinsTitle": "Total Check-Ins",
"checkinProgressTitle": "Progress until next",
"incentiveBackgroundsUnlockedWithCheckins": "Locked Plain Backgrounds will unlock with Daily Check-Ins.",
"moreIncentivesComingSoon": "New check-in incentives will be added soon!"
"moreIncentivesComingSoon": "New check-in incentives will be added soon!",
"checkinReceivedAllRewardsMessage" : "You have received all the Check-In prizes currently available! More will be added in the future."
}
2 changes: 1 addition & 1 deletion website/common/locales/zh/gear.json
Original file line number Diff line number Diff line change
Expand Up @@ -1189,4 +1189,4 @@
"eyewearMystery301703Notes": "完美适配美妙的化妆舞会,或者静悄悄地穿过那些特别讲究穿着的人群。没有属性加成。3017年三月捐赠者礼品。",
"eyewearArmoirePlagueDoctorMaskText": "瘟疫医生面具",
"eyewearArmoirePlagueDoctorMaskNotes": "防治延迟瘟疫的医生袋的地道面具。没有属性加成。魔法衣橱: 瘟疫医生系列 (3件的第2件)。"
}
}
5 changes: 4 additions & 1 deletion website/common/script/content/loginIncentives.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ module.exports = function getLoginIncentives (api) {
2: {
rewardKey: ['background_purple'],
reward: [api.backgrounds.incentiveBackgrounds],
rewardName: 'incentiveBackgrounds', // i18n string
assignReward: function assignReward (user) {
user.purchased.background.blue = true;
user.purchased.background.green = true;
Expand Down Expand Up @@ -225,8 +226,10 @@ module.exports = function getLoginIncentives (api) {
},
},
};
// When the final check-in prize is added here, change checkinReceivedAllRewardsMessage in website/common/locales/en/loginIncentives.json
// to say "You have received the final Check-In prize!". Confirm the message with Lemoness first.

// Add refence link to next reward and add filler days so we have a map to refernce the next reward from any day
// Add reference link to next reward and add filler days so we have a map to reference the next reward from any day
// We could also, use a list, but then we would be cloning each of the rewards.
// Create a new array if we want the loginIncentives to be immutable in the future
let nextRewardKey;
Expand Down
2 changes: 1 addition & 1 deletion website/common/script/fns/updateStats.js
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ module.exports = function updateStats (user, stats, req = {}, analytics) {
};
}
});
if (!user.flags.rebirthEnabled && (user.stats.lvl >= 50 || user.achievements.beastMaster)) {
if (!user.flags.rebirthEnabled && user.stats.lvl >= 50) {
user.addNotification('REBIRTH_ENABLED');
user.flags.rebirthEnabled = true;
}
Expand Down
7 changes: 6 additions & 1 deletion website/server/libs/cron.js
Original file line number Diff line number Diff line change
Expand Up @@ -157,14 +157,19 @@ function awardLoginIncentives (user) {
notificationData.rewardText = i18n.t('potion', {potionType: notificationData.rewardText}, user.preferences.language);
}
} else if (loginIncentive.rewardKey[0] === 'background_blue') {
notificationData.rewardText = i18n.t('incentiveBackgrounds');
notificationData.rewardText = i18n.t('incentiveBackgrounds', user.preferences.language);
}

if (loginIncentive.reward.length > 0 && count < loginIncentive.reward.length - 1) notificationData.rewardText += ', ';

count += 1;
}

// Overwrite notificationData.rewardText if rewardName was explicitly declared
if (loginIncentive.rewardName) {
notificationData.rewardText = i18n.t(loginIncentive.rewardName, user.preferences.language);
}

notificationData.rewardKey = loginIncentive.rewardKey;
notificationData.message = i18n.t('unlockedCheckInReward', user.preferences.language);
}
Expand Down
102 changes: 51 additions & 51 deletions website/views/options/profile/stats.jade
Original file line number Diff line number Diff line change
@@ -1,51 +1,51 @@
script(id='partials/options.profile.stats.html', type='text/ng-template')
.container-fluid
div(class='row')
.border-right(ng-class='user.flags.classSelected && !user.preferences.disableClasses ? "col-md-4" : "col-md-6"')
include ../../shared/profiles/stats_col1
div(ng-class='user.flags.classSelected && !user.preferences.disableClasses ? "col-md-4" : "col-md-6"')
button.btn.btn-default(ng-if='user.preferences.disableClasses', ng-click='User.changeClass({})', popover-trigger='mouseenter', popover-placement='right', popover=env.t('enableClassPop'))= env.t('enableClass')
hr(ng-if='user.preferences.disableClasses')
include ../../shared/profiles/stats_col2
.col-md-4.border-left.allocate-stats(ng-if='user.flags.classSelected && !user.preferences.disableClasses')
h3=env.t('characterBuild')
h4
=env.t('class') + ': '
span {{ {warrior:env.t("warrior"), wizard:env.t("mage"), rogue:env.t("rogue"), healer:env.t("healer")}[user.stats.class] }}&nbsp;
a.btn.btn-danger.btn-xs(ng-click='changeClass(null)')=env.t('changeClass')
small.cost 3 <span class="Pet_Currency_Gem1x inline-gems"/>
table.table.table-striped
tr
td
p(ng-if='::user.stats.lvl >= 100')!=env.t('noMoreAllocate')
p(ng-if='user.stats.points || user.stats.lvl < 100')
strong.inline
|{{user.stats.points}}&nbsp;
strong.hint(popover-trigger='mouseenter', popover-placement='right', popover=env.t('levelPopover'))=env.t('unallocated')
td
tr
td(colspan=2)
fieldset.auto-allocate
.checkbox
label
input(type='checkbox', ng-model='user.preferences.automaticAllocation', ng-change='set({"preferences.automaticAllocation": user.preferences.automaticAllocation?true: false})', ng-click='set({"preferences.allocationMode":"taskbased"})')
span.hint(popover-trigger='mouseenter', popover-placement='right', popover=env.t('autoAllocationPop'))=env.t('autoAllocation')
form(ng-show='user.preferences.automaticAllocation',style='margin-left:1em')
.radio
label
input(type='radio', name='allocationMode', value='flat', ng-model='user.preferences.allocationMode', ng-change='set({"preferences.allocationMode": "flat"})')
span.hint(popover-trigger='mouseenter', popover-placement='right', popover=env.t('evenAllocationPop'))=env.t('evenAllocation')
.radio
label
input(type='radio', name='allocationMode', value='classbased', ng-model='user.preferences.allocationMode', ng-change='set({"preferences.allocationMode": "classbased"})')
span.hint(popover-trigger='mouseenter', popover-placement='right', popover=env.t('classAllocationPop'))=env.t('classAllocation')
.radio
label
input(type='radio', name='allocationMode', value='taskbased', ng-model='user.preferences.allocationMode', ng-change='set({"preferences.allocationMode": "taskbased"})')
span.hint(popover-trigger='mouseenter', popover-placement='right', popover=env.t('taskAllocationPop'))=env.t('taskAllocation')
div(ng-show='user.preferences.automaticAllocation && !(user.preferences.allocationMode === "taskbased") && (user.stats.points > 0)')
a.btn.btn-primary.btn-xs(ng-click='User.allocateNow({})', popover-trigger='mouseenter', popover-placement='right', popover=env.t('distributePointsPop'))
span.glyphicon.glyphicon-download
|&nbsp;
=env.t('distributePoints')
+statAllocation()
script(id='partials/options.profile.stats.html', type='text/ng-template')
.container-fluid
div(class='row')
.border-right(ng-class='user.flags.classSelected && !user.preferences.disableClasses ? "col-md-4" : "col-md-6"')
include ../../shared/profiles/stats_col1
div(ng-class='user.flags.classSelected && !user.preferences.disableClasses ? "col-md-4" : "col-md-6"')
button.btn.btn-default(ng-if='user.preferences.disableClasses', ng-click='User.changeClass({})', popover-trigger='mouseenter', popover-placement='right', popover=env.t('enableClassPop'))= env.t('enableClass')
hr(ng-if='user.preferences.disableClasses')
include ../../shared/profiles/stats_col2
.col-md-4.border-left.allocate-stats(ng-if='user.flags.classSelected && !user.preferences.disableClasses')
h3=env.t('characterBuild')
h4
=env.t('class') + ': '
span {{ {warrior:env.t("warrior"), wizard:env.t("mage"), rogue:env.t("rogue"), healer:env.t("healer")}[user.stats.class] }}&nbsp;
a.btn.btn-danger.btn-xs(ng-click='changeClass(null)')=env.t('changeClass')
small.cost 3 <span class="Pet_Currency_Gem1x inline-gems"/>
table.table.table-striped
tr
td
p(ng-if='::user.stats.lvl >= 100')!=env.t('noMoreAllocate')
p(ng-if='user.stats.points || user.stats.lvl < 100')
strong.inline
|{{user.stats.points}}&nbsp;
strong.hint(popover-trigger='mouseenter', popover-placement='right', popover=env.t('levelPopover'))=env.t('unallocated')
td
tr
td(colspan=2)
fieldset.auto-allocate
.checkbox
label
input(type='checkbox', ng-model='user.preferences.automaticAllocation', ng-change='set({"preferences.automaticAllocation": user.preferences.automaticAllocation, "preferences.allocationMode":"taskbased"})')
span.hint(popover-trigger='mouseenter', popover-placement='right', popover=env.t('autoAllocationPop'))=env.t('autoAllocation')
form(ng-show='user.preferences.automaticAllocation',style='margin-left:1em')
.radio
label
input(type='radio', name='allocationMode', value='flat', ng-model='user.preferences.allocationMode', ng-change='set({"preferences.allocationMode": "flat"})')
span.hint(popover-trigger='mouseenter', popover-placement='right', popover=env.t('evenAllocationPop'))=env.t('evenAllocation')
.radio
label
input(type='radio', name='allocationMode', value='classbased', ng-model='user.preferences.allocationMode', ng-change='set({"preferences.allocationMode": "classbased"})')
span.hint(popover-trigger='mouseenter', popover-placement='right', popover=env.t('classAllocationPop'))=env.t('classAllocation')
.radio
label
input(type='radio', name='allocationMode', value='taskbased', ng-model='user.preferences.allocationMode', ng-change='set({"preferences.allocationMode": "taskbased"})')
span.hint(popover-trigger='mouseenter', popover-placement='right', popover=env.t('taskAllocationPop'))=env.t('taskAllocation')
div(ng-show='user.preferences.automaticAllocation && !(user.preferences.allocationMode === "taskbased") && (user.stats.points > 0)')
a.btn.btn-primary.btn-xs(ng-click='User.allocateNow({})', popover-trigger='mouseenter', popover-placement='right', popover=env.t('distributePointsPop'))
span.glyphicon.glyphicon-download
|&nbsp;
=env.t('distributePoints')
+statAllocation()
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ script(id='modals/login-incentives-reward-unlocked.html', type='text/ng-template
p {{env.t('earnedRewardForDevotion', {reward: data.rewardText})}}
.col-md-12.text-center(ng-show="data.nextRewardAt")
h4 {{env.t('nextRewardUnlocksIn', {numberOfCheckinsLeft: data.nextRewardAt - user.loginIncentives})}}
.col-md-10.col-md-offset-1.text-center
h4(ng-if="user.loginIncentives === MAX_INCENTIVES")=env.t('checkinReceivedAllRewardsMessage')
.modal-footer
.row
a.btn.btn-primary.col-md-6.col-md-offset-3(ng-click='$close()')=env.t('awesome')
Expand Down
2 changes: 1 addition & 1 deletion website/views/shared/modals/members.jade
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ script(type='text/ng-template', id='modals/send-gift.html')
.panel-heading=env.t('subscription')
.panel-body
.form-group
.radio(ng-repeat='block in Content.subscriptionBlocks | toArray | omit:"discount==true" | orderBy:"months"', ng-if="block.type !== 'group'")
.radio(ng-repeat='block in Content.subscriptionBlocks | toArray | omit:"discount==true" | orderBy:"months"', ng-if="block.target !== 'group' && block.canSubscribe === true")
label
input(type="radio", name="subRadio", ng-value="block.key", ng-model='gift.subscription.key')
=env.t('sendGiftSubscription', {price: '{{::block.price}}', months: '{{::block.months}}'})
Expand Down

0 comments on commit 7df10d5

Please sign in to comment.