mirror of
https://github.com/tiramisulabs/seyfert.git
synced 2025-07-03 05:26:07 +00:00
feat: StageInstance
This commit is contained in:
parent
a2ca96f86b
commit
adc41c88f7
2
mod.ts
2
mod.ts
@ -13,12 +13,14 @@ export * from "./structures/WelcomeChannel.ts";
|
||||
export * from "./structures/WelcomeScreen.ts";
|
||||
|
||||
export * from "./structures/channels/BaseChannel.ts";
|
||||
export * from "./structures/channels/BaseVoiceChannel.ts";
|
||||
export * from "./structures/channels/ChannelFactory.ts";
|
||||
export * from "./structures/channels/DMChannel.ts";
|
||||
export * from "./structures/channels/GuildChannel.ts";
|
||||
export * from "./structures/channels/NewsChannel.ts";
|
||||
export * from "./structures/channels/TextChannel.ts";
|
||||
export * from "./structures/channels/ThreadChannel.ts";
|
||||
export * from "./structures/channels/StageChannel.ts";
|
||||
export * from "./structures/channels/VoiceChannel.ts";
|
||||
|
||||
export * from "./structures/components/ActionRowComponent.ts";
|
||||
|
61
structures/StageInstance.ts
Normal file
61
structures/StageInstance.ts
Normal file
@ -0,0 +1,61 @@
|
||||
import type { Model } from "./Base.ts";
|
||||
import type { Session } from "../session/Session.ts";
|
||||
import type { Snowflake } from "../util/Snowflake.ts";
|
||||
import type { DiscordStageInstance as DiscordAutoClosingStageInstance } from "../vendor/external.ts";
|
||||
import * as Routes from "../util/Routes.ts";
|
||||
|
||||
interface DiscordStageInstance extends DiscordAutoClosingStageInstance {
|
||||
privacy_level: PrivacyLevels;
|
||||
discoverable_disabled: boolean;
|
||||
guild_scheduled_event_id: Snowflake;
|
||||
}
|
||||
|
||||
export enum PrivacyLevels {
|
||||
Public = 1,
|
||||
GuildOnly = 2,
|
||||
}
|
||||
|
||||
export class StageInstance implements Model {
|
||||
constructor(session: Session, data: DiscordStageInstance) {
|
||||
this.session = session;
|
||||
this.id = data.id;
|
||||
this.channelId = data.channel_id;
|
||||
this.guildId = data.guild_id;
|
||||
this.topic = data.topic;
|
||||
this.privacyLevel = data.privacy_level;
|
||||
this.discoverableDisabled = data.discoverable_disabled;
|
||||
this.guildScheduledEventId = data.guild_scheduled_event_id;
|
||||
}
|
||||
|
||||
readonly session: Session;
|
||||
readonly id: Snowflake;
|
||||
|
||||
channelId: Snowflake;
|
||||
guildId: Snowflake;
|
||||
topic: string;
|
||||
|
||||
// TODO: see if this works
|
||||
privacyLevel: PrivacyLevels;
|
||||
discoverableDisabled: boolean;
|
||||
guildScheduledEventId: Snowflake;
|
||||
|
||||
async edit(options: { topic?: string, privacyLevel?: PrivacyLevels }) {
|
||||
const stageInstance = await this.session.rest.runMethod<DiscordStageInstance>(
|
||||
this.session.rest,
|
||||
"PATCH",
|
||||
Routes.STAGE_INSTANCE(this.id),
|
||||
{
|
||||
topic: options.topic,
|
||||
privacy_level: options.privacyLevel
|
||||
}
|
||||
);
|
||||
|
||||
return new StageInstance(this.session, stageInstance);
|
||||
}
|
||||
|
||||
async delete() {
|
||||
await this.session.rest.runMethod<undefined>(this.session.rest, "DELETE", Routes.STAGE_INSTANCE(this.id));
|
||||
}
|
||||
}
|
||||
|
||||
export default StageInstance;
|
62
structures/channels/BaseVoiceChannel.ts
Normal file
62
structures/channels/BaseVoiceChannel.ts
Normal file
@ -0,0 +1,62 @@
|
||||
import type { Snowflake } from "../../util/Snowflake.ts";
|
||||
import type { Session } from "../../session/Session.ts";
|
||||
import type { ChannelTypes, DiscordChannel, VideoQualityModes } from "../../vendor/external.ts";
|
||||
import { GatewayOpcodes } from "../../vendor/external.ts";
|
||||
import { calculateShardId } from "../../vendor/gateway/calculateShardId.ts";
|
||||
import GuildChannel from "./GuildChannel.ts";
|
||||
|
||||
/**
|
||||
* @link https://discord.com/developers/docs/topics/gateway#update-voice-state
|
||||
*/
|
||||
export interface UpdateVoiceState {
|
||||
guildId: string;
|
||||
channelId?: string;
|
||||
selfMute: boolean;
|
||||
selfDeaf: boolean;
|
||||
}
|
||||
|
||||
export abstract class BaseVoiceChannel extends GuildChannel {
|
||||
constructor(session: Session, data: DiscordChannel, guildId: Snowflake) {
|
||||
super(session, data, guildId);
|
||||
this.bitRate = data.bitrate;
|
||||
this.userLimit = data.user_limit ?? 0;
|
||||
this.videoQuality = data.video_quality_mode;
|
||||
this.nsfw = !!data.nsfw;
|
||||
this.type = data.type as number;
|
||||
|
||||
if (data.rtc_region) {
|
||||
this.rtcRegion = data.rtc_region;
|
||||
}
|
||||
}
|
||||
override type: ChannelTypes.GuildVoice | ChannelTypes.GuildStageVoice;
|
||||
bitRate?: number;
|
||||
userLimit: number;
|
||||
rtcRegion?: Snowflake;
|
||||
|
||||
videoQuality?: VideoQualityModes;
|
||||
nsfw: boolean;
|
||||
|
||||
/**
|
||||
* This function was gathered from Discordeno it may not work
|
||||
*/
|
||||
async connect(options?: UpdateVoiceState) {
|
||||
const shardId = calculateShardId(this.session.gateway, BigInt(super.guildId));
|
||||
const shard = this.session.gateway.manager.shards.get(shardId);
|
||||
|
||||
if (!shard) {
|
||||
throw new Error(`Shard (id: ${shardId} not found`);
|
||||
}
|
||||
|
||||
await shard.send({
|
||||
op: GatewayOpcodes.VoiceStateUpdate,
|
||||
d: {
|
||||
guild_id: super.guildId,
|
||||
channel_id: super.id,
|
||||
self_mute: Boolean(options?.selfMute),
|
||||
self_deaf: options?.selfDeaf ?? true,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export default BaseVoiceChannel;
|
@ -7,13 +7,15 @@ import VoiceChannel from "./VoiceChannel.ts";
|
||||
import DMChannel from "./DMChannel.ts";
|
||||
import NewsChannel from "./NewsChannel.ts";
|
||||
import ThreadChannel from "./ThreadChannel.ts";
|
||||
import StageChannel from "./StageChannel.ts";
|
||||
|
||||
export type Channel =
|
||||
| TextChannel
|
||||
| VoiceChannel
|
||||
| DMChannel
|
||||
| NewsChannel
|
||||
| ThreadChannel;
|
||||
| ThreadChannel
|
||||
| StageChannel;
|
||||
|
||||
export class ChannelFactory {
|
||||
static from(session: Session, channel: DiscordChannel): Channel {
|
||||
@ -27,6 +29,8 @@ export class ChannelFactory {
|
||||
return new DMChannel(session, channel);
|
||||
case ChannelTypes.GuildVoice:
|
||||
return new VoiceChannel(session, channel, channel.guild_id!);
|
||||
case ChannelTypes.GuildStageVoice:
|
||||
return new StageChannel(session, channel, channel.guild_id!);
|
||||
default:
|
||||
if (textBasedChannels.includes(channel.type)) {
|
||||
return new TextChannel(session, channel);
|
||||
|
16
structures/channels/StageChannel.ts
Normal file
16
structures/channels/StageChannel.ts
Normal file
@ -0,0 +1,16 @@
|
||||
import type { Snowflake } from "../../util/Snowflake.ts";
|
||||
import type { Session } from "../../session/Session.ts";
|
||||
import type { ChannelTypes, DiscordChannel } from "../../vendor/external.ts";
|
||||
import BaseVoiceChannel from "./BaseVoiceChannel.ts";
|
||||
|
||||
export class StageChannel extends BaseVoiceChannel {
|
||||
constructor(session: Session, data: DiscordChannel, guildId: Snowflake) {
|
||||
super(session, data, guildId);
|
||||
this.type = data.type as number;
|
||||
this.topic = data.topic ? data.topic : undefined;
|
||||
}
|
||||
override type: ChannelTypes.GuildStageVoice;
|
||||
topic?: string;
|
||||
}
|
||||
|
||||
export default StageChannel;
|
@ -44,6 +44,7 @@ export const textBasedChannels = [
|
||||
ChannelTypes.GuildPrivateThread,
|
||||
ChannelTypes.GuildPublicThread,
|
||||
ChannelTypes.GuildNews,
|
||||
ChannelTypes.GuildVoice,
|
||||
ChannelTypes.GuildText,
|
||||
];
|
||||
|
||||
@ -53,6 +54,7 @@ export type TextBasedChannels =
|
||||
| ChannelTypes.GuildPrivateThread
|
||||
| ChannelTypes.GuildPublicThread
|
||||
| ChannelTypes.GuildNews
|
||||
| ChannelTypes.GuildVoice
|
||||
| ChannelTypes.GuildText;
|
||||
|
||||
export class TextChannel {
|
||||
@ -85,21 +87,28 @@ export class TextChannel {
|
||||
/**
|
||||
* Mixin
|
||||
*/
|
||||
static applyTo(klass: Function) {
|
||||
klass.prototype.fetchPins = TextChannel.prototype.fetchPins;
|
||||
klass.prototype.createInvite = TextChannel.prototype.createInvite;
|
||||
klass.prototype.fetchMessages = TextChannel.prototype.fetchMessages;
|
||||
klass.prototype.sendTyping = TextChannel.prototype.sendTyping;
|
||||
klass.prototype.pinMessage = TextChannel.prototype.pinMessage;
|
||||
klass.prototype.unpinMessage = TextChannel.prototype.unpinMessage;
|
||||
klass.prototype.addReaction = TextChannel.prototype.addReaction;
|
||||
klass.prototype.removeReaction = TextChannel.prototype.removeReaction;
|
||||
klass.prototype.removeReactionEmoji = TextChannel.prototype.removeReactionEmoji;
|
||||
klass.prototype.nukeReactions = TextChannel.prototype.nukeReactions;
|
||||
klass.prototype.fetchReactions = TextChannel.prototype.fetchReactions;
|
||||
klass.prototype.sendMessage = TextChannel.prototype.sendMessage;
|
||||
klass.prototype.editMessage = TextChannel.prototype.editMessage;
|
||||
klass.prototype.createWebhook = TextChannel.prototype.createWebhook;
|
||||
static applyTo(klass: Function, ignore: Array<keyof TextChannel> = []) {
|
||||
const methods: Array<keyof TextChannel> = [
|
||||
"fetchPins",
|
||||
"createInvite",
|
||||
"fetchMessages",
|
||||
"sendTyping",
|
||||
"pinMessage",
|
||||
"unpinMessage",
|
||||
"addReaction",
|
||||
"removeReaction",
|
||||
"nukeReactions",
|
||||
"fetchPins",
|
||||
"sendMessage",
|
||||
"editMessage",
|
||||
"createWebhook",
|
||||
];
|
||||
|
||||
for (const method of methods) {
|
||||
if (ignore.includes(method)) continue;
|
||||
|
||||
klass.prototype[method] = TextChannel.prototype[method];
|
||||
}
|
||||
}
|
||||
|
||||
async fetchPins(): Promise<Message[] | []> {
|
||||
|
@ -1,60 +1,19 @@
|
||||
import type { Snowflake } from "../../util/Snowflake.ts";
|
||||
import type { Session } from "../../session/Session.ts";
|
||||
import type { DiscordChannel, VideoQualityModes } from "../../vendor/external.ts";
|
||||
import { GatewayOpcodes } from "../../vendor/external.ts";
|
||||
import { calculateShardId } from "../../vendor/gateway/calculateShardId.ts";
|
||||
import GuildChannel from "./GuildChannel.ts";
|
||||
import type { ChannelTypes, DiscordChannel } from "../../vendor/external.ts";
|
||||
import BaseVoiceChannel from "./BaseVoiceChannel.ts";
|
||||
import TextChannel from "./TextChannel.ts";
|
||||
|
||||
/**
|
||||
* @link https://discord.com/developers/docs/topics/gateway#update-voice-state
|
||||
*/
|
||||
export interface UpdateVoiceState {
|
||||
guildId: string;
|
||||
channelId?: string;
|
||||
selfMute: boolean;
|
||||
selfDeaf: boolean;
|
||||
}
|
||||
|
||||
export class VoiceChannel extends GuildChannel {
|
||||
export class VoiceChannel extends BaseVoiceChannel {
|
||||
constructor(session: Session, data: DiscordChannel, guildId: Snowflake) {
|
||||
super(session, data, guildId);
|
||||
this.bitRate = data.bitrate;
|
||||
this.userLimit = data.user_limit ?? 0;
|
||||
this.videoQuality = data.video_quality_mode;
|
||||
this.nsfw = !!data.nsfw;
|
||||
|
||||
if (data.rtc_region) {
|
||||
this.rtcRegion = data.rtc_region;
|
||||
this.type = data.type as number;
|
||||
}
|
||||
}
|
||||
bitRate?: number;
|
||||
userLimit: number;
|
||||
rtcRegion?: Snowflake;
|
||||
|
||||
videoQuality?: VideoQualityModes;
|
||||
nsfw: boolean;
|
||||
|
||||
/**
|
||||
* This function was gathered from Discordeno it may not work
|
||||
*/
|
||||
async connect(options?: UpdateVoiceState) {
|
||||
const shardId = calculateShardId(this.session.gateway, BigInt(super.guildId));
|
||||
const shard = this.session.gateway.manager.shards.get(shardId);
|
||||
|
||||
if (!shard) {
|
||||
throw new Error(`Shard (id: ${shardId} not found`);
|
||||
override type: ChannelTypes.GuildVoice;
|
||||
}
|
||||
|
||||
await shard.send({
|
||||
op: GatewayOpcodes.VoiceStateUpdate,
|
||||
d: {
|
||||
guild_id: super.guildId,
|
||||
channel_id: super.id,
|
||||
self_mute: Boolean(options?.selfMute),
|
||||
self_deaf: options?.selfDeaf ?? true,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
export interface VoiceChannel extends TextChannel, BaseVoiceChannel {}
|
||||
|
||||
TextChannel.applyTo(VoiceChannel);
|
||||
|
||||
export default VoiceChannel;
|
||||
|
@ -128,7 +128,7 @@ export interface GuildCreateOptionsChannel {
|
||||
nsfw?: boolean;
|
||||
bitrate?: number;
|
||||
userLimit?: number;
|
||||
region?: string | null;
|
||||
rtcRegion?: string | null;
|
||||
videoQualityMode?: VideoQualityModes;
|
||||
permissionOverwrites?: MakeRequired<Partial<DiscordOverwrite>, "id">[];
|
||||
rateLimitPerUser?: number;
|
||||
@ -527,7 +527,7 @@ export class Guild extends BaseGuild implements Model {
|
||||
bitrate: channel.bitrate,
|
||||
parent_id: channel.parentId,
|
||||
permission_overwrites: channel.permissionOverwrites,
|
||||
region: channel.region,
|
||||
rtc_region: channel.rtcRegion,
|
||||
user_limit: channel.userLimit,
|
||||
video_quality_mode: channel.videoQualityMode,
|
||||
rate_limit_per_user: channel.rateLimitPerUser,
|
||||
|
@ -303,3 +303,11 @@ export function THREAD_ARCHIVED_PRIVATE_JOINED(channelId: Snowflake, options?: L
|
||||
export function FORUM_START(channelId: Snowflake) {
|
||||
return `/channels/${channelId}/threads?has_message=true`;
|
||||
}
|
||||
|
||||
export function STAGE_INSTANCES() {
|
||||
return `/stage-instances`;
|
||||
}
|
||||
|
||||
export function STAGE_INSTANCE(channelId: Snowflake) {
|
||||
return `/stage-instances/${channelId}`;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user