Files
habitica/website/client/mixins/avatarEditUtilities.js
negue 5f2032a9d5 Style fixes: Onboarding (#11241)
* wip: createIntro / onboard ui rework

* extract more methods - working body settings component

* move justin above the dialog

* extract submenu + fix styles

* white background on items, working example of "none" item, item border radius

* extract options as component

* move more subMenu's to the component

* add chair margins

* move tasks to common/content

* add menu indicator

* extract more parts of onboarding-intro

* refactor / fully converted hair-settings

* extract extra-settings

* fix sprite positions / lint

* extract task-strings to be translatable

* style fixes - hide submenu's if not editing

* style / margin fixes

* more style fixes

* show hair styles at onboarding - use arrowleft/right as svg instead of image fix next color

* finish button style - full set background/purchase button

* fix footer - prev/next hover

* Add Default Tasks + `byHabitica` property

* customize-options click item on the full zone

* purple tasks

* footer animation => none

* fix onboarding task habit up/down

* onboarding circle color/position

* task styles

* fix onboarding position

* show seasonal options

* add hover to (locked-) options

* added the correct behavior of shop-items to onboarding options

* hide hover on active options
2019-09-26 12:43:47 +02:00

179 lines
5.2 KiB
JavaScript

import moment from 'moment';
import axios from 'axios';
import unlock from '../../common/script/ops/unlock';
import buy from '../../common/script/ops/buy/buy';
import get from 'lodash/get';
import appearanceSets from 'common/script/content/appearance/sets';
import {userStateMixin} from './userState';
export const avatarEditorUtilies = {
mixins: [userStateMixin],
data () {
return {
backgroundUpdate: new Date(),
};
},
methods: {
hideSet (set) {
return moment(appearanceSets[set.key].availableUntil).isBefore(moment());
},
mapKeysToFreeOption (key, type, subType) {
const userPreference = subType ? this.user.preferences[type][subType] : this.user.preferences[type];
const pathKey = subType ? `${type}.${subType}` : `${type}`;
const option = {};
option.key = key;
option.pathKey = pathKey;
option.active = userPreference === key;
option.class = this.createClass(type, subType, key);
option.click = (optionParam) => {
return option.gemLocked ? this.unlock(`${optionParam.pathKey}.${key}`) : this.set({[`preferences.${optionParam.pathKey}`]: optionParam.key});
};
return option;
},
mapKeysToOption (key, type, subType, set) {
const option = this.mapKeysToFreeOption(key, type, subType);
let userPurchased = subType ? this.user.purchased[type][subType] : this.user.purchased[type];
let locked = !userPurchased || !userPurchased[key];
let hide = false;
if (set && appearanceSets[set]) {
if (locked) hide = moment(appearanceSets[set].availableUntil).isBefore(moment());
}
option.gemLocked = locked;
option.hide = hide;
if (locked) {
option.gem = 2;
}
return option;
},
createClass (type, subType, key) {
let str = `${type} ${subType} `;
switch (type) {
case 'shirt': {
str += `${this.user.preferences.size}_shirt_${key}`;
break;
}
case 'size': {
str += `${key}_shirt_black`;
break;
}
case 'hair': {
if (subType === 'color') {
str += `hair_bangs_1_${key}`; // todo get current hair-bang setting
} else {
str += `hair_${subType}_${key}_${this.user.preferences.hair.color}`;
}
break;
}
case 'skin': {
str += `skin skin_${key}`;
break;
}
default: {
// `hair_base_${option.key}_${user.preferences.hair.color}`
// console.warn('unknown type', type, key);
}
}
return str;
},
userOwnsSet (type, setKeys, subType) {
let owns = true;
setKeys.forEach(key => {
if (subType) {
if (!this.user.purchased[type] || !this.user.purchased[type][subType] || !this.user.purchased[type][subType][key]) owns = false;
return;
}
if (!this.user.purchased[type][key]) owns = false;
});
return owns;
},
set (settings) {
this.$store.dispatch('user:set', settings);
},
equip (key, type) {
this.$store.dispatch('common:equip', {key, type});
},
/**
* For gem-unlockable preferences, (a) if owned, select preference (b) else, purchase
* @param path: User.preferences <-> User.purchased maps like User.preferences.skin=abc <-> User.purchased.skin.abc.
* Pass in this paramater as "skin.abc". Alternatively, pass as an array ["skin.abc", "skin.xyz"] to unlock sets
*/
async unlock (path) {
let fullSet = path.indexOf(',') !== -1;
let isBackground = path.indexOf('background.') !== -1;
let cost;
if (isBackground) {
cost = fullSet ? 3.75 : 1.75; // (Backgrounds) 15G per set, 7G per individual
} else {
cost = fullSet ? 1.25 : 0.5; // (Hair, skin, etc) 5G per set, 2G per individual
}
let loginIncentives = [
'background.blue',
'background.green',
'background.red',
'background.purple',
'background.yellow',
'background.violet',
];
if (loginIncentives.indexOf(path) === -1) {
if (fullSet) {
if (confirm(this.$t('purchaseFor', {cost: cost * 4})) !== true) return;
// @TODO: implement gem modal
// if (this.user.balance < cost) return $rootScope.openModal('buyGems');
} else if (!get(this.user, `purchased.${path}`)) {
if (confirm(this.$t('purchaseFor', {cost: cost * 4})) !== true) return;
// @TODO: implement gem modal
// if (this.user.balance < cost) return $rootScope.openModal('buyGems');
}
}
await axios.post(`/api/v4/user/unlock?path=${path}`);
try {
unlock(this.user, {
query: {
path,
},
});
this.backgroundUpdate = new Date();
} catch (e) {
alert(e.message);
}
},
async buy (item) {
const options = {
currency: 'gold',
key: item,
type: 'marketGear',
quantity: 1,
pinType: 'marketGear',
};
await axios.post(`/api/v4/user/buy/${item}`, options);
try {
buy(this.user, {
params: options,
});
this.backgroundUpdate = new Date();
} catch (e) {
alert(e.message);
}
},
},
};