Squashed commit of the following:

commit 613e6af7f0dfa3862dff117fadbb7194a29b8dbd
Author: Sabe Jones <sabe@habitica.com>
Date:   Tue Sep 3 16:57:02 2024 -0500

    feat(promo): add canonical dates for gem sales

commit 8e2fbebf3c663b0d5af5c10f3019726dbed1ca31
Author: Sabe Jones <sabe@habitica.com>
Date:   Fri Aug 23 17:08:20 2024 -0500

    fix(gems): correct Gem amounts during sale

commit 85853c697ba8eb5e6d0e053e1fe1eab295028f23
Author: Sabe Jones <sabe@habitica.com>
Date:   Fri Aug 16 16:57:02 2024 -0500

    fix(event): show user timezone to compare to UTC

commit a0a312a315cb2efad0db9370109cb036a8af0b0a
Author: Sabe Jones <sabe@habitica.com>
Date:   Fri Aug 16 15:49:08 2024 -0500

    refactor(promo): add UTC parenthetical
This commit is contained in:
Sabe Jones
2024-09-03 17:03:21 -05:00
parent dd334f487e
commit fb626ebf7e
5 changed files with 68 additions and 53 deletions

View File

@@ -35,6 +35,7 @@
"lodash": "^4.17.21", "lodash": "^4.17.21",
"moment": "^2.29.4", "moment": "^2.29.4",
"moment-locales-webpack-plugin": "^1.2.0", "moment-locales-webpack-plugin": "^1.2.0",
"moment-timezone": "^0.5.45",
"nconf": "^0.12.1", "nconf": "^0.12.1",
"sass": "^1.63.4", "sass": "^1.63.4",
"sass-loader": "^14.1.1", "sass-loader": "^14.1.1",
@@ -9622,6 +9623,17 @@
"webpack": "^1 || ^2 || ^3 || ^4 || ^5" "webpack": "^1 || ^2 || ^3 || ^4 || ^5"
} }
}, },
"node_modules/moment-timezone": {
"version": "0.5.45",
"resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.45.tgz",
"integrity": "sha512-HIWmqA86KcmCAhnMAN0wuDOARV/525R2+lOLotuGFzn4HO+FH+/645z2wx0Dt3iDv6/p61SIvKnDstISainhLQ==",
"dependencies": {
"moment": "^2.29.4"
},
"engines": {
"node": "*"
}
},
"node_modules/mrmime": { "node_modules/mrmime": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.0.tgz", "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.0.tgz",

View File

@@ -37,6 +37,7 @@
"lodash": "^4.17.21", "lodash": "^4.17.21",
"moment": "^2.29.4", "moment": "^2.29.4",
"moment-locales-webpack-plugin": "^1.2.0", "moment-locales-webpack-plugin": "^1.2.0",
"moment-timezone": "^0.5.45",
"nconf": "^0.12.1", "nconf": "^0.12.1",
"sass": "^1.63.4", "sass": "^1.63.4",
"sass-loader": "^14.1.1", "sass-loader": "^14.1.1",

View File

@@ -4,7 +4,7 @@
id="buy-gems" id="buy-gems"
:hide-footer="true" :hide-footer="true"
size="md" size="md"
:modal-class="eventClass" :modal-class="eventInfo?.class"
> >
<div <div
slot="modal-header" slot="modal-header"
@@ -21,7 +21,7 @@
class="col-12 text-center" class="col-12 text-center"
> >
<img <img
v-if="eventName === 'fall_extra_gems'" v-if="eventInfo?.name === 'fall_extra_gems'"
:alt="$t('supportHabitica')" :alt="$t('supportHabitica')"
srcset=" srcset="
~@/assets/images/gems/fall-header.png, ~@/assets/images/gems/fall-header.png,
@@ -30,7 +30,7 @@
src="~@/assets/images/gems/fall-header.png" src="~@/assets/images/gems/fall-header.png"
> >
<img <img
v-else-if="eventName === 'spooky_extra_gems'" v-else-if="eventInfo?.name === 'spooky_extra_gems'"
:alt="$t('supportHabitica')" :alt="$t('supportHabitica')"
srcset=" srcset="
~@/assets/images/gems/spooky-header.png, ~@/assets/images/gems/spooky-header.png,
@@ -51,7 +51,7 @@
</div> </div>
</div> </div>
<div <div
v-if="currentEvent && currentEvent.promo && currentEvent.promo === 'g1g1'" v-if="eventInfo?.promo === 'g1g1'"
class="gift-promo-banner d-flex justify-content-around align-items-center px-4" class="gift-promo-banner d-flex justify-content-around align-items-center px-4"
@click="showSelectUser" @click="showSelectUser"
> >
@@ -162,24 +162,32 @@
:amazon-data="{type: 'single', gemsBlock: selectedGemsBlock}" :amazon-data="{type: 'single', gemsBlock: selectedGemsBlock}"
/> />
<div <div
v-if="eventName === 'fall_extra_gems' || eventName === 'spooky_extra_gems'" v-if="eventInfo?.name === 'fall_extra_gems' || eventInfo?.name === 'spooky_extra_gems'"
class="d-flex flex-column justify-content-center" class="d-flex flex-column justify-content-center"
> >
<h4 class="mt-3 mx-auto"> <h4 class="mt-3 mx-auto">
{{ $t('howItWorks') }} {{ $t('howItWorks') }}
</h4> </h4>
<small class="text-center"> <small class="text-center">
{{ $t('gemSaleHow', { eventStartMonth, eventStartOrdinal, eventEndOrdinal }) }} {{ $t('gemSaleHow', {
eventStartMonth: eventInfo.startMonth,
eventStartOrdinal: eventInfo.startOrdinal,
eventEndOrdinal: eventInfo.endOrdinal,
}) }}
</small> </small>
<h4 class="mt-3 mx-auto"> <h4 class="mt-3 mx-auto">
{{ $t('limitations') }} {{ $t('limitations') }}
</h4> </h4>
<small class="text-center"> <small class="text-center">
{{ $t('gemSaleLimitations', { {{ $t('gemSaleLimitationsText', {
eventStartMonth, eventStartMonth: eventInfo.startMonth,
eventStartOrdinal, eventStartOrdinal: eventInfo.startOrdinal,
eventEndMonth, eventStartTime: eventInfo.startTime,
eventEndOrdinal, eventStartUTC: eventInfo.startUTC,
eventEndMonth: eventInfo.endMonth,
eventEndOrdinal: eventInfo.endOrdinal,
eventEndTime: eventInfo.endTime,
eventEndUTC: eventInfo.endUTC,
}) }} }) }}
</small> </small>
</div> </div>
@@ -385,7 +393,7 @@
<script> <script>
import find from 'lodash/find'; import find from 'lodash/find';
import moment from 'moment'; import moment from 'moment-timezone';
import { mapState } from '@/libs/store'; import { mapState } from '@/libs/store';
import markdown from '@/directives/markdown'; import markdown from '@/directives/markdown';
import paymentsMixin from '@/mixins/payments'; import paymentsMixin from '@/mixins/payments';
@@ -431,37 +439,31 @@ export default {
originalGemsBlocks: 'content.gems', originalGemsBlocks: 'content.gems',
currentEventList: 'worldState.data.currentEventList', currentEventList: 'worldState.data.currentEventList',
}), }),
currentEvent () { eventInfo () {
return find(this.currentEventList, event => Boolean(event.gemsPromo) || Boolean(event.promo)); const currentEvent = find(
}, this.currentEventList, event => Boolean(event.gemsPromo) || Boolean(event.promo),
eventName () { );
return this.currentEvent && this.currentEvent.event; if (!currentEvent) return null;
},
eventClass () { const zone = moment.tz.guess();
if (this.currentEvent && this.currentEvent.gemsPromo) {
return `event-${this.eventName}`; return {
} name: currentEvent.event,
return ''; class: currentEvent.gemsPromo ? `event-${currentEvent.event}` : '',
}, gemsPromo: currentEvent.gemsPromo,
eventStartMonth () { promo: currentEvent.promo,
return moment(this.currentEvent.start).format('MMMM'); startMonth: moment(currentEvent.start).format('MMMM'),
}, startOrdinal: moment(currentEvent.start).format('Do'),
eventStartOrdinal () { startTime: moment.tz(currentEvent.start, zone).format('hh:mm A z'),
return moment(this.currentEvent.start).format('Do'); startUTC: moment(currentEvent.start).utc().format('hh:mm A'),
}, endMonth: moment(currentEvent.end).format('MMMM'),
eventEndMonth () { endOrdinal: moment(currentEvent.end).format('Do'),
return moment(this.currentEvent.end).format('MMMM'); endTime: moment.tz(currentEvent.end, zone).format('hh:mm A z'),
}, endUTC: moment(currentEvent.end).utc().format('hh:mm A'),
eventEndOrdinal () { };
return moment(this.currentEvent.end).format('Do');
}, },
isGemsPromoActive () { isGemsPromoActive () {
const currEvt = this.currentEvent; return Boolean(this.eventInfo);
if (currEvt && currEvt.gemsPromo && moment().isBefore(currEvt.end)) {
return true;
}
return false;
}, },
gemsBlocks () { gemsBlocks () {
// We don't want to modify the original gems blocks when a promotion is running // We don't want to modify the original gems blocks when a promotion is running
@@ -476,7 +478,7 @@ export default {
if (this.isGemsPromoActive) { if (this.isGemsPromoActive) {
newBlock.originalGems = originalBlock.gems; newBlock.originalGems = originalBlock.gems;
newBlock.gems = ( newBlock.gems = (
this.currentEvent.gemsPromo[gemsBlockKey] || originalBlock.gems this.eventInfo.gemsPromo[gemsBlockKey] || originalBlock.gems
); );
} }
}); });

View File

@@ -238,7 +238,7 @@
"g1g1Limitations": "This is a limited time event that starts on <%= promoStartMonth %> <%= promoStartOrdinal %> at <%= promoStartTime %> and will end <%= promoEndMonth %> <%= promoEndOrdinal %> at <%= promoEndTime %>. This promotion only applies when you gift to another Habitican. If you or your gift recipient already have a subscription, the gifted subscription will add months of credit that will only be used after the current subscription is canceled or expires.", "g1g1Limitations": "This is a limited time event that starts on <%= promoStartMonth %> <%= promoStartOrdinal %> at <%= promoStartTime %> and will end <%= promoEndMonth %> <%= promoEndOrdinal %> at <%= promoEndTime %>. This promotion only applies when you gift to another Habitican. If you or your gift recipient already have a subscription, the gifted subscription will add months of credit that will only be used after the current subscription is canceled or expires.",
"noLongerAvailable": "This item is no longer available.", "noLongerAvailable": "This item is no longer available.",
"gemSaleHow": "Between <%= eventStartMonth %> <%= eventStartOrdinal %> and <%= eventEndOrdinal %>, simply purchase any Gem bundle like usual and your account will be credited with the promotional amount of Gems. More Gems to spend, share, or save for any future releases!", "gemSaleHow": "Between <%= eventStartMonth %> <%= eventStartOrdinal %> and <%= eventEndOrdinal %>, simply purchase any Gem bundle like usual and your account will be credited with the promotional amount of Gems. More Gems to spend, share, or save for any future releases!",
"gemSaleLimitations": "This promotion only applies during the limited time event. This event starts on <%= eventStartMonth %> <%= eventStartOrdinal %> at 8:00 AM EDT (12:00 UTC) and will end <%= eventEndMonth %> <%= eventEndOrdinal %> at 8:00 PM EDT (00:00 UTC). The promo offer is only available when buying Gems for yourself.", "gemSaleLimitationsText": "This promotion only applies during the limited time event. This event starts on <%= eventStartMonth %> <%= eventStartOrdinal %> at <%= eventStartTime %> (<%= eventStartUTC %> UTC) and will end <%= eventEndMonth %> <%= eventEndOrdinal %> at <%= eventEndTime %> (<%= eventEndUTC %> UTC) . The promo offer is only available when buying Gems for yourself.",
"anniversaryLimitations": "This is a limited time event that starts on January 30th at 8:00 AM ET (13:00 UTC) and will end February 8th at 11:59 PM ET (04:59 UTC). The Limited Edition Jubilant Gryphatrice and ten Magic Hatching Potions will be available to buy during this time. The other Gifts listed in the Four for Free section will be automatically delivered to all accounts that were active in the 30 days prior to day the gift is sent. Accounts created after the gifts are sent will not be able to claim them.", "anniversaryLimitations": "This is a limited time event that starts on January 30th at 8:00 AM ET (13:00 UTC) and will end February 8th at 11:59 PM ET (04:59 UTC). The Limited Edition Jubilant Gryphatrice and ten Magic Hatching Potions will be available to buy during this time. The other Gifts listed in the Four for Free section will be automatically delivered to all accounts that were active in the 30 days prior to day the gift is sent. Accounts created after the gifts are sent will not be able to claim them.",
"anniversaryLimitedDates": "January 30th to February 8th", "anniversaryLimitedDates": "January 30th to February 8th",
"limitedEvent": "Limited Event", "limitedEvent": "Limited Event",

View File

@@ -83,6 +83,16 @@ export const REPEATING_EVENTS = {
season: 'habitoween', season: 'habitoween',
npcImageSuffix: '_halloween', npcImageSuffix: '_halloween',
}, },
fallGemSale: {
start: new Date('1970-09-23T04:00-04:00'),
end: new Date('1970-09-27T23:59-04:00'),
event: 'fall_extra_gems',
},
spookyGemSale: {
start: new Date('1970-10-28T04:00-04:00'),
end: new Date('1970-11-01T23:59-04:00'),
event: 'spooky_extra_gems',
},
harvestFeast: { harvestFeast: {
start: new Date('1970-11-22T08:00-05:00'), start: new Date('1970-11-22T08:00-05:00'),
end: new Date('1970-11-27T20:00-05:00'), end: new Date('1970-11-27T20:00-05:00'),
@@ -186,11 +196,6 @@ export const EVENTS = {
start: '2023-11-09T08:00-04:00', start: '2023-11-09T08:00-04:00',
end: '2023-11-30T23:59-04:00', end: '2023-11-30T23:59-04:00',
}, },
spooky_extra_gems: {
start: '2023-10-24T08:00-04:00',
end: '2023-10-31T23:59-04:00',
gemsPromo,
},
bundle202310: { bundle202310: {
start: '2023-10-17T08:00-04:00', start: '2023-10-17T08:00-04:00',
end: '2023-10-31T23:59-04:00', end: '2023-10-31T23:59-04:00',
@@ -308,11 +313,6 @@ export const EVENTS = {
season: 'fall', season: 'fall',
gear: true, gear: true,
}, },
fall_extra_gems: {
start: '2022-10-06T08:00-04:00',
end: '2022-10-13T20:00-04:00',
gemsPromo,
},
bundle202210: { bundle202210: {
start: '2022-10-13T08:00-04:00', start: '2022-10-13T08:00-04:00',
end: '2022-10-31T20:00-04:00', end: '2022-10-31T20:00-04:00',