-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
14 changed files
with
216 additions
and
96 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,24 +1,15 @@ | ||
import { ActionRowBuilder, ButtonBuilder, ButtonStyle, EmbedBuilder, MessageActionRowComponentBuilder } from "discord.js" | ||
import { ActionRowBuilder, ButtonBuilder, ButtonStyle, EmbedBuilder, MessageActionRowComponentBuilder, ModalBuilder, TextInputBuilder, TextInputStyle } from "discord.js" | ||
import { cancelColor, normalColor, successColor } from "../../utils/colors.js" | ||
|
||
const commandId = "post-mission" | ||
|
||
const replyEmbedPrototype = new EmbedBuilder().setTitle("승격조건을 추가합니까?").setColor(normalColor) | ||
const successEmbedPrototype = new EmbedBuilder().setTitle("승격조건을 추가했습니다").setColor(successColor) | ||
const cancelEmbedPrototype = new EmbedBuilder().setTitle("승격조건 추가를 취소했습니다").setColor(cancelColor) | ||
|
||
const confirmButtonId = "post-mission-confirm" | ||
const confirmButton = new ButtonBuilder().setCustomId(confirmButtonId).setLabel("확인").setStyle(ButtonStyle.Success) | ||
const cancelButtonId = "post-mission-cancel" | ||
const cancelButton = new ButtonBuilder().setCustomId(cancelButtonId).setLabel("취소").setStyle(ButtonStyle.Danger) | ||
const actionRow = new ActionRowBuilder<MessageActionRowComponentBuilder>().addComponents(confirmButton, cancelButton) | ||
|
||
export default { | ||
commandId, | ||
replyEmbedPrototype, | ||
successEmbedPrototype, | ||
cancelEmbedPrototype, | ||
|
||
confirmButtonId, | ||
confirmButton, | ||
cancelButtonId, | ||
cancelButton, | ||
actionRow | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,84 +1,95 @@ | ||
import builders from "./builders.js" | ||
import { ButtonInteraction, ChatInputCommandInteraction, ComponentType, EmbedBuilder, InteractionResponse, Message, User } from "discord.js" | ||
import { ButtonInteraction, ChatInputCommandInteraction, ComponentType, EmbedBuilder, InteractionResponse, Message, ModalSubmitInteraction, User } from "discord.js" | ||
import { postMission } from "../../../db/actions/missionActions.js" | ||
import { Mission } from "../../../interfaces/models/Mission.js" | ||
import { errorEmbed } from "../../utils/errorEmbeds.js" | ||
import { createMissionPreviewString, createMissionPreviewTitle } from "../../utils/createString/createMissionPreviewString.js" | ||
import { checkAssociate } from "../../utils/checks/checkAssociate.js" | ||
import { confirmCollect, confirmFilter, confirmTimeout, createConfirmActionRow } from "../../utils/components/confirmActionRow.js" | ||
import { createMissionModal, createMissionModalId, getMissionModalValue } from "../../utils/components/missionModal.js" | ||
import { createMissionPreviewString, createMissionPreviewTitle } from "../../utils/createString/createMissionPreviewString.js" | ||
import { errorEmbed } from "../../utils/errorEmbeds.js" | ||
import { getQuarterDataFooter } from "../../utils/quarterData/getQuarterData.js" | ||
import builders from "./builders.js" | ||
|
||
const { | ||
commandId, | ||
replyEmbedPrototype, | ||
successEmbedPrototype, | ||
cancelEmbedPrototype, | ||
confirmButtonId, | ||
cancelButtonId, | ||
actionRow | ||
} = builders | ||
|
||
const readOptions = (interaction: ChatInputCommandInteraction) => ({ | ||
target: interaction.options.getUser("대상", true), | ||
category: interaction.options.getString("카테고리"), | ||
content: interaction.options.getString("내용", true), | ||
note: interaction.options.getString("비고"), | ||
score: interaction.options.getNumber("점수") | ||
export const readOptions = (interaction: ChatInputCommandInteraction) => ({ | ||
target: interaction.options.getUser("대상", true) | ||
}) | ||
|
||
const doConfirm = async (interaction: ChatInputCommandInteraction, buttonInteraction: ButtonInteraction, target: User, mission: Mission) => { | ||
await buttonInteraction.deferReply({ephemeral: true}) | ||
const onConfirm = (modalInteraction: ModalSubmitInteraction, target: User, mission: Mission) => | ||
async (buttonInteraction: ButtonInteraction) => { | ||
await buttonInteraction.deferReply({ ephemeral: true }) | ||
|
||
const success = await postMission(mission) | ||
const success = await postMission(mission) | ||
|
||
if (success) { | ||
const successEmbed = new EmbedBuilder(successEmbedPrototype.toJSON()) | ||
.addFields({ name: createMissionPreviewTitle(mission, target), value: createMissionPreviewString(mission, target) }) | ||
if (success) { | ||
const successEmbed = new EmbedBuilder(successEmbedPrototype.toJSON()) | ||
.addFields({ name: createMissionPreviewTitle(mission, target), value: createMissionPreviewString(mission, target) }) | ||
|
||
await buttonInteraction.deleteReply() | ||
await interaction.editReply({ embeds: [successEmbed.setFooter(await getQuarterDataFooter())], components: [] }) | ||
await buttonInteraction.deleteReply() | ||
await modalInteraction.editReply({ embeds: [successEmbed.setFooter(await getQuarterDataFooter())], components: [] }) | ||
} | ||
else | ||
await buttonInteraction.editReply({ embeds: [errorEmbed] }) | ||
} | ||
else | ||
await buttonInteraction.editReply({ embeds: [errorEmbed] }) | ||
} | ||
|
||
const doCancel = async (interaction: ChatInputCommandInteraction, buttonInteraction: ButtonInteraction, target: User, mission: Mission) => { | ||
await buttonInteraction.deferUpdate() | ||
const onCancel = (modalInteraction: ModalSubmitInteraction, target: User, mission: Mission) => | ||
async (buttonInteraction: ButtonInteraction) => { | ||
await buttonInteraction.deferUpdate() | ||
|
||
const cancelEmbed = new EmbedBuilder(cancelEmbedPrototype.toJSON()) | ||
.addFields({ name: createMissionPreviewTitle(mission, target), value: createMissionPreviewString(mission, target) }) | ||
const cancelEmbed = new EmbedBuilder(cancelEmbedPrototype.toJSON()) | ||
.addFields({ name: createMissionPreviewTitle(mission, target), value: createMissionPreviewString(mission, target) }) | ||
|
||
await interaction.editReply({ embeds: [cancelEmbed.setFooter(await getQuarterDataFooter())], components: [] }) | ||
} | ||
await modalInteraction.editReply({ embeds: [cancelEmbed.setFooter(await getQuarterDataFooter())], components: [] }) | ||
} | ||
|
||
const addCollector = async ( | ||
interaction: ChatInputCommandInteraction, reply: Message<boolean> | InteractionResponse<boolean>, | ||
modalInteraction: ModalSubmitInteraction, reply: Message<boolean> | InteractionResponse<boolean>, | ||
target: User, mission: Mission | ||
) => { | ||
const collector = reply.createMessageComponentCollector({ | ||
filter: i => i.user === interaction.user, | ||
componentType: ComponentType.Button | ||
}) | ||
collector.on("collect", async buttonInteraction => { | ||
if (buttonInteraction.customId === confirmButtonId) | ||
doConfirm(interaction, buttonInteraction, target, mission) | ||
else if (buttonInteraction.customId === cancelButtonId) | ||
doCancel(interaction, buttonInteraction, target, mission) | ||
filter: confirmFilter(commandId, modalInteraction.user), | ||
componentType: ComponentType.Button, time: 10_000, max: 1 | ||
}) | ||
|
||
collector.on("collect", confirmCollect(commandId, modalInteraction.user, | ||
onConfirm(modalInteraction, target, mission), onCancel(modalInteraction, target, mission))) | ||
collector.on('end', confirmTimeout(modalInteraction)); | ||
} | ||
|
||
export const doReply = async (interaction: ChatInputCommandInteraction, target: User, isEditing: boolean = false) => { | ||
if (!await checkAssociate(interaction, target.id, true)) | ||
return | ||
|
||
const doReply = async (interaction: ChatInputCommandInteraction, target: User, mission: Mission, isEditing: boolean = false) => { | ||
if (!isEditing) | ||
await interaction.deferReply({ephemeral: true}) | ||
await interaction.showModal(createMissionModal(commandId, interaction.user, target)) | ||
|
||
if (!await checkAssociate(interaction, target.id, true)) | ||
const modalInteraction = await interaction.awaitModalSubmit({ | ||
filter: mI => mI.customId === createMissionModalId(commandId, interaction.user), | ||
time: 60_000 | ||
}).catch(_ => null) | ||
if (modalInteraction === null) | ||
return | ||
|
||
const replyEmbed = new EmbedBuilder(replyEmbedPrototype.toJSON()) | ||
const mission = getMissionModalValue(modalInteraction, target) | ||
if (mission === undefined) { | ||
await modalInteraction.reply("점수가 숫자가 아닙니다!") | ||
return | ||
} | ||
|
||
const replyEmbed = EmbedBuilder.from(replyEmbedPrototype) | ||
.addFields({ name: createMissionPreviewTitle(mission, target), value: createMissionPreviewString(mission, target) }) | ||
const reply = await interaction.editReply({ embeds: [replyEmbed.setFooter(await getQuarterDataFooter())], components: [actionRow] }); | ||
.setFooter(await getQuarterDataFooter()) | ||
|
||
if (!isEditing) | ||
addCollector(interaction, reply, target, mission) | ||
} | ||
const reply = await modalInteraction.reply({ | ||
embeds: [replyEmbed], | ||
components: [createConfirmActionRow(commandId, modalInteraction.user)], | ||
ephemeral: true, | ||
fetchReply: true | ||
}); | ||
|
||
export default { readOptions, doReply } | ||
await addCollector(modalInteraction, reply, target, mission) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,26 +1,13 @@ | ||
import assert from "assert" | ||
import { InteractionOperation } from "../../../interfaces/commands/InteractionOperation.js" | ||
import { Mission } from "../../../interfaces/models/Mission.js" | ||
import operations from "./operations.js" | ||
|
||
const { readOptions, doReply } = operations | ||
import { doReply, readOptions } from "./operations.js" | ||
|
||
const reply: InteractionOperation = async interaction => { | ||
assert(interaction.isChatInputCommand()) | ||
|
||
const { target, category, content, note, score } = readOptions(interaction) | ||
|
||
const mission: Mission = { | ||
category: category ?? (target !== interaction.user ? "개인 조건" : "공통 조건"), | ||
content, | ||
note: note ?? "", | ||
score: score ?? 1, | ||
giverId: interaction.user.id, | ||
targetId: target.id, | ||
completed: [] | ||
} | ||
const { target } = readOptions(interaction) | ||
|
||
await doReply(interaction, target, mission) | ||
await doReply(interaction, target) | ||
} | ||
|
||
export default reply |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.