Join Request Responses added
Event owner can now approve or deny requests Made all event buttons common strings
This commit is contained in:
parent
7c999ed27b
commit
126689171d
|
@ -7,6 +7,7 @@ import { createEventButton } from './event-creation/step3-createEvent.ts';
|
||||||
import { joinEventButton } from './live-event/joinEvent.ts';
|
import { joinEventButton } from './live-event/joinEvent.ts';
|
||||||
import { leaveEventButton } from './live-event/leaveEvent.ts';
|
import { leaveEventButton } from './live-event/leaveEvent.ts';
|
||||||
import { alternateEventButton } from './live-event/alternateEvent.ts';
|
import { alternateEventButton } from './live-event/alternateEvent.ts';
|
||||||
|
import { joinRequestButton } from './live-event/joinRequest.ts';
|
||||||
|
|
||||||
export const buttons: Array<Button> = [
|
export const buttons: Array<Button> = [
|
||||||
gameSelectionButton,
|
gameSelectionButton,
|
||||||
|
@ -17,4 +18,5 @@ export const buttons: Array<Button> = [
|
||||||
joinEventButton,
|
joinEventButton,
|
||||||
leaveEventButton,
|
leaveEventButton,
|
||||||
alternateEventButton,
|
alternateEventButton,
|
||||||
|
joinRequestButton,
|
||||||
];
|
];
|
||||||
|
|
|
@ -13,7 +13,17 @@ import {
|
||||||
import config from '../../../config.ts';
|
import config from '../../../config.ts';
|
||||||
import utils from '../../utils.ts';
|
import utils from '../../utils.ts';
|
||||||
import { Activity } from './activities.ts';
|
import { Activity } from './activities.ts';
|
||||||
import { generateAlternateList, generateMemberList, generateMemberTitle, idSeparator, leaveEventBtnStr, lfgStartTimeName } from '../eventUtils.ts';
|
import {
|
||||||
|
alternateEventBtnStr,
|
||||||
|
generateAlternateList,
|
||||||
|
generateMemberList,
|
||||||
|
generateMemberTitle,
|
||||||
|
idSeparator,
|
||||||
|
joinEventBtnStr,
|
||||||
|
leaveEventBtnStr,
|
||||||
|
lfgStartTimeName,
|
||||||
|
requestToJoinEventBtnStr,
|
||||||
|
} from '../eventUtils.ts';
|
||||||
import { successColor } from '../../commandUtils.ts';
|
import { successColor } 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';
|
||||||
|
@ -112,7 +122,7 @@ const finalizeButtons = (idxPath: string): [ButtonComponent, ButtonComponent, Bu
|
||||||
|
|
||||||
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,
|
||||||
label: `${whitelist ? 'Request to ' : ''}Join`,
|
label: whitelist ? requestToJoinEventBtnStr : joinEventBtnStr,
|
||||||
style: ButtonStyles.Success,
|
style: ButtonStyles.Success,
|
||||||
customId: `${joinEventCustomId}${whitelist ? idSeparator : ''}`,
|
customId: `${joinEventCustomId}${whitelist ? idSeparator : ''}`,
|
||||||
}, {
|
}, {
|
||||||
|
@ -122,7 +132,7 @@ export const generateLFGButtons = (whitelist: boolean): [ButtonComponent, Button
|
||||||
customId: leaveEventCustomId,
|
customId: leaveEventCustomId,
|
||||||
}, {
|
}, {
|
||||||
type: MessageComponentTypes.Button,
|
type: MessageComponentTypes.Button,
|
||||||
label: `Join as Alternate`,
|
label: alternateEventBtnStr,
|
||||||
style: ButtonStyles.Primary,
|
style: ButtonStyles.Primary,
|
||||||
customId: alternateEventCustomId,
|
customId: alternateEventCustomId,
|
||||||
}, {
|
}, {
|
||||||
|
|
|
@ -15,6 +15,9 @@ export const lfgStartTimeName = 'Start Time:';
|
||||||
export const idSeparator = '@';
|
export const idSeparator = '@';
|
||||||
export const noMembersStr = 'None';
|
export const noMembersStr = 'None';
|
||||||
export const leaveEventBtnStr = 'Leave';
|
export const leaveEventBtnStr = 'Leave';
|
||||||
|
export const joinEventBtnStr = 'Join';
|
||||||
|
export const requestToJoinEventBtnStr = 'Request to Join';
|
||||||
|
export const alternateEventBtnStr = 'Join as Alternate';
|
||||||
|
|
||||||
// Member List generators
|
// Member List generators
|
||||||
export const generateMemberTitle = (memberList: Array<LFGMember>, maxMembers: number): string => `Members Joined: ${memberList.length}/${maxMembers}`;
|
export const generateMemberTitle = (memberList: Array<LFGMember>, maxMembers: number): string => `Members Joined: ${memberList.length}/${maxMembers}`;
|
||||||
|
|
|
@ -0,0 +1,83 @@
|
||||||
|
import { Bot, ButtonStyles, Interaction, InteractionResponseTypes, MessageComponentTypes } from '../../../deps.ts';
|
||||||
|
import { sendDirectMessage, somethingWentWrong, successColor, warnColor } from '../../commandUtils.ts';
|
||||||
|
import { generateMapId, getLfgMembers, joinMemberToEvent, joinRequestMap, joinRequestResponseButtons, JoinRequestStatus } from './utils.ts';
|
||||||
|
import { alternateEventBtnStr, idSeparator } from '../eventUtils.ts';
|
||||||
|
import utils from '../../utils.ts';
|
||||||
|
|
||||||
|
export const customId = 'joinRequest';
|
||||||
|
export const approveStr = 'approved';
|
||||||
|
export const denyStr = 'denied';
|
||||||
|
|
||||||
|
export const execute = async (bot: Bot, interaction: Interaction) => {
|
||||||
|
if (
|
||||||
|
interaction.data?.customId && interaction.user && interaction.channelId && interaction.message && interaction.message.embeds[0] && interaction.message.embeds[0].fields &&
|
||||||
|
interaction.message.embeds[0].description
|
||||||
|
) {
|
||||||
|
const memberRequesting = getLfgMembers(interaction.message.embeds[0].fields[0].value || '')[0];
|
||||||
|
const approved = interaction.data.customId.includes(approveStr);
|
||||||
|
const responseStr = interaction.data.customId.split(idSeparator)[1] || '';
|
||||||
|
const capResponseStr = `${responseStr.charAt(0).toUpperCase()}${responseStr.slice(1)}`;
|
||||||
|
const eventIds = utils.messageUrlToIds(interaction.message.embeds[0].description.split(')')[0] || '');
|
||||||
|
const eventUrl = utils.idsToMessageUrl(eventIds);
|
||||||
|
const joinRequestMapId = generateMapId(eventIds.messageId, eventIds.channelId, memberRequesting.id);
|
||||||
|
|
||||||
|
if (approved) {
|
||||||
|
// If member was approved, get the event and add them to it
|
||||||
|
const eventMessage = await bot.helpers.getMessage(eventIds.channelId, eventIds.messageId).catch((e: Error) => utils.commonLoggers.messageGetError('joinRequest.ts', 'get eventMessage', e));
|
||||||
|
if (eventMessage) {
|
||||||
|
joinMemberToEvent(bot, interaction, eventMessage.embeds[0], eventIds.messageId, eventIds.channelId, memberRequesting, eventIds.guildId);
|
||||||
|
} else {
|
||||||
|
somethingWentWrong(bot, interaction, 'eventMissingFromJoinRequestButton');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// If denied, send deferredUpdate so discord doesn't think we ignored the user (approved is handled in joinMemberToEvent)
|
||||||
|
bot.helpers.sendInteractionResponse(interaction.id, interaction.token, {
|
||||||
|
type: InteractionResponseTypes.DeferredUpdateMessage,
|
||||||
|
}).catch((e: Error) => utils.commonLoggers.interactionSendError('joinRequest.ts', interaction, e));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the JoinRequestMap
|
||||||
|
joinRequestMap.set(joinRequestMapId, {
|
||||||
|
status: approved ? JoinRequestStatus.Approved : JoinRequestStatus.Denied,
|
||||||
|
timestamp: new Date().getTime(),
|
||||||
|
});
|
||||||
|
|
||||||
|
// Send DM to the requesting member to let them know of the result
|
||||||
|
sendDirectMessage(bot, memberRequesting.id, {
|
||||||
|
embeds: [{
|
||||||
|
color: approved ? successColor : warnColor,
|
||||||
|
title: `Notice: Join Request ${capResponseStr}`,
|
||||||
|
description: `The owner of [this event](${eventUrl}), <@${interaction.user.id}>, has ${responseStr} your join request.${
|
||||||
|
approved ? '' : ' If you would like to join the event as an alternate, please click on the button below.'
|
||||||
|
}`,
|
||||||
|
}],
|
||||||
|
components: approved ? undefined : [{
|
||||||
|
type: MessageComponentTypes.ActionRow,
|
||||||
|
components: [{
|
||||||
|
type: MessageComponentTypes.Button,
|
||||||
|
label: alternateEventBtnStr,
|
||||||
|
style: ButtonStyles.Primary,
|
||||||
|
customId: `tempId`, // TODO: fix
|
||||||
|
}],
|
||||||
|
}],
|
||||||
|
}).catch((e: Error) => utils.commonLoggers.messageSendError('joinRequest.ts', 'send DM fail', e));
|
||||||
|
|
||||||
|
// Update request DM to indicate if it was approved or denied and disable buttons
|
||||||
|
interaction.message.embeds[0].fields.push({
|
||||||
|
name: 'Your response:',
|
||||||
|
value: capResponseStr,
|
||||||
|
});
|
||||||
|
bot.helpers.editMessage(interaction.channelId, interaction.message.id, {
|
||||||
|
embeds: [interaction.message.embeds[0]],
|
||||||
|
components: joinRequestResponseButtons(true),
|
||||||
|
}).catch((e: Error) => utils.commonLoggers.messageEditError('joinRequest.ts', 'event edit fail', e));
|
||||||
|
} else {
|
||||||
|
somethingWentWrong(bot, interaction, 'noDataFromJoinRequestButton');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const joinRequestButton = {
|
||||||
|
customId,
|
||||||
|
execute,
|
||||||
|
};
|
|
@ -1,7 +1,8 @@
|
||||||
import { ActionRow, Bot, ButtonStyles, Embed, Interaction, InteractionResponseTypes, MessageComponentTypes } from '../../../deps.ts';
|
import { ActionRow, Bot, ButtonStyles, Embed, Interaction, InteractionResponseTypes, MessageComponentTypes } from '../../../deps.ts';
|
||||||
import { LFGMember, UrlIds } from '../../types/commandTypes.ts';
|
import { LFGMember, UrlIds } from '../../types/commandTypes.ts';
|
||||||
import { sendDirectMessage, somethingWentWrong, successColor } from '../../commandUtils.ts';
|
import { sendDirectMessage, somethingWentWrong, successColor } from '../../commandUtils.ts';
|
||||||
import { generateAlternateList, generateMemberList, generateMemberTitle, leaveEventBtnStr, LfgEmbedIndexes, noMembersStr } from '../eventUtils.ts';
|
import { generateAlternateList, generateMemberList, generateMemberTitle, idSeparator, leaveEventBtnStr, LfgEmbedIndexes, noMembersStr } from '../eventUtils.ts';
|
||||||
|
import { approveStr, customId as joinRequestCustomId, denyStr } from './joinRequest.ts';
|
||||||
import utils from '../../utils.ts';
|
import utils from '../../utils.ts';
|
||||||
|
|
||||||
// Join status map to prevent spamming the system
|
// Join status map to prevent spamming the system
|
||||||
|
@ -262,13 +263,13 @@ export const joinRequestResponseButtons = (disabled: boolean): ActionRow[] => [{
|
||||||
type: MessageComponentTypes.Button,
|
type: MessageComponentTypes.Button,
|
||||||
label: 'Approve Request',
|
label: 'Approve Request',
|
||||||
style: ButtonStyles.Success,
|
style: ButtonStyles.Success,
|
||||||
customId: 'approveJoinRequestCustomId', // TODO: fix
|
customId: `${joinRequestCustomId}${idSeparator}${approveStr}`,
|
||||||
disabled,
|
disabled,
|
||||||
}, {
|
}, {
|
||||||
type: MessageComponentTypes.Button,
|
type: MessageComponentTypes.Button,
|
||||||
label: 'Deny Request',
|
label: 'Deny Request',
|
||||||
style: ButtonStyles.Danger,
|
style: ButtonStyles.Danger,
|
||||||
customId: 'denyJoinRequestCustomId', // TODO: fix
|
customId: `${joinRequestCustomId}${idSeparator}${denyStr}`,
|
||||||
disabled,
|
disabled,
|
||||||
}],
|
}],
|
||||||
}];
|
}];
|
||||||
|
|
|
@ -18,6 +18,7 @@ import { dbClient, generateGuildSettingKey, lfgChannelSettings, queries } from '
|
||||||
import { CommandDetails } from '../types/commandTypes.ts';
|
import { CommandDetails } from '../types/commandTypes.ts';
|
||||||
import utils from '../utils.ts';
|
import utils from '../utils.ts';
|
||||||
import { customId as gameSelId } from '../buttons/event-creation/step1-gameSelection.ts';
|
import { customId as gameSelId } from '../buttons/event-creation/step1-gameSelection.ts';
|
||||||
|
import { alternateEventBtnStr, joinEventBtnStr, leaveEventBtnStr, requestToJoinEventBtnStr } from '../buttons/eventUtils.ts';
|
||||||
|
|
||||||
const withoutMgrRole = 'without-manager-role';
|
const withoutMgrRole = 'without-manager-role';
|
||||||
const withMgrRole = 'with-manager-role';
|
const withMgrRole = 'with-manager-role';
|
||||||
|
@ -91,14 +92,14 @@ const execute = async (bot: Bot, interaction: Interaction) => {
|
||||||
const introFields: Array<DiscordEmbedField> = [{
|
const introFields: Array<DiscordEmbedField> = [{
|
||||||
name: 'Joining Events:',
|
name: 'Joining Events:',
|
||||||
value:
|
value:
|
||||||
'To join an event, simply click on the `Join` or `Request to Join` button. If you try to join a full event, you will be placed in the Alternates column with an `*` next to your name. Members with an `*` next to their name will automatically get promoted to the Joined list if someone leaves the event.',
|
`To join an event, simply click on the \`${joinEventBtnStr}\` or \`${requestToJoinEventBtnStr}\` button. If you try to join a full event, you will be placed in the Alternates column with an \`*\` next to your name. Members with an \`*\` next to their name will automatically get promoted to the Joined list if someone leaves the event.`,
|
||||||
}, {
|
}, {
|
||||||
name: 'Leaving Events:',
|
name: 'Leaving Events:',
|
||||||
value: 'To leave an event, simply click on the `Leave` button.',
|
value: `To leave an event, simply click on the \`${leaveEventBtnStr}\` button.`,
|
||||||
inline: true,
|
inline: true,
|
||||||
}, {
|
}, {
|
||||||
name: 'Joining Events as an Alternate:',
|
name: 'Joining Events as an Alternate:',
|
||||||
value: 'To join as a backup or indicate you might be available, simply click on the `Join as Alternate` button.',
|
value: `To join as a backup or indicate you might be available, simply click on the \`${alternateEventBtnStr}\` button.`,
|
||||||
inline: true,
|
inline: true,
|
||||||
}, {
|
}, {
|
||||||
name: 'Editing/Deleting your event:',
|
name: 'Editing/Deleting your event:',
|
||||||
|
|
|
@ -9,7 +9,7 @@ const jsonStringifyBig = (input: any) => {
|
||||||
const idsToMessageUrl = (ids: UrlIds) => `https://discord.com/channels/${ids.guildId}/${ids.channelId}/${ids.messageId}`;
|
const idsToMessageUrl = (ids: UrlIds) => `https://discord.com/channels/${ids.guildId}/${ids.channelId}/${ids.messageId}`;
|
||||||
const messageUrlToIds = (url: string): UrlIds => {
|
const messageUrlToIds = (url: string): UrlIds => {
|
||||||
url = url.toLowerCase();
|
url = url.toLowerCase();
|
||||||
const [guildId, channelId, messageId] = (url.split('channels')[1] || '').split('/');
|
const [guildId, channelId, messageId] = (url.split('channels/')[1] || '').split('/');
|
||||||
|
|
||||||
return {
|
return {
|
||||||
guildId: BigInt(guildId || '0'),
|
guildId: BigInt(guildId || '0'),
|
||||||
|
|
Loading…
Reference in New Issue