Items/Market/Quests/misc fixes (#8987)

* use countBadge instead of class

* generic purchase action from buyModal to handle all kind of purchases - able to purchase backgrounds - return backgrounds as flat array

* List MysteryItem & Hourglass in Inventory/Items

* add Subscribers Gem Item (purchase by gold)

* fix mysterybox

* sort unlocked gear first

* add orb of rebirth to market

* remove old quest scroll + class of the quest items

* more padding on countBadge

* use the generic purchase on quests
This commit is contained in:
negue
2017-08-26 12:18:55 +02:00
committed by GitHub
parent 0233f7b486
commit c35e4f5750
19 changed files with 263 additions and 73 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -20,10 +20,3 @@
position: absolute; position: absolute;
top: -9px; top: -9px;
} }
.badge-quantity {
color: $white;
right: -9px;
padding: 4.5px 8.5px;
background-color: $orange-100;
}

View File

@@ -32,7 +32,7 @@
h2 h2
| {{ $t(group.key) }} | {{ $t(group.key) }}
| |
span.badge.badge-pill.badge-default {{group.quantity}} span.badge.badge-pill.badge-default(v-if="group.key != 'special'") {{group.quantity}}
itemRows( itemRows(
@@ -47,7 +47,7 @@
item( item(
:item="context.item", :item="context.item",
:key="context.item.key", :key="context.item.key",
:itemContentClass="`${group.classPrefix}${context.item.key}`", :itemContentClass="context.item.class",
:highlightBorder="isHatchable(currentDraggingPotion, context.item.key)", :highlightBorder="isHatchable(currentDraggingPotion, context.item.key)",
v-drag.drop.hatch="context.item.key", v-drag.drop.hatch="context.item.key",
@@ -61,7 +61,10 @@
h4.popover-content-title {{ context.item.text }} h4.popover-content-title {{ context.item.text }}
.popover-content-text(v-if="currentDraggingPotion == null") {{ context.item.notes }} .popover-content-text(v-if="currentDraggingPotion == null") {{ context.item.notes }}
template(slot="itemBadge", scope="context") template(slot="itemBadge", scope="context")
span.badge.badge-pill.badge-item.badge-quantity {{ context.item.quantity }} countBadge(
:show="true",
:count="context.item.quantity"
)
itemRows( itemRows(
v-else-if="group.key === 'hatchingPotions'", v-else-if="group.key === 'hatchingPotions'",
@@ -75,7 +78,7 @@
item( item(
:item="context.item", :item="context.item",
:key="context.item.key", :key="context.item.key",
:itemContentClass="`${group.classPrefix}${context.item.key}`", :itemContentClass="context.item.class",
:showPopover="currentDraggingPotion == null", :showPopover="currentDraggingPotion == null",
:active="currentDraggingPotion == context.item", :active="currentDraggingPotion == context.item",
v-drag.hatch="context.item.key", v-drag.hatch="context.item.key",
@@ -89,7 +92,10 @@
h4.popover-content-title {{ context.item.text }} h4.popover-content-title {{ context.item.text }}
.popover-content-text {{ context.item.notes }} .popover-content-text {{ context.item.notes }}
template(slot="itemBadge", scope="context") template(slot="itemBadge", scope="context")
span.badge.badge-pill.badge-item.badge-quantity {{ context.item.quantity }} countBadge(
:show="true",
:count="context.item.quantity"
)
itemRows( itemRows(
v-else, v-else,
@@ -103,14 +109,18 @@
item( item(
:item="context.item", :item="context.item",
:key="context.item.key", :key="context.item.key",
:itemContentClass="`${group.classPrefix}${context.item.key}`", :itemContentClass="context.item.class",
:showPopover="currentDraggingPotion == null" :showPopover="currentDraggingPotion == null",
@click="itemClicked(group.key, context.item)",
) )
template(slot="popoverContent", scope="context") template(slot="popoverContent", scope="context")
h4.popover-content-title {{ context.item.text }} h4.popover-content-title {{ context.item.text }}
.popover-content-text {{ context.item.notes }} .popover-content-text {{ context.item.notes }}
template(slot="itemBadge", scope="context") template(slot="itemBadge", scope="context")
span.badge.badge-pill.badge-item.badge-quantity {{ context.item.quantity }} countBadge(
:show="true",
:count="context.item.quantity"
)
hatchedPetDialog( hatchedPetDialog(
:pet="hatchedPet", :pet="hatchedPet",
@@ -162,14 +172,16 @@ import bDropdown from 'bootstrap-vue/lib/components/dropdown';
import bDropdownItem from 'bootstrap-vue/lib/components/dropdown-item'; import bDropdownItem from 'bootstrap-vue/lib/components/dropdown-item';
import Item from 'client/components/inventory/item'; import Item from 'client/components/inventory/item';
import ItemRows from 'client/components/ui/itemRows'; import ItemRows from 'client/components/ui/itemRows';
import CountBadge from 'client/components/ui/countBadge';
import HatchedPetDialog from '../stable/hatchedPetDialog'; import HatchedPetDialog from '../stable/hatchedPetDialog';
import createAnimal from 'client/libs/createAnimal'; import createAnimal from 'client/libs/createAnimal';
import moment from 'moment';
const allowedSpecialItems = ['snowball', 'spookySparkles', 'shinySeed', 'seafoam']; const allowedSpecialItems = ['snowball', 'spookySparkles', 'shinySeed', 'seafoam'];
import notifications from 'client/mixins/notifications';
import DragDropDirective from 'client/directives/dragdrop.directive'; import DragDropDirective from 'client/directives/dragdrop.directive';
import MouseMoveDirective from 'client/directives/mouseposition.directive'; import MouseMoveDirective from 'client/directives/mouseposition.directive';
@@ -191,6 +203,7 @@ const groups = [
let lastMouseMoveEvent = {}; let lastMouseMoveEvent = {};
export default { export default {
mixins: [notifications],
name: 'Items', name: 'Items',
components: { components: {
Item, Item,
@@ -198,6 +211,7 @@ export default {
bDropdown, bDropdown,
bDropdownItem, bDropdownItem,
HatchedPetDialog, HatchedPetDialog,
CountBadge,
}, },
directives: { directives: {
drag: DragDropDirective, drag: DragDropDirective,
@@ -243,6 +257,7 @@ export default {
if (isSearched) { if (isSearched) {
itemsArray.push({ itemsArray.push({
...item, ...item,
class: `${group.classPrefix}${item.key}`,
text: item.text(), text: item.text(),
notes: item.notes(), notes: item.notes(),
quantity: itemQuantity, quantity: itemQuantity,
@@ -262,6 +277,30 @@ export default {
}); });
}); });
let specialArray = [];
if (this.user.purchased.plan.mysteryItems.length) {
specialArray.push({
key: 'mysteryItem',
class: `inventory_present inventory_present_${moment().format('MM')}`,
text: this.$t('subscriberItemText'),
quantity: this.user.purchased.plan.mysteryItems.length,
});
}
if (this.user.purchased.plan.consecutive.trinkets) {
specialArray.push({
key: 'timeTravelers',
class: 'inventory_special_trinket',
text: this.$t('mysticHourglassPopover'),
quantity: this.user.purchased.plan.consecutive.trinkets,
});
}
if (specialArray.length > 0) {
itemsByType.special = specialArray;
}
return itemsByType; return itemsByType;
}, },
}, },
@@ -347,6 +386,19 @@ export default {
this.hatchedPet = null; this.hatchedPet = null;
}, },
async itemClicked (groupKey, item) {
if (groupKey === 'special') {
if (item.key === 'timeTravelers') {
this.$router.push({name: 'time'});
} else if (item.key === 'mysteryItem') {
let result = await this.$store.dispatch('user:openMysteryItem');
let openedItem = result.data.data;
let text = this.content.gear.flat[openedItem.key].text();
this.drop(this.$t('messageDropMysteryItem', {dropText: text}), openedItem);
}
}
},
mouseMoved ($event) { mouseMoved ($event) {
if (this.potionClickMode) { if (this.potionClickMode) {

View File

@@ -167,9 +167,10 @@
import BalanceInfo from './balanceInfo.vue'; import BalanceInfo from './balanceInfo.vue';
import currencyMixin from './_currencyMixin'; import currencyMixin from './_currencyMixin';
import notifications from 'client/mixins/notifications';
export default { export default {
mixins: [currencyMixin], mixins: [currencyMixin, notifications],
components: { components: {
bModal, bModal,
BalanceInfo, BalanceInfo,
@@ -206,6 +207,16 @@
this.$emit('change', $event); this.$emit('change', $event);
}, },
buyItem () { buyItem () {
if (this.genericPurchase) {
this.$store.dispatch('shops:genericPurchase', {
pinType: this.item.pinType,
type: this.item.purchaseType,
key: this.item.key,
currency: this.item.currency,
});
this.purchased(this.item.text);
}
this.$emit('buyPressed', this.item); this.$emit('buyPressed', this.item);
this.hideDialog(); this.hideDialog();
}, },
@@ -236,6 +247,10 @@
withPin: { withPin: {
type: Boolean, type: Boolean,
}, },
genericPurchase: {
type: Boolean,
default: true,
},
}, },
}; };
</script> </script>

View File

@@ -150,9 +150,12 @@
span(slot="popoverContent") span(slot="popoverContent")
h4.popover-content-title {{ item.text }} h4.popover-content-title {{ item.text }}
template(slot="itemImage", scope="scope")
span.svg-icon.inline.icon-48(v-if="scope.item.key == 'gem'", v-html="icons.gem")
template(slot="itemBadge", scope="ctx") template(slot="itemBadge", scope="ctx")
countBadge( countBadge(
v-if="item.purchaseType !== 'card'", v-if="item.showCount != false",
:show="userItems[item.purchaseType][item.key] != 0", :show="userItems[item.purchaseType][item.key] != 0",
:count="userItems[item.purchaseType][item.key] || 0" :count="userItems[item.purchaseType][item.key] || 0"
) )
@@ -230,8 +233,7 @@
priceType="gold", priceType="gold",
:withPin="true", :withPin="true",
@change="resetGearToBuy($event)", @change="resetGearToBuy($event)",
@buyPressed="buyGear($event)", @togglePinned="togglePinned($event)",
@togglePinned="togglePinned($event)"
) )
template(slot="item", scope="ctx") template(slot="item", scope="ctx")
div div
@@ -250,14 +252,16 @@
:item="selectedItemToBuy", :item="selectedItemToBuy",
:priceType="selectedItemToBuy ? selectedItemToBuy.currency : ''", :priceType="selectedItemToBuy ? selectedItemToBuy.currency : ''",
@change="resetItemToBuy($event)", @change="resetItemToBuy($event)",
@buyPressed="buyItem($event)", @togglePinned="togglePinned($event)",
@togglePinned="togglePinned($event)" @buyPressed="purchaseCallback($event)",
:genericPurchase="selectedItemToBuy != null && selectedItemToBuy.key != 'rebirth_orb'"
) )
template(slot="item", scope="ctx") template(slot="item", scope="ctx")
item.flat.bordered-item( item.flat.bordered-item(
:item="ctx.item", :item="ctx.item",
:itemContentClass="ctx.item.class", :itemContentClass="ctx.item.class",
:showPopover="false" :showPopover="false",
v-if="ctx.item.key != 'gem'"
) )
selectMembersModal( selectMembersModal(
@@ -306,6 +310,10 @@
width: 12px; width: 12px;
height: 12px; height: 12px;
} }
.icon-48 {
width: 48px;
height: 48px;
}
.hand-cursor { .hand-cursor {
cursor: pointer; cursor: pointer;
@@ -409,6 +417,7 @@
import bDropdownItem from 'bootstrap-vue/lib/components/dropdown-item'; import bDropdownItem from 'bootstrap-vue/lib/components/dropdown-item';
import svgPin from 'assets/svg/pin.svg'; import svgPin from 'assets/svg/pin.svg';
import svgGem from 'assets/svg/gem.svg';
import svgInformation from 'assets/svg/information.svg'; import svgInformation from 'assets/svg/information.svg';
import svgWarrior from 'assets/svg/warrior.svg'; import svgWarrior from 'assets/svg/warrior.svg';
import svgWizard from 'assets/svg/wizard.svg'; import svgWizard from 'assets/svg/wizard.svg';
@@ -475,6 +484,7 @@ export default {
icons: Object.freeze({ icons: Object.freeze({
pin: svgPin, pin: svgPin,
gem: svgGem,
information: svgInformation, information: svgInformation,
warrior: svgWarrior, warrior: svgWarrior,
wizard: svgWizard, wizard: svgWizard,
@@ -528,9 +538,50 @@ export default {
items: _map(_filter(this.content.cardTypes, (value) => { items: _map(_filter(this.content.cardTypes, (value) => {
return value.yearRound; return value.yearRound;
}), (value) => { }), (value) => {
return getItemInfo(this.user, 'card', value); return {
...getItemInfo(this.user, 'card', value),
showCount: false,
};
}), }),
}); });
let specialItems = [];
if (this.user.purchased.plan.customerId) {
specialItems.push({
showCount: false,
key: 'gem',
class: 'gem',
pinKey: 'gems',
purchaseType: 'gems',
text: this.$t('subGemName'),
notes: this.$t('subGemPop'),
currency: 'gold',
value: 20,
});
}
if (this.user.flags.rebirthEnabled) {
specialItems.push({
showCount: false,
key: 'rebirth_orb',
class: 'rebirth_orb',
purchaseType: 'rebirth_orb',
text: this.$t('rebirthName'),
notes: this.$t('rebirthPop'),
currency: 'gems',
value: this.user.stats.lvl < 100 ? 6 : '',
});
}
if (specialItems.length > 0) {
categories.push({
identifier: 'special',
text: this.$t('special'),
items: specialItems,
});
}
categories.map((category) => { categories.map((category) => {
this.$set(this.viewOptions, category.identifier, { this.$set(this.viewOptions, category.identifier, {
selected: true, selected: true,
@@ -655,7 +706,9 @@ export default {
return !this.userItems.gear.owned[gear.key]; return !this.userItems.gear.owned[gear.key];
}); });
result = _sortBy(result, [sortGearTypeMap[sortBy]]); // first all unlocked
// then the selected sort
result = _sortBy(result, [(item) => item.locked, sortGearTypeMap[sortBy]]);
return result; return result;
}, },
@@ -735,12 +788,6 @@ export default {
this.$parent.showUnpinNotification(item); this.$parent.showUnpinNotification(item);
} }
}, },
buyGear (item) {
this.$store.dispatch('shops:buyItem', {key: item.key});
},
buyItem (item) {
this.$store.dispatch('shops:purchase', {type: item.purchaseType, key: item.key});
},
itemSelected (item) { itemSelected (item) {
if (item.purchaseType === 'card') { if (item.purchaseType === 'card') {
if (this.user.party._id) { if (this.user.party._id) {
@@ -761,6 +808,12 @@ export default {
this.$store.dispatch('user:castSpell', {key: this.selectedCardToBuy.key, targetId: member.id}); this.$store.dispatch('user:castSpell', {key: this.selectedCardToBuy.key, targetId: member.id});
this.selectedCardToBuy = null; this.selectedCardToBuy = null;
}, },
async purchaseCallback (item) {
if (item.key === 'rebirth_orb') {
await this.$store.dispatch('user:rebirth');
window.location.reload(true);
}
},
}, },
created () { created () {
this.selectedGroupGearByClass = this.userStats.class; this.selectedGroupGearByClass = this.userStats.class;

View File

@@ -235,9 +235,10 @@
import BalanceInfo from '../balanceInfo.vue'; import BalanceInfo from '../balanceInfo.vue';
import currencyMixin from '../_currencyMixin'; import currencyMixin from '../_currencyMixin';
import QuestInfo from './questInfo.vue'; import QuestInfo from './questInfo.vue';
import notifications from 'client/mixins/notifications';
export default { export default {
mixins: [currencyMixin], mixins: [currencyMixin, notifications],
components: { components: {
bModal, bModal,
BalanceInfo, BalanceInfo,
@@ -278,6 +279,13 @@
this.$emit('change', $event); this.$emit('change', $event);
}, },
buyItem () { buyItem () {
this.$store.dispatch('shops:genericPurchase', {
pinType: this.item.pinType,
type: this.item.purchaseType,
key: this.item.key,
currency: this.item.currency,
});
this.purchased(this.item.text);
this.$emit('buyPressed', this.item); this.$emit('buyPressed', this.item);
this.hideDialog(); this.hideDialog();
}, },

View File

@@ -183,7 +183,6 @@
:priceType="selectedItemToBuy ? selectedItemToBuy.currency : ''", :priceType="selectedItemToBuy ? selectedItemToBuy.currency : ''",
:withPin="true", :withPin="true",
@change="resetItemToBuy($event)", @change="resetItemToBuy($event)",
@buyPressed="buyItem($event)",
@togglePinned="togglePinned($event)" @togglePinned="togglePinned($event)"
) )
template(slot="item", scope="ctx") template(slot="item", scope="ctx")
@@ -477,9 +476,6 @@ export default {
this.$parent.showUnpinNotification(item); this.$parent.showUnpinNotification(item);
} }
}, },
buyItem (item) {
this.$store.dispatch('shops:purchase', {type: item.purchaseType, key: item.key});
},
}, },
created () { created () {
this.$store.dispatch('shops:fetchQuests'); this.$store.dispatch('shops:fetchQuests');

View File

@@ -112,7 +112,6 @@
:priceType="selectedItemToBuy ? selectedItemToBuy.currency : ''", :priceType="selectedItemToBuy ? selectedItemToBuy.currency : ''",
:withPin="true", :withPin="true",
@change="resetItemToBuy($event)", @change="resetItemToBuy($event)",
@buyPressed="buyItem($event)",
@togglePinned="togglePinned($event)" @togglePinned="togglePinned($event)"
) )
template(slot="item", scope="ctx") template(slot="item", scope="ctx")
@@ -491,9 +490,6 @@
this.$parent.showUnpinNotification(item); this.$parent.showUnpinNotification(item);
} }
}, },
buyItem (item) {
this.$store.dispatch('shops:purchase', {type: item.purchaseType, key: item.key});
},
}, },
created () { created () {
this.$store.dispatch('shops:fetchSeasonal'); this.$store.dispatch('shops:fetchSeasonal');

View File

@@ -23,6 +23,7 @@ b-popover(
div.image div.image
div(:class="item.class", v-once) div(:class="item.class", v-once)
slot(name="itemImage", :item="item")
div.price div.price
span.svg-icon.inline.icon-16(v-html="icons[currencyClass]") span.svg-icon.inline.icon-16(v-html="icons[currencyClass]")

View File

@@ -11,7 +11,7 @@ span.badge.badge-pill.badge-item.badge-count(
right: -9px; right: -9px;
color: $white; color: $white;
background: $gray-200; background: $gray-200;
padding: 4.5px 6px; padding: 4.5px 8.5px;
min-width: 24px; min-width: 24px;
height: 24px; height: 24px;
box-shadow: 0 1px 1px 0 rgba($black, 0.12); box-shadow: 0 1px 1px 0 rgba($black, 0.12);

View File

@@ -86,6 +86,11 @@ export default {
mp (val) { mp (val) {
this.notify(`${this.sign(val)} ${this.round(val)}`, 'mp', 'glyphicon glyphicon-fire', this.sign(val)); this.notify(`${this.sign(val)} ${this.round(val)}`, 'mp', 'glyphicon glyphicon-fire', this.sign(val));
}, },
purchased (itemName) {
this.notify(this.$t('purchasedItem', {
itemName,
}));
},
streak (val) { streak (val) {
this.notify(`${this.$t('streaks')}: ${val}`, 'streak', 'glyphicon glyphicon-repeat'); this.notify(`${this.$t('streaks')}: ${val}`, 'streak', 'glyphicon glyphicon-repeat');
}, },

View File

@@ -1,10 +1,12 @@
import axios from 'axios'; import axios from 'axios';
import { loadAsyncResource } from 'client/libs/asyncResource'; import { loadAsyncResource } from 'client/libs/asyncResource';
import buyOp from 'common/script/ops/buy'; import buyOp from 'common/script/ops/buy';
import buyQuestOp from 'common/script/ops/buyQuest';
import purchaseOp from 'common/script/ops/purchaseWithSpell'; import purchaseOp from 'common/script/ops/purchaseWithSpell';
import buyMysterySetOp from 'common/script/ops/buyMysterySet'; import buyMysterySetOp from 'common/script/ops/buyMysterySet';
import hourglassPurchaseOp from 'common/script/ops/hourglassPurchase'; import hourglassPurchaseOp from 'common/script/ops/hourglassPurchase';
import sellOp from 'common/script/ops/sell'; import sellOp from 'common/script/ops/sell';
import unlockOp from 'common/script/ops/unlock';
export function fetchMarket (store, forceLoad = false) { // eslint-disable-line no-shadow export function fetchMarket (store, forceLoad = false) { // eslint-disable-line no-shadow
return loadAsyncResource({ return loadAsyncResource({
@@ -57,44 +59,86 @@ export function fetchTimeTravelers (store, forceLoad = false) { // eslint-disabl
export function buyItem (store, params) { export function buyItem (store, params) {
const user = store.state.user.data; const user = store.state.user.data;
buyOp(user, {params}); let opResult = buyOp(user, {params});
axios
.post(`/api/v3/user/buy/${params.key}`); return {
// TODO result: opResult,
// .then((res) => console.log('equip', res)) httpCall: axios.post(`/api/v3/user/buy/${params.key}`),
// .catch((err) => console.error('equip', err)); };
}
export function buyQuestItem (store, params) {
const user = store.state.user.data;
let opResult = buyQuestOp(user, {params});
return {
result: opResult,
httpCall: axios.post(`/api/v3/user/buy-quest/${params.key}`),
};
} }
export function purchase (store, params) { export function purchase (store, params) {
const user = store.state.user.data; const user = store.state.user.data;
purchaseOp(user, {params}); let opResult = purchaseOp(user, {params});
axios
.post(`/api/v3/user/purchase/${params.type}/${params.key}`); return {
// TODO result: opResult,
// .then((res) => console.log('equip', res)) httpCall: axios.post(`/api/v3/user/purchase/${params.type}/${params.key}`),
// .catch((err) => console.error('equip', err)); };
} }
export function purchaseMysterySet (store, params) { export function purchaseMysterySet (store, params) {
const user = store.state.user.data; const user = store.state.user.data;
buyMysterySetOp(user, {params}); let opResult = buyMysterySetOp(user, {params});
axios
.post(`/api/v3/user/buy-mystery-set/${params.key}`); return {
// TODO result: opResult,
// .then((res) => console.log('equip', res)) httpCall: axios.post(`/api/v3/user/buy-mystery-set/${params.key}`),
// .catch((err) => console.error('equip', err)); };
} }
export function purchaseHourglassItem (store, params) { export function purchaseHourglassItem (store, params) {
const user = store.state.user.data; const user = store.state.user.data;
hourglassPurchaseOp(user, {params}); let opResult = hourglassPurchaseOp(user, {params});
axios
.post(`/api/v3/user/purchase-hourglass/${params.type}/${params.key}`); return {
// TODO result: opResult,
// .then((res) => console.log('equip', res)) httpCall: axios.post(`/api/v3/user/purchase-hourglass/${params.type}/${params.key}`),
// .catch((err) => console.error('equip', err)); };
} }
export function unlock (store, params) {
const user = store.state.user.data;
let opResult = unlockOp(user, params);
return {
result: opResult,
httpCall: axios.post(`/api/v3/user/unlock?path=${params.query.path}`),
};
}
export function genericPurchase (store, params) {
switch (params.pinType) {
case 'mystery_set':
return purchaseMysterySet(store, params);
case 'potion':
case 'armoire':
case 'marketGear':
return buyItem(store, params);
case 'background':
return unlock(store, {
query: {
path: `background.${params.key}`,
},
});
default:
if (params.pinType === 'quests' && params.currency === 'gold') {
return buyQuestItem(store, params);
} else {
return purchase(store, params);
}
}
}
export function sellItems (store, params) { export function sellItems (store, params) {
const user = store.state.user.data; const user = store.state.user.data;

View File

@@ -96,3 +96,11 @@ export function castSpell (store, params) {
return axios.post(spellUrl); return axios.post(spellUrl);
} }
export function openMysteryItem () {
return axios.post('/api/v3/user/open-mystery-item');
}
export function rebirth () {
return axios.post('/api/v3/user/rebirth');
}

View File

@@ -303,5 +303,6 @@
"health_wellness": "Health & Wellness", "health_wellness": "Health & Wellness",
"self_care": "Self-Care", "self_care": "Self-Care",
"sendLink": "Send Link", "sendLink": "Send Link",
"forgotPassword": "Forgot Password" "forgotPassword": "Forgot Password",
"purchasedItem": "You bought <%= itemName %>"
} }

View File

@@ -584,12 +584,20 @@ let backgrounds = {
}; };
/* eslint-enable quote-props */ /* eslint-enable quote-props */
let flat = {};
forOwn(backgrounds, function prefillBackgroundSet (backgroundsInSet, set) { forOwn(backgrounds, function prefillBackgroundSet (backgroundsInSet, set) {
forOwn(backgroundsInSet, function prefillBackground (background, bgKey) { forOwn(backgroundsInSet, function prefillBackground (background, bgKey) {
background.key = bgKey; background.key = bgKey;
background.set = set; background.set = set;
background.price = 7; background.price = 7;
flat[bgKey] = background;
}); });
}); });
module.exports = backgrounds; module.exports = {
tree: backgrounds,
flat,
};

View File

@@ -24,7 +24,7 @@ import {
} from './quests'; } from './quests';
import appearances from './appearance'; import appearances from './appearance';
import backgrounds from './appearance/backgrounds.js'; import backgrounds from './appearance/backgrounds';
import spells from './spells'; import spells from './spells';
import subscriptionBlocks from './subscriptionBlocks'; import subscriptionBlocks from './subscriptionBlocks';
import faq from './faq'; import faq from './faq';
@@ -523,7 +523,8 @@ each(api.food, (food, key) => {
api.appearances = appearances; api.appearances = appearances;
api.backgrounds = backgrounds; api.backgrounds = backgrounds.tree;
api.backgroundsFlat = backgrounds.flat;
api.userDefaults = { api.userDefaults = {
habits: [ habits: [

View File

@@ -137,7 +137,7 @@ module.exports = function getItemInfo (user, type, item, language = 'en') {
}; };
}) : undefined, }) : undefined,
lvl: item.lvl, lvl: item.lvl,
class: locked ? `inventory_quest_scroll_locked inventory_quest_scroll_${item.key}_locked` : `inventory_quest_scroll inventory_quest_scroll_${item.key}`, class: locked ? `inventory_quest_scroll_${item.key}_locked` : `inventory_quest_scroll_${item.key}`,
purchaseType: 'quests', purchaseType: 'quests',
path: `quests.${item.key}`, path: `quests.${item.key}`,
pinType: 'quests', pinType: 'quests',

View File

@@ -9,6 +9,10 @@ import {
BadRequest, BadRequest,
} from '../libs/errors'; } from '../libs/errors';
import { removeItemByPath } from './pinnedGearUtils';
import getItemInfo from '../libs/getItemInfo';
import content from '../content/index';
// If item is already purchased -> equip it // If item is already purchased -> equip it
// Otherwise unlock it // Otherwise unlock it
module.exports = function unlock (user, req = {}, analytics) { module.exports = function unlock (user, req = {}, analytics) {
@@ -75,10 +79,11 @@ module.exports = function unlock (user, req = {}, analytics) {
setWith(user, `purchased.${pathPart}`, true, Object); setWith(user, `purchased.${pathPart}`, true, Object);
}); });
} else { } else {
let split = path.split('.');
let value = split.pop();
let key = split.join('.');
if (alreadyOwns) { // eslint-disable-line no-lonely-if if (alreadyOwns) { // eslint-disable-line no-lonely-if
let split = path.split('.');
let value = split.pop();
let key = split.join('.');
if (key === 'background' && value === user.preferences.background) { if (key === 'background' && value === user.preferences.background) {
value = ''; value = '';
} }
@@ -88,6 +93,10 @@ module.exports = function unlock (user, req = {}, analytics) {
} else { } else {
// Using Object so path[1] won't create an array but an object {path: {1: value}} // Using Object so path[1] won't create an array but an object {path: {1: value}}
setWith(user, `purchased.${path}`, true, Object); setWith(user, `purchased.${path}`, true, Object);
let backgroundContent = content.backgroundsFlat[value];
let itemInfo = getItemInfo(user, 'background', backgroundContent);
removeItemByPath(user, itemInfo.path);
} }
} }