mirror of
https://github.com/HabitRPG/habitica.git
synced 2025-12-16 06:07:21 +01:00
Don't $watch drops (#7547)
* WIP(drops): get drops out of _tmp * fix(notifications): no watch for drops/mystery * fix(ops): only two response values * fix(test): update op expectation Also update API docs for modified route. * fix(lint): remove trailing space * fix(test): update integration check
This commit is contained in:
@@ -13,7 +13,6 @@ module.exports = function openMysteryItem (user, req = {}, analytics) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
item = _.cloneDeep(content.gear.flat[item]);
|
item = _.cloneDeep(content.gear.flat[item]);
|
||||||
item.notificationType = 'Mystery';
|
|
||||||
user.items.gear.owned[item.key] = true;
|
user.items.gear.owned[item.key] = true;
|
||||||
|
|
||||||
user.markModified('purchased.plan.mysteryItems');
|
user.markModified('purchased.plan.mysteryItems');
|
||||||
@@ -28,16 +27,11 @@ module.exports = function openMysteryItem (user, req = {}, analytics) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof window !== 'undefined') {
|
|
||||||
if (!user._tmp) user._tmp = {};
|
|
||||||
user._tmp.drop = item;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (req.v2 === true) {
|
if (req.v2 === true) {
|
||||||
return user.items.gear.owned;
|
return user.items.gear.owned;
|
||||||
} else {
|
} else {
|
||||||
return [
|
return [
|
||||||
user.items.gear.owned,
|
item,
|
||||||
i18n.t('mysteryItemOpened', req.language),
|
i18n.t('mysteryItemOpened', req.language),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,10 +2,13 @@ import {
|
|||||||
generateUser,
|
generateUser,
|
||||||
translate as t,
|
translate as t,
|
||||||
} from '../../../../helpers/api-integration/v3';
|
} from '../../../../helpers/api-integration/v3';
|
||||||
|
import content from '../../../../../common/script/content/index';
|
||||||
|
|
||||||
describe('POST /user/open-mystery-item', () => {
|
describe('POST /user/open-mystery-item', () => {
|
||||||
let user;
|
let user;
|
||||||
let mysteryItemKey = 'eyewear_special_summerRogue';
|
let mysteryItemKey = 'eyewear_special_summerRogue';
|
||||||
|
let mysteryItemIndex = content.gear.flat[mysteryItemKey].index;
|
||||||
|
let mysteryItemType = content.gear.flat[mysteryItemKey].type;
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
user = await generateUser({
|
user = await generateUser({
|
||||||
@@ -21,6 +24,8 @@ describe('POST /user/open-mystery-item', () => {
|
|||||||
|
|
||||||
expect(user.items.gear.owned[mysteryItemKey]).to.be.true;
|
expect(user.items.gear.owned[mysteryItemKey]).to.be.true;
|
||||||
expect(response.message).to.equal(t('mysteryItemOpened'));
|
expect(response.message).to.equal(t('mysteryItemOpened'));
|
||||||
expect(response.data).to.deep.equal(user.items.gear.owned);
|
expect(response.data.key).to.eql(mysteryItemKey);
|
||||||
|
expect(response.data.index).to.eql(mysteryItemIndex);
|
||||||
|
expect(response.data.type).to.eql(mysteryItemType);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import {
|
|||||||
import {
|
import {
|
||||||
BadRequest,
|
BadRequest,
|
||||||
} from '../../../common/script/libs/errors';
|
} from '../../../common/script/libs/errors';
|
||||||
|
import content from '../../../common/script/content/index';
|
||||||
import i18n from '../../../common/script/i18n';
|
import i18n from '../../../common/script/i18n';
|
||||||
|
|
||||||
describe('shared.ops.openMysteryItem', () => {
|
describe('shared.ops.openMysteryItem', () => {
|
||||||
@@ -33,6 +34,6 @@ describe('shared.ops.openMysteryItem', () => {
|
|||||||
|
|
||||||
expect(user.items.gear.owned[mysteryItemKey]).to.be.true;
|
expect(user.items.gear.owned[mysteryItemKey]).to.be.true;
|
||||||
expect(message).to.equal(i18n.t('mysteryItemOpened'));
|
expect(message).to.equal(i18n.t('mysteryItemOpened'));
|
||||||
expect(data).to.equal(user.items.gear.owned);
|
expect(data).to.eql(content.gear.flat[mysteryItemKey]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -82,55 +82,6 @@ habitrpg.controller('NotificationCtrl',
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
$rootScope.$watch('user._tmp.drop', function(after, before){
|
|
||||||
// won't work when getting the same item twice?
|
|
||||||
if (_.isEqual(after, before) || !after) return;
|
|
||||||
var text, notes, type;
|
|
||||||
$rootScope.playSound('Item_Drop');
|
|
||||||
|
|
||||||
// Note: For Mystery Item gear, after.type will be 'head', 'armor', etc
|
|
||||||
// so we use after.notificationType below.
|
|
||||||
|
|
||||||
if (after.type !== 'gear' && after.type !== 'Quest' && after.notificationType !== 'Mystery') {
|
|
||||||
if (after.type === 'Food') {
|
|
||||||
type = 'food';
|
|
||||||
} else if (after.type === 'HatchingPotion') {
|
|
||||||
type = 'hatchingPotions';
|
|
||||||
} else {
|
|
||||||
type = after.type.toLowerCase() + 's';
|
|
||||||
}
|
|
||||||
if(!User.user.items[type][after.key]){
|
|
||||||
User.user.items[type][after.key] = 0;
|
|
||||||
}
|
|
||||||
User.user.items[type][after.key]++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (after.type === 'HatchingPotion'){
|
|
||||||
text = Content.hatchingPotions[after.key].text();
|
|
||||||
notes = Content.hatchingPotions[after.key].notes();
|
|
||||||
Notification.drop(env.t('messageDropPotion', {dropText: text, dropNotes: notes}), after);
|
|
||||||
} else if (after.type === 'Egg'){
|
|
||||||
text = Content.eggs[after.key].text();
|
|
||||||
notes = Content.eggs[after.key].notes();
|
|
||||||
Notification.drop(env.t('messageDropEgg', {dropText: text, dropNotes: notes}), after);
|
|
||||||
} else if (after.type === 'Food'){
|
|
||||||
text = Content.food[after.key].text();
|
|
||||||
notes = Content.food[after.key].notes();
|
|
||||||
Notification.drop(env.t('messageDropFood', {dropArticle: after.article, dropText: text, dropNotes: notes}), after);
|
|
||||||
} else if (after.type === 'Quest') {
|
|
||||||
$rootScope.selectedQuest = Content.quests[after.key];
|
|
||||||
$rootScope.openModal('questDrop', {controller:'PartyCtrl', size:'sm'});
|
|
||||||
} else if (after.notificationType === 'Mystery') {
|
|
||||||
text = Content.gear.flat[after.key].text();
|
|
||||||
Notification.drop(env.t('messageDropMysteryItem', {dropText: text}), after);
|
|
||||||
} else {
|
|
||||||
// Keep support for another type of drops that might be added
|
|
||||||
Notification.drop(User.user._tmp.drop.dialog);
|
|
||||||
}
|
|
||||||
|
|
||||||
Analytics.track({'hitType':'event','eventCategory':'behavior','eventAction':'acquire item','itemName':after.key,'acquireMethod':'Drop'});
|
|
||||||
});
|
|
||||||
|
|
||||||
$rootScope.$watch('user.achievements.streak', function(after, before){
|
$rootScope.$watch('user.achievements.streak', function(after, before){
|
||||||
if(before == undefined || after <= before) return;
|
if(before == undefined || after <= before) return;
|
||||||
Notification.streak(User.user.achievements.streak);
|
Notification.streak(User.user.achievements.streak);
|
||||||
|
|||||||
@@ -39,7 +39,14 @@ angular.module("habitrpg").factory("Notification",
|
|||||||
case "Food":
|
case "Food":
|
||||||
dropClass = 'Pet_Food_' + item.key;
|
dropClass = 'Pet_Food_' + item.key;
|
||||||
break;
|
break;
|
||||||
case "Mystery":
|
case "armor":
|
||||||
|
case "back":
|
||||||
|
case "body":
|
||||||
|
case "eyewear":
|
||||||
|
case "head":
|
||||||
|
case "headAccessory":
|
||||||
|
case "shield":
|
||||||
|
case "weapon":
|
||||||
dropClass = 'shop_' + item.key;
|
dropClass = 'shop_' + item.key;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -14,8 +14,8 @@ angular.module('habitrpg')
|
|||||||
/**
|
/**
|
||||||
* Services that persists and retrieves user from localStorage.
|
* Services that persists and retrieves user from localStorage.
|
||||||
*/
|
*/
|
||||||
.factory('User', ['$rootScope', '$http', '$location', '$window', 'STORAGE_USER_ID', 'STORAGE_SETTINGS_ID', 'Notification', 'ApiUrl', 'Tasks', 'Tags',
|
.factory('User', ['$rootScope', '$http', '$location', '$window', 'STORAGE_USER_ID', 'STORAGE_SETTINGS_ID', 'Notification', 'ApiUrl', 'Tasks', 'Tags', 'Content',
|
||||||
function($rootScope, $http, $location, $window, STORAGE_USER_ID, STORAGE_SETTINGS_ID, Notification, ApiUrl, Tasks, Tags) {
|
function($rootScope, $http, $location, $window, STORAGE_USER_ID, STORAGE_SETTINGS_ID, Notification, ApiUrl, Tasks, Tags, Content) {
|
||||||
var authenticated = false;
|
var authenticated = false;
|
||||||
var defaultSettings = {
|
var defaultSettings = {
|
||||||
auth: { apiId: '', apiToken: ''},
|
auth: { apiId: '', apiToken: ''},
|
||||||
@@ -162,6 +162,11 @@ angular.module('habitrpg')
|
|||||||
if (response.data.message && response.data.message !== clientMessage) {
|
if (response.data.message && response.data.message !== clientMessage) {
|
||||||
Notification.text(response.data.message);
|
Notification.text(response.data.message);
|
||||||
}
|
}
|
||||||
|
if (opName === 'openMysteryItem') {
|
||||||
|
var openedItem = clientResponse[0];
|
||||||
|
var text = Content.gear.flat[openedItem.key].text();
|
||||||
|
Notification.drop(env.t('messageDropMysteryItem', {dropText: text}), openedItem);
|
||||||
|
}
|
||||||
|
|
||||||
save();
|
save();
|
||||||
})
|
})
|
||||||
@@ -231,7 +236,49 @@ angular.module('habitrpg')
|
|||||||
var critBonus = crit * 100 - 100;
|
var critBonus = crit * 100 - 100;
|
||||||
Notification.crit(critBonus);
|
Notification.crit(critBonus);
|
||||||
}
|
}
|
||||||
if (drop) user._tmp.drop = drop;
|
if (drop) {
|
||||||
|
var text, notes, type;
|
||||||
|
$rootScope.playSound('Item_Drop');
|
||||||
|
|
||||||
|
// Note: For Mystery Item gear, drop.type will be 'head', 'armor', etc
|
||||||
|
// so we use drop.notificationType below.
|
||||||
|
|
||||||
|
if (drop.type !== 'gear' && drop.type !== 'Quest' && drop.notificationType !== 'Mystery') {
|
||||||
|
if (drop.type === 'Food') {
|
||||||
|
type = 'food';
|
||||||
|
} else if (drop.type === 'HatchingPotion') {
|
||||||
|
type = 'hatchingPotions';
|
||||||
|
} else {
|
||||||
|
type = drop.type.toLowerCase() + 's';
|
||||||
|
}
|
||||||
|
if(!user.items[type][drop.key]){
|
||||||
|
user.items[type][drop.key] = 0;
|
||||||
|
}
|
||||||
|
user.items[type][drop.key]++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (drop.type === 'HatchingPotion'){
|
||||||
|
text = Content.hatchingPotions[drop.key].text();
|
||||||
|
notes = Content.hatchingPotions[drop.key].notes();
|
||||||
|
Notification.drop(env.t('messageDropPotion', {dropText: text, dropNotes: notes}), drop);
|
||||||
|
} else if (drop.type === 'Egg'){
|
||||||
|
text = Content.eggs[drop.key].text();
|
||||||
|
notes = Content.eggs[drop.key].notes();
|
||||||
|
Notification.drop(env.t('messageDropEgg', {dropText: text, dropNotes: notes}), drop);
|
||||||
|
} else if (drop.type === 'Food'){
|
||||||
|
text = Content.food[drop.key].text();
|
||||||
|
notes = Content.food[drop.key].notes();
|
||||||
|
Notification.drop(env.t('messageDropFood', {dropArticle: drop.article, dropText: text, dropNotes: notes}), drop);
|
||||||
|
} else if (drop.type === 'Quest') {
|
||||||
|
$rootScope.selectedQuest = Content.quests[drop.key];
|
||||||
|
$rootScope.openModal('questDrop', {controller:'PartyCtrl', size:'sm'});
|
||||||
|
} else {
|
||||||
|
// Keep support for another type of drops that might be added
|
||||||
|
Notification.drop(drop.dialog);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Analytics.track({'hitType':'event','eventCategory':'behavior','eventAction':'acquire item','itemName':after.key,'acquireMethod':'Drop'});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -888,7 +888,7 @@ api.readCard = {
|
|||||||
* @apiName UserOpenMysteryItem
|
* @apiName UserOpenMysteryItem
|
||||||
* @apiGroup User
|
* @apiGroup User
|
||||||
*
|
*
|
||||||
* @apiSuccess {Object} data user.items.gear.owned
|
* @apiSuccess {Object} data The item obtained
|
||||||
* @apiSuccess {string} message Success message
|
* @apiSuccess {string} message Success message
|
||||||
*/
|
*/
|
||||||
api.userOpenMysteryItem = {
|
api.userOpenMysteryItem = {
|
||||||
|
|||||||
Reference in New Issue
Block a user