event info speedcode any% this is horrifying
This commit is contained in:
15
helpers/prune-null-values.ts
Normal file
15
helpers/prune-null-values.ts
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
export function pruneNullishValues<T extends object>(
|
||||||
|
object: T,
|
||||||
|
): PruneNullishValues<T> {
|
||||||
|
const result: any = {}
|
||||||
|
for (const [key, value] of Object.entries(object)) {
|
||||||
|
if (value != undefined) {
|
||||||
|
result[key] = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
type PruneNullishValues<T> = {
|
||||||
|
[Key in keyof T]: NonNullable<T[Key]>
|
||||||
|
}
|
||||||
@@ -2,7 +2,64 @@ import type { ReactNode } from "react"
|
|||||||
import type { ReacordInstance } from "./instance"
|
import type { ReacordInstance } from "./instance"
|
||||||
|
|
||||||
export type ComponentEvent = {
|
export type ComponentEvent = {
|
||||||
// todo: add more info, like user, channel, member, guild, etc.
|
message: MessageInfo
|
||||||
|
channel: ChannelInfo
|
||||||
|
user: UserInfo
|
||||||
|
guild?: GuildInfo
|
||||||
reply(content?: ReactNode): ReacordInstance
|
reply(content?: ReactNode): ReacordInstance
|
||||||
ephemeralReply(content?: ReactNode): ReacordInstance
|
ephemeralReply(content?: ReactNode): ReacordInstance
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type ChannelInfo = {
|
||||||
|
id: string
|
||||||
|
name?: string
|
||||||
|
topic?: string
|
||||||
|
nsfw?: boolean
|
||||||
|
lastMessageId?: string
|
||||||
|
ownerId?: string
|
||||||
|
parentId?: string
|
||||||
|
rateLimitPerUser?: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export type MessageInfo = {
|
||||||
|
id: string
|
||||||
|
channelId: string
|
||||||
|
authorId: UserInfo
|
||||||
|
member?: GuildMemberInfo
|
||||||
|
content: string
|
||||||
|
timestamp: string
|
||||||
|
editedTimestamp?: string
|
||||||
|
tts: boolean
|
||||||
|
mentionEveryone: boolean
|
||||||
|
/** The IDs of mentioned users */
|
||||||
|
mentions: string[]
|
||||||
|
}
|
||||||
|
|
||||||
|
export type GuildInfo = {
|
||||||
|
id: string
|
||||||
|
name: string
|
||||||
|
member: GuildMemberInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
export type GuildMemberInfo = {
|
||||||
|
id: string
|
||||||
|
nick?: string
|
||||||
|
displayName: string
|
||||||
|
avatarUrl?: string
|
||||||
|
displayAvatarUrl: string
|
||||||
|
roles: string[]
|
||||||
|
color: number
|
||||||
|
joinedAt?: string
|
||||||
|
premiumSince?: string
|
||||||
|
pending?: boolean
|
||||||
|
communicationDisabledUntil?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type UserInfo = {
|
||||||
|
id: string
|
||||||
|
username: string
|
||||||
|
discriminator: string
|
||||||
|
tag: string
|
||||||
|
avatarUrl: string
|
||||||
|
accentColor?: number
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,13 +1,22 @@
|
|||||||
/* eslint-disable class-methods-use-this */
|
/* eslint-disable class-methods-use-this */
|
||||||
import type * as Discord from "discord.js"
|
import * as Discord from "discord.js"
|
||||||
import type { ReactNode } from "react"
|
import type { ReactNode } from "react"
|
||||||
import type { Except } from "type-fest"
|
import type { Except } from "type-fest"
|
||||||
|
import { pick } from "../../helpers/pick"
|
||||||
|
import { pruneNullishValues } from "../../helpers/prune-null-values"
|
||||||
import { raise } from "../../helpers/raise"
|
import { raise } from "../../helpers/raise"
|
||||||
import { toUpper } from "../../helpers/to-upper"
|
import { toUpper } from "../../helpers/to-upper"
|
||||||
import type { ComponentInteraction } from "../internal/interaction"
|
import type { ComponentInteraction } from "../internal/interaction"
|
||||||
import type { Message, MessageOptions } from "../internal/message"
|
import type { Message, MessageOptions } from "../internal/message"
|
||||||
import { ChannelMessageRenderer } from "../internal/renderers/channel-message-renderer"
|
import { ChannelMessageRenderer } from "../internal/renderers/channel-message-renderer"
|
||||||
import { InteractionReplyRenderer } from "../internal/renderers/interaction-reply-renderer"
|
import { InteractionReplyRenderer } from "../internal/renderers/interaction-reply-renderer"
|
||||||
|
import type {
|
||||||
|
ChannelInfo,
|
||||||
|
GuildInfo,
|
||||||
|
GuildMemberInfo,
|
||||||
|
MessageInfo,
|
||||||
|
UserInfo,
|
||||||
|
} from "./component-event"
|
||||||
import type { ReacordInstance } from "./instance"
|
import type { ReacordInstance } from "./instance"
|
||||||
import type { ReacordConfig } from "./reacord"
|
import type { ReacordConfig } from "./reacord"
|
||||||
import { Reacord } from "./reacord"
|
import { Reacord } from "./reacord"
|
||||||
@@ -126,6 +135,81 @@ export class ReacordDiscordJs extends Reacord {
|
|||||||
private createReacordComponentInteraction(
|
private createReacordComponentInteraction(
|
||||||
interaction: Discord.MessageComponentInteraction,
|
interaction: Discord.MessageComponentInteraction,
|
||||||
): ComponentInteraction {
|
): ComponentInteraction {
|
||||||
|
// todo please dear god clean this up
|
||||||
|
const channel: ChannelInfo = interaction.channel
|
||||||
|
? {
|
||||||
|
...pick(pruneNullishValues(interaction.channel), [
|
||||||
|
"topic",
|
||||||
|
"nsfw",
|
||||||
|
"lastMessageId",
|
||||||
|
"ownerId",
|
||||||
|
"parentId",
|
||||||
|
"rateLimitPerUser",
|
||||||
|
]),
|
||||||
|
id: interaction.channelId,
|
||||||
|
}
|
||||||
|
: raise("Non-channel interactions are not supported")
|
||||||
|
|
||||||
|
const message: MessageInfo =
|
||||||
|
interaction.message instanceof Discord.Message
|
||||||
|
? {
|
||||||
|
...pick(interaction.message, [
|
||||||
|
"id",
|
||||||
|
"channelId",
|
||||||
|
"authorId",
|
||||||
|
"content",
|
||||||
|
"tts",
|
||||||
|
"mentionEveryone",
|
||||||
|
]),
|
||||||
|
timestamp: new Date(
|
||||||
|
interaction.message.createdTimestamp,
|
||||||
|
).toISOString(),
|
||||||
|
editedTimestamp: interaction.message.editedTimestamp
|
||||||
|
? new Date(interaction.message.editedTimestamp).toISOString()
|
||||||
|
: undefined,
|
||||||
|
mentions: interaction.message.mentions.users.map((u) => u.id),
|
||||||
|
}
|
||||||
|
: raise("Message not found")
|
||||||
|
|
||||||
|
const member: GuildMemberInfo | undefined =
|
||||||
|
interaction.member instanceof Discord.GuildMember
|
||||||
|
? {
|
||||||
|
...pick(pruneNullishValues(interaction.member), [
|
||||||
|
"id",
|
||||||
|
"nick",
|
||||||
|
"displayName",
|
||||||
|
"avatarUrl",
|
||||||
|
"displayAvatarUrl",
|
||||||
|
"color",
|
||||||
|
"pending",
|
||||||
|
]),
|
||||||
|
displayName: interaction.member.displayName,
|
||||||
|
roles: [...interaction.member.roles.cache.map((role) => role.id)],
|
||||||
|
joinedAt: interaction.member.joinedAt?.toISOString(),
|
||||||
|
premiumSince: interaction.member.premiumSince?.toISOString(),
|
||||||
|
communicationDisabledUntil:
|
||||||
|
interaction.member.communicationDisabledUntil?.toISOString(),
|
||||||
|
}
|
||||||
|
: undefined
|
||||||
|
|
||||||
|
const guild: GuildInfo | undefined = interaction.guild
|
||||||
|
? {
|
||||||
|
...pick(pruneNullishValues(interaction.guild), ["id", "name"]),
|
||||||
|
member: member ?? raise("unexpected: member is undefined"),
|
||||||
|
}
|
||||||
|
: undefined
|
||||||
|
|
||||||
|
const user: UserInfo = {
|
||||||
|
...pick(pruneNullishValues(interaction.user), [
|
||||||
|
"id",
|
||||||
|
"username",
|
||||||
|
"discriminator",
|
||||||
|
"tag",
|
||||||
|
]),
|
||||||
|
avatarUrl: interaction.user.avatarURL()!,
|
||||||
|
accentColor: interaction.user.accentColor ?? undefined,
|
||||||
|
}
|
||||||
|
|
||||||
const baseProps: Except<ComponentInteraction, "type"> = {
|
const baseProps: Except<ComponentInteraction, "type"> = {
|
||||||
id: interaction.id,
|
id: interaction.id,
|
||||||
customId: interaction.customId,
|
customId: interaction.customId,
|
||||||
@@ -151,6 +235,11 @@ export class ReacordDiscordJs extends Reacord {
|
|||||||
return createReacordMessage(message as Discord.Message)
|
return createReacordMessage(message as Discord.Message)
|
||||||
},
|
},
|
||||||
event: {
|
event: {
|
||||||
|
channel,
|
||||||
|
message,
|
||||||
|
user,
|
||||||
|
guild,
|
||||||
|
|
||||||
reply: (content?: ReactNode) =>
|
reply: (content?: ReactNode) =>
|
||||||
this.createInstance(
|
this.createInstance(
|
||||||
this.createInteractionReplyRenderer(interaction),
|
this.createInteractionReplyRenderer(interaction),
|
||||||
|
|||||||
@@ -22,6 +22,12 @@ import type {
|
|||||||
} from "../internal/message"
|
} from "../internal/message"
|
||||||
import { ChannelMessageRenderer } from "../internal/renderers/channel-message-renderer"
|
import { ChannelMessageRenderer } from "../internal/renderers/channel-message-renderer"
|
||||||
import { InteractionReplyRenderer } from "../internal/renderers/interaction-reply-renderer"
|
import { InteractionReplyRenderer } from "../internal/renderers/interaction-reply-renderer"
|
||||||
|
import type {
|
||||||
|
ChannelInfo,
|
||||||
|
GuildInfo,
|
||||||
|
MessageInfo,
|
||||||
|
UserInfo,
|
||||||
|
} from "./component-event"
|
||||||
import type { ButtonClickEvent } from "./components/button"
|
import type { ButtonClickEvent } from "./components/button"
|
||||||
import type { SelectChangeEvent } from "./components/select"
|
import type { SelectChangeEvent } from "./components/select"
|
||||||
import type { ReacordInstance } from "./instance"
|
import type { ReacordInstance } from "./instance"
|
||||||
@@ -250,6 +256,11 @@ class TestSelectInteraction
|
|||||||
class TestComponentEvent {
|
class TestComponentEvent {
|
||||||
constructor(private tester: ReacordTester) {}
|
constructor(private tester: ReacordTester) {}
|
||||||
|
|
||||||
|
message: MessageInfo = {} as any // todo
|
||||||
|
channel: ChannelInfo = {} as any // todo
|
||||||
|
user: UserInfo = {} as any // todo
|
||||||
|
guild: GuildInfo = {} as any // todo
|
||||||
|
|
||||||
reply(content?: ReactNode): ReacordInstance {
|
reply(content?: ReactNode): ReacordInstance {
|
||||||
return this.tester.reply()
|
return this.tester.reply()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -70,7 +70,12 @@ createCommandHandler(client, [
|
|||||||
<>
|
<>
|
||||||
<Button
|
<Button
|
||||||
label="public clic"
|
label="public clic"
|
||||||
onClick={() => reacord.reply(interaction, "you clic")}
|
onClick={(event) =>
|
||||||
|
reacord.reply(
|
||||||
|
interaction,
|
||||||
|
`${event.guild?.member.displayName} clic`,
|
||||||
|
)
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
<Button
|
<Button
|
||||||
label="clic"
|
label="clic"
|
||||||
|
|||||||
10
todo.md
10
todo.md
@@ -24,11 +24,11 @@
|
|||||||
- component events
|
- component events
|
||||||
- [x] reply / send functions
|
- [x] reply / send functions
|
||||||
- [x] select values
|
- [x] select values
|
||||||
- [ ] message.\*
|
- [x] message.\*
|
||||||
- [ ] channel.\*
|
- [x] channel.\*
|
||||||
- [ ] guild.\*
|
- [x] guild.\*
|
||||||
- [ ] guild.member.\*
|
- [x] guild.member.\*
|
||||||
- [ ] user.\*
|
- [x] user.\*
|
||||||
- [x] deactivate
|
- [x] deactivate
|
||||||
- [x] destroy
|
- [x] destroy
|
||||||
- [ ] docs
|
- [ ] docs
|
||||||
|
|||||||
Reference in New Issue
Block a user