diff --git a/website/client/assets/scss/item.scss b/website/client/assets/scss/item.scss
index 17688fdeb0..26415e5310 100644
--- a/website/client/assets/scss/item.scss
+++ b/website/client/assets/scss/item.scss
@@ -2,7 +2,7 @@
.items > div {
display: inline-block;
- margin-right: 24px;
+ margin-right: 23px;
}
.items > div:last-of-type {
@@ -87,3 +87,7 @@
color: $gray-400;
margin-top: 4px;
}
+
+.questPopover {
+ width: 200px;
+}
diff --git a/website/client/assets/scss/modal.scss b/website/client/assets/scss/modal.scss
index dc79171453..7f85a2cb9b 100644
--- a/website/client/assets/scss/modal.scss
+++ b/website/client/assets/scss/modal.scss
@@ -14,7 +14,7 @@
.modal-dialog {
.title {
- height: 24px;
+ min-height: 24px;
margin-top: 24px;
font-family: 'Roboto Condensed';
font-size: 20px;
diff --git a/website/client/assets/svg/difficulty-star-empty.svg b/website/client/assets/svg/difficulty-star-empty.svg
new file mode 100644
index 0000000000..d8178601e3
--- /dev/null
+++ b/website/client/assets/svg/difficulty-star-empty.svg
@@ -0,0 +1,3 @@
+
diff --git a/website/client/assets/svg/difficulty-star-half.svg b/website/client/assets/svg/difficulty-star-half.svg
new file mode 100644
index 0000000000..8643d1a6fb
--- /dev/null
+++ b/website/client/assets/svg/difficulty-star-half.svg
@@ -0,0 +1,6 @@
+
diff --git a/website/client/components/appMenu.vue b/website/client/components/appMenu.vue
index 645a06d754..78a3d0625c 100644
--- a/website/client/components/appMenu.vue
+++ b/website/client/components/appMenu.vue
@@ -52,6 +52,9 @@ div
a.dropdown-item(href="https://trello.com/c/odmhIqyW/440-read-first-table-of-contents", target='_blank') {{ $t('requestAF') }}
a.dropdown-item(href="http://habitica.wikia.com/wiki/Contributing_to_Habitica", target='_blank') {{ $t('contributing') }}
a.dropdown-item(href="http://habitica.wikia.com/wiki/Habitica_Wiki", target='_blank') {{ $t('wiki') }}
+ .item-with-icon(v-if="userHourglasses != 0")
+ .svg-icon(v-html="icons.hourglasses")
+ span {{ userHourglasses }}
.item-with-icon
.svg-icon(v-html="icons.gem")
span {{userGems | roundBigNumber}}
@@ -219,6 +222,7 @@ import { mapState, mapGetters } from 'client/libs/store';
import gemIcon from 'assets/svg/gem.svg';
import goldIcon from 'assets/svg/gold.svg';
import userIcon from 'assets/svg/user.svg';
+import svgHourglasses from 'assets/svg/hourglass.svg';
import logo from 'assets/svg/logo.svg';
import InboxModal from './userMenu/inbox.vue';
import notificationMenu from './notificationMenu';
@@ -236,6 +240,7 @@ export default {
gem: gemIcon,
gold: goldIcon,
user: userIcon,
+ hourglasses: svgHourglasses,
logo,
}),
groupPlans: [],
@@ -245,7 +250,10 @@ export default {
...mapGetters({
userGems: 'user:gems',
}),
- ...mapState({user: 'user.data'}),
+ ...mapState({
+ user: 'user.data',
+ userHourglasses: 'user.data.purchased.plan.consecutive.trinkets',
+ }),
},
mounted () {
this.getUserGroupPlans();
diff --git a/website/client/components/creatorIntro.vue b/website/client/components/creatorIntro.vue
index 557b2b488f..9287a72c32 100644
--- a/website/client/components/creatorIntro.vue
+++ b/website/client/components/creatorIntro.vue
@@ -157,7 +157,7 @@ b-modal#avatar-modal(title="", size='lg', :hide-header='true', :hide-footer='tru
.col-6.offset-3.text-center.set-title
strong {{set.text}}
.col-12(v-if='showPlainBackgroundBlurb(set.identifier, set.items)') {{ $t('incentiveBackgroundsUnlockedWithCheckins') }}
- .col-4.text-center.customize-option(v-for='bg in set.items',
+ .col-4.text-center.customize-option.background-button(v-for='bg in set.items',
@click='unlock("background." + bg.key)',
:popover-title='bg.text',
:popover='bg.notes',
@@ -167,6 +167,11 @@ b-modal#avatar-modal(title="", size='lg', :hide-header='true', :hide-footer='tru
.purchase-single(v-if='!user.purchased.background[bg.key]')
.svg-icon.gem(v-html='icons.gem')
span 7
+ span.badge.badge-pill.badge-item.badge-svg(
+ :class="{'item-selected-badge': isBackgroundPinned(bg), 'hide': !isBackgroundPinned(bg)}",
+ @click.prevent.stop="togglePinned(bg)"
+ )
+ span.svg-icon.inline.icon-12.color(v-html="icons.pin")
.col-12.text-center(v-if='!ownsSet("background", set.items) && set.identifier !== "incentiveBackgrounds"')
.gem-amount
.svg-icon.gem(v-html='icons.gem')
@@ -488,6 +493,39 @@ b-modal#avatar-modal(title="", size='lg', :hide-header='true', :hide-footer='tru
vertical-align: bottom;
}
}
+
+
+ .badge-svg {
+ left: calc((100% - 18px) / 2);
+ cursor: pointer;
+ color: $gray-400;
+ background: $white;
+ padding: 4.5px 6px;
+
+ &.item-selected-badge {
+ background: $purple-300;
+ color: $white;
+ }
+ }
+
+ .icon-12 {
+ width: 12px;
+ height: 12px;
+ }
+
+ span.badge.badge-pill.badge-item.badge-svg:not(.item-selected-badge) {
+ color: #a5a1ac;
+ }
+
+ span.badge.badge-pill.badge-item.badge-svg.hide {
+ display: none;
+ }
+
+ .background-button:hover {
+ span.badge.badge-pill.badge-item.badge-svg.hide {
+ display: block;
+ }
+ }
diff --git a/website/client/components/inventory/items/index.vue b/website/client/components/inventory/items/index.vue
index d720c62fd9..6e8724f540 100644
--- a/website/client/components/inventory/items/index.vue
+++ b/website/client/components/inventory/items/index.vue
@@ -48,7 +48,7 @@
:item="context.item",
:key="context.item.key",
:itemContentClass="`${group.classPrefix}${context.item.key}`",
- :highlightBorder="currentDraggingPotion != null",
+ :highlightBorder="isHatchable(currentDraggingPotion, context.item.key)",
v-drag.drop.hatch="context.item.key",
@itemDragOver="onDragOver($event, context.item)",
@@ -58,8 +58,8 @@
@click="onEggClicked($event, context.item)",
)
template(slot="popoverContent", scope="context")
- h4.popover-content-title {{ context.item.text() }}
- .popover-content-text(v-if="currentDraggingPotion == null") {{ context.item.notes() }}
+ h4.popover-content-title {{ context.item.text }}
+ .popover-content-text(v-if="currentDraggingPotion == null") {{ context.item.notes }}
template(slot="itemBadge", scope="context")
span.badge.badge-pill.badge-item.badge-quantity {{ context.item.quantity }}
@@ -86,8 +86,8 @@
@click="onPotionClicked($event, context.item)"
)
template(slot="popoverContent", scope="context")
- h4.popover-content-title {{ context.item.text() }}
- .popover-content-text {{ context.item.notes() }}
+ h4.popover-content-title {{ context.item.text }}
+ .popover-content-text {{ context.item.notes }}
template(slot="itemBadge", scope="context")
span.badge.badge-pill.badge-item.badge-quantity {{ context.item.quantity }}
@@ -107,8 +107,8 @@
:showPopover="currentDraggingPotion == null"
)
template(slot="popoverContent", scope="context")
- h4.popover-content-title {{ context.item.text() }}
- .popover-content-text {{ context.item.notes() }}
+ h4.popover-content-title {{ context.item.text }}
+ .popover-content-text {{ context.item.notes }}
template(slot="itemBadge", scope="context")
span.badge.badge-pill.badge-item.badge-quantity {{ context.item.quantity }}
@@ -121,13 +121,13 @@
div(v-if="currentDraggingPotion != null")
div.potion-icon(:class="'Pet_HatchingPotion_'+currentDraggingPotion.key")
div.popover
- div.popover-content {{ $t('dragThisPotion', {potionName: currentDraggingPotion.text() }) }}
+ div.popover-content {{ $t('dragThisPotion', {potionName: currentDraggingPotion.text }) }}
div.hatchingPotionInfo.mouse(ref="clickPotionInfo", v-if="potionClickMode")
div(v-if="currentDraggingPotion != null")
div.potion-icon(:class="'Pet_HatchingPotion_'+currentDraggingPotion.key")
div.popover
- div.popover-content {{ $t('clickOnEggToHatch', {potionName: currentDraggingPotion.text() }) }}
+ div.popover-content {{ $t('clickOnEggToHatch', {potionName: currentDraggingPotion.text }) }}
@@ -243,6 +243,8 @@ export default {
if (isSearched) {
itemsArray.push({
...item,
+ text: item.text(),
+ notes: item.notes(),
quantity: itemQuantity,
});
@@ -255,7 +257,7 @@ export default {
if (this.sortBy === 'quantity') {
return b.quantity - a.quantity;
} else { // AZ
- return a.data.text().localeCompare(b.data.text());
+ return a.text.localeCompare(b.text);
}
});
});
@@ -264,7 +266,7 @@ export default {
},
},
methods: {
- petExists (potionKey, eggKey) {
+ userHasPet (potionKey, eggKey) {
let animalKey = `${eggKey}-${potionKey}`;
let result = this.user.items.pets[animalKey] > 0;
@@ -290,10 +292,20 @@ export default {
dragEvent.dataTransfer.setDragImage(itemRef, -20, -20);
},
- onDragOver ($event, egg) {
- let potionKey = this.currentDraggingPotion.key;
+ isHatchable (potion, eggKey) {
+ if (potion === null)
+ return false;
- if (this.petExists(potionKey, egg.key)) {
+ let petKey = `${eggKey}-${potion.key}`;
+
+ if (!this.content.petInfo[petKey])
+ return false;
+
+ return !this.userHasPet(potion.key, eggKey);
+ },
+
+ onDragOver ($event, egg) {
+ if (this.isHatchable(this.currentDraggingPotion, egg.key)) {
$event.dropable = false;
}
},
@@ -309,7 +321,7 @@ export default {
return;
}
- if (!this.petExists(this.currentDraggingPotion.key, egg.key)) {
+ if (this.isHatchable(this.currentDraggingPotion, egg.key)) {
this.hatchPet(this.currentDraggingPotion, egg);
}
diff --git a/website/client/components/shops/market/index.vue b/website/client/components/shops/market/index.vue
index 0e4d101ef7..ad31d67729 100644
--- a/website/client/components/shops/market/index.vue
+++ b/website/client/components/shops/market/index.vue
@@ -144,13 +144,14 @@
:item="item",
:emptyItem="false",
:popoverPosition="'top'",
- @click="selectedItemToBuy = item"
+ @click="itemSelected(item)"
)
span(slot="popoverContent")
h4.popover-content-title {{ item.text }}
template(slot="itemBadge", scope="ctx")
countBadge(
+ v-if="item.purchaseType !== 'card'",
:show="userItems[item.purchaseType][item.key] != 0",
:count="userItems[item.purchaseType][item.key] || 0"
)
@@ -161,6 +162,7 @@
)
span.svg-icon.inline.icon-12.color(v-html="icons.pin")
+ div.fill-height
drawer(
:title="$t('quickInventory')"
@@ -255,11 +257,22 @@
:itemContentClass="ctx.item.class",
:showPopover="false"
)
+
+ selectMembersModal(
+ :card="selectedCardToBuy",
+ :group="user.party",
+ @change="resetCardToBuy($event)",
+ @memberSelected="memberSelected($event)",
+ )
+
+
diff --git a/website/client/components/shops/quests/buyQuestModal.vue b/website/client/components/shops/quests/buyQuestModal.vue
index ccc156a5e7..4f0720b306 100644
--- a/website/client/components/shops/quests/buyQuestModal.vue
+++ b/website/client/components/shops/quests/buyQuestModal.vue
@@ -23,7 +23,7 @@
h4.title {{ itemText }}
div.text(v-html="itemNotes")
- slot(name="additionalInfo", :item="item")
+ questInfo.questInfo(:quest="item")
div
span.svg-icon.inline.icon-32(aria-hidden="true", v-html="(priceType === 'gems') ? icons.gem : icons.gold")
@@ -81,7 +81,19 @@
.inner-content {
margin: 33px auto auto;
- width: 282px;
+ width: 400px;
+ }
+ .text {
+ max-height: 220px;
+ margin-bottom: 8px;
+ overflow-y: scroll;
+ text-overflow: ellipsis;
+ }
+
+ .questInfo {
+ width: 70%;
+ margin: 0 auto;
+ margin-bottom: 10px;
}
.content-text {
@@ -222,12 +234,14 @@
import BalanceInfo from '../balanceInfo.vue';
import currencyMixin from '../_currencyMixin';
+ import QuestInfo from './questInfo.vue';
export default {
mixins: [currencyMixin],
components: {
bModal,
BalanceInfo,
+ QuestInfo,
},
data () {
return {
diff --git a/website/client/components/shops/quests/index.vue b/website/client/components/shops/quests/index.vue
index 4d3cb9b544..f5dc6191fc 100644
--- a/website/client/components/shops/quests/index.vue
+++ b/website/client/components/shops/quests/index.vue
@@ -55,9 +55,9 @@
@click="selectedItemToBuy = item"
)
template(slot="popoverContent", scope="ctx")
- div
+ div.questPopover
h4.popover-content-title {{ item.text }}
- .popover-content-text(v-html="item.notes")
+ questInfo(:quest="item")
template(slot="itemBadge", scope="ctx")
span.badge.badge-pill.badge-item.badge-svg(
@@ -105,9 +105,9 @@
@click="selectedItemToBuy = ctx.item"
)
span(slot="popoverContent", scope="ctx")
- div
+ div.questPopover
h4.popover-content-title {{ ctx.item.text }}
- .popover-content-text(v-html="ctx.item.notes")
+ questInfo(:quest="ctx.item")
template(slot="itemBadge", scope="ctx")
span.badge.badge-pill.badge-item.badge-svg(
@@ -135,9 +135,9 @@
@click="selectedItemToBuy = item"
)
span(slot="popoverContent")
- div
+ div.questPopover
h4.popover-content-title {{ item.text }}
- .popover-content-text(v-html="item.notes")
+ questInfo(:quest="item")
template(slot="itemBadge", scope="ctx")
span.badge.badge-pill.badge-item.badge-svg(
@@ -162,9 +162,9 @@
@click="selectedItemToBuy = item"
)
span(slot="popoverContent")
- div
+ div.questPopover
h4.popover-content-title {{ item.text }}
- .popover-content-text(v-html="item.notes")
+ questInfo(:quest="item")
template(slot="itemBadge", scope="ctx")
span.badge.badge-pill.badge-item.badge-svg(
@@ -331,6 +331,7 @@
import Avatar from 'client/components/avatar';
import BuyModal from './buyQuestModal.vue';
+ import QuestInfo from './questInfo.vue';
import bPopover from 'bootstrap-vue/lib/components/popover';
import bDropdown from 'bootstrap-vue/lib/components/dropdown';
import bDropdownItem from 'bootstrap-vue/lib/components/dropdown-item';
@@ -363,6 +364,7 @@ export default {
Avatar,
BuyModal,
+ QuestInfo,
},
watch: {
searchText: _throttle(function throttleSearch () {
diff --git a/website/client/components/shops/quests/questInfo.vue b/website/client/components/shops/quests/questInfo.vue
new file mode 100644
index 0000000000..1bf64ded9b
--- /dev/null
+++ b/website/client/components/shops/quests/questInfo.vue
@@ -0,0 +1,88 @@
+
+ div.row
+ span.col-4(v-if="quest.collect") {{ $t('collect') }}
+ span.col-8(v-if="quest.collect")
+ div(v-for="(collect, key) of quest.collect")
+ span {{ collect.count }} {{ collect.text }}
+
+ span.col-4 {{ $t('difficulty') }}
+ span.col-8
+ span.svg-icon.inline.icon-16(v-for="star of stars()", v-html="icons[star]")
+
+
+
+
+
diff --git a/website/client/components/tasks/user.vue b/website/client/components/tasks/user.vue
index d8d5396f34..98d5b904bf 100644
--- a/website/client/components/tasks/user.vue
+++ b/website/client/components/tasks/user.vue
@@ -105,6 +105,14 @@
:item="ctx.item",
v-if="ctx.item.purchaseType === 'gear'"
)
+
+ selectMembersModal(
+ :card="selectedCardToBuy",
+ :group="user.party",
+ @change="resetCardToBuy($event)",
+ @memberSelected="memberSelectedToSendCard($event)",
+ )
+
spells
@@ -292,6 +300,7 @@ import BuyModal from 'client/components/shops/buyModal.vue';
import Item from 'client/components/inventory/item.vue';
import Avatar from 'client/components/avatar';
import EquipmentAttributesGrid from 'client/components/shops/market/equipmentAttributesGrid.vue';
+import SelectMembersModal from 'client/components/shops/market/selectMembersModal.vue';
export default {
components: {
@@ -304,6 +313,7 @@ export default {
Avatar,
EquipmentAttributesGrid,
spells,
+ SelectMembersModal,
},
data () {
return {
@@ -329,6 +339,7 @@ export default {
creatingTask: null,
selectedItemToBuy: null,
+ selectedCardToBuy: null,
};
},
computed: {
@@ -452,13 +463,20 @@ export default {
this.selectedItemToBuy = null;
}
},
+ resetCardToBuy ($event) {
+ if (!$event) {
+ this.selectedCardToBuy = null;
+ }
+ },
memberOverrideAvatarGear (gear) {
return {
[gear.type]: gear.key,
};
},
buyItem (item) {
- if (item.currency === 'gold') {
+ if (item.purchaseType === 'card') {
+ this.selectedCardToBuy = item;
+ } else if (item.currency === 'gold') {
this.$store.dispatch('shops:buyItem', {key: item.key});
} else {
this.$store.dispatch('shops:purchase', {type: item.purchaseType, key: item.key});
@@ -467,6 +485,10 @@ export default {
openBuyDialog (rewardItem) {
this.selectedItemToBuy = rewardItem;
},
+ memberSelectedToSendCard (member) {
+ this.$store.dispatch('user:castSpell', {key: this.selectedCardToBuy.key, targetId: member.id});
+ this.selectedCardToBuy = null;
+ },
},
};
diff --git a/website/client/components/ui/countBadge.vue b/website/client/components/ui/countBadge.vue
index b8f994b450..9d05cf0637 100644
--- a/website/client/components/ui/countBadge.vue
+++ b/website/client/components/ui/countBadge.vue
@@ -10,7 +10,7 @@ span.badge.badge-pill.badge-item.badge-count(
.badge-count {
right: -9px;
color: $white;
- background: $orange-100;
+ background: $gray-200;
padding: 4.5px 6px;
min-width: 24px;
height: 24px;
diff --git a/website/client/store/actions/user.js b/website/client/store/actions/user.js
index 4b18ef920b..bdf7c81f86 100644
--- a/website/client/store/actions/user.js
+++ b/website/client/store/actions/user.js
@@ -71,3 +71,10 @@ export function togglePinnedItem (store, params) {
return addedItem;
}
+
+export function castSpell (store, params) {
+ let spellUrl = `/api/v3/user/class/cast/${params.key}`;
+ if (params.targetId) spellUrl += `?targetId=${params.targetId}`;
+
+ return axios.post(spellUrl);
+}
diff --git a/website/common/locales/en/newClient.json b/website/common/locales/en/newClient.json
index 86a2db62ef..85accc962f 100644
--- a/website/common/locales/en/newClient.json
+++ b/website/common/locales/en/newClient.json
@@ -47,7 +47,7 @@
"dragThisFood": "Drag this <%= foodName %> to a Pet and watch it grow!",
"clickOnPetToFeed": "Click on a Pet to feed <%= foodName %> and watch it grow!",
"dragThisPotion": "Drag this <%= potionName %> to an Egg and hatch a new pet!",
- "clickOnEggToHatch": "Click on an Egg to use your <%= potionName %> and hatch a new pet!",
+ "clickOnEggToHatch": "Click on an Egg to use your <%= potionName %> hatching potion and hatch a new pet!",
"hatchDialogText": "Pour your <%= potionName %> hatching potion on your <%= eggName %> egg, and it will hatch into a <%= petName %> .",
"editAvatar": "Edit Avatar",
"sort": "Sort",
@@ -285,5 +285,7 @@
"sortByName": "Name",
"haveHatchablePet": "You have a <%= potion %> hatching potion and <%= egg %> egg to hatch this pet! Click the paw print to hatch.",
"welcomeBack": "Welcome back!",
- "checkOffYesterDailies": "Check off any Dailies you did yesterday:"
+ "checkOffYesterDailies": "Check off any Dailies you did yesterday:",
+ "selectPartyMember": "Select a Party Member",
+ "errorNotInParty": "You are not in a Party"
}
diff --git a/website/common/script/content/index.js b/website/common/script/content/index.js
index 1383cae9aa..0d00d2d01f 100644
--- a/website/common/script/content/index.js
+++ b/website/common/script/content/index.js
@@ -71,6 +71,7 @@ api.bundles = {
return moment().isBetween('2017-05-16', '2017-05-31');
},
type: 'quests',
+ class: 'quest_bundle_featheredFriends',
value: 7,
},
splashyPals: {
@@ -86,6 +87,7 @@ api.bundles = {
return moment().isBetween('2017-07-11', '2017-08-02');
},
type: 'quests',
+ class: 'quest_bundle_splashyPals',
value: 7,
},
};
diff --git a/website/common/script/content/shop-featuredItems.js b/website/common/script/content/shop-featuredItems.js
index 09c6b82e60..40f9594834 100644
--- a/website/common/script/content/shop-featuredItems.js
+++ b/website/common/script/content/shop-featuredItems.js
@@ -5,29 +5,33 @@ const featuredItems = {
path: 'armoire',
},
{
- type: 'hatchingPotion',
+ type: 'hatchingPotions',
path: 'hatchingPotions.Golden',
},
{
type: 'food',
path: 'food.Saddle',
},
+ {
+ type: 'card',
+ path: 'cardTypes.greeting',
+ },
],
quests: [
{
- type: 'quest',
+ type: 'quests',
path: 'quests.gryphon',
},
{
- type: 'quest',
+ type: 'quests',
path: 'quests.dilatoryDistress1',
},
{
- type: 'quest',
+ type: 'quests',
path: 'quests.nudibranch',
},
{
- type: 'quest',
+ type: 'quests',
path: 'quests.taskwoodsTerror1',
},
],
diff --git a/website/common/script/libs/getItemInfo.js b/website/common/script/libs/getItemInfo.js
index e27c7708e2..dc355cb469 100644
--- a/website/common/script/libs/getItemInfo.js
+++ b/website/common/script/libs/getItemInfo.js
@@ -3,6 +3,8 @@ import content from '../content/index';
import { BadRequest } from './errors';
import count from '../count';
+import _mapValues from 'lodash/mapValues';
+
function lockQuest (quest, user) {
if (quest.lvl && user.stats.lvl < quest.lvl) return true;
if (quest.unlockCondition && (quest.key === 'moon1' || quest.key === 'moon2' || quest.key === 'moon3')) {
@@ -42,7 +44,7 @@ module.exports = function getItemInfo (user, type, item, language = 'en') {
let itemInfo;
switch (type) {
- case 'egg':
+ case 'eggs':
itemInfo = {
key: item.key,
text: i18n.t('egg', {eggType: item.text(language)}, language),
@@ -53,10 +55,10 @@ module.exports = function getItemInfo (user, type, item, language = 'en') {
currency: 'gems',
purchaseType: 'eggs',
path: `eggs.${item.key}`,
- pinType: 'egg',
+ pinType: 'eggs',
};
break;
- case 'hatchingPotion':
+ case 'hatchingPotions':
itemInfo = {
key: item.key,
text: i18n.t('potion', {potionType: item.text(language)}),
@@ -67,7 +69,7 @@ module.exports = function getItemInfo (user, type, item, language = 'en') {
currency: 'gems',
purchaseType: 'hatchingPotions',
path: `hatchingPotions.${item.key}`,
- pinType: 'hatchingPotion',
+ pinType: 'hatchingPotions',
};
break;
case 'premiumHatchingPotion':
@@ -98,20 +100,20 @@ module.exports = function getItemInfo (user, type, item, language = 'en') {
pinType: 'food',
};
break;
- case 'questBundle':
+ case 'bundles':
itemInfo = {
key: item.key,
text: item.text(language),
notes: item.notes(language),
value: item.value,
currency: 'gems',
- class: `quest_bundle_${item.key}`,
+ class: item.class,
purchaseType: 'bundles',
path: `bundles.${item.key}`,
- pinType: 'questBundle',
+ pinType: 'bundles',
};
break;
- case 'quest': // eslint-disable-line no-case-declarations
+ case 'quests': // eslint-disable-line no-case-declarations
const locked = lockQuest(item, user);
itemInfo = {
@@ -125,13 +127,19 @@ module.exports = function getItemInfo (user, type, item, language = 'en') {
unlockCondition: item.unlockCondition,
drop: item.drop,
boss: item.boss,
- collect: item.collect,
+ collect: item.collect ? _mapValues(item.collect, (o) => {
+ return {
+ count: o.count,
+ text: o.text(),
+ };
+ }) : undefined,
lvl: item.lvl,
class: locked ? `inventory_quest_scroll_locked inventory_quest_scroll_${item.key}_locked` : `inventory_quest_scroll inventory_quest_scroll_${item.key}`,
purchaseType: 'quests',
path: `quests.${item.key}`,
- pinType: 'quest',
+ pinType: 'quests',
};
+
break;
case 'timeTravelers':
// TODO
@@ -235,6 +243,23 @@ module.exports = function getItemInfo (user, type, item, language = 'en') {
path: 'armoire',
pinType: 'armoire',
};
+ break;
+ case 'card': {
+ let spellInfo = content.spells.special[item.key];
+
+ itemInfo = {
+ key: item.key,
+ purchaseType: 'card',
+ class: `inventory_special_${item.key}`,
+ text: spellInfo.text(),
+ notes: spellInfo.notes(),
+ value: spellInfo.value,
+ currency: 'gold',
+ path: `cardTypes.${item.key}`,
+ pinType: 'card',
+ };
+ break;
+ }
}
if (itemInfo) {
diff --git a/website/common/script/libs/shops.js b/website/common/script/libs/shops.js
index 6aa2be0a7f..a136a42c85 100644
--- a/website/common/script/libs/shops.js
+++ b/website/common/script/libs/shops.js
@@ -24,7 +24,7 @@ shops.getMarketCategories = function getMarket (user, language) {
.filter(egg => egg.canBuy(user))
.concat(values(content.dropEggs))
.map(egg => {
- return getItemInfo(user, 'egg', egg, language);
+ return getItemInfo(user, 'eggs', egg, language);
}), 'key');
categories.push(eggsCategory);
@@ -36,7 +36,7 @@ shops.getMarketCategories = function getMarket (user, language) {
hatchingPotionsCategory.items = sortBy(values(content.hatchingPotions)
.filter(hp => !hp.limited)
.map(hatchingPotion => {
- return getItemInfo(user, 'hatchingPotion', hatchingPotion, language);
+ return getItemInfo(user, 'hatchingPotions', hatchingPotion, language);
}), 'key');
categories.push(hatchingPotionsCategory);
@@ -134,7 +134,7 @@ shops.getQuestShopCategories = function getQuestShopCategories (user, language)
bundleCategory.items = sortBy(values(content.bundles)
.filter(bundle => bundle.type === 'quests' && bundle.canBuy())
.map(bundle => {
- return getItemInfo(user, 'questBundle', bundle, language);
+ return getItemInfo(user, 'bundles', bundle, language);
}));
if (bundleCategory.items.length > 0) {
@@ -150,7 +150,7 @@ shops.getQuestShopCategories = function getQuestShopCategories (user, language)
category.items = content.questsByLevel
.filter(quest => quest.canBuy(user) && quest.category === type)
.map(quest => {
- return getItemInfo(user, 'quest', quest, language);
+ return getItemInfo(user, 'quests', quest, language);
});
categories.push(category);
diff --git a/website/common/script/ops/purchase.js b/website/common/script/ops/purchase.js
index a3efc076d1..c02346c4c9 100644
--- a/website/common/script/ops/purchase.js
+++ b/website/common/script/ops/purchase.js
@@ -11,6 +11,9 @@ import {
BadRequest,
} from '../libs/errors';
+import { removeItemByPath } from './pinnedGearUtils';
+import getItemInfo from '../libs/getItemInfo';
+
module.exports = function purchase (user, req = {}, analytics) {
let type = get(req.params, 'type');
let key = get(req.params, 'key');
@@ -103,6 +106,9 @@ module.exports = function purchase (user, req = {}, analytics) {
throw new NotAuthorized(i18n.t('notEnoughGems', req.language));
}
+ let itemInfo = getItemInfo(user, type, item);
+ removeItemByPath(user, itemInfo.path);
+
user.balance -= price;
if (type === 'gear') {