diff --git a/website/client/assets/images/shops/quest_shop__banner_background_web.png b/website/client/assets/images/shops/quest_shop__banner_background_web.png deleted file mode 100644 index 872e8b7e38..0000000000 Binary files a/website/client/assets/images/shops/quest_shop__banner_background_web.png and /dev/null differ diff --git a/website/client/assets/images/shops/quest_shop_banner_background.png b/website/client/assets/images/shops/quest_shop_banner_background.png new file mode 100644 index 0000000000..aa595a0974 Binary files /dev/null and b/website/client/assets/images/shops/quest_shop_banner_background.png differ diff --git a/website/client/components/achievements/levelUp.vue b/website/client/components/achievements/levelUp.vue index 44c7b3eff3..b77b8f39aa 100644 --- a/website/client/components/achievements/levelUp.vue +++ b/website/client/components/achievements/levelUp.vue @@ -47,30 +47,33 @@ a.tumblr-share-button(:data-href='socialLevelLink', data-notes='none') - diff --git a/website/client/components/inventory/equipment/index.vue b/website/client/components/inventory/equipment/index.vue index 92fbf02111..cd31e6aed2 100644 --- a/website/client/components/inventory/equipment/index.vue +++ b/website/client/components/inventory/equipment/index.vue @@ -72,13 +72,13 @@ :label="label", :popoverPosition="'top'", ) - template(slot="popoverContent", scope="ctx") - equipmentAttributesPopover(:item="ctx.item") - template(slot="itemBadge", scope="ctx") + template(slot="popoverContent", scope="context") + equipmentAttributesPopover(:item="context.item") + template(slot="itemBadge", scope="context") starBadge( :selected="true", :show="!costume || user.preferences.costume", - @click="equip(ctx.item)", + @click="equip(context.item)", ) div( v-for="group in itemsGroups", @@ -90,29 +90,27 @@ | {{ group.label }} span.badge.badge-pill.badge-default {{items[group.key].length}} - .items - item( - v-for="(item, index) in items[group.key]", - v-if="viewOptions[group.key].open || index < itemsPerLine", - :item="item", - :itemContentClass="'shop_' + item.key", - :emptyItem="!item || item.key.indexOf('_base_0') !== -1", - :key="item.key", - ) - template(slot="itemBadge", scope="ctx") - starBadge( - :selected="activeItems[ctx.item.type] === ctx.item.key", - :show="!costume || user.preferences.costume", - @click="equip(ctx.item)", - ) - template(slot="popoverContent", scope="ctx") - equipmentAttributesPopover(:item="ctx.item") - div(v-if="items[group.key].length === 0") - p(v-once) {{ $t('noGearItemsOfType', { type: group.label }) }} - a.btn.btn-show-more( - v-if="items[group.key].length > itemsPerLine", - @click="viewOptions[group.key].open = !viewOptions[group.key].open" - ) {{ viewOptions[group.key].open ? $t('showLessItems', { type: group.label }) : $t('showAllItems', { type: group.label, items: items[group.key].length }) }} + itemRows( + :items="items[group.key]", + :itemWidth=94, + :itemMargin=24, + :noItemsLabel="$t('noGearItemsOfType', { type: group.label })" + ) + template(slot="item", scope="context") + item( + :item="context.item", + :itemContentClass="'shop_' + context.item.key", + :emptyItem="!context.item || context.item.key.indexOf('_base_0') !== -1", + :key="context.item.key", + ) + template(slot="itemBadge", scope="context") + starBadge( + :selected="activeItems[context.item.type] === context.item.key", + :show="!costume || user.preferences.costume", + @click="equip(context.item)", + ) + template(slot="popoverContent", scope="context") + equipmentAttributesPopover(:item="context.item") + + + diff --git a/website/client/components/inventory/stable/index.vue b/website/client/components/inventory/stable/index.vue index 0405044aaa..91c31c67a0 100644 --- a/website/client/components/inventory/stable/index.vue +++ b/website/client/components/inventory/stable/index.vue @@ -54,7 +54,7 @@ @change="updateHideMissing" ) - .standard-page(v-resize="500", @resized="availableContentWidth = $event.width - 48") + .standard-page .clearfix h1.float-left.mb-0.page-header(v-once) {{ $t('stable') }} @@ -80,41 +80,39 @@ ) h4(v-if="viewOptions[petGroup.key].animalCount != 0") {{ petGroup.label }} - div.items - div( - v-for="pet in pets(petGroup, viewOptions[petGroup.key].open, hideMissing, selectedSortBy, searchTextThrottled, availableContentWidth)", - :key="pet.key", - v-drag.drop.food="pet.key", - @itemDragOver="onDragOver($event, pet)", - @itemDropped="onDrop($event, pet)", - @itemDragLeave="onDragLeave()", - :class="{'last': pet.isLastInRow}" - ) - petItem( - :item="pet", - :itemContentClass="getPetItemClass(pet)", - :popoverPosition="'top'", - :progress="pet.progress", - :emptyItem="!pet.isOwned()", - :showPopover="pet.isOwned()", - :highlightBorder="highlightPet == pet.key", - @click="petClicked(pet)" + itemRows( + :items="pets(petGroup, hideMissing, selectedSortBy, searchTextThrottled)", + :itemWidth=94, + :itemMargin=24, + ) + template(slot="item", scope="context") + div( + v-drag.drop.food="context.item.key", + @itemDragOver="onDragOver($event, context.item)", + @itemDropped="onDrop($event, context.item)", + @itemDragLeave="onDragLeave()", + :class="{'last': context.item.isLastInRow}" ) - span(slot="popoverContent") - div(v-if="pet.isOwned()") - h4.popover-content-title {{ pet.name }} + petItem( + :item="context.item", + :itemContentClass="getPetItemClass(context.item)", + :popoverPosition="'top'", + :progress="context.item.progress", + :emptyItem="!context.item.isOwned()", + :showPopover="context.item.isOwned()", + :highlightBorder="highlightPet == context.item.key", + @click="petClicked(context.item)" + ) + span(slot="popoverContent") + div(v-if="context.item.isOwned()") + h4.popover-content-title {{ context.item.name }} - template(slot="itemBadge", scope="ctx") - starBadge( - :selected="ctx.item.key === currentPet", - :show="ctx.item.isOwned()", - @click="selectPet(ctx.item)", - ) - - .btn.btn-show-more( - @click="viewOptions[petGroup.key].open = !viewOptions[petGroup.key].open", - v-if="viewOptions[petGroup.key].animalCount != 0" - ) {{ $t(viewOptions[petGroup.key].open ? 'showLessAnimals' : 'showAllAnimals', { color: petGroup.label, type: $t('pets')}) }} + template(slot="itemBadge", scope="context") + starBadge( + :selected="context.item.key === currentPet", + :show="context.item.isOwned()", + @click="selectPet(context.item)", + ) h2 | {{ $t('mounts') }} @@ -128,29 +126,28 @@ ) h4(v-if="viewOptions[mountGroup.key].animalCount != 0") {{ mountGroup.label }} - div.items - mountItem( - v-for="mount in mounts(mountGroup, viewOptions[mountGroup.key].open, hideMissing, selectedSortBy, searchTextThrottled, availableContentWidth)", - :item="mount", - :itemContentClass="mount.isOwned() ? ('Mount_Icon_' + mount.key) : 'PixelPaw GreyedOut'", - :key="mount.key", - :popoverPosition="'top'", - :emptyItem="!mount.isOwned()", - :showPopover="mount.isOwned()", - ) - span(slot="popoverContent") - h4.popover-content-title {{ mount.name }} - template(slot="itemBadge", scope="ctx") - starBadge( - :selected="ctx.item.key === currentMount", - :show="mount.isOwned()", - @click="selectMount(ctx.item)", - ) - - .btn.btn-show-more( - @click="viewOptions[mountGroup.key].open = !viewOptions[mountGroup.key].open", - v-if="viewOptions[mountGroup.key].animalCount != 0" - ) {{ $t(viewOptions[mountGroup.key].open ? 'showLessAnimals' : 'showAllAnimals', { color: mountGroup.label, type: $t('mounts')}) }} + itemRows( + :items="mounts(mountGroup, hideMissing, selectedSortBy, searchTextThrottled)", + :itemWidth=94, + :itemMargin=24, + ) + template(slot="item", scope="context") + mountItem( + :item="context.item", + :itemContentClass="context.item.isOwned() ? ('Mount_Icon_' + context.item.key) : 'PixelPaw GreyedOut'", + :key="context.item.key", + :popoverPosition="'top'", + :emptyItem="!context.item.isOwned()", + :showPopover="context.item.isOwned()", + ) + span(slot="popoverContent") + h4.popover-content-title {{ context.item.name }} + template(slot="itemBadge", scope="context") + starBadge( + :selected="context.item.key === currentMount", + :show="context.item.isOwned()", + @click="selectMount(context.item)", + ) drawer( :title="$t('quickInventory')", @@ -189,14 +186,14 @@ :itemWidth=94, :itemMargin=24, ) - template(slot="item", scope="ctx") + template(slot="item", scope="context") foodItem( - :item="ctx.item", - :itemCount="userItems.food[ctx.item.key]", - :active="currentDraggingFood == ctx.item", + :item="context.item", + :itemCount="userItems.food[context.item.key]", + :active="currentDraggingFood == context.item", @itemDragEnd="onDragEnd()", - @itemDragStart="onDragStart($event, ctx.item)", - @itemClick="onFoodClicked($event, ctx.item)" + @itemDragStart="onDragStart($event, context.item)", + @itemClick="onFoodClicked($event, context.item)" ) b-modal#welcome-modal( @@ -231,6 +228,12 @@ button.btn.btn-primary(@click="hatchPet(hatchablePet)") {{ $t('hatch') }} button.btn.btn-secondary.btn-flat(@click="closeHatchPetDialog()") {{ $t('cancel') }} + hatchedPetDialog( + :pet="hatchedPet", + :hideText="true", + @closed="closeHatchedPetDialog()" + ) + div.foodInfo(ref="dragginFoodInfo") div(v-if="currentDraggingFood != null") div.food-icon(:class="'Pet_Food_'+currentDraggingFood.key") @@ -420,6 +423,8 @@ position: absolute; left: -500px; + z-index: 1080; + &.mouse { position: fixed; pointer-events: none @@ -446,17 +451,16 @@ import _each from 'lodash/each'; import _sortBy from 'lodash/sortBy'; - import _take from 'lodash/take'; import _filter from 'lodash/filter'; - import _drop from 'lodash/drop'; import _flatMap from 'lodash/flatMap'; import _throttle from 'lodash/throttle'; - import _last from 'lodash/last'; import Item from '../item'; + import ItemRows from 'client/components/ui/itemRows'; import PetItem from './petItem'; import MountItem from './mountItem.vue'; import FoodItem from './foodItem'; + import HatchedPetDialog from './hatchedPetDialog'; import Drawer from 'client/components/ui/drawer'; import toggleSwitch from 'client/components/ui/toggleSwitch'; import StarBadge from 'client/components/ui/starBadge'; @@ -467,6 +471,8 @@ import DragDropDirective from 'client/directives/dragdrop.directive'; import MouseMoveDirective from 'client/directives/mouseposition.directive'; + import createAnimal from 'client/libs/createAnimal'; + import svgInformation from 'assets/svg/information.svg'; import svgClose from 'assets/svg/close.svg'; @@ -475,10 +481,13 @@ // import deepFreeze from 'client/libs/deepFreeze'; // const specialMounts = + let lastMouseMoveEvent = {}; + export default { components: { PetItem, Item, + ItemRows, FoodItem, MountItem, Drawer, @@ -490,6 +499,7 @@ StarBadge, CountBadge, DrawerSlider, + HatchedPetDialog, }, directives: { resize: ResizeDirective, @@ -521,11 +531,11 @@ highlightPet: '', hatchablePet: null, + hatchedPet: null, foodClickMode: false, currentDraggingFood: null, selectedDrawerTab: 0, - availableContentWidth: 0, }; }, watch: { @@ -581,7 +591,6 @@ petGroups.map((petGroup) => { this.$set(this.viewOptions, petGroup.key, { selected: true, - open: false, animalCount: 0, }); }); @@ -627,7 +636,6 @@ mountGroups.map((mountGroup) => { this.$set(this.viewOptions, mountGroup.key, { selected: true, - open: false, animalCount: 0, }); }); @@ -698,28 +706,7 @@ default: { _each(animalGroup.petSource.eggs, (egg) => { _each(animalGroup.petSource.potions, (potion) => { - let animalKey = `${egg.key}-${potion.key}`; - - animals.push({ - key: animalKey, - eggKey: egg.key, - eggName: egg.text(), - potionKey: potion.key, - potionName: potion.text(), - name: this.content[`${type}Info`][animalKey].text(), - isOwned () { - return userItems[`${type}s`][animalKey] > 0; - }, - mountOwned () { - return userItems.mounts[this.key] > 0; - }, - isAllowedToFeed () { - return type === 'pet' && this.isOwned() && !this.mountOwned(); - }, - isHatchable () { - return userItems.eggs[egg.key] > 0 && userItems.hatchingPotions[potion.key] > 0; - }, - }); + animals.push(createAnimal(egg, potion, type, this.content, userItems)); }); }); } @@ -730,7 +717,7 @@ return animals; }, - listAnimals (animalGroup, type, isOpen, hideMissing, sort, searchText, availableSpace) { + listAnimals (animalGroup, type, hideMissing, sort, searchText) { let animals = this.getAnimalList(animalGroup, type); let isPetList = type === 'pet'; let withProgress = isPetList && animalGroup.key !== 'specialPets'; @@ -770,32 +757,14 @@ } } - let animalRows = []; + let animalRows = withProgress ? _flatMap(animals, (a) => { + let progress = this.userItems[`${type}s`][a.key]; - let itemsPerRow = Math.floor(availableSpace / (94 + 20)); - - let rowsToShow = isOpen ? Math.ceil(animals.length / itemsPerRow) : 1; - - for (let i = 0; i < rowsToShow; i++) { - let skipped = _drop(animals, i * itemsPerRow); - let row = _take(skipped, itemsPerRow); - - let rowWithProgressData = withProgress ? _flatMap(row, (a) => { - let progress = this.userItems[`${type}s`][a.key]; - - return { - ...a, - progress, - }; - }) : row; - - let lastRowItem = _last(rowWithProgressData); - if (lastRowItem) { - lastRowItem.isLastInRow = true; - } - - animalRows.push(...rowWithProgressData); - } + return { + ...a, + progress, + }; + }) : animals; this.viewOptions[animalGroup.key].animalCount = animals.length; @@ -813,12 +782,12 @@ return `${countOwned.length}/${countAll}`; }, - pets (animalGroup, showAll, hideMissing, sortBy, searchText, availableSpace) { - return this.listAnimals(animalGroup, 'pet', showAll, hideMissing, sortBy, searchText, availableSpace); + pets (animalGroup, hideMissing, sortBy, searchText) { + return this.listAnimals(animalGroup, 'pet', hideMissing, sortBy, searchText); }, - mounts (animalGroup, showAll, hideMissing, sortBy, searchText, availableSpace) { - return this.listAnimals(animalGroup, 'mount', showAll, hideMissing, sortBy, searchText, availableSpace); + mounts (animalGroup, hideMissing, sortBy, searchText) { + return this.listAnimals(animalGroup, 'mount', hideMissing, sortBy, searchText); }, getPetItemClass (pet) { @@ -856,6 +825,7 @@ hatchPet (pet) { this.$store.dispatch('common:hatch', {egg: pet.eggKey, hatchingPotion: pet.potionKey}); + this.hatchedPet = pet; this.closeHatchPetDialog(); }, @@ -910,6 +880,9 @@ closeHatchPetDialog () { this.$root.$emit('hide::modal', 'hatching-modal'); }, + closeHatchedPetDialog () { + this.hatchedPet = null; + }, resetHatchablePet ($event) { if (!$event) { @@ -921,6 +894,10 @@ if (this.currentDraggingFood === null || this.currentDraggingFood !== food) { this.currentDraggingFood = food; this.foodClickMode = true; + + this.$nextTick(() => { + this.mouseMoved(lastMouseMoveEvent); + }); } else { this.currentDraggingFood = null; this.foodClickMode = false; @@ -931,6 +908,8 @@ if (this.foodClickMode) { this.$refs.clickFoodInfo.style.left = `${$event.x + 20}px`; this.$refs.clickFoodInfo.style.top = `${$event.y + 20}px`; + } else { + lastMouseMoveEvent = $event; } }, }, diff --git a/website/client/components/shops/market/index.vue b/website/client/components/shops/market/index.vue index de8c378395..b9d8354837 100644 --- a/website/client/components/shops/market/index.vue +++ b/website/client/components/shops/market/index.vue @@ -348,6 +348,7 @@ .npc { position: absolute; left: 0; + top: 0; width: 100%; height: 216px; background: url('~assets/images/shops/market_banner_web_alexnpc.png'); diff --git a/website/client/components/shops/quests/index.vue b/website/client/components/shops/quests/index.vue index 135d8549db..a72f0fe065 100644 --- a/website/client/components/shops/quests/index.vue +++ b/website/client/components/shops/quests/index.vue @@ -87,8 +87,6 @@ :items="questItems(category, selectedSortItemsBy, searchTextThrottled, hideLocked, hidePinned)", :itemWidth=94, :itemMargin=24, - :showAllLabel="$t('showAllGeneric', { type: category.text })", - :showLessLabel="$t('showLessGeneric', { type: category.text })" ) template(slot="item", scope="ctx") shopItem( @@ -275,7 +273,7 @@ height: 216px; .background { - background: url('~assets/images/shops/quest_shop__banner_background_web.png'); + background: url('~assets/images/shops/quest_shop_banner_background.png'); background-repeat: repeat-x; @@ -298,13 +296,15 @@ } .npc { + width: 100%; position: absolute; left: 0; - width: 100%; - height: 216px; + top: 0; + height: 100%; background: url('~assets/images/shops/quest_shop__banner_web_iannpc.png'); background-repeat: no-repeat; + .featured-label { position: absolute; bottom: -14px; diff --git a/website/client/components/shops/seasonal/index.vue b/website/client/components/shops/seasonal/index.vue index 07ce9cf990..81f1557dd0 100644 --- a/website/client/components/shops/seasonal/index.vue +++ b/website/client/components/shops/seasonal/index.vue @@ -281,6 +281,7 @@ .npc { position: absolute; left: 0; + top: 0; width: 100%; height: 216px; background: url('~assets/images/shops/seasonal_shop_closed_banner_web_leslienpc.png'); diff --git a/website/client/components/shops/shopItem.vue b/website/client/components/shops/shopItem.vue index a70f8fc2e8..8071f70686 100644 --- a/website/client/components/shops/shopItem.vue +++ b/website/client/components/shops/shopItem.vue @@ -21,7 +21,7 @@ b-popover( div.price span.svg-icon.inline.icon-16(v-html="icons[getSvgClass()]") - span.price-label(:class="priceType") {{ price }} + span.price-label(:class="getSvgClass()") {{ price }} @@ -76,6 +76,10 @@ b-popover( &.gold { color: $yellow-10 } + + &.hourglasses { + color: $blue-10; + } } span.svg-icon.inline.lock { diff --git a/website/client/components/shops/timeTravelers/index.vue b/website/client/components/shops/timeTravelers/index.vue index 30d5842e6a..415642c0d6 100644 --- a/website/client/components/shops/timeTravelers/index.vue +++ b/website/client/components/shops/timeTravelers/index.vue @@ -78,8 +78,6 @@ :items="travelersItems(category, selectedSortItemsBy, searchTextThrottled, hidePinned)", :itemWidth=94, :itemMargin=24, - :showAllLabel="$t('showAllGeneric', { type: category.text })", - :showLessLabel="$t('showLessGeneric', { type: category.text })" ) template(slot="item", scope="ctx") shopItem( @@ -236,6 +234,7 @@ .npc { position: absolute; left: 0; + top: 0; width: 100%; height: 216px; background: url('~assets/images/shops/time_travelers_open_banner_web_tylerandvickynpcs.png'); diff --git a/website/client/components/ui/itemRows.vue b/website/client/components/ui/itemRows.vue index b09adb0ef6..2dbace0fd9 100644 --- a/website/client/components/ui/itemRows.vue +++ b/website/client/components/ui/itemRows.vue @@ -7,13 +7,24 @@ :item="item", ) + div(v-if="items.length === 0") + p(v-once) {{ noItemsLabel }} + .btn.btn-show-more( @click="showAll = !showAll", v-if="items.length > itemsPerRow()" - ) {{ showAll ? showLessLabel : showAllLabel }} + ) {{ showAll ? $t('showLess') : $t('showMore') }} + + div.fill-height(v-else) + +