[WIP] multiple fixes (#8916)

* change quest banner backgrond

* itemRows in inventory

* use itemRows in inventory/items - showLess/showMore as default labels - extend white space if theres no button available

* hide popover if dragging is active - show dragging info on first click (without to move)

* use itemRows in inventory/stable

* fix some strings

* highlight currently dragging item in inventory/items - auto attach info on click - z-index

* fix shopItem label color

* fix floating npcs in banner

* hatched-pet-dialog in items / stable

* change all ctx to context
This commit is contained in:
negue
2017-08-08 03:04:46 +02:00
committed by Keith Holliday
parent 0b076311df
commit a380090013
16 changed files with 415 additions and 251 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View File

@@ -47,30 +47,33 @@
a.tumblr-share-button(:data-href='socialLevelLink', data-notes='none') a.tumblr-share-button(:data-href='socialLevelLink', data-notes='none')
</template> </template>
<style scope> <style lang="scss">
.modal-content { #level-up {
min-width: 28em;
}
.modal-body { .modal-content {
padding-bottom: 0; min-width: 28em;
} }
.modal-footer { .modal-body {
margin-top: 0; padding-bottom: 0;
} }
.herobox { .modal-footer {
margin:auto 8.3em; margin-top: 0;
width: 6em; }
height: 9em;
padding-top: 0;
cursor:default;
}
.character-sprites { .herobox {
margin: 0; margin: auto 8.3em;
width: 0; width: 6em;
height: 9em;
padding-top: 0;
cursor: default;
}
.character-sprites {
margin: 0;
width: 0;
}
} }
</style> </style>

View File

@@ -72,13 +72,13 @@
:label="label", :label="label",
:popoverPosition="'top'", :popoverPosition="'top'",
) )
template(slot="popoverContent", scope="ctx") template(slot="popoverContent", scope="context")
equipmentAttributesPopover(:item="ctx.item") equipmentAttributesPopover(:item="context.item")
template(slot="itemBadge", scope="ctx") template(slot="itemBadge", scope="context")
starBadge( starBadge(
:selected="true", :selected="true",
:show="!costume || user.preferences.costume", :show="!costume || user.preferences.costume",
@click="equip(ctx.item)", @click="equip(context.item)",
) )
div( div(
v-for="group in itemsGroups", v-for="group in itemsGroups",
@@ -90,29 +90,27 @@
| {{ group.label }} | {{ group.label }}
span.badge.badge-pill.badge-default {{items[group.key].length}} span.badge.badge-pill.badge-default {{items[group.key].length}}
.items itemRows(
item( :items="items[group.key]",
v-for="(item, index) in items[group.key]", :itemWidth=94,
v-if="viewOptions[group.key].open || index < itemsPerLine", :itemMargin=24,
:item="item", :noItemsLabel="$t('noGearItemsOfType', { type: group.label })"
:itemContentClass="'shop_' + item.key", )
:emptyItem="!item || item.key.indexOf('_base_0') !== -1", template(slot="item", scope="context")
:key="item.key", item(
) :item="context.item",
template(slot="itemBadge", scope="ctx") :itemContentClass="'shop_' + context.item.key",
starBadge( :emptyItem="!context.item || context.item.key.indexOf('_base_0') !== -1",
:selected="activeItems[ctx.item.type] === ctx.item.key", :key="context.item.key",
:show="!costume || user.preferences.costume", )
@click="equip(ctx.item)", template(slot="itemBadge", scope="context")
) starBadge(
template(slot="popoverContent", scope="ctx") :selected="activeItems[context.item.type] === context.item.key",
equipmentAttributesPopover(:item="ctx.item") :show="!costume || user.preferences.costume",
div(v-if="items[group.key].length === 0") @click="equip(context.item)",
p(v-once) {{ $t('noGearItemsOfType', { type: group.label }) }} )
a.btn.btn-show-more( template(slot="popoverContent", scope="context")
v-if="items[group.key].length > itemsPerLine", equipmentAttributesPopover(:item="context.item")
@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 }) }}
</template> </template>
<style lang="scss" scoped> <style lang="scss" scoped>
@@ -133,6 +131,7 @@ import bPopover from 'bootstrap-vue/lib/components/popover';
import toggleSwitch from 'client/components/ui/toggleSwitch'; import toggleSwitch from 'client/components/ui/toggleSwitch';
import Item from 'client/components/inventory/item'; import Item from 'client/components/inventory/item';
import ItemRows from 'client/components/ui/itemRows';
import EquipmentAttributesPopover from 'client/components/inventory/equipment/attributesPopover'; import EquipmentAttributesPopover from 'client/components/inventory/equipment/attributesPopover';
import StarBadge from 'client/components/ui/starBadge'; import StarBadge from 'client/components/ui/starBadge';
import Drawer from 'client/components/ui/drawer'; import Drawer from 'client/components/ui/drawer';
@@ -143,6 +142,7 @@ export default {
name: 'Equipment', name: 'Equipment',
components: { components: {
Item, Item,
ItemRows,
EquipmentAttributesPopover, EquipmentAttributesPopover,
StarBadge, StarBadge,
Drawer, Drawer,

View File

@@ -13,7 +13,7 @@ b-popover(
slot(name="popoverContent", :item="item") slot(name="popoverContent", :item="item")
.item-wrapper(@click="click") .item-wrapper(@click="click")
.item .item(:class="{'item-active': active }")
slot(name="itemBadge", :item="item") slot(name="itemBadge", :item="item")
span.item-content( span.item-content(
:class="itemContentClass" :class="itemContentClass"
@@ -50,6 +50,9 @@ export default {
type: Boolean, type: Boolean,
default: true, default: true,
}, },
active: {
type: Boolean,
},
}, },
methods: { methods: {
click () { click () {

View File

@@ -34,65 +34,85 @@
| |
span.badge.badge-pill.badge-default {{group.quantity}} span.badge.badge-pill.badge-default {{group.quantity}}
.items(v-if="group.key === 'eggs'")
item(
v-for="({data: item, quantity}, index) in items[group.key]",
v-if="group.open || index < itemsPerLine",
:item="item",
:key="item.key",
:itemContentClass="`${group.classPrefix}${item.key}`",
v-drag.drop.hatch="item.key",
@itemDragOver="onDragOver($event, item)", itemRows(
@itemDropped="onDrop($event, item)", v-if="group.key === 'eggs'",
@itemDragLeave="onDragLeave()", :items="items[group.key]",
:itemWidth=94,
:itemMargin=24,
:noItemsLabel="$t('noGearItemsOfType', { type: $t(group.key) })"
)
template(slot="item", scope="context")
item(
:item="context.item",
:key="context.item.key",
:itemContentClass="`${group.classPrefix}${context.item.key}`",
:showPopover="currentDraggingPotion == null",
v-drag.drop.hatch="context.item.key",
@click="onEggClicked($event, item)" @itemDragOver="onDragOver($event, context.item)",
) @itemDropped="onDrop($event, context.item)",
template(slot="popoverContent", scope="ctx") @itemDragLeave="onDragLeave()",
h4.popover-content-title {{ ctx.item.text() }}
.popover-content-text {{ ctx.item.notes() }}
template(slot="itemBadge", scope="ctx")
span.badge.badge-pill.badge-item.badge-quantity {{ quantity }}
.items(v-else-if="group.key === 'hatchingPotions'") @click="onEggClicked($event, context.item)"
item( )
v-for="({data: item, quantity}, index) in items[group.key]", template(slot="popoverContent", scope="context")
v-if="group.open || index < itemsPerLine", h4.popover-content-title {{ context.item.text() }}
:item="item", .popover-content-text {{ context.item.notes() }}
:key="item.key", template(slot="itemBadge", scope="context")
:itemContentClass="`${group.classPrefix}${item.key}`", span.badge.badge-pill.badge-item.badge-quantity {{ context.item.quantity }}
v-drag.hatch="item.key",
@itemDragEnd="onDragEnd($event, item)", itemRows(
@itemDragStart="onDragStart($event, item)", v-else-if="group.key === 'hatchingPotions'",
:items="items[group.key]",
:itemWidth=94,
:itemMargin=24,
:noItemsLabel="$t('noGearItemsOfType', { type: $t(group.key) })"
)
template(slot="item", scope="context")
item(
:item="context.item",
:key="context.item.key",
:itemContentClass="`${group.classPrefix}${context.item.key}`",
:showPopover="currentDraggingPotion == null",
:active="currentDraggingPotion == context.item",
v-drag.hatch="context.item.key",
@click="onPotionClicked($event, item)" @itemDragEnd="onDragEnd($event, context.item)",
) @itemDragStart="onDragStart($event, context.item)",
template(slot="popoverContent", scope="ctx")
h4.popover-content-title {{ ctx.item.text() }} @click="onPotionClicked($event, context.item)"
.popover-content-text {{ ctx.item.notes() }} )
template(slot="itemBadge", scope="ctx") template(slot="popoverContent", scope="context")
span.badge.badge-pill.badge-item.badge-quantity {{ quantity }} h4.popover-content-title {{ context.item.text() }}
.items(v-else) .popover-content-text {{ context.item.notes() }}
item( template(slot="itemBadge", scope="context")
v-for="({data: item, quantity}, index) in items[group.key]", span.badge.badge-pill.badge-item.badge-quantity {{ context.item.quantity }}
v-if="group.open || index < itemsPerLine",
:item="item", itemRows(
:key="item.key", v-else,
:itemContentClass="`${group.classPrefix}${item.key}`", :items="items[group.key]",
) :itemWidth=94,
template(slot="popoverContent", scope="ctx") :itemMargin=24,
h4.popover-content-title {{ ctx.item.text() }} :noItemsLabel="$t('noGearItemsOfType', { type: $t(group.key) })"
.popover-content-text {{ ctx.item.notes() }} )
template(slot="itemBadge", scope="ctx") template(slot="item", scope="context")
span.badge.badge-pill.badge-item.badge-quantity {{ quantity }} item(
div(v-if="items[group.key].length === 0") :item="context.item",
p(v-once) {{ $t('noGearItemsOfType', { type: $t(group.key) }) }} :key="context.item.key",
a.btn.btn-show-more( :itemContentClass="`${group.classPrefix}${context.item.key}`",
v-if="items[group.key].length > itemsPerLine", :showPopover="currentDraggingPotion == null"
@click="group.open = !group.open" )
) {{ group.open ? $t('showLessItems', { type: $t(group.key) }) : $t('showAllItems', { type: $t(group.key), items: items[group.key].length }) }} template(slot="popoverContent", scope="context")
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 }}
hatchedPetDialog(
:pet="hatchedPet",
@closed="closeHatchedPetDialog()"
)
div.hatchingPotionInfo(ref="draggingPotionInfo") div.hatchingPotionInfo(ref="draggingPotionInfo")
div(v-if="currentDraggingPotion != null") div(v-if="currentDraggingPotion != null")
@@ -112,6 +132,8 @@
position: absolute; position: absolute;
left: -500px; left: -500px;
z-index: 1080;
&.mouse { &.mouse {
position: fixed; position: fixed;
pointer-events: none pointer-events: none
@@ -136,6 +158,12 @@ import throttle from 'lodash/throttle';
import bDropdown from 'bootstrap-vue/lib/components/dropdown'; 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 HatchedPetDialog from '../stable/hatchedPetDialog';
import createAnimal from 'client/libs/createAnimal';
const allowedSpecialItems = ['snowball', 'spookySparkles', 'shinySeed', 'seafoam']; const allowedSpecialItems = ['snowball', 'spookySparkles', 'shinySeed', 'seafoam'];
@@ -152,18 +180,21 @@ const groups = [
key: group, key: group,
quantity: 0, quantity: 0,
selected: true, selected: true,
open: false,
classPrefix, classPrefix,
allowedItems, allowedItems,
}; };
}); });
let lastMouseMoveEvent = {};
export default { export default {
name: 'Items', name: 'Items',
components: { components: {
Item, Item,
ItemRows,
bDropdown, bDropdown,
bDropdownItem, bDropdownItem,
HatchedPetDialog,
}, },
directives: { directives: {
drag: DragDropDirective, drag: DragDropDirective,
@@ -171,15 +202,14 @@ export default {
}, },
data () { data () {
return { return {
itemsPerLine: 9,
searchText: null, searchText: null,
searchTextThrottled: null, searchTextThrottled: null,
groups, groups,
sortBy: 'quantity', // or 'AZ' sortBy: 'quantity', // or 'AZ'
currentDraggingPotion: null, currentDraggingPotion: null,
potionClickMode: false, potionClickMode: false,
hatchedPet: null,
}; };
}, },
watch: { watch: {
@@ -198,6 +228,7 @@ export default {
this.groups.forEach(group => { this.groups.forEach(group => {
const groupKey = group.key; const groupKey = group.key;
group.quantity = 0; // reset the count
let itemsArray = itemsByType[groupKey] = []; let itemsArray = itemsByType[groupKey] = [];
const contentItems = this.content[groupKey]; const contentItems = this.content[groupKey];
@@ -208,7 +239,7 @@ export default {
const isSearched = !searchText || item.text().toLowerCase().indexOf(searchText) !== -1; const isSearched = !searchText || item.text().toLowerCase().indexOf(searchText) !== -1;
if (isSearched) { if (isSearched) {
itemsArray.push({ itemsArray.push({
data: item, ...item,
quantity: itemQuantity, quantity: itemQuantity,
}); });
@@ -238,8 +269,9 @@ export default {
return result; return result;
}, },
hatchPet (potionKey, eggKey) { hatchPet (potion, egg) {
this.$store.dispatch('common:hatch', {egg: eggKey, hatchingPotion: potionKey}); this.$store.dispatch('common:hatch', {egg: egg.key, hatchingPotion: potion.key});
this.hatchedPet = createAnimal(egg, potion, 'pet', this.content, this.user.items);
}, },
onDragEnd () { onDragEnd () {
@@ -263,15 +295,19 @@ export default {
} }
}, },
onDrop ($event, egg) { onDrop ($event, egg) {
this.hatchPet(this.currentDraggingPotion.key, egg.key); this.hatchPet(this.currentDraggingPotion, egg);
}, },
onDragLeave () { onDragLeave () {
}, },
onEggClicked ($event, egg) { onEggClicked ($event, egg) {
if (this.currentDraggingPotion === null) {
return;
}
if (!this.petExists(this.currentDraggingPotion.key, egg.key)) { if (!this.petExists(this.currentDraggingPotion.key, egg.key)) {
this.hatchPet(this.currentDraggingPotion.key, egg.key); this.hatchPet(this.currentDraggingPotion, egg);
} }
this.currentDraggingPotion = null; this.currentDraggingPotion = null;
@@ -282,16 +318,27 @@ export default {
if (this.currentDraggingPotion === null || this.currentDraggingPotion !== potion) { if (this.currentDraggingPotion === null || this.currentDraggingPotion !== potion) {
this.currentDraggingPotion = potion; this.currentDraggingPotion = potion;
this.potionClickMode = true; this.potionClickMode = true;
this.$nextTick(() => {
this.mouseMoved(lastMouseMoveEvent);
});
} else { } else {
this.currentDraggingPotion = null; this.currentDraggingPotion = null;
this.potionClickMode = false; this.potionClickMode = false;
} }
}, },
closeHatchedPetDialog () {
this.hatchedPet = null;
},
mouseMoved ($event) { mouseMoved ($event) {
if (this.potionClickMode) { if (this.potionClickMode) {
this.$refs.clickPotionInfo.style.left = `${$event.x + 20}px`; this.$refs.clickPotionInfo.style.left = `${$event.x + 20}px`;
this.$refs.clickPotionInfo.style.top = `${$event.y + 20}px`; this.$refs.clickPotionInfo.style.top = `${$event.y + 20}px`;
} else {
lastMouseMoveEvent = $event;
} }
}, },
}, },

View File

@@ -0,0 +1,95 @@
<template lang="pug">
b-modal#hatchedPet-modal(
:visible="true",
v-if="pet != null",
:hide-header="true"
)
div.content
div.dialog-header.title You hatched a new pet!
div.inner-content
div.pet-background
div(:class="pet.class")
h4.title {{ pet.name }}
div.text(v-if="!hideText")
| {{ $t('hatchedPetNotesPart1') }}
|
router-link(:to="{name: 'stable'}") {{ $t('stable') }}
|
| {{ $t('hatchedPetNotesPart2') }}
button.btn.btn-primary(@click="close()") {{ $t('onward') }}
div.clearfix(slot="modal-footer")
</template>
<style lang="scss">
@import '~client/assets/scss/colors.scss';
@import '~client/assets/scss/modal.scss';
#hatchedPet-modal {
@include centeredModal();
.modal-dialog {
width: 330px;
}
.content {
text-align: center;
}
.inner-content {
margin: 33px auto auto;
display: flex;
flex-direction: column;
align-items: center;
}
.pet-background {
width: 112px;
height: 112px;
border-radius: 4px;
background-color: $gray-700;
}
.Pet {
margin: auto;
}
.dialog-header {
color: $purple-200;
}
}
</style>
<script>
import bModal from 'bootstrap-vue/lib/components/modal';
export default {
components: {
bModal,
},
methods: {
close () {
this.$emit('closed', this.item);
this.$root.$emit('hide::modal', 'hatchedPet-modal');
},
},
props: {
pet: {
type: Object,
},
hideText: {
type: Boolean,
},
},
};
</script>

View File

@@ -54,7 +54,7 @@
@change="updateHideMissing" @change="updateHideMissing"
) )
.standard-page(v-resize="500", @resized="availableContentWidth = $event.width - 48") .standard-page
.clearfix .clearfix
h1.float-left.mb-0.page-header(v-once) {{ $t('stable') }} 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 }} h4(v-if="viewOptions[petGroup.key].animalCount != 0") {{ petGroup.label }}
div.items itemRows(
div( :items="pets(petGroup, hideMissing, selectedSortBy, searchTextThrottled)",
v-for="pet in pets(petGroup, viewOptions[petGroup.key].open, hideMissing, selectedSortBy, searchTextThrottled, availableContentWidth)", :itemWidth=94,
:key="pet.key", :itemMargin=24,
v-drag.drop.food="pet.key", )
@itemDragOver="onDragOver($event, pet)", template(slot="item", scope="context")
@itemDropped="onDrop($event, pet)", div(
@itemDragLeave="onDragLeave()", v-drag.drop.food="context.item.key",
:class="{'last': pet.isLastInRow}" @itemDragOver="onDragOver($event, context.item)",
) @itemDropped="onDrop($event, context.item)",
petItem( @itemDragLeave="onDragLeave()",
:item="pet", :class="{'last': context.item.isLastInRow}"
:itemContentClass="getPetItemClass(pet)",
:popoverPosition="'top'",
:progress="pet.progress",
:emptyItem="!pet.isOwned()",
:showPopover="pet.isOwned()",
:highlightBorder="highlightPet == pet.key",
@click="petClicked(pet)"
) )
span(slot="popoverContent") petItem(
div(v-if="pet.isOwned()") :item="context.item",
h4.popover-content-title {{ pet.name }} :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") template(slot="itemBadge", scope="context")
starBadge( starBadge(
:selected="ctx.item.key === currentPet", :selected="context.item.key === currentPet",
:show="ctx.item.isOwned()", :show="context.item.isOwned()",
@click="selectPet(ctx.item)", @click="selectPet(context.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')}) }}
h2 h2
| {{ $t('mounts') }} | {{ $t('mounts') }}
@@ -128,29 +126,28 @@
) )
h4(v-if="viewOptions[mountGroup.key].animalCount != 0") {{ mountGroup.label }} h4(v-if="viewOptions[mountGroup.key].animalCount != 0") {{ mountGroup.label }}
div.items itemRows(
mountItem( :items="mounts(mountGroup, hideMissing, selectedSortBy, searchTextThrottled)",
v-for="mount in mounts(mountGroup, viewOptions[mountGroup.key].open, hideMissing, selectedSortBy, searchTextThrottled, availableContentWidth)", :itemWidth=94,
:item="mount", :itemMargin=24,
:itemContentClass="mount.isOwned() ? ('Mount_Icon_' + mount.key) : 'PixelPaw GreyedOut'", )
:key="mount.key", template(slot="item", scope="context")
:popoverPosition="'top'", mountItem(
:emptyItem="!mount.isOwned()", :item="context.item",
:showPopover="mount.isOwned()", :itemContentClass="context.item.isOwned() ? ('Mount_Icon_' + context.item.key) : 'PixelPaw GreyedOut'",
) :key="context.item.key",
span(slot="popoverContent") :popoverPosition="'top'",
h4.popover-content-title {{ mount.name }} :emptyItem="!context.item.isOwned()",
template(slot="itemBadge", scope="ctx") :showPopover="context.item.isOwned()",
starBadge( )
:selected="ctx.item.key === currentMount", span(slot="popoverContent")
:show="mount.isOwned()", h4.popover-content-title {{ context.item.name }}
@click="selectMount(ctx.item)", template(slot="itemBadge", scope="context")
) starBadge(
:selected="context.item.key === currentMount",
.btn.btn-show-more( :show="context.item.isOwned()",
@click="viewOptions[mountGroup.key].open = !viewOptions[mountGroup.key].open", @click="selectMount(context.item)",
v-if="viewOptions[mountGroup.key].animalCount != 0" )
) {{ $t(viewOptions[mountGroup.key].open ? 'showLessAnimals' : 'showAllAnimals', { color: mountGroup.label, type: $t('mounts')}) }}
drawer( drawer(
:title="$t('quickInventory')", :title="$t('quickInventory')",
@@ -189,14 +186,14 @@
:itemWidth=94, :itemWidth=94,
:itemMargin=24, :itemMargin=24,
) )
template(slot="item", scope="ctx") template(slot="item", scope="context")
foodItem( foodItem(
:item="ctx.item", :item="context.item",
:itemCount="userItems.food[ctx.item.key]", :itemCount="userItems.food[context.item.key]",
:active="currentDraggingFood == ctx.item", :active="currentDraggingFood == context.item",
@itemDragEnd="onDragEnd()", @itemDragEnd="onDragEnd()",
@itemDragStart="onDragStart($event, ctx.item)", @itemDragStart="onDragStart($event, context.item)",
@itemClick="onFoodClicked($event, ctx.item)" @itemClick="onFoodClicked($event, context.item)"
) )
b-modal#welcome-modal( b-modal#welcome-modal(
@@ -231,6 +228,12 @@
button.btn.btn-primary(@click="hatchPet(hatchablePet)") {{ $t('hatch') }} button.btn.btn-primary(@click="hatchPet(hatchablePet)") {{ $t('hatch') }}
button.btn.btn-secondary.btn-flat(@click="closeHatchPetDialog()") {{ $t('cancel') }} button.btn.btn-secondary.btn-flat(@click="closeHatchPetDialog()") {{ $t('cancel') }}
hatchedPetDialog(
:pet="hatchedPet",
:hideText="true",
@closed="closeHatchedPetDialog()"
)
div.foodInfo(ref="dragginFoodInfo") div.foodInfo(ref="dragginFoodInfo")
div(v-if="currentDraggingFood != null") div(v-if="currentDraggingFood != null")
div.food-icon(:class="'Pet_Food_'+currentDraggingFood.key") div.food-icon(:class="'Pet_Food_'+currentDraggingFood.key")
@@ -420,6 +423,8 @@
position: absolute; position: absolute;
left: -500px; left: -500px;
z-index: 1080;
&.mouse { &.mouse {
position: fixed; position: fixed;
pointer-events: none pointer-events: none
@@ -446,17 +451,16 @@
import _each from 'lodash/each'; import _each from 'lodash/each';
import _sortBy from 'lodash/sortBy'; import _sortBy from 'lodash/sortBy';
import _take from 'lodash/take';
import _filter from 'lodash/filter'; import _filter from 'lodash/filter';
import _drop from 'lodash/drop';
import _flatMap from 'lodash/flatMap'; import _flatMap from 'lodash/flatMap';
import _throttle from 'lodash/throttle'; import _throttle from 'lodash/throttle';
import _last from 'lodash/last';
import Item from '../item'; import Item from '../item';
import ItemRows from 'client/components/ui/itemRows';
import PetItem from './petItem'; import PetItem from './petItem';
import MountItem from './mountItem.vue'; import MountItem from './mountItem.vue';
import FoodItem from './foodItem'; import FoodItem from './foodItem';
import HatchedPetDialog from './hatchedPetDialog';
import Drawer from 'client/components/ui/drawer'; import Drawer from 'client/components/ui/drawer';
import toggleSwitch from 'client/components/ui/toggleSwitch'; import toggleSwitch from 'client/components/ui/toggleSwitch';
import StarBadge from 'client/components/ui/starBadge'; import StarBadge from 'client/components/ui/starBadge';
@@ -467,6 +471,8 @@
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';
import createAnimal from 'client/libs/createAnimal';
import svgInformation from 'assets/svg/information.svg'; import svgInformation from 'assets/svg/information.svg';
import svgClose from 'assets/svg/close.svg'; import svgClose from 'assets/svg/close.svg';
@@ -475,10 +481,13 @@
// import deepFreeze from 'client/libs/deepFreeze'; // import deepFreeze from 'client/libs/deepFreeze';
// const specialMounts = // const specialMounts =
let lastMouseMoveEvent = {};
export default { export default {
components: { components: {
PetItem, PetItem,
Item, Item,
ItemRows,
FoodItem, FoodItem,
MountItem, MountItem,
Drawer, Drawer,
@@ -490,6 +499,7 @@
StarBadge, StarBadge,
CountBadge, CountBadge,
DrawerSlider, DrawerSlider,
HatchedPetDialog,
}, },
directives: { directives: {
resize: ResizeDirective, resize: ResizeDirective,
@@ -521,11 +531,11 @@
highlightPet: '', highlightPet: '',
hatchablePet: null, hatchablePet: null,
hatchedPet: null,
foodClickMode: false, foodClickMode: false,
currentDraggingFood: null, currentDraggingFood: null,
selectedDrawerTab: 0, selectedDrawerTab: 0,
availableContentWidth: 0,
}; };
}, },
watch: { watch: {
@@ -581,7 +591,6 @@
petGroups.map((petGroup) => { petGroups.map((petGroup) => {
this.$set(this.viewOptions, petGroup.key, { this.$set(this.viewOptions, petGroup.key, {
selected: true, selected: true,
open: false,
animalCount: 0, animalCount: 0,
}); });
}); });
@@ -627,7 +636,6 @@
mountGroups.map((mountGroup) => { mountGroups.map((mountGroup) => {
this.$set(this.viewOptions, mountGroup.key, { this.$set(this.viewOptions, mountGroup.key, {
selected: true, selected: true,
open: false,
animalCount: 0, animalCount: 0,
}); });
}); });
@@ -698,28 +706,7 @@
default: { default: {
_each(animalGroup.petSource.eggs, (egg) => { _each(animalGroup.petSource.eggs, (egg) => {
_each(animalGroup.petSource.potions, (potion) => { _each(animalGroup.petSource.potions, (potion) => {
let animalKey = `${egg.key}-${potion.key}`; animals.push(createAnimal(egg, potion, type, this.content, userItems));
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;
},
});
}); });
}); });
} }
@@ -730,7 +717,7 @@
return animals; return animals;
}, },
listAnimals (animalGroup, type, isOpen, hideMissing, sort, searchText, availableSpace) { listAnimals (animalGroup, type, hideMissing, sort, searchText) {
let animals = this.getAnimalList(animalGroup, type); let animals = this.getAnimalList(animalGroup, type);
let isPetList = type === 'pet'; let isPetList = type === 'pet';
let withProgress = isPetList && animalGroup.key !== 'specialPets'; 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)); return {
...a,
let rowsToShow = isOpen ? Math.ceil(animals.length / itemsPerRow) : 1; progress,
};
for (let i = 0; i < rowsToShow; i++) { }) : animals;
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);
}
this.viewOptions[animalGroup.key].animalCount = animals.length; this.viewOptions[animalGroup.key].animalCount = animals.length;
@@ -813,12 +782,12 @@
return `${countOwned.length}/${countAll}`; return `${countOwned.length}/${countAll}`;
}, },
pets (animalGroup, showAll, hideMissing, sortBy, searchText, availableSpace) { pets (animalGroup, hideMissing, sortBy, searchText) {
return this.listAnimals(animalGroup, 'pet', showAll, hideMissing, sortBy, searchText, availableSpace); return this.listAnimals(animalGroup, 'pet', hideMissing, sortBy, searchText);
}, },
mounts (animalGroup, showAll, hideMissing, sortBy, searchText, availableSpace) { mounts (animalGroup, hideMissing, sortBy, searchText) {
return this.listAnimals(animalGroup, 'mount', showAll, hideMissing, sortBy, searchText, availableSpace); return this.listAnimals(animalGroup, 'mount', hideMissing, sortBy, searchText);
}, },
getPetItemClass (pet) { getPetItemClass (pet) {
@@ -856,6 +825,7 @@
hatchPet (pet) { hatchPet (pet) {
this.$store.dispatch('common:hatch', {egg: pet.eggKey, hatchingPotion: pet.potionKey}); this.$store.dispatch('common:hatch', {egg: pet.eggKey, hatchingPotion: pet.potionKey});
this.hatchedPet = pet;
this.closeHatchPetDialog(); this.closeHatchPetDialog();
}, },
@@ -910,6 +880,9 @@
closeHatchPetDialog () { closeHatchPetDialog () {
this.$root.$emit('hide::modal', 'hatching-modal'); this.$root.$emit('hide::modal', 'hatching-modal');
}, },
closeHatchedPetDialog () {
this.hatchedPet = null;
},
resetHatchablePet ($event) { resetHatchablePet ($event) {
if (!$event) { if (!$event) {
@@ -921,6 +894,10 @@
if (this.currentDraggingFood === null || this.currentDraggingFood !== food) { if (this.currentDraggingFood === null || this.currentDraggingFood !== food) {
this.currentDraggingFood = food; this.currentDraggingFood = food;
this.foodClickMode = true; this.foodClickMode = true;
this.$nextTick(() => {
this.mouseMoved(lastMouseMoveEvent);
});
} else { } else {
this.currentDraggingFood = null; this.currentDraggingFood = null;
this.foodClickMode = false; this.foodClickMode = false;
@@ -931,6 +908,8 @@
if (this.foodClickMode) { if (this.foodClickMode) {
this.$refs.clickFoodInfo.style.left = `${$event.x + 20}px`; this.$refs.clickFoodInfo.style.left = `${$event.x + 20}px`;
this.$refs.clickFoodInfo.style.top = `${$event.y + 20}px`; this.$refs.clickFoodInfo.style.top = `${$event.y + 20}px`;
} else {
lastMouseMoveEvent = $event;
} }
}, },
}, },

View File

@@ -348,6 +348,7 @@
.npc { .npc {
position: absolute; position: absolute;
left: 0; left: 0;
top: 0;
width: 100%; width: 100%;
height: 216px; height: 216px;
background: url('~assets/images/shops/market_banner_web_alexnpc.png'); background: url('~assets/images/shops/market_banner_web_alexnpc.png');

View File

@@ -87,8 +87,6 @@
:items="questItems(category, selectedSortItemsBy, searchTextThrottled, hideLocked, hidePinned)", :items="questItems(category, selectedSortItemsBy, searchTextThrottled, hideLocked, hidePinned)",
:itemWidth=94, :itemWidth=94,
:itemMargin=24, :itemMargin=24,
:showAllLabel="$t('showAllGeneric', { type: category.text })",
:showLessLabel="$t('showLessGeneric', { type: category.text })"
) )
template(slot="item", scope="ctx") template(slot="item", scope="ctx")
shopItem( shopItem(
@@ -275,7 +273,7 @@
height: 216px; height: 216px;
.background { .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; background-repeat: repeat-x;
@@ -298,13 +296,15 @@
} }
.npc { .npc {
width: 100%;
position: absolute; position: absolute;
left: 0; left: 0;
width: 100%; top: 0;
height: 216px; height: 100%;
background: url('~assets/images/shops/quest_shop__banner_web_iannpc.png'); background: url('~assets/images/shops/quest_shop__banner_web_iannpc.png');
background-repeat: no-repeat; background-repeat: no-repeat;
.featured-label { .featured-label {
position: absolute; position: absolute;
bottom: -14px; bottom: -14px;

View File

@@ -281,6 +281,7 @@
.npc { .npc {
position: absolute; position: absolute;
left: 0; left: 0;
top: 0;
width: 100%; width: 100%;
height: 216px; height: 216px;
background: url('~assets/images/shops/seasonal_shop_closed_banner_web_leslienpc.png'); background: url('~assets/images/shops/seasonal_shop_closed_banner_web_leslienpc.png');

View File

@@ -21,7 +21,7 @@ b-popover(
div.price div.price
span.svg-icon.inline.icon-16(v-html="icons[getSvgClass()]") span.svg-icon.inline.icon-16(v-html="icons[getSvgClass()]")
span.price-label(:class="priceType") {{ price }} span.price-label(:class="getSvgClass()") {{ price }}
</template> </template>
@@ -76,6 +76,10 @@ b-popover(
&.gold { &.gold {
color: $yellow-10 color: $yellow-10
} }
&.hourglasses {
color: $blue-10;
}
} }
span.svg-icon.inline.lock { span.svg-icon.inline.lock {

View File

@@ -78,8 +78,6 @@
:items="travelersItems(category, selectedSortItemsBy, searchTextThrottled, hidePinned)", :items="travelersItems(category, selectedSortItemsBy, searchTextThrottled, hidePinned)",
:itemWidth=94, :itemWidth=94,
:itemMargin=24, :itemMargin=24,
:showAllLabel="$t('showAllGeneric', { type: category.text })",
:showLessLabel="$t('showLessGeneric', { type: category.text })"
) )
template(slot="item", scope="ctx") template(slot="item", scope="ctx")
shopItem( shopItem(
@@ -236,6 +234,7 @@
.npc { .npc {
position: absolute; position: absolute;
left: 0; left: 0;
top: 0;
width: 100%; width: 100%;
height: 216px; height: 216px;
background: url('~assets/images/shops/time_travelers_open_banner_web_tylerandvickynpcs.png'); background: url('~assets/images/shops/time_travelers_open_banner_web_tylerandvickynpcs.png');

View File

@@ -7,13 +7,24 @@
:item="item", :item="item",
) )
div(v-if="items.length === 0")
p(v-once) {{ noItemsLabel }}
.btn.btn-show-more( .btn.btn-show-more(
@click="showAll = !showAll", @click="showAll = !showAll",
v-if="items.length > itemsPerRow()" v-if="items.length > itemsPerRow()"
) {{ showAll ? showLessLabel : showAllLabel }} ) {{ showAll ? $t('showLess') : $t('showMore') }}
div.fill-height(v-else)
</template> </template>
<style lang="scss" scoped>
.fill-height {
height: 38px; // button + margin + padding
}
</style>
<script> <script>
import ResizeDirective from 'client/directives/resize.directive'; import ResizeDirective from 'client/directives/resize.directive';
@@ -60,10 +71,7 @@
itemMargin: { itemMargin: {
type: Number, type: Number,
}, },
showAllLabel: { noItemsLabel: {
type: String,
},
showLessLabel: {
type: String, type: String,
}, },
}, },

View File

@@ -0,0 +1,25 @@
export default function createAnimal (egg, potion, type, content, userItems) {
let animalKey = `${egg.key}-${potion.key}`;
return {
key: animalKey,
class: type === 'pet' ? `Pet Pet-${animalKey}` : `Mount_Icon_${animalKey}`,
eggKey: egg.key,
eggName: egg.text(),
potionKey: potion.key,
potionName: potion.text(),
name: 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;
},
};
}

View File

@@ -54,9 +54,7 @@
"memberCount": "Member Count", "memberCount": "Member Count",
"recentActivity": "Recent Activity", "recentActivity": "Recent Activity",
"gearNotOwned": "You do not own this item.", "gearNotOwned": "You do not own this item.",
"showAllItems": "Show All <%= items %> <%= type %> Items", "noGearItemsOfType": "You don't own any of these.",
"showLessItems": "Show Less <%= type %> Items",
"noGearItemsOfType": "You don't own any pieces of <%= type %>.",
"myGuilds": "My Guilds", "myGuilds": "My Guilds",
"guildsDiscovery": "Discover Guilds", "guildsDiscovery": "Discover Guilds",
"habiticaOfficial": "Habitica Official", "habiticaOfficial": "Habitica Official",
@@ -127,8 +125,6 @@
"confirmPasswordPlaceholder": "Make sure its the same password!", "confirmPasswordPlaceholder": "Make sure its the same password!",
"termsAndAgreement": "By clicking the button below, you are indicating that you have read and agree to the <a href='/static/terms'>Terms of Service</a> and <a href='/static/privacy'>Privacy Policy</a>.", "termsAndAgreement": "By clicking the button below, you are indicating that you have read and agree to the <a href='/static/terms'>Terms of Service</a> and <a href='/static/privacy'>Privacy Policy</a>.",
"joinHabitica": "Join Habitica", "joinHabitica": "Join Habitica",
"showAllAnimals": "Show All <%= color %> <%= type %>",
"showLessAnimals": "Show Less <%= color %> <%= type %>",
"quickInventory": "Quick Inventory", "quickInventory": "Quick Inventory",
"noFoodAvailable": "You don't have any food.", "noFoodAvailable": "You don't have any food.",
"gotIt": "Got it!", "gotIt": "Got it!",
@@ -230,8 +226,6 @@
"sortByStr": "Str", "sortByStr": "Str",
"sortByInt": "Int", "sortByInt": "Int",
"classEquipment": "Class Equipment", "classEquipment": "Class Equipment",
"showAllGeneric": "Show All <%= type %>",
"showLessGeneric": "Show Less <%= type %>",
"howManyToSell": "How many would you like to sell?", "howManyToSell": "How many would you like to sell?",
"yourBalance": "Your balance", "yourBalance": "Your balance",
"sell": "Sell", "sell": "Sell",
@@ -257,6 +251,11 @@
"featuredset": "Featured Set <%= name %>", "featuredset": "Featured Set <%= name %>",
"mysterySets": "Mystery Sets", "mysterySets": "Mystery Sets",
"fetchRecentMessages": "Fetch Recent Messages", "fetchRecentMessages": "Fetch Recent Messages",
"showMore": "Show More",
"showLess": "Show Less",
"hatchedPetNotesPart1": "Visit the ",
"hatchedPetNotesPart2": "to feed and equip your newest pet!",
"onward": "Onward!",
"tavernChat": "Tavern Chat", "tavernChat": "Tavern Chat",
"partyChatPlaceholder": "Type message to Party members here", "partyChatPlaceholder": "Type message to Party members here",
"done": "Done" "done": "Done"