mirror of
https://github.com/HabitRPG/habitica.git
synced 2025-12-16 14:17:22 +01:00
Sept 15 fixes (#9044)
* Adjusted styles and added loading for private messages * Allowed for assigning during group task creation * Fixed white logos and start overflow * Added state styles to home * Fixed position * Updated avatar purchasing
This commit is contained in:
3
website/client/assets/svg/cnet.svg
Normal file
3
website/client/assets/svg/cnet.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" viewBox="0 0 40 40">
|
||||
<path fill-rule="evenodd" d="M35.907 26.51v-1.424s-.771-.01-1.182-.006c-.522.006-.973-.241-1.01-.975l.004-7.688-.005-.014h1.852V15.01h-1.858l.011-.022v-2.982h-1.938v11.946c.06 1.035.386 1.964 1.246 2.35l-.003-.001c-.02-.01-.02-.008 0 0l.012.005c-.003 0-.006-.002-.009-.004.097.04.56.22 1.034.215.316-.008 1.846-.006 1.846-.006zm-5.688-2.527V22.61h-1.926v1.466c0 1.423-2.477 1.444-2.503 0v-3.053l4.07.002a.353.353 0 0 0 .352-.353v-3.14c.12-3.802-6.393-3.797-6.342-.094v6.545c-.05 3.703 6.468 3.797 6.349 0zm-6.953 1.103h-1.22v-7.748c-.062-1.038-.39-1.969-1.257-2.351.156.067-.92-.54-2.02.07-.868.48-1.2.971-1.2.971l-.007-1.041h-2.715v1.416l1.06.007v8.676l-.894-.003v1.425h2.816V17.25c.088-1.311 2.297-1.332 2.297-.002l.002 9.26h3.138v-1.422zm-10.813 6.858h1.393V9.236h-1.393v22.708zm-1.285-7.96V22.61H9.241v1.466c0 1.423-2.476 1.444-2.501 0v-6.638l-.003.07c.024-1.447 2.504-1.489 2.504-.07l.023 1.23h1.896v-1.136c.123-3.803-6.394-3.797-6.343-.094v6.545c-.05 3.703 6.468 3.797 6.351 0zm28.83-3.982c0 11.046-8.954 19.998-20 19.998S0 31.047 0 20.002C0 8.954 8.952 0 19.998 0c11.046 0 20 8.954 20 20.002zm-11.71-.423l-2.498.001v-2.152c.033-1.42 2.503-1.409 2.503.01l-.005 2.14z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
3
website/client/assets/svg/fast-company.svg
Normal file
3
website/client/assets/svg/fast-company.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="162" height="24" viewBox="0 0 162 24">
|
||||
<path fill-rule="evenodd" d="M17.08 7.351L15.46 12.65h3.352L17.08 7.35zm1.515 10.487v-.757c1.081 0 1.298-.324 1.298-.648 0-.433-.108-.757-.217-1.081 0 0-.216-.866-.432-1.514h-4.216l-.433 1.405c-.107.325-.215.65-.215 1.082 0 .433.432.756 1.08.756v.757h-4.215v-.757c1.08 0 1.513-.324 1.945-1.513l3.244-9.73c-.109-.433-.433-.757-1.081-.757v-.757h3.458c1.18 3.463 2.369 6.922 3.567 10.379.54 1.837 1.081 2.378 1.946 2.378v.757h-5.729zM66.162 6.162c-2.81 0-3.784 2.703-3.784 5.838 0 2.92.865 5.838 3.784 5.838 2.811 0 3.676-2.92 3.676-5.946 0-2.919-1.08-5.73-3.676-5.73zm0 12.973c-4.108 0-6.92-2.92-6.92-7.135 0-4 2.92-7.135 6.92-7.135 3.892 0 6.81 3.027 6.81 7.135.002 4-3.026 7.135-6.81 7.135zM102.81 2.27h-.54v11.134h.972c3.57 0 5.407-1.622 5.407-5.73 0-4.108-1.623-5.404-5.84-5.404zm1.08 12.757h-1.62v4.647c0 2.38.647 2.92 2.486 2.92v.864h-8.324v-.864c1.73 0 2.379-.648 2.379-3.027V4.325c0-2.378-.649-2.81-2.379-2.81V.757h6.27c6.054 0 9.62 1.838 9.62 6.81.001 5.19-4.322 7.46-8.431 7.46zM117.3 5.189l-3.028 9.839h6.27L117.3 5.189zm13.513 1.081v12.973c0 2.81.647 3.35 2.377 3.35v.866h-12.755v-.865c.974 0 1.837-.325 1.837-.973 0-.433-.107-1.19-.325-1.947l-.973-3.135h-7.134c-.11.434-1.405 4-1.405 4.974 0 .864.973 1.08 1.62 1.08v.866h-5.946v-.865c1.081 0 1.947-.108 2.703-2.378l5.514-17.622c-.325-.757-.756-.973-1.513-1.082V.756h4.866l5.836 18.487c.541 1.946 1.08 2.92 1.946 3.35 1.298-.431 1.623-.864 1.623-3.35V3.676c-.974-1.298-1.083-2.163-2.92-2.163V.757h5.514l9.081 15.46V4.432c0-2.379-.54-2.92-2.379-2.92V.757h12.108v.756c-.756 0-1.405.325-1.405 1.082 0 .54.217 1.08.433 1.73l3.46 7.46 3.351-7.244c.54-.973.65-1.513.65-2.054 0-.649-.435-.974-1.406-.974V.757h5.729v.756c-1.405 0-2.272 1.298-2.919 2.81l-4.432 9.082v5.946c0 2.596.648 3.244 2.378 3.244v.864h-8.217v-.864c1.73 0 2.38-.648 2.38-3.244v-5.08L145.73 4.216c-.864-1.945-1.189-2.378-1.73-2.703-1.082.433-1.406 1.19-1.406 2.92V21.08s.11 1.298.217 2.81l-1.405.109-10.595-17.73zM14.162 4.973h-.864c0-1.946-.865-2.702-2.595-2.702H5.838v8.54h3.135c1.622 0 1.947-.864 2.162-2.27h.757v6.054h-.757c-.215-1.621-.54-2.27-2.27-2.27H5.838v7.244c0 2.702.649 3.027 2.379 3.027v.864H0v-.864c2.054 0 2.378-.54 2.378-3.027V3.676c0-1.514-.649-2.163-2.378-2.163V.757h11.243C13.188.757 13.62.65 13.946 0h.757l-.54 4.973zM26.486 24c-1.513 0-2.703-.216-3.567-.54-.865-.216-1.514-.541-1.838-.757a5.804 5.804 0 0 0-.757.973l-.649-.216.54-5.08.758.108c.432 2.378 2.054 4.108 5.406 4.108 2.594 0 4.324-2.162 4.324-4.54 0-1.946-.757-2.92-3.351-4.866-.865-.54-1.622-.972-2.271-1.513-2.378-1.513-3.892-3.243-3.892-6.054 0-3.243 2.703-5.405 6.27-5.405 2.054 0 3.352.648 3.784.864l.756-.864.54.108L32 4.974l-.756-.108c0-2.161-1.298-3.135-3.46-3.135-2.054 0-3.567 1.081-3.567 3.135 0 1.838 1.405 3.027 3.026 4.109.865.54 1.514.973 2.162 1.405 3.784 2.702 4.648 4.432 4.648 7.027C34.054 21.19 31.135 24 26.486 24zM49.405 4.973h-.756c-.109-2.054-.757-2.702-2.38-2.702h-3.134v16.973c0 2.81.54 3.35 2.379 3.35v.865h-8.109v-.864c1.838 0 2.379-.54 2.379-3.46V2.27h-3.135c-2.054 0-2.38.54-2.92 2.702h-.756l.54-4.865.541.109c.216.54.65.54 1.946.54h10.486c1.947 0 2.38 0 2.812-.649h.648l-.541 4.865zm20.433 18.595c-.432-.109-.864-.109-1.297-.109-.865 0-2.38.433-4.217.433-7.027 0-12.216-4.217-12.216-12 0-6.595 4.865-11.675 12.324-11.675 1.729 0 3.676.324 5.297.972.324-.324.433-.54.757-.864h.648c-.108 1.19-.54 5.08-.54 5.08h-.65c-.431-2.269-1.62-3.783-5.405-3.783-4.54 0-8.648 3.567-8.648 10.162 0 7.46 4.216 10.703 8.865 10.703 3.028 0 4.865-1.73 6.054-3.892l.758.325-1.73 4.648zM76.65 6.487c0 3.243-.324 13.298-.324 13.298 0 1.945.648 2.81 2.487 2.81v.864h-7.244v-.864c1.838 0 2.81-.865 2.81-2.81l.65-16.433c-.541-1.298-1.082-1.73-2.487-1.838V.758h5.513l5.838 15.352L89.84.758h4.972v.756c-1.405 0-2.161.65-2.161 2.163l.649 15.892c0 2.379.432 3.027 2.379 3.027v.864h-8.325v-.864c1.621 0 2.38-.54 2.27-3.027 0 0-.325-11.136-.432-13.081l-3.999 11.027a41.15 41.15 0 0 0-1.514 4.757l-1.296.108c-.325-1.19-1.19-3.35-1.19-3.35S77.838 9.621 76.65 6.486z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.0 KiB |
@@ -184,6 +184,9 @@
|
||||
|
||||
#bottom-wrap {
|
||||
margin-top: 6em;
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
#bottom-background {
|
||||
|
||||
@@ -14,7 +14,7 @@ b-modal#avatar-modal(title="", size='lg', :hide-header='true', :hide-footer='tru
|
||||
// @TODO Implement in V2 .section.row
|
||||
.col-12.text-center
|
||||
button.btn.btn-secondary(v-once) {{$t('randomize')}}
|
||||
.container.section.text-center.customize-menu
|
||||
#options-nav.container.section.text-center.customize-menu
|
||||
.row
|
||||
div(:class='{"col-3": !editing, "col-2 offset-1": editing}')
|
||||
.menu-item(@click='changeTopPage("body", "size")')
|
||||
@@ -36,8 +36,7 @@ b-modal#avatar-modal(title="", size='lg', :hide-header='true', :hide-footer='tru
|
||||
.menu-item(@click='changeTopPage("backgrounds", "2017")')
|
||||
.svg-icon(v-html='icons.backgroundsIcon')
|
||||
strong(v-once) {{$t('backgrounds')}}
|
||||
|
||||
.section.customize-section(v-if='activeTopPage === "body"')
|
||||
#body.section.customize-section(v-if='activeTopPage === "body"')
|
||||
.row.sub-menu.col-6.offset-3.text-center
|
||||
.col-2.offset-4.sub-menu-item(@click='changeSubPage("size")', :class='{active: activeSubPage === "size"}')
|
||||
strong(v-once) {{$t('size')}}
|
||||
@@ -53,16 +52,15 @@ b-modal#avatar-modal(title="", size='lg', :hide-header='true', :hide-footer='tru
|
||||
:class='{active: user.preferences.shirt === option}')
|
||||
.sprite.customize-option(:class="`slim_shirt_${option}`", @click='set({"preferences.shirt": option})')
|
||||
.col-12.customize-options(v-if='editing')
|
||||
.option(v-for='option in specialShirts',
|
||||
:class='{active: user.preferences.shirt === option, locked: !user.purchased.shirt[option]}')
|
||||
.sprite.customize-option(:class="`broad_shirt_${option}`", @click='user.purchased.shirt[option] ? set({"preferences.shirt": option}) : unlock(`shirt.${option}`)')
|
||||
.gem-lock(v-if='!user.purchased.shirt[option]')
|
||||
.option(v-for='item in specialShirts',
|
||||
:class='{active: item.active, locked: item.locked}')
|
||||
.sprite.customize-option(:class="`broad_shirt_${item.key}`", @click='item.click')
|
||||
.gem-lock(v-if='item.locked')
|
||||
.svg-icon.gem(v-html='icons.gem')
|
||||
span 2
|
||||
.col-12.text-center
|
||||
button.btn.btn-secondary(@click='unlock(`shirt.${specialShirts.join(",shirt.")}`)') Purchase All
|
||||
|
||||
.section.customize-section(v-if='activeTopPage === "skin"')
|
||||
.col-12.text-center
|
||||
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"')
|
||||
.row.sub-menu.col-6.offset-3.text-center
|
||||
.col-6.offset-3.text-center.sub-menu-item(:class='{active: activeSubPage === "color"}')
|
||||
strong(v-once) {{$t('color')}}
|
||||
@@ -73,41 +71,69 @@ b-modal#avatar-modal(title="", size='lg', :hide-header='true', :hide-footer='tru
|
||||
.skin.sprite.customize-option(:class="`skin_${option}`", @click='set({"preferences.skin": option})')
|
||||
.row(v-if='editing')
|
||||
.col-12.customize-options
|
||||
.option(v-for='option in ["eb052b", "f69922", "f5d70f", "0ff591", "2b43f6", "d7a9f7", "800ed0", "rainbow"]',
|
||||
:class='{active: user.preferences.skin === option, locked: !user.purchased.skin[option]}')
|
||||
.skin.sprite.customize-option(:class="`skin_${option}`", @click='user.purchased.skin[option] ? set({"preferences.skin": option}) : unlock(`skin.${option}`)')
|
||||
.gem-lock(v-if='!user.purchased.skin[option]')
|
||||
.option(v-for='option in rainbowSkins',
|
||||
: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", rainbowSkinKeys)', @click='unlock(`skin.${rainbowSkinKeys.join(",skin.")}`)') $t('purchaseAll')
|
||||
.row(v-if='editing')
|
||||
.col-12.customize-options
|
||||
.option(v-for='option in ["bear", "cactus", "fox", "lion", "panda", "pig", "tiger", "wolf"]',
|
||||
:class='{active: user.preferences.skin === option, locked: !user.purchased.skin[option]}')
|
||||
.skin.sprite.customize-option(:class="`skin_${option}`", @click='user.purchased.skin[option] ? set({"preferences.skin": option}) : unlock(`skin.${option}`)')
|
||||
.gem-lock(v-if='!user.purchased.skin[option]')
|
||||
.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"')
|
||||
.row.sub-menu.col-6.offset-3.text-center
|
||||
.col-2.offset-3.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"}')
|
||||
strong(v-once) {{$t('color')}}
|
||||
.col-2.text-center.sub-menu-item(@click='changeSubPage("style")', :class='{active: activeSubPage === "style"}', v-if='editing')
|
||||
strong(v-once) {{$t('style')}}
|
||||
.col-2.text-center.sub-menu-item(@click='changeSubPage("bangs")', :class='{active: activeSubPage === "bangs"}')
|
||||
strong(v-once) {{$t('bangs')}}
|
||||
.col-3.text-center.sub-menu-item(@click='changeSubPage("ponytail")', :class='{active: activeSubPage === "ponytail"}')
|
||||
strong(v-once) {{$t('ponytail')}}
|
||||
.row(v-if='activeSubPage === "color"')
|
||||
.col-2.text-center.sub-menu-item(@click='changeSubPage("facialhair")', :class='{active: activeSubPage === "facialhair"}', v-if='editing')
|
||||
strong(v-once) {{$t('facialhair')}}
|
||||
#hair-color.row(v-if='activeSubPage === "color"')
|
||||
.col-12.customize-options
|
||||
.option(v-for='option in ["white", "brown", "blond", "red", "black"]',
|
||||
:class='{active: user.preferences.hair.color === option}')
|
||||
.color-bangs.sprite.customize-option(:class="`hair_bangs_1_${option}`", @click='set({"preferences.hair.color": option})')
|
||||
.col-12.customize-options(v-if='editing')
|
||||
.option(v-for='option in ["rainbow", "yellow", "green", "purple", "blue", "TRUred"]',
|
||||
:class='{active: user.preferences.hair.color === option, locked: !user.purchased.hair.color || !user.purchased.hair.color[option]}')
|
||||
.color-bangs.sprite.customize-option(:class="`hair_bangs_1_${option}`", @click='user.purchased.hair.color && user.purchased.hair.color[option] ? set({"preferences.hair.color": option}) : unlock(`skin.${option}`)')
|
||||
.gem-lock(v-if='!user.purchased.hair.color || !user.purchased.hair.color[option]')
|
||||
.option(v-for='option in premiumHairColors',
|
||||
:class='{active: option.active === option, locked: option.locked}')
|
||||
.color-bangs.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='!userOwnsSet("hair", premiumHairColorKeys, "color")', @click='unlock(`hair.color.${premiumHairColorKeys.join(",hair.color.")}`)') $t('purchaseAll')
|
||||
#style.row(v-if='activeSubPage === "style"')
|
||||
.col-12.customize-options(v-if='editing')
|
||||
.option(v-for='option in baseHair3',
|
||||
:class='{active: option.active, locked: option.locked}')
|
||||
.base.sprite.customize-option(:class="`hair_base_${option.key}_${user.preferences.hair.color}`", @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("hair", baseHair3Keys, "base")', @click='unlock(`hair.base.${baseHair3Keys.join(",hair.base.")}`)') $t('purchaseAll')
|
||||
.col-12.customize-options(v-if='editing')
|
||||
.option(v-for='option in baseHair4',
|
||||
:class='{active: option.active, locked: option.locked}')
|
||||
.base.sprite.customize-option(:class="`hair_base_${option.key}_${user.preferences.hair.color}`", @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("hair", baseHair4Keys, "base")', @click='unlock(`hair.base.${baseHair4Keys.join(",hair.base.")}`)') $t('purchaseAll')
|
||||
#bangs.row(v-if='activeSubPage === "bangs"')
|
||||
.col-12.customize-options
|
||||
.head_0.option(@click='set({"preferences.hair.bangs": 0})',
|
||||
@@ -118,46 +144,38 @@ b-modal#avatar-modal(title="", size='lg', :hide-header='true', :hide-footer='tru
|
||||
#base-hair.row(v-if='activeSubPage === "ponytail"')
|
||||
.col-12.customize-options
|
||||
.head_0.option(@click='set({"preferences.hair.base": 0})', :class="[{ active: user.preferences.hair.base === 0 }, 'hair_base_0_' + user.preferences.hair.color]")
|
||||
.option(v-for='option in ["1", "3"]',
|
||||
.option(v-for='option in baseHair1',
|
||||
:class='{active: user.preferences.hair.base === option}')
|
||||
.base.sprite.customize-option(:class="`hair_base_${option}_${user.preferences.hair.color}`", @click='set({"preferences.hair.base": option})')
|
||||
.col-12.customize-options(v-if='editing')
|
||||
.option(v-for='option in ["2", "4", "5", "6", "7", "8"]',
|
||||
:class='{active: user.preferences.hair.base === option, locked: !user.purchased.hair.base || !user.purchased.hair.base[option]}')
|
||||
.base.sprite.customize-option(:class="`hair_base_${option}_${user.preferences.hair.color}`", @click='set({"preferences.hair.base": option})')
|
||||
.gem-lock(v-if='!user.purchased.hair.base || !user.purchased.hair.base[option]')
|
||||
.option(v-for='option in baseHair2',
|
||||
:class='{active: option.active, locked: option.locked}')
|
||||
.base.sprite.customize-option(:class="`hair_base_${option.key}_${user.preferences.hair.color}`", @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("hair", baseHair2Keys, "base")', @click='unlock(`hair.base.${baseHair2Keys.join(",hair.base.")}`)') $t('purchaseAll')
|
||||
#facialhair.row(v-if='activeSubPage === "facialhair"')
|
||||
.col-12.customize-options(v-if='editing')
|
||||
.option(v-for='option in ["9", "10", "11", "12", "13", "14"]',
|
||||
:class='{active: user.preferences.hair.base === option, locked: !user.purchased.hair.base || !user.purchased.hair.base[option]}')
|
||||
.base.sprite.customize-option(:class="`hair_base_${option}_${user.preferences.hair.color}`", @click='set({"preferences.hair.base": option})')
|
||||
.gem-lock(v-if='!user.purchased.hair.base || !user.purchased.hair.base[option]')
|
||||
.option(v-for='option in baseHair5',
|
||||
:class='{active: option.active, locked: option.locked}')
|
||||
.base.sprite.customize-option(:class="`hair_beard_${option.key}_${user.preferences.hair.color}`", @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("hair", baseHair5Keys, "beard")', @click='unlock(`hair.beard.${baseHair5Keys.join(",hair.beard.")}`)') $t('purchaseAll')
|
||||
.col-12.customize-options(v-if='editing')
|
||||
.option(v-for='option in ["15", "16", "17", "18", "19", "20"]',
|
||||
:class='{active: user.preferences.hair.base === option, locked: !user.purchased.hair.base || !user.purchased.hair.base[option]}')
|
||||
.base.sprite.customize-option(:class="`hair_base_${option}_${user.preferences.hair.color}`", @click='set({"preferences.hair.base": option})')
|
||||
.gem-lock(v-if='!user.purchased.hair.base || !user.purchased.hair.base[option]')
|
||||
.option(v-for='option in baseHair6',
|
||||
:class='{active: option.active, locked: option.locked}')
|
||||
.base.sprite.customize-option(:class="`hair_mustache_${option.key}_${user.preferences.hair.color}`", @click='option.click')
|
||||
.gem-lock(v-if='option.locked')
|
||||
.svg-icon.gem(v-html='icons.gem')
|
||||
span 2
|
||||
.col-12.customize-options(v-if='editing')
|
||||
.option(v-for='option in ["1", "2", "3"]',
|
||||
:class='{active: user.preferences.hair.beard === option, locked: !user.purchased.hair.base || !user.purchased.hair.base[option]}')
|
||||
.base.sprite.customize-option(:class="`hair_beard_${option}_${user.preferences.hair.color}`", @click='set({"preferences.hair.beard": option})')
|
||||
.gem-lock(v-if='!user.purchased.hair.base || !user.purchased.hair.base[option]')
|
||||
.svg-icon.gem(v-html='icons.gem')
|
||||
span 2
|
||||
.col-12.customize-options(v-if='editing')
|
||||
.option(v-for='option in ["1", "2"]',
|
||||
:class='{active: user.preferences.hair.mustache === option, locked: !user.purchased.hair.base || !user.purchased.hair.base[option]}')
|
||||
.base.sprite.customize-option(:class="`hair_mustache_${option}_${user.preferences.hair.color}`", @click='set({"preferences.hair.mustache": option})')
|
||||
.gem-lock(v-if='!user.purchased.hair.base || !user.purchased.hair.base[option]')
|
||||
.svg-icon.gem(v-html='icons.gem')
|
||||
span 2
|
||||
|
||||
.section.container.customize-section(v-if='activeTopPage === "extra"')
|
||||
.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')
|
||||
#extra.section.container.customize-section(v-if='activeTopPage === "extra"')
|
||||
.row.sub-menu.col-6.offset-3.text-center
|
||||
.col-4.text-center.sub-menu-item(@click='changeSubPage("glasses")', :class='{active: activeSubPage === "glasses"}')
|
||||
strong(v-once) {{$t('glasses')}}
|
||||
@@ -175,13 +193,14 @@ b-modal#avatar-modal(title="", size='lg', :hide-header='true', :hide-footer='tru
|
||||
.eyewear_special_whiteTopFrame.option(@click='equip("eyewear_special_whiteTopFrame")', :class='{active: user.preferences.costume ? user.items.gear.costume.eyewear === "eyewear_special_whiteTopFrame" : user.items.gear.equipped.eyewear === "eyewear_special_whiteTopFrame"}')
|
||||
.eyewear_special_yellowTopFrame.option(@click='equip("eyewear_special_yellowTopFrame")', :class='{active: user.preferences.costume ? user.items.gear.costume.eyewear === "eyewear_special_yellowTopFrame" : user.items.gear.equipped.eyewear === "eyewear_special_yellowTopFrame"}')
|
||||
#animal-ears.col-12.customize-options(v-if='editing')
|
||||
.option(v-for='option in ["bearEars", "cactusEars", "foxEars", "lionEars", "pandaEars", "pigEars", "tigerEars", "wolfEars"]',
|
||||
:class='[{active: user.preferences.costume ? user.items.gear.costume.headAccessory === `headAccessory_special_${option}` : user.items.gear.equipped.headAccessory === `headAccessory_special_${option}`}, {locked: !user.purchased.headAccessory || !user.purchased.headAccessory[option]}]')
|
||||
.sprite.customize-option(:class="`headAccessory_special_${option}`", @click='equip(`headAccessory_special_${option}`)')
|
||||
.gem-lock(v-if='!user.purchased.headAccessory || !user.purchased.headAccessory[option]')
|
||||
.option(v-for='option in animalEars',
|
||||
:class='{active: option.active, locked: option.locked}')
|
||||
.sprite.customize-option(:class="`headAccessory_special_${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='!animalEarsOwned', @click='unlock(animalEarsUnlockString)') $t('purchaseAll')
|
||||
#wheelchairs.row(v-if='activeSubPage === "wheelchair"')
|
||||
.col-12.customize-options.weelchairs
|
||||
.option(@click='set({"preferences.chair": "none"})', :class='{active: user.preferences.chair === "none"}')
|
||||
@@ -202,7 +221,6 @@ b-modal#avatar-modal(title="", size='lg', :hide-header='true', :hide-footer='tru
|
||||
popover='{{::item.notes()}}', popover-title='{{::item.text()}}', popover-trigger='mouseenter',
|
||||
popover-placement='right', popover-append-to-body='true',
|
||||
ng-click='user.items.gear.owned[item.key] ? equip(item.key) : purchase(item.type,item)')
|
||||
|
||||
#backgrounds.section.container.customize-section(v-if='activeTopPage === "backgrounds"')
|
||||
.row.col-12.text-center.set-title
|
||||
strong {{backgroundShopSets[0].text}}
|
||||
@@ -359,6 +377,10 @@ b-modal#avatar-modal(title="", size='lg', :hide-header='true', :hide-footer='tru
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.purchase-all {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
.section {
|
||||
margin-top: 2em;
|
||||
}
|
||||
@@ -892,18 +914,26 @@ export default {
|
||||
},
|
||||
mounted () {
|
||||
if (this.editing) this.modalPage = 2;
|
||||
|
||||
// Buy modal is global, so we listen at root. I'd like to not
|
||||
this.$root.$on('buyModal::boughtItem', this.backgroundPurchased);
|
||||
},
|
||||
data () {
|
||||
let backgroundShopSets = getBackgroundShopSets();
|
||||
|
||||
return {
|
||||
loading: false,
|
||||
backgroundShopSets,
|
||||
backgroundUpdate: new Date(),
|
||||
specialShirts: ['convict', 'cross', 'fire', 'horizon', 'ocean', 'purple', 'rainbow', 'redblue', 'thunder', 'tropical', 'zombie'],
|
||||
specialShirtKeys: ['convict', 'cross', 'fire', 'horizon', 'ocean', 'purple', 'rainbow', 'redblue', 'thunder', 'tropical', 'zombie'],
|
||||
rainbowSkinKeys: ['eb052b', 'f69922', 'f5d70f', '0ff591', '2b43f6', 'd7a9f7', '800ed0', 'rainbow'],
|
||||
animalSkinKeys: ['bear', 'cactus', 'fox', 'lion', 'panda', 'pig', 'tiger', 'wolf'],
|
||||
premiumHairColorKeys: ['rainbow', 'yellow', 'green', 'purple', 'blue', 'TRUred'],
|
||||
baseHair1: ['1', '3'],
|
||||
baseHair2Keys: ['2', '4', '5', '6', '7', '8'],
|
||||
baseHair3Keys: ['9', '10', '11', '12', '13', '14'],
|
||||
baseHair4Keys: ['15', '16', '17', '18', '19', '20'],
|
||||
baseHair5Keys: ['1', '2', '3'],
|
||||
baseHair6Keys: ['1', '2'],
|
||||
animalEarsKeys: ['bearEars', 'cactusEars', 'foxEars', 'lionEars', 'pandaEars', 'pigEars', 'tigerEars', 'wolfEars'],
|
||||
icons: Object.freeze({
|
||||
logoPurple,
|
||||
bodyIcon,
|
||||
@@ -934,6 +964,125 @@ export default {
|
||||
},
|
||||
computed: {
|
||||
...mapState({user: 'user.data'}),
|
||||
animalEarsUnlockString () {
|
||||
let animalItemKeys = this.animalEarsKeys.map(key => {
|
||||
return `items.gear.owned.headAccessory_special_${key}`;
|
||||
});
|
||||
|
||||
return animalItemKeys.join(',');
|
||||
},
|
||||
animalEarsOwned () {
|
||||
// @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 own = true;
|
||||
this.animalEarsKeys.forEach(key => {
|
||||
if (!this.user.items.gear.owned[`headAccessory_special_${key}`]) own = false;
|
||||
});
|
||||
return own;
|
||||
},
|
||||
animalEars () {
|
||||
// @TODO: This is not like other purchase items
|
||||
// @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 keys = this.animalEarsKeys;
|
||||
let options = keys.map(key => {
|
||||
let newKey = `headAccessory_special_${key}`;
|
||||
let userPurchased = this.user.items.gear.owned[newKey];
|
||||
let locked = !userPurchased;
|
||||
|
||||
let option = {};
|
||||
option.key = key;
|
||||
option.active = this.user.preferences.costume ? this.user.items.gear.costume.headAccessory === newKey : this.user.items.gear.equipped.headAccessory === newKey;
|
||||
option.locked = locked;
|
||||
option.click = () => {
|
||||
return locked ? this.purchase('gear', newKey) : this.equip(newKey);
|
||||
};
|
||||
return option;
|
||||
});
|
||||
return options;
|
||||
},
|
||||
specialShirts () {
|
||||
// @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 keys = this.specialShirtKeys;
|
||||
let options = keys.map(key => {
|
||||
return this.mapKeysToOption(key, 'shirt');
|
||||
});
|
||||
return options;
|
||||
},
|
||||
rainbowSkins () {
|
||||
// @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 keys = this.rainbowSkinKeys;
|
||||
let options = keys.map(key => {
|
||||
return this.mapKeysToOption(key, 'skin');
|
||||
});
|
||||
return options;
|
||||
},
|
||||
animalSkins () {
|
||||
// @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 keys = this.animalSkinKeys;
|
||||
let options = keys.map(key => {
|
||||
return this.mapKeysToOption(key, 'skin');
|
||||
});
|
||||
return options;
|
||||
},
|
||||
premiumHairColors () {
|
||||
// @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 keys = this.premiumHairColorKeys;
|
||||
let options = keys.map(key => {
|
||||
return this.mapKeysToOption(key, 'hair', 'color');
|
||||
});
|
||||
return options;
|
||||
},
|
||||
baseHair2 () {
|
||||
// @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 keys = this.baseHair2Keys;
|
||||
let options = keys.map(key => {
|
||||
return this.mapKeysToOption(key, 'hair', 'base');
|
||||
});
|
||||
return options;
|
||||
},
|
||||
baseHair3 () {
|
||||
// @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 keys = this.baseHair3Keys;
|
||||
let options = keys.map(key => {
|
||||
return this.mapKeysToOption(key, 'hair', 'base');
|
||||
});
|
||||
return options;
|
||||
},
|
||||
baseHair4 () {
|
||||
// @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 keys = this.baseHair4Keys;
|
||||
let options = keys.map(key => {
|
||||
return this.mapKeysToOption(key, 'hair', 'base');
|
||||
});
|
||||
return options;
|
||||
},
|
||||
baseHair5 () {
|
||||
// @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 keys = this.baseHair5Keys;
|
||||
let options = keys.map(key => {
|
||||
return this.mapKeysToOption(key, 'hair', 'beard');
|
||||
});
|
||||
return options;
|
||||
},
|
||||
baseHair6 () {
|
||||
// @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 keys = this.baseHair6Keys;
|
||||
let options = keys.map(key => {
|
||||
return this.mapKeysToOption(key, 'hair', 'mustache');
|
||||
});
|
||||
return options;
|
||||
},
|
||||
editing () {
|
||||
return this.$store.state.avatarEditorOptions.editingUser;
|
||||
},
|
||||
@@ -968,6 +1117,41 @@ export default {
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
purchase (type, key) {
|
||||
this.$store.dispatch('shops:purchase', {
|
||||
type,
|
||||
key,
|
||||
});
|
||||
this.backgroundUpdate = new Date();
|
||||
},
|
||||
mapKeysToOption (key, type, subType) {
|
||||
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 locked = !userPurchased || !userPurchased[key];
|
||||
let pathKey = subType ? `${type}.${subType}` : `${type}`;
|
||||
|
||||
let option = {};
|
||||
option.key = key;
|
||||
option.active = userPreference === key;
|
||||
option.locked = locked;
|
||||
option.click = () => {
|
||||
return locked ? this.unlock(`${pathKey}.${key}`) : this.set({[`preferences.${pathKey}`]: key});
|
||||
};
|
||||
return option;
|
||||
},
|
||||
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;
|
||||
},
|
||||
prev () {
|
||||
this.modalPage -= 1;
|
||||
},
|
||||
|
||||
@@ -118,6 +118,7 @@ export default {
|
||||
|
||||
let guilds = await this.$store.dispatch('guilds:getPublicGuilds', this.queryFilters);
|
||||
guilds.forEach((guild) => {
|
||||
if (!guild.categories) return;
|
||||
guild.categorySlugs = guild.categories.map(cat => {
|
||||
return cat.slug;
|
||||
});
|
||||
|
||||
@@ -1,9 +1,20 @@
|
||||
<template lang="pug">
|
||||
b-modal#private-message(title="Message", size='sm', :hide-footer="true")
|
||||
textarea.form-control(v-model='privateMessage')
|
||||
button.btn.btn-primary(@click='sendPrivateMessage()') Send
|
||||
b-modal#private-message(title="Message", size='md', :hide-footer="true")
|
||||
.content
|
||||
textarea.form-control(v-model='privateMessage')
|
||||
button.btn.btn-primary(@click='sendPrivateMessage()', :disabled='loading') Send
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.content {
|
||||
padding: 1em;
|
||||
|
||||
textarea {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
import bModal from 'bootstrap-vue/lib/components/modal';
|
||||
import notifications from 'client/mixins/notifications';
|
||||
@@ -17,17 +28,22 @@ export default {
|
||||
data () {
|
||||
return {
|
||||
privateMessage: '',
|
||||
loading: false,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
async sendPrivateMessage () {
|
||||
if (!this.privateMessage || !this.userIdToMessage) return;
|
||||
|
||||
this.loading = true;
|
||||
|
||||
await this.$store.dispatch('members:sendPrivateMessage', {
|
||||
message: this.privateMessage,
|
||||
toUserId: this.userIdToMessage,
|
||||
});
|
||||
|
||||
this.loading = false;
|
||||
|
||||
this.text(this.$t('messageSentAlert'));
|
||||
},
|
||||
},
|
||||
|
||||
@@ -23,11 +23,11 @@
|
||||
.strike
|
||||
span OR
|
||||
.form
|
||||
input.form-control(type='text', placeholder='Username', v-model='username')
|
||||
input.form-control(type='email', placeholder='Email', v-model='email')
|
||||
input.form-control(type='password', placeholder='Password', v-model='password')
|
||||
input.form-control(type='password', placeholder='Confirm Password', v-model='passwordConfirm')
|
||||
p By clicking the button below, you are indicating that you have read and agree to the Terms of Service and Privacy Policy.
|
||||
input.form-control(type='text', placeholder='Username', 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='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}')
|
||||
p.form-text(v-once, v-html="$t('termsAndAgreement')")
|
||||
button.sign-up(@click='register()') Sign Up
|
||||
.col-12
|
||||
.spacer.svg-icon(v-html='icons.spacer')
|
||||
@@ -98,12 +98,10 @@
|
||||
h3.col-12 Join over 2,000,000 people having fun while accomplishing their goals!
|
||||
.row
|
||||
.col-12.text-center
|
||||
button.btn.btn-primary(@click='playButtonClick()') Join Habitica Today
|
||||
button.btn.btn-primary.join-button(@click='playButtonClick()') Join Habitica Today
|
||||
.row.featured
|
||||
.col-12.text-center
|
||||
strong Featured in
|
||||
.container-fluid
|
||||
.seamless_stars_varied_opacity_repeat
|
||||
.container-fluid.featured
|
||||
.row
|
||||
.col-12
|
||||
@@ -111,10 +109,12 @@
|
||||
img(src='https://d2afqr2xdmyzvu.cloudfront.net/front/images/presslogos/nyt-logo.png', alt="$t(altAttrNewYorkTimes)")
|
||||
img(src='https://d2afqr2xdmyzvu.cloudfront.net/front/images/presslogos/makeuseof.png', alt="$t(altAttrMakeUseOf)")
|
||||
img(src='https://d2afqr2xdmyzvu.cloudfront.net/front/images/presslogos/Forbes_logo.png', alt="$t(altAttrForbes)")
|
||||
img(src='https://d2afqr2xdmyzvu.cloudfront.net/front/images/presslogos/Cnetlogo.png', alt="$t(altAttrCnet)")
|
||||
img(src='https://d2afqr2xdmyzvu.cloudfront.net/front/images/presslogos/Fast-Company-logo.png', alt="$t(altAttrFastCompany)")
|
||||
.cnet.svg-icon(v-html='icons.cnet')
|
||||
.fast-company.svg-icon(v-html='icons.fastCompany')
|
||||
img(src='https://d2afqr2xdmyzvu.cloudfront.net/front/images/presslogos/kickstarter-logo.png', alt="$t(altAttrKickstarter)")
|
||||
img(src='https://d2afqr2xdmyzvu.cloudfront.net/front/images/presslogos/discover-logo.png', alt="$t(altAttrDiscover)")
|
||||
.container-fluid
|
||||
.seamless_stars_varied_opacity_repeat
|
||||
|
||||
#bottom-wrap.purple-4
|
||||
#bottom-background
|
||||
@@ -122,6 +122,34 @@
|
||||
.midground_foreground_extended2
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
.form-text a {
|
||||
color: #fff !important;
|
||||
}
|
||||
|
||||
#purple-footer {
|
||||
background-color: #271b3d;
|
||||
|
||||
footer, footer a {
|
||||
background: transparent;
|
||||
color: #d5c8ff;
|
||||
}
|
||||
|
||||
.logo {
|
||||
color: #bda8ff;
|
||||
}
|
||||
|
||||
.social-circle, .btn-donate {
|
||||
background: #36205d;
|
||||
color: #bda8ff;
|
||||
|
||||
.svg-icon {
|
||||
color: #bda8ff;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import '~client/assets/scss/static.scss';
|
||||
|
||||
@@ -270,6 +298,11 @@
|
||||
color: $purple-400;
|
||||
}
|
||||
|
||||
input:focus {
|
||||
border: solid 2px #9a62ff;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
button.sign-up {
|
||||
width: 100%;
|
||||
height: 48px;
|
||||
@@ -280,6 +313,12 @@
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.sign-up:hover {
|
||||
background-color: #50b5e9;
|
||||
box-shadow: 0 4px 4px 0 rgba(26, 24, 29, 0.16), 0 1px 8px 0 rgba(26, 24, 29, 0.12);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
::-webkit-input-placeholder { /* Chrome/Opera/Safari */
|
||||
color: $purple-400;
|
||||
}
|
||||
@@ -336,6 +375,10 @@
|
||||
margin-right: .5em;
|
||||
}
|
||||
|
||||
.app {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.iphones {
|
||||
width: 436px
|
||||
}
|
||||
@@ -372,6 +415,12 @@
|
||||
padding-bottom: 5em;
|
||||
}
|
||||
|
||||
.join-button:hover {
|
||||
cursor: pointer;
|
||||
background-color: #b288ff;
|
||||
box-shadow: 0 4px 4px 0 rgba(26, 24, 29, 0.16), 0 1px 8px 0 rgba(26, 24, 29, 0.12);
|
||||
}
|
||||
|
||||
.featured .row {
|
||||
margin-top: 0;
|
||||
}
|
||||
@@ -379,6 +428,26 @@
|
||||
.featured {
|
||||
text-align: center;
|
||||
|
||||
.svg-icon {
|
||||
max-height: 30px;
|
||||
max-width: 120px;
|
||||
color: #fff;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.cnet {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
padding-top: .5em;
|
||||
margin-right: 1em;
|
||||
}
|
||||
|
||||
.fast-company {
|
||||
width: 161.3px;
|
||||
height: 24px;
|
||||
padding-top: .8em;
|
||||
}
|
||||
|
||||
img {
|
||||
max-height: 30px;
|
||||
max-width: 120px;
|
||||
@@ -440,6 +509,8 @@
|
||||
import pixelHorizontal3 from 'assets/images/home/pixel-horizontal-3.svg';
|
||||
import facebookSquareIcon from 'assets/svg/facebook-square.svg';
|
||||
import googleIcon from 'assets/svg/google.svg';
|
||||
import cnet from 'assets/svg/cnet.svg';
|
||||
import fastCompany from 'assets/svg/fast-company.svg';
|
||||
import * as Analytics from 'client/libs/analytics';
|
||||
|
||||
export default {
|
||||
@@ -455,6 +526,8 @@
|
||||
pixelHorizontal3,
|
||||
facebookIcon: facebookSquareIcon,
|
||||
googleIcon,
|
||||
cnet,
|
||||
fastCompany,
|
||||
}),
|
||||
userCount: 1000000,
|
||||
username: '',
|
||||
@@ -477,7 +550,29 @@
|
||||
google: process.env.GOOGLE_CLIENT_ID, // eslint-disable-line
|
||||
});
|
||||
},
|
||||
computed: {
|
||||
emailValid () {
|
||||
if (this.email.length === 0) return false;
|
||||
return this.validateEmail(this.email);
|
||||
},
|
||||
emailInvalid () {
|
||||
if (this.email.length === 0) return false;
|
||||
return !this.validateEmail(this.email);
|
||||
},
|
||||
passwordConfirmValid () {
|
||||
if (this.passwordConfirm.length === 0) return false;
|
||||
return this.passwordConfirm === this.password;
|
||||
},
|
||||
passwordConfirmInvalid () {
|
||||
if (this.passwordConfirm.length === 0) return false;
|
||||
return this.passwordConfirm !== this.password;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
validateEmail (email) {
|
||||
let re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
|
||||
return re.test(email);
|
||||
},
|
||||
async register () {
|
||||
if (this.password !== this.passwordConfirm) {
|
||||
alert('Passwords must match');
|
||||
|
||||
@@ -547,7 +547,7 @@ export default {
|
||||
weekdaysMin (dayNumber) {
|
||||
return moment.weekdaysMin(dayNumber);
|
||||
},
|
||||
submit () {
|
||||
async submit () {
|
||||
if (this.newChecklistItem) this.addChecklistItem();
|
||||
|
||||
if (this.purpose === 'create') {
|
||||
@@ -558,10 +558,21 @@ export default {
|
||||
});
|
||||
this.$emit('taskCreated', this.task);
|
||||
} else if (this.groupId) {
|
||||
this.$store.dispatch('tasks:createGroupTasks', {
|
||||
await this.$store.dispatch('tasks:createGroupTasks', {
|
||||
groupId: this.groupId,
|
||||
tasks: [this.task],
|
||||
});
|
||||
|
||||
let promises = this.assignedMembers.map(memberId => {
|
||||
return this.$store.dispatch('tasks:assignTask', {
|
||||
taskId: this.task._id,
|
||||
userId: memberId,
|
||||
});
|
||||
});
|
||||
Promise.all(promises);
|
||||
|
||||
this.task.group.assignedUsers = this.assignedMembers;
|
||||
|
||||
this.$emit('taskCreated', this.task);
|
||||
} else {
|
||||
this.createTask(this.task);
|
||||
@@ -596,13 +607,24 @@ export default {
|
||||
this.requiresApproval = truthy;
|
||||
},
|
||||
async toggleAssignment (memberId) {
|
||||
if (this.assignedMembers.indexOf(memberId) === -1) {
|
||||
let assignedIndex = this.assignedMembers.indexOf(memberId);
|
||||
|
||||
if (assignedIndex === -1) {
|
||||
if (this.purpose === 'create') {
|
||||
return;
|
||||
}
|
||||
|
||||
await this.$store.dispatch('tasks:unassignTask', {
|
||||
taskId: this.task._id,
|
||||
userId: this.user._id,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.purpose === 'create') {
|
||||
return;
|
||||
}
|
||||
|
||||
await this.$store.dispatch('tasks:assignTask', {
|
||||
taskId: this.task._id,
|
||||
userId: this.user._id,
|
||||
|
||||
@@ -189,5 +189,7 @@
|
||||
"hideQuickAllocation": "Hide stat allocation",
|
||||
"quickAllocationLevelPopover": "Each level earns you one point to assign to an attribute of your choice. You can do so manually, or let the game decide for you using one of the Automatic Allocation options found in User -> Stats.",
|
||||
"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",
|
||||
"facialhair": "Facial"
|
||||
}
|
||||
|
||||
@@ -198,5 +198,6 @@
|
||||
"subscriptionBenefit4": "Unique cosmetic items for your avatar each month.",
|
||||
"subscriptionBenefit5": "Receive the exclusive Royal Purple Jackalope pet!",
|
||||
"subscriptionBenefit6": "Earn Mystic Hourglasses for use in the Time Travelers' Shop!",
|
||||
"haveCouponCode": "Do you have a coupon code?"
|
||||
"haveCouponCode": "Do you have a coupon code?",
|
||||
"purchaseAll": "Purchase All"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user