mirror of
https://github.com/HabitRPG/habitica.git
synced 2025-12-14 21:27:23 +01:00
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:
Binary file not shown.
|
Before Width: | Height: | Size: 3.1 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 1.1 KiB |
@@ -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;
|
|
||||||
}
|
|
||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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();
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -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');
|
||||||
|
|||||||
@@ -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');
|
||||||
|
|||||||
@@ -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]")
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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');
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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');
|
||||||
|
}
|
||||||
|
|||||||
@@ -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 %>"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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,
|
||||||
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -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: [
|
||||||
|
|||||||
@@ -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',
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user