feat(avatar): popovers for customization

This commit is contained in:
Sabe Jones
2024-07-24 16:36:29 -05:00
parent 22def5111f
commit fb78495a1b
9 changed files with 92 additions and 60 deletions

View File

@@ -6,6 +6,7 @@
<div <div
v-for="option in items" v-for="option in items"
:key="option.key" :key="option.key"
:id="option.class"
class="outer-option-background" class="outer-option-background"
:class="{ :class="{
premium: Boolean(option.gem), premium: Boolean(option.gem),
@@ -14,6 +15,14 @@
hide: option.hide }" hide: option.hide }"
@click="option.click(option)" @click="option.click(option)"
> >
<b-popover
:target="option.class"
triggers="hover focus"
placement="bottom"
:prevent-overflow="false"
>
<strong> {{ option.text }} </strong>
</b-popover>
<div class="option"> <div class="option">
<div <div
class="sprite customize-option" class="sprite customize-option"

View File

@@ -75,6 +75,7 @@
<script> <script>
import appearance from '@/../../common/script/content/appearance'; import appearance from '@/../../common/script/content/appearance';
import upperFirst from 'lodash/upperFirst';
import { subPageMixin } from '../../mixins/subPage'; import { subPageMixin } from '../../mixins/subPage';
import { userStateMixin } from '../../mixins/userState'; import { userStateMixin } from '../../mixins/userState';
import { avatarEditorUtilities } from '../../mixins/avatarEditUtilities'; import { avatarEditorUtilities } from '../../mixins/avatarEditUtilities';
@@ -82,9 +83,6 @@ import customizeBanner from './customize-banner';
import customizeOptions from './customize-options'; import customizeOptions from './customize-options';
import subMenu from './sub-menu'; import subMenu from './sub-menu';
const freeShirtKeys = Object.keys(appearance.shirt).filter(k => appearance.shirt[k].price === 0);
const specialShirtKeys = Object.keys(appearance.shirt).filter(k => appearance.shirt[k].price !== 0);
export default { export default {
components: { components: {
customizeBanner, customizeBanner,
@@ -106,17 +104,6 @@ export default {
headAccessory: ['bearEars', 'cactusEars', 'foxEars', 'lionEars', 'pandaEars', 'pigEars', 'tigerEars', 'wolfEars'], headAccessory: ['bearEars', 'cactusEars', 'foxEars', 'lionEars', 'pandaEars', 'pigEars', 'tigerEars', 'wolfEars'],
}, },
chairKeys: ['none', 'black', 'blue', 'green', 'pink', 'red', 'yellow', 'handleless_black', 'handleless_blue', 'handleless_green', 'handleless_pink', 'handleless_red', 'handleless_yellow'], chairKeys: ['none', 'black', 'blue', 'green', 'pink', 'red', 'yellow', 'handleless_black', 'handleless_blue', 'handleless_green', 'handleless_pink', 'handleless_red', 'handleless_yellow'],
specialShirtKeys,
items: [
{
id: 'size',
label: this.$t('size'),
},
{
id: 'shirt',
label: this.$t('shirt'),
},
],
}; };
}, },
computed: { computed: {
@@ -167,6 +154,7 @@ export default {
]; ];
const noneOption = this.createGearItem(0, 'eyewear', 'base'); const noneOption = this.createGearItem(0, 'eyewear', 'base');
noneOption.none = true; noneOption.none = true;
noneOption.text = this.$t('none');
const options = [ const options = [
noneOption, noneOption,
]; ];
@@ -184,24 +172,17 @@ export default {
return this.equip(newKey, type); return this.equip(newKey, type);
}; };
option.text = this.$t(`eyewearSpecial${upperFirst(key)}Text`);
options.push(option); options.push(option);
} }
return options; return options;
}, },
freeShirts () {
return freeShirtKeys.map(s => this.mapKeysToFreeOption(s, 'shirt'));
},
specialShirts () {
let backgroundUpdate = this.backgroundUpdate; // eslint-disable-line
const keys = this.specialShirtKeys;
const options = keys.map(key => this.mapKeysToOption(key, 'shirt'));
return options;
},
headbands () { headbands () {
const keys = ['blackHeadband', 'blueHeadband', 'greenHeadband', 'pinkHeadband', 'redHeadband', 'whiteHeadband', 'yellowHeadband']; const keys = ['blackHeadband', 'blueHeadband', 'greenHeadband', 'pinkHeadband', 'redHeadband', 'whiteHeadband', 'yellowHeadband'];
const noneOption = this.createGearItem(0, 'headAccessory', 'base', 'headband'); const noneOption = this.createGearItem(0, 'headAccessory', 'base', 'headband');
noneOption.none = true; noneOption.none = true;
noneOption.text = this.$t('none');
const options = [ const options = [
noneOption, noneOption,
]; ];
@@ -213,7 +194,7 @@ export default {
const type = this.user.preferences.costume ? 'costume' : 'equipped'; const type = this.user.preferences.costume ? 'costume' : 'equipped';
return this.equip(newKey, type); return this.equip(newKey, type);
}; };
option.text = this.$t(`headAccessory${upperFirst(key)}Text`);
options.push(option); options.push(option);
} }
@@ -229,6 +210,7 @@ export default {
option.active = this.user.preferences.chair === key; option.active = this.user.preferences.chair === key;
option.class = `button_chair_${key} chair ${key.includes('handleless_') ? 'handleless' : ''}`; option.class = `button_chair_${key} chair ${key.includes('handleless_') ? 'handleless' : ''}`;
option.click = () => this.set({ 'preferences.chair': key }); option.click = () => this.set({ 'preferences.chair': key });
option.text = appearance.chair[key].text();
return option; return option;
}); });
return options; return options;
@@ -244,6 +226,7 @@ export default {
option.active = this.user.preferences.hair.flower === key; option.active = this.user.preferences.hair.flower === key;
option.class = `icon_hair_flower_${key} flower`; option.class = `icon_hair_flower_${key} flower`;
option.click = () => this.set({ 'preferences.hair.flower': key }); option.click = () => this.set({ 'preferences.hair.flower': key });
option.text = appearance.hair.flower[key].text();
return option; return option;
}); });
return options; return options;
@@ -271,6 +254,7 @@ export default {
const noneOption = this.createGearItem(0, category, 'base', category); const noneOption = this.createGearItem(0, category, 'base', category);
noneOption.none = true; noneOption.none = true;
noneOption.text = this.$t('none');
const options = [ const options = [
noneOption, noneOption,
]; ];
@@ -284,9 +268,13 @@ export default {
option.active = this.user.preferences.costume option.active = this.user.preferences.costume
? this.user.items.gear.costume[category] === newKey ? this.user.items.gear.costume[category] === newKey
: this.user.items.gear.equipped[category] === newKey; : this.user.items.gear.equipped[category] === newKey;
option.class = `headAccessory_special_${option.key} ${category}`;
if (category === 'back') { if (category === 'back') {
option.text = this.$t(`back${upperFirst(key)}Text`);
option.class = `icon_back_special_${option.key} back`; option.class = `icon_back_special_${option.key} back`;
} else {
option.text = this.$t(`headAccessory${upperFirst(key)}Text`);
option.class = `headAccessory_special_${option.key} ${category}`;
} }
option.click = () => { option.click = () => {
const type = this.user.preferences.costume ? 'costume' : 'equipped'; const type = this.user.preferences.costume ? 'costume' : 'equipped';

View File

@@ -5,6 +5,7 @@ import unlock from '@/../../common/script/ops/unlock';
import buy from '@/../../common/script/ops/buy/buy'; import buy from '@/../../common/script/ops/buy/buy';
import appearanceSets from '@/../../common/script/content/appearance/sets'; import appearanceSets from '@/../../common/script/content/appearance/sets';
import appearances from '@/../../common/script/content/appearance';
import { getScheduleMatchingGroup } from '@/../../common/script/content/constants/schedule'; import { getScheduleMatchingGroup } from '@/../../common/script/content/constants/schedule';
import { userStateMixin } from './userState'; import { userStateMixin } from './userState';
@@ -33,6 +34,9 @@ export const avatarEditorUtilities = { // eslint-disable-line import/prefer-defa
option.active = userPreference === key; option.active = userPreference === key;
option.class = this.createClass(type, subType, key); option.class = this.createClass(type, subType, key);
option.click = optionParam => (option.gemLocked ? this.unlock(`${optionParam.pathKey}.${key}`) : this.set({ [`preferences.${optionParam.pathKey}`]: optionParam.key })); option.click = optionParam => (option.gemLocked ? this.unlock(`${optionParam.pathKey}.${key}`) : this.set({ [`preferences.${optionParam.pathKey}`]: optionParam.key }));
option.text = subType ? appearances[type][subType][key].text()
: appearances[type][key].text();
return option; return option;
}, },
mapKeysToOption (key, type, subType, set) { mapKeysToOption (key, type, subType, set) {

View File

@@ -3,25 +3,35 @@
"2b43f6": "Blue", "2b43f6": "Blue",
"6bd049": "Green", "6bd049": "Green",
"800ed0": "Purple", "800ed0": "Purple",
"98461a": "Skin Tone 6",
"915533": "Skin Tone 1", "915533": "Skin Tone 1",
"98461a": "Skin Tone 6",
"allCustomizationsOwned": "You own all of these items. You can try them on by <a href=''>customizing your avatar</a>.",
"allEquipmentOwned": "You own all of these items. You can find them in your <a href='/inventory/equipment'>Equipment</a>. Be sure to check back later for next month's options!",
"aurora": "Aurora", "aurora": "Aurora",
"bear": "Bear", "bear": "Bear",
"black": "Black", "black": "Black",
"blond": "Blond", "blond": "Blond",
"blue": "Blue", "blue": "Blue",
"blueEarrings": "Blue Earrings",
"blueFlower": "Blue Flower",
"blunt": "Blunt",
"braid": "Braid", "braid": "Braid",
"broad": "Broad",
"brown": "Brown", "brown": "Brown",
"c06534": "Skin Tone 5", "c06534": "Skin Tone 5",
"c3e1dc": "Cyan", "c3e1dc": "Cyan",
"cactus": "Cactus", "cactus": "Cactus",
"candycane": "Candy Cane", "candycane": "Candy Cane",
"candycorn": "Candy Corn", "candycorn": "Candy Corn",
"checkNextMonth": "Be sure to check back later for next month's options!",
"checkNextSeason": "Be sure to check back later for next season's options!",
"clownfish": "Clownfish", "clownfish": "Clownfish",
"convict": "Referee", "convict": "Referee",
"cross": "Cross", "cross": "Cross",
"curly": "Curly",
"curlyLong": "Curly Long", "curlyLong": "Curly Long",
"curlyShort": "Curly Short", "curlyShort": "Curly Short",
"customizationsNPC": "Felicitus Fennec",
"d7a9f7": "Lavender", "d7a9f7": "Lavender",
"dapper": "Dapper", "dapper": "Dapper",
"ddc994": "Skin Tone 2", "ddc994": "Skin Tone 2",
@@ -43,18 +53,31 @@
"ghost": "Ghost", "ghost": "Ghost",
"ghostwhite": "Ghost White", "ghostwhite": "Ghost White",
"goatee": "Goatee", "goatee": "Goatee",
"goldEarringLeft": "Gold Earring Left",
"goldEarringRight": "Gold Earring Right",
"goldEarrings": "Gold Earrings",
"green": "Green", "green": "Green",
"greenEarrings": "Green Earrings",
"greenFlower": "Green Flower",
"halloween": "Halloween", "halloween": "Halloween",
"handleless_black": "Black Handleless",
"handleless_blue": "Blue Handleless",
"handleless_green": "Green Handleless",
"handleless_pink": "Pink Handleless",
"handleless_red": "Red Handleless",
"handleless_yellow": "Yellow Handleless",
"highPonytailLeft": "High Ponytail Left", "highPonytailLeft": "High Ponytail Left",
"highPonytailRight": "High Ponytail Right", "highPonytailRight": "High Ponytail Right",
"holly": "Holly", "holly": "Holly",
"hollygreen": "Holly Green", "hollygreen": "Holly Green",
"hoopEarrings": "Hoop Earrings",
"horizon": "Horizon", "horizon": "Horizon",
"largeMustache": "Large Mustache", "largeMustache": "Large Mustache",
"lava": "Lava", "lava": "Lava",
"leftBun": "Left Bun", "leftBun": "Left Bun",
"lion": "Lion", "lion": "Lion",
"longBeard": "Long Beard", "longBeard": "Long Beard",
"lookingForMore": "Looking for more?",
"merblue": "Merblue", "merblue": "Merblue",
"mergold": "Mergold", "mergold": "Mergold",
"mergreen": "Mergreen", "mergreen": "Mergreen",
@@ -63,8 +86,10 @@
"midnight": "Midnight", "midnight": "Midnight",
"mohawk": "Mohawk", "mohawk": "Mohawk",
"monster": "Monster", "monster": "Monster",
"noItemsOwned": "You don't own any of these items",
"ocean": "Ocean", "ocean": "Ocean",
"ogre": "Ogre", "ogre": "Ogre",
"orangeFlower": "Orange Flower",
"orchid": "Orchid", "orchid": "Orchid",
"panda": "Panda", "panda": "Panda",
"pastelBlue": "Pastel Blue", "pastelBlue": "Pastel Blue",
@@ -81,6 +106,9 @@
"pgreen": "Special Pastel Green", "pgreen": "Special Pastel Green",
"pgreen2": "Pastel Green", "pgreen2": "Pastel Green",
"pig": "Pig", "pig": "Pig",
"pink": "Pink",
"pinkEarrings": "Pink Earrings",
"pinkFlower": "Pink Flower",
"polar": "Polar", "polar": "Polar",
"ponytail": "Ponytail", "ponytail": "Ponytail",
"porange": "Special Pastel Orange", "porange": "Special Pastel Orange",
@@ -92,11 +120,14 @@
"pumpkin": "Pumpkin", "pumpkin": "Pumpkin",
"pumpkin2": "Jack O' Lantern", "pumpkin2": "Jack O' Lantern",
"purple": "Purple", "purple": "Purple",
"purpleEarrings": "Purple Earrings",
"purpleFlower": "Purple Flower",
"pyellow": "Special Pastel Yellow", "pyellow": "Special Pastel Yellow",
"pyellow2": "Pastel Yellow", "pyellow2": "Pastel Yellow",
"rainbow": "Rainbow", "rainbow": "Rainbow",
"red": "Red", "red": "Red",
"redblue": "Red and Blue", "redblue": "Red and Blue",
"redEarrings": "Red Earrings",
"reptile": "Reptile", "reptile": "Reptile",
"rightBun": "Right Bun", "rightBun": "Right Bun",
"sandnsea": "Sand 'n' Sea", "sandnsea": "Sand 'n' Sea",
@@ -105,8 +136,10 @@
"shadow2": "Shade", "shadow2": "Shade",
"shark": "Shark", "shark": "Shark",
"shortBeard": "Short Beard", "shortBeard": "Short Beard",
"sideswept": "Sideswept",
"skeleton": "Skeleton", "skeleton": "Skeleton",
"skeleton2": "Bones", "skeleton2": "Bones",
"slim": "Slim",
"smallMustache": "Small Mustache", "smallMustache": "Small Mustache",
"snowy": "Snowy", "snowy": "Snowy",
"straightLong": "Straight Long", "straightLong": "Straight Long",
@@ -121,21 +154,17 @@
"tropicalwater": "Tropical Water", "tropicalwater": "Tropical Water",
"TRUred": "Crimson", "TRUred": "Crimson",
"updo": "Updo", "updo": "Updo",
"visitCustomizationsShop": "Head over to the <a href='/shops/customizations'>Customizations Shop</a> to browse the many ways you can customize your avatar!",
"wavyLong": "Wavy Long", "wavyLong": "Wavy Long",
"wavyShort": "Wavy Short", "wavyShort": "Wavy Short",
"white": "White", "white": "White",
"whiteEarrings": "White Earrings",
"winternight": "Winter Night", "winternight": "Winter Night",
"winterstar": "Winter Star", "winterstar": "Winter Star",
"wispy": "Wispy",
"wolf": "Wolf", "wolf": "Wolf",
"yellow": "Yellow", "yellow": "Yellow",
"yellowFlower": "Yellow Flower",
"zombie": "Zombie", "zombie": "Zombie",
"zombie2": "Undead", "zombie2": "Undead"
"allCustomizationsOwned": "You own all of these items. You can try them on by <a href=''>customizing your avatar</a>.",
"checkNextMonth": "Be sure to check back later for next month's options!",
"checkNextSeason": "Be sure to check back later for next season's options!",
"noItemsOwned": "You don't own any of these items",
"visitCustomizationsShop": "Head over to the <a href='/shops/customizations'>Customizations Shop</a> to browse the many ways you can customize your avatar!",
"lookingForMore": "Looking for more?",
"allEquipmentOwned": "You own all of these items. You can find them in your <a href='/inventory/equipment'>Equipment</a>. Be sure to check back later for next month's options!",
"customizationsNPC": "Felicitus Fennec"
} }

View File

@@ -1,9 +1,10 @@
import prefill from '../prefill'; import prefill from '../prefill';
import t from '../../translation';
export default prefill({ export default prefill({
0: {}, 0: { text: t('none') },
1: {}, 1: { text: t('sideswept') },
2: {}, 2: { text: t('blunt') },
3: {}, 3: { text: t('wispy') },
4: {}, 4: { text: t('curly') },
}); });

View File

@@ -3,7 +3,7 @@ import sets from '../sets';
import t from '../../translation'; import t from '../../translation';
export default prefill({ export default prefill({
0: {}, 0: { text: t('none') },
1: { text: t('ponytail') }, 1: { text: t('ponytail') },
2: { text: t('doublePonytail'), price: 2, set: sets.baseHair1 }, 2: { text: t('doublePonytail'), price: 2, set: sets.baseHair1 },
3: { text: t('braid') }, 3: { text: t('braid') },

View File

@@ -3,7 +3,7 @@ import sets from '../sets';
import t from '../../translation'; import t from '../../translation';
export default prefill({ export default prefill({
0: {}, 0: { text: t('none') },
1: { text: t('goatee'), price: 2, set: sets.facialHair }, 1: { text: t('goatee'), price: 2, set: sets.facialHair },
2: { text: t('shortBeard'), price: 2, set: sets.facialHair }, 2: { text: t('shortBeard'), price: 2, set: sets.facialHair },
3: { text: t('longBeard'), price: 2, set: sets.facialHair }, 3: { text: t('longBeard'), price: 2, set: sets.facialHair },

View File

@@ -1,21 +1,22 @@
import prefill from '../prefill'; import prefill from '../prefill';
import t from '../../translation';
export default prefill({ export default prefill({
0: {}, 0: { text: t('none') },
1: {}, 1: { text: t('blueFlower') },
2: {}, 2: { text: t('greenFlower') },
3: {}, 3: { text: t('pinkFlower') },
4: {}, 4: { text: t('purpleFlower') },
5: {}, 5: { text: t('orangeFlower') },
6: {}, 6: { text: t('yellowFlower') },
7: {}, 7: { text: t('hoopEarrings') },
8: {}, 8: { text: t('goldEarringLeft') },
9: {}, 9: { text: t('goldEarringRight') },
10: {}, 10: { text: t('goldEarrings') },
11: {}, 11: { text: t('whiteEarrings') },
12: {}, 12: { text: t('blueEarrings') },
13: {}, 13: { text: t('greenEarrings') },
14: {}, 14: { text: t('redEarrings') },
15: {}, 15: { text: t('pinkEarrings') },
16: {}, 16: { text: t('purpleEarrings') },
}); });

View File

@@ -3,7 +3,7 @@ import sets from '../sets';
import t from '../../translation'; import t from '../../translation';
export default prefill({ export default prefill({
0: {}, 0: { text: t('none') },
1: { text: t('smallMustache'), price: 2, set: sets.facialHair }, 1: { text: t('smallMustache'), price: 2, set: sets.facialHair },
2: { text: t('largeMustache'), price: 2, set: sets.facialHair }, 2: { text: t('largeMustache'), price: 2, set: sets.facialHair },
}); });