Fixed Skill Layout (#12776)

* Fixed Skill Layout

* Fixed skill layout reponsiveness

* Fixed collapsing of drawer container

* Fixed skill card disabled state, extra white border and hover sstate

* Fixed task / member selection style

* Fixed few changes

* Fixed extra padding and box shadow

* Fixed box shadow and added popover component

* Fixed disabled state issue

* Fixed styles and skill card issues

* Fixed style issues

* Fixed style issue

* Fixed lint error

* Fixed space between drawer class

* Fixed border issue

* Fixed round border issue

* Fixed Mage issue

* auto eslint fixes

* use translated string and computed property, reorganize css

* perf: reduce calculated classes, throttle mouse moved event

Co-authored-by: Matteo Pagliazzi <matteopagliazzi@gmail.com>
This commit is contained in:
Vipul Khandelwal
2020-12-05 02:35:56 +05:30
committed by GitHub
parent 2018962eb5
commit bc181819f4
4 changed files with 374 additions and 167 deletions

View File

@@ -104,9 +104,9 @@
:variant="'success'" :variant="'success'"
> >
<b-dropdown-item <b-dropdown-item
class="selectListItem"
v-for="type in columns" v-for="type in columns"
:key="type" :key="type"
class="selectListItem"
@click="createTask(type)" @click="createTask(type)"
>{{ $t(type) }}</b-dropdown-item> >{{ $t(type) }}</b-dropdown-item>
</b-dropdown> </b-dropdown>

View File

@@ -43,23 +43,32 @@
> >
</div> </div>
<div class="col"> <div class="col">
<select-list :items="sortOptions" <select-list
@select="changeSortOption($event)" :items="sortOptions"
:value="optionEntryBySelectedValue" :value="optionEntryBySelectedValue"
key-prop="value"> key-prop="value"
@select="changeSortOption($event)"
>
<template v-slot:item="{ item }"> <template v-slot:item="{ item }">
<span class="label" v-if="item">{{ item.text }}</span> <span
v-if="item"
class="label"
>{{ item.text }}</span>
</template> </template>
</select-list> </select-list>
</div> </div>
<div class="col-3"> <div class="col-3">
<select-list
<select-list :items="sortDirections" :items="sortDirections"
@select="changeSortDirection($event)"
:value="directionEntryBySelectedValue" :value="directionEntryBySelectedValue"
key-prop="value"> key-prop="value"
@select="changeSortDirection($event)"
>
<template v-slot:item="{ item }"> <template v-slot:item="{ item }">
<span class="label" v-if="item">{{ item.text }}</span> <span
v-if="item"
class="label"
>{{ item.text }}</span>
</template> </template>
</select-list> </select-list>
</div> </div>

View File

@@ -5,60 +5,108 @@
ref="clickPotionInfo" ref="clickPotionInfo"
class="dragInfo mouse" class="dragInfo mouse"
> >
<div class="spell col-12 row"> <div class="spell">
<div class="col-8 details"> <div class="spell-border">
<p class="title"> <div class="mana">
{{ spell.text() }}
</p>
<p class="notes">
{{ `Click on a ${spell.target} to cast!` }}
</p>
<!-- @TODO make that translatable-->
</div>
<div class="col-4 mana">
<div <div
class="img" class="img"
:class="`shop_${spell.key} shop-sprite item-img`" :class="`shop_${spell.key} shop-sprite item-img`"
></div> ></div>
</div> </div>
</div> </div>
<div class="details">
<!-- @TODO make that translatable-->
<p class="notes">
{{ `Select a ${spell.target}` }}
</p>
</div> </div>
<div class="drawer-wrapper d-flex justify-content-center"> </div>
</div>
<div class="drawer-wrapper">
<drawer <drawer
v-if="user.stats.class && !user.preferences.disableClasses" v-if="user.stats.class && !user.preferences.disableClasses"
v-mousePosition="30" v-mousePosition="30"
:title="$t('skillsTitle')" :title="drawerTitle"
:open-status="openStatus" :open-status="openStatus"
@mouseMoved="mouseMoved($event)" @mouseMoved="mouseMoved($event)"
@toggled="drawerToggled" @toggled="drawerToggled"
> >
<div slot="drawer-slider"> <div slot="drawer-slider">
<div class="container spell-container"> <div class="spell-container">
<div class="row">
<!-- eslint-disable vue/no-use-v-if-with-v-for -->
<div <div
v-for="(skill, key) in spells[user.stats.class]" v-for="(skill, key) in spells[user.stats.class]"
v-if="user.stats.lvl >= skill.lvl" :id="`spell_${skill.key}`"
:key="key" :key="key"
v-b-popover.hover.auto="skillNotes(skill)"
class="col-12 col-md-3"
@click="!spellDisabled(key) ? castStart(skill) : null" @click="!spellDisabled(key) ? castStart(skill) : null"
> >
<!-- eslint-enable vue/no-use-v-if-with-v-for --> <b-popover
<div :target="`spell_${skill.key}`"
class="spell col-12 row" triggers="hover"
:class="{'disabled': spellDisabled(key)}" placement="top"
custom-class="popover-class"
> >
<div class="col-8 details"> <div class="popover-wrapper">
<div class="popover-title">
<div class="popover-title-text">
{{ skill.text() }}
</div>
<div class="popover-mana">
<div
v-once
class="popover-svg-icon"
v-html="icons.mana"
></div>
<div class="popover-mana-count">
{{ skill.mana }}
</div>
</div>
</div>
<div class="popover-description">
{{ skillNotes(skill) }}
</div>
</div>
</b-popover>
<div
class="spell-border"
:class="{ disabled: spellDisabled(key) || user.stats.lvl < skill.lvl }"
>
<div
class="spell"
>
<div class="details">
<div <div
class="img" class="img"
:class="`shop_${skill.key} shop-sprite item-img`" :class="`shop_${skill.key} shop-sprite item-img`"
></div> ></div>
<span class="title">{{ skill.text() }}</span>
</div> </div>
<div class="col-4 mana"> <div
v-if="user.stats.lvl < skill.lvl"
class="mana"
>
<div class="mana-text level">
<div>Level {{ skill.lvl }}</div>
</div>
</div>
<div
v-else-if="spellDisabled(key) === true"
class="mana"
>
<div class="mana-text"> <div class="mana-text">
<div <div
v-once
class="svg-icon"
v-html="icons.mana"
></div>
<div>{{ skill.mana }}</div>
</div>
</div>
<div
v-else
class="mana"
>
<div class="mana-text">
<div
v-once
class="svg-icon" class="svg-icon"
v-html="icons.mana" v-html="icons.mana"
></div> ></div>
@@ -76,68 +124,132 @@
</template> </template>
<style lang="scss" scoped> <style lang="scss" scoped>
@import '~@/assets/scss/colors.scss';
.drawer-wrapper { .drawer-wrapper {
width: 100vw; width: 100vw;
position: fixed; position: fixed;
bottom: 0; bottom: 0;
left: 0; left: 0;
z-index: 19; z-index: 19;
display: flex;
justify-content: center;
.drawer-container { .drawer-container {
left: auto !important; left: auto !important;
right: auto !important; right: auto !important;
min-width: 60%; min-width: 25.5rem;
} }
} }
.drawer-slider { .popover-class {
margin-top: 1em; .popover-wrapper {
display: flex;
flex-direction: column;
gap: 0.1em;
.popover-description {
text-align: left;
color: $white;
}
.popover-title {
display: flex;
justify-content: space-between;
padding-bottom: 0.5em;
.popover-title-text {
font-weight: bold;
font-size: 1.1em;
color: $white;
}
.popover-mana {
display: flex;
gap: 2px;
justify-content: center;
align-items: center;
.popover-svg-icon {
width: 1.3em;
}
.popover-mana-count {
font-weight: bold;
color: $blue-100;
font-size: 1.1em;
}
}
}
}
} }
.spell-container { .spell-container {
margin-top: .5em;
white-space: initial; white-space: initial;
display: flex;
justify-content: space-evenly;
align-items: center;
margin-left: -2rem;
margin-right: -1.5rem;
margin-top: -0.14rem;
box-sizing: content-box;
.spell-border {
padding: 2px;
background-color: transparent;
border-radius: 4px;
margin-bottom: 1rem;
&:hover:not(.disabled) {
background-color: $purple-400;
cursor: pointer;
box-shadow: 0 4px 4px 0 rgba(26, 24, 29, 0.16),
0 1px 4px 0 rgba(26, 24, 29, 0.12);
} }
.spell:hover:not(.disabled) { &.disabled {
cursor: pointer; .spell {
border: solid 2px #50b5e9; background-color: $gray-10;
box-shadow: none !important;
.mana {
background-color: rgba(26, 24, 29, 0.5);
}
.level {
color: $white;
font-weight: normal;
}
}
} }
.spell { .spell {
background: #ffffff; background: $white;
border: solid 2px transparent; border-radius: 4px;
margin-bottom: 1em; color: $gray-50;
box-shadow: 0 2px 2px 0 rgba(26, 24, 29, 0.16), 0 1px 4px 0 rgba(26, 24, 29, 0.12);
border-radius: 1000px;
color: #4e4a57;
padding-right: 0; padding-right: 0;
padding-left: 0; padding-left: 0;
overflow: hidden; overflow: hidden;
width: 4.5rem;
height: 4.6rem;
box-shadow: 0 1px 3px 0 rgba(26, 24, 29, 0.12),
0 1px 2px 0 rgba(26, 24, 29, 0.24);
&.disabled { &:hover {
opacity: 0.5; box-shadow: 0 3px 6px 0 rgba(26, 24, 29, 0.16),
0 3px 6px 0 rgba(26, 24, 29, 0.24);
} }
.details { .details {
text-align: left; text-align: center;
padding-top: .5em; height: 3.1rem;
padding-right: .1em; display: flex;
justify-content: center;
align-items: center;
.img { .img {
display: inline-block; display: block;
} text-align: center;
span {
display: inline-block;
width: 50%;
padding-bottom: .7em;
vertical-align: bottom;
}
.notes {
font-weight: normal;
color: #686274;
} }
} }
@@ -146,59 +258,128 @@
} }
.mana-text { .mana-text {
margin-bottom: .2em; display: flex;
padding-top: 1.1em; justify-content: center;
align-items: center;
div { gap: 0.2rem;
display: inline-block; text-align: center;
vertical-align: bottom; color: $blue-1;
}
.svg-icon { .svg-icon {
width: 16px; width: 16px;
height: 16px; height: 16px;
margin-right: .2em;
} }
} }
.mana { .mana {
padding: .2em; background-color: rgba(70, 167, 217, 0.15);
background-color: rgba(70, 167, 217, 0.24); color: $blue-10;
color: #2995cd;
font-weight: bold; font-weight: bold;
text-align: center; height: 1.5rem;
display: flex;
justify-content: center;
align-items: center;
} }
} }
}
}
.spell-container-row {
display: flex;
justify-content: space-evenly;
align-items: center;
gap: 2em;
margin-right: -1em;
margin-left: -1em;
}
.spell-skills {
flex: 0 0 auto;
width: 6em;
}
.dragInfo { .dragInfo {
position: absolute; position: absolute;
left: -500px; left: -500px;
z-index: 1080; z-index: 1080;
color: $gray-500;
border: none;
background-color: transparent;
box-shadow: transparent;
.spell { .spell {
border-radius: 1000px; width: 5.9rem;
min-width: 224px; height: 8rem;
height: 52px; padding-bottom: 0;
font-size: 12px; margin-bottom: 0;
padding-left: .5em; background-color: transparent;
border: none;
box-shadow: none;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
gap: 1.5rem;
.title { .spell-border {
font-weight: bold; width: 59px;
margin-bottom: .2em; height: 62px;
} background: $blue-50;
} border-radius: 4px;
box-sizing: border-box;
transform: rotate(45deg);
padding: 2px;
display: flex;
justify-content: center;
align-items: center;
.mana { .mana {
border-radius: 0 1000px 1000px 0; width: 58px;
height: 58px;
background-color: $gray-700;
border-radius: 4px;
display: flex;
justify-content: center;
align-items: center;
overflow: hidden;
.img {
background-color: $gray-700;
display: block;
text-align: center;
transform: rotate(-45deg);
}
}
}
.details {
margin-top: 1rem;
width: 100%;
height: 2em;
border-radius: 4px;
background-color: rgba(52, 49, 58, 0.96);
.notes {
font-size: 13px;
color: $white;
text-align: center;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
}
} }
&.mouse { &.mouse {
position: fixed; position: fixed;
pointer-events: none pointer-events: none;
} }
.potion-icon { .potion-icon {
margin: 0 auto; margin: 0 auto;
} }
.popover { .popover {
position: inherit; position: inherit;
width: 100px; width: 100px;
@@ -207,8 +388,11 @@
</style> </style>
<script> <script>
import spells, { stealthBuffsToAdd } from '@/../../common/script/content/spells'; import throttle from 'lodash/throttle';
import spells, {
stealthBuffsToAdd,
} from '@/../../common/script/content/spells';
import { mapState, mapGetters } from '@/libs/store'; import { mapState, mapGetters } from '@/libs/store';
import notifications from '@/mixins/notifications'; import notifications from '@/mixins/notifications';
import spellsMixin from '@/mixins/spells'; import spellsMixin from '@/mixins/spells';
@@ -216,7 +400,11 @@ import Drawer from '@/components/ui/drawer';
import MouseMoveDirective from '@/directives/mouseposition.directive'; import MouseMoveDirective from '@/directives/mouseposition.directive';
import mana from '@/assets/svg/mana.svg'; import mana from '@/assets/svg/mana.svg';
import { CONSTANTS, setLocalSetting, getLocalSetting } from '@/libs/userlocalManager'; import {
CONSTANTS,
setLocalSetting,
getLocalSetting,
} from '@/libs/userlocalManager';
export default { export default {
components: { components: {
@@ -246,6 +434,10 @@ export default {
openStatus () { openStatus () {
return this.$store.state.spellOptions.spellDrawOpen ? 1 : 0; return this.$store.state.spellOptions.spellDrawOpen ? 1 : 0;
}, },
drawerTitle () {
const classStr = this.$t(this.user.stats.class);
return this.$t('skillsTitle', { classStr });
},
}, },
mounted () { mounted () {
// @TODO: should we abstract the drawer state/local // @TODO: should we abstract the drawer state/local
@@ -260,10 +452,8 @@ export default {
this.$store.state.spellOptions.spellDrawOpen = newState; this.$store.state.spellOptions.spellDrawOpen = newState;
if (newState) { if (newState) {
setLocalSetting( setLocalSetting(CONSTANTS.keyConstants.SPELL_DRAWER_STATE,
CONSTANTS.keyConstants.SPELL_DRAWER_STATE, CONSTANTS.drawerStateValues.DRAWER_OPEN);
CONSTANTS.drawerStateValues.DRAWER_OPEN,
);
return; return;
} }
@@ -273,9 +463,18 @@ export default {
); );
}, },
spellDisabled (skill) { spellDisabled (skill) {
const incompleteDailiesDue = this.getUnfilteredTaskList('daily').filter(daily => !daily.completed && daily.isDue).length; const incompleteDailiesDue = this
if (skill === 'frost' && this.user.stats.buffs.streaks) return true; .getUnfilteredTaskList('daily')
if (skill === 'stealth' && this.user.stats.buffs.stealth >= incompleteDailiesDue) return true; .filter(daily => !daily.completed && daily.isDue)
.length;
if (skill === 'frost' && this.user.stats.buffs.streaks) {
return true;
}
if (skill === 'stealth' && this.user.stats.buffs.stealth >= incompleteDailiesDue) {
return true;
}
return false; return false;
}, },
@@ -296,15 +495,14 @@ export default {
return notes; return notes;
}, },
// @TODO: Move to mouse move component?? // @TODO: Move to mouse move component??
mouseMoved ($event) { mouseMoved: throttle(function mouseMoved ($event) {
// @TODO: throttle
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 { } else {
this.lastMouseMoveEvent = $event; this.lastMouseMoveEvent = $event;
} }
}, }, 10),
}, },
}; };
</script> </script>

View File

@@ -98,7 +98,7 @@
"classGearText": "Congratulations on choosing a class! I've added your new basic weapon to your inventory. Take a look below to equip it!", "classGearText": "Congratulations on choosing a class! I've added your new basic weapon to your inventory. Take a look below to equip it!",
"autoAllocate": "Auto Allocate", "autoAllocate": "Auto Allocate",
"spells": "Skills", "spells": "Skills",
"skillsTitle": "Skills", "skillsTitle": "<%= classStr %> Skills",
"toDo": "To Do", "toDo": "To Do",
"tourStatsPage": "This is your Stats page! Earn achievements by completing the listed tasks.", "tourStatsPage": "This is your Stats page! Earn achievements by completing the listed tasks.",
"tourTavernPage": "Welcome to the Tavern, an all-ages chat room! You can keep your Dailies from hurting you in case of illness or travel by clicking \"Pause Damage\". Come say hi!", "tourTavernPage": "Welcome to the Tavern, an all-ages chat room! You can keep your Dailies from hurting you in case of illness or travel by clicking \"Pause Damage\". Come say hi!",