diff --git a/website/client/app.vue b/website/client/app.vue index b294bda767..648ae75e32 100644 --- a/website/client/app.vue +++ b/website/client/app.vue @@ -101,7 +101,7 @@ export default { }; }, computed: { - ...mapState(['isUserLoggedIn']), + ...mapState(['isUserLoggedIn', 'browserTimezoneOffset']), ...mapState({user: 'user.data'}), isStaticPage () { return this.$route.meta.requiresLogin === false ? true : false; @@ -164,11 +164,19 @@ export default { Analytics.setUser(); Analytics.updateUser(); - const loadingScreen = document.getElementById('loading-screen'); - document.body.removeChild(loadingScreen); + this.hideLoadingScreen(); + + // Adjust the timezone offset + if (this.user.preferences.timezoneOffset !== this.browserTimezoneOffset) { + this.$store.dispatch('user:set', { + 'preferences.timezoneOffset': this.browserTimezoneOffset, + }); + } }).catch((err) => { console.error('Impossible to fetch user. Clean up localStorage and refresh.', err); // eslint-disable-line no-console }); + } else { + this.hideLoadingScreen(); } // Manage modals @@ -254,7 +262,10 @@ export default { this.$store.dispatch('user:castSpell', {key: this.selectedCardToBuy.key, targetId: member.id}); this.selectedCardToBuy = null; }, - + hideLoadingScreen () { + const loadingScreen = document.getElementById('loading-screen'); + if (loadingScreen) document.body.removeChild(loadingScreen); + }, }, }; diff --git a/website/client/assets/scss/loading-screen.scss b/website/client/assets/scss/loading-screen.scss index c055690440..00aa6b92df 100644 --- a/website/client/assets/scss/loading-screen.scss +++ b/website/client/assets/scss/loading-screen.scss @@ -1,4 +1,5 @@ #loading-screen { + z-index: 1050; position: absolute; top: 0; bottom: 0; diff --git a/website/client/components/notifications.vue b/website/client/components/notifications.vue index 088d0a8533..7703af4653 100644 --- a/website/client/components/notifications.vue +++ b/website/client/components/notifications.vue @@ -284,7 +284,7 @@ export default { console.log('next cron in', nextCronIn); - setInterval(async () => { + setTimeout(async () => { console.log('next cron timer fired, current time:', new Date(), 'syncing...'); // Sync the user before showing the modal await Promise.all([ diff --git a/website/client/components/tasks/spells.vue b/website/client/components/tasks/spells.vue index be4922e81a..20b970898f 100644 --- a/website/client/components/tasks/spells.vue +++ b/website/client/components/tasks/spells.vue @@ -283,17 +283,6 @@ export default { this.$store.state.spellOptions.castingSpell = false; this.potionClickMode = false; - // @TODO: We no longer wrap the users (or at least we should not), but some common code - // expects the user to be wrapped. For now, just manually set. But we need to fix the common code - this.user.fns = { - crit: (...args) => { - return crit(this.user, ...args); - }, - updateStats: (...args) => { - return updateStats(this.user, ...args); - }, - }; - this.spell.cast(this.user, target); // User.save(); // @TODO: diff --git a/website/client/store/index.js b/website/client/store/index.js index 8c8cf9358e..74e3fd4130 100644 --- a/website/client/store/index.js +++ b/website/client/store/index.js @@ -15,6 +15,7 @@ const IS_TEST = process.env.NODE_ENV === 'test'; // eslint-disable-line no-proce // Load user auth parameters and determine if it's logged in // before trying to load data let isUserLoggedIn = false; +let browserTimezoneOffset = moment().zone(); // eg, 240 - this will be converted on server as -(offset/60) axios.defaults.headers.common['x-client'] = 'habitica-web'; let AUTH_SETTINGS = localStorage.getItem('habit-mobile-settings'); @@ -24,8 +25,7 @@ if (AUTH_SETTINGS) { axios.defaults.headers.common['x-api-user'] = AUTH_SETTINGS.auth.apiId; axios.defaults.headers.common['x-api-key'] = AUTH_SETTINGS.auth.apiToken; - const timezoneOffset = moment().zone(); // eg, 240 - this will be converted on server as -(offset/60) - axios.defaults.headers.common['x-user-timezoneOffset'] = timezoneOffset; + axios.defaults.headers.common['x-user-timezoneOffset'] = browserTimezoneOffset; isUserLoggedIn = true; } @@ -55,6 +55,10 @@ export default function () { title: 'Habitica', isUserLoggedIn, user: asyncResourceFactory(), + // store the timezone offset in case it's different than the one in + // user.preferences.timezoneOffset and change it after the user is synced + // in app.vue + browserTimezoneOffset, tasks: asyncResourceFactory(), // user tasks completedTodosStatus: 'NOT_LOADED', party: { diff --git a/website/common/script/content/spells.js b/website/common/script/content/spells.js index e5e996018a..bda0304142 100644 --- a/website/common/script/content/spells.js +++ b/website/common/script/content/spells.js @@ -2,6 +2,8 @@ import t from './translation'; import each from 'lodash/each'; import { NotAuthorized } from '../libs/errors'; import statsComputed from '../libs/statsComputed'; +import crit from '../fns/crit'; +import updateStats from '../fns/updateStats'; /* --------------------------------------------------------------- @@ -43,12 +45,12 @@ spells.wizard = { target: 'task', notes: t('spellWizardFireballNotes'), cast (user, target, req) { - let bonus = statsComputed(user).int * user.fns.crit('per'); + let bonus = statsComputed(user).int * crit(user, 'per'); bonus *= Math.ceil((target.value < 0 ? 1 : target.value + 1) * 0.075); user.stats.exp += diminishingReturns(bonus, 75); if (!user.party.quest.progress.up) user.party.quest.progress.up = 0; user.party.quest.progress.up += Math.ceil(statsComputed(user).int * 0.1); - user.fns.updateStats(user.stats, req); + updateStats(user, user.stats, req); }, }, mpheal: { // Ethereal Surge @@ -100,7 +102,7 @@ spells.warrior = { target: 'task', notes: t('spellWarriorSmashNotes'), cast (user, target) { - let bonus = statsComputed(user).str * user.fns.crit('con'); + let bonus = statsComputed(user).str * crit(user, 'con'); target.value += diminishingReturns(bonus, 2.5, 35); if (!user.party.quest.progress.up) user.party.quest.progress.up = 0; user.party.quest.progress.up += diminishingReturns(bonus, 55, 70); @@ -167,11 +169,11 @@ spells.rogue = { target: 'task', notes: t('spellRogueBackStabNotes'), cast (user, target, req) { - let _crit = user.fns.crit('str', 0.3); + let _crit = crit(user, 'str', 0.3); let bonus = calculateBonus(target.value, statsComputed(user).str, _crit); user.stats.exp += diminishingReturns(bonus, 75, 50); user.stats.gp += diminishingReturns(bonus, 18, 75); - user.fns.updateStats(user.stats, req); + updateStats(user, user.stats, req); }, }, toolsOfTrade: { // Tools of the Trade