-
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
5 changed files
with
85 additions
and
106 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,28 +1,20 @@ | ||
import { ActionRowBuilder, ButtonBuilder, ButtonStyle, EmbedBuilder, MessageActionRowComponentBuilder } from "discord.js" | ||
import { EmbedBuilder } from "discord.js" | ||
import { cancelColor, errorColor, normalColor, successColor } from "../../utils/colors.js" | ||
|
||
const commandId = "patch-mission" | ||
|
||
const missionNotFoundEmbed = new EmbedBuilder().setTitle("승격조건을 찾을 수 없습니다.").setColor(errorColor) | ||
|
||
const noChangeEmbed = new EmbedBuilder().setTitle("수정 사항이 없습니다").setColor(errorColor) | ||
const replyEmbedPrototype = new EmbedBuilder().setTitle("승격조건을 수정합니까?").setColor(normalColor) | ||
const successEmbedPrototype = new EmbedBuilder().setTitle("승격조건을 수정했습니다").setColor(successColor) | ||
const cancelEmbedPrototype = new EmbedBuilder().setTitle("승격조건 수정을 취소했습니다").setColor(cancelColor) | ||
|
||
const confirmButtonId = "patch-mission-confirm" | ||
const confirmButton = new ButtonBuilder().setCustomId(confirmButtonId).setLabel("확인").setStyle(ButtonStyle.Success) | ||
const cancelButtonId = "patch-mission-cancel" | ||
const cancelButton = new ButtonBuilder().setCustomId(cancelButtonId).setLabel("취소").setStyle(ButtonStyle.Danger) | ||
const actionRow = new ActionRowBuilder<MessageActionRowComponentBuilder>().addComponents(confirmButton, cancelButton) | ||
|
||
export default { | ||
commandId, | ||
missionNotFoundEmbed, | ||
noChangeEmbed, | ||
replyEmbedPrototype, | ||
successEmbedPrototype, | ||
cancelEmbedPrototype, | ||
confirmButtonId, | ||
confirmButton, | ||
cancelButtonId, | ||
cancelButton, | ||
actionRow | ||
cancelEmbedPrototype | ||
} |
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,120 +1,116 @@ | ||
import { ButtonInteraction, ChatInputCommandInteraction, ComponentType, EmbedBuilder, InteractionResponse, Message, User } from "discord.js" | ||
import { ButtonInteraction, ChatInputCommandInteraction, ComponentType, EmbedBuilder, InteractionResponse, Message, ModalSubmitInteraction, User } from "discord.js" | ||
import { getMission, patchMission } from "../../../db/actions/missionActions.js" | ||
import { Mission, MissionUpdateData } from "../../../interfaces/models/Mission.js" | ||
import { checkAssociate } from "../../utils/checks/checkAssociate.js" | ||
import { createMissionEditPreviewString, createMissionPreviewTitle } from "../../utils/createString/createMissionPreviewString.js" | ||
import { errorEmbed } from "../../utils/errorEmbeds.js" | ||
import { getQuarterDataFooter } from "../../utils/quarterData/getQuarterData.js" | ||
import builders from "./builders.js" | ||
import { createMissionModal, createMissionModalId, getMissionModalMission } from "../../utils/components/missionModal.js" | ||
import { addConfirmCollector, createConfirmActionRow } from "../../utils/components/confirmActionRow.js" | ||
|
||
const { | ||
commandId, | ||
missionNotFoundEmbed, | ||
noChangeEmbed, | ||
replyEmbedPrototype, | ||
successEmbedPrototype, | ||
cancelEmbedPrototype, | ||
confirmButtonId, | ||
cancelButtonId, | ||
actionRow | ||
cancelEmbedPrototype | ||
} = builders | ||
|
||
const readOptions = (interaction: ChatInputCommandInteraction) => ({ | ||
export const readOptions = (interaction: ChatInputCommandInteraction) => ({ | ||
target: interaction.options.getUser("대상", true), | ||
category: interaction.options.getString("카테고리", true), | ||
index: interaction.options.getNumber("번호", true) - 1, | ||
content: interaction.options.getString("내용"), | ||
note: interaction.options.getString("비고"), | ||
score: interaction.options.getNumber("점수") | ||
}) | ||
|
||
const doConfirm = async ( | ||
interaction: ChatInputCommandInteraction, buttonInteraction: ButtonInteraction, | ||
target: User, category: string, index: number, missionUpdateData: MissionUpdateData, | ||
const onConfirm = ( | ||
interaction: ModalSubmitInteraction, | ||
target: User, category: string, index: number, | ||
missionNew: Mission, missionLast: Mission | ||
) => { | ||
await buttonInteraction.deferReply({ephemeral: true}) | ||
) => | ||
async (buttonInteraction: ButtonInteraction) => { | ||
await buttonInteraction.deferReply({ ephemeral: true }) | ||
|
||
const success = await patchMission(interaction.user.id, target.id, category, index, missionUpdateData) | ||
const success = await patchMission(interaction.user.id, target.id, category, index, missionNew) | ||
|
||
if (success) { | ||
const successEmbed = new EmbedBuilder(successEmbedPrototype.toJSON()) | ||
.addFields({ name: createMissionPreviewTitle(missionNew, target), value: createMissionEditPreviewString(missionNew, missionLast, target) }) | ||
if (success) { | ||
const successEmbed = new EmbedBuilder(successEmbedPrototype.toJSON()) | ||
.addFields({ name: createMissionPreviewTitle(missionNew, target), value: createMissionEditPreviewString(missionNew, missionLast, target) }) | ||
|
||
await buttonInteraction.deleteReply() | ||
await interaction.editReply({ embeds: [successEmbed.setFooter(await getQuarterDataFooter())], components: [] }) | ||
await buttonInteraction.deleteReply() | ||
await interaction.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, category: string, index: number, missionUpdateData: MissionUpdateData, | ||
const onCancel = ( | ||
interaction: ModalSubmitInteraction, | ||
target: User, category: string, index: number, | ||
missionNew: Mission, missionLast: Mission | ||
) => { | ||
await buttonInteraction.deferUpdate() | ||
|
||
const cancelEmbed = new EmbedBuilder(cancelEmbedPrototype.toJSON()) | ||
.addFields({ name: createMissionPreviewTitle(missionNew, target), value: createMissionEditPreviewString(missionNew, missionLast, target) }) | ||
) => | ||
async (buttonInteraction: ButtonInteraction) => { | ||
await buttonInteraction.deferUpdate() | ||
|
||
await interaction.editReply({ embeds: [cancelEmbed.setFooter(await getQuarterDataFooter())], components: [] }) | ||
} | ||
const cancelEmbed = new EmbedBuilder(cancelEmbedPrototype.toJSON()) | ||
.addFields({ name: createMissionPreviewTitle(missionNew, target), value: createMissionEditPreviewString(missionNew, missionLast, target) }) | ||
|
||
const addCollector = ( | ||
interaction: ChatInputCommandInteraction, reply: Message<boolean> | InteractionResponse<boolean>, | ||
target: User, category: string, index: number, missionUpdateData: MissionUpdateData, | ||
missionNew: Mission, missionLast: 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, category, index, missionUpdateData, missionNew, missionLast) | ||
else if (buttonInteraction.customId === cancelButtonId) | ||
doCancel(interaction, buttonInteraction, target, category, index, missionUpdateData, missionNew, missionLast) | ||
}) | ||
} | ||
|
||
const doReply = async (interaction: ChatInputCommandInteraction, target: User, category: string, index: number, missionUpdateData: MissionUpdateData, isEditing: boolean = false) => { | ||
if (!isEditing) | ||
await interaction.deferReply({ephemeral: true}) | ||
await interaction.editReply({ embeds: [cancelEmbed.setFooter(await getQuarterDataFooter())], components: [] }) | ||
} | ||
|
||
export const doReply = async (interaction: ChatInputCommandInteraction, target: User, category: string, index: number, isEditing: boolean = false) => { | ||
if (!await checkAssociate(interaction, target.id, true)) | ||
return | ||
|
||
if (missionUpdateData.content === undefined && missionUpdateData.note === undefined && missionUpdateData.score === undefined) { | ||
await interaction.editReply({ embeds: [noChangeEmbed] }) | ||
return | ||
} | ||
|
||
const missionLast = await getMission(interaction.user.id, target.id, category, index) | ||
|
||
if (missionLast === null) { | ||
await interaction.editReply({ embeds: [missionNotFoundEmbed] }) | ||
await interaction.reply({ embeds: [missionNotFoundEmbed] }) | ||
return | ||
} | ||
if (missionLast === undefined) { | ||
await interaction.editReply({ embeds: [errorEmbed] }) | ||
await interaction.reply({ embeds: [errorEmbed] }) | ||
return | ||
} | ||
|
||
const missionNew: Mission = { | ||
...missionLast, | ||
...missionUpdateData | ||
await interaction.showModal(createMissionModal( | ||
commandId, interaction.user, target, | ||
missionLast.category, missionLast.content, missionLast.score, missionLast.note | ||
)) | ||
|
||
const modalInteraction = await interaction.awaitModalSubmit({ | ||
filter: mI => mI.customId === createMissionModalId(commandId, interaction.user), | ||
time: 60_000 | ||
}).catch(_ => null) | ||
if (modalInteraction === null) | ||
return | ||
|
||
const missionNew = getMissionModalMission(modalInteraction, target, missionLast.completed) | ||
if (missionNew === undefined) { | ||
await modalInteraction.reply("점수가 숫자가 아닙니다!") | ||
return | ||
} | ||
else if (missionNew.content === missionLast.content && missionNew.note === missionLast.note && missionNew.score === missionLast.score) { | ||
await modalInteraction.reply({ embeds: [noChangeEmbed] }) | ||
return | ||
} | ||
|
||
const replyEmbed = new EmbedBuilder(replyEmbedPrototype.toJSON()) | ||
.addFields({ name: createMissionPreviewTitle(missionNew, target), value: createMissionEditPreviewString(missionNew, missionLast, target) }) | ||
const reply = await interaction.editReply({ embeds: [replyEmbed.setFooter(await getQuarterDataFooter())], components: [actionRow] }); | ||
const reply = await modalInteraction.reply({ | ||
embeds: [ | ||
EmbedBuilder.from(replyEmbedPrototype) | ||
.addFields({ name: createMissionPreviewTitle(missionNew, target), value: createMissionEditPreviewString(missionNew, missionLast, target) }) | ||
.setFooter(await getQuarterDataFooter()) | ||
], | ||
components: [createConfirmActionRow(commandId, modalInteraction.user)], | ||
ephemeral: true, | ||
fetchReply: true | ||
}); | ||
|
||
if (!isEditing) | ||
addCollector(interaction, reply, target, category, index, missionUpdateData, missionNew, missionLast) | ||
} | ||
|
||
export default { | ||
readOptions, | ||
doReply | ||
await addConfirmCollector( | ||
commandId, modalInteraction, reply, | ||
onConfirm(modalInteraction, target, category, index, missionNew, missionLast), | ||
onCancel(modalInteraction, target, category, index, missionNew, missionLast) | ||
) | ||
} |
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,21 +1,14 @@ | ||
import assert from "assert" | ||
import { InteractionOperation } from "../../../interfaces/commands/InteractionOperation.js" | ||
import { MissionUpdateData } 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, index, category, content, note, score } = readOptions(interaction) | ||
|
||
const missionUpdateData: MissionUpdateData = {} | ||
if (content !== null) missionUpdateData.content = content | ||
if (note !== null) missionUpdateData.note = note | ||
if (score !== null) missionUpdateData.score = score | ||
const { target, index, category } = readOptions(interaction) | ||
|
||
await doReply(interaction, target, category, index, missionUpdateData) | ||
await doReply(interaction, target, category, index) | ||
} | ||
|
||
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