refactor(achievements): crush down to much fewer notification types

most work by @CuriousMagpie
This commit is contained in:
SabreCat
2022-05-12 15:25:40 -05:00
parent d132b057eb
commit 1a74d2b3b0
21 changed files with 434 additions and 839 deletions

View File

@@ -634,7 +634,7 @@ describe('User Model', () => {
user = await user.save(); user = await user.save();
// verify that it's been awarded // verify that it's been awarded
expect(user.achievements.beastMaster).to.equal(true); expect(user.achievements.beastMaster).to.equal(true);
expect(user.notifications.find(notification => notification.type === 'ACHIEVEMENT_BEAST_MASTER')).to.exist; expect(user.notifications.find(notification => notification.type === 'ACHIEVEMENT_STABLE')).to.exist;
// reset the user // reset the user
user.achievements.beastMasterCount = 0; user.achievements.beastMasterCount = 0;
@@ -683,9 +683,9 @@ describe('User Model', () => {
user = await user.save(); user = await user.save();
// verify that it's been awarded // verify that it's been awarded
expect(user.notifications.find(notification => notification.type === 'ACHIEVEMENT_BEAST_MASTER')).to.exist; expect(user.notifications.find(
expect(user.notifications.find(notification => notification.type === 'ACHIEVEMENT_MOUNT_MASTER')).to.exist; notification => notification.type === 'ACHIEVEMENT_STABLE',
expect(user.notifications.find(notification => notification.type === 'ACHIEVEMENT_TRIAD_BINGO')).to.exist; )).to.exist;
}); });
context('manage unallocated stats points notifications', () => { context('manage unallocated stats points notifications', () => {

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -140,9 +140,6 @@ import NEW_INBOX_MESSAGE from './notifications/newPrivateMessage';
import NEW_CHAT_MESSAGE from './notifications/newChatMessage'; import NEW_CHAT_MESSAGE from './notifications/newChatMessage';
import WORLD_BOSS from './notifications/worldBoss'; import WORLD_BOSS from './notifications/worldBoss';
import VERIFY_USERNAME from './notifications/verifyUsername'; 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 ONBOARDING_COMPLETE from './notifications/onboardingComplete';
import GIFT_ONE_GET_ONE from './notifications/g1g1'; import GIFT_ONE_GET_ONE from './notifications/g1g1';
import OnboardingGuide from './onboardingGuide'; import OnboardingGuide from './onboardingGuide';
@@ -167,9 +164,6 @@ export default {
CARD_RECEIVED, CARD_RECEIVED,
NEW_INBOX_MESSAGE, NEW_INBOX_MESSAGE,
NEW_CHAT_MESSAGE, NEW_CHAT_MESSAGE,
ACHIEVEMENT_JUST_ADD_WATER,
ACHIEVEMENT_LOST_MASTERCLASSER,
ACHIEVEMENT_MIND_OVER_MATTER,
WorldBoss: WORLD_BOSS, WorldBoss: WORLD_BOSS,
VERIFY_USERNAME, VERIFY_USERNAME,
OnboardingGuide, OnboardingGuide,
@@ -194,13 +188,24 @@ export default {
// listed in the order they should appear in the notifications panel. // listed in the order they should appear in the notifications panel.
// NOTE: Those not listed here won't be shown in the notification panel! // NOTE: Those not listed here won't be shown in the notification panel!
handledNotifications: [ handledNotifications: [
'NEW_STUFF', 'GIFT_ONE_GET_ONE', 'GROUP_TASK_NEEDS_WORK', 'NEW_STUFF',
'GUILD_INVITATION', 'PARTY_INVITATION', 'CHALLENGE_INVITATION', 'GIFT_ONE_GET_ONE',
'QUEST_INVITATION', 'GROUP_TASK_ASSIGNED', 'GROUP_TASK_APPROVAL', 'GROUP_TASK_APPROVED', 'GROUP_TASK_NEEDS_WORK',
'GROUP_TASK_CLAIMED', 'NEW_MYSTERY_ITEMS', 'CARD_RECEIVED', 'GUILD_INVITATION',
'NEW_INBOX_MESSAGE', 'NEW_CHAT_MESSAGE', 'UNALLOCATED_STATS_POINTS', 'PARTY_INVITATION',
'ACHIEVEMENT_JUST_ADD_WATER', 'ACHIEVEMENT_LOST_MASTERCLASSER', 'ACHIEVEMENT_MIND_OVER_MATTER', 'CHALLENGE_INVITATION',
'VERIFY_USERNAME', 'ONBOARDING_COMPLETE', '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',
], ],
}; };
}, },

View File

@@ -30,9 +30,6 @@
v-if="notificationData && notificationData.achievement" v-if="notificationData && notificationData.achievement"
:data="notificationData" :data="notificationData"
/> />
<just-add-water />
<lost-masterclasser />
<mind-over-matter />
<onboarding-complete /> <onboarding-complete />
<first-drops /> <first-drops />
</div> </div>
@@ -141,25 +138,34 @@ import streak from './achievements/streak';
import ultimateGear from './achievements/ultimateGear'; import ultimateGear from './achievements/ultimateGear';
import wonChallenge from './achievements/wonChallenge'; import wonChallenge from './achievements/wonChallenge';
import genericAchievement from './achievements/genericAchievement'; 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 loginIncentives from './achievements/login-incentives';
import onboardingComplete from './achievements/onboardingComplete'; import onboardingComplete from './achievements/onboardingComplete';
import verifyUsername from './settings/verifyUsername'; import verifyUsername from './settings/verifyUsername';
import firstDrops from './achievements/firstDrops'; import firstDrops from './achievements/firstDrops';
const NOTIFICATIONS = { 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: { CHALLENGE_JOINED_ACHIEVEMENT: {
achievement: true, achievement: true,
label: $t => `${$t('achievement')}: ${$t('joinedChallenge')}`, label: $t => `${$t('achievement')}: ${$t('joinedChallenge')}`,
modalId: 'joined-challenge', modalId: 'joined-challenge',
}, },
ULTIMATE_GEAR_ACHIEVEMENT: {
achievement: true,
label: $t => `${$t('achievement')}: ${$t('gearAchievementNotification')}`,
modalId: 'ultimate-gear',
},
GUILD_JOINED_ACHIEVEMENT: { GUILD_JOINED_ACHIEVEMENT: {
label: $t => `${$t('achievement')}: ${$t('joinedGuild')}`, label: $t => `${$t('achievement')}: ${$t('joinedGuild')}`,
achievement: true, achievement: true,
@@ -170,42 +176,14 @@ const NOTIFICATIONS = {
label: $t => `${$t('achievement')}: ${$t('invitedFriend')}`, label: $t => `${$t('achievement')}: ${$t('invitedFriend')}`,
modalId: 'invited-friend', modalId: 'invited-friend',
}, },
NEW_CONTRIBUTOR_LEVEL: { ACHIEVEMENT_PARTY_ON: {
achievement: true, achievement: true,
label: $t => $t('modalContribAchievement'), label: $t => `${$t('achievement')}: ${$t('achievementPartyOn')}`,
modalId: 'contributor',
sticky: true,
},
ACHIEVEMENT_ALL_YOUR_BASE: {
achievement: true,
label: $t => `${$t('achievement')}: ${$t('achievementAllYourBase')}`,
modalId: 'generic-achievement', modalId: 'generic-achievement',
data: { data: {
achievement: 'allYourBase', // defined manually until the server sends all the necessary data message: $t => $t('achievement'),
}, modalText: $t => $t('achievementPartyOn'),
}, achievement: 'partyOn',
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',
}, },
}, },
ACHIEVEMENT_PARTY_UP: { ACHIEVEMENT_PARTY_UP: {
@@ -218,245 +196,47 @@ const NOTIFICATIONS = {
achievement: 'partyUp', achievement: 'partyUp',
}, },
}, },
ACHIEVEMENT_PARTY_ON: { ULTIMATE_GEAR_ACHIEVEMENT: {
achievement: true,
label: $t => `${$t('achievement')}: ${$t('gearAchievementNotification')}`,
modalId: 'ultimate-gear',
},
ACHIEVEMENT_STABLE: {
achievement: true, achievement: true,
label: $t => `${$t('achievement')}: ${$t('achievementPartyOn')}`,
modalId: 'generic-achievement', modalId: 'generic-achievement',
data: { data: {
message: $t => $t('achievement'), achievement: 'stableAchievs',
modalText: $t => $t('achievementPartyOn'),
achievement: 'partyOn',
}, },
}, },
ACHIEVEMENT_BEAST_MASTER: { ACHIEVEMENT_QUESTS: {
achievement: true, achievement: true,
label: $t => `${$t('achievement')}: ${$t('beastAchievement')}`,
modalId: 'generic-achievement', modalId: 'generic-achievement',
data: { data: {
message: $t => $t('achievement'), achievement: 'questSeriesAchievs',
modalText: $t => $t('beastAchievement'),
achievement: 'beastMaster',
}, },
}, },
ACHIEVEMENT_MOUNT_MASTER: { ACHIEVEMENT_ANIMAL_SET: {
achievement: true, achievement: true,
label: $t => `${$t('achievement')}: ${$t('mountAchievement')}`, label: $t => `${$t('achievement')}: ${$t('achievementAnimalSet')}`,
modalId: 'generic-achievement', modalId: 'generic-achievement',
data: { data: {
message: $t => $t('achievement'), achievement: 'animalSetAchievs',
modalText: $t => $t('mountAchievement'),
achievement: 'mountMaster',
}, },
}, },
ACHIEVEMENT_TRIAD_BINGO: { ACHIEVEMENT_PET_COLOR: {
achievement: true, achievement: true,
label: $t => `${$t('achievement')}: ${$t('triadBingoAchievement')}`, label: $t => `${$t('achievement')}: ${$t('achievementPetColor')}`,
modalId: 'generic-achievement', modalId: 'generic-achievement',
data: { data: {
message: $t => $t('achievement'), achievement: 'petColorAchievs',
modalText: $t => $t('triadBingoAchievement'),
achievement: 'triadBingo',
}, },
}, },
ACHIEVEMENT_MONSTER_MAGUS: { ACHIEVEMENT_MOUNT_COLOR: {
achievement: true, achievement: true,
label: $t => `${$t('achievement')}: ${$t('achievementMonsterMagus')}`, label: $t => `${$t('achievement')}: ${$t('achievementMountColor')}`,
modalId: 'generic-achievement', modalId: 'generic-achievement',
data: { data: {
achievement: 'monsterMagus', achievement: 'mountColorAchievs',
},
},
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',
}, },
}, },
}; };
@@ -486,9 +266,6 @@ export default {
loginIncentives, loginIncentives,
verifyUsername, verifyUsername,
genericAchievement, genericAchievement,
lostMasterclasser,
mindOverMatter,
justAddWater,
onboardingComplete, onboardingComplete,
firstDrops, firstDrops,
}, },
@@ -509,21 +286,30 @@ export default {
const handledNotifications = {}; const handledNotifications = {};
[ [
'GUILD_PROMPT', 'REBIRTH_ENABLED', 'WON_CHALLENGE', 'STREAK_ACHIEVEMENT', // general notifications
'ULTIMATE_GEAR_ACHIEVEMENT', 'REBIRTH_ACHIEVEMENT', 'GUILD_JOINED_ACHIEVEMENT', 'CRON',
'CHALLENGE_JOINED_ACHIEVEMENT', 'INVITED_FRIEND_ACHIEVEMENT', 'NEW_CONTRIBUTOR_LEVEL', 'FIRST_DROPS',
'CRON', 'LOGIN_INCENTIVE', 'ACHIEVEMENT_ALL_YOUR_BASE', 'ACHIEVEMENT_BACK_TO_BASICS', 'GUILD_PROMPT',
'GENERIC_ACHIEVEMENT', 'ACHIEVEMENT_PARTY_UP', 'ACHIEVEMENT_PARTY_ON', 'ACHIEVEMENT_BEAST_MASTER', 'LOGIN_INCENTIVE',
'ACHIEVEMENT_MOUNT_MASTER', 'ACHIEVEMENT_TRIAD_BINGO', 'ACHIEVEMENT_DUST_DEVIL', 'ACHIEVEMENT_ARID_AUTHORITY', 'NEW_CONTRIBUTOR_LEVEL',
'ACHIEVEMENT_MONSTER_MAGUS', 'ACHIEVEMENT_UNDEAD_UNDERTAKER', 'ACHIEVEMENT_PRIMED_FOR_PAINTING', 'ONBOARDING_COMPLETE',
'ACHIEVEMENT_PEARLY_PRO', 'ACHIEVEMENT_TICKLED_PINK', 'ACHIEVEMENT_ROSY_OUTLOOK', 'ACHIEVEMENT', 'REBIRTH_ENABLED',
'ONBOARDING_COMPLETE', 'FIRST_DROPS', 'ACHIEVEMENT_BUG_BONANZA', 'ACHIEVEMENT_BARE_NECESSITIES', 'WON_CHALLENGE',
'ACHIEVEMENT_FRESHWATER_FRIENDS', 'ACHIEVEMENT_GOOD_AS_GOLD', 'ACHIEVEMENT_ALL_THAT_GLITTERS', // achievement notifications
'ACHIEVEMENT_BONE_COLLECTOR', 'ACHIEVEMENT_SKELETON_CREW', 'ACHIEVEMENT_SEEING_RED', 'ACHIEVEMENT',
'ACHIEVEMENT_RED_LETTER_DAY', 'ACHIEVEMENT_LEGENDARY_BESTIARY', 'ACHIEVEMENT_SEASONAL_SPECIALIST', 'CHALLENGE_JOINED_ACHIEVEMENT',
'ACHIEVEMENT_VIOLETS_ARE_BLUE', 'ACHIEVEMENT_WILD_BLUE_YONDER', 'ACHIEVEMENT_DOMESTICATED', 'GUILD_JOINED_ACHIEVEMENT',
'ACHIEVEMENT_SHADY_CUSTOMER', 'ACHIEVEMENT_SHADE_OF_IT_ALL', 'ACHIEVEMENT_ZODIAC_ZOOKEEPER', 'INVITED_FRIEND_ACHIEVEMENT',
'ACHIEVEMENT_BIRDS_OF_A_FEATHER', '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 => { ].forEach(type => {
handledNotifications[type] = true; handledNotifications[type] = true;
}); });
@@ -921,57 +707,68 @@ export default {
case 'WON_CHALLENGE': case 'WON_CHALLENGE':
this.$root.$emit('habitica:won-challenge', notification); this.$root.$emit('habitica:won-challenge', notification);
break; break;
case 'REBIRTH_ACHIEVEMENT':
this.playSound('Achievement_Unlocked');
this.$root.$emit('bv::show::modal', 'rebirth');
break;
case 'STREAK_ACHIEVEMENT': case 'STREAK_ACHIEVEMENT':
this.text(`${this.$t('streaks')}: ${this.user.achievements.streak}`, () => { this.text(`${this.$t('streaks')}: ${this.user.achievements.streak}`, () => {
this.$root.$emit('bv::show::modal', 'streak'); this.$root.$emit('bv::show::modal', 'streak');
}, this.user.preferences.suppressModals.streak); }, this.user.preferences.suppressModals.streak);
this.playSound('Achievement_Unlocked'); this.playSound('Achievement_Unlocked');
break; 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 'NEW_CONTRIBUTOR_LEVEL':
case 'ACHIEVEMENT_ALL_YOUR_BASE': case 'CHALLENGE_JOINED_ACHIEVEMENT':
case 'ACHIEVEMENT_BACK_TO_BASICS': case 'GUILD_JOINED_ACHIEVEMENT':
case 'ACHIEVEMENT_DUST_DEVIL': case 'INVITED_FRIEND_ACHIEVEMENT':
case 'ACHIEVEMENT_ARID_AUTHORITY':
case 'ACHIEVEMENT_PARTY_UP':
case 'ACHIEVEMENT_PARTY_ON': case 'ACHIEVEMENT_PARTY_ON':
case 'ACHIEVEMENT_BEAST_MASTER': case 'ACHIEVEMENT_PARTY_UP':
case 'ACHIEVEMENT_MOUNT_MASTER': case 'ULTIMATE_GEAR_ACHIEVEMENT':
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':
this.showNotificationWithModal(notification); this.showNotificationWithModal(notification);
break; 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 case 'ACHIEVEMENT': { // generic achievement
const { achievement } = notification.data; const { achievement } = notification.data;
const upperCaseAchievement = achievement.charAt(0).toUpperCase() + achievement.slice(1); const upperCaseAchievement = achievement.charAt(0).toUpperCase() + achievement.slice(1);
@@ -984,10 +781,6 @@ export default {
Vue.set(this.user.achievements, achievement, true); Vue.set(this.user.achievements, achievement, true);
break; 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': case 'LOGIN_INCENTIVE':
if (this.user.flags.tour.intro === this.TOUR_END && this.user.flags.welcomed) { if (this.user.flags.tour.intro === this.TOUR_END && this.user.flags.welcomed) {
this.notificationData = notification.data; this.notificationData = notification.data;

View File

@@ -55,27 +55,30 @@ const seasonalSpellAchievs = {
}; };
Object.assign(achievementsData, seasonalSpellAchievs); Object.assign(achievementsData, seasonalSpellAchievs);
const masterAchievs = { const stableAchievs = {
beastMaster: { beastMaster: {
icon: 'achievement-rat', icon: 'achievement-rat',
titleKey: 'beastMasterName', titleKey: 'beastMasterName',
textKey: 'beastMasterText', textKey: 'beastMasterText',
text2Key: 'beastMasterText2', text2Key: 'beastMasterText2',
notificationText: 'beastAchievement',
}, },
mountMaster: { mountMaster: {
icon: 'achievement-wolf', icon: 'achievement-wolf',
titleKey: 'mountMasterName', titleKey: 'mountMasterName',
textKey: 'mountMasterText', textKey: 'mountMasterText',
text2Key: 'mountMasterText2', text2Key: 'mountMasterText2',
notificationText: 'mountAchievement',
}, },
triadBingo: { triadBingo: {
icon: 'achievement-triadbingo', icon: 'achievement-triadbingo',
titleKey: 'triadBingoName', titleKey: 'triadBingoName',
textKey: 'triadBingoText', textKey: 'triadBingoText',
text2Key: 'triadBingoText2', text2Key: 'triadBingoText2',
notificationText: 'triadBingoAchievement',
}, },
}; };
Object.assign(achievementsData, masterAchievs); Object.assign(achievementsData, stableAchievs);
const basicAchievs = { const basicAchievs = {
partyUp: { partyUp: {
@@ -122,146 +125,173 @@ const basicAchievs = {
titleKey: 'invitedFriend', titleKey: 'invitedFriend',
textKey: 'invitedFriendText', textKey: 'invitedFriendText',
}, },
};
Object.assign(achievementsData, basicAchievs);
const questSeriesAchievs = {
lostMasterclasser: { lostMasterclasser: {
icon: 'achievement-lostMasterclasser', icon: 'achievement-lostMasterclasser',
titleKey: 'achievementLostMasterclasser', titleKey: 'achievementLostMasterclasser',
textKey: 'achievementLostMasterclasserText', textKey: 'achievementLostMasterclasserText',
}, },
mindOverMatter: {
icon: 'achievement-mindOverMatter',
titleKey: 'achievementMindOverMatter',
textKey: 'achievementMindOverMatterText',
},
justAddWater: {
icon: 'achievement-justAddWater',
titleKey: 'achievementJustAddWater',
textKey: 'achievementJustAddWaterText',
},
backToBasics: {
icon: 'achievement-backToBasics',
titleKey: 'achievementBackToBasics',
textKey: 'achievementBackToBasicsText',
},
allYourBase: {
icon: 'achievement-allYourBase',
titleKey: 'achievementAllYourBase',
textKey: 'achievementAllYourBaseText',
},
dustDevil: {
icon: 'achievement-dustDevil',
titleKey: 'achievementDustDevil',
textKey: 'achievementDustDevilText',
},
aridAuthority: {
icon: 'achievement-aridAuthority',
titleKey: 'achievementAridAuthority',
textKey: 'achievementAridAuthorityText',
},
monsterMagus: {
icon: 'achievement-monsterMagus',
titleKey: 'achievementMonsterMagus',
textKey: 'achievementMonsterMagusText',
},
undeadUndertaker: {
icon: 'achievement-undeadUndertaker',
titleKey: 'achievementUndeadUndertaker',
textKey: 'achievementUndeadUndertakerText',
},
primedForPainting: {
icon: 'achievement-primedForPainting',
titleKey: 'achievementPrimedForPainting',
textKey: 'achievementPrimedForPaintingText',
},
pearlyPro: {
icon: 'achievement-pearlyPro',
titleKey: 'achievementPearlyPro',
textKey: 'achievementPearlyProText',
},
tickledPink: {
icon: 'achievement-tickledPink',
titleKey: 'achievementTickledPink',
textKey: 'achievementTickledPinkText',
},
rosyOutlook: {
icon: 'achievement-rosyOutlook',
titleKey: 'achievementRosyOutlook',
textKey: 'achievementRosyOutlookText',
},
bugBonanza: {
icon: 'achievement-bugBonanza',
titleKey: 'achievementBugBonanza',
textKey: 'achievementBugBonanzaText',
},
bareNecessities: { bareNecessities: {
icon: 'achievement-bareNecessities', icon: 'achievement-bareNecessities',
titleKey: 'achievementBareNecessities', titleKey: 'achievementBareNecessities',
textKey: 'achievementBareNecessitiesText', textKey: 'achievementBareNecessitiesText',
}, },
bugBonanza: {
icon: 'achievement-bugBonanza',
titleKey: 'achievementBugBonanza',
textKey: 'achievementBugBonanzaText',
},
freshwaterFriends: { freshwaterFriends: {
icon: 'achievement-freshwaterFriends', icon: 'achievement-freshwaterFriends',
titleKey: 'achievementFreshwaterFriends', titleKey: 'achievementFreshwaterFriends',
textKey: 'achievementFreshwaterFriendsText', textKey: 'achievementFreshwaterFriendsText',
}, },
goodAsGold: { justAddWater: {
icon: 'achievement-goodAsGold', icon: 'achievement-justAddWater',
titleKey: 'achievementGoodAsGold', titleKey: 'achievementJustAddWater',
textKey: 'achievementGoodAsGoldText', textKey: 'achievementJustAddWaterText',
}, },
allThatGlitters: { mindOverMatter: {
icon: 'achievement-allThatGlitters', icon: 'achievement-mindOverMatter',
titleKey: 'achievementAllThatGlitters', titleKey: 'achievementMindOverMatter',
textKey: 'achievementAllThatGlittersText', textKey: 'achievementMindOverMatterText',
},
boneCollector: {
icon: 'achievement-boneCollector',
titleKey: 'achievementBoneCollector',
textKey: 'achievementBoneCollectorText',
},
skeletonCrew: {
icon: 'achievement-skeletonCrew',
titleKey: 'achievementSkeletonCrew',
textKey: 'achievementSkeletonCrewText',
},
seeingRed: {
icon: 'achievement-seeingRed',
titleKey: 'achievementSeeingRed',
textKey: 'achievementSeeingRedText',
},
redLetterDay: {
icon: 'achievement-redLetterDay',
titleKey: 'achievementRedLetterDay',
textKey: 'achievementRedLetterDayText',
},
legendaryBestiary: {
icon: 'achievement-legendaryBestiary',
titleKey: 'achievementLegendaryBestiary',
textKey: 'achievementLegendaryBestiaryText',
}, },
seasonalSpecialist: { seasonalSpecialist: {
icon: 'achievement-seasonalSpecialist', icon: 'achievement-seasonalSpecialist',
titleKey: 'achievementSeasonalSpecialist', titleKey: 'achievementSeasonalSpecialist',
textKey: 'achievementSeasonalSpecialistText', textKey: 'achievementSeasonalSpecialistText',
}, },
violetsAreBlue: { };
icon: 'achievement-violetsAreBlue', Object.assign(achievementsData, questSeriesAchievs);
titleKey: 'achievementVioletsAreBlue',
textKey: 'achievementVioletsAreBlueText', const animalSetAchievs = {
legendaryBestiary: {
icon: 'achievement-legendaryBestiary',
titleKey: 'achievementLegendaryBestiary',
textKey: 'achievementLegendaryBestiaryText',
}, },
wildBlueYonder: { birdsOfAFeather: {
icon: 'achievement-wildBlueYonder', icon: 'achievement-birdsOfAFeather',
titleKey: 'achievementWildBlueYonder', titleKey: 'achievementBirdsOfAFeather',
textKey: 'achievementWildBlueYonderText', textKey: 'achievementBirdsOfAFeatherText',
}, },
domesticated: { domesticated: {
icon: 'achievement-domesticated', icon: 'achievement-domesticated',
titleKey: 'achievementDomesticated', titleKey: 'achievementDomesticated',
textKey: 'achievementDomesticatedText', textKey: 'achievementDomesticatedText',
}, },
zodiacZookeeper: {
icon: 'achievement-zodiac',
titleKey: 'achievementZodiacZookeeper',
textKey: 'achievementZodiacZookeeperText',
},
};
Object.assign(achievementsData, animalSetAchievs);
const petColorAchievs = {
backToBasics: {
icon: 'achievement-backToBasics',
titleKey: 'achievementBackToBasics',
textKey: 'achievementBackToBasicsText',
},
dustDevil: {
icon: 'achievement-dustDevil',
titleKey: 'achievementDustDevil',
textKey: 'achievementDustDevilText',
},
monsterMagus: {
icon: 'achievement-monsterMagus',
titleKey: 'achievementMonsterMagus',
textKey: 'achievementMonsterMagusText',
},
primedForPainting: {
icon: 'achievement-primedForPainting',
titleKey: 'achievementPrimedForPainting',
textKey: 'achievementPrimedForPaintingText',
},
tickledPink: {
icon: 'achievement-tickledPink',
titleKey: 'achievementTickledPink',
textKey: 'achievementTickledPinkText',
},
goodAsGold: {
icon: 'achievement-goodAsGold',
titleKey: 'achievementGoodAsGold',
textKey: 'achievementGoodAsGoldText',
},
boneCollector: {
icon: 'achievement-boneCollector',
titleKey: 'achievementBoneCollector',
textKey: 'achievementBoneCollectorText',
},
seeingRed: {
icon: 'achievement-seeingRed',
titleKey: 'achievementSeeingRed',
textKey: 'achievementSeeingRedText',
modalTextKey: 'achievementSeeingRedModalText',
},
violetsAreBlue: {
icon: 'achievement-violetsAreBlue',
titleKey: 'achievementVioletsAreBlue',
textKey: 'achievementVioletsAreBlueText',
},
shadyCustomer: { shadyCustomer: {
icon: 'achievement-shadyCustomer', icon: 'achievement-shadyCustomer',
titleKey: 'achievementShadyCustomer', titleKey: 'achievementShadyCustomer',
textKey: 'achievementShadyCustomerText', textKey: 'achievementShadyCustomerText',
}, },
};
Object.assign(achievementsData, petColorAchievs);
const mountColorAchievs = {
allYourBase: {
icon: 'achievement-allYourBase',
titleKey: 'achievementAllYourBase',
textKey: 'achievementAllYourBaseText',
},
aridAuthority: {
icon: 'achievement-aridAuthority',
titleKey: 'achievementAridAuthority',
textKey: 'achievementAridAuthorityText',
},
undeadUndertaker: {
icon: 'achievement-undeadUndertaker',
titleKey: 'achievementUndeadUndertaker',
textKey: 'achievementUndeadUndertakerText',
},
pearlyPro: {
icon: 'achievement-pearlyPro',
titleKey: 'achievementPearlyPro',
textKey: 'achievementPearlyProText',
},
rosyOutlook: {
icon: 'achievement-rosyOutlook',
titleKey: 'achievementRosyOutlook',
textKey: 'achievementRosyOutlookText',
},
allThatGlitters: {
icon: 'achievement-allThatGlitters',
titleKey: 'achievementAllThatGlitters',
textKey: 'achievementAllThatGlittersText',
},
skeletonCrew: {
icon: 'achievement-skeletonCrew',
titleKey: 'achievementSkeletonCrew',
textKey: 'achievementSkeletonCrewText',
},
redLetterDay: {
icon: 'achievement-redLetterDay',
titleKey: 'achievementRedLetterDay',
textKey: 'achievementRedLetterDayText',
},
wildBlueYonder: {
icon: 'achievement-wildBlueYonder',
titleKey: 'achievementWildBlueYonder',
textKey: 'achievementWildBlueYonderText',
},
shadeOfItAll: { shadeOfItAll: {
icon: 'achievement-shadeOfItAll', icon: 'achievement-shadeOfItAll',
titleKey: 'achievementShadeOfItAll', titleKey: 'achievementShadeOfItAll',
@@ -278,7 +308,7 @@ const basicAchievs = {
textKey: 'achievementBirdsOfAFeatherText', textKey: 'achievementBirdsOfAFeatherText',
}, },
}; };
Object.assign(achievementsData, basicAchievs); Object.assign(achievementsData, mountColorAchievs);
const onboardingAchievs = { const onboardingAchievs = {
createdTask: { createdTask: {

View File

@@ -2,72 +2,72 @@ const ANIMAL_COLOR_ACHIEVEMENTS = [
{ {
color: 'Base', color: 'Base',
petAchievement: 'backToBasics', petAchievement: 'backToBasics',
petNotificationType: 'ACHIEVEMENT_BACK_TO_BASICS', petNotificationType: 'ACHIEVEMENT_PET_COLOR',
mountAchievement: 'allYourBase', mountAchievement: 'allYourBase',
mountNotificationType: 'ACHIEVEMENT_ALL_YOUR_BASE', mountNotificationType: 'ACHIEVEMENT_MOUNT_COLOR',
}, },
{ {
color: 'Desert', color: 'Desert',
petAchievement: 'dustDevil', petAchievement: 'dustDevil',
petNotificationType: 'ACHIEVEMENT_DUST_DEVIL', petNotificationType: 'ACHIEVEMENT_PET_COLOR',
mountAchievement: 'aridAuthority', mountAchievement: 'aridAuthority',
mountNotificationType: 'ACHIEVEMENT_ARID_AUTHORITY', mountNotificationType: 'ACHIEVEMENT_MOUNT_COLOR',
}, },
{ {
color: 'Zombie', color: 'Zombie',
petAchievement: 'monsterMagus', petAchievement: 'monsterMagus',
petNotificationType: 'ACHIEVEMENT_MONSTER_MAGUS', petNotificationType: 'ACHIEVEMENT_PET_COLOR',
mountAchievement: 'undeadUndertaker', mountAchievement: 'undeadUndertaker',
mountNotificationType: 'ACHIEVEMENT_UNDEAD_UNDERTAKER', mountNotificationType: 'ACHIEVEMENT_MOUNT_COLOR',
}, },
{ {
color: 'White', color: 'White',
petAchievement: 'primedForPainting', petAchievement: 'primedForPainting',
petNotificationType: 'ACHIEVEMENT_PRIMED_FOR_PAINTING', petNotificationType: 'ACHIEVEMENT_PET_COLOR',
mountAchievement: 'pearlyPro', mountAchievement: 'pearlyPro',
mountNotificationType: 'ACHIEVEMENT_PEARLY_PRO', mountNotificationType: 'ACHIEVEMENT_MOUNT_COLOR',
}, },
{ {
color: 'CottonCandyPink', color: 'CottonCandyPink',
petAchievement: 'tickledPink', petAchievement: 'tickledPink',
petNotificationType: 'ACHIEVEMENT_TICKLED_PINK', petNotificationType: 'ACHIEVEMENT_PET_COLOR',
mountAchievement: 'rosyOutlook', mountAchievement: 'rosyOutlook',
mountNotificationType: 'ACHIEVEMENT_ROSY_OUTLOOK', mountNotificationType: 'ACHIEVEMENT_MOUNT_COLOR',
}, },
{ {
color: 'Golden', color: 'Golden',
petAchievement: 'goodAsGold', petAchievement: 'goodAsGold',
petNotificationType: 'ACHIEVEMENT_GOOD_AS_GOLD', petNotificationType: 'ACHIEVEMENT_PET_COLOR',
mountAchievement: 'allThatGlitters', mountAchievement: 'allThatGlitters',
mountNotificationType: 'ACHIEVEMENT_ALL_THAT_GLITTERS', mountNotificationType: 'ACHIEVEMENT_MOUNT_COLOR',
}, },
{ {
color: 'Skeleton', color: 'Skeleton',
petAchievement: 'boneCollector', petAchievement: 'boneCollector',
petNotificationType: 'ACHIEVEMENT_BONE_COLLECTOR', petNotificationType: 'ACHIEVEMENT_PET_COLOR',
mountAchievement: 'skeletonCrew', mountAchievement: 'skeletonCrew',
mountNotificationType: 'ACHIEVEMENT_SKELETON_CREW', mountNotificationType: 'ACHIEVEMENT_MOUNT_COLOR',
}, },
{ {
color: 'Red', color: 'Red',
petAchievement: 'seeingRed', petAchievement: 'seeingRed',
petNotificationType: 'ACHIEVEMENT_SEEING_RED', petNotificationType: 'ACHIEVEMENT_PET_COLOR',
mountAchievement: 'redLetterDay', mountAchievement: 'redLetterDay',
mountNotificationType: 'ACHIEVEMENT_RED_LETTER_DAY', mountNotificationType: 'ACHIEVEMENT_MOUNT_COLOR',
}, },
{ {
color: 'CottonCandyBlue', color: 'CottonCandyBlue',
petAchievement: 'violetsAreBlue', petAchievement: 'violetsAreBlue',
petNotificationType: 'ACHIEVEMENT_VIOLETS_ARE_BLUE', petNotificationType: 'ACHIEVEMENT_PET_COLOR',
mountAchievement: 'wildBlueYonder', mountAchievement: 'wildBlueYonder',
mountNotificationType: 'ACHIEVEMENT_WILD_BLUE_YONDER', mountNotificationType: 'ACHIEVEMENT_MOUNT_COLOR',
}, },
{ {
color: 'Shade', color: 'Shade',
petAchievement: 'shadyCustomer', petAchievement: 'shadyCustomer',
petNotificationType: 'ACHIEVEMENT_SHADY_CUSTOMER', petNotificationType: 'ACHIEVEMENT_PET_COLOR',
mountAchievement: 'shadeOfItAll', mountAchievement: 'shadeOfItAll',
mountNotificationType: 'ACHIEVEMENT_SHADE_OF_IT_ALL', mountNotificationType: 'ACHIEVEMENT_MOUNT_COLOR',
}, },
]; ];

View File

@@ -9,7 +9,7 @@ const ANIMAL_SET_ACHIEVEMENTS = {
'Unicorn', 'Unicorn',
], ],
achievementKey: 'legendaryBestiary', achievementKey: 'legendaryBestiary',
notificationType: 'ACHIEVEMENT_LEGENDARY_BESTIARY', notificationType: 'ACHIEVEMENT_ANIMAL_SET',
}, },
birdsOfAFeather: { birdsOfAFeather: {
type: 'pet', type: 'pet',
@@ -24,7 +24,7 @@ const ANIMAL_SET_ACHIEVEMENTS = {
'Peacock', 'Peacock',
], ],
achievementKey: 'birdsOfAFeather', achievementKey: 'birdsOfAFeather',
notificationType: 'ACHIEVEMENT_BIRDS_OF_A_FEATHER', notificationType: 'ACHIEVEMENT_ANIMAL_SET',
}, },
domesticated: { domesticated: {
type: 'pet', type: 'pet',
@@ -39,7 +39,7 @@ const ANIMAL_SET_ACHIEVEMENTS = {
'Cow', 'Cow',
], ],
achievementKey: 'domesticated', achievementKey: 'domesticated',
notificationType: 'ACHIEVEMENT_DOMESTICATED', notificationType: 'ACHIEVEMENT_ANIMAL_SET',
}, },
zodiacZookeeper: { zodiacZookeeper: {
type: 'pet', type: 'pet',
@@ -53,12 +53,12 @@ const ANIMAL_SET_ACHIEVEMENTS = {
'Monkey', 'Monkey',
'Rooster', 'Rooster',
'Wolf', 'Wolf',
'TigerCub', 'Tiger',
'FlyingPig', 'FlyingPig',
'Dragon', 'Dragon',
], ],
achievementKey: 'zodiacZookeeper', achievementKey: 'zodiacZookeeper',
notificationType: 'ACHIEVEMENT_ZODIAC_ZOOKEEPER', notificationType: 'ACHIEVEMENT_ANIMAL_SET',
}, },
}; };

View File

@@ -32,6 +32,7 @@ export { default as SEASONAL_SETS } from './seasonalSets';
export { default as ANIMAL_COLOR_ACHIEVEMENTS } from './animalColorAchievements'; export { default as ANIMAL_COLOR_ACHIEVEMENTS } from './animalColorAchievements';
export { default as ANIMAL_SET_ACHIEVEMENTS } from './animalSetAchievements'; export { default as ANIMAL_SET_ACHIEVEMENTS } from './animalSetAchievements';
export { default as QUEST_SERIES_ACHIEVEMENTS } from './questSeriesAchievements'; export { default as QUEST_SERIES_ACHIEVEMENTS } from './questSeriesAchievements';
export { default as STABLE_ACHIEVEMENTS } from './stableAchievements';
export { default as ITEM_LIST } from './itemList'; export { default as ITEM_LIST } from './itemList';
export { default as QUEST_SERIES } from '../quests/series'; export { default as QUEST_SERIES } from '../quests/series';
export { default as QUEST_MASTERCLASSER } from '../quests/masterclasser'; export { default as QUEST_MASTERCLASSER } from '../quests/masterclasser';

View File

@@ -17,10 +17,21 @@ const QUEST_SERIES_ACHIEVEMENTS = {
'lostMasterclasser3', 'lostMasterclasser3',
'lostMasterclasser4', 'lostMasterclasser4',
], ],
mindOverMatter: [ bareNecessities: [
'rock', 'monkey',
'slime', 'sloth',
'yarn', 'treeling',
],
bugBonanza: [
'beetle',
'butterfly',
'snail',
'spider',
],
freshwaterFriends: [
'axolotl',
'frog',
'hippo',
], ],
justAddWater: [ justAddWater: [
'octopus', 'octopus',
@@ -32,21 +43,10 @@ const QUEST_SERIES_ACHIEVEMENTS = {
'seaserpent', 'seaserpent',
'dolphin', 'dolphin',
], ],
bugBonanza: [ mindOverMatter: [
'beetle', 'rock',
'butterfly', 'slime',
'snail', 'yarn',
'spider',
],
bareNecessities: [
'monkey',
'sloth',
'treeling',
],
freshwaterFriends: [
'axolotl',
'frog',
'hippo',
], ],
seasonalSpecialist: [ seasonalSpecialist: [
'egg', 'egg',

View File

@@ -0,0 +1,16 @@
const STABLE_ACHIEVEMENTS = {
ACHIEVEMENT_BEAST_MASTER: {
masterAchievement: 'beastMasterName',
masterNotificationType: 'ACHIEVEMENT_STABLE',
},
ACHIEVEMENT_MOUNT_MASTER: {
masterAchievement: 'mountMasterName',
masterNotificationType: 'ACHIEVEMENT_STABLE',
},
ACHIEVEMENT_TRIAD_BINGO: {
masterAchievement: 'triadBingoName',
masterNotificationType: 'ACHIEVEMENT_STABLE',
},
};
export default STABLE_ACHIEVEMENTS;

View File

@@ -12,6 +12,7 @@ import {
QUEST_SERIES_ACHIEVEMENTS, QUEST_SERIES_ACHIEVEMENTS,
ANIMAL_COLOR_ACHIEVEMENTS, ANIMAL_COLOR_ACHIEVEMENTS,
ANIMAL_SET_ACHIEVEMENTS, ANIMAL_SET_ACHIEVEMENTS,
STABLE_ACHIEVEMENTS,
} from './constants'; } from './constants';
import achievements from './achievements'; import achievements from './achievements';
@@ -41,6 +42,7 @@ api.achievements = achievements;
api.questSeriesAchievements = QUEST_SERIES_ACHIEVEMENTS; api.questSeriesAchievements = QUEST_SERIES_ACHIEVEMENTS;
api.animalColorAchievements = ANIMAL_COLOR_ACHIEVEMENTS; api.animalColorAchievements = ANIMAL_COLOR_ACHIEVEMENTS;
api.animalSetAchievements = ANIMAL_SET_ACHIEVEMENTS; api.animalSetAchievements = ANIMAL_SET_ACHIEVEMENTS;
api.stableAchievements = STABLE_ACHIEVEMENTS;
api.quests = quests; api.quests = quests;
api.questsByLevel = questsByLevel; api.questsByLevel = questsByLevel;

View File

@@ -130,6 +130,7 @@ export default function feed (user, req = {}, analytics) {
if (user.addNotification) { if (user.addNotification) {
const achievementString = `achievement${upperFirst(achievement.mountAchievement)}`; const achievementString = `achievement${upperFirst(achievement.mountAchievement)}`;
user.addNotification(achievement.mountNotificationType, { user.addNotification(achievement.mountNotificationType, {
label: `${'achievement'}: ${achievementString}`,
achievement: achievement.mountAchievement, achievement: achievement.mountAchievement,
message: `${i18n.t('modalAchievement')} ${i18n.t(achievementString)}`, message: `${i18n.t('modalAchievement')} ${i18n.t(achievementString)}`,
modalText: i18n.t(`${achievementString}ModalText`), modalText: i18n.t(`${achievementString}ModalText`),

View File

@@ -72,6 +72,7 @@ export default function hatch (user, req = {}, analytics) {
if (user.addNotification) { if (user.addNotification) {
const achievementString = `achievement${upperFirst(achievement.petAchievement)}`; const achievementString = `achievement${upperFirst(achievement.petAchievement)}`;
user.addNotification(achievement.petNotificationType, { user.addNotification(achievement.petNotificationType, {
label: `${'achievement'}: ${achievementString}`,
achievement: achievement.petAchievement, achievement: achievement.petAchievement,
message: `${i18n.t('modalAchievement')} ${i18n.t(achievementString)}`, message: `${i18n.t('modalAchievement')} ${i18n.t(achievementString)}`,
modalText: i18n.t(`${achievementString}ModalText`), modalText: i18n.t(`${achievementString}ModalText`),
@@ -100,6 +101,7 @@ export default function hatch (user, req = {}, analytics) {
if (user.addNotification) { if (user.addNotification) {
const achievementString = `achievement${upperFirst(achievement.achievementKey)}`; const achievementString = `achievement${upperFirst(achievement.achievementKey)}`;
user.addNotification(achievement.notificationType, { user.addNotification(achievement.notificationType, {
label: `${'achievement'}: ${achievementString}`,
achievement: achievement.achievementKey, achievement: achievement.achievementKey,
message: `${i18n.t('modalAchievement')} ${i18n.t(achievementString)}`, message: `${i18n.t('modalAchievement')} ${i18n.t(achievementString)}`,
modalText: i18n.t(`${achievementString}ModalText`), modalText: i18n.t(`${achievementString}ModalText`),

View File

@@ -999,10 +999,9 @@ schema.methods.finishQuest = async function finishQuest (quest) {
const questAchievementUpdate = { $set: {}, $push: {} }; const questAchievementUpdate = { $set: {}, $push: {} };
questAchievementUpdate.$set[`achievements.${achievement}`] = true; questAchievementUpdate.$set[`achievements.${achievement}`] = true;
const achievementTitleCase = `${achievement.slice(0, 1).toUpperCase()}${achievement.slice(1, achievement.length)}`; const achievementTitleCase = `${achievement.slice(0, 1).toUpperCase()}${achievement.slice(1, achievement.length)}`;
const achievementSnakeCase = `ACHIEVEMENT_${_.snakeCase(achievement).toUpperCase()}`;
questAchievementUpdate.$push = { questAchievementUpdate.$push = {
notifications: new UserNotification({ notifications: new UserNotification({
type: achievementSnakeCase, type: 'ACHIEVEMENT_QUESTS',
data: { data: {
achievement, achievement,
message: `${shared.i18n.t('modalAchievement')} ${shared.i18n.t(`achievement${achievementTitleCase}`)}`, message: `${shared.i18n.t('modalAchievement')} ${shared.i18n.t(`achievement${achievementTitleCase}`)}`,

View File

@@ -258,7 +258,13 @@ schema.pre('save', true, function preSaveUser (next, done) {
&& this.achievements.beastMaster !== true && this.achievements.beastMaster !== true
) { ) {
this.achievements.beastMaster = true; this.achievements.beastMaster = true;
this.addNotification('ACHIEVEMENT_BEAST_MASTER'); this.addNotification(
'ACHIEVEMENT_STABLE',
{
achievement: 'beastMaster',
achievementNotification: 'beastAchievement',
},
);
} }
// Determines if Mount Master should be awarded // Determines if Mount Master should be awarded
@@ -269,7 +275,13 @@ schema.pre('save', true, function preSaveUser (next, done) {
&& this.achievements.mountMaster !== true && this.achievements.mountMaster !== true
) { ) {
this.achievements.mountMaster = true; this.achievements.mountMaster = true;
this.addNotification('ACHIEVEMENT_MOUNT_MASTER'); this.addNotification(
'ACHIEVEMENT_STABLE',
{
achievement: 'mountMaster',
achievementNotification: 'mountAchievement',
},
);
} }
// Determines if Triad Bingo should be awarded // Determines if Triad Bingo should be awarded
@@ -281,7 +293,13 @@ schema.pre('save', true, function preSaveUser (next, done) {
&& this.achievements.triadBingo !== true && this.achievements.triadBingo !== true
) { ) {
this.achievements.triadBingo = true; this.achievements.triadBingo = true;
this.addNotification('ACHIEVEMENT_TRIAD_BINGO'); this.addNotification(
'ACHIEVEMENT_STABLE',
{
achievement: 'triadBingo',
achievementNotification: 'triadBingoAchievement',
},
);
} }
// EXAMPLE CODE for allowing all existing and new players to be // EXAMPLE CODE for allowing all existing and new players to be

View File

@@ -5,75 +5,85 @@ import validator from 'validator';
import baseModel from '../libs/baseModel'; import baseModel from '../libs/baseModel';
const NOTIFICATION_TYPES = [ const NOTIFICATION_TYPES = [
'DROPS_ENABLED', // unused // general notifications
'REBIRTH_ENABLED', 'CARD_RECEIVED',
'WON_CHALLENGE',
'STREAK_ACHIEVEMENT',
'ULTIMATE_GEAR_ACHIEVEMENT',
'REBIRTH_ACHIEVEMENT',
'NEW_CONTRIBUTOR_LEVEL',
'CRON', 'CRON',
'DROP_CAP_REACHED',
'DROPS_ENABLED', // unused
'FIRST_DROPS',
'GIFT_ONE_GET_ONE',
'GROUP_INVITE_ACCEPTED',
'GROUP_TASK_APPROVAL', 'GROUP_TASK_APPROVAL',
'GROUP_TASK_APPROVED', 'GROUP_TASK_APPROVED',
'GROUP_TASK_ASSIGNED', 'GROUP_TASK_ASSIGNED',
'GROUP_TASK_CLAIMED', 'GROUP_TASK_CLAIMED',
'GROUP_TASK_NEEDS_WORK', 'GROUP_TASK_NEEDS_WORK',
'LOGIN_INCENTIVE',
'GROUP_INVITE_ACCEPTED',
'SCORED_TASK',
'BOSS_DAMAGE', // Not used currently but kept to avoid validation errors
'GIFT_ONE_GET_ONE',
'GUILD_PROMPT', 'GUILD_PROMPT',
'GUILD_JOINED_ACHIEVEMENT', 'LEVELED_UP', // not in use
'CHALLENGE_JOINED_ACHIEVEMENT', 'LOGIN_INCENTIVE',
'INVITED_FRIEND_ACHIEVEMENT',
'CARD_RECEIVED',
'NEW_MYSTERY_ITEMS',
'UNALLOCATED_STATS_POINTS',
'NEW_INBOX_MESSAGE',
'NEW_STUFF',
'NEW_CHAT_MESSAGE', 'NEW_CHAT_MESSAGE',
'LEVELED_UP', // Not in use 'NEW_CONTRIBUTOR_LEVEL',
'FIRST_DROPS', 'NEW_INBOX_MESSAGE',
'NEW_MYSTERY_ITEMS',
'NEW_STUFF',
'ONBOARDING_COMPLETE', 'ONBOARDING_COMPLETE',
'ACHIEVEMENT_ALL_YOUR_BASE', 'REBIRTH_ENABLED',
'ACHIEVEMENT_BACK_TO_BASICS', 'SCORED_TASK',
'ACHIEVEMENT_JUST_ADD_WATER', 'UNALLOCATED_STATS_POINTS',
'ACHIEVEMENT_LOST_MASTERCLASSER', 'WON_CHALLENGE',
'ACHIEVEMENT_MIND_OVER_MATTER', // achievement notifications
'ACHIEVEMENT_DUST_DEVIL',
'ACHIEVEMENT_ARID_AUTHORITY',
'ACHIEVEMENT_PARTY_UP',
'ACHIEVEMENT_PARTY_ON',
'ACHIEVEMENT_BEAST_MASTER',
'ACHIEVEMENT_MOUNT_MASTER',
'ACHIEVEMENT_TRIAD_BINGO',
'ACHIEVEMENT_MONSTER_MAGUS',
'ACHIEVEMENT_UNDEAD_UNDERTAKER',
'ACHIEVEMENT_PRIMED_FOR_PAINTING',
'ACHIEVEMENT_PEARLY_PRO',
'ACHIEVEMENT_TICKLED_PINK',
'ACHIEVEMENT_ROSY_OUTLOOK',
'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',
'ACHIEVEMENT', // generic achievement notification, details inside `notification.data` 'ACHIEVEMENT', // generic achievement notification, details inside `notification.data`
'DROP_CAP_REACHED', 'CHALLENGE_JOINED_ACHIEVEMENT',
'GUILD_JOINED_ACHIEVEMENT',
'ACHIEVEMENT_PARTY_ON',
'ACHIEVEMENT_PARTY_UP',
'INVITED_FRIEND_ACHIEVEMENT',
'REBIRTH_ACHIEVEMENT',
'STREAK_ACHIEVEMENT',
'ULTIMATE_GEAR_ACHIEVEMENT',
'ACHIEVEMENT_STABLE',
'ACHIEVEMENT_QUESTS',
'ACHIEVEMENT_ANIMAL_SET',
'ACHIEVEMENT_PET_COLOR',
'ACHIEVEMENT_MOUNT_COLOR',
// Deprecated notification types. Can be removed once old data is cleaned out
'BOSS_DAMAGE', // deprecated
'ACHIEVEMENT_ALL_YOUR_BASE', // deprecated
'ACHIEVEMENT_BACK_TO_BASICS', // deprecated
'ACHIEVEMENT_JUST_ADD_WATER', // deprecated
'ACHIEVEMENT_LOST_MASTERCLASSER', // deprecated
'ACHIEVEMENT_MIND_OVER_MATTER', // deprecated
'ACHIEVEMENT_DUST_DEVIL', // deprecated
'ACHIEVEMENT_ARID_AUTHORITY', // deprecated
'ACHIEVEMENT_PARTY_UP', // deprecated
'ACHIEVEMENT_PARTY_ON', // deprecated
'ACHIEVEMENT_BEAST_MASTER', // deprecated
'ACHIEVEMENT_MOUNT_MASTER', // deprecated
'ACHIEVEMENT_TRIAD_BINGO', // deprecated
'ACHIEVEMENT_MONSTER_MAGUS', // deprecated
'ACHIEVEMENT_UNDEAD_UNDERTAKER', // deprecated
'ACHIEVEMENT_PRIMED_FOR_PAINTING', // deprecated
'ACHIEVEMENT_PEARLY_PRO', // deprecated
'ACHIEVEMENT_TICKLED_PINK', // deprecated
'ACHIEVEMENT_ROSY_OUTLOOK', // deprecated
'ACHIEVEMENT_BUG_BONANZA', // deprecated
'ACHIEVEMENT_BARE_NECESSITIES', // deprecated
'ACHIEVEMENT_FRESHWATER_FRIENDS', // deprecated
'ACHIEVEMENT_GOOD_AS_GOLD', // deprecated
'ACHIEVEMENT_ALL_THAT_GLITTERS', // deprecated
'ACHIEVEMENT_BONE_COLLECTOR', // deprecated
'ACHIEVEMENT_SKELETON_CREW', // deprecated
'ACHIEVEMENT_SEEING_RED', // deprecated
'ACHIEVEMENT_RED_LETTER_DAY', // deprecated
'ACHIEVEMENT_LEGENDARY_BESTIARY', // deprecated
'ACHIEVEMENT_SEASONAL_SPECIALIST', // deprecated
'ACHIEVEMENT_VIOLETS_ARE_BLUE', // deprecated
'ACHIEVEMENT_WILD_BLUE_YONDER', // deprecated
'ACHIEVEMENT_DOMESTICATED', // deprecated
'ACHIEVEMENT_SHADY_CUSTOMER', // deprecated
'ACHIEVEMENT_SHADE_OF_IT_ALL', // deprecated
'ACHIEVEMENT_ZODIAC_ZOOKEEPER', // deprecated
'ACHIEVEMENT_BIRDS_OF_A_FEATHER', // deprecated
]; ];
const { Schema } = mongoose; const { Schema } = mongoose;