Prevent event from being created in the past (or edited to be in the past)

This commit is contained in:
Ean Milligan (Bastion) 2023-04-29 01:29:53 -04:00
parent 6f0b69e8f2
commit 3f80b5ea63
4 changed files with 57 additions and 32 deletions

View File

@ -154,7 +154,7 @@ 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] => { export const getDateFromRawInput = (rawEventTime: string, rawEventTimeZone: string, rawEventDate: string): [Date, string, boolean] => {
// Verify/Set Time // Verify/Set Time
const [parsedEventTimeHours, parsedEventTimeMinutes, parsedEventTimePeriod] = parseEventTime(rawEventTime.replaceAll(':', '').toUpperCase()); const [parsedEventTimeHours, parsedEventTimeMinutes, parsedEventTimePeriod] = parseEventTime(rawEventTime.replaceAll(':', '').toUpperCase());
@ -164,10 +164,12 @@ export const getDateFromRawInput = (rawEventTime: string, rawEventTimeZone: stri
// Verify/Set Date // Verify/Set Date
const [parsedEventYear, parsedEventMonth, parsedEventDay] = parseEventDate(rawEventDate.trim().toUpperCase()); const [parsedEventYear, parsedEventMonth, parsedEventDay] = parseEventDate(rawEventDate.trim().toUpperCase());
const parsedDateTime = new Date(`${parsedEventMonth} ${parsedEventDay}, ${parsedEventYear} ${parsedEventTimeHours}:${parsedEventTimeMinutes} ${parsedEventTimePeriod} ${parsedEventTimeZone}`);
return [ return [
new Date(`${parsedEventMonth} ${parsedEventDay}, ${parsedEventYear} ${parsedEventTimeHours}:${parsedEventTimeMinutes} ${parsedEventTimePeriod} ${parsedEventTimeZone}`), parsedDateTime,
`${parsedEventTimeHours}${parsedEventTimePeriod ? ':' : ''}${parsedEventTimeMinutes} ${parsedEventTimePeriod} ${userInputTimeZone} ${parsedEventMonth.slice(0, 1)}${ `${parsedEventTimeHours}${parsedEventTimePeriod ? ':' : ''}${parsedEventTimeMinutes} ${parsedEventTimePeriod} ${userInputTimeZone} ${parsedEventMonth.slice(0, 1)}${
parsedEventMonth.slice(1, 3).toLowerCase() parsedEventMonth.slice(1, 3).toLowerCase()
} ${parsedEventDay}, ${parsedEventYear}`, } ${parsedEventDay}, ${parsedEventYear}`,
parsedDateTime.getTime() > new Date().getTime(),
]; ];
}; };

View File

@ -53,7 +53,7 @@ const execute = async (bot: Bot, interaction: Interaction) => {
} }
// Get Date Object from user input // 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); addTokenToMap(bot, interaction, interaction.guildId, interaction.channelId, interaction.member.id);
bot.helpers.sendInteractionResponse( bot.helpers.sendInteractionResponse(
@ -73,7 +73,7 @@ const execute = async (bot: Bot, interaction: Interaction) => {
}], }],
[], [],
customIdIdxPath, customIdIdxPath,
true, eventInFuture,
), ),
).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

@ -15,7 +15,7 @@ import {
requestToJoinEventBtnStr, requestToJoinEventBtnStr,
} from '../eventUtils.ts'; } from '../eventUtils.ts';
import { selfDestructMessage } from '../tokenCleanup.ts'; import { selfDestructMessage } from '../tokenCleanup.ts';
import { successColor } from '../../commandUtils.ts'; import { successColor, warnColor } from '../../commandUtils.ts';
import { LFGMember } from '../../types/commandTypes.ts'; import { LFGMember } from '../../types/commandTypes.ts';
import { customId as gameSelCustomId } from './step1-gameSelection.ts'; import { customId as gameSelCustomId } from './step1-gameSelection.ts';
import { customId as createEventCustomId } from './step3-createEvent.ts'; import { customId as createEventCustomId } from './step3-createEvent.ts';
@ -56,22 +56,29 @@ 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'; const editEventDetailsBtnName = 'Edit Event Details';
const finalizeButtons = (idxPath: string): [ButtonComponent, ButtonComponent, ButtonComponent] => [{ const finalizeButtons = (idxPath: string, eventInFuture: boolean): [ButtonComponent, ButtonComponent, ButtonComponent] | [ButtonComponent] => {
type: MessageComponentTypes.Button, const editButton: ButtonComponent = {
label: createEventBtnName,
style: ButtonStyles.Success,
customId: createEventCustomId,
}, {
type: MessageComponentTypes.Button,
label: createWhitelistedBtnName,
style: ButtonStyles.Primary,
customId: `${createEventCustomId}${idSeparator}`,
}, {
type: MessageComponentTypes.Button, type: MessageComponentTypes.Button,
label: editEventDetailsBtnName, label: editEventDetailsBtnName,
style: ButtonStyles.Secondary, style: ButtonStyles.Secondary,
customId: `${gameSelCustomId}${idSeparator}${idxPath}${pathIdxEnder}`, 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] => [{ export const generateLFGButtons = (whitelist: boolean): [ButtonComponent, ButtonComponent, ButtonComponent, ButtonComponent, ButtonComponent] => [{
type: MessageComponentTypes.Button, type: MessageComponentTypes.Button,
@ -119,21 +126,19 @@ export const createLFGPost = (
memberList: Array<LFGMember>, memberList: Array<LFGMember>,
alternateList: Array<LFGMember>, alternateList: Array<LFGMember>,
idxPath: string, idxPath: string,
editing: boolean, eventInFuture: boolean,
whitelist = false,
): InteractionResponse => { ): InteractionResponse => {
const icsDetails = `${category}: ${activity.name}`; const icsDetails = `${category}: ${activity.name}`;
return { return {
type: InteractionResponseTypes.ChannelMessageWithSource, type: InteractionResponseTypes.ChannelMessageWithSource,
data: { data: {
flags: editing ? ApplicationCommandFlags.Ephemeral : undefined, flags: ApplicationCommandFlags.Ephemeral,
content: editing 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${ ? `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())
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: [{ embeds: [{
color: successColor, color: eventInFuture ? successColor : warnColor,
fields: [{ fields: [{
name: `${category}:`, name: `${category}:`,
value: activity.name, value: activity.name,
@ -166,7 +171,7 @@ export const createLFGPost = (
}], }],
components: [{ components: [{
type: MessageComponentTypes.ActionRow, type: MessageComponentTypes.ActionRow,
components: editing ? finalizeButtons(idxPath) : generateLFGButtons(whitelist), components: finalizeButtons(idxPath, eventInFuture),
}], }],
}, },
}; };

View File

@ -1,5 +1,5 @@
import { ApplicationCommandFlags, Bot, Interaction, InteractionResponseTypes } from '../../../deps.ts'; 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 { eventDateId, eventTimeId, eventTimeZoneId, idSeparator, LfgEmbedIndexes, pathIdxEnder, pathIdxSeparator } from '../eventUtils.ts';
import { addTokenToMap } from '../tokenCleanup.ts'; import { addTokenToMap } from '../tokenCleanup.ts';
import utils from '../../utils.ts'; import utils from '../../utils.ts';
@ -32,7 +32,25 @@ const execute = async (bot: Bot, interaction: Interaction) => {
} }
// Get Date Object from user input // 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) { if (eventMessage && eventMessage.embeds[0].fields) {
// eventMessage.embeds[0].fields[LfgEmbedIndexes.Description].value = newDescription || noDescProvided; // eventMessage.embeds[0].fields[LfgEmbedIndexes.Description].value = newDescription || noDescProvided;