refactor: channels

This commit is contained in:
Yuzu 2022-07-02 08:52:54 -05:00
parent 484ed2c0f7
commit 36acf92ad1
4 changed files with 123 additions and 8 deletions

View File

@ -1,14 +1,24 @@
import type { import type {
DiscordChannel,
DiscordChannelPinsUpdate,
DiscordGuildMemberAdd, DiscordGuildMemberAdd,
DiscordGuildMemberRemove, DiscordGuildMemberRemove,
DiscordGuildMemberUpdate, DiscordGuildMemberUpdate,
DiscordInteraction, DiscordInteraction,
DiscordMemberWithUser,
DiscordMessage, DiscordMessage,
DiscordMessageDelete, DiscordMessageDelete,
DiscordReady, DiscordReady,
// DiscordThreadMemberUpdate,
// DiscordThreadMembersUpdate,
DiscordThreadListSync,
} from "../vendor/external.ts"; } from "../vendor/external.ts";
import type { Snowflake } from "../util/Snowflake.ts"; import type { Snowflake } from "../util/Snowflake.ts";
import type { Session } from "../session/Session.ts"; import type { Session } from "../session/Session.ts";
import type { Channel } from "../structures/BaseChannel.ts";
import BaseChannel from "../structures/BaseChannel.ts";
import GuildChannel from "../structures/GuildChannel.ts";
import ThreadChannel from "../structures/ThreadChannel.ts";
import Member from "../structures/Member.ts"; import Member from "../structures/Member.ts";
import Message from "../structures/Message.ts"; import Message from "../structures/Message.ts";
import User from "../structures/User.ts"; import User from "../structures/User.ts";
@ -56,6 +66,56 @@ export const INTERACTION_CREATE: RawHandler<DiscordInteraction> = (session, _sha
session.emit("interactionCreate", new Interaction(session, interaction)); session.emit("interactionCreate", new Interaction(session, interaction));
}; };
export const CHANNEL_CREATE: RawHandler<DiscordChannel> = (session, _shardId, channel) => {
session.emit("channelCreate", BaseChannel.from(session, channel));
};
export const CHANNEL_UPDATE: RawHandler<DiscordChannel> = (session, _shardId, channel) => {
session.emit("channelUpdate", BaseChannel.from(session, channel));
};
export const CHANNEL_DELETE: RawHandler<DiscordChannel> = (session, _shardId, channel) => {
if (!channel.guild_id) return;
session.emit("channelDelete", new GuildChannel(session, channel, channel.guild_id));
};
export const THREAD_CREATE: RawHandler<DiscordChannel> = (session, _shardId, channel) => {
if (!channel.guild_id) return;
session.emit("threadCreate", new ThreadChannel(session, channel, channel.guild_id));
};
export const THREAD_UPDATE: RawHandler<DiscordChannel> = (session, _shardId, channel) => {
if (!channel.guild_id) return;
session.emit("threadUpdate", new ThreadChannel(session, channel, channel.guild_id));
};
export const THREAD_DELETE: RawHandler<DiscordChannel> = (session, _shardId, channel) => {
if (!channel.guild_id) return;
session.emit("threadDelete", new ThreadChannel(session, channel, channel.guild_id));
};
export const THREAD_LIST_SYNC: RawHandler<DiscordThreadListSync> = (session, _shardId, payload) => {
session.emit("threadListSync", {
guildId: payload.guild_id,
channelIds: payload.channel_ids ?? [],
threads: payload.threads.map((channel) => new ThreadChannel(session, channel, payload.guild_id)),
// @ts-ignore: TODO: thread member structure
members: payload.members.map((member) => new Member(session, member as DiscordMemberWithUser, payload.guild_id)),
});
};
export const CHANNEL_PINS_UPDATE: RawHandler<DiscordChannelPinsUpdate> = (session, _shardId, payload) => {
session.emit("channelPinsUpdate", {
guildId: payload.guild_id,
channelId: payload.channel_id,
lastPinTimestamp: payload.last_pin_timestamp ? Date.parse(payload.last_pin_timestamp) : undefined,
});
};
export const raw: RawHandler<unknown> = (session, shardId, data) => { export const raw: RawHandler<unknown> = (session, shardId, data) => {
session.emit("raw", data, shardId); session.emit("raw", data, shardId);
}; };
@ -73,6 +133,14 @@ export interface Events {
"guildMemberAdd": Handler<[Member]>; "guildMemberAdd": Handler<[Member]>;
"guildMemberUpdate": Handler<[Member]>; "guildMemberUpdate": Handler<[Member]>;
"guildMemberRemove": Handler<[User, Snowflake]>; "guildMemberRemove": Handler<[User, Snowflake]>;
"channelCreate": Handler<[Channel]>;
"channelUpdate": Handler<[Channel]>;
"channelDelete": Handler<[GuildChannel]>;
"channelPinsUpdate": Handler<[{ guildId?: Snowflake, channelId: Snowflake, lastPinTimestamp?: number }]>
"threadCreate": Handler<[ThreadChannel]>;
"threadUpdate": Handler<[ThreadChannel]>;
"threadDelete": Handler<[ThreadChannel]>;
"threadListSync": Handler<[{ guildId: Snowflake, channelIds: Snowflake[], threads: ThreadChannel[], members: Member[] }]>
"interactionCreate": Handler<[Interaction]>; "interactionCreate": Handler<[Interaction]>;
"raw": Handler<[unknown, number]>; "raw": Handler<[unknown, number]>;
} }

View File

@ -1,13 +1,21 @@
import type { Model } from "./Base.ts"; import type { Model } from "./Base.ts";
import type { Snowflake } from "../util/Snowflake.ts"; import type { Snowflake } from "../util/Snowflake.ts";
import type { Session } from "../session/Session.ts"; import type { Session } from "../session/Session.ts";
import type { ChannelTypes, DiscordChannel } from "../vendor/external.ts"; import type { DiscordChannel } from "../vendor/external.ts";
import TextChannel from "./TextChannel.ts"; import { ChannelTypes } from "../vendor/external.ts";
import TextChannel, { textBasedChannels } from "./TextChannel.ts";
import VoiceChannel from "./VoiceChannel.ts"; import VoiceChannel from "./VoiceChannel.ts";
import DMChannel from "./DMChannel.ts"; import DMChannel from "./DMChannel.ts";
import NewsChannel from "./NewsChannel.ts"; import NewsChannel from "./NewsChannel.ts";
import ThreadChannel from "./ThreadChannel.ts"; import ThreadChannel from "./ThreadChannel.ts";
export type Channel =
| TextChannel
| VoiceChannel
| DMChannel
| NewsChannel
| ThreadChannel;
export abstract class BaseChannel implements Model { export abstract class BaseChannel implements Model {
constructor(session: Session, data: DiscordChannel) { constructor(session: Session, data: DiscordChannel) {
this.id = data.id; this.id = data.id;
@ -22,23 +30,42 @@ export abstract class BaseChannel implements Model {
type: ChannelTypes; type: ChannelTypes;
isText(): this is TextChannel { isText(): this is TextChannel {
return this instanceof TextChannel; return textBasedChannels.includes(this.type);
} }
isVoice(): this is VoiceChannel { isVoice(): this is VoiceChannel {
return this instanceof VoiceChannel; return this.type === ChannelTypes.GuildVoice;
} }
isDM(): this is DMChannel { isDM(): this is DMChannel {
return this instanceof DMChannel; return this.type === ChannelTypes.DM;
} }
isNews(): this is NewsChannel { isNews(): this is NewsChannel {
return this instanceof NewsChannel; return this.type === ChannelTypes.GuildNews;
} }
isThread(): this is ThreadChannel { isThread(): this is ThreadChannel {
return this instanceof ThreadChannel; return this.type === ChannelTypes.GuildPublicThread || this.type === ChannelTypes.GuildPrivateThread;
}
static from(session: Session, channel: DiscordChannel): Channel {
switch (channel.type) {
case ChannelTypes.GuildPublicThread:
case ChannelTypes.GuildPrivateThread:
return new ThreadChannel(session, channel, channel.guild_id!);
case ChannelTypes.GuildNews:
return new NewsChannel(session, channel, channel.guild_id!);
case ChannelTypes.DM:
return new DMChannel(session, channel);
case ChannelTypes.GuildVoice:
return new VoiceChannel(session, channel, channel.guild_id!);
default:
if (textBasedChannels.includes(channel.type)) {
return new TextChannel(session, channel, channel.guild_id!);
}
throw new Error("Channel was not implemented");
}
} }
toString(): string { toString(): string {

View File

@ -6,7 +6,7 @@ import BaseChannel from "./BaseChannel.ts";
import Invite from "./Invite.ts"; import Invite from "./Invite.ts";
import * as Routes from "../util/Routes.ts"; import * as Routes from "../util/Routes.ts";
export abstract class GuildChannel extends BaseChannel implements Model { export class GuildChannel extends BaseChannel implements Model {
constructor(session: Session, data: DiscordChannel, guildId: Snowflake) { constructor(session: Session, data: DiscordChannel, guildId: Snowflake) {
super(session, data); super(session, data);
this.guildId = guildId; this.guildId = guildId;

View File

@ -3,6 +3,7 @@ import type { Snowflake } from "../util/Snowflake.ts";
import type { GetMessagesOptions, GetReactions } from "../util/Routes.ts"; import type { GetMessagesOptions, GetReactions } from "../util/Routes.ts";
import type { DiscordChannel, DiscordInvite, DiscordMessage, TargetTypes } from "../vendor/external.ts"; import type { DiscordChannel, DiscordInvite, DiscordMessage, TargetTypes } from "../vendor/external.ts";
import type { CreateMessage, EditMessage, ReactionResolvable } from "./Message.ts"; import type { CreateMessage, EditMessage, ReactionResolvable } from "./Message.ts";
import { ChannelTypes } from "../vendor/external.ts";
import GuildChannel from "./GuildChannel.ts"; import GuildChannel from "./GuildChannel.ts";
import ThreadChannel from "./ThreadChannel.ts"; import ThreadChannel from "./ThreadChannel.ts";
import Message from "./Message.ts"; import Message from "./Message.ts";
@ -36,15 +37,34 @@ export interface ThreadCreateOptions {
reason?: string; reason?: string;
} }
export const textBasedChannels = [
ChannelTypes.DM,
ChannelTypes.GroupDm,
ChannelTypes.GuildPrivateThread,
ChannelTypes.GuildPublicThread,
ChannelTypes.GuildNews,
ChannelTypes.GuildText,
];
export type TextBasedChannels =
| ChannelTypes.DM
| ChannelTypes.GroupDm
| ChannelTypes.GuildPrivateThread
| ChannelTypes.GuildPublicThread
| ChannelTypes.GuildNews
| ChannelTypes.GuildText;
export class TextChannel extends GuildChannel { export class TextChannel extends GuildChannel {
constructor(session: Session, data: DiscordChannel, guildId: Snowflake) { constructor(session: Session, data: DiscordChannel, guildId: Snowflake) {
super(session, data, guildId); super(session, data, guildId);
data.last_message_id ? this.lastMessageId = data.last_message_id : undefined; data.last_message_id ? this.lastMessageId = data.last_message_id : undefined;
data.last_pin_timestamp ? this.lastPinTimestamp = data.last_pin_timestamp : undefined; data.last_pin_timestamp ? this.lastPinTimestamp = data.last_pin_timestamp : undefined;
this.type = data.type as TextBasedChannels;
this.rateLimitPerUser = data.rate_limit_per_user ?? 0; this.rateLimitPerUser = data.rate_limit_per_user ?? 0;
this.nsfw = !!data.nsfw ?? false; this.nsfw = !!data.nsfw ?? false;
} }
override type: TextBasedChannels;
lastMessageId?: Snowflake; lastMessageId?: Snowflake;
lastPinTimestamp?: string; lastPinTimestamp?: string;
rateLimitPerUser: number; rateLimitPerUser: number;