item pinning (#8918)
* toggle pinned state of items server + client * pin quests / add pin src * add officially pinned items and api to get in app rewards * update schema and get items deatils * update pin actions to the new logic * show countBadge only with a number * extract getPinKey - pin seasonal items * togglePinned in buy-dialogs * add pinKey to shop items * wip * wip * fix path * togglePinnedItem as common.op / use in client * fix linting * pinning: getItemInfo and save in db path and type * make api more consistent, fix bugs * updates * fix bugs * update actions to current api * marketGear * change to pinType * add mystery_set to getItemInfo * fix isPinned * ignore animals * list shopItems (initial) * shopItem now has default popoverconent, itemclass and price / currency - list pinned items as rewards - attributes to gear * show buyModal for the rewards * show mystery_set icon * add info whether item is suggested * write migration, fix style issues * pin potion and armoire * make potion, armoire not unpinnable * show notes for armoire and potion, add default items for new users * show unpin notification * add/remove pinned gear on class-change * remove pinned & add new gear on purchase - refactoring pinning methods - fixes * always allow to purchase armoire * highlight item if suggested
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
<template lang="pug">
|
||||
div
|
||||
h4.popover-content-title {{ item.text() }}
|
||||
.popover-content-text {{ item.notes() }}
|
||||
h4.popover-content-title {{ itemText }}
|
||||
.popover-content-text {{ itemNotes }}
|
||||
.popover-content-attr(v-for="attr in ATTRIBUTES", :key="attr", v-once)
|
||||
span.popover-content-attr-key {{ `${$t(attr)}: ` }}
|
||||
span.popover-content-attr-val {{ `+${item[attr]}` }}
|
||||
@@ -20,6 +20,20 @@ div
|
||||
...mapState({
|
||||
ATTRIBUTES: 'constants.ATTRIBUTES',
|
||||
}),
|
||||
itemText () {
|
||||
if (this.item.text instanceof Function) {
|
||||
return this.item.text();
|
||||
} else {
|
||||
return this.item.text;
|
||||
}
|
||||
},
|
||||
itemNotes () {
|
||||
if (this.item.notes instanceof Function) {
|
||||
return this.item.notes();
|
||||
} else {
|
||||
return this.item.notes;
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
export default function _isPinned (user, item) {
|
||||
const isUnpinned = user.unpinnedItems.findIndex(unpinned => unpinned.path === item.path) > -1;
|
||||
const isPinned = user.pinnedItems.findIndex(pinned => pinned.path === item.path) > -1;
|
||||
|
||||
return isPinned && !isUnpinned;
|
||||
}
|
||||
@@ -6,8 +6,9 @@
|
||||
@change="onChange($event)"
|
||||
)
|
||||
span.badge.badge-pill.badge-dialog(
|
||||
:class="{'item-selected-badge': true}",
|
||||
v-if="withPin"
|
||||
:class="{'item-selected-badge': item.pinned}",
|
||||
v-if="withPin",
|
||||
@click.prevent.stop="togglePinned()"
|
||||
)
|
||||
span.svg-icon.inline.color.icon-10(v-html="icons.pin")
|
||||
|
||||
@@ -127,7 +128,15 @@
|
||||
padding: 8px 10px;
|
||||
top: -12px;
|
||||
background: white;
|
||||
cursor: pointer;
|
||||
|
||||
&.item-selected-badge {
|
||||
background: $purple-300;
|
||||
color: $white;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -182,6 +191,9 @@
|
||||
this.$emit('buyPressed', this.item);
|
||||
this.hideDialog();
|
||||
},
|
||||
togglePinned () {
|
||||
this.$emit('togglePinned', this.item);
|
||||
},
|
||||
hideDialog () {
|
||||
this.$root.$emit('hide::modal', 'buy-modal');
|
||||
},
|
||||
|
||||
@@ -11,10 +11,17 @@
|
||||
|
||||
<script>
|
||||
import SecondaryMenu from 'client/components/secondaryMenu';
|
||||
import notifications from 'client/mixins/notifications';
|
||||
|
||||
export default {
|
||||
mixins: [notifications],
|
||||
components: {
|
||||
SecondaryMenu,
|
||||
},
|
||||
methods: {
|
||||
showUnpinNotification (item) {
|
||||
this.text(this.$t('unpinnedItem', {item: item.text}));
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -48,14 +48,11 @@
|
||||
:key="item.key",
|
||||
:item="item",
|
||||
:price="item.value",
|
||||
:priceType="item.currency",
|
||||
:itemContentClass="'shop_'+item.key",
|
||||
:emptyItem="false",
|
||||
:popoverPosition="'top'",
|
||||
@click="selectedGearToBuy = item"
|
||||
)
|
||||
template(slot="popoverContent", scope="ctx")
|
||||
equipmentAttributesPopover(:item="ctx.item")
|
||||
|
||||
h1.mb-0.page-header(v-once) {{ $t('market') }}
|
||||
|
||||
@@ -102,15 +99,10 @@
|
||||
shopItem(
|
||||
:key="ctx.item.key",
|
||||
:item="ctx.item",
|
||||
:price="ctx.item.value",
|
||||
:priceType="ctx.item.currency",
|
||||
:itemContentClass="'shop_'+ctx.item.key",
|
||||
:emptyItem="userItems.gear[ctx.item.key] === undefined",
|
||||
:popoverPosition="'top'",
|
||||
@click="selectedGearToBuy = ctx.item"
|
||||
)
|
||||
template(slot="popoverContent", scope="ctx")
|
||||
equipmentAttributesPopover(:item="ctx.item")
|
||||
|
||||
template(slot="itemBadge", scope="ctx")
|
||||
span.badge.badge-pill.badge-item.badge-svg(
|
||||
@@ -142,12 +134,9 @@
|
||||
|
||||
div.items
|
||||
shopItem(
|
||||
v-for="item in sortedMarketItems(category, selectedSortItemsBy, searchTextThrottled)",
|
||||
v-for="item in sortedMarketItems(category, selectedSortItemsBy, searchTextThrottled, hidePinned)",
|
||||
:key="item.key",
|
||||
:item="item",
|
||||
:price="item.value",
|
||||
:priceType="item.currency",
|
||||
:itemContentClass="item.class",
|
||||
:emptyItem="false",
|
||||
:popoverPosition="'top'",
|
||||
@click="selectedItemToBuy = item"
|
||||
@@ -161,6 +150,12 @@
|
||||
:count="userItems[item.purchaseType][item.key] || 0"
|
||||
)
|
||||
|
||||
span.badge.badge-pill.badge-item.badge-svg(
|
||||
:class="{'item-selected-badge': ctx.item.pinned, 'hide': !ctx.item.pinned}",
|
||||
@click.prevent.stop="togglePinned(ctx.item)"
|
||||
)
|
||||
span.svg-icon.inline.icon-12.color(v-html="icons.pin")
|
||||
|
||||
|
||||
drawer(
|
||||
:title="$t('quickInventory')"
|
||||
@@ -226,7 +221,8 @@
|
||||
priceType="gold",
|
||||
:withPin="true",
|
||||
@change="resetGearToBuy($event)",
|
||||
@buyPressed="buyGear($event)"
|
||||
@buyPressed="buyGear($event)",
|
||||
@togglePinned="togglePinned($event)"
|
||||
)
|
||||
template(slot="item", scope="ctx")
|
||||
div
|
||||
@@ -244,7 +240,8 @@
|
||||
:item="selectedItemToBuy",
|
||||
:priceType="selectedItemToBuy ? selectedItemToBuy.currency : ''",
|
||||
@change="resetItemToBuy($event)",
|
||||
@buyPressed="buyItem($event)"
|
||||
@buyPressed="buyItem($event)",
|
||||
@togglePinned="togglePinned($event)"
|
||||
)
|
||||
template(slot="item", scope="ctx")
|
||||
item.flat(
|
||||
@@ -380,8 +377,6 @@
|
||||
import toggleSwitch from 'client/components/ui/toggleSwitch';
|
||||
import Avatar from 'client/components/avatar';
|
||||
|
||||
import EquipmentAttributesPopover from 'client/components/inventory/equipment/attributesPopover';
|
||||
|
||||
import SellModal from './sellModal.vue';
|
||||
import BuyModal from '../buyModal.vue';
|
||||
import EquipmentAttributesGrid from './equipmentAttributesGrid.vue';
|
||||
@@ -398,12 +393,15 @@
|
||||
import svgHealer from 'assets/svg/healer.svg';
|
||||
|
||||
import featuredItems from 'common/script/content/shop-featuredItems';
|
||||
import getItemInfo from 'common/script/libs/getItemInfo';
|
||||
|
||||
import _filter from 'lodash/filter';
|
||||
import _sortBy from 'lodash/sortBy';
|
||||
import _map from 'lodash/map';
|
||||
import _throttle from 'lodash/throttle';
|
||||
|
||||
import _isPinned from '../_isPinned';
|
||||
|
||||
const sortGearTypes = ['sortByType', 'sortByPrice', 'sortByCon', 'sortByPer', 'sortByStr', 'sortByInt'];
|
||||
|
||||
const sortGearTypeMap = {
|
||||
@@ -429,7 +427,6 @@ export default {
|
||||
bDropdown,
|
||||
bDropdownItem,
|
||||
|
||||
EquipmentAttributesPopover,
|
||||
SellModal,
|
||||
BuyModal,
|
||||
EquipmentAttributesGrid,
|
||||
@@ -523,7 +520,7 @@ export default {
|
||||
|
||||
featuredItems () {
|
||||
return featuredItems.market.map(i => {
|
||||
return this.content.gear.flat[i];
|
||||
return getItemInfo(this.user, 'marketGear', this.content.gear.flat[i]);
|
||||
});
|
||||
},
|
||||
},
|
||||
@@ -577,11 +574,12 @@ export default {
|
||||
filteredGear (groupByClass, searchBy, sortBy, hideLocked, hidePinned) {
|
||||
let result = _filter(this.content.gear.flat, ['klass', groupByClass]);
|
||||
result = _map(result, (e) => {
|
||||
return {
|
||||
...e,
|
||||
pinned: false, // TODO read pinned state
|
||||
locked: this.isGearLocked(e),
|
||||
};
|
||||
let newItem = getItemInfo(this.user, 'marketGear', e);
|
||||
|
||||
newItem.pinned = _isPinned(this.user, newItem);
|
||||
newItem.locked = this.isGearLocked(newItem);
|
||||
|
||||
return newItem;
|
||||
});
|
||||
|
||||
result = _filter(result, (gear) => {
|
||||
@@ -607,9 +605,27 @@ export default {
|
||||
|
||||
return result;
|
||||
},
|
||||
sortedMarketItems (category, sortBy, searchBy) {
|
||||
let result = _filter(category.items, (i) => {
|
||||
return !searchBy || i.text.toLowerCase().indexOf(searchBy) !== -1;
|
||||
sortedMarketItems (category, sortBy, searchBy, hidePinned) {
|
||||
let result = _map(category.items, (e) => {
|
||||
return {
|
||||
...e,
|
||||
pinned: _isPinned(this.user, e),
|
||||
};
|
||||
});
|
||||
|
||||
result = _filter(result, (item) => {
|
||||
if (hidePinned && item.pinned) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (searchBy) {
|
||||
let foundPosition = item.text().toLowerCase().indexOf(searchBy);
|
||||
if (foundPosition === -1) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
switch (sortBy) {
|
||||
@@ -656,9 +672,9 @@ export default {
|
||||
};
|
||||
},
|
||||
togglePinned (item) {
|
||||
let isPinned = Boolean(item.pinned);
|
||||
item.pinned = !isPinned;
|
||||
this.$store.dispatch(isPinned ? 'shops:unpinGear' : 'shops:pinGear', {key: item.key});
|
||||
if (!this.$store.dispatch('user:togglePinnedItem', {type: item.pinType, path: item.path})) {
|
||||
this.$parent.showUnpinNotification(item);
|
||||
}
|
||||
},
|
||||
buyGear (item) {
|
||||
this.$store.dispatch('shops:buyItem', {key: item.key});
|
||||
@@ -669,7 +685,6 @@ export default {
|
||||
},
|
||||
created () {
|
||||
this.$store.dispatch('shops:fetchMarket');
|
||||
|
||||
this.selectedGroupGearByClass = this.userStats.class;
|
||||
},
|
||||
};
|
||||
|
||||
@@ -6,8 +6,9 @@
|
||||
@change="onChange($event)"
|
||||
)
|
||||
span.badge.badge-pill.badge-dialog(
|
||||
:class="{'item-selected-badge': true}",
|
||||
v-if="withPin"
|
||||
:class="{'item-selected-badge': item.pinned}",
|
||||
v-if="withPin",
|
||||
@click.prevent.stop="togglePinned()"
|
||||
)
|
||||
span.svg-icon.inline.color.icon-10(v-html="icons.pin")
|
||||
|
||||
@@ -178,6 +179,12 @@
|
||||
padding: 8px 10px;
|
||||
top: -12px;
|
||||
background: white;
|
||||
cursor: pointer;
|
||||
|
||||
&.item-selected-badge {
|
||||
background: $purple-300;
|
||||
color: $white;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -239,6 +246,9 @@
|
||||
this.$emit('buyPressed', this.item);
|
||||
this.hideDialog();
|
||||
},
|
||||
togglePinned () {
|
||||
this.$emit('togglePinned', this.item);
|
||||
},
|
||||
hideDialog () {
|
||||
this.$root.$emit('hide::modal', 'buy-quest-modal');
|
||||
},
|
||||
|
||||
@@ -56,8 +56,8 @@
|
||||
)
|
||||
template(slot="popoverContent", scope="ctx")
|
||||
div
|
||||
h4.popover-content-title {{ item.text() }}
|
||||
.popover-content-text(v-html="item.notes()")
|
||||
h4.popover-content-title {{ item.text }}
|
||||
.popover-content-text(v-html="item.notes")
|
||||
|
||||
h1.mb-0.page-header(v-once) {{ $t('quests') }}
|
||||
|
||||
@@ -124,8 +124,6 @@
|
||||
:key="item.key",
|
||||
:item="item",
|
||||
:price="item.value",
|
||||
:priceType="item.currency",
|
||||
:itemContentClass="item.class",
|
||||
:emptyItem="false",
|
||||
:popoverPosition="'top'",
|
||||
@click="selectedItemToBuy = item"
|
||||
@@ -153,8 +151,6 @@
|
||||
:key="item.key",
|
||||
:item="item",
|
||||
:price="item.value",
|
||||
:priceType="item.currency",
|
||||
:itemContentClass="item.class",
|
||||
:emptyItem="false",
|
||||
:popoverPosition="'top'",
|
||||
@click="selectedItemToBuy = item"
|
||||
@@ -181,7 +177,8 @@
|
||||
:priceType="selectedItemToBuy ? selectedItemToBuy.currency : ''",
|
||||
:withPin="true",
|
||||
@change="resetItemToBuy($event)",
|
||||
@buyPressed="buyItem($event)"
|
||||
@buyPressed="buyItem($event)",
|
||||
@togglePinned="togglePinned($event)"
|
||||
)
|
||||
template(slot="item", scope="ctx")
|
||||
item.flat(
|
||||
@@ -335,11 +332,15 @@
|
||||
import svgPin from 'assets/svg/pin.svg';
|
||||
|
||||
import featuredItems from 'common/script/content/shop-featuredItems';
|
||||
import getItemInfo from 'common/script/libs/getItemInfo';
|
||||
|
||||
import _isPinned from '../_isPinned';
|
||||
|
||||
import _filter from 'lodash/filter';
|
||||
import _sortBy from 'lodash/sortBy';
|
||||
import _throttle from 'lodash/throttle';
|
||||
import _groupBy from 'lodash/groupBy';
|
||||
import _map from 'lodash/map';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
@@ -405,13 +406,20 @@ export default {
|
||||
|
||||
featuredItems () {
|
||||
return featuredItems.quests.map(i => {
|
||||
return this.content.quests[i];
|
||||
return getItemInfo(this.user, 'quest', this.content.quests[i]);
|
||||
});
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
questItems (category, sortBy, searchBy, hideLocked, hidePinned) {
|
||||
let result = _filter(category.items, (i) => {
|
||||
let result = _map(category.items, (e) => {
|
||||
return {
|
||||
...e,
|
||||
pinned: _isPinned(this.user, e),
|
||||
};
|
||||
});
|
||||
|
||||
result = _filter(result, (i) => {
|
||||
if (hideLocked && i.locked) {
|
||||
return false;
|
||||
}
|
||||
@@ -453,9 +461,9 @@ export default {
|
||||
return false;
|
||||
},
|
||||
togglePinned (item) {
|
||||
let isPinned = Boolean(item.pinned);
|
||||
item.pinned = !isPinned;
|
||||
this.$store.dispatch(isPinned ? 'shops:unpinGear' : 'shops:pinGear', {key: item.key});
|
||||
if (!this.$store.dispatch('user:togglePinnedItem', {type: item.pinType, path: item.path})) {
|
||||
this.$parent.showUnpinNotification(item);
|
||||
}
|
||||
},
|
||||
buyItem (item) {
|
||||
this.$store.dispatch('shops:purchase', {type: item.purchaseType, key: item.key});
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
span.rectangle
|
||||
span.text Leslie
|
||||
span.rectangle
|
||||
div.content
|
||||
div.content(v-if="featuredSet")
|
||||
div.featured-label.with-border
|
||||
span.rectangle
|
||||
span.text(v-once) {{ $t('featuredset', { name: featuredSet.text }) }}
|
||||
@@ -42,8 +42,6 @@
|
||||
:key="item.key",
|
||||
:item="item",
|
||||
:price="item.value",
|
||||
:priceType="item.currency",
|
||||
:itemContentClass="item.class",
|
||||
:emptyItem="false",
|
||||
:popoverPosition="'top'",
|
||||
@click="selectedItemToBuy = item"
|
||||
@@ -88,8 +86,6 @@
|
||||
:key="item.key",
|
||||
:item="item",
|
||||
:price="item.value",
|
||||
:priceType="item.currency",
|
||||
:itemContentClass="item.class",
|
||||
:emptyItem="false",
|
||||
:popoverPosition="'top'",
|
||||
@click="selectedItemToBuy = item"
|
||||
@@ -106,37 +102,13 @@
|
||||
)
|
||||
span.svg-icon.inline.icon-12.color(v-html="icons.pin")
|
||||
|
||||
|
||||
div.items(v-if="false")
|
||||
shopItem(
|
||||
v-for="item in seasonalItems(category, selectedSortItemsBy, searchTextThrottled, hidePinned)",
|
||||
:key="item.key",
|
||||
:item="item",
|
||||
:price="item.value",
|
||||
:priceType="item.currency",
|
||||
:itemContentClass="item.class",
|
||||
:emptyItem="false",
|
||||
:popoverPosition="'top'",
|
||||
@click="selectedItemToBuy = item"
|
||||
)
|
||||
span(slot="popoverContent")
|
||||
div
|
||||
h4.popover-content-title {{ item.text }}
|
||||
.popover-content-text {{ item.notes }}
|
||||
|
||||
template(slot="itemBadge", scope="ctx")
|
||||
span.badge.badge-pill.badge-item.badge-svg(
|
||||
:class="{'item-selected-badge': ctx.item.pinned, 'hide': !ctx.item.pinned}",
|
||||
@click.prevent.stop="togglePinned(ctx.item)"
|
||||
)
|
||||
span.svg-icon.inline.icon-12.color(v-html="icons.pin")
|
||||
|
||||
buyModal(
|
||||
:item="selectedItemToBuy",
|
||||
:priceType="selectedItemToBuy ? selectedItemToBuy.currency : ''",
|
||||
:withPin="true",
|
||||
@change="resetItemToBuy($event)",
|
||||
@buyPressed="buyItem($event)"
|
||||
@buyPressed="buyItem($event)",
|
||||
@togglePinned="togglePinned($event)"
|
||||
)
|
||||
template(slot="item", scope="ctx")
|
||||
item.flat(
|
||||
@@ -328,7 +300,9 @@
|
||||
import _throttle from 'lodash/throttle';
|
||||
import _groupBy from 'lodash/groupBy';
|
||||
|
||||
export default {
|
||||
import _isPinned from '../_isPinned';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
ShopItem,
|
||||
Item,
|
||||
@@ -377,7 +351,6 @@ export default {
|
||||
seasonal: 'shops.seasonal.data',
|
||||
user: 'user.data',
|
||||
userStats: 'user.data.stats',
|
||||
userItems: 'user.data.items',
|
||||
}),
|
||||
categories () {
|
||||
if (this.seasonal) {
|
||||
@@ -428,7 +401,14 @@ export default {
|
||||
}
|
||||
},
|
||||
seasonalItems (category, sortBy, searchBy, viewOptions, hidePinned) {
|
||||
let result = _filter(category.items, (i) => {
|
||||
let result = _map(category.items, (e) => {
|
||||
return {
|
||||
...e,
|
||||
pinned: _isPinned(this.user, e),
|
||||
};
|
||||
});
|
||||
|
||||
result = _filter(result, (i) => {
|
||||
if (hidePinned && i.pinned) {
|
||||
return false;
|
||||
}
|
||||
@@ -482,9 +462,9 @@ export default {
|
||||
return false;
|
||||
},
|
||||
togglePinned (item) {
|
||||
let isPinned = Boolean(item.pinned);
|
||||
item.pinned = !isPinned;
|
||||
this.$store.dispatch(isPinned ? 'shops:unpinGear' : 'shops:pinGear', {key: item.key});
|
||||
if (!this.$store.dispatch('user:togglePinnedItem', {type: item.pinType, path: item.path})) {
|
||||
this.$parent.showUnpinNotification(item);
|
||||
}
|
||||
},
|
||||
buyItem (item) {
|
||||
this.$store.dispatch('shops:purchase', {type: item.purchaseType, key: item.key});
|
||||
|
||||
@@ -5,31 +5,41 @@ b-popover(
|
||||
)
|
||||
span(slot="content")
|
||||
slot(name="popoverContent", :item="item")
|
||||
equipmentAttributesPopover(
|
||||
v-if="item.purchaseType==='gear'",
|
||||
:item="item"
|
||||
)
|
||||
div(v-else)
|
||||
h4.popover-content-title {{ item.text }}
|
||||
.popover-content-text(v-if="showNotes") {{ item.notes }}
|
||||
|
||||
.item-wrapper(@click="click()")
|
||||
.item(
|
||||
:class="{'item-empty': emptyItem, 'highlight': highlightBorder}",
|
||||
:class="{'item-empty': emptyItem, 'highlight-border': highlightBorder}",
|
||||
)
|
||||
slot(name="itemBadge", :item="item", :emptyItem="emptyItem")
|
||||
div.shop-content
|
||||
span.svg-icon.inline.lock(v-if="item.locked" v-html="icons.lock")
|
||||
|
||||
|
||||
div.image
|
||||
div(:class="itemContentClass")
|
||||
div(:class="item.class")
|
||||
|
||||
div.price
|
||||
span.svg-icon.inline.icon-16(v-html="icons[getSvgClass()]")
|
||||
|
||||
span.price-label(:class="getSvgClass()") {{ price }}
|
||||
span.price-label(:class="getSvgClass()") {{ getPrice() }}
|
||||
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import '~client/assets/scss/colors.scss';
|
||||
|
||||
.item {
|
||||
min-height: 106px;
|
||||
.item-wrapper {
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.item {
|
||||
min-height: 106px;
|
||||
}
|
||||
|
||||
.item.item-empty {
|
||||
@@ -100,9 +110,12 @@ b-popover(
|
||||
import svgHourglasses from 'assets/svg/hourglass.svg';
|
||||
import svgLock from 'assets/svg/lock.svg';
|
||||
|
||||
import EquipmentAttributesPopover from 'client/components/inventory/equipment/attributesPopover';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
bPopover,
|
||||
EquipmentAttributesPopover,
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
@@ -118,16 +131,10 @@ b-popover(
|
||||
item: {
|
||||
type: Object,
|
||||
},
|
||||
itemContentClass: {
|
||||
type: String,
|
||||
},
|
||||
price: {
|
||||
type: Number,
|
||||
default: -1,
|
||||
},
|
||||
priceType: {
|
||||
type: String,
|
||||
},
|
||||
emptyItem: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
@@ -145,17 +152,29 @@ b-popover(
|
||||
default: true,
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
showNotes () {
|
||||
if (['armoire', 'potion'].indexOf(this.item.path) > -1) return true;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
click () {
|
||||
this.$emit('click', {});
|
||||
},
|
||||
getSvgClass () {
|
||||
if (this.priceType && this.icons[this.priceType]) {
|
||||
return this.priceType;
|
||||
if (this.item.currency && this.icons[this.item.currency]) {
|
||||
return this.item.currency;
|
||||
} else {
|
||||
return 'gold';
|
||||
}
|
||||
},
|
||||
getPrice () {
|
||||
if (this.price === -1) {
|
||||
return this.item.value;
|
||||
} else {
|
||||
return this.price;
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -92,11 +92,10 @@
|
||||
span(slot="popoverContent", scope="ctx")
|
||||
div
|
||||
h4.popover-content-title {{ ctx.item.text }}
|
||||
.popover-content-text {{ ctx.item.notes }}
|
||||
div {{ ctx.item }}
|
||||
|
||||
template(slot="itemBadge", scope="ctx")
|
||||
span.badge.badge-pill.badge-item.badge-svg(
|
||||
v-if="ctx.item.pinType !== 'IGNORE'",
|
||||
:class="{'item-selected-badge': ctx.item.pinned, 'hide': !ctx.item.pinned}",
|
||||
@click.prevent.stop="togglePinned(ctx.item)"
|
||||
)
|
||||
@@ -277,6 +276,9 @@
|
||||
import _sortBy from 'lodash/sortBy';
|
||||
import _throttle from 'lodash/throttle';
|
||||
import _groupBy from 'lodash/groupBy';
|
||||
import _map from 'lodash/map';
|
||||
|
||||
import _isPinned from '../_isPinned';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
@@ -345,8 +347,8 @@ export default {
|
||||
...c,
|
||||
value: 1,
|
||||
currency: 'hourglasses',
|
||||
type: 'set_mystery',
|
||||
key: c.identifier,
|
||||
class: `shop_set_mystery_${c.identifier}`,
|
||||
};
|
||||
}),
|
||||
};
|
||||
@@ -373,7 +375,14 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
travelersItems (category, sortBy, searchBy, hidePinned) {
|
||||
let result = _filter(category.items, (i) => {
|
||||
let result = _map(category.items, (e) => {
|
||||
return {
|
||||
...e,
|
||||
pinned: _isPinned(this.user, e),
|
||||
};
|
||||
});
|
||||
|
||||
result = _filter(result, (i) => {
|
||||
if (hidePinned && i.pinned) {
|
||||
return false;
|
||||
}
|
||||
@@ -405,9 +414,9 @@ export default {
|
||||
}
|
||||
},
|
||||
togglePinned (item) {
|
||||
let isPinned = Boolean(item.pinned);
|
||||
item.pinned = !isPinned;
|
||||
this.$store.dispatch(isPinned ? 'shops:unpinGear' : 'shops:pinGear', {key: item.key});
|
||||
if (!this.$store.dispatch('user:togglePinnedItem', {type: item.pinType, path: item.path})) {
|
||||
this.$parent.showUnpinNotification(item);
|
||||
}
|
||||
},
|
||||
buyItem (item) {
|
||||
this.$store.dispatch('shops:purchase', {type: item.purchaseType, key: item.key});
|
||||
|
||||
@@ -17,6 +17,17 @@
|
||||
:isUser="isUser",
|
||||
@editTask="editTask",
|
||||
)
|
||||
template(v-if="isUser === true && type === 'reward' && activeFilter.label !== 'custom'")
|
||||
.reward-items
|
||||
shopItem(
|
||||
v-for="reward in inAppRewards",
|
||||
:item="reward",
|
||||
:key="reward.key",
|
||||
:highlightBorder="reward.isSuggested",
|
||||
@click="openBuyDialog(reward)"
|
||||
)
|
||||
|
||||
.bottom-gradient
|
||||
.column-background(
|
||||
v-if="isUser === true",
|
||||
:class="{'initial-description': tasks[`${type}s`].length === 0}",
|
||||
@@ -34,6 +45,12 @@
|
||||
height: 556px;
|
||||
}
|
||||
|
||||
.reward-items {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.tasks-list {
|
||||
border-radius: 4px;
|
||||
background: $gray-600;
|
||||
@@ -137,17 +154,20 @@
|
||||
import Task from './task';
|
||||
import { mapState, mapActions } from 'client/libs/store';
|
||||
import { shouldDo } from 'common/script/cron';
|
||||
import inAppRewards from 'common/script/libs/inAppRewards';
|
||||
import habitIcon from 'assets/svg/habit.svg';
|
||||
import dailyIcon from 'assets/svg/daily.svg';
|
||||
import todoIcon from 'assets/svg/todo.svg';
|
||||
import rewardIcon from 'assets/svg/reward.svg';
|
||||
import bModal from 'bootstrap-vue/lib/components/modal';
|
||||
import shopItem from '../shops/shopItem';
|
||||
import throttle from 'lodash/throttle';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Task,
|
||||
bModal,
|
||||
shopItem,
|
||||
},
|
||||
props: ['type', 'isUser', 'searchText', 'selectedTags', 'taskListOverride'],
|
||||
data () {
|
||||
@@ -203,12 +223,16 @@ export default {
|
||||
computed: {
|
||||
...mapState({
|
||||
tasks: 'tasks.data',
|
||||
user: 'user.data',
|
||||
userPreferences: 'user.data.preferences',
|
||||
}),
|
||||
taskList () {
|
||||
if (this.taskListOverride) return this.taskListOverride;
|
||||
return this.tasks[`${this.type}s`];
|
||||
},
|
||||
inAppRewards () {
|
||||
return inAppRewards(this.user);
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
taskList: {
|
||||
@@ -240,6 +264,12 @@ export default {
|
||||
Array.from(taskListEl.getElementsByClassName('task')).forEach(el => {
|
||||
combinedTasksHeights += el.offsetHeight;
|
||||
});
|
||||
|
||||
const rewardsList = taskListEl.getElementsByClassName('reward-items')[0];
|
||||
if (rewardsList) {
|
||||
combinedTasksHeights += rewardsList.offsetHeight;
|
||||
}
|
||||
|
||||
const columnBackgroundStyle = this.$refs.columnBackground.style;
|
||||
|
||||
if (tasklistHeight - combinedTasksHeights < 150) {
|
||||
@@ -279,6 +309,9 @@ export default {
|
||||
return checklistItemIndex !== -1;
|
||||
}
|
||||
},
|
||||
openBuyDialog (rewardItem) {
|
||||
this.$emit('openBuyDialog', rewardItem);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -74,7 +74,38 @@
|
||||
:isUser="true", :searchText="searchTextThrottled",
|
||||
:selectedTags="selectedTags",
|
||||
@editTask="editTask",
|
||||
@openBuyDialog="openBuyDialog($event)"
|
||||
)
|
||||
|
||||
buyModal(
|
||||
:item="selectedItemToBuy",
|
||||
:priceType="selectedItemToBuy ? selectedItemToBuy.currency : ''",
|
||||
@change="resetItemToBuy($event)",
|
||||
@buyPressed="buyItem($event)",
|
||||
@togglePinned="togglePinned($event)"
|
||||
)
|
||||
template(slot="item", scope="ctx")
|
||||
div(v-if="ctx.item.purchaseType === 'gear'")
|
||||
avatar.inline(
|
||||
:member="user",
|
||||
:avatarOnly="true",
|
||||
:withBackground="true",
|
||||
:overrideAvatarGear="memberOverrideAvatarGear(ctx.item)"
|
||||
)
|
||||
|
||||
item.flat(
|
||||
:item="ctx.item",
|
||||
:itemContentClass="ctx.item.class",
|
||||
:showPopover="false",
|
||||
v-else
|
||||
)
|
||||
|
||||
template(slot="additionalInfo", scope="ctx")
|
||||
equipmentAttributesGrid.bordered(
|
||||
:item="ctx.item",
|
||||
v-if="ctx.item.purchaseType === 'gear'"
|
||||
)
|
||||
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
@@ -246,12 +277,21 @@ import cloneDeep from 'lodash/cloneDeep';
|
||||
import { mapState, mapActions } from 'client/libs/store';
|
||||
import taskDefaults from 'common/script/libs/taskDefaults';
|
||||
|
||||
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';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
TaskColumn,
|
||||
TaskModal,
|
||||
bDropdown,
|
||||
bDropdownItem,
|
||||
BuyModal,
|
||||
Item,
|
||||
Avatar,
|
||||
EquipmentAttributesGrid,
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
@@ -275,6 +315,8 @@ export default {
|
||||
newTag: null,
|
||||
editingTask: null,
|
||||
creatingTask: null,
|
||||
|
||||
selectedItemToBuy: null,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
@@ -393,6 +435,26 @@ export default {
|
||||
if (this.temporarilySelectedTags.indexOf(tagId) !== -1) return true;
|
||||
return false;
|
||||
},
|
||||
resetItemToBuy ($event) {
|
||||
if (!$event) {
|
||||
this.selectedItemToBuy = null;
|
||||
}
|
||||
},
|
||||
memberOverrideAvatarGear (gear) {
|
||||
return {
|
||||
[gear.type]: gear.key,
|
||||
};
|
||||
},
|
||||
buyItem (item) {
|
||||
if (item.currency === 'gold') {
|
||||
this.$store.dispatch('shops:buyItem', {key: item.key});
|
||||
} else {
|
||||
this.$store.dispatch('shops:purchase', {type: item.purchaseType, key: item.key});
|
||||
}
|
||||
},
|
||||
openBuyDialog (rewardItem) {
|
||||
this.selectedItemToBuy = rewardItem;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template lang="pug">
|
||||
span.badge.badge-pill.badge-item.badge-count(
|
||||
v-if="show",
|
||||
v-if="show && count != 0",
|
||||
) {{ count }}
|
||||
</template>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user