mirror of
https://github.com/HabitRPG/habitica.git
synced 2025-12-15 21:57:22 +01:00
Sept 18 fixes (#9051)
* Added hover state to buy buttons * Translated profile * Fixed sending private message from member modal * Added payment functions * Added translation to home page * Fixed translation * Some front page styles * Fixed inbox sorting and searching * Added seasonals * Fixed buy gem modal conflict * Fixed paypal link * Fixed footer style crossover * Fixed quest update * Fixed sanity
This commit is contained in:
@@ -59,7 +59,7 @@ b-modal#avatar-modal(title="", size='lg', :hide-header='true', :hide-footer='tru
|
|||||||
.svg-icon.gem(v-html='icons.gem')
|
.svg-icon.gem(v-html='icons.gem')
|
||||||
span 2
|
span 2
|
||||||
.col-12.text-center
|
.col-12.text-center
|
||||||
button.btn.btn-secondary.purchase-all(v-if='!userOwnsSet("shirt", specialShirtKeys)', @click='unlock(`shirt.${specialShirtKeys.join(",shirt.")}`)') $t('purchaseAll')
|
button.btn.btn-secondary.purchase-all(v-if='!userOwnsSet("shirt", specialShirtKeys)', @click='unlock(`shirt.${specialShirtKeys.join(",shirt.")}`)') {{ $t('purchaseAll') }}
|
||||||
#skin.section.customize-section(v-if='activeTopPage === "skin"')
|
#skin.section.customize-section(v-if='activeTopPage === "skin"')
|
||||||
.row.sub-menu.col-6.offset-3.text-center
|
.row.sub-menu.col-6.offset-3.text-center
|
||||||
.col-6.offset-3.text-center.sub-menu-item(:class='{active: activeSubPage === "color"}')
|
.col-6.offset-3.text-center.sub-menu-item(:class='{active: activeSubPage === "color"}')
|
||||||
@@ -69,26 +69,17 @@ b-modal#avatar-modal(title="", size='lg', :hide-header='true', :hide-footer='tru
|
|||||||
.option(v-for='option in ["ddc994", "f5a76e", "ea8349", "c06534", "98461a", "915533", "c3e1dc", "6bd049"]',
|
.option(v-for='option in ["ddc994", "f5a76e", "ea8349", "c06534", "98461a", "915533", "c3e1dc", "6bd049"]',
|
||||||
:class='{active: user.preferences.skin === option}')
|
:class='{active: user.preferences.skin === option}')
|
||||||
.skin.sprite.customize-option(:class="`skin_${option}`", @click='set({"preferences.skin": option})')
|
.skin.sprite.customize-option(:class="`skin_${option}`", @click='set({"preferences.skin": option})')
|
||||||
.row(v-if='editing')
|
.row(v-if='editing && set.key !== "undefined"', v-for='set in seasonalSkins')
|
||||||
.col-12.customize-options
|
.col-12.customize-options
|
||||||
.option(v-for='option in rainbowSkins',
|
//h3(v-if='!hideSet(set)') {{$t(set.key)}}
|
||||||
:class='{active: option.active, locked: option.locked}')
|
.option(v-for='option in set.options',
|
||||||
|
:class='{active: option.active, locked: option.locked, hide: option.hide}')
|
||||||
.skin.sprite.customize-option(:class="`skin_${option.key}`", @click='option.click')
|
.skin.sprite.customize-option(:class="`skin_${option.key}`", @click='option.click')
|
||||||
.gem-lock(v-if='option.locked')
|
.gem-lock(v-if='option.locked')
|
||||||
.svg-icon.gem(v-html='icons.gem')
|
.svg-icon.gem(v-html='icons.gem')
|
||||||
span 2
|
span 2
|
||||||
.col-12.text-center
|
.col-12.text-center
|
||||||
button.btn.btn-secondary.purchase-all(v-if='!userOwnsSet("skin", rainbowSkinKeys)', @click='unlock(`skin.${rainbowSkinKeys.join(",skin.")}`)') $t('purchaseAll')
|
button.btn.btn-secondary.purchase-all(v-if='!hideSet(set) && !userOwnsSet("skin", set.keys)', @click='unlock(`skin.${set.keys.join(",skin.")}`)') {{ $t('purchaseAll') }}
|
||||||
.row(v-if='editing')
|
|
||||||
.col-12.customize-options
|
|
||||||
.option(v-for='option in animalSkins',
|
|
||||||
:class='{active: option.active, locked: option.locked}')
|
|
||||||
.skin.sprite.customize-option(:class="`skin_${option.key}`", @click='option.click')
|
|
||||||
.gem-lock(v-if='option.locked')
|
|
||||||
.svg-icon.gem(v-html='icons.gem')
|
|
||||||
span 2
|
|
||||||
.col-12.text-center
|
|
||||||
button.btn.btn-secondary.purchase-all(v-if='!userOwnsSet("skin", animalSkinKeys)', @click='unlock(`skin.${animalSkinKeys.join(",skin.")}`)') $t('purchaseAll')
|
|
||||||
#hair.section.customize-section(v-if='activeTopPage === "hair"')
|
#hair.section.customize-section(v-if='activeTopPage === "hair"')
|
||||||
.row.sub-menu.col-6.offset-3.text-center
|
.row.sub-menu.col-6.offset-3.text-center
|
||||||
.col-2.offset-1.text-center.sub-menu-item(@click='changeSubPage("color")', :class='{active: activeSubPage === "color"}')
|
.col-2.offset-1.text-center.sub-menu-item(@click='changeSubPage("color")', :class='{active: activeSubPage === "color"}')
|
||||||
@@ -101,20 +92,33 @@ b-modal#avatar-modal(title="", size='lg', :hide-header='true', :hide-footer='tru
|
|||||||
strong(v-once) {{$t('ponytail')}}
|
strong(v-once) {{$t('ponytail')}}
|
||||||
.col-2.text-center.sub-menu-item(@click='changeSubPage("facialhair")', :class='{active: activeSubPage === "facialhair"}', v-if='editing')
|
.col-2.text-center.sub-menu-item(@click='changeSubPage("facialhair")', :class='{active: activeSubPage === "facialhair"}', v-if='editing')
|
||||||
strong(v-once) {{$t('facialhair')}}
|
strong(v-once) {{$t('facialhair')}}
|
||||||
#hair-color.row(v-if='activeSubPage === "color"')
|
#hair-color.section.customize-section(v-if='activeSubPage === "color"')
|
||||||
.col-12.customize-options
|
.row
|
||||||
.option(v-for='option in ["white", "brown", "blond", "red", "black"]',
|
.col-12.customize-options
|
||||||
:class='{active: user.preferences.hair.color === option}')
|
.option(v-for='option in ["white", "brown", "blond", "red", "black"]',
|
||||||
.color-bangs.sprite.customize-option(:class="`hair_bangs_1_${option}`", @click='set({"preferences.hair.color": option})')
|
:class='{active: user.preferences.hair.color === option}')
|
||||||
.col-12.customize-options(v-if='editing')
|
.color-bangs.sprite.customize-option(:class="`hair_bangs_1_${option}`", @click='set({"preferences.hair.color": option})')
|
||||||
.option(v-for='option in premiumHairColors',
|
//.row(v-if='editing')
|
||||||
:class='{active: option.active === option, locked: option.locked}')
|
.col-12.customize-options(v-if='editing')
|
||||||
.color-bangs.sprite.customize-option(:class="`hair_bangs_1_${option.key}`", @click='option.click')
|
.option(v-for='option in premiumHairColors',
|
||||||
.gem-lock(v-if='option.locked')
|
:class='{active: option.active === option, locked: option.locked}')
|
||||||
.svg-icon.gem(v-html='icons.gem')
|
.color-bangs.sprite.customize-option(:class="`hair_bangs_1_${option.key}`", @click='option.click')
|
||||||
span 2
|
.gem-lock(v-if='option.locked')
|
||||||
.col-12.text-center
|
.svg-icon.gem(v-html='icons.gem')
|
||||||
button.btn.btn-secondary.purchase-all(v-if='!userOwnsSet("hair", premiumHairColorKeys, "color")', @click='unlock(`hair.color.${premiumHairColorKeys.join(",hair.color.")}`)') $t('purchaseAll')
|
span 2
|
||||||
|
.col-12.text-center
|
||||||
|
button.btn.btn-secondary.purchase-all(v-if='!userOwnsSet("hair", premiumHairColorKeys, "color")', @click='unlock(`hair.color.${premiumHairColorKeys.join(",hair.color.")}`)') {{ $t('purchaseAll') }}
|
||||||
|
.row(v-if='editing && set.key !== "undefined"', v-for='set in seasonalHairColors')
|
||||||
|
.col-12.customize-options
|
||||||
|
//h3(v-if='!hideSet(set)') {{set.text}}
|
||||||
|
.option(v-for='option in set.options',
|
||||||
|
:class='{active: option.active, locked: option.locked, hide: option.hide}')
|
||||||
|
.skin.sprite.customize-option(:class="`hair_bangs_1_${option.key}`", @click='option.click')
|
||||||
|
.gem-lock(v-if='option.locked')
|
||||||
|
.svg-icon.gem(v-html='icons.gem')
|
||||||
|
span 2
|
||||||
|
.col-12.text-center
|
||||||
|
button.btn.btn-secondary.purchase-all(v-if='!hideSet(set) && !userOwnsSet("hair", set.keys, "color")', @click='unlock(`hair.color.${set.keys.join(",hair.color.")}`)') {{ $t('purchaseAll') }}
|
||||||
#style.row(v-if='activeSubPage === "style"')
|
#style.row(v-if='activeSubPage === "style"')
|
||||||
.col-12.customize-options(v-if='editing')
|
.col-12.customize-options(v-if='editing')
|
||||||
.option(v-for='option in baseHair3',
|
.option(v-for='option in baseHair3',
|
||||||
@@ -124,7 +128,7 @@ b-modal#avatar-modal(title="", size='lg', :hide-header='true', :hide-footer='tru
|
|||||||
.svg-icon.gem(v-html='icons.gem')
|
.svg-icon.gem(v-html='icons.gem')
|
||||||
span 2
|
span 2
|
||||||
.col-12.text-center
|
.col-12.text-center
|
||||||
button.btn.btn-secondary.purchase-all(v-if='!userOwnsSet("hair", baseHair3Keys, "base")', @click='unlock(`hair.base.${baseHair3Keys.join(",hair.base.")}`)') $t('purchaseAll')
|
button.btn.btn-secondary.purchase-all(v-if='!userOwnsSet("hair", baseHair3Keys, "base")', @click='unlock(`hair.base.${baseHair3Keys.join(",hair.base.")}`)') {{ $t('purchaseAll') }}
|
||||||
.col-12.customize-options(v-if='editing')
|
.col-12.customize-options(v-if='editing')
|
||||||
.option(v-for='option in baseHair4',
|
.option(v-for='option in baseHair4',
|
||||||
:class='{active: option.active, locked: option.locked}')
|
:class='{active: option.active, locked: option.locked}')
|
||||||
@@ -133,7 +137,7 @@ b-modal#avatar-modal(title="", size='lg', :hide-header='true', :hide-footer='tru
|
|||||||
.svg-icon.gem(v-html='icons.gem')
|
.svg-icon.gem(v-html='icons.gem')
|
||||||
span 2
|
span 2
|
||||||
.col-12.text-center
|
.col-12.text-center
|
||||||
button.btn.btn-secondary.purchase-all(v-if='!userOwnsSet("hair", baseHair4Keys, "base")', @click='unlock(`hair.base.${baseHair4Keys.join(",hair.base.")}`)') $t('purchaseAll')
|
button.btn.btn-secondary.purchase-all(v-if='!userOwnsSet("hair", baseHair4Keys, "base")', @click='unlock(`hair.base.${baseHair4Keys.join(",hair.base.")}`)') {{ $t('purchaseAll') }}
|
||||||
#bangs.row(v-if='activeSubPage === "bangs"')
|
#bangs.row(v-if='activeSubPage === "bangs"')
|
||||||
.col-12.customize-options
|
.col-12.customize-options
|
||||||
.head_0.option(@click='set({"preferences.hair.bangs": 0})',
|
.head_0.option(@click='set({"preferences.hair.bangs": 0})',
|
||||||
@@ -155,7 +159,7 @@ b-modal#avatar-modal(title="", size='lg', :hide-header='true', :hide-footer='tru
|
|||||||
.svg-icon.gem(v-html='icons.gem')
|
.svg-icon.gem(v-html='icons.gem')
|
||||||
span 2
|
span 2
|
||||||
.col-12.text-center
|
.col-12.text-center
|
||||||
button.btn.btn-secondary.purchase-all(v-if='!userOwnsSet("hair", baseHair2Keys, "base")', @click='unlock(`hair.base.${baseHair2Keys.join(",hair.base.")}`)') $t('purchaseAll')
|
button.btn.btn-secondary.purchase-all(v-if='!userOwnsSet("hair", baseHair2Keys, "base")', @click='unlock(`hair.base.${baseHair2Keys.join(",hair.base.")}`)') {{ $t('purchaseAll') }}
|
||||||
#facialhair.row(v-if='activeSubPage === "facialhair"')
|
#facialhair.row(v-if='activeSubPage === "facialhair"')
|
||||||
.col-12.customize-options(v-if='editing')
|
.col-12.customize-options(v-if='editing')
|
||||||
.option(v-for='option in baseHair5',
|
.option(v-for='option in baseHair5',
|
||||||
@@ -165,7 +169,7 @@ b-modal#avatar-modal(title="", size='lg', :hide-header='true', :hide-footer='tru
|
|||||||
.svg-icon.gem(v-html='icons.gem')
|
.svg-icon.gem(v-html='icons.gem')
|
||||||
span 2
|
span 2
|
||||||
.col-12.text-center
|
.col-12.text-center
|
||||||
button.btn.btn-secondary.purchase-all(v-if='!userOwnsSet("hair", baseHair5Keys, "beard")', @click='unlock(`hair.beard.${baseHair5Keys.join(",hair.beard.")}`)') $t('purchaseAll')
|
button.btn.btn-secondary.purchase-all(v-if='!userOwnsSet("hair", baseHair5Keys, "beard")', @click='unlock(`hair.beard.${baseHair5Keys.join(",hair.beard.")}`)') {{ $t('purchaseAll') }}
|
||||||
.col-12.customize-options(v-if='editing')
|
.col-12.customize-options(v-if='editing')
|
||||||
.option(v-for='option in baseHair6',
|
.option(v-for='option in baseHair6',
|
||||||
:class='{active: option.active, locked: option.locked}')
|
:class='{active: option.active, locked: option.locked}')
|
||||||
@@ -174,7 +178,7 @@ b-modal#avatar-modal(title="", size='lg', :hide-header='true', :hide-footer='tru
|
|||||||
.svg-icon.gem(v-html='icons.gem')
|
.svg-icon.gem(v-html='icons.gem')
|
||||||
span 2
|
span 2
|
||||||
.col-12.text-center
|
.col-12.text-center
|
||||||
button.btn.btn-secondary.purchase-all(v-if='!userOwnsSet("hair", baseHair6Keys, "mustache")', @click='unlock(`hair.mustache.${baseHair6Keys.join(",hair.mustache.")}`)') $t('purchaseAll')
|
button.btn.btn-secondary.purchase-all(v-if='!userOwnsSet("hair", baseHair6Keys, "mustache")', @click='unlock(`hair.mustache.${baseHair6Keys.join(",hair.mustache.")}`)') {{ $t('purchaseAll') }}
|
||||||
#extra.section.container.customize-section(v-if='activeTopPage === "extra"')
|
#extra.section.container.customize-section(v-if='activeTopPage === "extra"')
|
||||||
.row.sub-menu.col-6.offset-3.text-center
|
.row.sub-menu.col-6.offset-3.text-center
|
||||||
.col-4.text-center.sub-menu-item(@click='changeSubPage("glasses")', :class='{active: activeSubPage === "glasses"}')
|
.col-4.text-center.sub-menu-item(@click='changeSubPage("glasses")', :class='{active: activeSubPage === "glasses"}')
|
||||||
@@ -200,7 +204,7 @@ b-modal#avatar-modal(title="", size='lg', :hide-header='true', :hide-footer='tru
|
|||||||
.svg-icon.gem(v-html='icons.gem')
|
.svg-icon.gem(v-html='icons.gem')
|
||||||
span 2
|
span 2
|
||||||
.col-12.text-center
|
.col-12.text-center
|
||||||
button.btn.btn-secondary.purchase-all(v-if='!animalEarsOwned', @click='unlock(animalEarsUnlockString)') $t('purchaseAll')
|
button.btn.btn-secondary.purchase-all(v-if='!animalEarsOwned', @click='unlock(animalEarsUnlockString)') {{ $t('purchaseAll') }}
|
||||||
#wheelchairs.row(v-if='activeSubPage === "wheelchair"')
|
#wheelchairs.row(v-if='activeSubPage === "wheelchair"')
|
||||||
.col-12.customize-options.weelchairs
|
.col-12.customize-options.weelchairs
|
||||||
.option(@click='set({"preferences.chair": "none"})', :class='{active: user.preferences.chair === "none"}')
|
.option(@click='set({"preferences.chair": "none"})', :class='{active: user.preferences.chair === "none"}')
|
||||||
@@ -508,6 +512,10 @@ b-modal#avatar-modal(title="", size='lg', :hide-header='true', :hide-footer='tru
|
|||||||
box-shadow: 0 2px 2px 0 rgba(26, 24, 29, 0.16), 0 1px 4px 0 rgba(26, 24, 29, 0.12);
|
box-shadow: 0 2px 2px 0 rgba(26, 24, 29, 0.16), 0 1px 4px 0 rgba(26, 24, 29, 0.12);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.option.hide {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
.customize-options .option {
|
.customize-options .option {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
vertical-align: bottom;
|
vertical-align: bottom;
|
||||||
@@ -756,14 +764,18 @@ b-modal#avatar-modal(title="", size='lg', :hide-header='true', :hide-footer='tru
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
|
import moment from 'moment';
|
||||||
import map from 'lodash/map';
|
import map from 'lodash/map';
|
||||||
import get from 'lodash/get';
|
import get from 'lodash/get';
|
||||||
|
import groupBy from 'lodash/groupBy';
|
||||||
import { mapState } from 'client/libs/store';
|
import { mapState } from 'client/libs/store';
|
||||||
import avatar from './avatar';
|
import avatar from './avatar';
|
||||||
import { getBackgroundShopSets } from '../../common/script/libs/shops';
|
import { getBackgroundShopSets } from '../../common/script/libs/shops';
|
||||||
import unlock from '../../common/script/ops/unlock';
|
import unlock from '../../common/script/ops/unlock';
|
||||||
import guide from 'client/mixins/guide';
|
import guide from 'client/mixins/guide';
|
||||||
import notifications from 'client/mixins/notifications';
|
import notifications from 'client/mixins/notifications';
|
||||||
|
import appearance from 'common/script/content/appearance';
|
||||||
|
import appearanceSets from 'common/script/content/appearance/sets';
|
||||||
|
|
||||||
import bModal from 'bootstrap-vue/lib/components/modal';
|
import bModal from 'bootstrap-vue/lib/components/modal';
|
||||||
|
|
||||||
@@ -777,6 +789,9 @@ import gem from 'assets/svg/gem.svg';
|
|||||||
import pin from 'assets/svg/pin.svg';
|
import pin from 'assets/svg/pin.svg';
|
||||||
import isPinned from 'common/script/libs/isPinned';
|
import isPinned from 'common/script/libs/isPinned';
|
||||||
|
|
||||||
|
const skinsBySet = groupBy(appearance.skin, 'set.key');
|
||||||
|
const hairColorBySet = groupBy(appearance.hair.color, 'set.key');
|
||||||
|
|
||||||
let tasksByCategory = {
|
let tasksByCategory = {
|
||||||
work: [
|
work: [
|
||||||
{
|
{
|
||||||
@@ -1029,6 +1044,70 @@ export default {
|
|||||||
});
|
});
|
||||||
return options;
|
return options;
|
||||||
},
|
},
|
||||||
|
seasonalSkins () {
|
||||||
|
// @TODO: For some resonse when I use $set on the user purchases object, this is not recomputed. Hack for now
|
||||||
|
let backgroundUpdate = this.backgroundUpdate; // eslint-disable-line
|
||||||
|
|
||||||
|
let seasonalSkins = [];
|
||||||
|
for (let key in skinsBySet) {
|
||||||
|
let set = skinsBySet[key];
|
||||||
|
|
||||||
|
let keys = set.map(item => {
|
||||||
|
return item.key;
|
||||||
|
});
|
||||||
|
|
||||||
|
let options = keys.map(optionKey => {
|
||||||
|
return this.mapKeysToOption(optionKey, 'skin', '', key);
|
||||||
|
});
|
||||||
|
|
||||||
|
let text = this.$t(key);
|
||||||
|
if (appearanceSets[key] && appearanceSets[key].text) {
|
||||||
|
text = appearanceSets[key].text();
|
||||||
|
}
|
||||||
|
|
||||||
|
let compiledSet = {
|
||||||
|
key,
|
||||||
|
options,
|
||||||
|
keys,
|
||||||
|
text,
|
||||||
|
};
|
||||||
|
seasonalSkins.push(compiledSet);
|
||||||
|
}
|
||||||
|
|
||||||
|
return seasonalSkins;
|
||||||
|
},
|
||||||
|
seasonalHairColors () {
|
||||||
|
// @TODO: For some resonse when I use $set on the user purchases object, this is not recomputed. Hack for now
|
||||||
|
let backgroundUpdate = this.backgroundUpdate; // eslint-disable-line
|
||||||
|
|
||||||
|
let seasonalHairColors = [];
|
||||||
|
for (let key in hairColorBySet) {
|
||||||
|
let set = hairColorBySet[key];
|
||||||
|
|
||||||
|
let keys = set.map(item => {
|
||||||
|
return item.key;
|
||||||
|
});
|
||||||
|
|
||||||
|
let options = keys.map(optionKey => {
|
||||||
|
return this.mapKeysToOption(optionKey, 'hair', 'color', key);
|
||||||
|
});
|
||||||
|
|
||||||
|
let text = this.$t(key);
|
||||||
|
if (appearanceSets[key] && appearanceSets[key].text) {
|
||||||
|
text = appearanceSets[key].text();
|
||||||
|
}
|
||||||
|
|
||||||
|
let compiledSet = {
|
||||||
|
key,
|
||||||
|
options,
|
||||||
|
keys,
|
||||||
|
text,
|
||||||
|
};
|
||||||
|
seasonalHairColors.push(compiledSet);
|
||||||
|
}
|
||||||
|
|
||||||
|
return seasonalHairColors;
|
||||||
|
},
|
||||||
premiumHairColors () {
|
premiumHairColors () {
|
||||||
// @TODO: For some resonse when I use $set on the user purchases object, this is not recomputed. Hack for now
|
// @TODO: For some resonse when I use $set on the user purchases object, this is not recomputed. Hack for now
|
||||||
let backgroundUpdate = this.backgroundUpdate; // eslint-disable-line
|
let backgroundUpdate = this.backgroundUpdate; // eslint-disable-line
|
||||||
@@ -1117,6 +1196,9 @@ export default {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
hideSet (set) {
|
||||||
|
return moment(appearanceSets[set.key].availableUntil).isBefore(moment());
|
||||||
|
},
|
||||||
purchase (type, key) {
|
purchase (type, key) {
|
||||||
this.$store.dispatch('shops:purchase', {
|
this.$store.dispatch('shops:purchase', {
|
||||||
type,
|
type,
|
||||||
@@ -1124,16 +1206,22 @@ export default {
|
|||||||
});
|
});
|
||||||
this.backgroundUpdate = new Date();
|
this.backgroundUpdate = new Date();
|
||||||
},
|
},
|
||||||
mapKeysToOption (key, type, subType) {
|
mapKeysToOption (key, type, subType, set) {
|
||||||
let userPreference = subType ? this.user.preferences[type][subType] : this.user.preferences[type];
|
let userPreference = subType ? this.user.preferences[type][subType] : this.user.preferences[type];
|
||||||
let userPurchased = subType ? this.user.purchased[type][subType] : this.user.purchased[type];
|
let userPurchased = subType ? this.user.purchased[type][subType] : this.user.purchased[type];
|
||||||
let locked = !userPurchased || !userPurchased[key];
|
let locked = !userPurchased || !userPurchased[key];
|
||||||
let pathKey = subType ? `${type}.${subType}` : `${type}`;
|
let pathKey = subType ? `${type}.${subType}` : `${type}`;
|
||||||
|
let hide = false;
|
||||||
|
|
||||||
|
if (set && appearanceSets[set]) {
|
||||||
|
if (locked) hide = moment(appearanceSets[set].availableUntil).isBefore(moment());
|
||||||
|
}
|
||||||
|
|
||||||
let option = {};
|
let option = {};
|
||||||
option.key = key;
|
option.key = key;
|
||||||
option.active = userPreference === key;
|
option.active = userPreference === key;
|
||||||
option.locked = locked;
|
option.locked = locked;
|
||||||
|
option.hide = hide;
|
||||||
option.click = () => {
|
option.click = () => {
|
||||||
return locked ? this.unlock(`${pathKey}.${key}`) : this.set({[`preferences.${pathKey}`]: key});
|
return locked ? this.unlock(`${pathKey}.${key}`) : this.set({[`preferences.${pathKey}`]: key});
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -234,7 +234,7 @@ export default {
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
sendMessage () {
|
sendMessage () {
|
||||||
this.userIdToMessage = this.user._id;
|
this.$store.state.userIdToMessage = this.user._id;
|
||||||
this.$root.$emit('show::modal', 'private-message');
|
this.$root.$emit('show::modal', 'private-message');
|
||||||
},
|
},
|
||||||
async getMembers () {
|
async getMembers () {
|
||||||
|
|||||||
@@ -170,7 +170,7 @@ export default {
|
|||||||
const response = await this.$store.dispatch('guilds:inviteToQuest', {groupId: this.group._id, key});
|
const response = await this.$store.dispatch('guilds:inviteToQuest', {groupId: this.group._id, key});
|
||||||
const quest = response.data.data;
|
const quest = response.data.data;
|
||||||
|
|
||||||
this.$store.party.data.quest = quest;
|
this.$store.state.party.data.quest = quest;
|
||||||
this.$root.$emit('hide::modal', 'start-quest-modal');
|
this.$root.$emit('hide::modal', 'start-quest-modal');
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -30,39 +30,39 @@
|
|||||||
.col
|
.col
|
||||||
+featureBullet("{{ $t('gemBenefit3') }}")
|
+featureBullet("{{ $t('gemBenefit3') }}")
|
||||||
+featureBullet("{{ $t('gemBenefit4') }}")
|
+featureBullet("{{ $t('gemBenefit4') }}")
|
||||||
.card-deck
|
.card-deck.gem-deck
|
||||||
.card.text-center
|
//.card.text-center(:class="{active: gemAmount === 4}")
|
||||||
.card-img-top
|
.card-img-top
|
||||||
.mx-auto(v-html='icons.fourGems', style='"height: 53px; width: 49.5px; margin-top: 2em;"')
|
.mx-auto(v-html='icons.fourGems', style='"height: 53px; width: 49.5px; margin-top: 2em;"')
|
||||||
.card-body
|
.card-body
|
||||||
.gem-count 4
|
.gem-count 4
|
||||||
.gem-text {{ $t('gems') }}
|
.gem-text {{ $t('gems') }}
|
||||||
.divider
|
.divider
|
||||||
button.btn.btn-primary $.99
|
button.btn.btn-primary(@click='gemAmount = 4') {{gemAmount === 4 ? $t('selected') : '$1.00'}}
|
||||||
.card.text-center
|
.card.text-center.col-3(:class="{active: gemAmount === 21}")
|
||||||
.card-img-top
|
.card-img-top
|
||||||
.mx-auto(v-html='icons.twentyOneGems', style='"height: 55px; width: 47.5px; margin-top: 1.85em;"')
|
.mx-auto(v-html='icons.twentyOneGems', style='"height: 55px; width: 47.5px; margin-top: 1.85em;"')
|
||||||
.card-body
|
.card-body
|
||||||
.gem-count 21
|
.gem-count 21
|
||||||
.gem-text {{ $t('gems') }}
|
.gem-text {{ $t('gems') }}
|
||||||
.divider
|
.divider
|
||||||
button.btn.btn-primary $4.99
|
button.btn.btn-primary(@click='gemAmount = 21') {{gemAmount === 21 ? $t('selected') : '$5.00'}}
|
||||||
.card.text-center
|
//.card.text-center(:class="{active: gemAmount === 42}")
|
||||||
.card-img-top
|
.card-img-top
|
||||||
.mx-auto(v-html='icons.fortyTwoGems', style='"height: 49.5px; width: 51px; margin-top: 1.9em;"')
|
.mx-auto(v-html='icons.fortyTwoGems', style='"height: 49.5px; width: 51px; margin-top: 1.9em;"')
|
||||||
.card-body
|
.card-body
|
||||||
.gem-count 42
|
.gem-count 42
|
||||||
.gem-text {{ $t('gems') }}
|
.gem-text {{ $t('gems') }}
|
||||||
.divider
|
.divider
|
||||||
button.btn.btn-primary $9.99
|
button.btn.btn-primary(@click='gemAmount = 42') {{gemAmount === 42 ? $t('selected') : '$10.00'}}
|
||||||
.card.text-center
|
//.card.text-center(:class="{active: gemAmount === 84}")
|
||||||
.card-img-top
|
.card-img-top
|
||||||
.mx-auto(v-html='icons.eightyFourGems', style='"height: 65px; width: 67px; margin-top: 1em;"')
|
.mx-auto(v-html='icons.eightyFourGems', style='"height: 65px; width: 67px; margin-top: 1em;"')
|
||||||
.card-body
|
.card-body
|
||||||
.gem-count 84
|
.gem-count 84
|
||||||
.gem-text {{ $t('gems') }}
|
.gem-text {{ $t('gems') }}
|
||||||
.divider
|
.divider
|
||||||
button.btn.btn-primary $19.99
|
button.btn.btn-primary(@click='gemAmount = 84') {{gemAmount === 84 ? $t('selected') : '$20.00'}}
|
||||||
.row.text-center
|
.row.text-center
|
||||||
h2.mx-auto.text-payment {{ $t('choosePaymentMethod') }}
|
h2.mx-auto.text-payment {{ $t('choosePaymentMethod') }}
|
||||||
.card-deck
|
.card-deck
|
||||||
@@ -100,63 +100,63 @@
|
|||||||
+featureBullet("{{ $t('subscriptionBenefit5') }}")
|
+featureBullet("{{ $t('subscriptionBenefit5') }}")
|
||||||
+featureBullet("{{ $t('subscriptionBenefit6') }}")
|
+featureBullet("{{ $t('subscriptionBenefit6') }}")
|
||||||
.card-deck
|
.card-deck
|
||||||
.card.text-center
|
.card.text-center(:class='{active: subscriptionPlan === "basic_earned"}')
|
||||||
.card-body
|
.card-body
|
||||||
.subscription-price
|
.subscription-price
|
||||||
span.superscript $
|
span.superscript $
|
||||||
span 4
|
span 5
|
||||||
span.superscript.muted .99
|
span.superscript.muted .00
|
||||||
.small {{ $t('everyMonth') }}
|
.small {{ $t('everyMonth') }}
|
||||||
.divider
|
.divider
|
||||||
p.benefits(v-markdown='$t("earnGemsMonthly", {cap:25})')
|
p.benefits(v-markdown='$t("earnGemsMonthly", {cap:25})')
|
||||||
.spacer
|
.spacer
|
||||||
button.btn.btn-primary {{ $t('select') }}
|
button.btn.btn-primary(@click='subscriptionPlan = "basic_earned"') {{ subscriptionPlan === "basic_earned" ? $t('select') : $t('selected') }}
|
||||||
.card.text-center
|
.card.text-center(:class='{active: subscriptionPlan === "basic_3mo"}')
|
||||||
.card-body
|
.card-body
|
||||||
.subscription-price
|
.subscription-price
|
||||||
span.superscript $
|
span.superscript $
|
||||||
span 14
|
span 15
|
||||||
span.superscript.muted .99
|
span.superscript.muted .00
|
||||||
.small {{ $t('everyXMonths', {interval: 3}) }}
|
.small {{ $t('everyXMonths', {interval: 3}) }}
|
||||||
.divider
|
.divider
|
||||||
p.benefits(v-markdown='$t("earnGemsMonthly", {cap:30})')
|
p.benefits(v-markdown='$t("earnGemsMonthly", {cap:30})')
|
||||||
p.benefits(v-markdown='$t("receiveMysticHourglass")')
|
p.benefits(v-markdown='$t("receiveMysticHourglass")')
|
||||||
button.btn.btn-primary {{ $t('select') }}
|
button.btn.btn-primary(@click='subscriptionPlan = "basic_3mo"') {{ subscriptionPlan === "basic_3mo" ? $t('select') : $t('selected') }}
|
||||||
.card.text-center
|
.card.text-center(:class='{active: subscriptionPlan === "basic_6mo"}')
|
||||||
.card-body
|
.card-body
|
||||||
.subscription-price
|
.subscription-price
|
||||||
span.superscript $
|
span.superscript $
|
||||||
span 29
|
span 30
|
||||||
span.superscript.muted .99
|
span.superscript.muted .00
|
||||||
.small {{ $t('everyXMonths', {interval: 6}) }}
|
.small {{ $t('everyXMonths', {interval: 6}) }}
|
||||||
.divider
|
.divider
|
||||||
p.benefits(v-markdown='$t("earnGemsMonthly", {cap:35})')
|
p.benefits(v-markdown='$t("earnGemsMonthly", {cap:35})')
|
||||||
p.benefits(v-markdown='$t("receiveMysticHourglasses", {amount:2})')
|
p.benefits(v-markdown='$t("receiveMysticHourglasses", {amount:2})')
|
||||||
button.btn.btn-primary {{ $t('select') }}
|
button.btn.btn-primary(@click='subscriptionPlan = "basic_6mo"') {{ subscriptionPlan === "basic_6mo" ? $t('select') : $t('selected') }}
|
||||||
.card.text-center
|
.card.text-center(:class='{active: subscriptionPlan === "basic_12mo"}')
|
||||||
.card-body
|
.card-body
|
||||||
.subscription-price
|
.subscription-price
|
||||||
span.superscript $
|
span.superscript $
|
||||||
span 47
|
span 48
|
||||||
span.superscript.muted .99
|
span.superscript.muted .00
|
||||||
.small {{ $t('everyYear') }}
|
.small {{ $t('everyYear') }}
|
||||||
.divider
|
.divider
|
||||||
p.benefits(v-markdown='$t("earnGemsMonthly", {cap:45})')
|
p.benefits(v-markdown='$t("earnGemsMonthly", {cap:45})')
|
||||||
p.benefits(v-markdown='$t("receiveMysticHourglasses", {amount:4})')
|
p.benefits(v-markdown='$t("receiveMysticHourglasses", {amount:4})')
|
||||||
button.btn.btn-primary {{ $t('select') }}
|
button.btn.btn-primary(@click='subscriptionPlan = "basic_12mo"') {{ subscriptionPlan === "basic_12mo" ? $t('select') : $t('selected') }}
|
||||||
.row.text-center
|
.row.text-center
|
||||||
h2.mx-auto.text-payment {{ $t('choosePaymentMethod') }}
|
h2.mx-auto.text-payment {{ $t('choosePaymentMethod') }}
|
||||||
.row.text-center
|
.row.text-center
|
||||||
a.mx-auto {{ $t('haveCouponCode') }}
|
a.mx-auto {{ $t('haveCouponCode') }}
|
||||||
.card-deck
|
.card-deck
|
||||||
.card.text-center.payment-method
|
.card.text-center.payment-method
|
||||||
.card-body(@click='showStripe({})')
|
.card-body(@click='showStripe({subscription: subscriptionPlan})')
|
||||||
.mx-auto(v-html='icons.creditCard', style='"height: 56px; width: 159px; margin-top: 1em;"')
|
.mx-auto(v-html='icons.creditCard', style='"height: 56px; width: 159px; margin-top: 1em;"')
|
||||||
.card.text-center.payment-method
|
.card.text-center.payment-method
|
||||||
a.card-body.paypal(:href='paypalCheckoutLink', target='_blank')
|
a.card-body.paypal(:href='paypalSubscriptionLink', target='_blank')
|
||||||
img(src='~assets/images/paypal.png')
|
img(src='~assets/images/paypal.png')
|
||||||
.card.text-center.payment-method
|
.card.text-center.payment-method
|
||||||
.card-body.amazon(@click="amazonPaymentsInit({type: 'single'})")
|
.card-body.amazon(@click="amazonPaymentsInit({type: 'subscription', subscription: subscriptionPlan})")
|
||||||
img(src='~assets/images/amazon-payments.png')
|
img(src='~assets/images/amazon-payments.png')
|
||||||
.row.text-center
|
.row.text-center
|
||||||
.svg-icon.mx-auto(v-html='icons.heart', style='"height: 24px; width: 24px;"')
|
.svg-icon.mx-auto(v-html='icons.heart', style='"height: 24px; width: 24px;"')
|
||||||
@@ -198,12 +198,24 @@
|
|||||||
border: solid 2px #e1e0e3;
|
border: solid 2px #e1e0e3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.gem-deck {
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
.card {
|
.card {
|
||||||
margin: 1em;
|
margin: 1em;
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
box-shadow: 0 2px 2px 0 rgba(26, 24, 29, 0.16), 0 1px 4px 0 rgba(26, 24, 29, 0.12);
|
box-shadow: 0 2px 2px 0 rgba(26, 24, 29, 0.16), 0 1px 4px 0 rgba(26, 24, 29, 0.12);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.card.active {
|
||||||
|
border-color: #24cc8f;
|
||||||
|
button {
|
||||||
|
background-color: #24cc8f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.divider {
|
.divider {
|
||||||
width: 80%;
|
width: 80%;
|
||||||
height: 1px;
|
height: 1px;
|
||||||
@@ -261,6 +273,10 @@
|
|||||||
background-color: #e1e0e3;
|
background-color: #e1e0e3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.payment-method:hover {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
.paypal {
|
.paypal {
|
||||||
padding-top: 1.3em;
|
padding-top: 1.3em;
|
||||||
}
|
}
|
||||||
@@ -369,6 +385,8 @@
|
|||||||
fortyTwoGems,
|
fortyTwoGems,
|
||||||
eightyFourGems,
|
eightyFourGems,
|
||||||
}),
|
}),
|
||||||
|
gemAmount: 0,
|
||||||
|
subscriptionPlan: '',
|
||||||
selectedPage: 'subscribe',
|
selectedPage: 'subscribe',
|
||||||
amazonPayments: {},
|
amazonPayments: {},
|
||||||
planGemLimits,
|
planGemLimits,
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ import notifications from 'client/mixins/notifications';
|
|||||||
|
|
||||||
export default {
|
export default {
|
||||||
mixins: [notifications],
|
mixins: [notifications],
|
||||||
props: ['userIdToMessage'],
|
|
||||||
components: {
|
components: {
|
||||||
bModal,
|
bModal,
|
||||||
},
|
},
|
||||||
@@ -29,8 +28,19 @@ export default {
|
|||||||
return {
|
return {
|
||||||
privateMessage: '',
|
privateMessage: '',
|
||||||
loading: false,
|
loading: false,
|
||||||
|
userIdToMessage: '',
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
computed: {
|
||||||
|
userIdToMessageStore () {
|
||||||
|
return this.$store.state.userIdToMessage;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
userIdToMessageStore () {
|
||||||
|
this.userIdToMessage = this.userIdToMessageStore;
|
||||||
|
},
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async sendPrivateMessage () {
|
async sendPrivateMessage () {
|
||||||
if (!this.privateMessage || !this.userIdToMessage) return;
|
if (!this.privateMessage || !this.userIdToMessage) return;
|
||||||
@@ -45,6 +55,8 @@ export default {
|
|||||||
this.loading = false;
|
this.loading = false;
|
||||||
|
|
||||||
this.text(this.$t('messageSentAlert'));
|
this.text(this.$t('messageSentAlert'));
|
||||||
|
|
||||||
|
this.privateMessage = '';
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -82,7 +82,7 @@
|
|||||||
a.purchase(:href='paypalPurchaseLink', :disabled='!subscription.key', target='_blank')
|
a.purchase(:href='paypalPurchaseLink', :disabled='!subscription.key', target='_blank')
|
||||||
img(src='https://www.paypalobjects.com/webstatic/en_US/i/buttons/pp-acceptance-small.png', :alt="$t('paypal')")
|
img(src='https://www.paypalobjects.com/webstatic/en_US/i/buttons/pp-acceptance-small.png', :alt="$t('paypal')")
|
||||||
.col-md-4
|
.col-md-4
|
||||||
a.purchase(@click="amazonPaymentsInit({type: 'subscription', subscription:subscription.key, coupon:subscription.coupon})")
|
a.btn.btn-secondary.purchase(@click="amazonPaymentsInit({type: 'subscription', subscription:subscription.key, coupon:subscription.coupon})")
|
||||||
img(src='https://payments.amazon.com/gp/cba/button', :alt="$t('amazonPayments')")
|
img(src='https://payments.amazon.com/gp/cba/button', :alt="$t('amazonPayments')")
|
||||||
|
|
||||||
.row
|
.row
|
||||||
@@ -153,12 +153,6 @@ export default {
|
|||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapState({user: 'user.data'}),
|
...mapState({user: 'user.data'}),
|
||||||
paypalPurchaseLink () {
|
|
||||||
let couponString = '';
|
|
||||||
if (this.subscription.coupon) couponString = `&coupon=${this.subscription.coupon}`;
|
|
||||||
return `/paypal/subscribe?_id=${this.user._id}&apiToken=${this.user.apiToken}&sub=${this.subscription.key}${couponString}`;
|
|
||||||
// @TODO don't put API Token in URL parameters
|
|
||||||
},
|
|
||||||
subscriptionBlocksOrdered () {
|
subscriptionBlocksOrdered () {
|
||||||
let subscriptions = filter(subscriptionBlocks, (o) => {
|
let subscriptions = filter(subscriptionBlocks, (o) => {
|
||||||
return o.discount !== true;
|
return o.discount !== true;
|
||||||
|
|||||||
@@ -9,10 +9,10 @@
|
|||||||
.row
|
.row
|
||||||
.col-6
|
.col-6
|
||||||
img(src='~assets/images/home/home-main@3x.png', width='357px')
|
img(src='~assets/images/home/home-main@3x.png', width='357px')
|
||||||
h1 Motivate yourself to achieve your goals.
|
h1 {{$t('motivateYourself')}}
|
||||||
p.section-main It's time to have fun when you get things done! Join over 2 million Habiticans and improve your life one task at a time.
|
p.section-main {{$t('timeToGetThingsDone')}}
|
||||||
.col-6
|
.col-6
|
||||||
h3.text-center Sign Up For Free
|
h3.text-center {{$t('singUpForFree')}}
|
||||||
div.text-center
|
div.text-center
|
||||||
button.social-button(@click='socialAuth("facebook")')
|
button.social-button(@click='socialAuth("facebook")')
|
||||||
.svg-icon.social-icon(v-html="icons.facebookIcon")
|
.svg-icon.social-icon(v-html="icons.facebookIcon")
|
||||||
@@ -21,14 +21,14 @@
|
|||||||
.svg-icon.social-icon(v-html="icons.googleIcon")
|
.svg-icon.social-icon(v-html="icons.googleIcon")
|
||||||
span {{$t('signUpWithSocial', {social: 'Google'})}}
|
span {{$t('signUpWithSocial', {social: 'Google'})}}
|
||||||
.strike
|
.strike
|
||||||
span OR
|
span {{$t('or')}}
|
||||||
.form
|
.form
|
||||||
input.form-control(type='text', placeholder='Login Name', v-model='username', :class='{"input-valid": username.length > 0}')
|
input.form-control(type='text', placeholder='Login Name', v-model='username', :class='{"input-valid": username.length > 0}')
|
||||||
input.form-control(type='email', placeholder='Email', v-model='email', :class='{"input-invalid": emailInvalid, "input-valid": emailValid}')
|
input.form-control(type='email', placeholder='Email', v-model='email', :class='{"input-invalid": emailInvalid, "input-valid": emailValid}')
|
||||||
input.form-control(type='password', placeholder='Password', v-model='password', :class='{"input-valid": password.length > 0}')
|
input.form-control(type='password', placeholder='Password', v-model='password', :class='{"input-valid": password.length > 0}')
|
||||||
input.form-control(type='password', placeholder='Confirm Password', v-model='passwordConfirm', :class='{"input-invalid": passwordConfirmInvalid, "input-valid": passwordConfirmValid}')
|
input.form-control(type='password', placeholder='Confirm Password', v-model='passwordConfirm', :class='{"input-invalid": passwordConfirmInvalid, "input-valid": passwordConfirmValid}')
|
||||||
p.form-text(v-once, v-html="$t('termsAndAgreement')")
|
p.form-text(v-once, v-html="$t('termsAndAgreement')")
|
||||||
button.sign-up(@click='register()') Sign Up
|
button.sign-up(@click='register()') {{$t('signup')}}
|
||||||
.col-12
|
.col-12
|
||||||
.spacer.svg-icon(v-html='icons.spacer')
|
.spacer.svg-icon(v-html='icons.spacer')
|
||||||
|
|
||||||
@@ -38,21 +38,21 @@
|
|||||||
.container
|
.container
|
||||||
.row
|
.row
|
||||||
.col-6.offset-3.text-center
|
.col-6.offset-3.text-center
|
||||||
h2 Gamify Your Life
|
h2 {{$t('gamifyYourLife')}}
|
||||||
p.section-main Habitica is a free habit-building and productivity app that treats your real life like a game. With in-game rewards and punishments to motivate you and a strong social network to inspire you, Habitica can help you achieve your goals to become healthy, hard-working, and happy.
|
p.section-main {{$t('aboutHabitica')}}
|
||||||
.row
|
.row
|
||||||
.col-4
|
.col-4
|
||||||
img.track-habits(src='~assets/images/home/track-habits@3x.png', width='354px', height='228px')
|
img.track-habits(src='~assets/images/home/track-habits@3x.png', width='354px', height='228px')
|
||||||
strong Track Your Habits and Goals
|
strong {{$t('trackYourGoals')}}
|
||||||
p Stay accountable by tracking and managing your Habits, Daily goals, and To-Do list with Habitica’s easy-to-use mobile apps and web interface.
|
p {{$t('trackYourGoalsDesc')}}
|
||||||
.col-4
|
.col-4
|
||||||
img(src='~assets/images/home/earn-rewards@3x.png', width='316px', height='244px')
|
img(src='~assets/images/home/earn-rewards@3x.png', width='316px', height='244px')
|
||||||
strong Earn Rewards for Your Goals
|
strong {{$t('earnRewards')}}
|
||||||
p Check off tasks to level up your Avatar and unlock in-game features such as battle armor, mysterious pets, magic skills, and even quests!
|
p {{$t('earnRewardsDesc')}}
|
||||||
.col-4
|
.col-4
|
||||||
img(src='~assets/images/home/battle-monsters@3x.png', width='303px', height='244px')
|
img(src='~assets/images/home/battle-monsters@3x.png', width='303px', height='244px')
|
||||||
strong Battle Monsters with Friends
|
strong {{$t('battleMonsters')}}
|
||||||
p Fight monsters with other Habiticans! Use the Gold that you earn to buy in-game or custom rewards, like watching an episode of your favorite TV show.
|
p {{$t('battleMonstersDesc')}}
|
||||||
.col-12
|
.col-12
|
||||||
.spacer.svg-icon(v-html='icons.spacer')
|
.spacer.svg-icon(v-html='icons.spacer')
|
||||||
|
|
||||||
@@ -60,20 +60,20 @@
|
|||||||
.container.text-center
|
.container.text-center
|
||||||
.row
|
.row
|
||||||
.col-12
|
.col-12
|
||||||
h2 Players Use Habitica to Improve
|
h2 {{$t('playersUseToImprove')}}
|
||||||
.row
|
.row
|
||||||
.col-4
|
.col-4
|
||||||
img(src='~assets/images/home/health-fitness@3x.png', width='300px', height='300px')
|
img(src='~assets/images/home/health-fitness@3x.png', width='300px', height='300px')
|
||||||
strong Health and Fitness
|
strong {{$t('healthAndFitness')}}
|
||||||
p Never motivated to floss? Can't seem to get to the gym? Habitica finally makes it fun to get healthy.
|
p {{$t('healthAndFitnessDesc')}}
|
||||||
.col-4
|
.col-4
|
||||||
img(src='~assets/images/home/school-work@3x.png', width='300px', height='300px')
|
img(src='~assets/images/home/school-work@3x.png', width='300px', height='300px')
|
||||||
strong School and Work
|
strong {{$t('schoolAndWork')}}
|
||||||
p Whether you're preparing a report for your teacher or your boss, it's easy to keep track of your progress as you tackle your toughest tasks.
|
p {{$t('schoolAndWorkDesc')}}
|
||||||
.col-4
|
.col-4
|
||||||
img(src='~assets/images/home/much-more@3x.png', width='300px', height='300px')
|
img(src='~assets/images/home/much-more@3x.png', width='300px', height='300px')
|
||||||
strong And much, much more!
|
strong {{$t('muchmuchMore')}}
|
||||||
p Our fully customizable task list means that you can shape Habitica to fit your personal goals. Work on creative projects, emphasize self-care, or pursue a different dream -- it's all up to you.
|
p {{$t('muchmuchMoreDesc')}}
|
||||||
.col-12
|
.col-12
|
||||||
.spacer.svg-icon(v-html='icons.spacer')
|
.spacer.svg-icon(v-html='icons.spacer')
|
||||||
.container-fluid
|
.container-fluid
|
||||||
@@ -85,8 +85,8 @@
|
|||||||
.col-6
|
.col-6
|
||||||
.iphones.svg-icon(v-html='icons.iphones')
|
.iphones.svg-icon(v-html='icons.iphones')
|
||||||
.col-6.text-column
|
.col-6.text-column
|
||||||
h2 Level Up Anywhere
|
h2 {{ $t('levelUpAnywhere') }}
|
||||||
p Our mobile apps make it simple to keep track of your tasks on-the-go. Accomplish your goals with a single tap, no matter where you are.
|
p {{ $t('levelUpAnywhereDesc') }}
|
||||||
a.app.svg-icon(v-html='icons.googlePlay', href='https://play.google.com/store/apps/details?id=com.habitrpg.android.habitica', target='_blank')
|
a.app.svg-icon(v-html='icons.googlePlay', href='https://play.google.com/store/apps/details?id=com.habitrpg.android.habitica', target='_blank')
|
||||||
a.app.svg-icon(v-html='icons.iosAppStore', href='https://itunes.apple.com/us/app/habitica-gamified-task-manager/id994882113?mt=8', target='_blank')
|
a.app.svg-icon(v-html='icons.iosAppStore', href='https://itunes.apple.com/us/app/habitica-gamified-task-manager/id994882113?mt=8', target='_blank')
|
||||||
.container-fluid
|
.container-fluid
|
||||||
@@ -95,13 +95,13 @@
|
|||||||
#call-to-action.purple-4
|
#call-to-action.purple-4
|
||||||
.container.featured
|
.container.featured
|
||||||
.row.text-center
|
.row.text-center
|
||||||
h3.col-12 Join over 2,000,000 people having fun while accomplishing their goals!
|
h3.col-12 {{ $t('joinMany') }}
|
||||||
.row
|
.row
|
||||||
.col-12.text-center
|
.col-12.text-center
|
||||||
button.btn.btn-primary.join-button(@click='playButtonClick()') Join Habitica Today
|
button.btn.btn-primary.join-button(@click='playButtonClick()') {{ $t('joinToday') }}
|
||||||
.row.featured
|
.row.featured
|
||||||
.col-12.text-center
|
.col-12.text-center
|
||||||
strong Featured in
|
strong {{ $t('featuredIn') }}
|
||||||
.container-fluid.featured
|
.container-fluid.featured
|
||||||
.row
|
.row
|
||||||
.col-12
|
.col-12
|
||||||
@@ -115,11 +115,6 @@
|
|||||||
img(src='https://d2afqr2xdmyzvu.cloudfront.net/front/images/presslogos/discover-logo.png', alt="$t(altAttrDiscover)")
|
img(src='https://d2afqr2xdmyzvu.cloudfront.net/front/images/presslogos/discover-logo.png', alt="$t(altAttrDiscover)")
|
||||||
.container-fluid
|
.container-fluid
|
||||||
.seamless_stars_varied_opacity_repeat
|
.seamless_stars_varied_opacity_repeat
|
||||||
|
|
||||||
#bottom-wrap.purple-4
|
|
||||||
#bottom-background
|
|
||||||
.seamless_mountains_demo_repeat
|
|
||||||
.midground_foreground_extended2
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
@@ -240,13 +235,19 @@
|
|||||||
.social-button {
|
.social-button {
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
border: solid 2px #bda8ff;
|
border: solid 2px #bda8ff;
|
||||||
width: 206px;
|
width: 48%;
|
||||||
height: 40px;
|
min-height: 40px;
|
||||||
|
padding: .5em;
|
||||||
background: transparent;
|
background: transparent;
|
||||||
margin-right: .5em;
|
margin-right: .5em;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.social-button:hover {
|
||||||
|
cursor: pointer;
|
||||||
|
border-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
.social-icon {
|
.social-icon {
|
||||||
margin-right: 1em;
|
margin-right: 1em;
|
||||||
width: 18px;
|
width: 18px;
|
||||||
@@ -290,17 +291,28 @@
|
|||||||
margin-left: 15px;
|
margin-left: 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.form {
|
||||||
|
padding-top: 1em;
|
||||||
|
padding-bottom: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
input {
|
input {
|
||||||
margin-bottom: 1em;
|
margin-bottom: 1em;
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
background-color: #432874;
|
background-color: #432874;
|
||||||
border-color: #432874;
|
border-color: #432874;
|
||||||
color: $purple-400;
|
color: $purple-400;
|
||||||
|
border: solid 2px transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
input:focus {
|
input:focus {
|
||||||
border: solid 2px #9a62ff;
|
border: solid 2px #9a62ff;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
|
background-color: #36205d;
|
||||||
|
}
|
||||||
|
|
||||||
|
input:hover {
|
||||||
|
background-color: #36205d;
|
||||||
}
|
}
|
||||||
|
|
||||||
button.sign-up {
|
button.sign-up {
|
||||||
@@ -469,33 +481,6 @@
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#bottom-wrap {
|
|
||||||
padding-top: 10em;
|
|
||||||
}
|
|
||||||
|
|
||||||
#bottom-background {
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
.seamless_mountains_demo_repeat {
|
|
||||||
background-image: url('~assets/images/auth/seamless_mountains_demo.png');
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
width: 100%;
|
|
||||||
height: 500px;
|
|
||||||
position: absolute;
|
|
||||||
z-index: 0;
|
|
||||||
bottom: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.midground_foreground_extended2 {
|
|
||||||
background-image: url('~assets/images/auth/midground_foreground_extended2.png');
|
|
||||||
position: relative;
|
|
||||||
width: 1500px;
|
|
||||||
max-width: 100%;
|
|
||||||
height: 150px;
|
|
||||||
margin: 0 auto;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|||||||
@@ -7,11 +7,20 @@
|
|||||||
|
|
||||||
#purple-footer
|
#purple-footer
|
||||||
app-footer
|
app-footer
|
||||||
|
|
||||||
|
#bottom-wrap.purple-4
|
||||||
|
#bottom-background
|
||||||
|
.seamless_mountains_demo_repeat
|
||||||
|
.midground_foreground_extended2
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang='scss'>
|
<style lang='scss'>
|
||||||
@import '~client/assets/scss/colors.scss';
|
@import '~client/assets/scss/colors.scss';
|
||||||
|
|
||||||
|
.purple-4 {
|
||||||
|
background-color: #271b3d;
|
||||||
|
}
|
||||||
|
|
||||||
#purple-footer {
|
#purple-footer {
|
||||||
background-color: #271b3d;
|
background-color: #271b3d;
|
||||||
|
|
||||||
@@ -34,6 +43,33 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#bottom-wrap {
|
||||||
|
padding-top: 10em;
|
||||||
|
}
|
||||||
|
|
||||||
|
#bottom-background {
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
.seamless_mountains_demo_repeat {
|
||||||
|
background-image: url('~assets/images/auth/seamless_mountains_demo.png');
|
||||||
|
background-repeat: repeat-x;
|
||||||
|
width: 100%;
|
||||||
|
height: 500px;
|
||||||
|
position: absolute;
|
||||||
|
z-index: 0;
|
||||||
|
bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.midground_foreground_extended2 {
|
||||||
|
background-image: url('~assets/images/auth/midground_foreground_extended2.png');
|
||||||
|
position: relative;
|
||||||
|
width: 1500px;
|
||||||
|
max-width: 100%;
|
||||||
|
height: 150px;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.static-wrapper {
|
.static-wrapper {
|
||||||
.container-fluid {
|
.container-fluid {
|
||||||
margin: 5em 2em 2em 2em;
|
margin: 5em 2em 2em 2em;
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
h4(v-once) {{$t('emptyMessagesLine1')}}
|
h4(v-once) {{$t('emptyMessagesLine1')}}
|
||||||
p(v-once) {{$t('emptyMessagesLine2')}}
|
p(v-once) {{$t('emptyMessagesLine2')}}
|
||||||
.conversations(v-if='filtersConversations.length > 0')
|
.conversations(v-if='filtersConversations.length > 0')
|
||||||
.conversation(v-for='conversation in conversations', @click='selectConversation(conversation.key)',
|
.conversation(v-for='conversation in filtersConversations', @click='selectConversation(conversation.key)',
|
||||||
:class="{active: selectedConversation === conversation.key}")
|
:class="{active: selectedConversation === conversation.key}")
|
||||||
div
|
div
|
||||||
span(:class="userLevelStyle(conversation)") {{conversation.name}}
|
span(:class="userLevelStyle(conversation)") {{conversation.name}}
|
||||||
@@ -213,6 +213,11 @@ export default {
|
|||||||
conversations[userId].date = message.timestamp;
|
conversations[userId].date = message.timestamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
conversations = sortBy(conversations, [(o) => {
|
||||||
|
return moment(o.date).toDate();
|
||||||
|
}]);
|
||||||
|
conversations = conversations.reverse();
|
||||||
|
|
||||||
return conversations;
|
return conversations;
|
||||||
},
|
},
|
||||||
currentMessages () {
|
currentMessages () {
|
||||||
@@ -220,7 +225,7 @@ export default {
|
|||||||
return this.conversations[this.selectedConversation].messages;
|
return this.conversations[this.selectedConversation].messages;
|
||||||
},
|
},
|
||||||
filtersConversations () {
|
filtersConversations () {
|
||||||
if (!this.search) return Object.values(this.conversations);
|
if (!this.search) return this.conversations;
|
||||||
return filter(this.conversations, (conversation) => {
|
return filter(this.conversations, (conversation) => {
|
||||||
return conversation.name.toLowerCase().indexOf(this.search.toLowerCase()) !== -1;
|
return conversation.name.toLowerCase().indexOf(this.search.toLowerCase()) !== -1;
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -20,46 +20,46 @@ div
|
|||||||
member-details(:member="user")
|
member-details(:member="user")
|
||||||
.row
|
.row
|
||||||
.col-6.offset-3.text-center.nav
|
.col-6.offset-3.text-center.nav
|
||||||
.nav-item(@click='selectedPage = "profile"', :class="{active: selectedPage === 'profile'}") Profile
|
.nav-item(@click='selectedPage = "profile"', :class="{active: selectedPage === 'profile'}") {{ $t('profile') }}
|
||||||
.nav-item(@click='selectedPage = "stats"', :class="{active: selectedPage === 'stats'}") Stats
|
.nav-item(@click='selectedPage = "stats"', :class="{active: selectedPage === 'stats'}") {{ $t('stats') }}
|
||||||
.nav-item(@click='selectedPage = "achievements"', :class="{active: selectedPage === 'achievements'}") Achievements
|
.nav-item(@click='selectedPage = "achievements"', :class="{active: selectedPage === 'achievements'}") {{ $t('achievements') }}
|
||||||
#userProfile.standard-page(v-show='selectedPage === "profile"', v-if='user.profile')
|
#userProfile.standard-page(v-show='selectedPage === "profile"', v-if='user.profile')
|
||||||
.row
|
.row
|
||||||
.col-8
|
.col-8
|
||||||
.header
|
.header
|
||||||
h1 {{user.profile.name}}
|
h1 {{user.profile.name}}
|
||||||
h4
|
h4
|
||||||
strong User Id:
|
strong {{ $t('userId') }}:
|
||||||
| {{user._id}}
|
| {{user._id}}
|
||||||
.col-4
|
.col-4
|
||||||
button.btn.btn-secondary(v-if='user._id === userLoggedIn._id', @click='editing = !editing') Edit
|
button.btn.btn-secondary(v-if='user._id === userLoggedIn._id', @click='editing = !editing') {{ $t('edit') }}
|
||||||
.row(v-if='!editing')
|
.row(v-if='!editing')
|
||||||
.col-8
|
.col-8
|
||||||
.about
|
.about
|
||||||
h2 About
|
h2 {{ $t('about') }}
|
||||||
p(v-markdown='user.profile.blurb')
|
p(v-markdown='user.profile.blurb')
|
||||||
.photo
|
.photo
|
||||||
h2 Photo
|
h2 {{ $t('photo') }}
|
||||||
img.img-rendering-auto(v-if='user.profile.imageUrl', :src='user.profile.imageUrl')
|
img.img-rendering-auto(v-if='user.profile.imageUrl', :src='user.profile.imageUrl')
|
||||||
|
|
||||||
.col-4
|
.col-4
|
||||||
.info
|
.info
|
||||||
h2 info
|
h2 {{ $t('info') }}
|
||||||
div
|
div
|
||||||
strong Joined:
|
strong {{ $t('joined') }}:
|
||||||
| {{user.auth.timestamps.created}}
|
| {{user.auth.timestamps.created}}
|
||||||
div
|
div
|
||||||
strong Total Log Ins:
|
strong {{ $t('totalLogins') }}:
|
||||||
span {{ $t('totalCheckins', {count: user.loginIncentives}) }}
|
span {{ $t('totalCheckins', {count: user.loginIncentives}) }}
|
||||||
div
|
div
|
||||||
| {{getProgressDisplay()}}
|
| {{getProgressDisplay()}}
|
||||||
.progress
|
.progress
|
||||||
.progress-bar(role='progressbar', :aria-valuenow='incentivesProgress', aria-valuemin='0', aria-valuemax='100', :style='{width: incentivesProgress + "%"}')
|
.progress-bar(role='progressbar', :aria-valuenow='incentivesProgress', aria-valuemin='0', aria-valuemax='100', :style='{width: incentivesProgress + "%"}')
|
||||||
span.sr-only {{ incentivesProgress }}% Complete
|
span.sr-only {{ incentivesProgress }}% {{$t('complete')}}
|
||||||
// @TODO: Implement in V2 .social
|
// @TODO: Implement in V2 .social
|
||||||
|
|
||||||
.row(v-if='editing')
|
.row(v-if='editing')
|
||||||
h1 Edit Profile
|
h1 {{$t('editProfile')}}
|
||||||
.col-12
|
.col-12
|
||||||
.alert.alert-info.alert-sm(v-html='$t("communityGuidelinesWarning", managerEmail)')
|
.alert.alert-info.alert-sm(v-html='$t("communityGuidelinesWarning", managerEmail)')
|
||||||
|
|
||||||
@@ -87,7 +87,6 @@ div
|
|||||||
.col-12.text-center
|
.col-12.text-center
|
||||||
button.btn.btn-primary(@click='save()') {{ $t("save") }}
|
button.btn.btn-primary(@click='save()') {{ $t("save") }}
|
||||||
button.btn.btn-warning(@click='editing = false') {{ $t("cancel") }}
|
button.btn.btn-warning(@click='editing = false') {{ $t("cancel") }}
|
||||||
|
|
||||||
#achievements.standard-page.container(v-show='selectedPage === "achievements"', v-if='user.achievements')
|
#achievements.standard-page.container(v-show='selectedPage === "achievements"', v-if='user.achievements')
|
||||||
.row(v-for='(category, key) in achievements')
|
.row(v-for='(category, key) in achievements')
|
||||||
h2.col-12.text-center {{ $t(key+'Achievs') }}
|
h2.col-12.text-center {{ $t(key+'Achievs') }}
|
||||||
@@ -107,94 +106,93 @@ div
|
|||||||
.row
|
.row
|
||||||
.col-6(v-if='user.achievements.challenges')
|
.col-6(v-if='user.achievements.challenges')
|
||||||
.achievement-icon.achievement-alien
|
.achievement-icon.achievement-alien
|
||||||
h2.text-center Challeges Won
|
h2.text-center {{$t('challengesWon')}}
|
||||||
div(v-for='chal in user.achievements.challenges')
|
div(v-for='chal in user.achievements.challenges')
|
||||||
span {{chal}}
|
span {{chal}}
|
||||||
hr
|
hr
|
||||||
.col-6(v-if='user.achievements.quests')
|
.col-6(v-if='user.achievements.quests')
|
||||||
.achievement-icon.achievement-karaoke
|
.achievement-icon.achievement-karaoke
|
||||||
h2.text-center Quests Completed
|
h2.text-center {{$t('questsCompleted')}}
|
||||||
div(v-for='(value, key) in user.achievements.quests')
|
div(v-for='(value, key) in user.achievements.quests')
|
||||||
span {{ content.quests[key].text() }}
|
span {{ content.quests[key].text() }}
|
||||||
span {{ value }}
|
span {{ value }}
|
||||||
|
|
||||||
#stats.standard-page(v-show='selectedPage === "stats"', v-if='user.preferences')
|
#stats.standard-page(v-show='selectedPage === "stats"', v-if='user.preferences')
|
||||||
.row
|
.row
|
||||||
.col-6
|
.col-6 {{$t('equipment')}}
|
||||||
h2.text-center Equipment
|
h2.text-center
|
||||||
.well
|
.well
|
||||||
.col-4.item-wrapper
|
.col-4.item-wrapper
|
||||||
.box(:class='{white: equippedItems.eyewear}')
|
.box(:class='{white: equippedItems.eyewear}')
|
||||||
div(:class="`shop_${equippedItems.eyewear}`")
|
div(:class="`shop_${equippedItems.eyewear}`")
|
||||||
h3 Eyewear
|
h3 {{$t('eyewear')}}
|
||||||
.col-4.item-wrapper
|
.col-4.item-wrapper
|
||||||
.box(:class='{white: equippedItems.head}')
|
.box(:class='{white: equippedItems.head}')
|
||||||
div(:class="`shop_${equippedItems.head}`")
|
div(:class="`shop_${equippedItems.head}`")
|
||||||
h3 Head Gear
|
h3 {{$t('headGear')}}
|
||||||
.col-4.item-wrapper
|
.col-4.item-wrapper
|
||||||
.box(:class='{white: equippedItems.headAccessory}')
|
.box(:class='{white: equippedItems.headAccessory}')
|
||||||
div(:class="`shop_${equippedItems.headAccessory}`")
|
div(:class="`shop_${equippedItems.headAccessory}`")
|
||||||
h3 Head Access.
|
h3 {{$t('headAccess')}}
|
||||||
.col-4.item-wrapper
|
.col-4.item-wrapper
|
||||||
.box(:class='{white: equippedItems.backAccessory}')
|
.box(:class='{white: equippedItems.backAccessory}')
|
||||||
div(:class="`shop_${equippedItems.backAccessory}`")
|
div(:class="`shop_${equippedItems.backAccessory}`")
|
||||||
h3 Back Access.
|
h3 {{$t('backAccess')}}
|
||||||
.col-4.item-wrapper
|
.col-4.item-wrapper
|
||||||
.box(:class='{white: equippedItems.armor}')
|
.box(:class='{white: equippedItems.armor}')
|
||||||
div(:class="`shop_${equippedItems.armor}`")
|
div(:class="`shop_${equippedItems.armor}`")
|
||||||
h3 Armor
|
h3 {{$t('armor')}}
|
||||||
.col-4.item-wrapper
|
.col-4.item-wrapper
|
||||||
.box(:class='{white: equippedItems.bodyAccessory}')
|
.box(:class='{white: equippedItems.bodyAccessory}')
|
||||||
div(:class="`shop_${equippedItems.bodyAccessory}`")
|
div(:class="`shop_${equippedItems.bodyAccessory}`")
|
||||||
h3 Body Access.
|
h3 {{$t('bodyAccess')}}
|
||||||
.col-4.item-wrapper
|
.col-4.item-wrapper
|
||||||
.box(:class='{white: equippedItems.weapon}')
|
.box(:class='{white: equippedItems.weapon}')
|
||||||
div(:class="`shop_${equippedItems.weapon}`")
|
div(:class="`shop_${equippedItems.weapon}`")
|
||||||
h3 Main-Hand
|
h3 {{$t('mainHand')}}
|
||||||
.col-4.item-wrapper
|
.col-4.item-wrapper
|
||||||
.col-4.item-wrapper
|
.col-4.item-wrapper
|
||||||
.box(:class='{white: equippedItems.shield}')
|
.box(:class='{white: equippedItems.shield}')
|
||||||
div(:class="`shop_${equippedItems.shield}`")
|
div(:class="`shop_${equippedItems.shield}`")
|
||||||
h3 Off-Hand
|
h3 {{$t('offHand')}}
|
||||||
.col-6
|
.col-6
|
||||||
h2.text-center Costume
|
h2.text-center {{$t('costume')}}
|
||||||
.well
|
.well
|
||||||
.col-4.item-wrapper
|
.col-4.item-wrapper
|
||||||
.box(:class='{white: costumeItems.eyewear}')
|
.box(:class='{white: costumeItems.eyewear}')
|
||||||
div(:class="`shop_${costumeItems.eyewear}`")
|
div(:class="`shop_${costumeItems.eyewear}`")
|
||||||
h3 Eyewear
|
h3 {{$t('eyewear')}}
|
||||||
.col-4.item-wrapper
|
.col-4.item-wrapper
|
||||||
.box(:class='{white: costumeItems.head}')
|
.box(:class='{white: costumeItems.head}')
|
||||||
div(:class="`shop_${costumeItems.head}`")
|
div(:class="`shop_${costumeItems.head}`")
|
||||||
h3 Head Gear
|
h3 {{$t('headGear')}}
|
||||||
.col-4.item-wrapper
|
.col-4.item-wrapper
|
||||||
.box(:class='{white: costumeItems.headAccessory}')
|
.box(:class='{white: costumeItems.headAccessory}')
|
||||||
div(:class="`shop_${costumeItems.headAccessory}`")
|
div(:class="`shop_${costumeItems.headAccessory}`")
|
||||||
h3 Head Access.
|
h3 {{$t('headAccess')}}
|
||||||
.col-4.item-wrapper
|
.col-4.item-wrapper
|
||||||
.box(:class='{white: costumeItems.backAccessory}')
|
.box(:class='{white: costumeItems.backAccessory}')
|
||||||
div(:class="`shop_${costumeItems.backAccessory}`")
|
div(:class="`shop_${costumeItems.backAccessory}`")
|
||||||
h3 Back Access.
|
h3 {{$t('backAccess')}}
|
||||||
.col-4.item-wrapper
|
.col-4.item-wrapper
|
||||||
.box(:class='{white: costumeItems.armor}')
|
.box(:class='{white: costumeItems.armor}')
|
||||||
div(:class="`shop_${costumeItems.armor}`")
|
div(:class="`shop_${costumeItems.armor}`")
|
||||||
h3 Armor
|
h3 {{$t('armor')}}
|
||||||
.col-4.item-wrapper
|
.col-4.item-wrapper
|
||||||
.box(:class='{white: costumeItems.bodyAccessory}')
|
.box(:class='{white: costumeItems.bodyAccessory}')
|
||||||
div(:class="`shop_${costumeItems.bodyAccessory}`")
|
div(:class="`shop_${costumeItems.bodyAccessory}`")
|
||||||
h3 Body Access.
|
h3 {{$t('bodyAccess')}}
|
||||||
.col-4.item-wrapper
|
.col-4.item-wrapper
|
||||||
.box(:class='{white: costumeItems.weapon}')
|
.box(:class='{white: costumeItems.weapon}')
|
||||||
div(:class="`shop_${costumeItems.weapon}`")
|
div(:class="`shop_${costumeItems.weapon}`")
|
||||||
h3 Main-Hand
|
h3 {{$t('mainHand')}}
|
||||||
.col-4.item-wrapper
|
.col-4.item-wrapper
|
||||||
.box(:class='{white: user.preferences.background}')
|
.box(:class='{white: user.preferences.background}')
|
||||||
div(:class="user.preferences.background")
|
div(:class="user.preferences.background")
|
||||||
h3 Background
|
h3 {{$t('background')}}
|
||||||
.col-4.item-wrapper
|
.col-4.item-wrapper
|
||||||
.box(:class='{white: costumeItems.shield}')
|
.box(:class='{white: costumeItems.shield}')
|
||||||
div(:class="`shop_${costumeItems.shield}`")
|
div(:class="`shop_${costumeItems.shield}`")
|
||||||
h3 Off-Hand
|
h3 {{$t('offHand')}}
|
||||||
.row.pet-mount-row
|
.row.pet-mount-row
|
||||||
.col-6
|
.col-6
|
||||||
h2.text-center(v-once) {{ $t('pets') }}
|
h2.text-center(v-once) {{ $t('pets') }}
|
||||||
@@ -230,7 +228,7 @@ div
|
|||||||
span {{ mountMasterProgress(user.items.mounts) }}
|
span {{ mountMasterProgress(user.items.mounts) }}
|
||||||
#attributes.row
|
#attributes.row
|
||||||
hr.col-12
|
hr.col-12
|
||||||
h2.col-12 Attributes
|
h2.col-12 {{$t('attributes')}}
|
||||||
.col-6(v-for="(statInfo, stat) in stats")
|
.col-6(v-for="(statInfo, stat) in stats")
|
||||||
.row.col-12.stats-column
|
.row.col-12.stats-column
|
||||||
.col-4.attribute-label
|
.col-4.attribute-label
|
||||||
@@ -241,31 +239,33 @@ div
|
|||||||
.col-6
|
.col-6
|
||||||
ul.bonus-stats
|
ul.bonus-stats
|
||||||
li
|
li
|
||||||
strong Level:
|
strong {{$t('level')}}:
|
||||||
| {{statsComputed.levelBonus[stat]}}
|
| {{statsComputed.levelBonus[stat]}}
|
||||||
li
|
li
|
||||||
strong Equipment:
|
strong {{$t('equipment')}}:
|
||||||
| {{statsComputed.gearBonus[stat]}}
|
| {{statsComputed.gearBonus[stat]}}
|
||||||
li
|
li
|
||||||
strong Class:
|
strong {{$t('class')}}:
|
||||||
| {{statsComputed.classBonus[stat]}}
|
| {{statsComputed.classBonus[stat]}}
|
||||||
li
|
li
|
||||||
strong Allocated:
|
strong {{$t('allocated')}}:
|
||||||
| {{user.stats[stat]}}
|
| {{user.stats[stat]}}
|
||||||
li
|
li
|
||||||
strong Buffs:
|
strong {{$t('buffs')}}:
|
||||||
| {{user.stats.buffs[stat]}}
|
| {{user.stats.buffs[stat]}}
|
||||||
#allocation(v-if='user._id === userLoggedIn._id')
|
#allocation(v-if='user._id === userLoggedIn._id')
|
||||||
.row.title-row
|
.row.title-row
|
||||||
.col-6
|
.col-6
|
||||||
h3(v-if='userLevel100Plus', v-once, v-html="$t('noMoreAllocate')")
|
h3(v-if='userLevel100Plus', v-once, v-html="$t('noMoreAllocate')")
|
||||||
h3(v-if='user.stats.points || userLevel100Plus')
|
h3(v-if='user.stats.points || userLevel100Plus')
|
||||||
| Points Available
|
| {{$t('pointsAvailable')}}
|
||||||
.counter.badge(v-if='user.stats.points || userLevel100Plus')
|
.counter.badge(v-if='user.stats.points || userLevel100Plus')
|
||||||
| {{user.stats.points}}
|
| {{user.stats.points}}
|
||||||
.col-6
|
.col-6
|
||||||
.float-right
|
.float-right
|
||||||
toggle-switch(:label="$t('autoAllocation')", v-model='user.preferences.automaticAllocation', @change='userset({"preferences.automaticAllocation": Boolean(user.preferences.automaticAllocation), "preferences.allocationMode": "taskbased"})')
|
toggle-switch(:label="$t('autoAllocation')",
|
||||||
|
v-model='user.preferences.automaticAllocation',
|
||||||
|
@change='userset({"preferences.automaticAllocation": Boolean(user.preferences.automaticAllocation), "preferences.allocationMode": "taskbased"})')
|
||||||
|
|
||||||
.row
|
.row
|
||||||
.col-3(v-for='(statInfo, stat) in allocateStatsList')
|
.col-3(v-for='(statInfo, stat) in allocateStatsList')
|
||||||
@@ -273,10 +273,10 @@ div
|
|||||||
.col-12
|
.col-12
|
||||||
div(:class='stat') {{ $t(stats[stat].title) }}
|
div(:class='stat') {{ $t(stats[stat].title) }}
|
||||||
.number {{ user.stats[stat] }}
|
.number {{ user.stats[stat] }}
|
||||||
.points pts
|
.points {{$t('pts')}}
|
||||||
.col-4
|
.col-4
|
||||||
.up(v-if='user.stats.points', @click='allocate(stat)')
|
.up(v-if='user.stats.points', @click='allocate(stat)')
|
||||||
private-message-modal(:userIdToMessage='userIdToMessage')
|
private-message-modal
|
||||||
send-gems-modal(:userReceivingGems='userReceivingGems')
|
send-gems-modal(:userReceivingGems='userReceivingGems')
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -686,7 +686,7 @@ export default {
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
sendMessage () {
|
sendMessage () {
|
||||||
this.userIdToMessage = this.user._id;
|
this.$store.state.userIdToMessage = this.user._id;
|
||||||
this.$root.$emit('show::modal', 'private-message');
|
this.$root.$emit('show::modal', 'private-message');
|
||||||
},
|
},
|
||||||
getProgressDisplay () {
|
getProgressDisplay () {
|
||||||
|
|||||||
@@ -2,8 +2,10 @@ import axios from 'axios';
|
|||||||
|
|
||||||
let AUTH_SETTINGS = localStorage.getItem('habit-mobile-settings');
|
let AUTH_SETTINGS = localStorage.getItem('habit-mobile-settings');
|
||||||
let API_TOKEN = '';
|
let API_TOKEN = '';
|
||||||
|
let API_ID = '';
|
||||||
if (AUTH_SETTINGS) {
|
if (AUTH_SETTINGS) {
|
||||||
AUTH_SETTINGS = JSON.parse(AUTH_SETTINGS);
|
AUTH_SETTINGS = JSON.parse(AUTH_SETTINGS);
|
||||||
|
API_ID = AUTH_SETTINGS.auth.apiId;
|
||||||
API_TOKEN = AUTH_SETTINGS.auth.apiToken;
|
API_TOKEN = AUTH_SETTINGS.auth.apiToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -15,7 +17,16 @@ let StripeCheckout = window.StripeCheckout;
|
|||||||
export default {
|
export default {
|
||||||
computed: {
|
computed: {
|
||||||
paypalCheckoutLink () {
|
paypalCheckoutLink () {
|
||||||
return `/paypal/checkout?_id=${this.user._id}&apiToken=${API_TOKEN}`;
|
return `/paypal/checkout?_id=${API_ID}&apiToken=${API_TOKEN}`;
|
||||||
|
},
|
||||||
|
paypalSubscriptionLink () {
|
||||||
|
return `/paypal/subscribe?_id=${API_ID}&apiToken=${API_TOKEN}&sub=${this.subscriptionPlan}`;
|
||||||
|
},
|
||||||
|
paypalPurchaseLink () {
|
||||||
|
if (!this.subscription) return '';
|
||||||
|
let couponString = '';
|
||||||
|
if (this.subscription.coupon) couponString = `&coupon=${this.subscription.coupon}`;
|
||||||
|
return `/paypal/subscribe?_id=${API_ID}&apiToken=${API_TOKEN}&sub=${this.subscription.key}${couponString}`;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
|||||||
@@ -122,6 +122,7 @@ export default function () {
|
|||||||
notificationStore: [],
|
notificationStore: [],
|
||||||
modalStack: [],
|
modalStack: [],
|
||||||
afterLoginRedirect: '',
|
afterLoginRedirect: '',
|
||||||
|
userIdToMessage: '',
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -199,5 +199,25 @@
|
|||||||
"invalidAttribute": "\"<%= attr %>\" is not a valid attribute.",
|
"invalidAttribute": "\"<%= attr %>\" is not a valid attribute.",
|
||||||
"notEnoughAttrPoints": "You don't have enough attribute points.",
|
"notEnoughAttrPoints": "You don't have enough attribute points.",
|
||||||
"style": "Style",
|
"style": "Style",
|
||||||
"facialhair": "Facial"
|
"facialhair": "Facial",
|
||||||
|
"photo": "Photo",
|
||||||
|
"info": "Info",
|
||||||
|
"joined": "Joined",
|
||||||
|
"totalLogins": "Total Log Ins",
|
||||||
|
"editProfile": "Edit Profile",
|
||||||
|
"challengesWon": "Challeges Won",
|
||||||
|
"questsCompleted": "Quests Completed",
|
||||||
|
"equipment": "Equipment",
|
||||||
|
"costume": "Costume",
|
||||||
|
"headGear": "Head Gear",
|
||||||
|
"headAccess": "Head Access.",
|
||||||
|
"backAccess": "Back Access.",
|
||||||
|
"bodyAccess": "Body Access.",
|
||||||
|
"mainHand": "Main-Hand",
|
||||||
|
"offHand": "Off-Hand",
|
||||||
|
"level": "Level",
|
||||||
|
"allocated": "Allocated",
|
||||||
|
"buffs": "Buffs",
|
||||||
|
"pointsAvailable": "Points Available",
|
||||||
|
"pts": "pts"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -282,5 +282,30 @@
|
|||||||
"confirmPasswordPlaceholder": "Make sure it's the same password!",
|
"confirmPasswordPlaceholder": "Make sure it's the same password!",
|
||||||
"joinHabitica": "Join Habitica",
|
"joinHabitica": "Join Habitica",
|
||||||
"alreadyHaveAccountLogin": "Already have a Habitica account? <strong>Log in.</strong>",
|
"alreadyHaveAccountLogin": "Already have a Habitica account? <strong>Log in.</strong>",
|
||||||
"dontHaveAccountSignup": "Don’t have a Habitica account? <strong>Sign up.</strong>"
|
"dontHaveAccountSignup": "Don’t have a Habitica account? <strong>Sign up.</strong>",
|
||||||
|
"motivateYourself": "Motivate yourself to achieve your goals.",
|
||||||
|
"timeToGetThingsDone": "It's time to have fun when you get things done! Join over 2 million Habiticans and improve your life one task at a time.",
|
||||||
|
"singUpForFree": "Sign Up For Free",
|
||||||
|
"or": "OR",
|
||||||
|
"gamifyYourLife": "Gamify Your Life",
|
||||||
|
"aboutHabitica": "Habitica is a free habit-building and productivity app that treats your real life like a game. With in-game rewards and punishments to motivate you and a strong social network to inspire you, Habitica can help you achieve your goals to become healthy, hard-working, and happy.",
|
||||||
|
"trackYourGoals": "Track Your Habits and Goals",
|
||||||
|
"trackYourGoalsDesc": "Stay accountable by tracking and managing your Habits, Daily goals, and To-Do list with Habitica’s easy-to-use mobile apps and web interface.",
|
||||||
|
"earnRewards": "Earn Rewards for Your Goals",
|
||||||
|
"earnRewardsDesc": "Check off tasks to level up your Avatar and unlock in-game features such as battle armor, mysterious pets, magic skills, and even quests!",
|
||||||
|
"battleMonsters": "Battle Monsters with Friends",
|
||||||
|
"battleMonstersDesc": "Fight monsters with other Habiticans! Use the Gold that you earn to buy in-game or custom rewards, like watching an episode of your favorite TV show.",
|
||||||
|
"playersUseToImprove": "Players Use Habitica to Improve",
|
||||||
|
"healthAndFitness": "Health and Fitness",
|
||||||
|
"healthAndFitnessDesc": "Never motivated to floss? Can't seem to get to the gym? Habitica finally makes it fun to get healthy.",
|
||||||
|
"schoolAndWork": "School and Work",
|
||||||
|
"schoolAndWorkDesc": "Whether you're preparing a report for your teacher or your boss, it's easy to keep track of your progress as you tackle your toughest tasks.",
|
||||||
|
"muchmuchMore": "And much, much more!",
|
||||||
|
"muchmuchMoreDesc": "Our fully customizable task list means that you can shape Habitica to fit your personal goals. Work on creative projects, emphasize self-care, or pursue a different dream -- it's all up to you.",
|
||||||
|
"levelUpAnywhere": "Level Up Anywhere",
|
||||||
|
"levelUpAnywhereDesc": "Our mobile apps make it simple to keep track of your tasks on-the-go. Accomplish your goals with a single tap, no matter where you are.",
|
||||||
|
"joinMany": "Join over 2,000,000 people having fun while accomplishing their goals!",
|
||||||
|
"joinToday": "Join Habitica Today",
|
||||||
|
"featuredIn": "Featured in",
|
||||||
|
"signup": "Sign Up"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -68,7 +68,6 @@
|
|||||||
"subscriberItemText": "Each month, subscribers will receive a mystery item. This is usually released about one week before the end of the month. See the wiki's 'Mystery Item' page for more information.",
|
"subscriberItemText": "Each month, subscribers will receive a mystery item. This is usually released about one week before the end of the month. See the wiki's 'Mystery Item' page for more information.",
|
||||||
"all": "All",
|
"all": "All",
|
||||||
"none": "None",
|
"none": "None",
|
||||||
"or": "Or",
|
|
||||||
"and": "and",
|
"and": "and",
|
||||||
"loginSuccess": "Login successful!",
|
"loginSuccess": "Login successful!",
|
||||||
"youSure": "Are you sure?",
|
"youSure": "Are you sure?",
|
||||||
@@ -279,5 +278,6 @@
|
|||||||
"messages": "Messages",
|
"messages": "Messages",
|
||||||
"emptyMessagesLine1": "You don't have any messages",
|
"emptyMessagesLine1": "You don't have any messages",
|
||||||
"emptyMessagesLine2": "Send a message to start a conversation!",
|
"emptyMessagesLine2": "Send a message to start a conversation!",
|
||||||
"letsgo": "Let's Go!"
|
"letsgo": "Let's Go!",
|
||||||
|
"selected": "Selected"
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user