This commit is contained in:
tungdo0602
2025-06-29 12:56:55 +07:00
parent 1aa4f523ad
commit 767b72182e
8 changed files with 144 additions and 7 deletions

View File

@@ -5,16 +5,39 @@ const { MessageComponentTypes } = require('../util/Constants');
class ContainerComponent extends BaseMessageComponent { class ContainerComponent extends BaseMessageComponent {
/** /**
* * @typedef {MessageActionRow|TextDisplayComponent|SectionComponent|MediaGalleryComponent|SeparatorComponent|FileComponent} ContainerComponents
* @param {*} data * @property {ContainerComponents[]} [components] Components of the type action row, text display, section, media gallery, separator, or file
* @property {Number} [accent_color] Color for the accent on the container as RGB from 0x000000 to 0xFFFFFF
* @property {Boolean} [spoiler] Whether the container should be a spoiler (or blurred out). Defaults to false.
*/
/**
* @param {} [data={}]
*/ */
constructor(data = {}) { constructor(data = {}) {
super({ type: 'CONTAINER' }, data); super({ type: 'CONTAINER' }, data);
/**
* Components of the type action row, text display, section, media gallery, separator, or file
* @type {ContainerComponents[]}
*/
this.components = data.components?.map(c => BaseMessageComponent.create(c)) ?? null; this.components = data.components?.map(c => BaseMessageComponent.create(c)) ?? null;
/**
* Color for the accent on the container as RGB from 0x000000 to 0xFFFFFF
* @type {Number}
*/
this.accent_color = data.accent_color ?? null; this.accent_color = data.accent_color ?? null;
/**
* Whether the container should be a spoiler (or blurred out). Defaults to false.
* @type {Boolean}
*/
this.spoiler = data.spoiler ?? false; this.spoiler = data.spoiler ?? false;
} }
/**
* @returns {APIContainerComponent}
*/
toJSON() { toJSON() {
return { return {
type: MessageComponentTypes[this.type], type: MessageComponentTypes[this.type],

View File

@@ -4,13 +4,36 @@ const BaseMessageComponent = require('./BaseMessageComponent');
const UnfurledMediaItem = require('./UnfurledMediaItem'); const UnfurledMediaItem = require('./UnfurledMediaItem');
const { MessageComponentTypes } = require('../util/Constants'); const { MessageComponentTypes } = require('../util/Constants');
class FileComponent extends BaseMessageComponent { class FileComponent extends BaseMessageComponent {
/**
* @property {UnfurledMediaItem} [file] This unfurled media item is unique in that it only supports attachment references using the attachment://<filename> syntax
* @property {Boolean} [spoiler] Whether the container should be a spoiler (or blurred out). Defaults to false.
*/
/**
* @param {} [data={}]
*/
constructor(data = {}) { constructor(data = {}) {
super({ type: 'FILE' }, data); super({ type: 'FILE' }, data);
/**
* This unfurled media item is unique in that it only supports attachment references using the attachment://<filename> syntax
* @type {UnfurledMediaItem}
*/
this.file = new UnfurledMediaItem(data.file) ?? null; this.file = new UnfurledMediaItem(data.file) ?? null;
/**
* Whether the container should be a spoiler (or blurred out). Defaults to false.
* @type {Boolean}
*/
this.spoiler = data.spoiler ?? false; this.spoiler = data.spoiler ?? false;
} }
/**
* @returns {APIFileComponent}
*/
toJSON() { toJSON() {
return { return {
type: MessageComponentTypes[this.type], type: MessageComponentTypes[this.type],

View File

@@ -5,11 +5,26 @@ const MediaGalleryItem = require('./MediaGalleryItem');
const { MessageComponentTypes } = require('../util/Constants'); const { MessageComponentTypes } = require('../util/Constants');
class MediaGalleryComponent extends BaseMessageComponent { class MediaGalleryComponent extends BaseMessageComponent {
/**
* @property {MediaGalleryItem[]} [items] 1 to 10 media gallery items
*/
/**
* @param {} [data={}]
*/
constructor(data = {}) { constructor(data = {}) {
super({ type: 'MEDIA_GALLERY' }, data); super({ type: 'MEDIA_GALLERY' }, data);
/**
* 1 to 10 media gallery items
* @type {MediaGalleryItem[]}
*/
this.items = data.items?.map(item => new MediaGalleryItem(item)) ?? []; this.items = data.items?.map(item => new MediaGalleryItem(item)) ?? [];
} }
/**
* @returns {APIMediaGalleryComponent}
*/
toJSON() { toJSON() {
return { return {
type: MessageComponentTypes[this.type], type: MessageComponentTypes[this.type],

View File

@@ -3,12 +3,38 @@
const UnfurledMediaItem = require('./UnfurledMediaItem'); const UnfurledMediaItem = require('./UnfurledMediaItem');
class MediaGalleryItem { class MediaGalleryItem {
/**
* @property {UnfurledMediaItem} [media] A url or attachment
* @property {String} [description] Alt text for the media, max 1024 characters
* @property {Boolean} [spoiler] Whether the media should be a spoiler (or blurred out). Defaults to false
*/
/**
* @param {} [data={}]
*/
constructor(data = {}) { constructor(data = {}) {
/**
* A url or attachment
* @type {UnfurledMediaItem}
*/
this.media = new UnfurledMediaItem(data.media); this.media = new UnfurledMediaItem(data.media);
/**
* Alt text for the media, max 1024 characters
* @type {String}
*/
this.description = data.description ?? null; this.description = data.description ?? null;
/**
* Whether the media should be a spoiler (or blurred out). Defaults to false
* @type {Boolean}
*/
this.spoiler = data.spoiler ?? false; this.spoiler = data.spoiler ?? false;
} }
/**
* @returns {APIMediaGalleryItem}
*/
toJSON() { toJSON() {
return { return {
media: this.media.toJSON(), media: this.media.toJSON(),

View File

@@ -1,16 +1,36 @@
'use strict'; 'use strict';
const BaseMessageComponent = require('./BaseMessageComponent'); const BaseMessageComponent = require('./BaseMessageComponent');
const { TextDisplayComponent } = require('./TextDisplayComponent');
const { MessageComponentTypes } = require('../util/Constants'); const { MessageComponentTypes } = require('../util/Constants');
class SectionComponent extends BaseMessageComponent { class SectionComponent extends BaseMessageComponent {
/**
* @property {TextDisplayComponent[]} [components] One to three text components
* @property {ThumbnailComponent|MessageButton} [accessory] A thumbnail or a button component, with a future possibility of adding more compatible components
*/
/**
* @param {} [data={}]
*/
constructor(data = {}) { constructor(data = {}) {
super({ type: 'SECTION' }, data); super({ type: 'SECTION' }, data);
/**
* One to three text components
* @type {TextDisplayComponent[]}
*/
this.components = data.components?.map(c => BaseMessageComponent.create(c)) ?? []; this.components = data.components?.map(c => BaseMessageComponent.create(c)) ?? [];
/**
* A thumbnail or a button component, with a future possibility of adding more compatible components
* @type {ThumbnailComponent|MessageButton}
*/
this.accessory = BaseMessageComponent.create(data.accessory) ?? null; this.accessory = BaseMessageComponent.create(data.accessory) ?? null;
} }
/**
* @returns {APISectionComponent}
*/
toJSON() { toJSON() {
return { return {
type: MessageComponentTypes[this.type], type: MessageComponentTypes[this.type],

View File

@@ -4,12 +4,33 @@ const BaseMessageComponent = require('./BaseMessageComponent');
const { MessageComponentTypes, SeparatorSpacingSizes } = require('../util/Constants'); const { MessageComponentTypes, SeparatorSpacingSizes } = require('../util/Constants');
class SeparatorComponent extends BaseMessageComponent { class SeparatorComponent extends BaseMessageComponent {
/**
* @property {SeparatorSpacingSizes} [spacing] Size of separator padding — SeparatorSpacingSizes.SMALL for small padding, SeparatorSpacingSizes.LARGE for large padding. Defaults to SeparatorSpacingSizes.SMALL
* @property {Boolean} [divider] Whether a visual divider should be displayed in the component. Defaults to true
*/
/**
* @param {} [data={}]
*/
constructor(data = {}) { constructor(data = {}) {
super({ type: 'SEPARATOR' }, data); super({ type: 'SEPARATOR' }, data);
/**
* Size of separator padding — SeparatorSpacingSizes.SMALL for small padding, SeparatorSpacingSizes.LARGE for large padding. Defaults to SeparatorSpacingSizes.SMALL
* @type {SeparatorSpacingSizes}
*/
this.spacing = data.spacing ?? SeparatorSpacingSizes.SMALL; this.spacing = data.spacing ?? SeparatorSpacingSizes.SMALL;
/**
* Whether a visual divider should be displayed in the component. Defaults to true
* @type {Boolean}
*/
this.divider = data.divider ?? true; this.divider = data.divider ?? true;
} }
/**
* @returns {APISeparatorComponent}
*/
toJSON() { toJSON() {
return { return {
type: MessageComponentTypes[this.type], type: MessageComponentTypes[this.type],

View File

@@ -2,8 +2,7 @@
class UnfurledMediaItem { class UnfurledMediaItem {
/** /**
* * @property {string} [url] Supports arbitrary urls and `attachment://<filename>` references
* @param {*} data
*/ */
constructor(data = {}) { constructor(data = {}) {
/** /**

View File

@@ -88,13 +88,14 @@ import {
GuildFeature, GuildFeature,
LocalizationMap, LocalizationMap,
} from 'discord-api-types/v10'; } from 'discord-api-types/v10';
import { GuildChannel, Guild, PermissionOverwrites } from '.'; import { GuildChannel, Guild, PermissionOverwrites, MessageActionRow } from '.';
import type { import type {
AutoModerationActionTypes, AutoModerationActionTypes,
AutoModerationRuleEventTypes, AutoModerationRuleEventTypes,
AutoModerationRuleKeywordPresetTypes, AutoModerationRuleKeywordPresetTypes,
AutoModerationRuleTriggerTypes, AutoModerationRuleTriggerTypes,
ApplicationRoleConnectionMetadataTypes, ApplicationRoleConnectionMetadataTypes,
MessageComponentTypes,
} from './enums'; } from './enums';
export type RawActivityData = GatewayActivity; export type RawActivityData = GatewayActivity;
@@ -341,6 +342,15 @@ export interface APIApplicationRoleConnectionMetadata {
description_localizations?: LocalizationMap; description_localizations?: LocalizationMap;
} }
export interface APIBaseComponent<T extends MessageComponentTypes> {
type: T;
id?: Number;
}
export interface APIUnfurledMediaItem { export interface APIUnfurledMediaItem {
url: String; url: String;
} }
export interface APIContainerComponent extends APIBaseComponent<MessageComponentTypes.CONTAINER> {
components: MessageActionRow
}