Skip to content

Commit

Permalink
feat(guess): allow guess game to be played inside a thread or played …
Browse files Browse the repository at this point in the history
…outside in a channel (#1478)
  • Loading branch information
namnhce authored and tuanddd committed Sep 8, 2023
1 parent ca1461c commit 42d5fdd
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 56 deletions.
8 changes: 4 additions & 4 deletions src/commands/guess/end/slash.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { SlashCommandSubcommandBuilder, userMention } from "@discordjs/builders"
import mochiGuess from "adapters/mochi-guess"
import { ThreadChannel, MessageOptions } from "discord.js"
import { ThreadChannel, MessageOptions, Message } from "discord.js"
import { now, truncate, groupBy } from "lodash"
import { logger } from "logger"
import moment from "moment-timezone"
Expand All @@ -27,7 +27,7 @@ export async function cleanupAfterEndGame(
}

export async function announceResult(
thread: ThreadChannel,
messageContext: ThreadChannel | Message["channel"],
gameCode: string,
answer: string,
gameResult: any,
Expand All @@ -41,7 +41,7 @@ export async function announceResult(
const embed = composeEmbedMessage(null, {
color: "GREEN",
})
embed.setTitle(`:crossed_swords: Result ${gameCode}`)
embed.setTitle(`:crossed_swords: Result - ${gameCode}`)
embed.setDescription(
"The rewards you received include taxes and transaction fees. Please be aware when receiving rewards. Contact us if you have questions or concerns. Thank you! \n\nHere is the result:",
)
Expand Down Expand Up @@ -86,7 +86,7 @@ export async function announceResult(
embeds: [embed],
}

await thread.send(msgOpt).catch(() => null)
await messageContext.send(msgOpt).catch(() => null)
}

const slashCmd: SlashCommand = {
Expand Down
121 changes: 69 additions & 52 deletions src/commands/guess/new/slash.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,12 @@ const slashCmd: SlashCommand = {
.setDescription("the label for no option (optional)")
.setRequired(false),
)
.addBooleanOption((opt) =>
opt
.setName("thread")
.setDescription("game played in thread (default false)")
.setRequired(false),
)
},
run: async (i) => {
if (i.channel?.type !== "GUILD_TEXT") {
Expand All @@ -152,23 +158,30 @@ const slashCmd: SlashCommand = {
}
}

const threadMode = i.options.getBoolean("thread", false)

const reply = (await i.editReply({
content: [`${i.user} asked:`, `> ${question}`].join("\n"),
content: [`Hey @here, ${i.user}'s popped new Quiz.`].join("\n"),
})) as Message

const thread = await reply.startThread({
name: truncate(question, { length: 100 }),
})

await thread.members.add(referee)
let messageContext: any = reply.channel
let flowID = reply.channel.id
if (threadMode) {
const thread = await reply.startThread({
name: truncate(question, { length: 100 }),
})
await thread.members.add(referee)
messageContext = thread
flowID = thread.id
}

const game = {
duration: durationMin,
host_id: i.user.id,
options: [yesLabel, noLabel],
question,
referee_id: referee.id,
thread_id: thread.id,
thread_id: flowID,
}
const { ok, data, originalError, error } = await mochiGuess.createGame(game)
if (!ok) {
Expand All @@ -179,6 +192,33 @@ const slashCmd: SlashCommand = {
}
}

const yesCode = data.options.find((opt: any) =>
equalIgnoreCase(opt.option, yesLabel),
).code
const noCode = data.options.find((opt: any) =>
equalIgnoreCase(opt.option, noLabel),
).code

const options: Record<string, string> = {
[yesCode]: yesLabel,
[noCode]: noLabel,
}

const choices = [
new MessageActionRow().addComponents(
new MessageButton({
label: yesLabel,
style: "SECONDARY",
customId: yesCode,
}),
new MessageButton({
label: noLabel,
style: "SECONDARY",
customId: noCode,
}),
),
]

const start = Date.now(),
end = start + durationMs
const updatePlayers = async function () {
Expand Down Expand Up @@ -207,34 +247,7 @@ const slashCmd: SlashCommand = {
}
}

const yesCode = data.options.find((opt: any) =>
equalIgnoreCase(opt.option, yesLabel),
).code
const noCode = data.options.find((opt: any) =>
equalIgnoreCase(opt.option, noLabel),
).code

const options: Record<string, string> = {
[yesCode]: yesLabel,
[noCode]: noLabel,
}

const choices = [
new MessageActionRow().addComponents(
new MessageButton({
label: yesLabel,
style: "SECONDARY",
customId: yesCode,
}),
new MessageButton({
label: noLabel,
style: "SECONDARY",
customId: noCode,
}),
),
]

const msg = await thread.send({
const msg = await messageContext.send({
content: renderProgress(
referee,
question,
Expand All @@ -255,12 +268,12 @@ const slashCmd: SlashCommand = {
const embed = composeEmbedMessage(null, {
color: "RED",
})
embed.setTitle(":loudspeaker: Judgement")
embed.setTitle(`:loudspeaker: Judgement - ${data.code}`)
embed.setDescription(
`Hey ${referee}, time is up:hourglass:\nPlease submit the game result to decide the winners of the game.`,
)

const msg = await thread
const msg = await messageContext
.send({
embeds: [embed],
components: choices,
Expand All @@ -273,7 +286,7 @@ const slashCmd: SlashCommand = {
// 10 minutes to decide
time: 10 * 60 * 1000,
})
.on("collect", async (i) => {
.on("collect", async (i: any) => {
await i.deferReply({ ephemeral: true }).catch(() => null)
if (i.user.id !== referee.id) {
await i.editReply({
Expand All @@ -290,14 +303,16 @@ const slashCmd: SlashCommand = {
await i.deleteReply().catch(() => null)
if (gameResult?.data) {
await announceResult(
thread,
messageContext,
data.code,
options[i.customId as keyof typeof options],
gameResult.data,
)
}

await cleanupAfterEndGame(thread, data.code)
if (threadMode) {
await cleanupAfterEndGame(messageContext, data.code)
}
})
},
durationMs + 30 * 1000,
Expand All @@ -306,19 +321,21 @@ const slashCmd: SlashCommand = {

timers.set(data.code, setInterval(updatePlayers, 10 * 1000))

const editedReply = await reply
.edit({
content: [`${i.user} asked:`, `> ${question}`].join("\n"),
components: choices,
})
.catch(() => null)
if (threadMode) {
const editedReply = await reply
.edit({
content: [`${i.user} asked:`, `> ${question}`].join("\n"),
components: choices,
})
.catch(() => null)

editedReply
?.createMessageComponentCollector({
componentType: "BUTTON",
time: durationMs,
})
.on("collect", collectPlayerChoice(data, referee))
editedReply
?.createMessageComponentCollector({
componentType: "BUTTON",
time: durationMs,
})
.on("collect", collectPlayerChoice(data, referee))
}

msg
.createMessageComponentCollector({
Expand Down

0 comments on commit 42d5fdd

Please sign in to comment.