Merge branch 'develop' into sabrecat/teams-rebase

This commit is contained in:
SabreCat
2022-05-17 09:34:51 -05:00
44 changed files with 1410 additions and 899 deletions
@@ -1,60 +0,0 @@
<template>
<b-modal
id="just-add-water"
:title="title"
size="md"
:hide-footer="true"
>
<div class="modal-body">
<div class="col-12">
<achievement-avatar class="avatar" />
</div>
<div class="col-6 offset-3 text-center">
<p>{{ $t('achievementJustAddWaterModalText') }}</p>
<button
class="btn btn-primary"
@click="close()"
>
{{ $t('huzzah') }}
</button>
</div>
</div>
<achievement-footer />
</b-modal>
</template>
<style scoped>
.avatar {
width: 140px;
margin: 0 auto;
margin-bottom: 1.5em;
margin-top: 1.5em;
}
</style>
<script>
import achievementFooter from './achievementFooter';
import achievementAvatar from './achievementAvatar';
import { mapState } from '@/libs/store';
export default {
components: {
achievementFooter,
achievementAvatar,
},
data () {
return {
title: `${this.$t('modalAchievement')} ${this.$t('achievementJustAddWater')}`,
};
},
computed: {
...mapState({ user: 'user.data' }),
},
methods: {
close () {
this.$root.$emit('bv::hide::modal', 'just-add-water');
},
},
};
</script>
@@ -1,60 +0,0 @@
<template>
<b-modal
id="lost-masterclasser"
:title="title"
size="md"
:hide-footer="true"
>
<div class="modal-body">
<div class="col-12">
<achievement-avatar class="avatar" />
</div>
<div class="col-6 offset-3 text-center">
<p>{{ $t('achievementLostMasterclasserModalText') }}</p>
<button
class="btn btn-primary"
@click="close()"
>
{{ $t('huzzah') }}
</button>
</div>
</div>
<achievement-footer />
</b-modal>
</template>
<style scoped>
.avatar {
width: 140px;
margin: 0 auto;
margin-bottom: 1.5em;
margin-top: 1.5em;
}
</style>
<script>
import achievementFooter from './achievementFooter';
import achievementAvatar from './achievementAvatar';
import { mapState } from '@/libs/store';
export default {
components: {
achievementFooter,
achievementAvatar,
},
data () {
return {
title: `${this.$t('modalAchievement')} ${this.$t('achievementLostMasterclasser')}`,
};
},
computed: {
...mapState({ user: 'user.data' }),
},
methods: {
close () {
this.$root.$emit('bv::hide::modal', 'lost-masterclasser');
},
},
};
</script>
@@ -1,60 +0,0 @@
<template>
<b-modal
id="mind-over-matter"
:title="title"
size="md"
:hide-footer="true"
>
<div class="modal-body">
<div class="col-12">
<achievement-avatar class="avatar" />
</div>
<div class="col-6 offset-3 text-center">
<p>{{ $t('achievementMindOverMatterModalText') }}</p>
<button
class="btn btn-primary"
@click="close()"
>
{{ $t('huzzah') }}
</button>
</div>
</div>
<achievement-footer />
</b-modal>
</template>
<style scoped>
.avatar {
width: 140px;
margin: 0 auto;
margin-bottom: 1.5em;
margin-top: 1.5em;
}
</style>
<script>
import achievementFooter from './achievementFooter';
import achievementAvatar from './achievementAvatar';
import { mapState } from '@/libs/store';
export default {
components: {
achievementFooter,
achievementAvatar,
},
data () {
return {
title: `${this.$t('modalAchievement')} ${this.$t('achievementMindOverMatter')}`,
};
},
computed: {
...mapState({ user: 'user.data' }),
},
methods: {
close () {
this.$root.$emit('bv::hide::modal', 'mind-over-matter');
},
},
};
</script>
@@ -3,7 +3,7 @@
<creator-intro />
<profileModal />
<report-flag-modal />
<send-gems-modal />
<send-gift-modal />
<select-user-modal />
<b-navbar
id="habitica-menu"
@@ -747,7 +747,7 @@ import creatorIntro from '../creatorIntro';
import notificationMenu from './notificationsDropdown';
import profileModal from '../userMenu/profileModal';
import reportFlagModal from '../chat/reportFlagModal';
import sendGemsModal from '@/components/payments/sendGemsModal';
import sendGiftModal from '@/components/payments/sendGiftModal';
import selectUserModal from '@/components/payments/selectUserModal';
import sync from '@/mixins/sync';
import userDropdown from './userDropdown';
@@ -759,7 +759,7 @@ export default {
notificationMenu,
profileModal,
reportFlagModal,
sendGemsModal,
sendGiftModal,
selectUserModal,
userDropdown,
},
@@ -1,34 +0,0 @@
<template>
<base-notification
:can-remove="canRemove"
:notification="notification"
:read-after-click="true"
@click="action"
>
<div
slot="content"
v-html="achievementString"
></div>
</base-notification>
</template>
<script>
import BaseNotification from './base';
export default {
components: {
BaseNotification,
},
props: ['notification', 'canRemove'],
computed: {
achievementString () {
return `<strong>${this.$t('achievement')}</strong>: ${this.$t('achievementJustAddWater')}`;
},
},
methods: {
action () {
this.$root.$emit('bv::show::modal', 'just-add-water');
},
},
};
</script>
@@ -1,34 +0,0 @@
<template>
<base-notification
:can-remove="canRemove"
:notification="notification"
:read-after-click="true"
@click="action"
>
<div
slot="content"
v-html="achievementString"
></div>
</base-notification>
</template>
<script>
import BaseNotification from './base';
export default {
components: {
BaseNotification,
},
props: ['notification', 'canRemove'],
computed: {
achievementString () {
return `<strong>${this.$t('achievement')}</strong>: ${this.$t('achievementLostMasterclasser')}`;
},
},
methods: {
action () {
this.$root.$emit('bv::show::modal', 'lost-masterclasser');
},
},
};
</script>
@@ -1,34 +0,0 @@
<template>
<base-notification
:can-remove="canRemove"
:notification="notification"
:read-after-click="true"
@click="action"
>
<div
slot="content"
v-html="achievementString"
></div>
</base-notification>
</template>
<script>
import BaseNotification from './base';
export default {
components: {
BaseNotification,
},
props: ['notification', 'canRemove'],
computed: {
achievementString () {
return `<strong>${this.$t('achievement')}</strong>: ${this.$t('achievementMindOverMatter')}`;
},
},
methods: {
action () {
this.$root.$emit('bv::show::modal', 'mind-over-matter');
},
},
};
</script>
@@ -140,9 +140,6 @@ import NEW_INBOX_MESSAGE from './notifications/newPrivateMessage';
import NEW_CHAT_MESSAGE from './notifications/newChatMessage';
import WORLD_BOSS from './notifications/worldBoss';
import VERIFY_USERNAME from './notifications/verifyUsername';
import ACHIEVEMENT_JUST_ADD_WATER from './notifications/justAddWater';
import ACHIEVEMENT_LOST_MASTERCLASSER from './notifications/lostMasterclasser';
import ACHIEVEMENT_MIND_OVER_MATTER from './notifications/mindOverMatter';
import ONBOARDING_COMPLETE from './notifications/onboardingComplete';
import GIFT_ONE_GET_ONE from './notifications/g1g1';
import OnboardingGuide from './onboardingGuide';
@@ -167,9 +164,6 @@ export default {
CARD_RECEIVED,
NEW_INBOX_MESSAGE,
NEW_CHAT_MESSAGE,
ACHIEVEMENT_JUST_ADD_WATER,
ACHIEVEMENT_LOST_MASTERCLASSER,
ACHIEVEMENT_MIND_OVER_MATTER,
WorldBoss: WORLD_BOSS,
VERIFY_USERNAME,
OnboardingGuide,
@@ -194,13 +188,24 @@ export default {
// listed in the order they should appear in the notifications panel.
// NOTE: Those not listed here won't be shown in the notification panel!
handledNotifications: [
'NEW_STUFF', 'GIFT_ONE_GET_ONE', 'GROUP_TASK_NEEDS_WORK',
'GUILD_INVITATION', 'PARTY_INVITATION', 'CHALLENGE_INVITATION',
'QUEST_INVITATION', 'GROUP_TASK_ASSIGNED', 'GROUP_TASK_APPROVAL', 'GROUP_TASK_APPROVED',
'GROUP_TASK_CLAIMED', 'NEW_MYSTERY_ITEMS', 'CARD_RECEIVED',
'NEW_INBOX_MESSAGE', 'NEW_CHAT_MESSAGE', 'UNALLOCATED_STATS_POINTS',
'ACHIEVEMENT_JUST_ADD_WATER', 'ACHIEVEMENT_LOST_MASTERCLASSER', 'ACHIEVEMENT_MIND_OVER_MATTER',
'VERIFY_USERNAME', 'ONBOARDING_COMPLETE',
'NEW_STUFF',
'GIFT_ONE_GET_ONE',
'GROUP_TASK_NEEDS_WORK',
'GUILD_INVITATION',
'PARTY_INVITATION',
'CHALLENGE_INVITATION',
'QUEST_INVITATION',
'GROUP_TASK_ASSIGNED',
'GROUP_TASK_APPROVAL',
'GROUP_TASK_APPROVED',
'GROUP_TASK_CLAIMED',
'NEW_MYSTERY_ITEMS',
'CARD_RECEIVED',
'NEW_INBOX_MESSAGE',
'NEW_CHAT_MESSAGE',
'UNALLOCATED_STATS_POINTS',
'VERIFY_USERNAME',
'ONBOARDING_COMPLETE',
],
};
},
+116 -323
View File
@@ -30,9 +30,6 @@
v-if="notificationData && notificationData.achievement"
:data="notificationData"
/>
<just-add-water />
<lost-masterclasser />
<mind-over-matter />
<onboarding-complete />
<first-drops />
</div>
@@ -141,25 +138,34 @@ import streak from './achievements/streak';
import ultimateGear from './achievements/ultimateGear';
import wonChallenge from './achievements/wonChallenge';
import genericAchievement from './achievements/genericAchievement';
import justAddWater from './achievements/justAddWater';
import lostMasterclasser from './achievements/lostMasterclasser';
import mindOverMatter from './achievements/mindOverMatter';
import loginIncentives from './achievements/login-incentives';
import onboardingComplete from './achievements/onboardingComplete';
import verifyUsername from './settings/verifyUsername';
import firstDrops from './achievements/firstDrops';
const NOTIFICATIONS = {
// general notifications
NEW_CONTRIBUTOR_LEVEL: {
achievement: true,
label: $t => $t('modalContribAchievement'),
modalId: 'contributor',
sticky: true,
},
// achievement notifications
ACHIEVEMENT: { // null data filled in handleUserNotifications
achievement: true,
modalId: 'generic-achievement',
label: null,
data: {
message: $t => $t('achievement'),
modalText: null,
},
},
CHALLENGE_JOINED_ACHIEVEMENT: {
achievement: true,
label: $t => `${$t('achievement')}: ${$t('joinedChallenge')}`,
modalId: 'joined-challenge',
},
ULTIMATE_GEAR_ACHIEVEMENT: {
achievement: true,
label: $t => `${$t('achievement')}: ${$t('gearAchievementNotification')}`,
modalId: 'ultimate-gear',
},
GUILD_JOINED_ACHIEVEMENT: {
label: $t => `${$t('achievement')}: ${$t('joinedGuild')}`,
achievement: true,
@@ -170,42 +176,14 @@ const NOTIFICATIONS = {
label: $t => `${$t('achievement')}: ${$t('invitedFriend')}`,
modalId: 'invited-friend',
},
NEW_CONTRIBUTOR_LEVEL: {
ACHIEVEMENT_PARTY_ON: {
achievement: true,
label: $t => $t('modalContribAchievement'),
modalId: 'contributor',
sticky: true,
},
ACHIEVEMENT_ALL_YOUR_BASE: {
achievement: true,
label: $t => `${$t('achievement')}: ${$t('achievementAllYourBase')}`,
label: $t => `${$t('achievement')}: ${$t('achievementPartyOn')}`,
modalId: 'generic-achievement',
data: {
achievement: 'allYourBase', // defined manually until the server sends all the necessary data
},
},
ACHIEVEMENT_BACK_TO_BASICS: {
achievement: true,
label: $t => `${$t('achievement')}: ${$t('achievementBackToBasics')}`,
modalId: 'generic-achievement',
data: {
achievement: 'backToBasics',
},
},
ACHIEVEMENT_DUST_DEVIL: {
achievement: true,
label: $t => `${$t('achievement')}: ${$t('achievementDustDevil')}`,
modalId: 'generic-achievement',
data: {
achievement: 'dustDevil',
},
},
ACHIEVEMENT_ARID_AUTHORITY: {
achievement: true,
label: $t => `${$t('achievement')}: ${$t('achievementAridAuthority')}`,
modalId: 'generic-achievement',
data: {
achievement: 'aridAuthority',
message: $t => $t('achievement'),
modalText: $t => $t('achievementPartyOn'),
achievement: 'partyOn',
},
},
ACHIEVEMENT_PARTY_UP: {
@@ -218,245 +196,47 @@ const NOTIFICATIONS = {
achievement: 'partyUp',
},
},
ACHIEVEMENT_PARTY_ON: {
ULTIMATE_GEAR_ACHIEVEMENT: {
achievement: true,
label: $t => `${$t('achievement')}: ${$t('gearAchievementNotification')}`,
modalId: 'ultimate-gear',
},
ACHIEVEMENT_STABLE: {
achievement: true,
label: $t => `${$t('achievement')}: ${$t('achievementPartyOn')}`,
modalId: 'generic-achievement',
data: {
message: $t => $t('achievement'),
modalText: $t => $t('achievementPartyOn'),
achievement: 'partyOn',
achievement: 'stableAchievs',
},
},
ACHIEVEMENT_BEAST_MASTER: {
ACHIEVEMENT_QUESTS: {
achievement: true,
label: $t => `${$t('achievement')}: ${$t('beastAchievement')}`,
modalId: 'generic-achievement',
data: {
message: $t => $t('achievement'),
modalText: $t => $t('beastAchievement'),
achievement: 'beastMaster',
achievement: 'questSeriesAchievs',
},
},
ACHIEVEMENT_MOUNT_MASTER: {
ACHIEVEMENT_ANIMAL_SET: {
achievement: true,
label: $t => `${$t('achievement')}: ${$t('mountAchievement')}`,
label: $t => `${$t('achievement')}: ${$t('achievementAnimalSet')}`,
modalId: 'generic-achievement',
data: {
message: $t => $t('achievement'),
modalText: $t => $t('mountAchievement'),
achievement: 'mountMaster',
achievement: 'animalSetAchievs',
},
},
ACHIEVEMENT_TRIAD_BINGO: {
ACHIEVEMENT_PET_COLOR: {
achievement: true,
label: $t => `${$t('achievement')}: ${$t('triadBingoAchievement')}`,
label: $t => `${$t('achievement')}: ${$t('achievementPetColor')}`,
modalId: 'generic-achievement',
data: {
message: $t => $t('achievement'),
modalText: $t => $t('triadBingoAchievement'),
achievement: 'triadBingo',
achievement: 'petColorAchievs',
},
},
ACHIEVEMENT_MONSTER_MAGUS: {
ACHIEVEMENT_MOUNT_COLOR: {
achievement: true,
label: $t => `${$t('achievement')}: ${$t('achievementMonsterMagus')}`,
label: $t => `${$t('achievement')}: ${$t('achievementMountColor')}`,
modalId: 'generic-achievement',
data: {
achievement: 'monsterMagus',
},
},
ACHIEVEMENT_UNDEAD_UNDERTAKER: {
achievement: true,
label: $t => `${$t('achievement')}: ${$t('achievementUndeadUndertaker')}`,
modalId: 'generic-achievement',
data: {
achievement: 'undeadUndertaker',
},
},
ACHIEVEMENT: { // data filled in handleUserNotifications
achievement: true,
modalId: 'generic-achievement',
label: null, // data filled in handleUserNotifications
data: {
message: $t => $t('achievement'),
modalText: null, // data filled in handleUserNotifications
},
},
ACHIEVEMENT_PRIMED_FOR_PAINTING: {
achievement: true,
label: $t => `${$t('achievement')}: ${$t('achievementPrimedForPainting')}`,
modalId: 'generic-achievement',
data: {
achievement: 'primedForPainting',
},
},
ACHIEVEMENT_PEARLY_PRO: {
achievement: true,
label: $t => `${$t('achievement')}: ${$t('achievementPearlyPro')}`,
modalId: 'generic-achievement',
data: {
achievement: 'pearlyPro',
},
},
ACHIEVEMENT_TICKLED_PINK: {
achievement: true,
label: $t => `${$t('achievement')}: ${$t('achievementTickledPink')}`,
modalId: 'generic-achievement',
data: {
achievement: 'tickledPink',
},
},
ACHIEVEMENT_ROSY_OUTLOOK: {
achievement: true,
label: $t => `${$t('achievement')}: ${$t('achievementRosyOutlook')}`,
modalId: 'generic-achievement',
data: {
achievement: 'rosyOutlook',
},
},
ACHIEVEMENT_BUG_BONANZA: {
achievement: true,
label: $t => `${$t('achievement')}: ${$t('achievementBugBonanza')}`,
modalId: 'generic-achievement',
data: {
achievement: 'bugBonanza',
},
},
ACHIEVEMENT_BARE_NECESSITIES: {
achievement: true,
label: $t => `${$t('achievement')}: ${$t('achievementBareNecessities')}`,
modalId: 'generic-achievement',
data: {
achievement: 'bareNecessities',
},
},
ACHIEVEMENT_FRESHWATER_FRIENDS: {
achievement: true,
label: $t => `${$t('achievement')}: ${$t('achievementFreshwaterFriends')}`,
modalId: 'generic-achievement',
data: {
achievement: 'freshwaterFriends',
},
},
ACHIEVEMENT_GOOD_AS_GOLD: {
achievement: true,
label: $t => `${$t('achievement')}: ${$t('achievementGoodAsGold')}`,
modalId: 'generic-achievement',
data: {
achievement: 'goodAsGold',
},
},
ACHIEVEMENT_ALL_THAT_GLITTERS: {
achievement: true,
label: $t => `${$t('achievement')}: ${$t('achievementAllThatGlitters')}`,
modalId: 'generic-achievement',
data: {
achievement: 'allThatGlitters',
},
},
ACHIEVEMENT_BONE_COLLECTOR: {
achievement: true,
label: $t => `${$t('achievement')}: ${$t('achievementBoneCollector')}`,
modalId: 'generic-achievement',
data: {
achievement: 'boneCollector',
},
},
ACHIEVEMENT_SKELETON_CREW: {
achievement: true,
label: $t => `${$t('achievement')}: ${$t('achievementSkeletonCrew')}`,
modalId: 'generic-achievement',
data: {
achievement: 'skeletonCrew',
},
},
ACHIEVEMENT_SEEING_RED: {
achievement: true,
label: $t => `${$t('achievement')}: ${$t('achievementSeeingRed')}`,
modalId: 'generic-achievement',
data: {
achievement: 'seeingRed',
},
},
ACHIEVEMENT_RED_LETTER_DAY: {
achievement: true,
label: $t => `${$t('achievement')}: ${$t('achievementRedLetterDay')}`,
modalId: 'generic-achievement',
data: {
achievement: 'redLetterDay',
},
},
ACHIEVEMENT_LEGENDARY_BESTIARY: {
achievement: true,
label: $t => `${$t('achievement')}: ${$t('achievementLegendaryBestiary')}`,
modalId: 'generic-achievement',
data: {
achievement: 'legendaryBestiary',
},
},
ACHIEVEMENT_SEASONAL_SPECIALIST: {
achievement: true,
label: $t => `${$t('achievement')}: ${$t('achievementSeasonalSpecialist')}`,
modalId: 'generic-achievement',
data: {
achievement: 'seasonalSpecialist',
},
},
ACHIEVEMENT_VIOLETS_ARE_BLUE: {
achievement: true,
label: $t => `${$t('achievement')}: ${$t('achievementVioletsAreBlue')}`,
modalId: 'generic-achievement',
data: {
achievement: 'violetsAreBlue',
},
},
ACHIEVEMENT_WILD_BLUE_YONDER: {
achievement: true,
label: $t => `${$t('achievement')}: ${$t('achievementWildBlueYonder')}`,
modalId: 'generic-achievement',
data: {
achievement: 'wildBlueYonder',
},
},
ACHIEVEMENT_DOMESTICATED: {
achievement: true,
label: $t => `${$t('achievement')}: ${$t('achievementDomesticated')}`,
modalId: 'generic-achievement',
data: {
achievement: 'domesticated',
},
},
ACHIEVEMENT_SHADY_CUSTOMER: {
achievement: true,
label: $t => `${$t('achievement')}: ${$t('achievementShadyCustomer')}`,
modalId: 'generic-achievement',
data: {
achievement: 'shadyCustomer',
},
},
ACHIEVEMENT_SHADE_OF_IT_ALL: {
achievement: true,
label: $t => `${$t('achievement')}: ${$t('achievementShadeOfItAll')}`,
modalId: 'generic-achievement',
data: {
achievement: 'shadeOfItAll',
},
},
ACHIEVEMENT_ZODIAC_ZOOKEEPER: {
achievement: true,
label: $t => `${$t('achievement')}: ${$t('achievementZodiacZookeeper')}`,
modalId: 'generic-achievement',
data: {
achievement: 'zodiacZookeeper',
},
},
ACHIEVEMENT_BIRDS_OF_A_FEATHER: {
achievement: true,
label: $t => `${$t('achievement')}: ${$t('achievementBirdsOfAFeather')}`,
modalId: 'generic-achievement',
data: {
achievement: 'birdsOfAFeather',
achievement: 'mountColorAchievs',
},
},
};
@@ -486,9 +266,6 @@ export default {
loginIncentives,
verifyUsername,
genericAchievement,
lostMasterclasser,
mindOverMatter,
justAddWater,
onboardingComplete,
firstDrops,
},
@@ -509,21 +286,30 @@ export default {
const handledNotifications = {};
[
'GUILD_PROMPT', 'REBIRTH_ENABLED', 'WON_CHALLENGE', 'STREAK_ACHIEVEMENT',
'ULTIMATE_GEAR_ACHIEVEMENT', 'REBIRTH_ACHIEVEMENT', 'GUILD_JOINED_ACHIEVEMENT',
'CHALLENGE_JOINED_ACHIEVEMENT', 'INVITED_FRIEND_ACHIEVEMENT', 'NEW_CONTRIBUTOR_LEVEL',
'CRON', 'LOGIN_INCENTIVE', 'ACHIEVEMENT_ALL_YOUR_BASE', 'ACHIEVEMENT_BACK_TO_BASICS',
'GENERIC_ACHIEVEMENT', 'ACHIEVEMENT_PARTY_UP', 'ACHIEVEMENT_PARTY_ON', 'ACHIEVEMENT_BEAST_MASTER',
'ACHIEVEMENT_MOUNT_MASTER', 'ACHIEVEMENT_TRIAD_BINGO', 'ACHIEVEMENT_DUST_DEVIL', 'ACHIEVEMENT_ARID_AUTHORITY',
'ACHIEVEMENT_MONSTER_MAGUS', 'ACHIEVEMENT_UNDEAD_UNDERTAKER', 'ACHIEVEMENT_PRIMED_FOR_PAINTING',
'ACHIEVEMENT_PEARLY_PRO', 'ACHIEVEMENT_TICKLED_PINK', 'ACHIEVEMENT_ROSY_OUTLOOK', 'ACHIEVEMENT',
'ONBOARDING_COMPLETE', 'FIRST_DROPS', 'ACHIEVEMENT_BUG_BONANZA', 'ACHIEVEMENT_BARE_NECESSITIES',
'ACHIEVEMENT_FRESHWATER_FRIENDS', 'ACHIEVEMENT_GOOD_AS_GOLD', 'ACHIEVEMENT_ALL_THAT_GLITTERS',
'ACHIEVEMENT_BONE_COLLECTOR', 'ACHIEVEMENT_SKELETON_CREW', 'ACHIEVEMENT_SEEING_RED',
'ACHIEVEMENT_RED_LETTER_DAY', 'ACHIEVEMENT_LEGENDARY_BESTIARY', 'ACHIEVEMENT_SEASONAL_SPECIALIST',
'ACHIEVEMENT_VIOLETS_ARE_BLUE', 'ACHIEVEMENT_WILD_BLUE_YONDER', 'ACHIEVEMENT_DOMESTICATED',
'ACHIEVEMENT_SHADY_CUSTOMER', 'ACHIEVEMENT_SHADE_OF_IT_ALL', 'ACHIEVEMENT_ZODIAC_ZOOKEEPER',
'ACHIEVEMENT_BIRDS_OF_A_FEATHER',
// general notifications
'CRON',
'FIRST_DROPS',
'GUILD_PROMPT',
'LOGIN_INCENTIVE',
'NEW_CONTRIBUTOR_LEVEL',
'ONBOARDING_COMPLETE',
'REBIRTH_ENABLED',
'WON_CHALLENGE',
// achievement notifications
'ACHIEVEMENT',
'CHALLENGE_JOINED_ACHIEVEMENT',
'GUILD_JOINED_ACHIEVEMENT',
'INVITED_FRIEND_ACHIEVEMENT',
'ACHIEVEMENT_PARTY_ON',
'ACHIEVEMENT_PARTY_UP',
'REBIRTH_ACHIEVEMENT',
'STREAK_ACHIEVEMENT',
'ULTIMATE_GEAR_ACHIEVEMENT',
'ACHIEVEMENT_STABLE',
'ACHIEVEMENT_QUESTS',
'ACHIEVEMENT_ANIMAL_SET',
'ACHIEVEMENT_PET_COLOR',
'ACHIEVEMENT_MOUNT_COLOR',
].forEach(type => {
handledNotifications[type] = true;
});
@@ -921,57 +707,68 @@ export default {
case 'WON_CHALLENGE':
this.$root.$emit('habitica:won-challenge', notification);
break;
case 'REBIRTH_ACHIEVEMENT':
this.playSound('Achievement_Unlocked');
this.$root.$emit('bv::show::modal', 'rebirth');
break;
case 'STREAK_ACHIEVEMENT':
this.text(`${this.$t('streaks')}: ${this.user.achievements.streak}`, () => {
this.$root.$emit('bv::show::modal', 'streak');
}, this.user.preferences.suppressModals.streak);
this.playSound('Achievement_Unlocked');
break;
case 'REBIRTH_ACHIEVEMENT':
this.playSound('Achievement_Unlocked');
this.$root.$emit('bv::show::modal', 'rebirth');
break;
case 'ULTIMATE_GEAR_ACHIEVEMENT':
case 'GUILD_JOINED_ACHIEVEMENT':
case 'CHALLENGE_JOINED_ACHIEVEMENT':
case 'INVITED_FRIEND_ACHIEVEMENT':
case 'NEW_CONTRIBUTOR_LEVEL':
case 'ACHIEVEMENT_ALL_YOUR_BASE':
case 'ACHIEVEMENT_BACK_TO_BASICS':
case 'ACHIEVEMENT_DUST_DEVIL':
case 'ACHIEVEMENT_ARID_AUTHORITY':
case 'ACHIEVEMENT_PARTY_UP':
case 'CHALLENGE_JOINED_ACHIEVEMENT':
case 'GUILD_JOINED_ACHIEVEMENT':
case 'INVITED_FRIEND_ACHIEVEMENT':
case 'ACHIEVEMENT_PARTY_ON':
case 'ACHIEVEMENT_BEAST_MASTER':
case 'ACHIEVEMENT_MOUNT_MASTER':
case 'ACHIEVEMENT_TRIAD_BINGO':
case 'ACHIEVEMENT_MONSTER_MAGUS':
case 'ACHIEVEMENT_UNDEAD_UNDERTAKER':
case 'ACHIEVEMENT_PRIMED_FOR_PAINTING':
case 'ACHIEVEMENT_PEARLY_PRO':
case 'ACHIEVEMENT_TICKLED_PINK':
case 'ACHIEVEMENT_ROSY_OUTLOOK':
case 'ACHIEVEMENT_BUG_BONANZA':
case 'ACHIEVEMENT_BARE_NECESSITIES':
case 'ACHIEVEMENT_FRESHWATER_FRIENDS':
case 'ACHIEVEMENT_GOOD_AS_GOLD':
case 'ACHIEVEMENT_ALL_THAT_GLITTERS':
case 'ACHIEVEMENT_BONE_COLLECTOR':
case 'ACHIEVEMENT_SKELETON_CREW':
case 'ACHIEVEMENT_SEEING_RED':
case 'ACHIEVEMENT_RED_LETTER_DAY':
case 'ACHIEVEMENT_LEGENDARY_BESTIARY':
case 'ACHIEVEMENT_SEASONAL_SPECIALIST':
case 'ACHIEVEMENT_VIOLETS_ARE_BLUE':
case 'ACHIEVEMENT_WILD_BLUE_YONDER':
case 'ACHIEVEMENT_DOMESTICATED':
case 'ACHIEVEMENT_SHADY_CUSTOMER':
case 'ACHIEVEMENT_SHADE_OF_IT_ALL':
case 'ACHIEVEMENT_ZODIAC_ZOOKEEPER':
case 'ACHIEVEMENT_BIRDS_OF_A_FEATHER':
case 'GENERIC_ACHIEVEMENT':
case 'ACHIEVEMENT_PARTY_UP':
case 'ULTIMATE_GEAR_ACHIEVEMENT':
this.showNotificationWithModal(notification);
break;
case 'ACHIEVEMENT_QUESTS': {
const { achievement } = notification.data;
const upperCaseAchievement = achievement.charAt(0).toUpperCase() + achievement.slice(1);
const achievementTitleKey = `achievement${upperCaseAchievement}`;
NOTIFICATIONS.ACHIEVEMENT_QUESTS.label = $t => `${$t('achievement')}: ${$t(achievementTitleKey)}`;
this.showNotificationWithModal(notification);
Vue.set(this.user.achievements, achievement, true);
break;
}
case 'ACHIEVEMENT_STABLE': {
const { achievement, achievementNotification } = notification.data;
NOTIFICATIONS.ACHIEVEMENT_STABLE.label = $t => `${$t('achievement')}: ${$t(achievementNotification)}`;
this.showNotificationWithModal(notification);
Vue.set(this.user.achievements, achievement, true);
break;
}
case 'ACHIEVEMENT_ANIMAL_SET': {
const { achievement } = notification.data;
const upperCaseAchievement = achievement.charAt(0).toUpperCase() + achievement.slice(1);
const achievementTitleKey = `achievement${upperCaseAchievement}`;
NOTIFICATIONS.ACHIEVEMENT_ANIMAL_SET.label = $t => `${$t('achievement')}: ${$t(achievementTitleKey)}`;
this.showNotificationWithModal(notification);
Vue.set(this.user.achievements, achievement, true);
break;
}
case 'ACHIEVEMENT_PET_COLOR': {
const { achievement } = notification.data;
const upperCaseAchievement = achievement.charAt(0).toUpperCase() + achievement.slice(1);
const achievementTitleKey = `achievement${upperCaseAchievement}`;
NOTIFICATIONS.ACHIEVEMENT_PET_COLOR.label = $t => `${$t('achievement')}: ${$t(achievementTitleKey)}`;
this.showNotificationWithModal(notification);
Vue.set(this.user.achievements, achievement, true);
break;
}
case 'ACHIEVEMENT_MOUNT_COLOR': {
const { achievement } = notification.data;
const upperCaseAchievement = achievement.charAt(0).toUpperCase() + achievement.slice(1);
const achievementTitleKey = `achievement${upperCaseAchievement}`;
NOTIFICATIONS.ACHIEVEMENT_MOUNT_COLOR.label = $t => `${$t('achievement')}: ${$t(achievementTitleKey)}`;
this.showNotificationWithModal(notification);
Vue.set(this.user.achievements, achievement, true);
break;
}
case 'ACHIEVEMENT': { // generic achievement
const { achievement } = notification.data;
const upperCaseAchievement = achievement.charAt(0).toUpperCase() + achievement.slice(1);
@@ -984,10 +781,6 @@ export default {
Vue.set(this.user.achievements, achievement, true);
break;
}
case 'CRON':
// Not needed because it's shown already by the userHp and userMp watchers
// Keeping an empty block so that it gets read
break;
case 'LOGIN_INCENTIVE':
if (this.user.flags.tour.intro === this.TOUR_END && this.user.flags.welcomed) {
this.notificationData = notification.data;
@@ -1,5 +1,6 @@
<template>
<div class="payments-column mx-auto mt-auto">
<h4>{{ $t('choosePaymentMethod') }}</h4>
<button
v-if="stripeAvailable"
class="btn btn-primary payment-button payment-item with-icon"
@@ -80,6 +81,13 @@
cursor: default !important;
}
}
h4 {
font-size: 0.875rem;
font-weight: bold;
text-align: center;
margin-bottom: 1rem;
}
</style>
<script>
@@ -14,15 +14,44 @@
</div>
<h2
v-else
class="ml-2"
class="d-flex flex-column mx-auto align-items-center"
>
{{ $t('sendGift') }}
{{ $t('sendAGift') }}
</h2>
<div
v-if="currentEvent && currentEvent.promo === 'g1g1'"
class="g1g1-margin d-flex flex-column align-items-center"
>
<div
class="svg-big-gift"
v-once
v-html="icons.bigGift"
></div>
</div>
<div
v-else
class="d-flex flex-column align-items-center">
<div
class="svg-big-gift"
v-once
v-html="icons.bigGift"
></div>
</div>
<div class="d-flex flex-column align-items-center">
<div
class="modal-close"
v-if="currentEvent && currentEvent.promo === 'g1g1'"
class="g1g1-modal-close"
@click="close()"
>
<div
class="g1g1-svg-icon"
v-html="icons.close"
></div>
</div>
<div
v-else
class="modal-close"
@click="close()">
<div
class="svg-icon"
v-html="icons.close"
@@ -42,6 +71,7 @@
v-model="userSearchTerm"
class="form-control"
type="text"
ref="textBox"
:placeholder="$t('usernameOrUserId')"
:class="{
'input-valid': foundUser._id,
@@ -70,15 +100,20 @@
<div
v-else
>
{{ $t('selectGift') }}
{{ $t('next') }}
</div>
</button>
<a
class="cancel-link mx-auto mt-3"
@click="close()"
<div
v-if="currentEvent && currentEvent.promo ==='g1g1'"
class="g1g1-cancel d-flex justify-content-center"
v-html="$t('cancel')"
@click="close()"
>
{{ $t('cancel') }}
</a>
{{ $t('cancel') }}
</div>
<div
v-else>
</div>
</div>
</div>
</div>
@@ -110,13 +145,16 @@
@import '~@/assets/scss/mixins.scss';
#select-user-modal {
.modal-content {
width:448px;
}
.input-group {
margin-top: 0rem;
}
.modal-dialog {
width: 29.5rem;
margin-top: 25vh;
width: 448px;
}
.modal-footer {
@@ -126,7 +164,16 @@
margin: 0rem 0.25rem 0.25rem 0.25rem;
}
}
}
body.modal-open .modal {
display: flex !important;
height: 100%;
}
body.modal-open .modal .modal-dialog {
margin: auto;
}
}
</style>
<style lang="scss" scoped>
@@ -146,12 +193,12 @@
.g1g1 {
background-image: url('~@/assets/images/g1g1-send.png');
background-size: 472px 152px;
width: 470px;
background-size: 446px 152px;
width: 446px;
height: 152px;
margin: -1rem 0rem 0rem -1rem;
border-radius: 0.3rem 0.3rem 0rem 0rem;
padding: 1.5rem;
margin: -16px 0px 0px -16px;
border-radius: 4.8px 4.8px 0px 0px;
padding: 24px;
color: $white;
h1 {
@@ -169,6 +216,16 @@
}
}
.g1g1-margin {
margin-top: 24px;
}
.g1g1-cancel {
margin-top: 16px;
color: $blue-10;
cursor: pointer;
}
.g1g1-fine-print {
color: $gray-100;
background-color: $gray-700;
@@ -176,6 +233,29 @@
line-height: 1.33;
}
.g1g1-modal-close {
position: absolute;
width: 18px;
height: 18px;
padding: 4px;
right: 16px;
top: 16px;
cursor: pointer;
.g1g1-svg-icon {
width: 12px;
height: 12px;
& ::v-deep svg path {
fill: #FFFFFF;
}
}
}
.g1g1-modal-dialog {
margin-top: 10vh;
}
.input-error {
color: $red-50;
font-size: 90%;
@@ -192,6 +272,18 @@
border-color: $purple-500;
}
h2 {
font-size: 1.25rem;
line-height: 1.75rem;
color: $purple-300;
padding-top: 1rem;
}
.svg-big-gift {
width: 176px;
height: 64px;
}
.modal-close {
position: absolute;
width: 18px;
@@ -206,14 +298,17 @@
height: 12px;
}
}
</style>
<script>
// import { nextTick } from 'vue'; // may not need this? I don't know!
import debounce from 'lodash/debounce';
import find from 'lodash/find';
import isUUID from 'validator/lib/isUUID';
import { mapState } from '@/libs/store';
import closeIcon from '@/assets/svg/close.svg';
import bigGiftIcon from '@/assets/svg/big-gift.svg';
export default {
data () {
@@ -223,6 +318,7 @@ export default {
foundUser: {},
icons: Object.freeze({
close: closeIcon,
bigGift: bigGiftIcon,
}),
};
},
@@ -281,7 +377,7 @@ export default {
this.foundUser = result;
}, 500),
selectUser () {
this.$root.$emit('habitica::send-gems', this.foundUser);
this.$root.$emit('habitica::send-gift', this.foundUser);
this.close();
},
onHide () {
@@ -0,0 +1,634 @@
<template>
<b-modal
id="send-gift"
:hide-footer="true"
:hide-header="true"
size="md"
@hide="onHide()"
>
<div>
<!-- header -->
<div
class="modal-close"
@click="close()"
>
<div
class="icon-close"
v-html="icons.closeIcon"
>
</div>
</div>
<div>
<h2 class="d-flex flex-column mx-auto align-items-center">
{{ $t('sendAGift') }}
</h2>
</div>
<!-- user avatar -->
<div
v-if="userReceivingGift"
class="modal-body"
>
<avatar
:member="userReceivingGift"
:hideClassBadge="true"
class="d-flex flex-column mx-auto align-items-center"
/>
<div class="avatar-spacer"></div>
<div class="d-flex flex-column mx-auto align-items-center display-name">
<!-- user display name and username -->
<user-link
:user-id="displayName"
:name="displayName"
:backer="userBacker"
:contributor="userContributor"
:class="display-name"
/>
</div>
<div class="d-flex flex-column mx-auto align-items-center user-name">
@{{ userName }}
</div>
</div>
<!-- menu area -->
<div class="row">
<div class="col-12 col-md-8 offset-md-2 text-center nav">
<div
class="nav-item"
:class="{active: selectedPage === 'subscription'}"
@click="selectPage('subscription')"
>
{{ $t('subscription') }}
</div>
<div
class="nav-item"
:class="{active: selectedPage !== 'subscription'}"
@click="selectPage('buyGems')"
>
{{ $t('gems') }}
</div>
</div>
</div>
<!-- subscriber block -->
<subscription-options
v-show="selectedPage === 'subscription'"
class="subscribe-option"
/>
<!-- gem block -->
<div
v-show="selectedPage === 'buyGems'"
>
<div class="gem-group">
<!-- buy gems with money -->
<label v-once>
{{ $t('howManyGemsPurchase') }}
</label>
<div class="d-flex flex-row align-items-center justify-content-center">
<div
class="gray-circle"
@click="gift.gems.amount <= 0 ? gift.gems.amount = 0 : gift.gems.amount--"
>
<div
class="icon-negative"
v-html="icons.negativeIcon"
></div>
</div>
<div class="input-group">
<div class="input-group-prepend input-group-icon align-items-center">
<div
class="icon-gem"
v-html="icons.gemIcon"
></div>
</div>
<input
id="gemsForm"
v-model.number="gift.gems.amount"
class="form-control"
min="0"
max="9999"
>
</div>
<div
class="gray-circle"
@click="gift.gems.amount++"
>
<div
class="icon-positive"
v-html="icons.positiveIcon"
></div>
</div>
</div>
<!-- the word "total" -->
<div class="buy-gem-total">
{{ $t('sendGiftTotal') }}
</div>
<!-- the actual dollar amount -->
<div class="buy-gem-amount">
<span>
{{formatter.format(totalGems)}}
</span>
</div>
<!-- change to sending own gems page -->
<div
:class="{active: selectedPage === 'ownGems'}"
@click="selectPage('ownGems')"
class="gem-state-change"
>
{{ $t('wantToSendOwnGems') }}
</div>
</div>
<!-- paying for gems -->
<payments-buttons
class="payment-buttons"
:stripe-fn="() => redirectToStripe({gift, uuid: userReceivingGift._id, receiverName})"
:paypal-fn="() => openPaypalGift({
gift: gift, giftedTo: userReceivingGift._id, receiverName,
})"
:amazon-data="{type: 'single', gift, giftedTo: userReceivingGift._id, receiverName}"
/>
</div>
<!-- send gems from balance -->
<div
v-show="selectedPage === 'ownGems'"
>
<div class="gem-group">
<label v-once>
{{ $t('howManyGemsSend') }}
</label>
<div class="d-flex align-items-center justify-content-center">
<div
class="gray-circle"
@click="gift.gems.amount <= 0 ? gift.gems.amount = 0 : gift.gems.amount--"
>
<div
class="icon-negative"
v-html="icons.negativeIcon"
></div>
</div>
<div class="input-group">
<div class="input-group-prepend input-group-icon align-items-center">
<div
class="icon-gem"
v-html="icons.gemIcon"
></div>
</div>
<input
id="gemsForm"
v-model="gift.gems.amount"
class="form-control"
min="0"
:max="maxGems"
>
</div>
<div
class="gray-circle"
@click="gift.gems.amount < maxGems ? gift.gems.amount++ : gift.gems.amount = maxGems"
>
<div
class="icon-positive"
v-html="icons.positiveIcon"
></div>
</div>
</div>
<div class="align-items-middle">
<div class="d-flex justify-content-center align-items-middle">
<span class="balance-text">
{{ $t('yourBalance') }}
</span>
<span
class="icon-gem balance-gem-margin"
v-html="icons.gemIcon"
style="display: inline-block;"
></span>
<span
class="balance-gems">
{{ maxGems }}
</span>
</div>
</div>
<div class="d-flex flex-column justify-content-center align-items-middle mt-3">
<button
v-if="fromBal"
class="btn btn-primary mx-auto mt-2"
type="submit"
:disabled="sendingInProgress"
@click="sendGift()"
>
{{ $t("send") }}
</button>
</div>
<!-- change to buying gems page -->
<div
:class="{active: selectedPage === 'buyGems'}"
@click="selectPage('buyGems')"
class="gem-state-change"
>
{{ $t('needToPurchaseGems') }}
</div>
</div>
</div>
</div>
</b-modal>
</template>
<style lang="scss">
@import '~@/assets/scss/mixins.scss';
#send-gift {
.modal-dialog {
max-width: 448px;
}
.modal-content {
width: 448px;
border-radius: 8px;
box-shadow: 0 14px 28px 0 rgba(26, 24, 29, 0.24), 0 10px 10px 0 rgba(26, 24, 29, 0.28);
}
.modal-body{
padding: 0px;
}
.modal-close {
position: absolute;
width: 18px;
height: 18px;
padding: 4px;
right: 16px;
top: 16px;
cursor: pointer;
.icon-close {
width: 15px;
height: 15px;
& ::v-deep svg path {
fill: #878190;
}
}
}
#subscription-form .subscribe-option {
background: #F9F9F9;
}
}
</style>
<style scoped lang="scss">
@import '~@/assets/scss/colors.scss';
h2 {
color: $purple-300;
padding-top: 2rem;
}
.avatar-spacer {
height: 9px;
}
.display-name {
font-size: 0.875rem;
font-weight: bold;
line-height: 1.71;
margin: 0px 6px 0 20px;
}
.display-name a:hover{
text-decoration: none;
}
.user-name {
font-size: 0.75rem;
line-height: 1.33;
text-align: center;
color: $gray-100;
padding-bottom: 16px;
}
.row {
background-color: $gray-700;
margin: 0 0 0 0;
min-height: 32px;
}
.nav {
font-weight: bold;
font-size: 0.75rem;
min-height: 32px;
padding: 16px 0 0 0;
color: $purple-300;
justify-content: center;
}
.nav-item {
display: inline-block;
padding: 0px 8px 6px 8px;
}
.nav-item:hover, .nav-item.active {
color: $purple-300;
border-bottom: 2px solid $purple-400;
cursor: pointer;
}
.nav-item.inactive {
color: $purple-300;
border-bottom: 0px;
cursor: pointer;
}
.gem-group {
padding: 0 0 24px 0;
background-color: $gray-700;
margin: 0 0 0 0;
border-bottom-right-radius: 8px;
border-bottom-left-radius: 8px
}
label {
color: $gray-50;
font-size: 0.875rem;
font-weight: bold;
line-height: 1.71;
margin: 12px 0 16px 0;
width: 100%;
text-align: center;
}
.input-group {
width: 94px;
height: 32px;
margin: 0px 16px 0px 16px;
padding: 0;
border-radius: 2px;
border: solid 1px $gray-400;
background-color: $white;
}
.gray-circle {
border-radius: 100%;
border: solid 2px $gray-300;
width: 32px;
height: 32px;
cursor: pointer;
&:hover {
border-color: $purple-400;
}
}
.gray-circle:hover{
.icon-positive, .icon-negative {
& ::v-deep svg path {
fill: $purple-400;
}
}
}
.icon-gem {
width: 16px;
height: 16px;
}
.icon-positive, .icon-negative {
width: 10px;
height: 10px;
margin: 4px auto;
& ::v-deep svg path {
fill: $gray-300;
}
}
.buy-gem-total {
font-size: 0.875rem;
font-weight: bold;
line-height: 1.71;
padding-top: 24px;
text-align: center;
height: 28px;
}
.buy-gem-amount {
font-size: 1.25rem;
font-weight: bold;
line-height: 1.4;
margin: 16px 0 24px 0;
text-align: center;
height: 28px;
color: $green-10;
}
.balance-text {
font-size: 0.75rem;
font-weight: bold;
color: $gray-100;
line-height: 1.33;
margin: 12px 0px 0px 70px;
}
.balance-gem-margin {
margin: 8px 4px 0px 8px;
}
.balance-gems {
font-size: 0.75rem;
color: $gray-100;
line-height: 1.33;
margin: 12px 71px 0px 4px;
}
.gem-state-change {
color: $blue-10;
font-size: 0.875rem;
min-height: 24px;
margin: 16px 0 0;
text-align: center;
cursor: pointer;
}
.subscribe-option {
border-bottom-left-radius: 8px;
border-bottom-right-radius: 8px;
padding-bottom: 24px;
}
.payment-buttons {
padding: 24px 0;
}
</style>
<script>
// libs imports
import { mapState } from '@/libs/store';
// mixins imports
import paymentsMixin from '../../mixins/payments';
// component imports
import avatar from '../avatar';
import userLink from '../userLink';
import subscriptionOptions from '../settings/subscriptionOptions.vue';
import paymentsButtons from '@/components/payments/buttons/list';
// svg imports
import closeIcon from '@/assets/svg/close.svg';
import gemIcon from '@/assets/svg/gem.svg';
import positiveIcon from '@/assets/svg/positive.svg';
import negativeIcon from '@/assets/svg/negative.svg';
export default {
components: {
avatar,
subscriptionOptions,
paymentsButtons,
userLink,
},
mixins: [
paymentsMixin,
],
data () {
return {
subscription: {
key: '',
},
icons: Object.freeze({
closeIcon,
gemIcon,
positiveIcon,
negativeIcon,
}),
userReceivingGift: {
profile: '',
},
name: '',
display: '',
selectedPage: 'subscription',
gift: {
type: 'gems',
gems: {
amount: 0,
fromBalance: true,
},
},
sendingInProgress: false,
amazonPayments: {},
gemCost: 1,
};
},
methods: {
close () {
this.$root.$emit('bv::hide::modal', 'send-gift');
},
selectPage (page) {
this.selectedPage = page || 'subscription';
},
async sendGift () {
this.sendingInProgress = true;
await this.$store.dispatch('members:transferGems', {
toUserId: this.userReceivingGift._id,
gemAmount: this.gift.gems.amount,
});
this.close();
setTimeout(() => { // wait for the send gem modal to be closed
this.$root.$emit('habitica:payment-success', {
paymentMethod: 'balance',
paymentCompleted: true,
paymentType: 'gift-gems-balance',
gift: {
gems: {
amount: this.gift.gems.amount,
},
},
giftReceiver: this.receiverName,
});
}, 500);
},
onHide () {
this.sendingInProgress = false;
},
},
computed: {
...mapState({
userLoggedIn: 'user.data',
}),
userName () {
const userName = this.userReceivingGift.auth
&& this.userReceivingGift.auth.local
&& this.userReceivingGift.auth.local.username;
return userName;
},
displayName () {
const displayName = this.userReceivingGift.profile.name;
return displayName;
},
userBacker () {
const userBacker = this.userReceivingGift.backer;
return userBacker;
},
userContributor () {
const userContributor = this.userReceivingGift.contributor;
return userContributor;
},
tierIcon () {
if (this.isNPC) {
return this.icons.tierNPC;
}
return this.icons[`tier${this.level}`];
},
fromBal () {
return this.gift.type === 'gems' && this.gift.gems.fromBalance;
},
maxGems () {
const maxGems = this.fromBal ? this.userLoggedIn.balance * 4 : 9999;
return maxGems;
},
formatter () {
const formatter = new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'USD',
minimumFractionDigits: 2,
});
return formatter;
},
totalGems () {
const totalGems = this.gift.gems.amount * 0.25;
return totalGems;
},
receiverName () {
if (
this.userReceivingGift.auth
&& this.userReceivingGift.auth.local
&& this.userReceivingGift.auth.local.username
) {
return this.userReceivingGift.auth.local.username;
}
return this.userReceivingGift.profile.name;
},
},
watch: {
startingPage () {
this.selectedPage = this.startingPage;
},
},
mounted () {
this.$root.$on('habitica::send-gift', data => {
this.userReceivingGift = data;
if (this.$store.state.giftModalOptions.startingPage) {
this.selectedPage = this.$store.state.giftModalOptions.startingPage;
this.$store.state.giftModalOptions.startingPage = '';
this.selectPage(this.selectedPage);
} else {
this.selectPage(this.startingPage);
}
this.$root.$emit('bv::show::modal', 'send-gift');
});
},
};
</script>
@@ -450,10 +450,6 @@
background-color: $white;
}
.subscribe-option {
border-bottom: 1px solid $gray-600;
}
.svg-amazon-pay {
width: 208px;
}
@@ -969,7 +969,8 @@ export default {
axios.post(`/api/v4/user/block/${this.user._id}`);
},
openSendGemsModal () {
this.$root.$emit('habitica::send-gems', this.user);
this.$store.state.giftModalOptions.startingPage = 'buyGems';
this.$root.$emit('habitica::send-gift', this.user);
},
adminTurnOnShadowMuting () {
if (!this.hero.flags) {