From 3f80b5ea637176d37a70725c361c8f7fa5bc9c27 Mon Sep 17 00:00:00 2001 From: "Ean Milligan (Bastion)" Date: Sat, 29 Apr 2023 01:29:53 -0400 Subject: [PATCH] Prevent event from being created in the past (or edited to be in the past) --- src/buttons/event-creation/dateTimeUtils.ts | 6 ++- src/buttons/event-creation/step2-finalize.ts | 4 +- src/buttons/event-creation/utils.ts | 57 +++++++++++--------- src/buttons/live-event/applyDateTime.ts | 22 +++++++- 4 files changed, 57 insertions(+), 32 deletions(-) diff --git a/src/buttons/event-creation/dateTimeUtils.ts b/src/buttons/event-creation/dateTimeUtils.ts index b409f66..4d37648 100644 --- a/src/buttons/event-creation/dateTimeUtils.ts +++ b/src/buttons/event-creation/dateTimeUtils.ts @@ -154,7 +154,7 @@ const parseEventDate = (preParsedEventDate: string): [string, string, string] => }; // Take full raw Date/Time input and convert it to a proper Date -export const getDateFromRawInput = (rawEventTime: string, rawEventTimeZone: string, rawEventDate: string): [Date, string] => { +export const getDateFromRawInput = (rawEventTime: string, rawEventTimeZone: string, rawEventDate: string): [Date, string, boolean] => { // Verify/Set Time const [parsedEventTimeHours, parsedEventTimeMinutes, parsedEventTimePeriod] = parseEventTime(rawEventTime.replaceAll(':', '').toUpperCase()); @@ -164,10 +164,12 @@ export const getDateFromRawInput = (rawEventTime: string, rawEventTimeZone: stri // Verify/Set Date const [parsedEventYear, parsedEventMonth, parsedEventDay] = parseEventDate(rawEventDate.trim().toUpperCase()); + const parsedDateTime = new Date(`${parsedEventMonth} ${parsedEventDay}, ${parsedEventYear} ${parsedEventTimeHours}:${parsedEventTimeMinutes} ${parsedEventTimePeriod} ${parsedEventTimeZone}`); return [ - new Date(`${parsedEventMonth} ${parsedEventDay}, ${parsedEventYear} ${parsedEventTimeHours}:${parsedEventTimeMinutes} ${parsedEventTimePeriod} ${parsedEventTimeZone}`), + parsedDateTime, `${parsedEventTimeHours}${parsedEventTimePeriod ? ':' : ''}${parsedEventTimeMinutes} ${parsedEventTimePeriod} ${userInputTimeZone} ${parsedEventMonth.slice(0, 1)}${ parsedEventMonth.slice(1, 3).toLowerCase() } ${parsedEventDay}, ${parsedEventYear}`, + parsedDateTime.getTime() > new Date().getTime(), ]; }; diff --git a/src/buttons/event-creation/step2-finalize.ts b/src/buttons/event-creation/step2-finalize.ts index e7bf63c..33dd781 100644 --- a/src/buttons/event-creation/step2-finalize.ts +++ b/src/buttons/event-creation/step2-finalize.ts @@ -53,7 +53,7 @@ const execute = async (bot: Bot, interaction: Interaction) => { } // Get Date Object from user input - const [eventDateTime, eventDateTimeStr] = getDateFromRawInput(rawEventTime, rawEventTimeZone, rawEventDate); // TODO: verify dt + const [eventDateTime, eventDateTimeStr, eventInFuture] = getDateFromRawInput(rawEventTime, rawEventTimeZone, rawEventDate); // TODO: verify dt addTokenToMap(bot, interaction, interaction.guildId, interaction.channelId, interaction.member.id); bot.helpers.sendInteractionResponse( @@ -73,7 +73,7 @@ const execute = async (bot: Bot, interaction: Interaction) => { }], [], customIdIdxPath, - true, + eventInFuture, ), ).catch((e: Error) => utils.commonLoggers.interactionSendError('step2-finalize.ts', interaction, e)); } else { diff --git a/src/buttons/event-creation/utils.ts b/src/buttons/event-creation/utils.ts index c3a66cc..43c71a6 100644 --- a/src/buttons/event-creation/utils.ts +++ b/src/buttons/event-creation/utils.ts @@ -15,7 +15,7 @@ import { requestToJoinEventBtnStr, } from '../eventUtils.ts'; import { selfDestructMessage } from '../tokenCleanup.ts'; -import { successColor } from '../../commandUtils.ts'; +import { successColor, warnColor } from '../../commandUtils.ts'; import { LFGMember } from '../../types/commandTypes.ts'; import { customId as gameSelCustomId } from './step1-gameSelection.ts'; import { customId as createEventCustomId } from './step3-createEvent.ts'; @@ -56,22 +56,29 @@ export const generateActionRow = (baseValue: string, activities: Array const createEventBtnName = 'Create Event'; const createWhitelistedBtnName = 'Create Whitelisted Event'; const editEventDetailsBtnName = 'Edit Event Details'; -const finalizeButtons = (idxPath: string): [ButtonComponent, ButtonComponent, ButtonComponent] => [{ - type: MessageComponentTypes.Button, - label: createEventBtnName, - style: ButtonStyles.Success, - customId: createEventCustomId, -}, { - type: MessageComponentTypes.Button, - label: createWhitelistedBtnName, - style: ButtonStyles.Primary, - customId: `${createEventCustomId}${idSeparator}`, -}, { - type: MessageComponentTypes.Button, - label: editEventDetailsBtnName, - style: ButtonStyles.Secondary, - customId: `${gameSelCustomId}${idSeparator}${idxPath}${pathIdxEnder}`, -}]; +const finalizeButtons = (idxPath: string, eventInFuture: boolean): [ButtonComponent, ButtonComponent, ButtonComponent] | [ButtonComponent] => { + const editButton: ButtonComponent = { + type: MessageComponentTypes.Button, + label: editEventDetailsBtnName, + style: ButtonStyles.Secondary, + customId: `${gameSelCustomId}${idSeparator}${idxPath}${pathIdxEnder}`, + }; + if (eventInFuture) { + return [{ + type: MessageComponentTypes.Button, + label: createEventBtnName, + style: ButtonStyles.Success, + customId: createEventCustomId, + }, { + type: MessageComponentTypes.Button, + label: createWhitelistedBtnName, + style: ButtonStyles.Primary, + customId: `${createEventCustomId}${idSeparator}`, + }, editButton]; + } else { + return [editButton]; + } +}; export const generateLFGButtons = (whitelist: boolean): [ButtonComponent, ButtonComponent, ButtonComponent, ButtonComponent, ButtonComponent] => [{ type: MessageComponentTypes.Button, @@ -119,21 +126,19 @@ export const createLFGPost = ( memberList: Array, alternateList: Array, idxPath: string, - editing: boolean, - whitelist = false, + eventInFuture: boolean, ): InteractionResponse => { const icsDetails = `${category}: ${activity.name}`; return { type: InteractionResponseTypes.ChannelMessageWithSource, data: { - flags: editing ? ApplicationCommandFlags.Ephemeral : undefined, - content: editing - ? `Please 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()) + flags: ApplicationCommandFlags.Ephemeral, + content: eventInFuture + ? `Please 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()) }` - : '', + : `You cannot create an event in the past. Please change the event's \`Date/Time\` to be in the future with the \`${editEventDetailsBtnName}\` button below.`, embeds: [{ - color: successColor, + color: eventInFuture ? successColor : warnColor, fields: [{ name: `${category}:`, value: activity.name, @@ -166,7 +171,7 @@ export const createLFGPost = ( }], components: [{ type: MessageComponentTypes.ActionRow, - components: editing ? finalizeButtons(idxPath) : generateLFGButtons(whitelist), + components: finalizeButtons(idxPath, eventInFuture), }], }, }; diff --git a/src/buttons/live-event/applyDateTime.ts b/src/buttons/live-event/applyDateTime.ts index 11cf1e6..8d866ad 100644 --- a/src/buttons/live-event/applyDateTime.ts +++ b/src/buttons/live-event/applyDateTime.ts @@ -1,5 +1,5 @@ import { ApplicationCommandFlags, Bot, Interaction, InteractionResponseTypes } from '../../../deps.ts'; -import { somethingWentWrong } from '../../commandUtils.ts'; +import { somethingWentWrong, warnColor } from '../../commandUtils.ts'; import { eventDateId, eventTimeId, eventTimeZoneId, idSeparator, LfgEmbedIndexes, pathIdxEnder, pathIdxSeparator } from '../eventUtils.ts'; import { addTokenToMap } from '../tokenCleanup.ts'; import utils from '../../utils.ts'; @@ -32,7 +32,25 @@ const execute = async (bot: Bot, interaction: Interaction) => { } // Get Date Object from user input - const [eventDateTime, eventDateTimeStr] = getDateFromRawInput(newTime, newTimeZone, newDate); // TODO: verify dt + const [eventDateTime, eventDateTimeStr, eventInFuture] = getDateFromRawInput(newTime, newTimeZone, newDate); // TODO: verify dt + if (!eventInFuture) { + bot.helpers.sendInteractionResponse(interaction.id, interaction.token, { + type: InteractionResponseTypes.ChannelMessageWithSource, + data: { + flags: ApplicationCommandFlags.Ephemeral, + embeds: [{ + color: warnColor, + title: 'You cannot create an event in the past.', + description: 'Please dismiss this message and try again with a date in the future', + fields: [{ + name: 'Date/Time Entered:', + value: generateTimeFieldStr(eventDateTimeStr, eventDateTime), + }], + }], + }, + }).catch((e: Error) => utils.commonLoggers.interactionSendError('applyDateTime.ts', interaction, e)); + return; + } if (eventMessage && eventMessage.embeds[0].fields) { // eventMessage.embeds[0].fields[LfgEmbedIndexes.Description].value = newDescription || noDescProvided;