mirror of
https://github.com/HabitRPG/habitica.git
synced 2025-12-16 22:27:26 +01:00
feat(notifications): alert user to achievements
This commit is contained in:
@@ -0,0 +1,42 @@
|
|||||||
|
<template lang="pug">
|
||||||
|
b-modal#generic-achievement(:title='data.message', size='md', :hide-footer='true')
|
||||||
|
.modal-body
|
||||||
|
.col-12
|
||||||
|
achievement-avatar.avatar
|
||||||
|
.col-6.offset-3.text-center
|
||||||
|
p(v-html='data.modalText')
|
||||||
|
button.btn.btn-primary(@click='close()') {{ $t('huzzah') }}
|
||||||
|
achievement-footer
|
||||||
|
</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 'client/libs/store';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
achievementFooter,
|
||||||
|
achievementAvatar,
|
||||||
|
},
|
||||||
|
props: ['data'],
|
||||||
|
computed: {
|
||||||
|
...mapState({user: 'user.data'}),
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
close () {
|
||||||
|
this.$root.$emit('bv::hide::modal', 'generic-achievement');
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
46
website/client/components/achievements/justAddWater.vue
Normal file
46
website/client/components/achievements/justAddWater.vue
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
<template lang="pug">
|
||||||
|
b-modal#just-add-water(:title='title', size='md', :hide-footer='true')
|
||||||
|
.modal-body
|
||||||
|
.col-12
|
||||||
|
achievement-avatar.avatar
|
||||||
|
.col-6.offset-3.text-center
|
||||||
|
p {{ $t('achievementJustAddWaterModalText') }}
|
||||||
|
button.btn.btn-primary(@click='close()') {{ $t('huzzah') }}
|
||||||
|
achievement-footer
|
||||||
|
</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 'client/libs/store';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
achievementFooter,
|
||||||
|
achievementAvatar,
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapState({user: 'user.data'}),
|
||||||
|
},
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
title: `${this.$t('modalAchievement')} ${this.$t('achievementJustAddWater')}`,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
close () {
|
||||||
|
this.$root.$emit('bv::hide::modal', 'just-add-water');
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
46
website/client/components/achievements/lostMasterclasser.vue
Normal file
46
website/client/components/achievements/lostMasterclasser.vue
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
<template lang="pug">
|
||||||
|
b-modal#lost-masterclasser(:title='title', size='md', :hide-footer='true')
|
||||||
|
.modal-body
|
||||||
|
.col-12
|
||||||
|
achievement-avatar.avatar
|
||||||
|
.col-6.offset-3.text-center
|
||||||
|
p {{ $t('achievementLostMasterclasserModalText') }}
|
||||||
|
button.btn.btn-primary(@click='close()') {{ $t('huzzah') }}
|
||||||
|
achievement-footer
|
||||||
|
</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 'client/libs/store';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
achievementFooter,
|
||||||
|
achievementAvatar,
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapState({user: 'user.data'}),
|
||||||
|
},
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
title: `${this.$t('modalAchievement')} ${this.$t('achievementLostMasterclasser')}`,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
close () {
|
||||||
|
this.$root.$emit('bv::hide::modal', 'lost-masterclasser');
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
46
website/client/components/achievements/mindOverMatter.vue
Normal file
46
website/client/components/achievements/mindOverMatter.vue
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
<template lang="pug">
|
||||||
|
b-modal#mind-over-matter(:title='title', size='md', :hide-footer='true')
|
||||||
|
.modal-body
|
||||||
|
.col-12
|
||||||
|
achievement-avatar.avatar
|
||||||
|
.col-6.offset-3.text-center
|
||||||
|
p {{ $t('achievementMindOverMatterModalText') }}
|
||||||
|
button.btn.btn-primary(@click='close()') {{ $t('huzzah') }}
|
||||||
|
achievement-footer
|
||||||
|
</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 'client/libs/store';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
achievementFooter,
|
||||||
|
achievementAvatar,
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapState({user: 'user.data'}),
|
||||||
|
},
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
title: `${this.$t('modalAchievement')} ${this.$t('achievementMindOverMatter')}`,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
close () {
|
||||||
|
this.$root.$emit('bv::hide::modal', 'mind-over-matter');
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
<template lang="pug">
|
||||||
|
base-notification(
|
||||||
|
:can-remove="canRemove",
|
||||||
|
:notification="notification",
|
||||||
|
:read-after-click="true",
|
||||||
|
@click="action"
|
||||||
|
)
|
||||||
|
div(slot="content", v-html="achievementString")
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import BaseNotification from './base';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
props: ['notification', 'canRemove'],
|
||||||
|
components: {
|
||||||
|
BaseNotification,
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
achievementString () {
|
||||||
|
return `<strong>${this.$t('achievement')}</strong>: ${this.$t('achievementJustAddWater')}`;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
action () {
|
||||||
|
this.$root.$emit('bv::show::modal', 'just-add-water');
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
<template lang="pug">
|
||||||
|
base-notification(
|
||||||
|
:can-remove="canRemove",
|
||||||
|
:notification="notification",
|
||||||
|
:read-after-click="true",
|
||||||
|
@click="action"
|
||||||
|
)
|
||||||
|
div(slot="content", v-html="achievementString")
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import BaseNotification from './base';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
props: ['notification', 'canRemove'],
|
||||||
|
components: {
|
||||||
|
BaseNotification,
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
achievementString () {
|
||||||
|
return `<strong>${this.$t('achievement')}</strong>: ${this.$t('achievementLostMasterclasser')}`;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
action () {
|
||||||
|
this.$root.$emit('bv::show::modal', 'lost-masterclasser');
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
<template lang="pug">
|
||||||
|
base-notification(
|
||||||
|
:can-remove="canRemove",
|
||||||
|
:notification="notification",
|
||||||
|
:read-after-click="true",
|
||||||
|
@click="action"
|
||||||
|
)
|
||||||
|
div(slot="content", v-html="achievementString")
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import BaseNotification from './base';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
props: ['notification', 'canRemove'],
|
||||||
|
components: {
|
||||||
|
BaseNotification,
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
achievementString () {
|
||||||
|
return `<strong>${this.$t('achievement')}</strong>: ${this.$t('achievementMindOverMatter')}`;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
action () {
|
||||||
|
this.$root.$emit('bv::show::modal', 'mind-over-matter');
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
@@ -95,6 +95,9 @@ import NEW_INBOX_MESSAGE from './notifications/newInboxMessage';
|
|||||||
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';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
@@ -106,6 +109,7 @@ export default {
|
|||||||
QUEST_INVITATION, GROUP_TASK_APPROVAL, GROUP_TASK_APPROVED, GROUP_TASK_ASSIGNED,
|
QUEST_INVITATION, GROUP_TASK_APPROVAL, GROUP_TASK_APPROVED, GROUP_TASK_ASSIGNED,
|
||||||
UNALLOCATED_STATS_POINTS, NEW_MYSTERY_ITEMS, CARD_RECEIVED,
|
UNALLOCATED_STATS_POINTS, NEW_MYSTERY_ITEMS, CARD_RECEIVED,
|
||||||
NEW_INBOX_MESSAGE, NEW_CHAT_MESSAGE,
|
NEW_INBOX_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,
|
||||||
},
|
},
|
||||||
@@ -130,6 +134,7 @@ export default {
|
|||||||
'QUEST_INVITATION', 'GROUP_TASK_ASSIGNED', 'GROUP_TASK_APPROVAL', 'GROUP_TASK_APPROVED',
|
'QUEST_INVITATION', 'GROUP_TASK_ASSIGNED', 'GROUP_TASK_APPROVAL', 'GROUP_TASK_APPROVED',
|
||||||
'NEW_MYSTERY_ITEMS', 'CARD_RECEIVED',
|
'NEW_MYSTERY_ITEMS', 'CARD_RECEIVED',
|
||||||
'NEW_INBOX_MESSAGE', 'NEW_CHAT_MESSAGE', 'UNALLOCATED_STATS_POINTS',
|
'NEW_INBOX_MESSAGE', 'NEW_CHAT_MESSAGE', 'UNALLOCATED_STATS_POINTS',
|
||||||
|
'ACHIEVEMENT_JUST_ADD_WATER', 'ACHIEVEMENT_LOST_MASTERCLASSER', 'ACHIEVEMENT_MIND_OVER_MATTER',
|
||||||
'VERIFY_USERNAME',
|
'VERIFY_USERNAME',
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -26,6 +26,10 @@ div
|
|||||||
quest-completed
|
quest-completed
|
||||||
quest-invitation
|
quest-invitation
|
||||||
verify-username
|
verify-username
|
||||||
|
generic-achievement(:data='notificationData')
|
||||||
|
just-add-water
|
||||||
|
lost-masterclasser
|
||||||
|
mind-over-matter
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang='scss'>
|
<style lang='scss'>
|
||||||
@@ -118,6 +122,10 @@ import rebirth from './achievements/rebirth';
|
|||||||
import streak from './achievements/streak';
|
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 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 verifyUsername from './settings/verifyUsername';
|
import verifyUsername from './settings/verifyUsername';
|
||||||
|
|
||||||
@@ -147,6 +155,16 @@ const NOTIFICATIONS = {
|
|||||||
label: ($t) => $t('modalContribAchievement'),
|
label: ($t) => $t('modalContribAchievement'),
|
||||||
modalId: 'contributor',
|
modalId: 'contributor',
|
||||||
},
|
},
|
||||||
|
ACHIEVEMENT_ALL_YOUR_BASE: {
|
||||||
|
achievement: true,
|
||||||
|
label: ($t) => `${$t('achievement')}: ${$t('achievementAllYourBase')}`,
|
||||||
|
modalId: 'generic-achievement',
|
||||||
|
},
|
||||||
|
ACHIEVEMENT_BACK_TO_BASICS: {
|
||||||
|
achievement: true,
|
||||||
|
label: ($t) => `${$t('achievement')}: ${$t('achievementBackToBasics')}`,
|
||||||
|
modalId: 'generic-achievement',
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
@@ -176,6 +194,10 @@ export default {
|
|||||||
contributor,
|
contributor,
|
||||||
loginIncentives,
|
loginIncentives,
|
||||||
verifyUsername,
|
verifyUsername,
|
||||||
|
genericAchievement,
|
||||||
|
lostMasterclasser,
|
||||||
|
mindOverMatter,
|
||||||
|
justAddWater,
|
||||||
},
|
},
|
||||||
data () {
|
data () {
|
||||||
// Levels that already display modals and should not trigger generic Level Up
|
// Levels that already display modals and should not trigger generic Level Up
|
||||||
@@ -197,7 +219,8 @@ export default {
|
|||||||
'GUILD_PROMPT', 'DROPS_ENABLED', 'REBIRTH_ENABLED', 'WON_CHALLENGE', 'STREAK_ACHIEVEMENT',
|
'GUILD_PROMPT', 'DROPS_ENABLED', 'REBIRTH_ENABLED', 'WON_CHALLENGE', 'STREAK_ACHIEVEMENT',
|
||||||
'ULTIMATE_GEAR_ACHIEVEMENT', 'REBIRTH_ACHIEVEMENT', 'GUILD_JOINED_ACHIEVEMENT',
|
'ULTIMATE_GEAR_ACHIEVEMENT', 'REBIRTH_ACHIEVEMENT', 'GUILD_JOINED_ACHIEVEMENT',
|
||||||
'CHALLENGE_JOINED_ACHIEVEMENT', 'INVITED_FRIEND_ACHIEVEMENT', 'NEW_CONTRIBUTOR_LEVEL',
|
'CHALLENGE_JOINED_ACHIEVEMENT', 'INVITED_FRIEND_ACHIEVEMENT', 'NEW_CONTRIBUTOR_LEVEL',
|
||||||
'CRON', 'SCORED_TASK', 'LOGIN_INCENTIVE',
|
'CRON', 'SCORED_TASK', 'LOGIN_INCENTIVE', 'ACHIEVEMENT_ALL_YOUR_BASE', 'ACHIEVEMENT_BACK_TO_BASICS',
|
||||||
|
'GENERIC_ACHIEVEMENT',
|
||||||
].forEach(type => {
|
].forEach(type => {
|
||||||
handledNotifications[type] = true;
|
handledNotifications[type] = true;
|
||||||
});
|
});
|
||||||
@@ -342,8 +365,8 @@ export default {
|
|||||||
this.playSound('Death');
|
this.playSound('Death');
|
||||||
this.$root.$emit('bv::show::modal', 'death');
|
this.$root.$emit('bv::show::modal', 'death');
|
||||||
},
|
},
|
||||||
showNotificationWithModal (type, forceToModal) {
|
showNotificationWithModal (notification, forceToModal) {
|
||||||
const config = NOTIFICATIONS[type];
|
const config = NOTIFICATIONS[notification.type];
|
||||||
|
|
||||||
if (!config) {
|
if (!config) {
|
||||||
return;
|
return;
|
||||||
@@ -355,6 +378,10 @@ export default {
|
|||||||
this.playSound(config.sound);
|
this.playSound(config.sound);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (notification.data) {
|
||||||
|
this.notificationData = notification.data;
|
||||||
|
}
|
||||||
|
|
||||||
if (forceToModal) {
|
if (forceToModal) {
|
||||||
this.$root.$emit('bv::show::modal', config.modalId);
|
this.$root.$emit('bv::show::modal', config.modalId);
|
||||||
} else {
|
} else {
|
||||||
@@ -566,7 +593,10 @@ export default {
|
|||||||
case 'CHALLENGE_JOINED_ACHIEVEMENT':
|
case 'CHALLENGE_JOINED_ACHIEVEMENT':
|
||||||
case 'INVITED_FRIEND_ACHIEVEMENT':
|
case 'INVITED_FRIEND_ACHIEVEMENT':
|
||||||
case 'NEW_CONTRIBUTOR_LEVEL':
|
case 'NEW_CONTRIBUTOR_LEVEL':
|
||||||
this.showNotificationWithModal(notification.type);
|
case 'ACHIEVEMENT_ALL_YOUR_BASE':
|
||||||
|
case 'ACHIEVEMENT_BACK_TO_BASICS':
|
||||||
|
case 'GENERIC_ACHIEVEMENT':
|
||||||
|
this.showNotificationWithModal(notification);
|
||||||
break;
|
break;
|
||||||
case 'CRON':
|
case 'CRON':
|
||||||
if (notification.data) {
|
if (notification.data) {
|
||||||
|
|||||||
@@ -6,12 +6,17 @@
|
|||||||
"reachedLevel": "You Reached Level <%= level %>",
|
"reachedLevel": "You Reached Level <%= level %>",
|
||||||
"achievementLostMasterclasser": "Quest Completionist: Masterclasser Series",
|
"achievementLostMasterclasser": "Quest Completionist: Masterclasser Series",
|
||||||
"achievementLostMasterclasserText": "Completed all sixteen quests in the Masterclasser Quest Series and solved the mystery of the Lost Masterclasser!",
|
"achievementLostMasterclasserText": "Completed all sixteen quests in the Masterclasser Quest Series and solved the mystery of the Lost Masterclasser!",
|
||||||
|
"achievementLostMasterclasserModalText": "You completed all sixteen quests in the Masterclasser Quest Series and solved the mystery of the Lost Masterclasser!",
|
||||||
"achievementMindOverMatter": "Mind Over Matter",
|
"achievementMindOverMatter": "Mind Over Matter",
|
||||||
"achievementMindOverMatterText": "Has completed Rock, Slime, and Yarn pet quests.",
|
"achievementMindOverMatterText": "Has completed Rock, Slime, and Yarn pet quests.",
|
||||||
|
"achievementMindOverMatterModalText": "You completed the Rock, Slime, and Yarn pet quests!",
|
||||||
"achievementJustAddWater": "Just Add Water",
|
"achievementJustAddWater": "Just Add Water",
|
||||||
"achievementJustAddWaterText": "Has completed Octopus, Seahorse, Cuttlefish, Whale, Turtle, Nudibranch, Sea Serpent, and Dolphin pet quests.",
|
"achievementJustAddWaterText": "Has completed Octopus, Seahorse, Cuttlefish, Whale, Turtle, Nudibranch, Sea Serpent, and Dolphin pet quests.",
|
||||||
|
"achievementJustAddWaterModalText": "You completed the Octopus, Seahorse, Cuttlefish, Whale, Turtle, Nudibranch, Sea Serpent, and Dolphin pet quests!",
|
||||||
"achievementBackToBasics": "Back to Basics",
|
"achievementBackToBasics": "Back to Basics",
|
||||||
"achievementBackToBasicsText": "Has collected all Base Pets.",
|
"achievementBackToBasicsText": "Has collected all Base Pets.",
|
||||||
|
"achievementBackToBasicsModalText": "You collected all the Base Pets!",
|
||||||
"achievementAllYourBase": "All Your Base",
|
"achievementAllYourBase": "All Your Base",
|
||||||
"achievementAllYourBaseText": "Has tamed all Base Mounts."
|
"achievementAllYourBaseText": "Has tamed all Base Mounts.",
|
||||||
|
"achievementAllYourBaseModalText": "You tamed all the Base Mounts!"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -96,6 +96,13 @@ module.exports = function feed (user, req = {}) {
|
|||||||
});
|
});
|
||||||
if (mountIndex === -1) {
|
if (mountIndex === -1) {
|
||||||
user.achievements.allYourBase = true;
|
user.achievements.allYourBase = true;
|
||||||
|
if (user.addNotification) {
|
||||||
|
user.addNotification('ACHIEVEMENT_ALL_YOUR_BASE', {
|
||||||
|
achievement: 'allYourBase',
|
||||||
|
message: `${i18n.t('modalAchievement')} ${i18n.t('achievementAllYourBase')}`,
|
||||||
|
modalText: i18n.t('achievementAllYourBaseModalText'),
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -46,6 +46,13 @@ module.exports = function hatch (user, req = {}) {
|
|||||||
});
|
});
|
||||||
if (petIndex === -1) {
|
if (petIndex === -1) {
|
||||||
user.achievements.backToBasics = true;
|
user.achievements.backToBasics = true;
|
||||||
|
if (user.addNotification) {
|
||||||
|
user.addNotification('ACHIEVEMENT_BACK_TO_BASICS', {
|
||||||
|
achievement: 'backToBasics',
|
||||||
|
message: `${i18n.t('modalAchievement')} ${i18n.t('achievementBackToBasics')}`,
|
||||||
|
modalText: i18n.t('achievementBackToBasicsModalText'),
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -886,8 +886,20 @@ schema.methods.finishQuest = async function finishQuest (quest) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let questAchievementUpdate = {$set: {}};
|
let 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 achievementSnakeCase = `ACHIEVEMENT_${_.snakeCase(achievement).toUpperCase()}`;
|
||||||
|
questAchievementUpdate.$push = {
|
||||||
|
notifications: new UserNotification({
|
||||||
|
type: achievementSnakeCase,
|
||||||
|
data: {
|
||||||
|
achievement,
|
||||||
|
message: `${shared.i18n.t('modalAchievement')} ${shared.i18n.t(`achievement${achievementTitleCase}`)}`,
|
||||||
|
modalText: shared.i18n.t(`achievement${achievementTitleCase}ModalText`),
|
||||||
|
},
|
||||||
|
}).toObject(),
|
||||||
|
};
|
||||||
|
|
||||||
promises.push(participants.map(userId => {
|
promises.push(participants.map(userId => {
|
||||||
return _updateUserWithRetries(userId, questAchievementUpdate, null, questAchievementQuery);
|
return _updateUserWithRetries(userId, questAchievementUpdate, null, questAchievementQuery);
|
||||||
|
|||||||
@@ -32,6 +32,10 @@ const NOTIFICATION_TYPES = [
|
|||||||
'NEW_STUFF',
|
'NEW_STUFF',
|
||||||
'NEW_CHAT_MESSAGE',
|
'NEW_CHAT_MESSAGE',
|
||||||
'LEVELED_UP',
|
'LEVELED_UP',
|
||||||
|
'ACHIEVEMENT_ALL_YOUR_BASE',
|
||||||
|
'ACHIEVEMENT_BACK_TO_BASICS',
|
||||||
|
'ACHIEVEMENT_JUST_ADD_WATER',
|
||||||
|
'ACHIEVEMENT_MIND_OVER_MATTER',
|
||||||
];
|
];
|
||||||
|
|
||||||
const Schema = mongoose.Schema;
|
const Schema = mongoose.Schema;
|
||||||
|
|||||||
Reference in New Issue
Block a user