Add Hawaii and Alaska time zones to US list, add warning for when user possibly doesn't know the difference between XDT and XST.

This commit is contained in:
Ean Milligan 2024-05-21 03:08:36 -04:00
parent 05ac1a79dd
commit 123aaa89a0
5 changed files with 36 additions and 11 deletions

View File

@ -1,3 +1,6 @@
import config from '../../../config.ts';
import {editEventDetailsBtnName} from './utils.ts';
const monthsLong: Array<string> = ['JANUARY', 'FEBRUARY', 'MARCH', 'APRIL', 'MAY', 'JUNE', 'JULY', 'AUGUST', 'SEPTEMBER', 'OCTOBER', 'NOVEMBER', 'DECEMBER']; const monthsLong: Array<string> = ['JANUARY', 'FEBRUARY', 'MARCH', 'APRIL', 'MAY', 'JUNE', 'JULY', 'AUGUST', 'SEPTEMBER', 'OCTOBER', 'NOVEMBER', 'DECEMBER'];
export const monthsShort: Array<string> = monthsLong.map((month) => month.slice(0, 3)); export const monthsShort: Array<string> = monthsLong.map((month) => month.slice(0, 3));
const tzMap: Map<string, string> = new Map([ const tzMap: Map<string, string> = new Map([
@ -52,7 +55,8 @@ const tzMap: Map<string, string> = new Map([
['CHST', '+10:00'], ['CHST', '+10:00'],
['SST', '-11:00'], ['SST', '-11:00'],
]); ]);
const shorthandUSTZ: Array<string> = ['ET', 'CT', 'MT', 'PT']; const shorthandUSTZ: Array<string> = ['ET', 'CT', 'MT', 'PT', 'HT', 'AKT'];
const allUSTZ: Array<string> = ['EST', 'CST', 'MST', 'PST', 'HST', 'AKST', 'EDT', 'CDT', 'MDT', 'PDT', 'HDT', 'AKDT'];
// Takes user input Time and makes it actually usable // Takes user input Time and makes it actually usable
const parseEventTime = (preParsedEventTime: string): [string, string, string] => { const parseEventTime = (preParsedEventTime: string): [string, string, string] => {
@ -93,14 +97,31 @@ export const isDSTActive = (): boolean => {
return today.getTimezoneOffset() < Math.max(jan.getTimezoneOffset(), jul.getTimezoneOffset()); return today.getTimezoneOffset() < Math.max(jan.getTimezoneOffset(), jul.getTimezoneOffset());
}; };
const editButtonMessage = `click \`${editEventDetailsBtnName}\` and change`;
const warningText = (incorrectTZ: string, correctTZ: string, newEvent: boolean) =>
`⚠️⚠️⚠️ WARNING! Did you mean to enter \`${incorrectTZ}\` for the time zone? ⚠️⚠️⚠️\nCurrently (as of the posting of this message), Daylight Savings Time is ${isDSTActive() ? '' : 'not '}active in most of the United States. If DST is ${
isDSTActive() ? '' : 'not '
}in effect for you (and will be when this event is scheduled to happen), ${newEvent ? editButtonMessage : 'please dismiss this message and start over, using'} the time zone ${newEvent ? 'to ' : ''}\`${correctTZ}\`, or shorten it to \`${correctTZ.slice(0, -2)}T\` to let ${config.name} automatically use the correct time zone.\n\n`;
const usTZDSTCheck = (timeZone: string, newEvent: boolean): string => {
if (allUSTZ.includes(timeZone)) {
if (isDSTActive() && timeZone.endsWith('ST')) {
return warningText(timeZone, `${timeZone.slice(0, -2)}DT`, newEvent);
} else if (!isDSTActive() && timeZone.endsWith('DT')) {
return warningText(timeZone, `${timeZone.slice(0, -2)}ST`, newEvent);
}
}
return '';
};
// Takes user input Time Zone and makes it actually usable // Takes user input Time Zone and makes it actually usable
const parseEventTimeZone = (preParsedEventTimeZone: string): [string, string] => { const parseEventTimeZone = (preParsedEventTimeZone: string): [string, string] => {
if (shorthandUSTZ.includes(preParsedEventTimeZone)) { if (shorthandUSTZ.includes(preParsedEventTimeZone)) {
// Handle shorthand US timezones, adding S for standard time and D for Daylight Savings // Handle shorthand US timezones, adding S for standard time and D for Daylight Savings
if (isDSTActive()) { if (isDSTActive()) {
preParsedEventTimeZone = `${preParsedEventTimeZone.slice(0, 1)}DT`; preParsedEventTimeZone = `${preParsedEventTimeZone.slice(0, -1)}DT`;
} else { } else {
preParsedEventTimeZone = `${preParsedEventTimeZone.slice(0, 1)}ST`; preParsedEventTimeZone = `${preParsedEventTimeZone.slice(0, -1)}ST`;
} }
} }
if (tzMap.has(preParsedEventTimeZone)) { if (tzMap.has(preParsedEventTimeZone)) {
@ -154,12 +175,13 @@ const parseEventDate = (preParsedEventDate: string): [string, string, string] =>
}; };
// Take full raw Date/Time input and convert it to a proper Date // Take full raw Date/Time input and convert it to a proper Date
export const getDateFromRawInput = (rawEventTime: string, rawEventTimeZone: string, rawEventDate: string): [Date, string, boolean, boolean] => { export const getDateFromRawInput = (rawEventTime: string, rawEventTimeZone: string, rawEventDate: string, newEvent: boolean): [Date, string, boolean, boolean, string] => {
// Verify/Set Time // Verify/Set Time
const [parsedEventTimeHours, parsedEventTimeMinutes, parsedEventTimePeriod] = parseEventTime(rawEventTime.replaceAll(':', '').toUpperCase()); const [parsedEventTimeHours, parsedEventTimeMinutes, parsedEventTimePeriod] = parseEventTime(rawEventTime.replaceAll(':', '').toUpperCase());
// Verify/Set Time Zone // Verify/Set Time Zone
const [parsedEventTimeZone, userInputTimeZone] = parseEventTimeZone(rawEventTimeZone.replaceAll(' ', '').trim().toUpperCase()); const [parsedEventTimeZone, userInputTimeZone] = parseEventTimeZone(rawEventTimeZone.replaceAll(' ', '').trim().toUpperCase());
const usTZWarning = usTZDSTCheck(userInputTimeZone, newEvent);
// Verify/Set Date // Verify/Set Date
const [parsedEventYear, parsedEventMonth, parsedEventDay] = parseEventDate(rawEventDate.trim().toUpperCase()); const [parsedEventYear, parsedEventMonth, parsedEventDay] = parseEventDate(rawEventDate.trim().toUpperCase());
@ -172,5 +194,6 @@ export const getDateFromRawInput = (rawEventTime: string, rawEventTimeZone: stri
} ${parsedEventDay}, ${parsedEventYear}`, } ${parsedEventDay}, ${parsedEventYear}`,
parsedDateTime.getTime() > new Date().getTime(), parsedDateTime.getTime() > new Date().getTime(),
!isNaN(parsedDateTime.getTime()), !isNaN(parsedDateTime.getTime()),
usTZWarning
]; ];
}; };

View File

@ -67,7 +67,7 @@ const execute = async (bot: Bot, interaction: Interaction) => {
} }
// Get Date Object from user input // Get Date Object from user input
const [eventDateTime, eventDateTimeStr, eventInFuture, dateTimeValid] = getDateFromRawInput(rawEventTime, rawEventTimeZone, rawEventDate); const [eventDateTime, eventDateTimeStr, eventInFuture, dateTimeValid, usTZWarning] = getDateFromRawInput(rawEventTime, rawEventTimeZone, rawEventDate, true);
addTokenToMap(bot, interaction, interaction.guildId, interaction.channelId, interaction.member.id); addTokenToMap(bot, interaction, interaction.guildId, interaction.channelId, interaction.member.id);
bot.helpers.sendInteractionResponse( bot.helpers.sendInteractionResponse(
@ -89,6 +89,7 @@ const execute = async (bot: Bot, interaction: Interaction) => {
customIdIdxPath, customIdIdxPath,
eventInFuture, eventInFuture,
dateTimeValid, dateTimeValid,
usTZWarning,
), ),
).catch((e: Error) => utils.commonLoggers.interactionSendError('step2-finalize.ts', interaction, e)); ).catch((e: Error) => utils.commonLoggers.interactionSendError('step2-finalize.ts', interaction, e));
} else { } else {

View File

@ -55,7 +55,7 @@ export const generateActionRow = (baseValue: string, activities: Array<Activity>
const createEventBtnName = 'Create Event'; const createEventBtnName = 'Create Event';
const createWhitelistedBtnName = 'Create Whitelisted Event'; const createWhitelistedBtnName = 'Create Whitelisted Event';
const editEventDetailsBtnName = 'Edit Event Details'; export const editEventDetailsBtnName = 'Edit Event Details';
export const invalidDateTimeStr = '`Invalid Date/Time`'; export const invalidDateTimeStr = '`Invalid Date/Time`';
const finalizeButtons = (idxPath: string, eventInFuture: boolean): [ButtonComponent, ButtonComponent, ButtonComponent] | [ButtonComponent] => { const finalizeButtons = (idxPath: string, eventInFuture: boolean): [ButtonComponent, ButtonComponent, ButtonComponent] | [ButtonComponent] => {
const editButton: ButtonComponent = { const editButton: ButtonComponent = {
@ -129,6 +129,7 @@ export const createLFGPost = (
idxPath: string, idxPath: string,
eventInFuture: boolean, eventInFuture: boolean,
dateTimeValid: boolean, dateTimeValid: boolean,
usTZWarning: string,
): InteractionResponse => { ): InteractionResponse => {
const icsDetails = `${category}: ${activity.name}`; const icsDetails = `${category}: ${activity.name}`;
const dateTimePastFutureStr = dateTimeValid ? 'in the past' : 'with an invalid date/time'; const dateTimePastFutureStr = dateTimeValid ? 'in the past' : 'with an invalid date/time';
@ -138,7 +139,7 @@ export const createLFGPost = (
data: { data: {
flags: ApplicationCommandFlags.Ephemeral, flags: ApplicationCommandFlags.Ephemeral,
content: eventInFuture content: eventInFuture
? `🛑🛑🛑 HEY! ONE MORE THING! 🛑🛑🛑\n\nPlease verify the information below, then click on the \`${createEventBtnName}\` or \`${createWhitelistedBtnName}\` button, or change the event \`Date/Time\` or \`Description\` with the \`${editEventDetailsBtnName}\` button below. \n\n${ ? `${usTZWarning}🛑🛑🛑 HEY! ONE MORE THING! 🛑🛑🛑\n\nPlease verify the information below, then click on the \`${createEventBtnName}\` or \`${createWhitelistedBtnName}\` button, or change the event \`Date/Time\` or \`Description\` with the \`${editEventDetailsBtnName}\` button below. \n\n${
selfDestructMessage(new Date().getTime()) selfDestructMessage(new Date().getTime())
}` }`
: `You cannot create an event ${dateTimePastFutureStr}. Please change the event's \`Date/Time\` to be ${dateTimeValidStr} with the \`${editEventDetailsBtnName}\` button below.`, : `You cannot create an event ${dateTimePastFutureStr}. Please change the event's \`Date/Time\` to be ${dateTimeValidStr} with the \`${editEventDetailsBtnName}\` button below.`,

View File

@ -33,7 +33,7 @@ const execute = async (bot: Bot, interaction: Interaction) => {
} }
// Get Date Object from user input // Get Date Object from user input
const [eventDateTime, eventDateTimeStr, eventInFuture, dateTimeValid] = getDateFromRawInput(newTime, newTimeZone, newDate); const [eventDateTime, eventDateTimeStr, eventInFuture, dateTimeValid, usTZWarning] = getDateFromRawInput(newTime, newTimeZone, newDate, false);
if (!eventInFuture || !dateTimeValid) { if (!eventInFuture || !dateTimeValid) {
bot.helpers.sendInteractionResponse(interaction.id, interaction.token, { bot.helpers.sendInteractionResponse(interaction.id, interaction.token, {
type: InteractionResponseTypes.ChannelMessageWithSource, type: InteractionResponseTypes.ChannelMessageWithSource,
@ -70,7 +70,7 @@ const execute = async (bot: Bot, interaction: Interaction) => {
type: InteractionResponseTypes.ChannelMessageWithSource, type: InteractionResponseTypes.ChannelMessageWithSource,
data: { data: {
flags: ApplicationCommandFlags.Ephemeral, flags: ApplicationCommandFlags.Ephemeral,
content: applyEditMessage(new Date().getTime()), content: applyEditMessage(new Date().getTime(), usTZWarning),
embeds: [eventMessage.embeds[0]], embeds: [eventMessage.embeds[0]],
components: applyEditButtons(interaction.data.customId.split(idSeparator)[1] || ''), components: applyEditButtons(interaction.data.customId.split(idSeparator)[1] || ''),
}, },

View File

@ -353,8 +353,8 @@ export const joinRequestResponseButtons = (disabled: boolean): ActionRow[] => [{
}]; }];
export const applyEditButtonName = 'Apply Edit'; export const applyEditButtonName = 'Apply Edit';
export const applyEditMessage = (currentTime: number) => export const applyEditMessage = (currentTime: number, usTZWarning: string) =>
`Please verify the updated event below, then click on the \`${applyEditButtonName}\` button. If this does not look right, please dismiss this message and start over.\n\n${ `${usTZWarning}Please verify the updated event below, then click on the \`${applyEditButtonName}\` button. If this does not look right, please dismiss this message and start over.\n\n${
selfDestructMessage(currentTime) selfDestructMessage(currentTime)
}`; }`;
export const applyEditButtons = (idxPath: string): ActionRow[] => [{ export const applyEditButtons = (idxPath: string): ActionRow[] => [{