issue(11266) - Restyle level-up modal with sparkles (#12486)

* issue(11266) - Restyle level-up modal with sparkles

* issue(11266) - Add reward display to level up modal

At levels 15, 30, 40 and 60 the earned quests are now shown in the level-up modal.

* issue(11266) - Simplify css and don't use custom footer

* issue(11266) - Don't show pink bars and use colour variables
This commit is contained in:
Bart Enkelaar
2020-08-29 16:33:06 +02:00
committed by GitHub
parent c00b2247d4
commit 1b301e9c68
10 changed files with 241 additions and 73 deletions

View File

@@ -36,7 +36,7 @@ import BootstrapVue from 'bootstrap-vue';
import StoreModule from '@/libs/store'; import StoreModule from '@/libs/store';
// couldn't inject the languages easily, // couldn't inject the languages easily,
// so just a "$t()" string to show that this will be translated // so just a "$t()" string to show that this will be translated
Vue.prototype.$t = function translateString (...args) { Vue.prototype.$t = function translateString (...args) {
return `$t(${JSON.stringify(args)})`; return `$t(${JSON.stringify(args)})`;
}; };

View File

@@ -206,5 +206,4 @@
font-style: normal; font-style: normal;
} }
} }
} }

View File

@@ -0,0 +1,7 @@
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="15" viewBox="0 0 32 15">
<g fill="none" fill-rule="evenodd">
<path fill="#FFA624" d="M9.074 8.485L13.333 6.364 9.074 4.242 6.944 0 4.815 4.242 0.556 6.364 4.815 8.485 6.944 12.727z" transform="rotate(90 16 16)"/>
<path fill="#FFBE5D" d="M12.634 19.632L15.19 18.359 12.634 17.087 11.356 14.541 10.079 17.087 7.523 18.359 10.079 19.632 11.356 22.177z" transform="rotate(90 16 16) rotate(53 11.356 18.36)"/>
<path fill="#FEDEAD" d="M7.111 29.091L9.667 27.818 7.111 26.545 5.833 24 4.556 26.545 2 27.818 4.556 29.091 5.833 31.636z" transform="rotate(90 16 16)"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 662 B

View File

@@ -0,0 +1,9 @@
<svg xmlns="http://www.w3.org/2000/svg" width="40" height="64" viewBox="0 0 40 64">
<g fill="none" fill-rule="evenodd">
<path fill="#77F4C7" d="M35.667 8.667L40 6.5 35.667 4.333 33.5 0 31.333 4.333 27 6.5 31.333 8.667 33.5 13z" transform="matrix(-1 0 0 1 40 0)"/>
<path fill="#BDA8FF" d="M24.667 35.667L30 33 24.667 30.333 22 25 19.333 30.333 14 33 19.333 35.667 22 41z" transform="matrix(-1 0 0 1 40 0)"/>
<path fill="#8EEDF6" d="M35.667 60.667L39 59 35.667 57.333 34 54 32.333 57.333 29 59 32.333 60.667 34 64z" transform="matrix(-1 0 0 1 40 0)"/>
<path fill="#FFBE5D" d="M6.667 46.667L10 45 6.667 43.333 5 40 3.333 43.333 0 45 3.333 46.667 5 50z" transform="matrix(-1 0 0 1 40 0)"/>
<path fill="#FFB6B8" d="M5.667 17.667L8 16.5 5.667 15.333 4.5 13 3.333 15.333 1 16.5 3.333 17.667 4.5 20z" transform="matrix(-1 0 0 1 40 0)"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 889 B

View File

@@ -1,109 +1,200 @@
<template> <template>
<b-modal <b-modal
id="level-up" id="level-up"
:title="$t('levelUpShare')"
size="sm" size="sm"
:hide-footer="true" :title="title"
:hide-header="true" ok-only
:ok-title="$t('onwards')"
v-bind:footer-class="{ greyed: displayRewardQuest }"
> >
<div class="modal-body text-center"> <section class="d-flex">
<h2>{{ $t('reachedLevel', {level: user.stats.lvl}) }}</h2> <span
class="star-group mirror"
v-html="icons.starGroup"
></span>
<avatar <avatar
class="avatar" class="avatar"
:member="user" :member="user"
/> />
<p class="text"> <span
{{ $t('levelup') }} class="star-group"
</p> v-html="icons.starGroup"
<button ></span>
class="btn btn-primary" </section>
@click="close()"
<p
class="text"
v-once
>
{{ $t('levelup') }}
</p>
<section
v-if="displayRewardQuest"
class="greyed"
>
<div
class="your-rewards d-flex"
v-once
> >
{{ $t('onwards') }} <span
</button> class="sparkles"
<br> v-html="icons.sparkles"
<!-- @TODO: Keep this? .checkboxinput(type='checkbox', v-model= ></span>
<span class="text">{{ $t('yourRewards') }}</span>
<span
class="sparkles mirror"
v-html="icons.sparkles"
></span>
</div>
<div :class="questClass"></div>
</section>
<!-- @TODO: Keep this? .checkboxinput(type='checkbox', v-model=
'user.preferences.suppressModals.levelUp', @change='changeLevelupSuppress()') 'user.preferences.suppressModals.levelUp', @change='changeLevelupSuppress()')
label(style='display:inline-block') {{ $t('dontShowAgain') }} label(style='display:inline-block') {{ $t('dontShowAgain') }}
--> -->
</div>
</b-modal> </b-modal>
</template> </template>
<style lang="scss"> <style lang="scss">
@import '~@/assets/scss/colors.scss';
#level-up { #level-up {
h2 { .modal-content {
color: #4f2a93; border-radius: 8px;
box-shadow: 0 14px 28px 0 rgba($black, 0.24), 0 10px 10px 0 rgba($black, 0.28);
} }
.modal-content { @media (min-width: 576px) {
min-width: 28em; .modal-sm {
max-width: 330px;
}
}
header {
padding: 0;
border: none;
h5 {
margin: 31px auto 16px;
color: $purple-200;
}
button {
position: absolute;
right: 18px;
top: 12px;
}
}
footer {
padding: 0;
border: none;
button {
margin: 0 auto 32px auto;
}
}
.greyed {
background-color: $gray-700;
} }
.modal-body { .modal-body {
padding-top: 1em; padding: 0;
} }
.modal-footer { .mirror {
margin-top: 0; transform: scaleX(-1);
} }
.herobox { .star-group {
margin: auto 8.3em; margin: auto;
width: 6em;
height: 9em; svg {
padding-top: 0; height: 64px;
cursor: default; width: 40px;
}
} }
.character-sprites { .avatar {
margin: 0; cursor: auto;
width: 0; }
.class-badge {
display: none !important;
} }
.text { .text {
font-size: 14px; margin: 25px 24px 24px;
text-align: center; min-height: auto;
color: #686274;
margin-top: 1em;
min-height: 0px;
} }
}
</style>
<style scoped> .your-rewards {
.avatar { margin: 0 auto;
margin-left: 6.8em; width: fit-content;
.sparkles {
width: 32px;
margin-top: 12px;
}
.text {
font-weight: bold;
margin: 16px;
color: $gray-50;
}
}
section.greyed {
padding-bottom: 17px
}
.scroll {
margin: -11px auto 0;
}
} }
</style> </style>
<script> <script>
import Avatar from '../avatar'; import Avatar from '../avatar';
import { mapState } from '@/libs/store'; import { mapState } from '@/libs/store';
import { MAX_HEALTH as maxHealth } from '@/../../common/script/constants'; import starGroup from '@/assets/svg/star-group.svg';
import styleHelper from '@/mixins/styleHelper'; import sparkles from '@/assets/svg/sparkles-left.svg';
const levelQuests = {
15: 'atom1',
30: 'vice1',
40: 'goldenknight1',
60: 'moonstone1',
};
export default { export default {
components: { components: {
Avatar, Avatar,
}, },
mixins: [styleHelper],
data () { data () {
return { return {
statsAllocationBoxIsOpen: true, icons: Object.freeze({
maxHealth, starGroup,
sparkles,
}),
}; };
}, },
computed: { computed: {
...mapState({ user: 'user.data' }), ...mapState({ user: 'user.data' }),
showAllocation () { title () {
return this.$store.getters['members:hasClass'](this.user) && !this.user.preferences.automaticAllocation; return this.$t('reachedLevel', { level: this.user.stats.lvl });
},
displayRewardQuest () {
return this.user.stats.lvl in levelQuests;
},
questClass () {
return `scroll inventory_quest_scroll_${levelQuests[this.user.stats.lvl]}`;
}, },
}, },
methods: { methods: {
close () {
this.$root.$emit('bv::hide::modal', 'level-up');
},
changeLevelupSuppress () { changeLevelupSuppress () {
// @TODO: dispatch set({"preferences.suppressModals.levelUp": // @TODO: dispatch set({"preferences.suppressModals.levelUp":
// user.preferences.suppressModals.levelUp?true: false}) // user.preferences.suppressModals.levelUp?true: false})

View File

@@ -46,7 +46,6 @@
</template> </template>
<style lang="scss"> <style lang="scss">
@import '~@/assets/scss/colors.scss';
@import '~@/assets/scss/modal.scss'; @import '~@/assets/scss/modal.scss';
#hatchedPet-modal { #hatchedPet-modal {

View File

@@ -389,7 +389,7 @@ export default {
data () { data () {
// Levels that already display modals and should not trigger generic Level Up // Levels that already display modals and should not trigger generic Level Up
const unlockLevels = { const unlockLevels = {
10: 'class system', 10: 'Class system',
50: 'Orb of Rebirth', 50: 'Orb of Rebirth',
}; };
@@ -661,13 +661,7 @@ export default {
showLevelUpNotifications (newlevel) { showLevelUpNotifications (newlevel) {
this.lvl(); this.lvl();
this.playSound('Level_Up'); this.playSound('Level_Up');
// NOTE this code isn't actually used because no modal is shown when a quest is dropped if (this.unlockLevels[newlevel]) return;
// In case it's added again it should keep in mind that it will not work
// when the user progress to the next level using the RYA modal
// as it doesn't score the tasks on the client side and thus this.user._tmp is not filled
// with any value
// if (this.user._tmp && this.user._tmp.drop && this.user._tmp.drop.type === 'Quest') return;
if (this.unlockLevels[`${newlevel}`]) return;
if (!this.user.preferences.suppressModals.levelUp) this.$root.$emit('bv::show::modal', 'level-up'); if (!this.user.preferences.suppressModals.levelUp) this.$root.$emit('bv::show::modal', 'level-up');
}, },
playSound (sound) { playSound (sound) {

View File

@@ -696,12 +696,6 @@
box-shadow: 0 14px 28px 0 rgba($black, 0.24), 0 10px 10px 0 rgba($black, 0.28); box-shadow: 0 14px 28px 0 rgba($black, 0.24), 0 10px 10px 0 rgba($black, 0.28);
} }
.modal-body {
// the body has a margin/padding that can't be found
// if found please remove that padding and this style
// margin-bottom: -2rem;
}
.modal-header, .modal-body, .modal-footer { .modal-header, .modal-body, .modal-footer {
padding: 0px; padding: 0px;
border: none; border: none;
@@ -711,10 +705,6 @@
cursor: auto; cursor: auto;
} }
.cursor-auto {
cursor: auto;
}
.task-modal-header { .task-modal-header {
color: $white; color: $white;
width: 100%; width: 100%;

View File

@@ -0,0 +1,78 @@
import LevelUp from '@/components/achievements/levelUp.vue';
/*
// I couldn't get rendering to work for the modal, this is what I tried.
// Now the testing is done by overriding `this` for the exported computed
// functions directly. I intend to come back to this later to test it
// properly in a rendered component.
import { mount, createLocalVue } from '@vue/test-utils';
import BootstrapVue from 'bootstrap-vue';
import Store from '@/libs/store';
const localVue = createLocalVue();
localVue.use(Store);
localVue.use(BootstrapVue);
function createContainer () {
const container = document.createElement('div');
document.body.appendChild(container);
return container;
}
*/
describe('LevelUp', () => {
function testFunction (name, level = 10) {
return LevelUp.computed[name].bind({
user: { stats: { lvl: level } },
$t: (...args) => args.map(JSON.stringify).join(' '),
});
}
/*
// More potential rendering code
let wrapper;
beforeEach(async () => {
wrapper = mount(LevelUp, {
store: new Store({
state: { user: { data: createUser() } },
getters: {},
actions: {},
}),
propsData: {
static: true,
visible: true,
},
localVue,
mocks: { $t: string => string },
attachTo: createContainer(),
});
});
*/
it('displays the right level in the title', () => {
const title = testFunction('title', 12);
expect(title()).to.equal('"reachedLevel" {"level":12}');
});
it('does not display rewards for level 10', () => {
const displayRewardQuest = testFunction('displayRewardQuest', 10);
expect(displayRewardQuest()).to.be.false;
});
[15, 30, 40, 60].forEach(level => {
it(`does display rewards for level ${level}`, () => {
const displayRewardQuest = testFunction('displayRewardQuest', level);
expect(displayRewardQuest()).to.be.true;
});
});
it('generates the right test class for level 15', () => {
const questClass = testFunction('questClass', 15);
expect(questClass()).to.equal('scroll inventory_quest_scroll_atom1');
});
});

View File

@@ -4,6 +4,7 @@
"onwards": "Onwards!", "onwards": "Onwards!",
"levelup": "By accomplishing your real life goals, you leveled up and are now fully healed!", "levelup": "By accomplishing your real life goals, you leveled up and are now fully healed!",
"reachedLevel": "You Reached Level <%= level %>", "reachedLevel": "You Reached Level <%= level %>",
"yourRewards": "Your Rewards",
"gettingStartedDesc": "Complete these onboarding tasks and youll earn <strong>5 Achievements</strong> and <strong class=\"gold-amount\">100 Gold</strong> once youre done!", "gettingStartedDesc": "Complete these onboarding tasks and youll earn <strong>5 Achievements</strong> and <strong class=\"gold-amount\">100 Gold</strong> once youre done!",
"onboardingProgress": "<%= percentage %>% progress", "onboardingProgress": "<%= percentage %>% progress",
"yourProgress": "Your Progress", "yourProgress": "Your Progress",