From b75e65f42d4e8e6d9dbc720fa71d35a9760e0c09 Mon Sep 17 00:00:00 2001 From: negue Date: Fri, 20 Jul 2018 23:56:36 +0200 Subject: [PATCH 1/6] move modals to notifications (to open the modals) --- website/client/components/notifications.vue | 101 +++++++++++++----- .../components/snackbars/notification.vue | 10 +- website/client/mixins/notifications.js | 17 +-- website/common/locales/en/achievements.json | 1 + 4 files changed, 95 insertions(+), 34 deletions(-) diff --git a/website/client/components/notifications.vue b/website/client/components/notifications.vue index d255437879..75e6b55c30 100644 --- a/website/client/components/notifications.vue +++ b/website/client/components/notifications.vue @@ -87,6 +87,7 @@ div import axios from 'axios'; import moment from 'moment'; import throttle from 'lodash/throttle'; +import debounce from 'lodash/debounce'; import { shouldDo } from '../../common/script/cron'; import { mapState } from 'client/libs/store'; @@ -117,6 +118,44 @@ import ultimateGear from './achievements/ultimateGear'; import wonChallenge from './achievements/wonChallenge'; import loginIncentives from './achievements/login-incentives'; +const NOTIFICATIONS = { + CHALLENGE_JOINED_ACHIEVEMENT: { + achievement: true, + label: ($t) => `${$t('achievement')}: ${$t('joinedChallenge')}`, + modalId: 'joined-challenge', + }, + ULTIMATE_GEAR_ACHIEVEMENT: { + achievement: true, + label: ($t) => `${$t('achievement')}: ${$t('gearAchievement')}`, + modalId: 'ultimate-gear', + }, + REBIRTH_ACHIEVEMENT: { + label: ($t) => `${$t('achievement')}: ${$t('rebirthBegan')}`, + achievement: true, + modalId: 'rebirth', + }, + GUILD_JOINED_ACHIEVEMENT: { + label: ($t) => `${$t('achievement')}: ${$t('joinedGuild')}`, + achievement: true, + modalId: 'joined-guild', + }, + INVITED_FRIEND_ACHIEVEMENT: { + achievement: true, + label: ($t) => `${$t('achievement')}: ${$t('invitedFriend')}`, + modalId: 'invited-friend', + }, + NEW_CONTRIBUTOR_LEVEL: { + achievement: true, + label: ($t) => $t('modalContribAchievement'), + modalId: 'contributor', + }, + DEATH: { + sound: 'Death', + label: ($t) => $t('lostAllHealth'), + modalId: 'death', + }, +}; + export default { mixins: [notifications, guide], components: { @@ -206,8 +245,8 @@ export default { userHp (after, before) { if (this.user.needsCron) return; if (after <= 0) { - this.playSound('Death'); - this.$root.$emit('bv::show::modal', 'death'); + alert('userHp'); + this.showNotificationWithModal('DEATH'); // @TODO: {keyboard:false, backdrop:'static'} } else if (after <= 30 && !this.user.flags.warnedLowHealth) { this.$root.$emit('bv::show::modal', 'low-health'); @@ -282,7 +321,7 @@ export default { this.$store.dispatch('user:fetch'), this.$store.dispatch('tasks:fetchUserTasks'), ]).then(() => { - this.checkUserAchievements(); + this.debounceCheckUserAchievements(); // @TODO: This is a timeout to ensure dom is loaded window.setTimeout(() => { @@ -307,6 +346,30 @@ export default { document.removeEventListener('keydown', this.checkNextCron); }, methods: { + showNotificationWithModal (type, forceToModal) { + const config = NOTIFICATIONS[type]; + + if (!config) { + return; + } + + if (config.achievement) { + this.playSound('Achievement_Unlocked'); + } else if (config.sound) { + this.playSound(config.sound); + } + + if (forceToModal) { + this.$root.$emit('bv::show::modal', config.modalId); + } else { + this.text(config.label(this.$t), () => { + this.$root.$emit('bv::show::modal', config.modalId); + }, false); + } + }, + debounceCheckUserAchievements: debounce(function debounceCheck () { + this.checkUserAchievements(); + }, 700), checkUserAchievements () { if (this.user.needsCron) return; @@ -317,8 +380,7 @@ export default { } if (this.user.stats.hp <= 0) { - this.playSound('Death'); - this.$root.$emit('bv::show::modal', 'death'); + this.showNotificationWithModal('DEATH'); } if (this.questCompleted) { @@ -465,35 +527,20 @@ export default { this.$root.$emit('bv::show::modal', 'won-challenge'); break; case 'STREAK_ACHIEVEMENT': - this.streak(this.user.achievements.streak); + this.streak(this.user.achievements.streak, () => { + if (!this.user.preferences.suppressModals.streak) { + this.$root.$emit('bv::show::modal', 'streak'); + } + }); this.playSound('Achievement_Unlocked'); - if (!this.user.preferences.suppressModals.streak) { - this.$root.$emit('bv::show::modal', 'streak'); - } break; case 'ULTIMATE_GEAR_ACHIEVEMENT': - this.playSound('Achievement_Unlocked'); - this.$root.$emit('bv::show::modal', 'ultimate-gear'); - break; case 'REBIRTH_ACHIEVEMENT': - this.playSound('Achievement_Unlocked'); - this.$root.$emit('bv::show::modal', 'rebirth'); - break; case 'GUILD_JOINED_ACHIEVEMENT': - this.playSound('Achievement_Unlocked'); - this.$root.$emit('bv::show::modal', 'joined-guild'); - break; case 'CHALLENGE_JOINED_ACHIEVEMENT': - this.playSound('Achievement_Unlocked'); - this.$root.$emit('bv::show::modal', 'joined-challenge'); - break; case 'INVITED_FRIEND_ACHIEVEMENT': - this.playSound('Achievement_Unlocked'); - this.$root.$emit('bv::show::modal', 'invited-friend'); - break; case 'NEW_CONTRIBUTOR_LEVEL': - this.playSound('Achievement_Unlocked'); - this.$root.$emit('bv::show::modal', 'contributor'); + this.showNotificationWithModal(notification.type); break; case 'CRON': if (notification.data) { @@ -566,7 +613,7 @@ export default { }); } - this.checkUserAchievements(); + this.debounceCheckUserAchievements(); }, }, }; diff --git a/website/client/components/snackbars/notification.vue b/website/client/components/snackbars/notification.vue index 648387cdb1..69ca15b5fb 100644 --- a/website/client/components/snackbars/notification.vue +++ b/website/client/components/snackbars/notification.vue @@ -1,6 +1,6 @@ @@ -37,10 +36,8 @@ diff --git a/website/client/components/notifications.vue b/website/client/components/notifications.vue index 75e6b55c30..5fb3f54ce3 100644 --- a/website/client/components/notifications.vue +++ b/website/client/components/notifications.vue @@ -118,6 +118,8 @@ import ultimateGear from './achievements/ultimateGear'; import wonChallenge from './achievements/wonChallenge'; import loginIncentives from './achievements/login-incentives'; +import revive from '../../common/script/ops/revive'; + const NOTIFICATIONS = { CHALLENGE_JOINED_ACHIEVEMENT: { achievement: true, @@ -218,6 +220,7 @@ export default { isRunningYesterdailies: false, nextCron: null, handledNotifications, + reviveRunning: false, }; }, computed: { @@ -245,8 +248,7 @@ export default { userHp (after, before) { if (this.user.needsCron) return; if (after <= 0) { - alert('userHp'); - this.showNotificationWithModal('DEATH'); + this.showDeathNotification(); // @TODO: {keyboard:false, backdrop:'static'} } else if (after <= 30 && !this.user.flags.warnedLowHealth) { this.$root.$emit('bv::show::modal', 'low-health'); @@ -346,6 +348,21 @@ export default { document.removeEventListener('keydown', this.checkNextCron); }, methods: { + showDeathNotification () { + if (this.reviveRunning) return; + + this.reviveRunning = true; + this.showNotificationWithModal('DEATH'); + + // if there is an api call still running (which removes health) + // a call to "revive" wouldn't do anything since the user is still alive on the server + // wait a second until the prior api call is done + setTimeout(async () => { + await axios.post('/api/v4/user/revive'); + revive(this.user); + this.reviveRunning = false; + }, 1000); + }, showNotificationWithModal (type, forceToModal) { const config = NOTIFICATIONS[type]; @@ -380,7 +397,7 @@ export default { } if (this.user.stats.hp <= 0) { - this.showNotificationWithModal('DEATH'); + this.showDeathNotification(); } if (this.questCompleted) { From 9fd26a88ea5106c7b7a885feccaf504311328a7d Mon Sep 17 00:00:00 2001 From: negue Date: Sun, 29 Jul 2018 21:55:24 +0200 Subject: [PATCH 3/6] Update notification.vue remove duplicate methods props --- website/client/components/snackbars/notification.vue | 9 --------- 1 file changed, 9 deletions(-) diff --git a/website/client/components/snackbars/notification.vue b/website/client/components/snackbars/notification.vue index a4c433b0d3..69ca15b5fb 100644 --- a/website/client/components/snackbars/notification.vue +++ b/website/client/components/snackbars/notification.vue @@ -146,15 +146,6 @@ export default { beforeDestroy () { clearTimeout(this.timer); }, - methods: { - handleOnClick () { - if (typeof this.notification.onClick === 'function') { - this.notification.onClick(); - } - - this.show = false; - }, - }, watch: { show () { this.$store.dispatch('snackbars:remove', this.notification); From b596576c53608d333b48741f551d0aeb8dbc51ce Mon Sep 17 00:00:00 2001 From: negue Date: Sat, 18 Aug 2018 14:22:16 +0200 Subject: [PATCH 4/6] rollback death modal changes --- .../client/components/achievements/death.vue | 8 +++++ website/client/components/notifications.vue | 29 ++++--------------- 2 files changed, 13 insertions(+), 24 deletions(-) diff --git a/website/client/components/achievements/death.vue b/website/client/components/achievements/death.vue index 6333c66bf5..c052a48bbf 100644 --- a/website/client/components/achievements/death.vue +++ b/website/client/components/achievements/death.vue @@ -23,6 +23,7 @@ p.death-penalty {{ $t('deathPenaltyDetails') }} .modal-footer .col-12.text-center + button.btn.btn-danger(@click='revive()') {{ $t('refillHealthTryAgain') }} h4.text-center(v-html="$t('dyingOftenTips')") @@ -36,10 +37,12 @@ diff --git a/website/client/components/notifications.vue b/website/client/components/notifications.vue index f346a1f4bd..62e57fa614 100644 --- a/website/client/components/notifications.vue +++ b/website/client/components/notifications.vue @@ -118,8 +118,6 @@ import ultimateGear from './achievements/ultimateGear'; import wonChallenge from './achievements/wonChallenge'; import loginIncentives from './achievements/login-incentives'; -import revive from '../../common/script/ops/revive'; - const NOTIFICATIONS = { CHALLENGE_JOINED_ACHIEVEMENT: { achievement: true, @@ -151,11 +149,6 @@ const NOTIFICATIONS = { label: ($t) => $t('modalContribAchievement'), modalId: 'contributor', }, - DEATH: { - sound: 'Death', - label: ($t) => $t('lostAllHealth'), - modalId: 'death', - }, }; export default { @@ -220,7 +213,6 @@ export default { isRunningYesterdailies: false, nextCron: null, handledNotifications, - reviveRunning: false, }; }, computed: { @@ -248,7 +240,7 @@ export default { userHp (after, before) { if (this.user.needsCron) return; if (after <= 0) { - this.showDeathNotification(); + this.showDeathModal(); // @TODO: {keyboard:false, backdrop:'static'} } else if (after <= 30 && !this.user.flags.warnedLowHealth) { this.$root.$emit('bv::show::modal', 'low-health'); @@ -348,20 +340,9 @@ export default { document.removeEventListener('keydown', this.checkNextCron); }, methods: { - showDeathNotification () { - if (this.reviveRunning) return; - - this.reviveRunning = true; - this.showNotificationWithModal('DEATH'); - - // if there is an api call still running (which removes health) - // a call to "revive" wouldn't do anything since the user is still alive on the server - // wait a second until the prior api call is done - setTimeout(async () => { - await axios.post('/api/v4/user/revive'); - revive(this.user); - this.reviveRunning = false; - }, 1000); + showDeathModal () { + this.playSound('Death'); + this.$root.$emit('bv::show::modal', 'death'); }, showNotificationWithModal (type, forceToModal) { const config = NOTIFICATIONS[type]; @@ -397,7 +378,7 @@ export default { } if (this.user.stats.hp <= 0) { - this.showDeathNotification(); + this.showDeathModal(); } if (this.questCompleted) { From 07bc37407887a0cbf333ac79644f5ccdc5a66b51 Mon Sep 17 00:00:00 2001 From: negue Date: Mon, 27 Aug 2018 20:08:09 +0200 Subject: [PATCH 5/6] fix ultimate gear notification length - allow longer notifications but with a-like border-radius --- website/client/components/notifications.vue | 2 +- website/client/components/snackbars/notification.vue | 3 +-- website/common/locales/en/character.json | 1 + 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/website/client/components/notifications.vue b/website/client/components/notifications.vue index 4fa0b2e4dd..c1516a0644 100644 --- a/website/client/components/notifications.vue +++ b/website/client/components/notifications.vue @@ -127,7 +127,7 @@ const NOTIFICATIONS = { }, ULTIMATE_GEAR_ACHIEVEMENT: { achievement: true, - label: ($t) => `${$t('achievement')}: ${$t('gearAchievement')}`, + label: ($t) => `${$t('achievement')}: ${$t('gearAchievementNotification')}`, modalId: 'ultimate-gear', }, REBIRTH_ACHIEVEMENT: { diff --git a/website/client/components/snackbars/notification.vue b/website/client/components/snackbars/notification.vue index 69ca15b5fb..918f6b226e 100644 --- a/website/client/components/snackbars/notification.vue +++ b/website/client/components/snackbars/notification.vue @@ -33,7 +33,7 @@ transition(name="fade") diff --git a/website/client/components/notifications.vue b/website/client/components/notifications.vue index c1516a0644..0e0092d363 100644 --- a/website/client/components/notifications.vue +++ b/website/client/components/notifications.vue @@ -363,7 +363,18 @@ export default { this.playSound(config.sound); } - if (forceToModal) { + if (type === 'REBIRTH_ACHIEVEMENT') { + // reload if the user hasn't clicked on the notification + const timeOut = setTimeout(() => { + window.location.reload(true); + }, 60000); + + this.text(config.label(this.$t), () => { + // prevent the current reload timeout + clearTimeout(timeOut); + this.$root.$emit('bv::show::modal', config.modalId); + }, false); + } else if (forceToModal) { this.$root.$emit('bv::show::modal', config.modalId); } else { this.text(config.label(this.$t), () => { diff --git a/website/client/store/actions/user.js b/website/client/store/actions/user.js index d87fd8862f..9ae2ef3f3c 100644 --- a/website/client/store/actions/user.js +++ b/website/client/store/actions/user.js @@ -139,8 +139,6 @@ export function newStuffLater (store) { export async function rebirth () { let result = await axios.post('/api/v4/user/rebirth'); - window.location.reload(true); - return result; }