discord-types: update & add types (#4052)

Co-authored-by: prism <69634294+imjustprism@users.noreply.github.com>
This commit is contained in:
thororen 2026-04-06 20:48:13 -04:00 • committed by GitHub
parent e0efe846bd
commit a98d0d0426
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
63 changed files with 2669 additions and 468 deletions

View file

@ -20,7 +20,8 @@ export const enum ActivityFlags {
PARTY_PRIVACY_FRIENDS = 1 << 6,
PARTY_PRIVACY_VOICE_CHANNEL = 1 << 7,
EMBEDDED = 1 << 8,
CONTEXTLESS = 1 << 9
CONTEXTLESS = 1 << 9,
SUPPORTS_GATEWAY_ACTIVITY_ACTION_JOIN = 1 << 10,
}
export const enum ActivityStatusDisplayType {
@ -28,3 +29,26 @@ export const enum ActivityStatusDisplayType {
STATE = 1,
DETAILS = 2
}
export const enum OrientationLockState {
UNLOCKED = 1,
PORTRAIT = 2,
LANDSCAPE = 3,
}
export const enum ActivityGameMode {
PLAY = 0,
SPECTATE = 1,
}
export const enum ActivityLayout {
FOCUSED = 0,
PIP = 1,
GRID = 2,
}
export const enum ActivityLabelType {
NONE = 0,
NEW = 1,
UPDATED = 2,
}

View file

@ -0,0 +1,41 @@
export const enum ApplicationType {
DEPRECATED_GAME = 1,
TICKETED_EVENTS = 3,
GUILD_ROLE_SUBSCRIPTIONS = 4,
GAME = 5,
NON_GAME_DETECTABLE = 6,
}
export const enum LinkedGameType {
LINKED = 1,
OFFICIAL = 2,
NVIDIA = 3,
}
export const enum CarouselItemType {
IMG = 1,
YOUTUBE_VIDEO = 2,
VIDEO = 3,
}
export const enum ApplicationFlags {
EMBEDDED_RELEASED = 1 << 1,
EMBEDDED_IAP = 1 << 3,
APPLICATION_AUTO_MODERATION_RULE_CREATE_BADGE = 1 << 6,
GAME_PROFILE_DISABLED = 1 << 7,
CONTEXTLESS_ACTIVITY = 1 << 9,
SOCIAL_LAYER_INTEGRATION_LIMITED = 1 << 10,
CLOUD_GAMING_DEMO = 1 << 11,
GATEWAY_PRESENCE = 1 << 12,
GATEWAY_PRESENCE_LIMITED = 1 << 13,
GATEWAY_GUILD_MEMBERS = 1 << 14,
GATEWAY_GUILD_MEMBERS_LIMITED = 1 << 15,
EMBEDDED = 1 << 17,
GATEWAY_MESSAGE_CONTENT = 1 << 18,
GATEWAY_MESSAGE_CONTENT_LIMITED = 1 << 19,
EMBEDDED_FIRST_PARTY = 1 << 20,
APPLICATION_COMMAND_BADGE = 1 << 23,
SOCIAL_LAYER_INTEGRATION = 1 << 27,
PROMOTED = 1 << 29,
PARTNER = 1 << 30,
}

View file

@ -1,3 +1,58 @@
export const enum PermissionOverwriteType {
ROLE = 0,
MEMBER = 1,
OWNER = 2
}
export const enum PermissionOverwriteRowType {
EMPTY_STATE = 0,
ADMINISTRATOR = 1,
ROLE = 2,
OWNER = 3,
MEMBER = 4,
USER = 5,
GUILD = 6,
}
export const enum PermissionOverwriteSectionType {
ROLES = 0,
MEMBERS = 1,
USERS = 2,
GUILDS = 3,
}
export const enum ForumLayout {
DEFAULT = 0,
LIST = 1,
GRID = 2,
}
export const enum SafetyWarningType {
STRANGER_DANGER = 1,
INAPPROPRIATE_CONVERSATION_TIER_1 = 2,
INAPPROPRIATE_CONVERSATION_TIER_2 = 3,
LIKELY_ATO = 4,
}
export const enum ChannelFlags {
GUILD_FEED_REMOVED = 1,
PINNED = 2,
ACTIVE_CHANNELS_REMOVED = 4,
REQUIRE_TAG = 16,
IS_SPAM = 32,
IS_GUILD_RESOURCE_CHANNEL = 128,
CLYDE_AI = 256,
IS_SCHEDULED_FOR_DELETION = 512,
IS_MEDIA_CHANNEL = 1024,
SUMMARIES_DISABLED = 2048,
IS_ROLE_SUBSCRIPTION_TEMPLATE_PREVIEW_CHANNEL = 8192,
IS_BROADCASTING = 16384,
HIDE_MEDIA_DOWNLOAD_OPTIONS = 32768,
IS_JOIN_REQUEST_INTERVIEW_CHANNEL = 65536,
OBFUSCATED = 131072,
IS_MODERATOR_REPORT_CHANNEL = 524288,
}
export const enum ChannelType {
GUILD_TEXT = 0,
DM = 1,
@ -5,11 +60,100 @@ export const enum ChannelType {
GROUP_DM = 3,
GUILD_CATEGORY = 4,
GUILD_ANNOUNCEMENT = 5,
GUILD_STORE = 6,
ANNOUNCEMENT_THREAD = 10,
PUBLIC_THREAD = 11,
PRIVATE_THREAD = 12,
GUILD_STAGE_VOICE = 13,
GUILD_DIRECTORY = 14,
GUILD_FORUM = 15,
GUILD_MEDIA = 16
GUILD_MEDIA = 16,
LOBBY = 17,
DM_SDK = 18,
UNKNOWN = 10000,
}
/**
* Pre-defined Sets of channel types for grouping related channels.
* Each property is a Set<ChannelType> containing channel type numbers.
*/
export interface ChannelTypesSets {
/** DM and GROUP_DM, channels that support calling. */
CALLABLE: Set<ChannelType>;
/** Channels that support text messages. */
TEXTUAL: Set<ChannelType>;
/** Forum and media channels, threads only, no direct messages. */
GUILD_THREADS_ONLY: Set<ChannelType>;
/** Channels that support stickers. */
STICKERS: Set<ChannelType>;
/** Channels that can be read/viewed. */
READABLE: Set<ChannelType>;
/** All guild channel types including threads. */
GUILD: Set<ChannelType>;
/** Guild channels excluding threads. */
GUILD_CHANNEL: Set<ChannelType>;
/** All thread types (announcement, public, private). */
THREADS: Set<ChannelType>;
/** DM and GROUP_DM, private/non-guild channels. */
PRIVATE_CHANNEL: Set<ChannelType>;
/** Announcement and public threads only. */
PUBLIC_THREADS: Set<ChannelType>;
/** Guild channels that can have threads. */
GUILD_THREADED: Set<ChannelType>;
/** Guild channels that are persisted/stored. */
GUILD_STORED: Set<ChannelType>;
/** Guild channels with text capability. */
GUILD_TEXTUAL: Set<ChannelType>;
/** Guild voice and stage channels. */
GUILD_VOCAL: Set<ChannelType>;
/** Thread types that support voice. */
VOCAL_THREAD: Set<ChannelType>;
/** All channels with voice capability. */
VOCAL: Set<ChannelType>;
/** Channels that support voice effects. */
VOICE_EFFECTS: Set<ChannelType>;
/** Guild text-only channels (no voice). */
GUILD_TEXT_ONLY: Set<ChannelType>;
/** Channels with character-limited names. */
LIMITED_CHANNEL_NAME: Set<ChannelType>;
/** Channels that support message search. */
SEARCHABLE: Set<ChannelType>;
/** Guild channels with user-generated content. */
GUILD_USER_CONTENT: Set<ChannelType>;
/** Guild channels that can have topics. */
GUILD_TOPICAL: Set<ChannelType>;
/** Guild channels that support webhooks. */
GUILD_WEBHOOKS: Set<ChannelType>;
/** Guild channels usable as system message channel. */
GUILD_SYSTEM_CHANNEL: Set<ChannelType>;
/** Guild channels that can have a parent category. */
GUILD_PARENTABLE: Set<ChannelType>;
/** Guild channels subject to auto-moderation. */
GUILD_AUTO_MODERATED: Set<ChannelType>;
/** Basic guild channel types for creation. */
GUILD_BASIC: Set<ChannelType>;
/** Guild channel types that can be created. */
CREATEABLE_GUILD_CHANNELS: Set<ChannelType>;
/** GROUP_DM only, multi-user DMs. */
MULTI_USER_DMS: Set<ChannelType>;
/** DM and GROUP_DM. */
ALL_DMS: Set<ChannelType>;
/** Channels that support invites. */
INVITABLE: Set<ChannelType>;
/** Guild channels supporting feed-featurable messages. */
GUILD_FEED_FEATURABLE_MESSAGES: Set<ChannelType>;
/** Channels supporting role subscriptions. */
ROLE_SUBSCRIPTIONS: Set<ChannelType>;
/** Channels supporting icon emojis. */
ICON_EMOJIS: Set<ChannelType>;
/** Channels that can be summarized. */
SUMMARIZEABLE: Set<ChannelType>;
/** Channels supporting content entry embeds. */
CONTENT_ENTRY_EMBEDS: Set<ChannelType>;
/** Channels that support polls. */
POLLS: Set<ChannelType>;
/** Channels that can launch activities. */
ACTIVITY_LAUNCHABLE: Set<ChannelType>;
/** All known channel types. */
ALL: Set<ChannelType>;
}

View file

@ -21,12 +21,45 @@ export const enum ApplicationCommandInputType {
}
export const enum ApplicationCommandType {
/**
* @remarks Discord API calls this just CHAT
*/
CHAT_INPUT = 1,
USER = 2,
MESSAGE = 3,
PRIMARY_ENTRY_POINT = 4,
}
export const enum ApplicationIntegrationType {
GUILD_INSTALL = 0,
USER_INSTALL = 1
USER_INSTALL = 1,
}
export const enum InteractionType {
APPLICATION_COMMAND = 2,
MESSAGE_COMPONENT = 3,
APPLICATION_COMMAND_AUTOCOMPLETE = 4,
MODAL_SUBMIT = 5,
}
export const enum ApplicationCommandSectionType {
BUILT_IN = 0,
APPLICATION = 1,
}
export const enum ApplicationCommandPermissionType {
ROLE = 1,
USER = 2,
CHANNEL = 3,
}
export const enum InteractionContextType {
GUILD = 0,
BOT_DM = 1,
PRIVATE_CHANNEL = 2,
}
export const enum ApplicationCommandHandlerType {
APP_HANDLER = 1,
DISCORD_LAUNCH_ACTIVITY = 2,
}

View file

@ -0,0 +1,103 @@
export const enum GuildScheduledEventStatus {
SCHEDULED = 1,
ACTIVE = 2,
COMPLETED = 3,
CANCELED = 4,
}
export const enum GuildScheduledEventEntityType {
NONE = 0,
STAGE_INSTANCE = 1,
VOICE = 2,
EXTERNAL = 3,
PRIME_TIME = 4,
}
export const enum GuildScheduledEventPrivacyLevel {
PUBLIC = 1,
GUILD_ONLY = 2,
}
export const enum GuildNSFWLevel {
DEFAULT = 0,
EXPLICIT = 1,
SAFE = 2,
AGE_RESTRICTED = 3,
}
export const enum GuildVerificationLevel {
NONE = 0,
LOW = 1,
MEDIUM = 2,
HIGH = 3,
VERY_HIGH = 4,
}
export const enum GuildExplicitContentFilter {
DISABLED = 0,
MEMBERS_WITHOUT_ROLES = 1,
ALL_MEMBERS = 2,
}
export const enum GuildMFALevel {
NONE = 0,
ELEVATED = 1,
}
export const enum GuildDefaultMessageNotifications {
ALL_MESSAGES = 0,
ONLY_MENTIONS = 1,
}
export const enum GuildPremiumTier {
NONE = 0,
TIER_1 = 1,
TIER_2 = 2,
TIER_3 = 3,
}
export const enum GuildSettingsFlags {
UNREADS_ALL_MESSAGES = 2048,
UNREADS_ONLY_MENTIONS = 4096,
OPT_IN_CHANNELS_OFF = 8192,
OPT_IN_CHANNELS_ON = 16384,
}
export const enum SystemChannelFlags {
SUPPRESS_JOIN_NOTIFICATIONS = 1,
SUPPRESS_PREMIUM_SUBSCRIPTIONS = 2,
SUPPRESS_GUILD_REMINDER_NOTIFICATIONS = 4,
SUPPRESS_JOIN_NOTIFICATION_REPLIES = 8,
SUPPRESS_ROLE_SUBSCRIPTION_PURCHASE_NOTIFICATIONS = 16,
SUPPRESS_ROLE_SUBSCRIPTION_PURCHASE_NOTIFICATION_REPLIES = 32,
SUPPRESS_CHANNEL_PROMPT_DEADCHAT = 128,
SUPPRESS_UGC_ADDED_NOTIFICATIONS = 256,
}
export const enum GuildMemberFlags {
DID_REJOIN = 1,
COMPLETED_ONBOARDING = 2,
BYPASSES_VERIFICATION = 4,
STARTED_ONBOARDING = 8,
IS_GUEST = 16,
STARTED_HOME_ACTIONS = 32,
COMPLETED_HOME_ACTIONS = 64,
AUTOMOD_QUARANTINED_USERNAME_OR_GUILD_NICKNAME = 128,
AUTOMOD_QUARANTINED_BIO = 256,
DM_SETTINGS_UPSELL_ACKNOWLEDGED = 512,
AUTOMOD_QUARANTINED_SERVER_TAG = 1024,
}
export const enum RoleFlags {
IN_PROMPT = 1,
}
export const enum RecurrenceRuleFrequency {
YEARLY = 0,
MONTHLY = 1,
WEEKLY = 2,
DAILY = 3,
HOURLY = 4,
MINUTELY = 5,
SECONDLY = 6,
}

View file

@ -1,6 +1,10 @@
export * from "./activity";
export * from "./application";
export * from "./channel";
export * from "./commands";
export * from "./guild";
export * from "./messages";
export * from "./misc";
export * from "./settings";
export * from "./user";
export * from "./voice";

View file

@ -1,3 +1,54 @@
export const enum ComponentType {
UNKNOWN = -1,
ACTION_ROW = 1,
BUTTON = 2,
STRING_SELECT = 3,
TEXT_INPUT = 4,
USER_SELECT = 5,
ROLE_SELECT = 6,
MENTIONABLE_SELECT = 7,
CHANNEL_SELECT = 8,
SECTION = 9,
TEXT_DISPLAY = 10,
THUMBNAIL = 11,
MEDIA_GALLERY = 12,
FILE = 13,
SEPARATOR = 14,
CONTENT_INVENTORY_ENTRY = 16,
CONTAINER = 17,
LABEL = 18,
FILE_UPLOAD = 19,
CHECKPOINT_CARD = 20,
}
export const enum ButtonStyle {
PRIMARY = 1,
SECONDARY = 2,
SUCCESS = 3,
DESTRUCTIVE = 4,
LINK = 5,
PREMIUM = 6,
}
export const enum MessageReferenceType {
DEFAULT = 0,
FORWARD = 1,
}
export const enum PollLayoutType {
UNKNOWN = 0,
DEFAULT = 1,
IMAGE_ONLY_ANSWERS = 2
}
export const enum MessageActivityType {
JOIN = 1,
LISTEN = 3,
WATCH = 4,
JOIN_REQUEST = 5,
STREAM_REQUEST = 6,
}
export const enum StickerType {
/** an official sticker in a pack */
STANDARD = 1,
@ -92,6 +143,8 @@ export const enum MessageType {
* Name: PREMIUM_GUILD_SUBSCRIPTION
* Rendered Content: "{author} just boosted the server{content ? " {content} times"}!"
* Deletable: true
*
* @remarks Discord API calls this GUILD_BOOST
*/
PREMIUM_GUILD_SUBSCRIPTION = 8,
/**
@ -101,6 +154,8 @@ export const enum MessageType {
* Name: PREMIUM_GUILD_SUBSCRIPTION_TIER_1
* Rendered Content: "{author} just boosted the server{content ? " {content} times"}! {guild} has achieved Level 1! "
* Deletable: true
*
* @remarks Discord API calls this GUILD_BOOST_TIER_1
*/
PREMIUM_GUILD_SUBSCRIPTION_TIER_1 = 9,
/**
@ -110,6 +165,8 @@ export const enum MessageType {
* Name: PREMIUM_GUILD_SUBSCRIPTION_TIER_2
* Rendered Content: "{author} just boosted the server{content ? " {content} times"}! {guild} has achieved Level 2! "
* Deletable: true
*
* @remarks Discord API calls this GUILD_BOOST_TIER_2
*/
PREMIUM_GUILD_SUBSCRIPTION_TIER_2 = 10,
/**
@ -119,6 +176,8 @@ export const enum MessageType {
* Name: PREMIUM_GUILD_SUBSCRIPTION_TIER_3
* Rendered Content: "{author} just boosted the server{content ? " {content} times"}! {guild} has achieved Level 3! "
* Deletable: true
*
* @remarks Discord API calls this GUILD_BOOST_TIER_3
*/
PREMIUM_GUILD_SUBSCRIPTION_TIER_3 = 11,
/**
@ -130,6 +189,14 @@ export const enum MessageType {
* Deletable: true
*/
CHANNEL_FOLLOW_ADD = 12,
/**
* A message sent when a user starts a stream in a guild.
*
* Value: 13
* Name: GUILD_STREAM
* Deletable: true
*/
GUILD_STREAM = 13,
/**
* A message sent when a guild is disqualified from discovery
*
@ -301,6 +368,22 @@ export const enum MessageType {
* Deletable: true
*/
GUILD_APPLICATION_PREMIUM_SUBSCRIPTION = 32,
/**
* A message sent when an integration is added to a private channel
*
* Value: 33
* Name: PRIVATE_CHANNEL_INTEGRATION_ADDED
* Deletable: true
*/
PRIVATE_CHANNEL_INTEGRATION_ADDED = 33,
/**
* A message sent when an integration is removed from a private channel
*
* Value: 34
* Name: PRIVATE_CHANNEL_INTEGRATION_REMOVED
* Deletable: true
*/
PRIVATE_CHANNEL_INTEGRATION_REMOVED = 34,
/**
* A message sent when a user gifts a premium (Nitro) referral
*
@ -380,6 +463,14 @@ export const enum MessageType {
* Deletable: true
*/
PURCHASE_NOTIFICATION = 44,
/**
* A message sent as a voice hangout invite
*
* Value: 45
* Name: VOICE_HANGOUT_INVITE
* Deletable: true
*/
VOICE_HANGOUT_INVITE = 45,
/**
* A message sent when a poll is finalized
*
@ -470,6 +561,22 @@ export const enum MessageType {
* Deletable: true
*/
HD_STREAMING_UPGRADED = 55,
/**
* A message sent when a chat wallpaper is set
*
* Value: 56
* Name: CHAT_WALLPAPER_SET
* Deletable: true
*/
CHAT_WALLPAPER_SET = 56,
/**
* A message sent when a chat wallpaper is removed
*
* Value: 57
* Name: CHAT_WALLPAPER_REMOVED
* Deletable: true
*/
CHAT_WALLPAPER_REMOVED = 57,
/**
* A message sent when a user resolves a moderation report by deleting the offending message
*
@ -524,6 +631,14 @@ export const enum MessageType {
* Deletable: true
*/
EMOJI_ADDED = 63,
/**
* A message sent as a premium group invite
*
* Value: 64
* Name: PREMIUM_GROUP_INVITE
* Deletable: true
*/
PREMIUM_GROUP_INVITE = 64,
}
export const enum MessageFlags {

View file

@ -11,42 +11,7 @@ export const enum DraftType {
Poll = 4,
SlashCommand = 5,
ForwardContextMessage = 6,
}
export const enum GuildScheduledEventStatus {
SCHEDULED = 1,
ACTIVE = 2,
COMPLETED = 3,
CANCELED = 4,
}
export const enum GuildScheduledEventEntityType {
STAGE_INSTANCE = 1,
VOICE = 2,
EXTERNAL = 3,
}
export const enum GuildScheduledEventPrivacyLevel {
GUILD_ONLY = 2,
}
export const enum ParticipantType {
STREAM = 0,
HIDDEN_STREAM = 1,
USER = 2,
ACTIVITY = 3,
}
export const enum RTCPlatform {
DESKTOP = 0,
MOBILE = 1,
XBOX = 2,
PLAYSTATION = 3,
}
export const enum VideoSourceType {
VIDEO = 0,
CAMERA_PREVIEW = 1,
InteractionModal = 7,
}
export const enum EmojiIntention {
@ -75,29 +40,15 @@ export const enum LoadState {
ERROR = 3,
}
export const enum ConnectionStatsFlags {
TRANSPORT = 1,
OUTBOUND = 2,
INBOUND = 4,
ALL = 7,
export const enum InviteTargetType {
STREAM = 1,
EMBEDDED_APPLICATION = 2,
ROLE_SUBSCRIPTIONS_PURCHASE = 3,
}
export const enum SpeakingFlags {
export const enum PremiumType {
NONE = 0,
VOICE = 1,
SOUNDSHARE = 2,
PRIORITY = 4,
HIDDEN = 8,
}
export const enum GoLiveQualityMode {
AUTO = 1,
FULL = 2,
}
export const enum VoiceProcessingStateReason {
CPU_OVERUSE = 1,
FAILED = 2,
VAD_CPU_OVERUSE = 3,
INITIALIZED = 4,
TIER_1 = 1,
TIER_2 = 2,
TIER_0 = 3,
}

View file

@ -0,0 +1,42 @@
export const enum Theme {
UNSET = 0,
DARK = 1,
LIGHT = 2,
DARKER = 3,
MIDNIGHT = 4,
}
export const enum UIDensity {
UNSET = 0,
COMPACT = 1,
COZY = 2,
RESPONSIVE = 3,
DEFAULT = 4,
}
export const enum StickerAnimationSetting {
ALWAYS = 0,
ON_INTERACTION = 1,
NEVER = 2,
}
export const enum UserNotificationSetting {
ALL_MESSAGES = 0,
ONLY_MENTIONS = 1,
NO_MESSAGES = 2,
}
export const enum ChannelOverrideFlags {
UNREADS_ONLY_MENTIONS = 512,
UNREADS_ALL_MESSAGES = 1024,
FAVORITED = 2048,
OPT_IN_ENABLED = 4096,
NEW_FORUM_THREADS_OFF = 8192,
NEW_FORUM_THREADS_ON = 16384,
}
export const enum NotifyHighlights {
NULL = 0,
DISABLED = 1,
ENABLED = 2,
}

View file

@ -2,10 +2,16 @@ export const enum RelationshipType {
NONE = 0,
FRIEND = 1,
BLOCKED = 2,
/**
* @remarks Discord API calls this PENDING_INCOMING
*/
INCOMING_REQUEST = 3,
/**
* @remarks Discord API calls this PENDING_OUTGOING
*/
OUTGOING_REQUEST = 4,
IMPLICIT = 5,
SUGGESTION = 6
SUGGESTION = 6,
}
export enum GiftIntentType {
@ -20,3 +26,38 @@ export const enum ReadStateType {
GUILD_ONBOARDING_QUESTION = 4,
MESSAGE_REQUESTS = 5,
}
export const enum UserFlags {
STAFF = 1 << 0,
PARTNER = 1 << 1,
HYPESQUAD = 1 << 2,
BUG_HUNTER_LEVEL_1 = 1 << 3,
MFA_SMS = 1 << 4,
PREMIUM_PROMO_DISMISSED = 1 << 5,
HYPESQUAD_ONLINE_HOUSE_1 = 1 << 6,
HYPESQUAD_ONLINE_HOUSE_2 = 1 << 7,
HYPESQUAD_ONLINE_HOUSE_3 = 1 << 8,
PREMIUM_EARLY_SUPPORTER = 1 << 9,
TEAM_PSEUDO_USER = 1 << 10,
IS_HUBSPOT_CONTACT = 1 << 11,
SYSTEM = 1 << 12,
HAS_UNREAD_URGENT_MESSAGES = 1 << 13,
BUG_HUNTER_LEVEL_2 = 1 << 14,
UNDERAGE_DELETED = 1 << 15,
VERIFIED_BOT = 1 << 16,
VERIFIED_DEVELOPER = 1 << 17,
CERTIFIED_MODERATOR = 1 << 18,
BOT_HTTP_INTERACTIONS = 1 << 19,
SPAMMER = 1 << 20,
DISABLE_PREMIUM = 1 << 21,
ACTIVE_DEVELOPER = 1 << 22,
PROVISIONAL_ACCOUNT = 1 << 23,
}
export const enum StandingState {
ALL_GOOD = 100,
LIMITED = 200,
VERY_LIMITED = 300,
AT_RISK = 400,
SUSPENDED = 500,
}

View file

@ -0,0 +1,50 @@
export const enum ParticipantType {
STREAM = 0,
HIDDEN_STREAM = 1,
USER = 2,
ACTIVITY = 3,
}
export const enum RTCPlatform {
DESKTOP = 0,
MOBILE = 1,
XBOX = 2,
PLAYSTATION = 3,
}
export const enum VideoSourceType {
VIDEO = 0,
CAMERA_PREVIEW = 1,
}
export const enum ConnectionStatsFlags {
TRANSPORT = 1,
OUTBOUND = 2,
INBOUND = 4,
ALL = 7,
}
export const enum SpeakingFlags {
NONE = 0,
VOICE = 1,
SOUNDSHARE = 2,
PRIORITY = 4,
HIDDEN = 8,
}
export const enum GoLiveQualityMode {
AUTO = 1,
FULL = 2,
}
export const enum VoiceProcessingStateReason {
CPU_OVERUSE = 1,
FAILED = 2,
VAD_CPU_OVERUSE = 3,
INITIALIZED = 4,
}
export const enum VideoQualityMode {
AUTO = 1,
FULL = 2,
}

View file

@ -3,7 +3,7 @@
"author": "Vencord Contributors",
"private": false,
"description": "Typescript definitions for the webpack modules of the Discord Web app",
"version": "1.0.0",
"version": "1.0.1",
"license": "LGPL-3.0-or-later",
"types": "src/index.d.ts",
"type": "module",

View file

@ -1,5 +1,7 @@
import { ActivityFlags, ActivityStatusDisplayType, ActivityType } from "../../enums";
export type ActivityPlatform = "desktop" | "mobile" | "web" | "embedded" | "xbox" | "playstation" | "samsung" | "ios" | "android";
export interface ActivityAssets {
large_image?: string;
large_text?: string;
@ -15,9 +17,18 @@ export interface ActivityButton {
}
export interface Activity {
created_at?: number;
id?: string;
name: string;
application_id: string;
application_id?: string;
type: ActivityType;
session_id?: string;
sync_id?: string;
emoji?: {
animated: boolean;
id: string;
name: string;
};
state?: string;
state_url?: string;
details?: string;
@ -34,6 +45,7 @@ export interface Activity {
metadata?: {
button_urls?: Array<string>;
};
platform?: ActivityPlatform;
party?: {
id?: string;
size?: [number, number];

View file

@ -1,6 +1,36 @@
import { ActivityLabelType, ApplicationFlags, ApplicationType, CarouselItemType, LinkedGameType, OrientationLockState } from "../../enums";
import { Guild } from "./Guild";
import { User } from "./User";
export type EmbeddedActivityPlatform = "ios" | "android" | "web";
export interface EmbeddedActivityPlatformConfig {
label_type: ActivityLabelType;
label_from: string | null;
label_until: string | null;
release_phase: string;
omit_badge_from_surfaces: string[];
}
export interface EmbeddedActivityConfig {
application_id: string;
activity_preview_video_asset_id: string | null;
supported_platforms: EmbeddedActivityPlatform[];
default_orientation_lock_state: OrientationLockState;
tablet_default_orientation_lock_state: OrientationLockState;
requires_age_gate: boolean;
legacy_responsive_aspect_ratio: boolean;
premium_tier_requirement: number | null;
free_period_starts_at: string | null;
free_period_ends_at: string | null;
client_platform_config: Partial<Record<EmbeddedActivityPlatform, EmbeddedActivityPlatformConfig>>;
shelf_rank: number;
has_csp_exception: boolean;
displays_advertisements: boolean;
blocked_locales: string[];
supported_locales: string[];
}
export interface ApplicationExecutable {
os: "win32" | "darwin" | "linux";
name: string;
@ -23,12 +53,23 @@ export interface ApplicationInstallParams {
scopes: string[];
}
export interface ApplicationIntegrationTypeConfig {
oauth2InstallParams: ApplicationInstallParams;
}
export interface ApplicationDirectoryEntry {
guild_count?: number;
detailed_description?: string;
supported_locales?: string[];
carousel_items?: { asset_id: string; type: CarouselItemType; }[];
}
export interface Application {
id: string;
name: string;
icon: string | null;
description: string;
type: number | null;
type: ApplicationType | null;
coverImage: string | null;
primarySkuId: string | undefined;
bot: User | null;
@ -54,24 +95,30 @@ export interface Application {
hashes: string[];
eulaId: string | undefined;
slug: string | undefined;
flags: number;
maxParticipants: number | undefined;
flags: ApplicationFlags;
maxParticipants: number | null;
tags: string[];
embeddedActivityConfig: Record<string, unknown> | undefined;
embeddedActivityConfig: EmbeddedActivityConfig | undefined;
team: ApplicationTeam | undefined;
integrationTypesConfig: Record<string, Record<string, unknown>>;
integrationTypesConfig: Record<string, ApplicationIntegrationTypeConfig>;
storefront_available: boolean;
termsOfServiceUrl: string | undefined;
privacyPolicyUrl: string | undefined;
isDiscoverable: boolean;
customInstallUrl: string | undefined;
installParams: ApplicationInstallParams | undefined;
directoryEntry: Record<string, unknown> | undefined;
directoryEntry: ApplicationDirectoryEntry | undefined;
categories: string[] | undefined;
linkedGames: string[] | undefined;
linkedGames: ApplicationLinkedGame[] | undefined;
deepLinkUri: string | undefined;
}
export interface ApplicationLinkedGame {
id: string;
type: LinkedGameType;
application?: Application;
}
export interface ApplicationTeam {
id: string;
name: string;

View file

@ -1,83 +1,369 @@
import { ChannelFlags, ChannelType, ForumLayout, PermissionOverwriteType, SafetyWarningType, UserFlags, VideoQualityMode } from "../../enums";
import { DiscordRecord } from "./Record";
/** Permission overwrite for a role or member. */
export interface PermissionOverwrite {
id: string;
/** 0 = role, 1 = member. */
type: PermissionOverwriteType;
deny: bigint;
allow: bigint;
}
/** Avatar decoration data for user profiles. */
export interface AvatarDecorationData {
asset: string;
expires_at: string | null;
skuId: string;
}
/** Clan identity information. */
export interface ClanData {
badge: string;
tag: string;
identityEnabled: boolean;
identityGuildId: string;
}
/** Display name style configuration. */
export interface DisplayNameStyles {
colors: number[];
effect_id: number;
font_id: number;
}
/** Collectible item data. */
export interface CollectibleItem {
asset: string;
expires_at: string | null;
label: string;
palette: string;
type: number;
skuId: string;
}
/** User collectibles configuration. */
export interface Collectibles {
nameplate?: CollectibleItem;
}
/** Raw recipient data from API. */
export interface RawRecipient {
id: string;
avatar: string | null;
avatar_decoration_data: AvatarDecorationData | null;
bot: boolean;
clan: ClanData | null;
collectibles: Collectibles | null;
discriminator: string;
display_name: string | null;
display_name_styles: DisplayNameStyles | null;
global_name: string | null;
primary_guild: ClanData | null;
public_flags: UserFlags;
username: string;
}
/** Thread metadata for thread channels. */
export interface ThreadMetadata {
archived: boolean;
autoArchiveDuration: number;
archiveTimestamp: string | undefined;
createTimestamp: string | undefined;
locked: boolean;
invitable: boolean;
}
/** Icon emoji for channels that support it. */
export interface ChannelIconEmoji {
id: string | null;
name: string;
}
/** Thread member info, present when user has joined a thread. */
export interface ThreadMember {
flags: number;
joinTimestamp: string;
muted: boolean;
muteConfig: {
end_time: string | null;
selected_time_window: number;
} | null;
}
/** Available tag for forum/media channels. */
export interface ForumTag {
id: string;
name: string;
emojiId: string | null;
emojiName: string | null;
moderated: boolean;
color: number | null;
}
/** Default reaction emoji for forum/media channels. */
export interface DefaultReactionEmoji {
emojiId: string | null;
emojiName: string;
}
/** Linked lobby for voice channels. */
export interface LinkedLobby {
application_id: string;
lobby_id: string;
linked_by: string;
linked_at: string;
require_application_authorization: boolean;
}
/** Safety warning for DM spam detection. */
export interface SafetyWarning {
id: string;
type: SafetyWarningType;
expiry: string;
dismiss_timestamp: string | null;
}
/** Sort order for forum/media channels. */
export type ForumSortOrder = 0 | 1;
/** Tag setting for forum/media channels. */
export type ForumTagSetting = "match_all" | "match_some";
/** Discord channel object. */
export class Channel extends DiscordRecord {
constructor(channel: object);
application_id: number | undefined;
bitrate: number;
/** Application ID for bot-created channels. */
application_id: string | undefined;
/** Applied tag IDs. Threads in forum/media channels only. */
appliedTags: string[] | undefined;
/** Available tags for forum/media channels. */
availableTags: ForumTag[] | undefined;
/** Internal, use bitrate getter. Voice channels only. */
bitrate_: number | undefined;
/** Whether blocked user warning was dismissed. */
blockedUserWarningDismissed: boolean | undefined;
/** Default auto-archive duration for threads in minutes. Guild text channels only. */
defaultAutoArchiveDuration: number | undefined;
flags: number;
/** Default layout for forum/media channels. */
defaultForumLayout: ForumLayout | undefined;
/** Default reaction emoji for forum/media channels. */
defaultReactionEmoji: DefaultReactionEmoji | undefined;
/** Default sort order for forum/media channels. */
defaultSortOrder: ForumSortOrder | undefined;
/** Default tag setting for forum/media channels. */
defaultTagSetting: ForumTagSetting | undefined;
/** Default slowmode for new threads. Guild text channels only. */
defaultThreadRateLimitPerUser: number | undefined;
/** Internal, use flags getter. */
flags_: ChannelFlags;
/** Guild ID. */
guild_id: string;
icon: string;
/** User ID who purchased HD streaming. */
hdStreamingBuyerId: string | undefined;
/** HD streaming end timestamp. */
hdStreamingUntil: string | undefined;
/** Icon hash for group DMs. */
icon: string | undefined;
/** Icon emoji for channels that support it. */
iconEmoji: ChannelIconEmoji | undefined;
/** Channel snowflake ID. */
id: string;
lastMessageId: string;
/** For DMs, whether this is a message request. */
isMessageRequest: boolean;
/** Timestamp when message request was created. */
isMessageRequestTimestamp: string | null;
/** Whether the DM is flagged as spam. */
isSpam: boolean;
/** ID of the last message in the channel. */
lastMessageId: string | null;
/** ISO timestamp of the last pinned message. */
lastPinTimestamp: string | undefined;
member: unknown;
/** Linked lobby for voice channels. */
linkedLobby: LinkedLobby | null;
/** Thread member info if user joined thread. Threads only. */
member: ThreadMember | undefined;
/** Approximate member count. Threads only. */
memberCount: number | undefined;
/** Preview of member IDs in the thread. Threads only. */
memberIdsPreview: string[] | undefined;
memberListId: unknown;
/** Member list ID for guild channels. */
memberListId: string | undefined;
/** Approximate message count. Threads only. */
messageCount: number | undefined;
/** Channel name. */
name: string;
nicks: Record<string, unknown>;
nsfw: boolean;
originChannelId: unknown;
ownerId: string;
/** Custom nicknames in group DMs, keyed by user ID. */
nicks: Record<string, string>;
/** Internal, use nsfw getter. Guild channels only. */
nsfw_: boolean;
/** Origin channel ID for crossposted messages. */
originChannelId: string | undefined;
/** Owner ID for group DMs and threads. */
ownerId: string | undefined;
/** Parent category or channel ID. */
parent_id: string;
permissionOverwrites: {
[role: string]: {
id: string;
type: number;
deny: bigint;
allow: bigint;
};
};
position: number;
rateLimitPerUser: number;
rawRecipients: {
id: string;
avatar: string;
username: string;
public_flags: number;
discriminator: string;
}[];
/** Parent channel type for threads. */
parentChannelThreadType: ChannelType | undefined;
/** Internal, use permissionOverwrites getter. Guild channels only. */
permissionOverwrites_: Record<string, PermissionOverwrite>;
/** Internal, use position getter. Guild channels only. */
position_: number;
/** Internal, use rateLimitPerUser getter. */
rateLimitPerUser_: number;
/** Raw recipient data from API. DMs and group DMs. */
rawRecipients: RawRecipient[];
/** Recipient flags for DMs. */
recipientFlags: number;
/** Recipient user IDs. DMs and group DMs. */
recipients: string[];
rtcRegion: string;
threadMetadata: {
locked: boolean;
archived: boolean;
invitable: boolean;
createTimestamp: string | undefined;
autoArchiveDuration: number;
archiveTimestamp: string | undefined;
};
topic: string;
type: number;
userLimit: number;
videoQualityMode: undefined;
/** RTC region for voice channels, null for automatic. Voice channels only. */
rtcRegion: string | null;
/** Safety warnings for DM spam detection. */
safetyWarnings: SafetyWarning[];
/** Template string. */
template: string | undefined;
/** Theme color for group DMs. */
themeColor: number | undefined;
/** Thread metadata. Threads only. */
threadMetadata: ThreadMetadata | undefined;
/** Internal, use topic getter. */
topic_: string | null;
/** Total messages sent in thread. Threads only. */
totalMessageSent: number | undefined;
/** Channel type from ChannelType enum. */
type: ChannelType;
/** Internal, use userLimit getter. Voice channels only. */
userLimit_: number | undefined;
/** Channel version number. */
version: number | undefined;
/** Video quality mode for voice channels. Voice channels only. */
videoQualityMode: VideoQualityMode | undefined;
/** Computed access permissions for the current user. */
get accessPermissions(): bigint;
get lastActiveTimestamp(): number;
/** Bitrate in bits per second. Voice channels only. */
get bitrate(): number;
/** Channel flags bitmask. */
get flags(): ChannelFlags;
/** Whether HD streaming splash is active. */
get isHDStreamSplashed(): boolean;
/** Whether the channel is marked as NSFW. */
get nsfw(): boolean;
/** Permission overwrites keyed by role or user ID. */
get permissionOverwrites(): Record<string, PermissionOverwrite>;
/** Channel position in the channel list. */
get position(): number;
/** Slowmode delay in seconds. */
get rateLimitPerUser(): number;
/** Channel topic or description. */
get topic(): string;
/** Maximum users allowed in voice channel. 0 = unlimited. */
get userLimit(): number;
computeLurkerPermissionsAllowList(): unknown;
getApplicationId(): unknown;
/** Computes allowed permissions for lurkers. */
computeLurkerPermissionsAllowList(): bigint | undefined;
/** Gets the application ID for bot-created channels. */
getApplicationId(): string | undefined;
/** Gets the default layout for forum channels. */
getDefaultLayout(): ForumLayout;
/** Gets the default sort order for forum channels. */
getDefaultSortOrder(): ForumSortOrder;
/** Gets the default tag setting for forum channels. */
getDefaultTagSetting(): ForumTagSetting;
/** Gets the guild ID this channel belongs to. */
getGuildId(): string;
getRecipientId(): unknown;
/** Gets the recipient user ID for DMs. */
getRecipientId(): string | undefined;
/** Checks if the channel has a specific flag. */
hasFlag(flag: number): boolean;
/** Returns a new Channel with the given properties merged. */
merge(props: Record<string, unknown>): this;
/** Returns a new Channel with the given property set. */
set(key: string, value: unknown): this;
/** Converts the channel to a plain JavaScript object. */
toJS(): Record<string, unknown>;
/** Whether this is an active (non-archived) thread. */
isActiveThread(): boolean;
/** Whether this is an announcement thread. */
isAnnouncementThread(): boolean;
/** Whether this is an archived and locked thread. */
isArchivedLockedThread(): boolean;
/** Whether this is an archived thread. */
isArchivedThread(): boolean;
/** Whether this is a category channel. */
isCategory(): boolean;
/** Whether this is a DM channel. */
isDM(): boolean;
/** Whether this is a directory channel. */
isDirectory(): boolean;
/** Whether this is a forum channel. */
isForumChannel(): boolean;
/** Whether this is a forum-like channel (forum or media). */
isForumLikeChannel(): boolean;
/** Whether this is a forum post thread. */
isForumPost(): boolean;
/** Whether this is a group DM. */
isGroupDM(): boolean;
/** Whether this is a stage voice channel. */
isGuildStageVoice(): boolean;
/** Whether this is a guild voice or stage channel. */
isGuildVocal(): boolean;
/** Whether this is a guild vocal channel or vocal thread. */
isGuildVocalOrThread(): boolean;
/** Whether this is a guild voice channel. */
isGuildVoice(): boolean;
/** Whether this is a guild voice channel or voice thread. */
isGuildVoiceOrThread(): boolean;
/** Whether this channel supports listen mode. */
isListenModeCapable(): boolean;
/** Whether this is a locked thread. */
isLockedThread(): boolean;
/** Whether this channel is managed by an integration. */
isManaged(): boolean;
/** Whether this is a media channel. */
isMediaChannel(): boolean;
/** Whether this is a media post thread. */
isMediaPost(): boolean;
/** Whether this is a moderator report channel. */
isModeratorReportChannel(): boolean;
/** Whether this is a multi-user DM (group DM). */
isMultiUserDM(): boolean;
/** Whether the channel is marked as NSFW. */
isNSFW(): boolean;
isOwner(): boolean;
/**
* Checks if the given user is the channel owner.
* @param userId User ID to check.
*/
isOwner(userId: string): boolean;
/** Whether this is a private channel (DM or group DM). */
isPrivate(): boolean;
/** Whether this channel supports ringing. */
isRingable(): boolean;
/** Whether this is a role subscription template preview channel. */
isRoleSubscriptionTemplatePreviewChannel(): boolean;
/** Whether this channel is scheduled for deletion. */
isScheduledForDeletion(): boolean;
/** Whether this is a system DM (from Discord). */
isSystemDM(): boolean;
/** Whether this is any type of thread. */
isThread(): boolean;
/** Whether this channel supports voice. */
isVocal(): boolean;
/** Whether this is a vocal thread. */
isVocalThread(): boolean;
/**
* Adds a recipient to a group DM.
* @param userId User ID to add.
* @param nick Optional nickname for the user.
* @param currentUserId Current user's ID.
*/
addRecipient(userId: string, nick?: string | null, currentUserId?: string): this;
/**
* Removes a recipient from a group DM.
* @param userId User ID to remove.
*/
removeRecipient(userId: string): this;
}

View file

@ -1,9 +1,18 @@
import { Role } from './Role';
import { DiscordRecord } from './Record';
import {
GuildDefaultMessageNotifications,
GuildExplicitContentFilter,
GuildMFALevel,
GuildNSFWLevel,
GuildPremiumTier,
GuildVerificationLevel,
PermissionOverwriteType,
SystemChannelFlags,
} from "../../enums";
// copy(Object.keys(findByProps("CREATOR_MONETIZABLE")).map(JSON.stringify).join("|"))
export type GuildFeatures =
"INVITE_SPLASH" | "VIP_REGIONS" | "VANITY_URL" | "MORE_EMOJI" | "MORE_STICKERS" | "MORE_SOUNDBOARD" | "VERIFIED" | "COMMERCE" | "DISCOVERABLE" | "COMMUNITY" | "FEATURABLE" | "NEWS" | "HUB" | "PARTNERED" | "ANIMATED_ICON" | "BANNER" | "ENABLED_DISCOVERABLE_BEFORE" | "WELCOME_SCREEN_ENABLED" | "MEMBER_VERIFICATION_GATE_ENABLED" | "PREVIEW_ENABLED" | "ROLE_SUBSCRIPTIONS_ENABLED" | "ROLE_SUBSCRIPTIONS_AVAILABLE_FOR_PURCHASE" | "CREATOR_MONETIZABLE" | "CREATOR_MONETIZABLE_PROVISIONAL" | "CREATOR_MONETIZABLE_WHITEGLOVE" | "CREATOR_MONETIZABLE_DISABLED" | "CREATOR_MONETIZABLE_RESTRICTED" | "CREATOR_STORE_PAGE" | "CREATOR_MONETIZABLE_PENDING_NEW_OWNER_ONBOARDING" | "PRODUCTS_AVAILABLE_FOR_PURCHASE" | "GUILD_WEB_PAGE_VANITY_URL" | "THREADS_ENABLED" | "THREADS_ENABLED_TESTING" | "NEW_THREAD_PERMISSIONS" | "ROLE_ICONS" | "TEXT_IN_STAGE_ENABLED" | "TEXT_IN_VOICE_ENABLED" | "HAS_DIRECTORY_ENTRY" | "ANIMATED_BANNER" | "LINKED_TO_HUB" | "EXPOSED_TO_ACTIVITIES_WTP_EXPERIMENT" | "GUILD_HOME_DEPRECATION_OVERRIDE" | "GUILD_HOME_TEST" | "GUILD_HOME_OVERRIDE" | "GUILD_ONBOARDING" | "GUILD_ONBOARDING_EVER_ENABLED" | "GUILD_ONBOARDING_HAS_PROMPTS" | "GUILD_SERVER_GUIDE" | "INTERNAL_EMPLOYEE_ONLY" | "AUTO_MODERATION" | "INVITES_DISABLED" | "BURST_REACTIONS" | "SOUNDBOARD" | "SHARD" | "ACTIVITY_FEED_ENABLED_BY_USER" | "ACTIVITY_FEED_DISABLED_BY_USER" | "SUMMARIES_ENABLED_GA" | "LEADERBOARD_ENABLED" | "SUMMARIES_ENABLED_BY_USER" | "SUMMARIES_OPT_OUT_EXPERIENCE" | "CHANNEL_ICON_EMOJIS_GENERATED" | "NON_COMMUNITY_RAID_ALERTS" | "RAID_ALERTS_DISABLED" | "AUTOMOD_TRIGGER_USER_PROFILE" | "ENABLED_MODERATION_EXPERIENCE_FOR_NON_COMMUNITY" | "GUILD_PRODUCTS_ALLOW_ARCHIVED_FILE" | "CLAN" | "MEMBER_VERIFICATION_MANUAL_APPROVAL" | "FORWARDING_DISABLED" | "MEMBER_VERIFICATION_ROLLOUT_TEST" | "AUDIO_BITRATE_128_KBPS" | "AUDIO_BITRATE_256_KBPS" | "AUDIO_BITRATE_384_KBPS" | "VIDEO_BITRATE_ENHANCED" | "MAX_FILE_SIZE_50_MB" | "MAX_FILE_SIZE_100_MB" | "GUILD_TAGS" | "ENHANCED_ROLE_COLORS" | "PREMIUM_TIER_3_OVERRIDE" | "REPORT_TO_MOD_PILOT" | "TIERLESS_BOOSTING_SYSTEM_MESSAGE";
"ACTIVITY_FEED_DISABLED_BY_USER" | "ACTIVITY_FEED_ENABLED_BY_USER" | "AGE_VERIFICATION_LARGE_GUILD" | "ANIMATED_BANNER" | "ANIMATED_ICON" | "AUDIO_BITRATE_128_KBPS" | "AUDIO_BITRATE_256_KBPS" | "AUDIO_BITRATE_384_KBPS" | "AUTOMOD_TRIGGER_USER_PROFILE" | "AUTO_MODERATION" | "BANNER" | "BURST_REACTIONS" | "BYPASS_SLOWMODE_PERMISSION_MIGRATION_COMPLETE" | "CHANNEL_ICON_EMOJIS_GENERATED" | "CLAN" | "COMMERCE" | "COMMUNITY" | "CREATOR_MONETIZABLE" | "CREATOR_MONETIZABLE_DISABLED" | "CREATOR_MONETIZABLE_PENDING_NEW_OWNER_ONBOARDING" | "CREATOR_MONETIZABLE_PROVISIONAL" | "CREATOR_MONETIZABLE_RESTRICTED" | "CREATOR_MONETIZABLE_WHITEGLOVE" | "CREATOR_STORE_PAGE" | "DISCOVERABLE" | "ENABLED_DISCOVERABLE_BEFORE" | "ENABLED_MODERATION_EXPERIENCE_FOR_NON_COMMUNITY" | "ENHANCED_ROLE_COLORS" | "EXPOSED_TO_ACTIVITIES_WTP_EXPERIMENT" | "FEATURABLE" | "FORWARDING_DISABLED" | "GAME_SERVERS" | "GUILD_HOME_DEPRECATION_OVERRIDE" | "GUILD_HOME_OVERRIDE" | "GUILD_HOME_TEST" | "GUILD_ONBOARDING" | "GUILD_ONBOARDING_EVER_ENABLED" | "GUILD_ONBOARDING_HAS_PROMPTS" | "GUILD_PRODUCTS_ALLOW_ARCHIVED_FILE" | "GUILD_SERVER_GUIDE" | "GUILD_TAGS" | "GUILD_TAGS_BADGE_PACK_FLEX" | "GUILD_TAGS_BADGE_PACK_PETS" | "GUILD_WEB_PAGE_VANITY_URL" | "HAS_DIRECTORY_ENTRY" | "HUB" | "INTERNAL_EMPLOYEE_ONLY" | "INVITES_DISABLED" | "INVITE_SPLASH" | "LINKED_TO_HUB" | "MAX_FILE_SIZE_100_MB" | "MAX_FILE_SIZE_50_MB" | "MEMBER_VERIFICATION_GATE_ENABLED" | "MEMBER_VERIFICATION_MANUAL_APPROVAL" | "MEMBER_VERIFICATION_ROLLOUT_TEST" | "MORE_EMOJI" | "MORE_SOUNDBOARD" | "MORE_STICKERS" | "NEWS" | "NEW_THREAD_PERMISSIONS" | "NON_COMMUNITY_RAID_ALERTS" | "PARTNERED" | "PIN_PERMISSION_MIGRATION_COMPLETE" | "PREMIUM_TIER_3_OVERRIDE" | "PREVIEW_ENABLED" | "PRODUCTS_AVAILABLE_FOR_PURCHASE" | "RAID_ALERTS_DISABLED" | "RELAY_ENABLED" | "REPORT_TO_MOD_PILOT" | "REPORT_TO_MOD_SURVEY" | "ROLE_ICONS" | "ROLE_SUBSCRIPTIONS_AVAILABLE_FOR_PURCHASE" | "ROLE_SUBSCRIPTIONS_ENABLED" | "SOCIAL_LAYER_STOREFRONT" | "SOUNDBOARD" | "SUMMARIES_ENABLED_BY_USER" | "SUMMARIES_ENABLED_GA" | "SUMMARIES_OPT_OUT_EXPERIENCE" | "TEXT_IN_STAGE_ENABLED" | "TEXT_IN_VOICE_ENABLED" | "THREADS_ENABLED" | "THREADS_ENABLED_TESTING" | "TIERLESS_BOOSTING_SYSTEM_MESSAGE" | "VANITY_URL" | "VERIFIED" | "VIDEO_BITRATE_ENHANCED" | "VIP_REGIONS" | "WELCOME_SCREEN_ENABLED";
export type GuildPremiumFeatures =
"ANIMATED_ICON" | "STAGE_CHANNEL_VIEWERS_150" | "ROLE_ICONS" | "GUILD_TAGS" | "BANNER" | "MAX_FILE_SIZE_50_MB" | "VIDEO_QUALITY_720_60FPS" | "STAGE_CHANNEL_VIEWERS_50" | "VIDEO_QUALITY_1080_60FPS" | "MAX_FILE_SIZE_100_MB" | "VANITY_URL" | "VIDEO_BITRATE_ENHANCED" | "STAGE_CHANNEL_VIEWERS_300" | "AUDIO_BITRATE_128_KBPS" | "ANIMATED_BANNER" | "TIERLESS_BOOSTING" | "ENHANCED_ROLE_COLORS" | "INVITE_SPLASH" | "AUDIO_BITRATE_256_KBPS" | "AUDIO_BITRATE_384_KBPS";
@ -16,15 +25,15 @@ export class Guild extends DiscordRecord {
1: number;
2: number;
};
application_id: unknown;
application_id: string | null;
banner: string | undefined;
defaultMessageNotifications: number;
defaultMessageNotifications: GuildDefaultMessageNotifications;
description: string | undefined;
discoverySplash: string | undefined;
explicitContentFilter: number;
explicitContentFilter: GuildExplicitContentFilter;
features: Set<GuildFeatures>;
homeHeader: string | undefined;
hubType: unknown;
hubType: number | null;
icon: string | undefined;
id: string;
joinedAt: Date;
@ -32,10 +41,13 @@ export class Guild extends DiscordRecord {
maxMembers: number;
maxStageVideoChannelUsers: number;
maxVideoChannelUsers: number;
mfaLevel: number;
moderatorReporting: unknown;
mfaLevel: GuildMFALevel;
moderatorReporting: {
moderatorReportingEnabled: boolean;
moderatorReportChannelId: string;
} | null;
name: string;
nsfwLevel: number;
nsfwLevel: GuildNSFWLevel;
ownerConfiguredContentLevel: number;
ownerId: string;
preferredLocale: string;
@ -47,18 +59,25 @@ export class Guild extends DiscordRecord {
};
premiumProgressBarEnabled: boolean;
premiumSubscriberCount: number;
premiumTier: 0 | 1 | 2 | 3;
premiumTier: GuildPremiumTier;
profile: {
badge: string | undefined;
tag: string | undefined;
} | undefined;
publicUpdatesChannelId: string | undefined;
roles: Record<string, Role>;
rulesChannelId: string | undefined;
safetyAlertsChannelId: string | undefined;
splash: string | undefined;
systemChannelFlags: number;
systemChannelFlags: SystemChannelFlags;
systemChannelId: string | undefined;
vanityURLCode: string | undefined;
verificationLevel: number;
verificationLevel: GuildVerificationLevel;
}
export interface RoleOrUserPermission {
type: PermissionOverwriteType;
id?: string;
permissions?: bigint;
overwriteAllow?: bigint;
overwriteDeny?: bigint;
}

View file

@ -1,26 +1,30 @@
import { GuildMemberFlags } from "../../enums";
import { Collectibles, DisplayNameStyles } from "./Channel";
export interface GuildMember {
avatar: string | undefined;
avatarDecoration: string | undefined;
banner: string | undefined;
bio: string;
avatar: string | null | undefined;
avatarDecoration: string | null | undefined;
collectibles: Collectibles | null;
colorRoleId: string | undefined;
colorString: string;
colorString: string | undefined;
colorStrings: {
primaryColor: string | undefined;
secondaryColor: string | undefined;
tertiaryColor: string | undefined;
};
communicationDisabledUntil: string | undefined;
flags: number;
fullProfileLoadedTimestamp: number;
} | null;
communicationDisabledUntil: string | null | undefined;
displayNameStyles: DisplayNameStyles | null;
flags: GuildMemberFlags;
fullProfileLoadedTimestamp: number | undefined;
guildId: string;
highestRoleId: string;
hoistRoleId: string;
iconRoleId: string;
highestRoleId: string | undefined;
hoistRoleId: string | undefined;
iconRoleId: string | undefined;
isPending: boolean | undefined;
joinedAt: string | undefined;
nick: string | undefined;
premiumSince: string | undefined;
nick: string | null | undefined;
premiumSince: string | null | undefined;
roles: string[];
unusualDMActivityUntil: string | undefined;
userId: string;
}

View file

@ -1,3 +1,5 @@
import { RoleFlags } from "../../enums";
export interface Role {
color: number;
colorString: string | undefined;
@ -11,23 +13,25 @@ export interface Role {
secondary_color: number | undefined;
tertiary_color: number | undefined;
};
flags: number;
description: string | undefined;
flags: RoleFlags;
guildId: string;
hoist: boolean;
icon: string | undefined;
id: string;
managed: boolean;
mentionable: boolean;
name: string;
originalPosition: number;
permissions: bigint;
position: number;
/**
* probably incomplete
*/
tags: {
bot_id: string;
integration_id: string;
premium_subscriber: unknown;
bot_id?: string;
integration_id?: string;
premium_subscriber?: unknown;
subscription_listing_id?: string;
available_for_purchase?: unknown;
guild_connections?: unknown;
} | undefined;
unicodeEmoji: string | undefined;
version: number | undefined;
}

View file

@ -1,65 +1,134 @@
// TODO: a lot of optional params can also be null, not just undef
import { DiscordRecord } from "./Record";
import { AvatarDecorationData, ClanData, Collectibles, DisplayNameStyles } from "./Channel";
import { PremiumType, UserFlags } from "../../enums";
export class User extends DiscordRecord {
constructor(user: object);
accentColor: number;
ageVerificationStatus: number;
avatar: string;
avatarDecorationData: AvatarDecorationData | null;
banner: string | null | undefined;
bio: string;
bot: boolean;
collectibles: Collectibles | null;
desktop: boolean;
discriminator: string;
displayNameStyles: DisplayNameStyles | null;
email: string | undefined;
flags: number;
flags: UserFlags;
globalName: string | undefined;
guildMemberAvatars: Record<string, string>;
hasBouncedEmail: boolean;
id: string;
mfaEnabled: boolean;
mobile: boolean;
nsfwAllowed: boolean | undefined;
personalConnectionId: string | null;
phone: string | undefined;
premiumType: number | undefined;
premiumState: { subscriptionId: string; } | null;
premiumType: PremiumType | undefined;
premiumUsageFlags: number;
publicFlags: number;
primaryGuild: ClanData | null;
publicFlags: UserFlags;
purchasedFlags: number;
system: boolean;
username: string;
verified: boolean;
get avatarDecoration(): AvatarDecorationData | null;
get createdAt(): Date;
get hasPremiumPerks(): boolean;
get isProvisional(): boolean;
get nameplate(): { asset: string; skuId: string; } | null;
get premiumGroupRole(): { id: string; name: string; color: number; } | null;
get tag(): string;
get usernameNormalized(): string;
addGuildAvatarHash(guildId: string, avatarHash: string): User;
getAvatarSource(guildId: string, canAnimate?: boolean): { uri: string; };
getAvatarURL(guildId?: string | null, t?: unknown, canAnimate?: boolean): string;
addGuildAvatarHash(guildId: string, avatarHash: string): this;
getAvatarSource(guildId: string): { uri: string; };
getAvatarURL(guildId?: string | null, size?: number, canAnimate?: boolean, format?: string): string;
hadPremiumSubscription(): boolean;
hasAvatarForGuild(guildId: string): boolean;
hasDisabledPremium(): boolean;
hasFlag(flag: number): boolean;
hasFlag(flag: UserFlags): boolean;
hasFreePremium(): boolean;
hasHadSKU(e: unknown): boolean;
hasHadPremium(): boolean;
hasHadSKU(sku: string): boolean;
hasPremiumUsageFlag(flag: number): boolean;
hasPurchasedFlag(flag: number): boolean;
hasUniqueUsername(): boolean;
hasUrgentMessages(): boolean;
hasVerifiedEmailOrPhone(): boolean;
isClaimed(): boolean;
isFractionalPremiumWithNoSubscription(): boolean;
isLocalBot(): boolean;
isNonUserBot(): boolean;
isPhoneVerified(): boolean;
isStaff(): boolean;
isPremiumGroupMember(): boolean;
isPremiumGroupPrimary(): boolean;
isPremiumWithFractionalPremiumOnly(): boolean;
isPremiumWithPremiumGroup(): boolean;
isSystemUser(): boolean;
isVerifiedBot(): boolean;
removeGuildAvatarHash(guildId: string): User;
removeGuildAvatarHash(guildId: string): this;
toJS(): object;
toString(): string;
update(props: Partial<User>): this;
}
export interface UserJSON {
avatar: string;
avatarDecoration: unknown | undefined;
avatarDecoration: AvatarDecorationData | null;
discriminator: string;
id: string;
publicFlags: number;
publicFlags: UserFlags;
username: string;
globalName: string | undefined;
}
export interface ProfileEffect {
skuId: string;
title?: string;
description?: string;
accessibilityLabel?: string;
reducedMotionSrc?: string;
thumbnailPreviewSrc?: string;
effects?: any[];
animationType?: number;
staticFrameSrc?: string;
type?: number;
}
export interface Nameplate {
skuId: string;
asset: string;
label?: string;
palette?: string;
type?: number;
}
export interface ProfilePreset {
name: string;
timestamp: number;
avatarDataUrl?: string | null;
bannerDataUrl?: string | null;
bio?: string | null;
accentColor?: number | null;
themeColors?: number[] | null;
globalName?: string | null;
pronouns?: string | null;
avatarDecoration?: {
asset: string;
skuId: string;
} | null;
profileEffect?: ProfileEffect | null;
nameplate?: Nameplate | null;
primaryGuildId?: string | null;
customStatus?: CustomStatus | null;
displayNameStyles?: DisplayNameStyles | null;
}
export interface CustomStatus {
text?: string;
emojiId?: string;
emojiName?: string;
expiresAtMs?: string;
}

View file

@ -1,41 +1,74 @@
export type EmbedType =
| "image"
| "video"
| "link"
| "article"
| "tweet"
| "rich"
| "gifv"
| "application_news"
| "auto_moderation_message"
| "auto_moderation_notification"
| "text"
| "post_preview"
| "gift"
| "safety_policy_notice"
| "safety_system_notification"
| "age_verification_system_notification"
| "voice_channel"
| "gaming_profile"
| "poll_result";
export interface EmbedMedia {
height: number;
width: number;
url: string;
proxyURL?: string;
placeholder: string;
placeholderVersion: number;
description?: string;
srcIsAnimated: boolean;
flags: number;
contentType: string;
}
export interface EmbedField {
rawName: string;
rawValue: string;
inline: boolean;
}
export interface Embed {
id: string;
url: string;
type: EmbedType;
rawTitle: string;
rawDescription: string;
referenceId: string | undefined;
flags: number | undefined;
contentScanVersion: number;
author?: {
name: string;
url: string;
iconURL: string | undefined;
iconProxyURL: string | undefined;
};
color: string;
fields: [];
id: string;
image?: {
height: number;
width: number;
url: string;
proxyURL: string;
footer?: {
text: string;
iconURL: string | undefined;
iconProxyURL: string | undefined;
};
provider?: {
name: string;
url: string | undefined;
};
rawDescription: string;
rawTitle: string;
referenceId: unknown;
timestamp: string;
thumbnail?: {
height: number;
proxyURL: string | undefined;
url: string;
width: number;
};
type: string;
url: string | undefined;
video?: {
height: number;
width: number;
url: string;
proxyURL: string | undefined;
};
timestamp?: Date;
color: string;
thumbnail?: EmbedMedia;
image?: EmbedMedia;
images?: EmbedMedia[];
video?: EmbedMedia;
fields: EmbedField[];
}
export interface EmbedJSON {
@ -48,7 +81,7 @@ export interface EmbedJSON {
title: string;
color: string;
description: string;
type: string;
type: EmbedType;
url: string | undefined;
provider?: {
name: string;

View file

@ -2,60 +2,135 @@ import { CommandOption } from './Commands';
import { User, UserJSON } from '../User';
import { Embed, EmbedJSON } from './Embed';
import { DiscordRecord } from "../Record";
import { ApplicationIntegrationType, MessageFlags, MessageType, StickerFormatType } from "../../../enums";
import { ApplicationCommandOptionType, ApplicationCommandType, ApplicationIntegrationType, ButtonStyle, ComponentType, InteractionType, MessageActivityType, MessageFlags, MessageReferenceType, MessageType, PollLayoutType, StickerFormatType } from "../../../enums";
export type MessageState = "SENT" | "SENDING" | "SEND_FAILED";
export type CodedLinkType =
| "INVITE"
| "TEMPLATE"
| "BUILD_OVERRIDE"
| "MANUAL_BUILD_OVERRIDE"
| "EXPERIMENT"
| "EVENT"
| "CHANNEL_LINK"
| "APP_DIRECTORY_PROFILE"
| "APP_DIRECTORY_STOREFRONT"
| "APP_DIRECTORY_STOREFRONT_SKU"
| "APP_OAUTH2_LINK"
| "ACTIVITY_BOOKMARK"
| "EMBEDDED_ACTIVITY_INVITE"
| "GUILD_PRODUCT"
| "SERVER_SHOP"
| "SOCIAL_LAYER_STOREFRONT"
| "QUESTS_EMBED"
| "COLLECTIBLES_SHOP";
export interface MessageActivity {
type: MessageActivityType;
party_id?: string;
}
export interface PollMedia {
text?: string;
emoji?: ReactionEmoji;
}
export interface PollAnswer {
answer_id: number;
poll_media: PollMedia;
}
export interface Poll {
question: PollMedia;
answers: PollAnswer[];
expiry: string;
allow_multiselect: boolean;
layout_type: PollLayoutType;
}
export interface RoleSubscriptionData {
role_subscription_listing_id: string;
tier_name: string;
total_months_subscribed: number;
is_renewal: boolean;
}
export interface MessageComponent {
type: ComponentType;
id?: string;
custom_id?: string;
disabled?: boolean;
style?: ButtonStyle;
label?: string;
emoji?: ReactionEmoji;
url?: string;
options?: { label: string; value: string; description?: string; emoji?: ReactionEmoji; default?: boolean; }[];
placeholder?: string;
min_values?: number;
max_values?: number;
components?: MessageComponent[];
}
/*
* TODO: looks like discord has moved over to Date instead of Moment;
*/
export class Message extends DiscordRecord {
constructor(message: object);
activity: unknown;
application: unknown;
applicationId: string | unknown;
activity: MessageActivity | null;
activityInstance: { applicationId: string; instanceId: string; } | null;
application: { id: string; name: string; icon: string | null; } | null;
applicationId: string | null;
attachments: MessageAttachment[];
author: User;
blocked: boolean;
bot: boolean;
call: {
duration: moment.Duration;
endedTimestamp: moment.Moment;
duration: number | null;
endedTimestamp: Date | null;
participants: string[];
};
} | null;
changelogId: string | null;
channel_id: string;
/**
* NOTE: not fully typed
*/
codedLinks: {
code?: string;
type: string;
type: CodedLinkType;
}[];
colorString: unknown;
components: unknown[];
colorString: string | null;
components: MessageComponent[];
content: string;
customRenderedContent: unknown;
editedTimestamp: Date;
customRenderedContent: {
content: React.ReactNode;
[key: string]: unknown;
} | null;
editedTimestamp: Date | null;
embeds: Embed[];
flags: MessageFlags;
giftCodes: string[];
giftInfo: { sku_id: string; slug: string; } | null;
giftingPrompt: { recipientUserId: string; } | null;
id: string;
interaction: {
id: string;
name: string;
type: number;
type: InteractionType;
user: User;
}[] | undefined;
}[] | null;
interactionData: {
application_command: {
application_id: string;
default_member_permissions: unknown;
default_member_permissions: string | null;
default_permission: boolean;
description: string;
dm_permission: unknown;
dm_permission: boolean | null;
id: string;
name: string;
options: CommandOption[];
permissions: unknown[];
type: number;
permissions: string[];
type: ApplicationCommandType;
version: string;
};
attachments: MessageAttachment[];
@ -63,19 +138,19 @@ export class Message extends DiscordRecord {
id: string;
name: string;
options: {
focused: unknown;
focused: boolean | undefined;
name: string;
type: number;
type: ApplicationCommandOptionType;
value: string;
}[];
type: number;
type: InteractionType;
version: string;
}[];
interactionMetadata?: {
}[] | null;
interactionMetadata: {
id: string;
type: number;
type: InteractionType;
name?: string;
command_type?: number;
command_type?: ApplicationCommandType;
ephemerality_reason?: number;
user: User;
authorizing_integration_owners: Record<ApplicationIntegrationType, string>;
@ -83,16 +158,20 @@ export class Message extends DiscordRecord {
interacted_message_id?: string;
target_user?: User;
target_message_id?: string;
};
interactionError: unknown[];
} | null;
interactionError: string[] | null;
ignored: boolean;
isSearchHit: boolean;
loggingName: unknown;
isUnsupported: boolean;
loggingName: string | null;
mentionChannels: string[];
mentionEveryone: boolean;
mentionGames: { id: string; name: string; }[];
mentionRoles: string[];
mentioned: boolean;
mentions: string[];
messageReference: {
type?: MessageReferenceType;
guild_id?: string;
channel_id: string;
message_id: string;
@ -100,18 +179,26 @@ export class Message extends DiscordRecord {
messageSnapshots: {
message: Message;
}[];
nick: unknown; // probably a string
nick: string | null;
nonce: string | undefined;
pinned: boolean;
poll: Poll | null;
potions: { id: string; expiresAt: string; }[];
premiumGroupInviteId: string | null;
purchaseNotification: { type: number; guild_product_purchase?: { product_name: string; }; } | null;
reactions: MessageReaction[];
state: string;
referralTrialOfferId: string | null;
roleSubscriptionData: RoleSubscriptionData | null;
sharedClientTheme: { primary_color: number; secondary_color: number; } | null;
soundboardSounds: { sound_id: string; volume: number; emoji_id?: string; emoji_name?: string; }[];
state: MessageState;
stickerItems: {
format_type: StickerFormatType;
id: string;
name: string;
}[];
stickers: unknown[];
timestamp: moment.Moment;
stickers: { id: string; name: string; format_type: StickerFormatType; }[];
timestamp: Date;
tts: boolean;
type: MessageType;
webhookId: string | undefined;
@ -134,10 +221,18 @@ export class Message extends DiscordRecord {
removeReaction(emoji: ReactionEmoji, fromCurrentUser: boolean): Message;
getChannelId(): string;
getContentMessage(): Message;
hasFlag(flag: MessageFlags): boolean;
hasPotions(): boolean;
isCommandType(): boolean;
isEdited(): boolean;
isFirstMessageInForumPost(channel: unknown): boolean;
isInteractionPlaceholder(): boolean;
isPoll(): boolean;
isSystemDM(): boolean;
canDeleteOwnMessage(userId: string): boolean;
userHasReactedWithEmoji(emoji: ReactionEmoji, burst?: boolean): boolean;
addReactionBatch(reactions: { emoji: ReactionEmoji; users: string[]; }[], burstReactions: { emoji: ReactionEmoji; users: string[]; }[]): Message;
/** Vencord added */
deleted?: boolean;
@ -148,14 +243,14 @@ export interface MessageJSON {
attachments: MessageAttachment[];
author: UserJSON;
channel_id: string;
components: unknown[];
components: MessageComponent[];
content: string;
edited_timestamp: string;
embeds: EmbedJSON[];
flags: number;
flags: MessageFlags;
guild_id: string | undefined;
id: string;
loggingName: unknown;
loggingName: string | null;
member: {
avatar: string | undefined;
communication_disabled_until: string | undefined;
@ -180,10 +275,10 @@ export interface MessageJSON {
nonce: string | undefined;
pinned: boolean;
referenced_message: MessageJSON | undefined;
state: string;
state: MessageState;
timestamp: string;
tts: boolean;
type: number;
type: MessageType;
}
export interface MessageAttachment {

View file

@ -1,7 +1,7 @@
import { StickerFormatType, StickerType } from "../../../enums";
interface BaseSticker {
asset: string;
asset?: string;
available: boolean;
description: string;
format_type: StickerFormatType;

View file

@ -1,3 +1,4 @@
import { Moment } from "moment";
import type { ComponentClass, ComponentPropsWithRef, ComponentType, CSSProperties, FunctionComponent, HtmlHTMLAttributes, HTMLProps, JSX, KeyboardEvent, MouseEvent, PointerEvent, PropsWithChildren, ReactNode, Ref, RefObject } from "react";
@ -153,7 +154,7 @@ export type Checkbox = ComponentType<PropsWithChildren<{
};
export type Timestamp = ComponentType<PropsWithChildren<{
timestamp: Date;
timestamp: Date | Moment;
isEdited?: boolean;
className?: string;
@ -193,7 +194,7 @@ export type TextArea = ComponentType<Omit<HTMLProps<HTMLTextAreaElement>, "onCha
inputRef?: Ref<HTMLTextAreaElement>;
}>;
interface SelectOption {
export interface SelectOption {
disabled?: boolean;
value: any;
label: string;
@ -392,6 +393,7 @@ export type Paginator = ComponentType<{
pageSize: number;
totalCount: number;
className?: string;
onPageChange?(page: number): void;
hideMaxPage?: boolean;
}>;
@ -409,6 +411,24 @@ export type MaskedLink = ComponentType<PropsWithChildren<{
channelId?: string;
}>>;
interface ScrollToOptions {
animate?: boolean;
callback?: (() => unknown);
}
/** Full type can be found at {@link https://github.com/fedeericodl/discord-client-types/blob/main/src/discord_common/js/packages/design/components/Scroller/utils/core/getAnimatedScrollHelpers.ts} */
export interface ScrollerBaseRef {
scrollTo: (props: { to: number; } & ScrollToOptions) => void;
scrollPageUp: (props?: ScrollToOptions) => void;
scrollPageDown: (props?: ScrollToOptions) => void;
scrollToTop: (props?: ScrollToOptions) => void;
scrollToBottom: (props?: ScrollToOptions) => void;
isScrolledToTop: () => boolean;
isScrolledToBottom: () => boolean;
getDistanceFromTop: () => number;
getDistanceFromBottom: () => number;
}
export interface ScrollerBaseProps {
className?: string;
style?: CSSProperties;
@ -416,6 +436,7 @@ export interface ScrollerBaseProps {
paddingFix?: boolean;
onClose?(): void;
onScroll?(): void;
ref?: Ref<ScrollerBaseRef>;
}
export type ScrollerThin = ComponentType<PropsWithChildren<ScrollerBaseProps & {
@ -446,9 +467,9 @@ export type ListScrollerThin = ComponentType<ScrollerBaseProps & {
renderSidebar?: (listVisible: boolean, sidebarVisible: boolean) => React.ReactNode;
wrapSection?: (section: number, children: React.ReactNode) => React.ReactNode;
sectionHeight: number;
rowHeight: number;
footerHeight?: number;
sectionHeight: number | ((section: number) => number);
rowHeight: number | ((section: number, row: number) => number);
footerHeight?: number | ((section: number) => number);
sidebarHeight?: number;
chunkSize?: number;
@ -479,6 +500,7 @@ export type Avatar = ComponentType<PropsWithChildren<{
src?: string;
size?: "SIZE_16" | "SIZE_20" | "SIZE_24" | "SIZE_32" | "SIZE_40" | "SIZE_48" | "SIZE_56" | "SIZE_80" | "SIZE_120";
status?: string;
statusColor?: string;
statusTooltip?: string;
statusBackdropColor?: string;
@ -497,6 +519,12 @@ type FocusLock = ComponentType<PropsWithChildren<{
containerRef: Ref<HTMLElement>;
}>>;
export type Dots = ComponentType<PropsWithChildren<{
dotRadius: number;
themed?: boolean;
className?: string;
}>>;
export type Icon = ComponentType<JSX.IntrinsicElements["svg"] & {
size?: string;
colorClass?: string;

View file

@ -1,5 +1,42 @@
import { GuildMemberFlags } from "../enums";
import { VoiceState } from "./stores";
import { FluxStore } from "./stores/FluxStore";
export interface PassiveUpdateState {
type: string;
guildId: string;
members?: ({
user: {
avatar: string | null;
communication_disabled_until: string | null;
deaf: boolean;
flags: GuildMemberFlags;
joined_at: string;
mute: boolean;
nick: string;
pending: boolean;
premium_since: string | null;
};
roles: string[];
premium_since: string | null;
pending: boolean;
nick: string | null;
mute: boolean;
joined_at: string;
flags: GuildMemberFlags;
deaf: boolean;
communication_disabled_until: string | null;
avatar: string | null;
})[];
channels: ({
lastPinTimestamp?: string;
lastMessageId: string;
id: string;
})[];
voiceStates?: VoiceState[];
}
export class FluxEmitter {
constructor();

File diff suppressed because one or more lines are too long

View file

@ -50,10 +50,10 @@ export interface Menu {
control: ForwardRefRenderFunction<any, any>;
}>;
MenuSliderControl: RC<{
minValue: number,
maxValue: number,
value: number,
onChange(value: number): void,
minValue?: number,
maxValue?: number,
value?: number,
onChange?(value: number): void,
renderValue?(value: number): string,
}>;
MenuSearchControl: RC<{
@ -77,4 +77,3 @@ export interface ContextMenuApi {
options?: { enableSpellCheck?: boolean; }
): void;
}

View file

@ -16,7 +16,6 @@ export interface ReactNativeUploadItem extends BaseUploadItem {
mimeType?: string;
durationSecs?: number;
waveform?: string;
isRemix?: boolean;
}
export interface WebUploadItem extends BaseUploadItem {
@ -41,7 +40,6 @@ export class CloudUpload extends EventEmitter {
filename: string;
id: string;
isImage: boolean;
isRemix: boolean | undefined;
isThumbnail: boolean;
isVideo: boolean;
item: {

View file

@ -4,12 +4,13 @@ export type ReducedMotionPreference = "auto" | "reduce" | "no-preference";
export type ForcedColorsPreference = "none" | "active";
export type ContrastPreference = "no-preference" | "more" | "less" | "custom";
export type RoleStyle = "username" | "dot" | "hidden";
export type ContrastMode = "default" | "high";
export interface AccessibilityState {
fontSize: number;
zoom: number;
keyboardModeEnabled: boolean;
contrastMode: string;
contrastMode: ContrastMode;
colorblindMode: boolean;
lowContrastMode: boolean;
saturation: number;

View file

@ -0,0 +1,443 @@
import { Application, Channel, FluxStore } from "..";
import { CommandArgument, CommandContext } from "../common/messages/Commands";
import {
ApplicationCommandHandlerType,
ApplicationCommandInputType,
ApplicationCommandOptionType,
ApplicationCommandPermissionType,
ApplicationCommandSectionType,
ApplicationCommandType,
ApplicationIntegrationType,
ChannelType,
InteractionContextType
} from "../../enums";
/** Score method for ranking command results. */
export type ApplicationCommandScoreMethod =
| "none"
| "application_only"
| "command_only"
| "command_or_application";
/** Built-in command handling mode. */
export type BuiltInCommandMode =
| "allow"
| "deny"
| "only_text";
/** Target for fetching guild command index. */
export interface ApplicationCommandIndexGuildTarget {
type: "guild";
guildId: string;
}
/** Target for fetching channel command index. */
export interface ApplicationCommandIndexChannelTarget {
type: "channel";
channelId: string;
}
/** Target for fetching user command index. */
export interface ApplicationCommandIndexUserTarget {
type: "user";
}
/** Target for fetching application-specific command index. */
export interface ApplicationCommandIndexApplicationTarget {
type: "application";
applicationId: string;
}
/** Union of all fetch target types. */
export type ApplicationCommandIndexFetchTarget =
| ApplicationCommandIndexGuildTarget
| ApplicationCommandIndexChannelTarget
| ApplicationCommandIndexUserTarget
| ApplicationCommandIndexApplicationTarget;
/** Context for querying commands with a channel. */
export interface ApplicationCommandChannelContext {
type: "channel";
channel: Channel;
}
/** Context for querying commands without a channel. */
export interface ApplicationCommandContextlessContext {
type: "contextless";
}
/** Union of query context types. */
export type ApplicationCommandContext =
| ApplicationCommandChannelContext
| ApplicationCommandContextlessContext;
/** Fetch state when not fetching. */
export interface ApplicationCommandIndexFetchStateIdle {
fetching: false;
retryAfter?: number;
}
/** Fetch state when actively fetching. */
export interface ApplicationCommandIndexFetchStateFetching {
fetching: true;
abort: AbortController;
promise: Promise<void>;
}
/** Union of fetch state types. */
export type ApplicationCommandIndexFetchState =
| ApplicationCommandIndexFetchStateIdle
| ApplicationCommandIndexFetchStateFetching;
/** Result of a successful command index fetch. */
export interface ApplicationCommandIndexResult {
/** Command sections keyed by application ID. */
sections: Record<string, ApplicationCommandSection>;
/** Maps bot user ID to application ID. */
sectionIdsByBotId: Record<string, string>;
/** Version symbol for cache invalidation. */
version: symbol;
}
/** State for a command index entry. */
export interface ApplicationCommandIndexState {
/** Server version symbol for staleness detection. */
serverVersion: symbol;
/** Current fetch state. */
fetchState: ApplicationCommandIndexFetchState;
/** Fetched result, if available. */
result?: ApplicationCommandIndexResult;
}
/** A section containing commands from a single application. */
export interface ApplicationCommandSection {
/** Section descriptor with application info. */
descriptor: ApplicationCommandSectionDescriptor;
/** Commands keyed by command ID. */
commands: Record<string, ApplicationCommand>;
}
/** Descriptor for a command section. */
export interface ApplicationCommandSectionDescriptor {
/** Section ID, typically the application ID or a special value like "-1" for built-in. */
id: string;
/** Section type. */
type: ApplicationCommandSectionType;
/** Display name for the section. */
name: string;
/** Application icon hash. */
icon?: string | null;
/** Full application object for application sections. */
application?: Application;
/** Whether this is a user-installed app. */
isUserApp?: boolean;
/** Bot user ID for this application. */
botId?: string;
/** Permissions for the application's commands. */
permissions?: ApplicationCommandPermission[] | Record<string, ApplicationCommandPermission>;
}
/** Permission override for a command. */
export interface ApplicationCommandPermission {
/** Type of permission target. */
type: ApplicationCommandPermissionType;
/** ID of the role, user, or channel. */
id: string;
/** Whether the target has permission to use the command. */
permission: boolean;
}
/** Option for an application command. */
export interface ApplicationCommandOption {
/** Option type. */
type: ApplicationCommandOptionType;
/** Option name. */
name: string;
/** Localized display name for the option. */
displayName?: string;
/** Localized option name from server. Bot commands only. */
serverLocalizedName?: string;
/** Option description. */
description: string;
/** Localized display description for the option. */
displayDescription?: string;
/** Localized option description from server. Bot commands only. */
serverLocalizedDescription?: string;
/** Whether this option is required. */
required?: boolean;
/** Choices for string/integer/number options. */
choices?: ApplicationCommandOptionChoice[];
/** Nested options for subcommands. */
options?: ApplicationCommandOption[];
/** Channel types allowed for channel options. */
channel_types?: ChannelType[];
/** Minimum value for number/integer options. */
min_value?: number;
/** Maximum value for number/integer options. */
max_value?: number;
/** Minimum length for string options. */
min_length?: number;
/** Maximum length for string options. */
max_length?: number;
/** Whether autocomplete is enabled. */
autocomplete?: boolean;
}
/** Choice for a command option. */
export interface ApplicationCommandOptionChoice {
/** Choice name. */
name: string;
/** Localized choice name, if available. */
name_localized?: string;
/** Choice value. */
value: string | number;
}
/** Raw application command from the API. */
export interface RawApplicationCommand {
id: string;
application_id: string;
version: string;
guild_id?: string;
type?: ApplicationCommandType;
name: string;
name_default?: string;
name_localized?: string;
description: string;
description_default?: string;
description_localized?: string;
options?: ApplicationCommandOption[];
default_member_permissions?: string | null;
dm_permission?: boolean;
nsfw?: boolean;
contexts?: InteractionContextType[];
integration_types?: ApplicationIntegrationType[];
permissions?: ApplicationCommandPermission[];
global_popularity_rank?: number;
handler?: ApplicationCommandHandlerType;
}
/** Processed application command. */
export interface ApplicationCommand {
/** Command version string. Bot commands only. */
version?: string;
/** Guild ID if guild-specific. Bot commands only. */
guildId?: string;
/** Composite command ID including subcommand path. */
id: string;
/** Original untranslated command name. */
untranslatedName: string;
/** Localized command name from server. Bot commands only. */
serverLocalizedName?: string;
/** Application ID. */
applicationId: string;
/** Command type. */
type: ApplicationCommandType;
/** Input type. */
inputType: ApplicationCommandInputType;
/** Original untranslated description. */
untranslatedDescription: string;
/** Command options. */
options: ApplicationCommandOption[];
/** Root command reference for subcommands. Bot commands only. */
rootCommand?: RawApplicationCommand;
/** Path of subcommand options for nested commands. Bot commands only. */
subCommandPath?: ApplicationCommandOption[];
/** Default member permissions required as bigint. Bot commands only. */
defaultMemberPermissions?: bigint;
/** Whether usable in DMs. Bot commands only. */
dmPermission?: boolean;
/** Command permissions. Bot commands only. */
permissions?: ApplicationCommandPermission[] | Record<string, ApplicationCommandPermission>;
/** Localized display name. */
displayName: string;
/** Localized display description. */
displayDescription: string;
/** Whether this is an NSFW command. Bot commands only. */
nsfw?: boolean;
/** Allowed interaction contexts. Bot commands only. */
contexts?: InteractionContextType[];
/** Integration types that can use this command. Bot commands only. */
integration_types?: ApplicationIntegrationType[];
/** Global popularity ranking. Bot commands only. */
global_popularity_rank?: number;
/** Handler type. Bot commands only. */
handler?: ApplicationCommandHandlerType;
/** Section descriptor for display purposes. */
section?: ApplicationCommandSectionDescriptor;
/** Score for search ranking. */
score?: number;
/** Predicate to check if command should be shown. Built-in commands only. */
predicate?(ctx: CommandContext): boolean;
/** Execute the command. Built-in commands only. */
execute?(args: CommandArgument[], ctx: CommandContext): void;
}
/** Sectioned command group for display. */
export interface SectionedApplicationCommands {
/** Section this group belongs to. */
section: ApplicationCommandSectionDescriptor;
/** Commands in this section. */
data: ApplicationCommand[];
}
/** Filter options for querying commands. */
export interface ApplicationCommandQueryFilters {
/** Command types to include. */
commandTypes: ApplicationCommandType[];
/** Search text. */
text?: string;
/** Built-in command handling mode. */
builtIns?: BuiltInCommandMode;
/** Whether to include application commands. */
applicationCommands?: boolean;
}
/** Options for querying commands. */
export interface ApplicationCommandQueryOptions {
/** Number of placeholder commands to show while loading. */
placeholderCount?: number;
/** Score method for ranking results. */
scoreMethod?: ApplicationCommandScoreMethod;
/** Whether to allow empty sections in results. */
allowEmptySections?: boolean;
/** Whether to allow fetching if needed. */
allowFetch?: boolean;
/** Whether to include application state. */
allowApplicationState?: boolean;
/** Specific application ID to query. */
applicationId?: string;
/** Sorting options. */
sortOptions?: ApplicationCommandSortOptions;
/** Whether to include install-on-demand apps. */
installOnDemand?: boolean;
}
/** Sorting options for application command queries. */
export interface ApplicationCommandSortOptions {
/** Sorting options for applications. */
applications: ApplicationCommandSortConfig;
/** Sorting options for commands. */
commands: ApplicationCommandSortConfig;
}
/** Sort configuration for frecency and score. */
export interface ApplicationCommandSortConfig {
/** Whether to use frecency for sorting. */
useFrecency: boolean;
/** Whether to use score for sorting. */
useScore: boolean;
}
/** Result of a command query. */
export interface ApplicationCommandQueryResult {
/** All section descriptors. */
descriptors: ApplicationCommandSectionDescriptor[];
/** Flat list of all commands. */
commands: ApplicationCommand[];
/** Commands grouped by section. */
sectionedCommands: SectionedApplicationCommands[];
/** Whether data is still loading. */
loading: boolean;
}
/** Parameters for checking context state application. */
export interface ApplicationCommandContextStateParams {
applicationId: string;
channelId: string;
guildId?: string;
}
/** Result of getting section info. */
export interface ApplicationCommandSectionInfo {
/** Section descriptor. */
descriptor?: ApplicationCommandSectionDescriptor;
/** Commands in this section. */
sectionCommands?: ApplicationCommand[];
/** Whether installed in a guild. */
isGuildInstalled: boolean;
/** Whether installed for user. */
isUserInstalled: boolean;
}
/**
* Store for application command indexes.
* Manages fetching, caching, and querying of slash commands and context menu commands.
*/
export class ApplicationCommandIndexStore extends FluxStore {
/** Internal index cache keyed by guild/channel/user ID. */
indices: Record<string, ApplicationCommandIndexState>;
/**
* Gets the command index state for the given context.
* @param context Channel context or contextless context.
* @returns Index state for the context.
*/
getContextState(context: ApplicationCommandContext): ApplicationCommandIndexState;
/**
* Checks if an application has commands in the context state.
* @param params Application and channel info.
* @returns Whether the application has commands in context.
*/
hasContextStateApplication(params: ApplicationCommandContextStateParams): boolean;
/**
* Gets the command index state for a guild.
* @param guildId Guild ID.
* @returns Index state for the guild.
*/
getGuildState(guildId: string): ApplicationCommandIndexState;
/**
* Gets the command index state for the current user's installed apps.
* @returns Index state for user-installed apps.
*/
getUserState(): ApplicationCommandIndexState;
/**
* Checks if an application has commands in the user state.
* @param applicationId Application ID.
* @returns Whether the application has user commands.
*/
hasUserStateApplication(applicationId: string): boolean;
/**
* Gets the command index state for a specific application.
* @param applicationId Application ID.
* @returns Index state for the application.
*/
getApplicationState(applicationId: string): ApplicationCommandIndexState;
/**
* Gets all application index states.
* @returns Map of application ID to index state.
*/
getApplicationStates(): Map<string, ApplicationCommandIndexState>;
/**
* Checks if an application state exists.
* @param applicationId Application ID.
* @returns Whether the application state exists.
*/
hasApplicationState(applicationId: string): boolean;
/**
* Queries commands based on context and filters.
* @param context Channel or contextless context.
* @param filters Query filters.
* @param options Query options.
* @returns Query result with commands and sections.
*/
query(
context: ApplicationCommandContext,
filters: ApplicationCommandQueryFilters,
options: ApplicationCommandQueryOptions
): ApplicationCommandQueryResult;
/**
* Queries for install-on-demand app commands.
* @param applicationId Application ID.
* @param channelId Channel ID.
*/
queryInstallOnDemandApp(applicationId: string, channelId: string): void;
}

View file

@ -1,4 +1,5 @@
import { Application, FluxStore } from "..";
import { ApplicationType } from "../../enums";
export interface ApplicationStoreState {
botUserIdToAppUsage: Record<string, ApplicationUsage>;
@ -10,11 +11,12 @@ export interface ApplicationUsage {
}
export class ApplicationStore extends FluxStore {
_getAllApplications(): Application[];
getState(): ApplicationStoreState;
getApplication(applicationId: string): Application;
getApplicationByName(name: string): Application | undefined;
getApplicationLastUpdated(applicationId: string): number | undefined;
getGuildApplication(guildId: string, type: number): Application | undefined;
getGuildApplication(guildId: string, type: ApplicationType): Application | undefined;
getGuildApplicationIds(guildId: string): string[];
getAppIdForBotUserId(botUserId: string): string | undefined;
getFetchingOrFailedFetchingIds(): string[];

View file

@ -0,0 +1,7 @@
import { FluxStore } from "..";
export interface ApplicationStreamPreviewStore extends FluxStore {
getIsPreviewLoading: (guildId: string | bigint | null, channelId: string | bigint, ownerId: string | bigint) => boolean;
getPreviewURL: (guildId: string | bigint | null, channelId: string | bigint, ownerId: string | bigint) => Promise<string | null>;
getPreviewURLForStreamKey: (streamKey: string) => ReturnType<ApplicationStreamPreviewStore["getPreviewURL"]>;
}

View file

@ -1,39 +1,4 @@
/*
* Vencord, a modification for Discord's desktop app
* Copyright (c) 2023 Vendicated and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { FluxStore } from "@vencord/discord-types";
export interface ApplicationStreamPreviewStore extends FluxStore {
getIsPreviewLoading: (guildId: string | bigint | null, channelId: string | bigint, ownerId: string | bigint) => boolean;
getPreviewURL: (guildId: string | bigint | null, channelId: string | bigint, ownerId: string | bigint) => Promise<string | null>;
getPreviewURLForStreamKey: (streamKey: string) => ReturnType<ApplicationStreamPreviewStore["getPreviewURL"]>;
}
export interface ApplicationStream {
streamType: string;
guildId: string | null;
channelId: string;
ownerId: string;
}
export interface Stream extends ApplicationStream {
state: string;
}
import { ApplicationStream, FluxStore, Stream } from "..";
export interface RTCStream {
region: string,
@ -54,9 +19,6 @@ export interface StreamingStoreState {
streamsByUserAndGuild: { [key: string]: { [key: string]: ApplicationStream; }; };
}
/**
* example how a stream key could look like: `call(type of connection):1116549917987192913(channelId):305238513941667851(ownerId)`
*/
export interface ApplicationStreamingStore extends FluxStore {
getActiveStreamForApplicationStream: (stream: ApplicationStream) => Stream | null;
getActiveStreamForStreamKey: (streamKey: string) => Stream | null;

View file

@ -1,5 +1,6 @@
import { FluxStore, User, VoiceState } from "..";
import { ParticipantType, RTCPlatform } from "../../enums";
import { AvatarDecorationData, FluxStore, User, VoiceState } from "..";
import { ActivityType, ParticipantType, RTCPlatform } from "../../enums";
import { StreamType } from "./FriendsStore";
export type RTCLayout = "normal" | "minimum" | "no-chat" | "full-screen" | "haven";
export type RTCMode = "video" | "voice";
@ -15,7 +16,7 @@ export interface Stream {
channelId: string;
guildId: string | null;
ownerId: string;
streamType: string;
streamType: StreamType;
}
export interface BaseParticipant {
@ -36,8 +37,7 @@ export interface UserParticipant extends BaseParticipant {
soundsharing: boolean;
ringing: boolean;
userNick: string;
// TODO: type
userAvatarDecoration: any | null;
userAvatarDecoration: AvatarDecorationData | null;
localVideoDisabled: boolean;
userVideo?: boolean;
streamId?: string;
@ -57,7 +57,7 @@ export interface StreamParticipant extends BaseParticipant {
export interface ActivityParticipant extends BaseParticipant {
type: ParticipantType.ACTIVITY;
applicationId: string;
activityType: number;
activityType: ActivityType;
activityUrl: string;
participants: string[];
guildId: string | null;

View file

@ -1,31 +1,111 @@
import { Channel, FluxStore } from "..";
/** Debug info for channel store state. */
export interface ChannelStoreDebugInfo {
/** Guild IDs that have been loaded. */
loadedGuildIds: string[];
/** Guild IDs currently being loaded. */
pendingGuildLoads: string[];
/** String descriptions of guild channel counts. */
guildSizes: string[];
}
/**
* Flux store managing all channel data including guild channels,
* threads, DMs, and group DMs.
*/
export class ChannelStore extends FluxStore {
/**
* Gets a channel by ID.
* @param channelId Channel ID to look up.
*/
getChannel(channelId: string): Channel;
/**
* Gets basic channel info by ID, returns undefined if not found.
* @param channelId Channel ID to look up.
*/
getBasicChannel(channelId: string): Channel | undefined;
/**
* Checks if a channel exists in the store.
* @param channelId Channel ID to check.
*/
hasChannel(channelId: string): boolean;
/**
* Gets all channel IDs, optionally filtered by guild.
* @param guildId Guild ID to filter by, or null/undefined for all channels.
*/
getChannelIds(guildId?: string | null): string[];
/**
* Gets basic guild channels as a mutable record.
* @param guildId Guild ID to get channels for.
* @returns Record keyed by channel ID.
*/
getMutableBasicGuildChannelsForGuild(guildId: string): Record<string, Channel>;
/**
* Gets all guild channels as a mutable record.
* @param guildId Guild ID to get channels for.
* @returns Record keyed by channel ID.
*/
getMutableGuildChannelsForGuild(guildId: string): Record<string, Channel>;
/**
* Gets all threads for a guild.
* @param guildId Guild ID to get threads for.
*/
getAllThreadsForGuild(guildId: string): Channel[];
getAllThreadsForParent(channelId: string): Channel[];
/**
* Gets all threads under a parent channel.
* @param parentChannelId Parent channel ID.
*/
getAllThreadsForParent(parentChannelId: string): Channel[];
/**
* Gets sorted linked channels for a guild, such as stage instances and events.
* @param guildId Guild ID.
*/
getSortedLinkedChannelsForGuild(guildId: string): Channel[];
getDMFromUserId(userId: string): string;
/**
* Gets DM channel ID for a user.
* @param userId User ID to get DM for.
* @returns Channel ID, not the channel object.
*/
getDMFromUserId(userId: string): string | undefined;
/**
* Gets DM channel object for a user.
* @param userId User ID to get DM for.
*/
getDMChannelFromUserId(userId: string): Channel | undefined;
/** Gets all user IDs that have DM channels. */
getDMUserIds(): string[];
/**
* Gets mutable map of user ID to DM channel ID.
* @returns Record keyed by user ID.
*/
getMutableDMsByUserIds(): Record<string, string>;
/**
* Gets mutable map of all private channels.
* @returns Record keyed by channel ID.
*/
getMutablePrivateChannels(): Record<string, Channel>;
/** Gets private channels sorted by last message. */
getSortedPrivateChannels(): Channel[];
/**
* Gets version number for guild channels, incremented on changes.
* @param guildId Guild ID.
*/
getGuildChannelsVersion(guildId: string): number;
/** Gets version number for private channels, incremented on changes. */
getPrivateChannelsVersion(): number;
/**
* Gets initial channel state for overlay rendering.
* @returns Record keyed by channel ID.
*/
getInitialOverlayState(): Record<string, Channel>;
getDebugInfo(): {
loadedGuildIds: string[];
pendingGuildLoads: string[];
guildSizes: string[];
};
/** Gets debug info about store state. */
getDebugInfo(): ChannelStoreDebugInfo;
/** Loads all guild and private channels from disk cache. */
loadAllGuildAndPrivateChannelsFromDisk(): Promise<void>;
}

View file

@ -0,0 +1,253 @@
import { ApplicationCommandOptionType } from "../../enums";
import { FluxStore, Message } from "..";
/** Slate node type values used in the rich text editor. */
export type SlateNodeType =
| "text"
| "line"
| "s"
| "u"
| "strong"
| "em"
| "image"
| "emoji"
| "customEmoji"
| "link"
| "url"
| "autolink"
| "highlight"
| "paragraph"
| "br"
| "newline"
| "escape"
| "spoiler"
| "blockQuote"
| "inlineCode"
| "codeBlock"
| "mention"
| "userMention"
| "channelMention"
| "channel"
| "guild"
| "attachmentLink"
| "shopLink"
| "soundboard"
| "staticRouteLink"
| "roleMention"
| "commandMention"
| "timestamp"
| "timestampMentionInput"
| "list"
| "heading"
| "subtext"
| "silentPrefix"
| "gameMention"
| "gameMentionInput"
| "textMention"
| "applicationCommandOption";
/** A plain text leaf node. */
export interface SlateTextNode {
text: string;
}
/** Base interface for Slate element nodes with children. */
export interface SlateBaseElement {
type: string;
children: SlateNode[];
}
/** A line element in the editor. */
export interface SlateLineElement extends SlateBaseElement {
type: "line";
codeBlockState?: {
isInCodeBlock: boolean;
};
}
/** A block quote element. */
export interface SlateBlockQuoteElement extends SlateBaseElement {
type: "blockQuote";
}
/** An emoji element. */
export interface SlateEmojiElement extends SlateBaseElement {
type: "emoji";
emoji: {
name: string;
src?: string;
surrogate: string;
jumboable?: boolean;
};
}
/** A custom emoji element. */
export interface SlateCustomEmojiElement extends SlateBaseElement {
type: "customEmoji";
emoji: {
emojiId: string;
name: string;
animated: boolean;
jumboable?: boolean;
};
}
/** A user mention element. */
export interface SlateUserMentionElement extends SlateBaseElement {
type: "userMention";
userId: string;
}
/** A channel mention element. */
export interface SlateChannelMentionElement extends SlateBaseElement {
type: "channelMention";
channelId: string;
}
/** A role mention element. */
export interface SlateRoleMentionElement extends SlateBaseElement {
type: "roleMention";
roleId: string;
}
/** A text mention element (for @everyone, @here, etc.). */
export interface SlateTextMentionElement extends SlateBaseElement {
type: "textMention";
name: string;
}
/** A soundboard element. */
export interface SlateSoundboardElement extends SlateBaseElement {
type: "soundboard";
guildId: string;
soundId: string;
}
/** Timestamp format style characters. */
export type TimestampStyle = "t" | "T" | "d" | "D" | "f" | "F" | "R";
/** Parsed timestamp data. */
export interface ParsedTimestamp {
/** The Unix timestamp in seconds as a string. */
timestamp: string;
/** The format style character. */
format: TimestampStyle | undefined;
/** The parsed Moment.js object. */
parsed: object;
/** The full formatted date string. */
full: string;
/** The formatted string based on the format style. */
formatted: string;
}
/** A timestamp element. */
export interface SlateTimestampElement extends SlateBaseElement {
type: "timestamp";
parsed: ParsedTimestamp;
}
/** A static route link element. */
export interface SlateStaticRouteLinkElement extends SlateBaseElement {
type: "staticRouteLink";
id: string;
itemId?: string;
}
/** A game mention element. */
export interface SlateGameMentionElement extends SlateBaseElement {
type: "gameMention";
applicationId: string;
}
/** A timestamp mention input element (while typing). */
export interface SlateTimestampMentionInputElement extends SlateBaseElement {
type: "timestampMentionInput";
}
/** A game mention input element (while typing). */
export interface SlateGameMentionInputElement extends SlateBaseElement {
type: "gameMentionInput";
}
/** An application command option element. */
export interface SlateApplicationCommandOptionElement extends SlateBaseElement {
type: "applicationCommandOption";
optionType: ApplicationCommandOptionType;
}
/** Union of all Slate element types. */
export type SlateElement =
| SlateLineElement
| SlateBlockQuoteElement
| SlateEmojiElement
| SlateCustomEmojiElement
| SlateUserMentionElement
| SlateChannelMentionElement
| SlateRoleMentionElement
| SlateTextMentionElement
| SlateSoundboardElement
| SlateTimestampElement
| SlateTimestampMentionInputElement
| SlateStaticRouteLinkElement
| SlateGameMentionElement
| SlateGameMentionInputElement
| SlateApplicationCommandOptionElement
| SlateBaseElement;
/** A Slate node can be either an element or a text leaf. */
export type SlateNode = SlateElement | SlateTextNode;
/** The rich value representation used by Slate editor for message editing. */
export type SlateValue = SlateLineElement[];
export class EditMessageStore extends FluxStore {
/**
* Gets the action source that triggered editing for a channel.
* @param channelId The channel ID.
* @returns The source string or undefined if not editing.
*/
getEditActionSource(channelId: string): string | undefined;
/**
* Gets the message currently being edited in a channel.
* @param channelId The channel ID.
* @returns The message being edited or null if not editing.
*/
getEditingMessage(channelId: string): Message | null;
/**
* Gets the ID of the message currently being edited in a channel.
* @param channelId The channel ID.
* @returns The message ID or undefined if not editing.
*/
getEditingMessageId(channelId: string): string | undefined;
/**
* Gets the rich value (Slate editor format) of the editing text.
* @param channelId The channel ID.
* @returns The Slate value or undefined if not editing.
*/
getEditingRichValue(channelId: string): SlateValue | undefined;
/**
* Gets the plain text value of the editing text.
* @param channelId The channel ID.
* @returns The text value or undefined if not editing.
*/
getEditingTextValue(channelId: string): string | undefined;
/**
* Checks if a specific message is currently being edited.
* @param channelId The channel ID.
* @param messageId The message ID to check.
* @returns True if the specific message is being edited.
*/
isEditing(channelId: string, messageId: string): boolean;
/**
* Checks if any message is currently being edited in a channel.
* @param channelId The channel ID.
* @returns True if any message is being edited in the channel.
*/
isEditingAny(channelId: string): boolean;
}

View file

@ -0,0 +1,101 @@
import { FluxStore } from "..";
interface ExperimentAssignmentOverride {
type: "user" | "guild";
revision: number;
population?: number;
bucket: number;
override: boolean;
}
interface UserExperimentAssignment {
aaMode: boolean;
assignmentSource: string;
bucket: number;
fingerprint: string | null;
hashResult: number;
holdoutBucket: number | null;
holdoutName: string | null;
holdoutRevision: number | null;
loadedFromCache: boolean;
override: boolean;
population: number;
revision: number;
sessionId: string;
triggerDebuggingEnabled: boolean;
type: string;
}
interface GuildExperimentAssignment {
aaMode: boolean;
assignmentSource: string;
fingerprint: string | null;
hashKey: string | null;
holdoutControlBucket: number | null;
holdoutName: string | null;
loadedFromCache: boolean;
overrides: Record<string, number>;
overridesFormatted: unknown[];
populations: unknown[];
revision: number;
sessionId: string;
triggerDebuggingEnabled: boolean;
}
interface ExperimentDescriptor {
buckets: number[];
commonTriggerPoint?: string;
description: string[];
title: string;
type: "user" | "guild";
}
interface ExperimentExposureEntry {
time: number;
hash: number;
}
type GuildExposureKey = `guild|${string}|${string}`;
type UserExposureKey = `user|${string}`;
interface TrackedExposures {
[key: UserExposureKey]: ExperimentExposureEntry;
[key: GuildExposureKey]: ExperimentExposureEntry;
}
interface ExperimentState {
assignmentFingerprint: string | null;
assignmentSessionId: string;
assignmentSource: string;
cookieOverrides: unknown;
guildExperimentOverrides: ExperimentAssignmentOverride;
hasLoadedExperiments: boolean;
loadedGuildExperiments: GuildExperimentAssignment;
loadedUserExperiments: UserExperimentAssignment;
trackedExposureExperiments: TrackedExposures;
userExperimentOverrides: ExperimentAssignmentOverride;
}
export class ExperimentStore extends FluxStore {
hasLoadedExperiments: boolean;
persistKey: string;
getAllExperimentAssignments(): Record<string, number>;
getAllExperimentOverrideDescriptors(): ExperimentAssignmentOverride;
getAllUserExperimentDescriptors(): Record<number, UserExperimentAssignment>;
getExperimentOverrideDescriptor(experimentId: string): ExperimentAssignmentOverride;
getGuildExperimentBucket(experimentId: string, guildId: string): number;
getGuildExperimentDescriptor(experimentId: string, guildId: string): ExperimentAssignmentOverride;
getGuildExperiments(): Record<number, GuildExperimentAssignment>;
getLoadedGuildExperiment(experimentId: string): GuildExperimentAssignment;
getLoadedUserExperiment(experimentId: string): UserExperimentAssignment;
getRegisteredExperiments(): ExperimentDescriptor;
getSerializedState(): ExperimentState;
getUserExperimentBucket(experimentId: string): number;
getUserExperimentDescriptor(experimentId: string): ExperimentAssignmentOverride;
hasRegisteredExperiment(experimentId: string): boolean;
// has two args
getRecentExposures(): unknown;
// has four args
hasExperimentTrackedExposure(): unknown;
}

View file

@ -5,11 +5,13 @@ export type FriendsSection = "ADD_FRIEND" | "ALL" | "ONLINE" | "PENDING" | "PEND
export type StatusType = "online" | "offline" | "idle" | "dnd" | "invisible" | "streaming" | "unknown";
export type StreamType = "call" | "guild";
export interface ApplicationStream {
channelId: string;
guildId: string | null;
ownerId: string;
streamType: string;
streamType: StreamType;
}
export interface FriendsRow {

View file

@ -1,5 +1,5 @@
import { FluxStore } from "..";
import { GuildScheduledEventEntityType, GuildScheduledEventPrivacyLevel, GuildScheduledEventStatus } from "../../enums";
import { GuildScheduledEventEntityType, GuildScheduledEventPrivacyLevel, GuildScheduledEventStatus, RecurrenceRuleFrequency } from "../../enums";
export interface GuildScheduledEventEntityMetadata {
location?: string;
@ -8,7 +8,7 @@ export interface GuildScheduledEventEntityMetadata {
export interface GuildScheduledEventRecurrenceRule {
start: string;
end: string | null;
frequency: number;
frequency: RecurrenceRuleFrequency;
interval: number;
byWeekday: number[] | null;
byNWeekday: { n: number; day: number; }[] | null;

View file

@ -1,4 +1,17 @@
import { Channel, FluxStore, Guild, User } from "..";
import { Application } from "../common/Application";
import { GuildScheduledEvent } from "./GuildScheduledEventStore";
import { GuildScheduledEventPrivacyLevel, InviteTargetType } from "../../enums";
export interface StageInstance {
id: string;
guild_id: string;
channel_id: string;
topic: string;
privacy_level: GuildScheduledEventPrivacyLevel;
discoverable_disabled: boolean;
guild_scheduled_event_id: string | null;
}
export interface Invite {
code: string;
@ -9,12 +22,11 @@ export interface Invite {
approximate_presence_count?: number;
expires_at?: string | null;
flags?: number;
target_type?: number;
target_type?: InviteTargetType;
target_user?: User;
// TODO: type these
target_application?: any;
stage_instance?: any;
guild_scheduled_event?: any;
target_application?: Application;
stage_instance?: StageInstance;
guild_scheduled_event?: GuildScheduledEvent;
}
export class InviteStore extends FluxStore {

View file

@ -675,7 +675,7 @@ export interface MediaEngineConnection {
/** whether QoS is enabled. */
qos: boolean;
/** current input mode. */
inputMode: string;
inputMode: VoiceMode;
/** VAD threshold in dB, default -60. */
vadThreshold: number;
/** whether VAD auto threshold is enabled, default true. */

View file

@ -1,15 +1,16 @@
import { FluxStore } from "..";
import { PremiumType } from "../../enums";
export interface OverridePremiumTypeState {
createdAtOverride: Date | undefined;
premiumTypeActual: number | null;
premiumTypeOverride: number | undefined;
premiumTypeActual: PremiumType | null;
premiumTypeOverride: PremiumType | undefined;
}
export class OverridePremiumTypeStore extends FluxStore {
getState(): OverridePremiumTypeState;
getCreatedAtOverride(): Date | undefined;
getPremiumTypeActual(): number | null;
getPremiumTypeOverride(): number | undefined;
get premiumType(): number | undefined;
getPremiumTypeActual(): PremiumType | null;
getPremiumTypeOverride(): PremiumType | undefined;
get premiumType(): PremiumType | undefined;
}

View file

@ -8,7 +8,14 @@ export interface PendingReply {
showMentionToggle: boolean;
}
interface PendingReplyState {
channelId: string;
messageId: string;
shouldMention: boolean;
showMentionToggle: boolean;
}
export class PendingReplyStore extends FluxStore {
getState(): Record<string, PendingReplyState>;
getPendingReply(channelId: string): PendingReply | undefined;
/** Discord doesn't use this method. Also seems to always return undefined */
getPendingReplyActionSource(channelId: string): unknown;

View file

@ -36,7 +36,8 @@ export interface VoiceStateStats {
}
export interface SecureFramesState {
state: string;
version: number;
epochAuthenticator: string;
}
export interface SecureFramesRosterMapEntry {

View file

@ -1,4 +1,5 @@
import { FluxStore } from "..";
import { Message, MessageJSON } from "../common/messages";
import { RelationshipType } from "../../enums";
export class RelationshipStore extends FluxStore {
@ -24,18 +25,18 @@ export class RelationshipStore extends FluxStore {
getVersion(): number;
isBlocked(userId: string): boolean;
isBlockedForMessage(userId: string): boolean;
isBlockedForMessage(message: Message | MessageJSON): boolean;
/**
* @see {@link isBlocked}
* @see {@link isIgnored}
*/
isBlockedOrIgnored(userId: string): boolean;
isBlockedOrIgnoredForMessage(userId: string): boolean;
isBlockedOrIgnoredForMessage(message: Message | MessageJSON): boolean;
isFriend(userId: string): boolean;
isIgnored(userId: string): boolean;
isIgnoredForMessage(userId: string): boolean;
isIgnoredForMessage(message: Message | MessageJSON): boolean;
isSpam(userId: string): boolean;
isStranger(userId: string): boolean;
isUnfilteredPendingIncoming(userId: string): boolean;

View file

@ -21,8 +21,10 @@ export interface GameOverlayStatus {
enabledOOP: boolean;
}
export type SystemServiceState = "unknown" | "running" | "stopped" | "error";
export interface SystemServiceStatus {
state: string;
state: SystemServiceState;
}
export class RunningGameStore extends FluxStore {

View file

@ -1,4 +1,9 @@
import { FluxStore } from "..";
import { ActivityFlags } from "../../enums";
export type SpotifyDeviceType = "computer" | "smartphone" | "speaker" | "tv" | "game_console" | "automobile" | "unknown";
export type SpotifyMediaType = "track" | "episode";
export type SpotifyAlbumType = "album" | "single" | "compilation";
export interface SpotifyDevice {
id: string;
@ -7,7 +12,7 @@ export interface SpotifyDevice {
is_restricted: boolean;
name: string;
supports_volume: boolean;
type: string;
type: SpotifyDeviceType;
volume_percent: number;
}
@ -38,7 +43,7 @@ export interface SpotifyImage {
export interface SpotifyAlbum {
id: string;
name: string;
type: string;
type: SpotifyAlbumType;
image: SpotifyImage | null;
}
@ -47,7 +52,7 @@ export interface SpotifyTrack {
name: string;
duration: number;
isLocal: boolean;
type: string;
type: SpotifyMediaType;
album: SpotifyAlbum;
artists: SpotifyArtist[];
}
@ -55,7 +60,7 @@ export interface SpotifyTrack {
export interface SpotifyPlayerState {
track: SpotifyTrack;
startTime: number;
context: { uri: string } | null;
context: { uri: string; } | null;
}
export interface SpotifyActivity {
@ -74,12 +79,12 @@ export interface SpotifyActivity {
id: string;
};
sync_id?: string;
flags?: number;
flags?: ActivityFlags;
metadata?: {
context_uri: string | undefined;
album_id: string;
artist_ids: string[];
type: string;
type: SpotifyMediaType;
button_urls: string[];
};
}

View file

@ -1,21 +1,57 @@
import { FluxStore, GuildSticker, PremiumStickerPack, Sticker } from "..";
import { LoadState } from "../../enums";
export type StickerGuildMap = Map<string, GuildSticker[]>;
export type StickerPackMap = Map<string, Sticker[]>;
export interface StickerPackMeta {
id: string;
title: string;
author?: {
name: string;
url?: string;
};
logo: Sticker;
dynamic?: DynamicStickerPackMeta["dynamic"];
}
export interface DynamicStickerPackMeta extends StickerPackMeta {
dynamic: {
version?: string;
refreshUrl: string;
authHeaders?: Record<string, string>;
};
}
export interface StickerPack extends StickerPackMeta {
stickers: Sticker[];
}
export interface StickerCategoryType {
id: string;
name: string;
iconUrl?: string;
}
export interface StickerMetadataEntry {
type: number;
value: string;
}
export class StickersStore extends FluxStore {
hasLoadedStickerPacks: boolean;
isFetchingStickerPacks: boolean;
isLoaded: boolean;
loadState: number;
loadState: LoadState;
getAllGuildStickers(): StickerGuildMap;
getAllPackStickers(): StickerPackMap;
getPremiumPacks(): PremiumStickerPack[];
getRawStickersByGuild(): StickerGuildMap;
getStickerById(id: string): Sticker | undefined;
// TODO: type
getStickerMetadataArrays(): any[];
getStickerMetadataArrays(): [Record<string, StickerMetadataEntry[]>, Record<string, StickerMetadataEntry[]>];
getStickerPack(id: string): PremiumStickerPack | undefined;
getStickersByGuildId(guildId: string): Sticker[] | undefined;
isPremiumPack(id: string): boolean;

View file

@ -0,0 +1,33 @@
import { FluxStore } from "..";
interface UserAffinity {
otherUserId: string;
userSegment: string;
otherUserSegment: string;
isFriend: boolean;
dmProbability: number;
dmRank: number;
vcProbability: number;
vcRank: number;
serverMessageProbability: number;
serverMessageRank: number;
communicationProbability: number;
communicationRank: number;
}
interface UserAffinitiesResponse {
lastFetched: number;
userAffinities: UserAffinity[];
}
export class UserAffinitiesStore extends FluxStore {
compare(firstUserId: string, secondUserId: string): number;
compareByDmProbability(firstUserId: string, secondUserId: string): number;
getState(): UserAffinitiesResponse;
getUserAffinities(): UserAffinity[];
getUserAffinitiesMap(): Map<string, UserAffinity>;
getUserAffinity(userId: string): UserAffinity;
isFetching(): boolean;
isHighlyAffinedVCUser(userId: string): boolean;
shouldFetch(): boolean;
}

View file

@ -1,4 +1,5 @@
import { Channel, FluxStore } from "..";
import { Channel, FluxStore, Guild } from "..";
import { ChannelOverrideFlags, GuildSettingsFlags, NotifyHighlights, UserNotificationSetting } from "../../enums";
export interface MuteConfig {
selected_time_window: number;
@ -8,8 +9,8 @@ export interface MuteConfig {
export interface ChannelOverride {
muted: boolean;
mute_config: MuteConfig | null;
message_notifications: number;
flags: number;
message_notifications: UserNotificationSetting;
flags: ChannelOverrideFlags;
collapsed: boolean;
channel_id: string;
}
@ -20,10 +21,10 @@ export interface GuildSettings {
mute_scheduled_events: boolean;
mobile_push: boolean;
muted: boolean;
message_notifications: number;
flags: number;
message_notifications: UserNotificationSetting;
flags: GuildSettingsFlags;
channel_overrides: Record<string, ChannelOverride>;
notify_highlights: number;
notify_highlights: NotifyHighlights;
hide_muted_channels: boolean;
version: number;
mute_config: MuteConfig | null;
@ -43,26 +44,26 @@ export class UserGuildSettingsStore extends FluxStore {
get mentionOnAllMessages(): boolean;
get useNewNotifications(): boolean;
allowAllMessages(guildId: string): boolean;
allowNoMessages(guildId: string): boolean;
allowAllMessages(channel: Channel): boolean;
allowNoMessages(channel: Channel): boolean;
getAddedToMessages(): string[];
// TODO: finish typing
getAllSettings(): { userGuildSettings: Record<string, GuildSettings>; };
getChannelFlags(channel: Channel): number;
getChannelIdFlags(guildId: string, channelId: string): number;
getChannelMessageNotifications(guildId: string, channelId: string): number | null;
getChannelFlags(channel: Channel): ChannelOverrideFlags;
getChannelIdFlags(guildId: string, channelId: string): ChannelOverrideFlags;
getChannelMessageNotifications(guildId: string, channelId: string): UserNotificationSetting | null;
getChannelMuteConfig(guildId: string, channelId: string): MuteConfig | null;
getChannelOverrides(guildId: string): Record<string, ChannelOverride>;
getChannelRecordUnreadSetting(channel: Channel): number;
getChannelUnreadSetting(guildId: string, channelId: string): number;
getGuildFavorites(guildId: string): string[];
getGuildFlags(guildId: string): number;
getGuildFlags(guildId: string): GuildSettingsFlags;
getGuildUnreadSetting(guildId: string): number;
getMessageNotifications(guildId: string): number;
getMessageNotifications(guildId: string): UserNotificationSetting;
getMuteConfig(guildId: string): MuteConfig | null;
getMutedChannels(guildId: string): string[];
getNewForumThreadsCreated(guildId: string): boolean;
getNotifyHighlights(guildId: string): number;
getNewForumThreadsCreated(channel: Channel): boolean;
getNotifyHighlights(guildId: string): NotifyHighlights;
getOptedInChannels(guildId: string): string[];
// TODO: finish typing these
getOptedInChannelsWithPendingUpdates(guildId: string): Record<string, any>;
@ -85,7 +86,7 @@ export class UserGuildSettingsStore extends FluxStore {
isSuppressEveryoneEnabled(guildId: string): boolean;
isSuppressRolesEnabled(guildId: string): boolean;
isTemporarilyMuted(guildId: string): boolean;
resolveGuildUnreadSetting(guildId: string): number;
resolveGuildUnreadSetting(guild: Guild): number;
resolveUnreadSetting(channel: Channel): number;
resolvedMessageNotifications(guildId: string): number;
resolvedMessageNotifications(channel: Channel): UserNotificationSetting;
}

View file

@ -1,5 +1,5 @@
import { FluxStore, Guild, User, Application, ApplicationInstallParams } from "..";
import { ApplicationIntegrationType } from "../../enums";
import { FluxStore, Guild, User, Application, ApplicationInstallParams, ProfileEffect } from "..";
import { ApplicationFlags, ApplicationIntegrationType } from "../../enums";
export interface MutualFriend {
/**
@ -54,7 +54,7 @@ export interface ProfileApplication {
id: string;
customInstallUrl: string | undefined;
installParams: ApplicationInstallParams | undefined;
flags: number;
flags: ApplicationFlags;
popularApplicationCommandIds?: string[];
integrationTypesConfig: Record<ApplicationIntegrationType, Partial<{
oauth2_install_params: ApplicationInstallParams;
@ -70,9 +70,11 @@ export interface UserProfileBase extends Pick<User, "banner"> {
*/
badges: ProfileBadge[];
bio: string | undefined;
collectibles: ProfileEffect[];
popoutAnimationParticleType: string | null;
profileEffectExpiresAt: number | Date | undefined;
profileEffectId: undefined | string;
profileEffect: ProfileEffect;
/**
* often an empty string when not set
*/

View file

@ -1,4 +1,7 @@
import { FluxStore } from "..";
import { StickerAnimationSetting, Theme, UIDensity } from "../../enums";
export type UserStatus = "online" | "idle" | "dnd" | "invisible";
export interface GuildFolder {
guildIds: string[];
@ -68,7 +71,7 @@ export interface TextAndImagesSettings {
renderEmbeds: boolean;
renderReactions: boolean;
animateEmoji: boolean;
animateStickers: number;
animateStickers: StickerAnimationSetting;
enableTtsCommand: boolean;
messageDisplayCompact: boolean;
explicitContentFilter: number;
@ -122,7 +125,7 @@ export interface GameLibrarySettings {
export interface StatusSettings {
statusExpiresAtMs: string;
status: { status: string; } | null;
status: { value: UserStatus; } | null;
showCurrentGame: boolean;
statusCreatedAtMs: string;
}
@ -133,12 +136,12 @@ export interface LocalizationSettings {
}
export interface AppearanceSettings {
theme: number;
theme: Theme;
developerMode: boolean;
mobileRedesignDisabled: boolean;
timestampHourCycle: number;
launchPadMode: number;
uiDensity: number;
uiDensity: UIDensity;
swipeRightToLeftMode: number;
// TODO: type
clientThemeSettings: any;

View file

@ -10,6 +10,7 @@ export interface VoiceState extends DiscordRecord {
sessionId: string | null | undefined;
mute: boolean;
deaf: boolean;
stream: boolean;
selfMute: boolean;
selfDeaf: boolean;
selfVideo: boolean;
@ -20,6 +21,9 @@ export interface VoiceState extends DiscordRecord {
isVoiceMuted(): boolean;
isVoiceDeafened(): boolean;
oldChannelId?: string;
guildId?: string;
}
export class VoiceStateStore extends FluxStore {

View file

@ -1,13 +1,18 @@
// please keep in alphabetical order
export * from "./AccessibilityStore";
export * from "./ActiveJoinedThreadsStore";
export * from "./ApplicationCommandIndexStore";
export * from "./ApplicationStore";
export * from "./ApplicationStreamingStore";
export * from "./ApplicationStreamPreviewStore";
export * from "./AuthenticationStore";
export * from "./CallStore";
export * from "./ChannelRTCStore";
export * from "./ChannelStore";
export * from "./DraftStore";
export * from "./EditMessageStore";
export * from "./EmojiStore";
export * from "./ExperimentStore";
export * from "./FluxStore";
export * from "./FriendsStore";
export * from "./GuildChannelStore";
@ -41,6 +46,7 @@ export * from "./StreamerModeStore";
export * from "./ThemeStore";
export * from "./TypingStore";
export * from "./UploadAttachmentStore";
export * from "./UserAffinitiesStore";
export * from "./UserGuildSettingsStore";
export * from "./UserProfileStore";
export * from "./UserSettingsProtoStore";

View file

@ -3,6 +3,7 @@ import type { ReactNode } from "react";
import { LiteralUnion } from "type-fest";
import type { FluxEvents } from "./fluxEvents";
import { ApplicationCommandOptionType, ChannelType, PremiumType } from "../enums";
export { FluxEvents };
@ -10,7 +11,9 @@ type FluxEventsAutoComplete = LiteralUnion<FluxEvents, string>;
export interface FluxDispatcher {
_actionHandlers: any;
_interceptors: any;
_subscriptions: any;
addInterceptor(interceptor: any): void;
dispatch(event: { [key: string]: unknown; type: FluxEventsAutoComplete; }): Promise<void>;
isDispatching(): boolean;
subscribe(event: FluxEventsAutoComplete, callback: (data: any) => void): void;
@ -22,14 +25,30 @@ export type Parser = Record<
| "parse"
| "parseTopic"
| "parseEmbedTitle"
| "parseEmbedTitleWithoutLinks"
| "parseInlineReply"
| "parseGuildVerificationFormRule"
| "parseGuildEventDescription"
| "parseAutoModerationSystemMessage"
| "parseForumPostGuidelines"
| "parseForumPostMostRecentMessage",
| "parseForumPostMostRecentMessage"
| "parseVoiceChannelStatus",
(content: string, inline?: boolean, state?: Record<string, any>) => ReactNode[]
> & Record<"defaultRules" | "guildEventRules", Record<string, Record<"react" | "html" | "parse" | "match" | "order", any>>>;
> & Record<
| "parseToAST"
| "parseTopicToAST"
| "parseEmbedTitleToAST"
| "parseEmbedTitleWithoutLinksToAST"
| "parseInlineReplyToAST"
| "parseAutoModerationSystemMessageToAST",
(content: string, inline?: boolean, state?: Record<string, any>) => any[]
> & Record<"defaultRules" | "guildEventRules" | "notifCenterV2MessagePreviewRules" | "lockscreenWidgetMessageRules", Record<string, Record<"react" | "html" | "parse" | "match" | "order", any>>> & {
reactParserFor(rules: Record<string, any>): (content: string, inline?: boolean, state?: Record<string, any>) => ReactNode[];
astParserFor(rules: Record<string, any>): (content: string, inline?: boolean, state?: Record<string, any>) => any[];
createReactRules(options: Record<string, any>): Record<string, any>;
defaultReactRuleOptions: Record<string, any>;
combineAndInjectMentionRule(rules: Record<string, any>, mentionRule: Record<string, any>): Record<string, any>;
};
export interface Alerts {
show(alert: {
@ -45,16 +64,39 @@ export interface Alerts {
onConfirmSecondary?(): void;
onCloseCallback?(): void;
}): void;
confirm(alert: {
title: any;
body: React.ReactNode;
className?: string;
confirmColor?: string;
cancelText?: string;
confirmText?: string;
secondaryConfirmText?: string;
onCancel?(): void;
onConfirmSecondary?(): void;
onCloseCallback?(): void;
}): Promise<boolean>;
/** This is a noop, it does nothing. */
close(): void;
}
export interface SnowflakeUtils {
fromTimestamp(timestamp: number): string;
fromTimestampWithSequence(timestamp: number, sequence: number): string;
extractTimestamp(snowflake: string): number;
age(snowflake: string): number;
atPreviousMillisecond(snowflake: string): string;
atNextMillisecond(snowflake: string): string;
compare(snowflake1?: string, snowflake2?: string): number;
isProbablyAValidSnowflake(snowflake: string): boolean;
castChannelIdAsMessageId(channelId: string): string;
castMessageIdAsChannelId(messageId: string): string;
castGuildIdAsEveryoneGuildRoleId(guildId: string): string;
cast(snowflake: string): string;
keys(obj: Record<string, any>): string[];
forEach(obj: Record<string, any>, callback: (value: any, key: string) => void): void;
forEachKey(obj: Record<string, any>, callback: (key: string) => void): void;
entries(obj: Record<string, any>): [string, any][];
}
interface RestRequestData {
@ -84,6 +126,8 @@ export type Permissions = "CREATE_INSTANT_INVITE"
| "VIEW_GUILD_ANALYTICS"
| "VIEW_CREATOR_MONETIZATION_ANALYTICS"
| "MODERATE_MEMBERS"
| "USE_EMBEDDED_ACTIVITIES"
| "USE_EXTERNAL_APPS"
| "SEND_MESSAGES"
| "SEND_TTS_MESSAGES"
| "MANAGE_MESSAGES"
@ -100,6 +144,9 @@ export type Permissions = "CREATE_INSTANT_INVITE"
| "USE_EXTERNAL_STICKERS"
| "SEND_MESSAGES_IN_THREADS"
| "SEND_VOICE_MESSAGES"
| "SEND_POLLS"
| "PIN_MESSAGES"
| "BYPASS_SLOWMODE"
| "CONNECT"
| "SPEAK"
| "MUTE_MEMBERS"
@ -108,9 +155,9 @@ export type Permissions = "CREATE_INSTANT_INVITE"
| "USE_VAD"
| "PRIORITY_SPEAKER"
| "STREAM"
| "USE_EMBEDDED_ACTIVITIES"
| "USE_SOUNDBOARD"
| "USE_EXTERNAL_SOUNDS"
| "SET_VOICE_CHANNEL_STATUS"
| "REQUEST_TO_SPEAK"
| "MANAGE_EVENTS"
| "CREATE_EVENTS";
@ -156,7 +203,7 @@ export interface IconUtils {
getUserAvatarURL(user: User, canAnimate?: boolean, size?: number, format?: string): string;
getDefaultAvatarURL(id: string, discriminator?: string): string;
getUserBannerURL(data: { id: string, banner: string, canAnimate?: boolean, size: number; }): string | undefined;
getAvatarDecorationURL(dara: { avatarDecoration: string, size: number; canCanimate?: boolean; }): string | undefined;
getAvatarDecorationURL(data: { avatarDecoration: string, size: number; canCanimate?: boolean; }): string | undefined;
getGuildMemberAvatarURL(member: GuildMember, canAnimate?: string): string | null;
getGuildMemberAvatarURLSimple(data: { guildId: string, userId: string, avatar: string, canAnimate?: boolean; size?: number; }): string;
@ -241,45 +288,55 @@ export interface UsernameUtils {
useName(user: User): string;
getUserTag(user: User, options?: UserNameUtilsTagOptions): string;
useUserTag(user: User, options?: UserNameUtilsTagOptions): string;
isNameConcealed(user: User): boolean;
getUserIsStaff(user: User): boolean;
useDirectMessageRecipient: any;
humanizeStatus: any;
}
// TODO: fix type
export class DisplayProfile {
userId: string;
guildId?: string;
banner?: string;
bio?: string;
pronouns?: string;
accentColor?: number;
themeColors?: number[];
profileEffect?: any;
popoutAnimationParticleType?: any;
profileEffectId?: string;
fetchStartedAt?: Date | null;
fetchEndedAt?: Date | null;
_userProfile?: any;
_guildMemberProfile?: any;
canUsePremiumProfileCustomization: boolean;
canEditThemes: boolean;
premiumGuildSince: Date | null;
premiumSince: Date | null;
premiumType?: number;
primaryColor?: number;
get premiumSince(): Date | null;
get premiumGuildSince(): Date | null;
get premiumType(): PremiumType | undefined;
get private(): boolean;
get widgets(): any[] | undefined;
get gameWidgets(): any[] | undefined;
get primaryColor(): number | undefined;
get canUsePremiumProfileCustomization(): boolean;
get canEditThemes(): boolean;
get application(): any;
get isLoaded(): boolean;
hasThemeColors(): boolean;
hasPremiumCustomization(): boolean;
isUsingGuildMemberBanner(): boolean;
isUsingGuildMemberBio(): boolean;
isUsingGuildMemberPronouns(): boolean;
getBannerURL(options: { canAnimate: boolean; size: number; }): string;
getPreviewBanner(banner: string | null, canAnimate: boolean, size?: number): string | null;
getPreviewBio(bio: string | undefined): string | undefined;
getPreviewThemeColors(themeColors: number[] | undefined): number[] | undefined;
getBadges(): Array<{
id: string;
description: string;
icon: string;
link?: string;
}>;
getBannerURL(options: { canAnimate: boolean; size: number; }): string;
getLegacyUsername(): string | null;
hasFullProfile(): boolean;
hasPremiumCustomization(): boolean;
hasThemeColors(): boolean;
isUsingGuildMemberBanner(): boolean;
isUsingGuildMemberBio(): boolean;
isUsingGuildMemberPronouns(): boolean;
}
export interface DisplayProfileUtils {
@ -295,7 +352,7 @@ export interface DateUtils {
}
export interface CommandOptions {
type: number;
type: ApplicationCommandOptionType;
name: string;
description: string;
required?: boolean;
@ -304,8 +361,56 @@ export interface CommandOptions {
values: string | number;
}[];
options?: CommandOptions[];
channel_types?: number[];
channel_types?: ChannelType[];
min_value?: number;
max_value?: number;
autocomplete?: boolean;
}
export interface URLUtils {
URL_REGEX: RegExp;
makeUrl(url: string): URL | null;
isDiscordUrl(url: string): boolean;
isDiscordCdnUrl(url: string): boolean;
isDiscordAssetUrl(url: string, proxyUrl?: string, originalUrl?: string): boolean;
isDiscordDirectAssetUrl(url: string): boolean;
isDiscordProxiedAssetUrl(url: string, proxyUrl?: string, originalUrl?: string): boolean;
isDiscordHostname(hostname: string): boolean;
isDiscordLocalhost(hostname: string): boolean;
isDiscordProtocol(url: string): boolean;
isDiscordUri(url: string): boolean;
isDiscordUrlOrUri(url: string): boolean;
isAllowedGifProviderUrl(url: string): boolean;
isAppRoute(url: string): boolean;
isOriginalContentTypeDifferent(url: string, proxyUrl: string): boolean;
toURLSafe(url: string): URL | null;
safeDecodeURIComponent(component: string): string;
safeParseWithQuery(url: string): URL | null;
format(url: URL): string;
formatPathWithQuery(path: string, query: Record<string, string>): string;
formatSearch(query: Record<string, string>): string;
}
export interface Humanize {
filesize(bytes: number, base?: number, decimals?: number, decimalSep?: string, thousandsSep?: string, suffix?: string): string;
intword(number: number, units?: string[], base?: number, decimals?: number, decimalSep?: string, thousandsSep?: string): string;
relativeTime(timestamp?: number): string;
naturalDay(timestamp?: number, format?: string): string;
ordinal(value: number): string;
numberFormat(number: number, decimals?: number, decimalSep?: string, thousandsSep?: string): string;
truncatechars(str: string, maxLength: number): string;
truncatewords(str: string, maxWords: number): string;
pad(str: string, length: number, padChar?: string, direction?: "left" | "right"): string;
date(format: string, timestamp?: Date | number): string;
time(): number;
linebreaks(str: string): string;
nl2br(str: string): string;
}
export interface EmojiUtils {
getEmojiColors(emoji: any): number[] | null;
getURL(emoji: any): string;
filterUnsupportedEmojis(emojis: any[]): any[];
triggerFullscreenAnimation(emoji: any, node: HTMLElement): void;
applyPlatformToThemedEmojiColorPalette(colors: any): any;
}

View file

@ -21,11 +21,8 @@ import { ScreenshareIcon } from "@components/Icons";
import { Devs } from "@utils/constants";
import { openImageModal } from "@utils/discord";
import definePlugin from "@utils/types";
import { Channel, User } from "@vencord/discord-types";
import { Menu } from "@webpack/common";
import { ApplicationStreamingStore, ApplicationStreamPreviewStore } from "./webpack/stores";
import { ApplicationStream, Stream } from "./webpack/types/stores";
import { ApplicationStream, Channel, Stream, User } from "@vencord/discord-types";
import { ApplicationStreamingStore, ApplicationStreamPreviewStore, Menu } from "@webpack/common";
export interface UserContextProps {
channel: Channel,

View file

@ -1,24 +0,0 @@
/*
* Vencord, a modification for Discord's desktop app
* Copyright (c) 2023 Vendicated and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { findStoreLazy } from "@webpack";
import * as t from "./types/stores";
export const ApplicationStreamPreviewStore: t.ApplicationStreamPreviewStore = findStoreLazy("ApplicationStreamPreviewStore");
export const ApplicationStreamingStore: t.ApplicationStreamingStore = findStoreLazy("ApplicationStreamingStore");

View file

@ -20,12 +20,9 @@ import { definePluginSettings } from "@api/Settings";
import { Devs } from "@utils/constants";
import { Logger } from "@utils/Logger";
import definePlugin, { OptionType } from "@utils/types";
import { findStoreLazy } from "@webpack";
import { Constants, FluxDispatcher, GuildStore, RelationshipStore, SnowflakeUtils, UserStore } from "@webpack/common";
import { Constants, FluxDispatcher, GuildStore, RelationshipStore, SnowflakeUtils, UserAffinitiesStore, UserStore } from "@webpack/common";
import { Settings } from "Vencord";
const UserAffinitiesStore = findStoreLazy("UserAffinitiesV2Store");
export default definePlugin({
name: "ImplicitRelationships",
description: "Shows your implicit relationships in the Friends tab.",

View file

@ -23,27 +23,14 @@ import { cl, getGuildPermissionSpecMap } from "@plugins/permissionsViewer/utils"
import { copyToClipboard } from "@utils/clipboard";
import { getIntlMessage, getUniqueUsername } from "@utils/discord";
import { ModalCloseButton, ModalContent, ModalHeader, ModalProps, ModalRoot, ModalSize, openModal } from "@utils/modal";
import { Guild, Role, UnicodeEmoji, User } from "@vencord/discord-types";
import { Guild, Role, RoleOrUserPermission, UnicodeEmoji, User } from "@vencord/discord-types";
import { PermissionOverwriteType } from "@vencord/discord-types/enums";
import { findByCodeLazy } from "@webpack";
import { ContextMenuApi, FluxDispatcher, GuildMemberStore, GuildRoleStore, i18n, Menu, PermissionsBits, ScrollerThin, Text, Tooltip, useEffect, useMemo, UserStore, useState, useStateFromStores } from "@webpack/common";
import { settings } from "..";
import { PermissionAllowedIcon, PermissionDefaultIcon, PermissionDeniedIcon } from "./icons";
export const enum PermissionType {
Role = 0,
User = 1,
Owner = 2
}
export interface RoleOrUserPermission {
type: PermissionType;
id?: string;
permissions?: bigint;
overwriteAllow?: bigint;
overwriteDeny?: bigint;
}
type GetRoleIconData = (role: Role, size: number) => { customIconSrc?: string; unicodeEmoji?: UnicodeEmoji; };
const getRoleIconData: GetRoleIconData = findByCodeLazy("convertSurrogateToName", "customIconSrc", "unicodeEmoji");
@ -71,7 +58,7 @@ function RolesAndUsersPermissionsComponent({ permissions, guild, modalProps, hea
useEffect(() => {
const usersToRequest = permissions
.filter(p => p.type === PermissionType.User && !GuildMemberStore.isMember(guild.id, p.id!))
.filter(p => p.type === PermissionOverwriteType.MEMBER && !GuildMemberStore.isMember(guild.id, p.id!))
.map(({ id }) => id);
FluxDispatcher.dispatch({
@ -122,7 +109,7 @@ function RolesAndUsersPermissionsComponent({ permissions, guild, modalProps, hea
<div
className={cl("modal-list-item", { "modal-list-item-active": selectedItemIndex === index })}
onContextMenu={e => {
if (permission.type === PermissionType.Role)
if (permission.type === PermissionOverwriteType.ROLE)
ContextMenuApi.openContextMenu(e, () => (
<RoleContextMenu
guild={guild}
@ -130,7 +117,7 @@ function RolesAndUsersPermissionsComponent({ permissions, guild, modalProps, hea
onClose={modalProps.onClose}
/>
));
else if (permission.type === PermissionType.User) {
else if (permission.type === PermissionOverwriteType.MEMBER) {
ContextMenuApi.openContextMenu(e, () => (
<UserContextMenu
userId={permission.id!}
@ -139,19 +126,19 @@ function RolesAndUsersPermissionsComponent({ permissions, guild, modalProps, hea
}
}}
>
{(permission.type === PermissionType.Role || permission.type === PermissionType.Owner) && (
{(permission.type === PermissionOverwriteType.ROLE || permission.type === PermissionOverwriteType.OWNER) && (
<span
className={cl("modal-role-circle")}
style={{ backgroundColor: role?.colorString ?? "var(--primary-300)" }}
/>
)}
{permission.type === PermissionType.Role && roleIconSrc != null && (
{permission.type === PermissionOverwriteType.ROLE && roleIconSrc != null && (
<img
className={cl("modal-role-image")}
src={roleIconSrc}
/>
)}
{permission.type === PermissionType.User && user != null && (
{permission.type === PermissionOverwriteType.MEMBER && user != null && (
<img
className={cl("modal-user-img")}
src={user.getAvatarURL(void 0, void 0, false)}
@ -159,9 +146,9 @@ function RolesAndUsersPermissionsComponent({ permissions, guild, modalProps, hea
)}
<Text variant="text-md/normal" className={cl("modal-list-item-text")}>
{
permission.type === PermissionType.Role
permission.type === PermissionOverwriteType.ROLE
? role?.name ?? "Unknown Role"
: permission.type === PermissionType.User
: permission.type === PermissionOverwriteType.MEMBER
? (user != null && getUniqueUsername(user)) ?? "Unknown User"
: (
<Flex gap="0.2em">

View file

@ -21,12 +21,13 @@ import { HeadingTertiary } from "@components/Heading";
import { cl, getGuildPermissionSpecMap, getSortedRolesForMember, sortUserRoles } from "@plugins/permissionsViewer/utils";
import { getIntlMessage } from "@utils/discord";
import { classes } from "@utils/misc";
import type { Guild, GuildMember } from "@vencord/discord-types";
import type { Guild, GuildMember, RoleOrUserPermission } from "@vencord/discord-types";
import { PermissionOverwriteType } from "@vencord/discord-types/enums";
import { findCssClassesLazy } from "@webpack";
import { PermissionsBits, Text, Tooltip, useMemo, UserStore } from "@webpack/common";
import { PermissionsSortOrder, settings } from "..";
import openRolesAndUsersPermissionsModal, { PermissionType, type RoleOrUserPermission } from "./RolesAndUsersPermissions";
import openRolesAndUsersPermissionsModal from "./RolesAndUsersPermissions";
interface UserPermission {
permission: string;
@ -91,13 +92,13 @@ function UserPermissionsComponent({ guild, guildMember, closePopout }: { guild:
const userRoles = getSortedRolesForMember(guild, guildMember);
const rolePermissions: Array<RoleOrUserPermission> = userRoles.map(role => ({
type: PermissionType.Role,
type: PermissionOverwriteType.ROLE,
...role
}));
if (guild.ownerId === guildMember.userId) {
rolePermissions.push({
type: PermissionType.Owner,
type: PermissionOverwriteType.OWNER,
permissions: Object.values(PermissionsBits).reduce((prev, curr) => prev | curr, 0n)
});

View file

@ -26,11 +26,12 @@ import { TooltipContainer } from "@components/TooltipContainer";
import { Devs } from "@utils/constants";
import { classes } from "@utils/misc";
import definePlugin, { OptionType } from "@utils/types";
import type { Guild } from "@vencord/discord-types";
import type { Guild, RoleOrUserPermission } from "@vencord/discord-types";
import { PermissionOverwriteType } from "@vencord/discord-types/enums";
import { findCssClassesLazy } from "@webpack";
import { Button, ChannelStore, Dialog, GuildMemberStore, GuildRoleStore, GuildStore, match, Menu, PermissionsBits, Popout, useRef, UserStore } from "@webpack/common";
import openRolesAndUsersPermissionsModal, { PermissionType, RoleOrUserPermission } from "./components/RolesAndUsersPermissions";
import openRolesAndUsersPermissionsModal from "./components/RolesAndUsersPermissions";
import UserPermissions from "./components/UserPermissions";
import { getSortedRolesForMember, sortPermissionOverwrites } from "./utils";
@ -75,13 +76,13 @@ function MenuItem(guildId: string, id?: string, type?: MenuItemParentType) {
const permissions: RoleOrUserPermission[] = getSortedRolesForMember(guild, member)
.map(role => ({
type: PermissionType.Role,
type: PermissionOverwriteType.ROLE,
...role
}));
if (guild.ownerId === id) {
permissions.push({
type: PermissionType.Owner,
type: PermissionOverwriteType.OWNER,
permissions: Object.values(PermissionsBits).reduce((prev, curr) => prev | curr, 0n)
});
}
@ -95,7 +96,7 @@ function MenuItem(guildId: string, id?: string, type?: MenuItemParentType) {
const channel = ChannelStore.getChannel(id!);
const permissions = sortPermissionOverwrites(Object.values(channel.permissionOverwrites).map(({ id, allow, deny, type }) => ({
type: type as PermissionType,
type,
id,
overwriteAllow: allow,
overwriteDeny: deny
@ -108,7 +109,7 @@ function MenuItem(guildId: string, id?: string, type?: MenuItemParentType) {
})
.otherwise(() => {
const permissions = GuildRoleStore.getSortedRoles(guild.id).map(role => ({
type: PermissionType.Role,
type: PermissionOverwriteType.ROLE,
...role
}));
@ -143,7 +144,6 @@ function makeContextMenuPatch(childId: string | string[], type?: MenuItemParentT
.with(MenuItemParentType.Guild, () => MenuItem(props.guild.id))
.otherwise(() => null);
if (item == null) return;
if (group) {

View file

@ -18,12 +18,11 @@
import { classNameFactory } from "@utils/css";
import { Guild, GuildMember, Role } from "@vencord/discord-types";
import { PermissionOverwriteType } from "@vencord/discord-types/enums";
import { findByPropsLazy } from "@webpack";
import { GuildRoleStore } from "@webpack/common";
import { PermissionsSortOrder, settings } from ".";
import { PermissionType } from "./components/RolesAndUsersPermissions";
export const { getGuildPermissionSpecMap } = findByPropsLazy("getGuildPermissionSpecMap");
export const cl = classNameFactory("vc-permviewer-");
@ -50,7 +49,7 @@ export function sortPermissionOverwrites<T extends { id: string; type: number; }
const roles = GuildRoleStore.getRolesSnapshot(guildId);
return overwrites.sort((a, b) => {
if (a.type !== PermissionType.Role || b.type !== PermissionType.Role) return 0;
if (a.type !== PermissionOverwriteType.ROLE || b.type !== PermissionOverwriteType.ROLE) return 0;
const roleA = roles[a.id];
const roleB = roles[b.id];

View file

@ -20,11 +20,11 @@ import { isPluginEnabled } from "@api/PluginManager";
import { Settings } from "@api/Settings";
import ErrorBoundary from "@components/ErrorBoundary";
import PermissionsViewerPlugin from "@plugins/permissionsViewer";
import openRolesAndUsersPermissionsModal, { PermissionType, RoleOrUserPermission } from "@plugins/permissionsViewer/components/RolesAndUsersPermissions";
import openRolesAndUsersPermissionsModal from "@plugins/permissionsViewer/components/RolesAndUsersPermissions";
import { sortPermissionOverwrites } from "@plugins/permissionsViewer/utils";
import { classes } from "@utils/misc";
import { formatDuration } from "@utils/text";
import type { Channel } from "@vencord/discord-types";
import type { Channel, RoleOrUserPermission } from "@vencord/discord-types";
import { findByPropsLazy, findComponentByCodeLazy, findCssClassesLazy } from "@webpack";
import { EmojiStore, FluxDispatcher, GuildMemberStore, GuildStore, Parser, PermissionsBits, PermissionStore, SnowflakeUtils, Text, Timestamp, Tooltip, useEffect, useState } from "@webpack/common";
@ -46,22 +46,6 @@ interface DefaultReaction {
emojiName: string | null;
}
interface Tag {
id: string;
name: string;
emojiId: string | null;
emojiName: string | null;
moderated: boolean;
}
interface ExtendedChannel extends Channel {
defaultThreadRateLimitPerUser?: number;
defaultSortOrder?: SortOrderTypes | null;
defaultForumLayout?: ForumLayoutTypes;
defaultReactionEmoji?: DefaultReaction | null;
availableTags?: Array<Tag>;
}
const enum ChannelTypes {
GUILD_TEXT = 0,
GUILD_VOICE = 2,
@ -80,7 +64,6 @@ const enum ChannelFlags {
REQUIRE_TAG = 1 << 4
}
const ChatScrollClasses = findCssClassesLazy("auto", "managedReactiveScroller", "customTheme");
const ChannelBeginHeader = findComponentByCodeLazy("#{intl::ROLE_REQUIRED_SINGLE_USER_MESSAGE}");
const TagComponent = findComponentByCodeLazy("#{intl::FORUM_TAG_A11Y_FILTER_BY_TAG}");
@ -115,7 +98,7 @@ const VideoQualityModesToNames = {
// Icon from the modal when clicking a message link you don't have access to view
const HiddenChannelLogo = "/assets/433e3ec4319a9d11b0cbe39342614982.svg";
function HiddenChannelLockScreen({ channel }: { channel: ExtendedChannel; }) {
function HiddenChannelLockScreen({ channel }: { channel: Channel; }) {
const { defaultAllowedUsersAndRolesDropdownState } = settings.use(["defaultAllowedUsersAndRolesDropdownState"]);
const [permissions, setPermissions] = useState<RoleOrUserPermission[]>([]);
@ -142,7 +125,7 @@ function HiddenChannelLockScreen({ channel }: { channel: ExtendedChannel; }) {
useEffect(() => {
const membersToFetch: Array<string> = [];
const guildOwnerId = GuildStore.getGuild(guild_id).ownerId;
const guildOwnerId = GuildStore.getGuild(guild_id)?.ownerId;
if (!GuildMemberStore.getMember(guild_id, guildOwnerId)) membersToFetch.push(guildOwnerId);
Object.values(permissionOverwrites).forEach(({ type, id: userId }) => {
@ -161,7 +144,7 @@ function HiddenChannelLockScreen({ channel }: { channel: ExtendedChannel; }) {
if (Settings.plugins.PermissionsViewer.enabled) {
setPermissions(sortPermissionOverwrites(Object.values(permissionOverwrites).map(overwrite => ({
type: overwrite.type as PermissionType,
type: overwrite.type,
id: overwrite.id,
overwriteAllow: overwrite.allow,
overwriteDeny: overwrite.deny

View file

@ -80,6 +80,12 @@ export let LocaleStore: t.LocaleStore;
export let RTCConnectionStore: t.RTCConnectionStore;
export let SoundboardStore: t.SoundboardStore;
export let PopoutWindowStore: t.PopoutWindowStore;
export let ApplicationCommandIndexStore: t.ApplicationCommandIndexStore;
export let EditMessageStore: t.EditMessageStore;
export let ExperimentStore: t.ExperimentStore;
export let UserAffinitiesStore: t.UserAffinitiesStore;
export let ApplicationStreamingStore: t.ApplicationStreamingStore;
export let ApplicationStreamPreviewStore: t.ApplicationStreamPreviewStore;
/**
* @see jsdoc of {@link t.useStateFromStores}
@ -132,6 +138,12 @@ waitForStore("RTCConnectionStore", m => RTCConnectionStore = m);
waitForStore("SoundboardStore", m => SoundboardStore = m);
waitForStore("PopoutWindowStore", m => PopoutWindowStore = m);
waitForStore("PendingReplyStore", m => PendingReplyStore = m);
waitForStore("ApplicationCommandIndexStore", m => ApplicationCommandIndexStore = m);
waitForStore("EditMessageStore", m => EditMessageStore = m);
waitForStore("ExperimentStore", m => ExperimentStore = m);
waitForStore("UserAffinitiesV2Store", m => UserAffinitiesStore = m);
waitForStore("ApplicationStreamingStore", m => ApplicationStreamingStore = m);
waitForStore("ApplicationStreamPreviewStore", m => ApplicationStreamPreviewStore = m);
waitForStore("ThemeStore", m => {
ThemeStore = m;
// Importing this directly causes all webpack commons to be imported, which can easily cause circular dependencies.