refactor discord types into separate npm package (#3520)

Co-authored-by: V <vendicated@riseup.net>
Co-authored-by: sadan <117494111+sadan4@users.noreply.github.com>
Co-authored-by: ezzud <contact@ezzud.fr>
This commit is contained in:
V 2025-07-10 00:38:39 +02:00 committed by dorkbutt
parent 3bbf885146
commit 619b0ef858
No known key found for this signature in database
149 changed files with 1561 additions and 751 deletions

View file

@ -8,9 +8,9 @@ import "./ChatButton.css";
import ErrorBoundary from "@components/ErrorBoundary";
import { Logger } from "@utils/Logger";
import { Channel } from "@vencord/discord-types";
import { waitFor } from "@webpack";
import { Button, ButtonWrapperClasses, Tooltip } from "@webpack/common";
import { Channel } from "discord-types/general";
import { HTMLProps, JSX, MouseEventHandler, ReactNode } from "react";
let ChannelTextAreaClasses: Record<"button" | "buttonContainer", string>;

View file

@ -17,13 +17,11 @@
*/
import { mergeDefaults } from "@utils/mergeDefaults";
import { CommandArgument, Message } from "@vencord/discord-types";
import { findByCodeLazy } from "@webpack";
import { MessageActions, SnowflakeUtils } from "@webpack/common";
import { Message } from "discord-types/general";
import type { PartialDeep } from "type-fest";
import { Argument } from "./types";
const createBotMessage = findByCodeLazy('username:"Clyde"');
export function generateId() {
@ -51,8 +49,8 @@ export function sendBotMessage(channelId: string, message: PartialDeep<Message>)
* @param fallbackValue Fallback value in case this option wasn't passed
* @returns Value
*/
export function findOption<T>(args: Argument[], name: string): T & {} | undefined;
export function findOption<T>(args: Argument[], name: string, fallbackValue: T): T & {};
export function findOption(args: Argument[], name: string, fallbackValue?: any) {
export function findOption<T>(args: CommandArgument[], name: string): T & {} | undefined;
export function findOption<T>(args: CommandArgument[], name: string, fallbackValue: T): T & {};
export function findOption(args: CommandArgument[], name: string, fallbackValue?: any) {
return (args.find(a => a.name === name)?.value ?? fallbackValue) as any;
}

View file

@ -18,38 +18,39 @@
import { Logger } from "@utils/Logger";
import { makeCodeblock } from "@utils/text";
import { CommandArgument, CommandContext, CommandOption } from "@vencord/discord-types";
import { sendBotMessage } from "./commandHelpers";
import { ApplicationCommandInputType, ApplicationCommandOptionType, ApplicationCommandType, Argument, Command, CommandContext, Option } from "./types";
import { ApplicationCommandInputType, ApplicationCommandOptionType, ApplicationCommandType, VencordCommand } from "./types";
export * from "./commandHelpers";
export * from "./types";
export let BUILT_IN: Command[];
export const commands = {} as Record<string, Command>;
export let BUILT_IN: VencordCommand[];
export const commands = {} as Record<string, VencordCommand>;
// hack for plugins being evaluated before we can grab these from webpack
const OptPlaceholder = Symbol("OptionalMessageOption") as any as Option;
const ReqPlaceholder = Symbol("RequiredMessageOption") as any as Option;
const OptPlaceholder = Symbol("OptionalMessageOption") as any as CommandOption;
const ReqPlaceholder = Symbol("RequiredMessageOption") as any as CommandOption;
/**
* Optional message option named "message" you can use in commands.
* Used in "tableflip" or "shrug"
* @see {@link RequiredMessageOption}
*/
export let OptionalMessageOption: Option = OptPlaceholder;
export let OptionalMessageOption: CommandOption = OptPlaceholder;
/**
* Required message option named "message" you can use in commands.
* Used in "me"
* @see {@link OptionalMessageOption}
*/
export let RequiredMessageOption: Option = ReqPlaceholder;
export let RequiredMessageOption: CommandOption = ReqPlaceholder;
// Discord's command list has random gaps for some reason, which can cause issues while rendering the commands
// Add this offset to every added command to keep them unique
let commandIdOffset: number;
export const _init = function (cmds: Command[]) {
export const _init = function (cmds: VencordCommand[]) {
try {
BUILT_IN = cmds;
OptionalMessageOption = cmds.find(c => (c.untranslatedName || c.displayName) === "shrug")!.options![0];
@ -61,7 +62,7 @@ export const _init = function (cmds: Command[]) {
return cmds;
} as never;
export const _handleCommand = function (cmd: Command, args: Argument[], ctx: CommandContext) {
export const _handleCommand = function (cmd: VencordCommand, args: CommandArgument[], ctx: CommandContext) {
if (!cmd.isVencordCommand)
return cmd.execute(args, ctx);
@ -92,7 +93,7 @@ export const _handleCommand = function (cmd: Command, args: Argument[], ctx: Com
* Prepare a Command Option for Discord by filling missing fields
* @param opt
*/
export function prepareOption<O extends Option | Command>(opt: O): O {
export function prepareOption<O extends CommandOption | VencordCommand>(opt: O): O {
opt.displayName ||= opt.name;
opt.displayDescription ||= opt.description;
opt.options?.forEach((opt, i, opts) => {
@ -109,7 +110,7 @@ export function prepareOption<O extends Option | Command>(opt: O): O {
// Yes, Discord registers individual commands for each subcommand
// TODO: This probably doesn't support nested subcommands. If that is ever needed,
// investigate
function registerSubCommands(cmd: Command, plugin: string) {
function registerSubCommands(cmd: VencordCommand, plugin: string) {
cmd.options?.forEach(o => {
if (o.type !== ApplicationCommandOptionType.SUB_COMMAND)
throw new Error("When specifying sub-command options, all options must be sub-commands.");
@ -132,7 +133,7 @@ function registerSubCommands(cmd: Command, plugin: string) {
});
}
export function registerCommand<C extends Command>(command: C, plugin: string) {
export function registerCommand<C extends VencordCommand>(command: C, plugin: string) {
if (!BUILT_IN) {
console.warn(
"[CommandsAPI]",

View file

@ -1,106 +1,12 @@
/*
* Vencord, a modification for Discord's desktop app
* Copyright (c) 2022 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/>.
*/
* Vencord, a Discord client mod
* Copyright (c) 2025 Vendicated and contributors
* SPDX-License-Identifier: GPL-3.0-or-later
*/
import { Channel, Guild } from "discord-types/general";
import { Promisable } from "type-fest";
import { Command } from "@vencord/discord-types";
export { ApplicationCommandInputType, ApplicationCommandOptionType, ApplicationCommandType } from "@vencord/discord-types/enums";
export interface CommandContext {
channel: Channel;
guild?: Guild;
}
export const enum ApplicationCommandOptionType {
SUB_COMMAND = 1,
SUB_COMMAND_GROUP = 2,
STRING = 3,
INTEGER = 4,
BOOLEAN = 5,
USER = 6,
CHANNEL = 7,
ROLE = 8,
MENTIONABLE = 9,
NUMBER = 10,
ATTACHMENT = 11,
}
export const enum ApplicationCommandInputType {
BUILT_IN = 0,
BUILT_IN_TEXT = 1,
BUILT_IN_INTEGRATION = 2,
BOT = 3,
PLACEHOLDER = 4,
}
export interface Option {
name: string;
displayName?: string;
type: ApplicationCommandOptionType;
description: string;
displayDescription?: string;
required?: boolean;
options?: Option[];
choices?: Array<ChoicesOption>;
}
export interface ChoicesOption {
label: string;
value: string;
name: string;
displayName?: string;
}
export const enum ApplicationCommandType {
CHAT_INPUT = 1,
USER = 2,
MESSAGE = 3,
}
export interface CommandReturnValue {
content: string;
/** TODO: implement */
cancel?: boolean;
}
export interface Argument {
type: ApplicationCommandOptionType;
name: string;
value: string;
focused: undefined;
options: Argument[];
}
export interface Command {
id?: string;
applicationId?: string;
type?: ApplicationCommandType;
inputType?: ApplicationCommandInputType;
plugin?: string;
export interface VencordCommand extends Command {
isVencordCommand?: boolean;
name: string;
untranslatedName?: string;
displayName?: string;
description: string;
untranslatedDescription?: string;
displayDescription?: string;
options?: Option[];
predicate?(ctx: CommandContext): boolean;
execute(args: Argument[], ctx: CommandContext): Promisable<void | CommandReturnValue>;
}

View file

@ -22,9 +22,9 @@ export function promisifyRequest<T = undefined>(
request: IDBRequest<T> | IDBTransaction,
): Promise<T> {
return new Promise<T>((resolve, reject) => {
// @ts-ignore - file size hacks
// @ts-expect-error - file size hacks
request.oncomplete = request.onsuccess = () => resolve(request.result);
// @ts-ignore - file size hacks
// @ts-expect-error - file size hacks
request.onabort = request.onerror = () => reject(request.error);
});
}

View file

@ -17,7 +17,7 @@
*/
import ErrorBoundary from "@components/ErrorBoundary";
import { Channel, User } from "discord-types/general/index.js";
import { Channel, User } from "@vencord/discord-types";
import { JSX } from "react";
interface DecoratorProps {

View file

@ -17,7 +17,7 @@
*/
import ErrorBoundary from "@components/ErrorBoundary";
import { Channel, Message } from "discord-types/general/index.js";
import { Channel, Message } from "@vencord/discord-types";
import { JSX } from "react";
export interface MessageDecorationProps {

View file

@ -17,9 +17,8 @@
*/
import { Logger } from "@utils/Logger";
import type { Channel, CustomEmoji, Message } from "@vencord/discord-types";
import { MessageStore } from "@webpack/common";
import { CustomEmoji } from "@webpack/types";
import type { Channel, Message } from "discord-types/general";
import type { Promisable } from "type-fest";
const MessageEventsLogger = new Logger("MessageEvents", "#e5c890");

View file

@ -18,7 +18,7 @@
import ErrorBoundary from "@components/ErrorBoundary";
import { Logger } from "@utils/Logger";
import { Channel, Message } from "discord-types/general";
import { Channel, Message } from "@vencord/discord-types";
import type { ComponentType, MouseEventHandler } from "react";
const logger = new Logger("MessagePopover");

View file

@ -4,9 +4,8 @@
* SPDX-License-Identifier: GPL-3.0-or-later
*/
import { FluxStore, Message } from "@vencord/discord-types";
import { MessageCache, MessageStore } from "@webpack/common";
import { FluxStore } from "@webpack/types";
import { Message } from "discord-types/general";
/**
* Update and re-render a message

View file

@ -268,7 +268,7 @@ type ResolveUseSettings<T extends object> = {
[Key in keyof T]:
Key extends string
? T[Key] extends Record<string, unknown>
// @ts-ignore "Type instantiation is excessively deep and possibly infinite"
// @ts-expect-error "Type instantiation is excessively deep and possibly infinite"
? UseSettings<T[Key]> extends string ? `${Key}.${UseSettings<T[Key]>}` : never
: Key
: never;

View file

@ -16,8 +16,8 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { ButtonProps } from "@vencord/discord-types";
import { Button } from "@webpack/common";
import { ButtonProps } from "@webpack/types";
import { Heart } from "./Heart";

View file

@ -14,8 +14,8 @@ import { DevsById } from "@utils/constants";
import { fetchUserProfile } from "@utils/discord";
import { classes, pluralise } from "@utils/misc";
import { ModalContent, ModalRoot, openModal } from "@utils/modal";
import { User } from "@vencord/discord-types";
import { Forms, showToast, useEffect, useMemo, UserProfileStore, useStateFromStores } from "@webpack/common";
import { User } from "discord-types/general";
import Plugins from "~plugins";

View file

@ -29,9 +29,9 @@ import { Margins } from "@utils/margins";
import { classes, isObjectEmpty } from "@utils/misc";
import { ModalCloseButton, ModalContent, ModalFooter, ModalHeader, ModalProps, ModalRoot, ModalSize, openModal } from "@utils/modal";
import { OptionType, Plugin } from "@utils/types";
import { User } from "@vencord/discord-types";
import { findByPropsLazy, findComponentByCodeLazy } from "@webpack";
import { Button, Clickable, FluxDispatcher, Forms, React, Text, Tooltip, UserStore, UserUtils } from "@webpack/common";
import { User } from "discord-types/general";
import { Constructor } from "type-fest";
import { PluginMeta } from "~plugins";

View file

@ -6,9 +6,10 @@
import { Logger } from "@utils/Logger";
import { canonicalizeMatch } from "@utils/patches";
import { ModuleFactory } from "@vencord/discord-types/webpack";
import * as Webpack from "@webpack";
import { wreq } from "@webpack";
import { AnyModuleFactory, ModuleFactory } from "@webpack/wreq.d";
import { AnyModuleFactory } from "webpack";
export async function loadLazyChunks() {
const LazyChunkLoaderLogger = new Logger("LazyChunkLoader");

View file

@ -28,7 +28,7 @@ async function runReporter() {
}
}, "Vencord Reporter");
// @ts-ignore
// @ts-expect-error
Vencord.Webpack._initReporter = function () {
// initReporter is called in the patched entry point of Discord
// setImmediate to only start searching for lazy chunks after Discord initialized the app
@ -83,7 +83,6 @@ async function runReporter() {
result = Webpack.mapMangledModule(code, mapper, includeBlacklistedExports);
if (Object.keys(result).length !== Object.keys(mapper).length) throw new Error("Webpack Find Fail");
} else {
// @ts-ignore
result = Webpack[method](...args);
}

View file

@ -38,7 +38,7 @@ const asarPath = join(dirname(injectorPath), "..", asarName);
const discordPkg = require(join(asarPath, "package.json"));
require.main!.filename = join(asarPath, discordPkg.main);
// @ts-ignore Untyped method? Dies from cringe
// @ts-expect-error Untyped method? Dies from cringe
app.setAppPath(asarPath);
if (!IS_VANILLA) {

View file

@ -30,8 +30,8 @@ import { Margins } from "@utils/margins";
import { shouldShowContributorBadge } from "@utils/misc";
import { closeModal, ModalContent, ModalFooter, ModalHeader, ModalRoot, openModal } from "@utils/modal";
import definePlugin from "@utils/types";
import { User } from "@vencord/discord-types";
import { Forms, Toasts, UserStore } from "@webpack/common";
import { User } from "discord-types/general";
const CONTRIBUTOR_BADGE = "https://cdn.discordapp.com/emojis/1092089799109775453.png?size=64";

View file

@ -20,7 +20,7 @@ import { definePluginSettings } from "@api/Settings";
import { Devs } from "@utils/constants";
import { Logger } from "@utils/Logger";
import definePlugin, { OptionType, StartAt } from "@utils/types";
import { WebpackRequire } from "@webpack/wreq.d";
import { WebpackRequire } from "@vencord/discord-types/webpack";
const settings = definePluginSettings({
disableAnalytics: {

View file

@ -213,7 +213,7 @@ export default definePlugin({
get chromiumVersion() {
try {
return VencordNative.native.getVersions().chrome
// @ts-ignore Typescript will add userAgentData IMMEDIATELY
// @ts-expect-error Typescript will add userAgentData IMMEDIATELY
|| navigator.userAgentData?.brands?.find(b => b.brand === "Chromium" || b.brand === "Google Chrome")?.version
|| null;
} catch { // inb4 some stupid browser throws unsupported error for navigator.userAgentData, it's only in chromium

View file

@ -32,8 +32,8 @@ import { onlyOnce } from "@utils/onlyOnce";
import { makeCodeblock } from "@utils/text";
import definePlugin from "@utils/types";
import { checkForUpdates, isOutdated, update } from "@utils/updater";
import { Channel } from "@vencord/discord-types";
import { Alerts, Button, Card, ChannelStore, Forms, GuildMemberStore, Parser, PermissionsBits, PermissionStore, RelationshipStore, showToast, Text, Toasts, UserStore } from "@webpack/common";
import { Channel } from "discord-types/general";
import { JSX } from "react";
import gitHash from "~git-hash";
@ -196,7 +196,6 @@ export default definePlugin({
}
}
// @ts-ignore outdated type
const roles = GuildMemberStore.getSelfMember(VENCORD_GUILD_ID)?.roles;
if (!roles || TrustedRolesIds.some(id => roles.includes(id))) return;

View file

@ -9,9 +9,9 @@ import ErrorBoundary from "@components/ErrorBoundary";
import { Devs } from "@utils/constants";
import { getCurrentChannel } from "@utils/discord";
import definePlugin, { OptionType } from "@utils/types";
import { User } from "@vencord/discord-types";
import { findComponentByCodeLazy } from "@webpack";
import { ContextMenuApi, Menu, useEffect, useRef } from "@webpack/common";
import { User } from "discord-types/general";
interface UserProfileProps {
popoutProps: Record<string, any>;

View file

@ -21,8 +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 { Channel, User } from "discord-types/general";
import { ApplicationStreamingStore, ApplicationStreamPreviewStore } from "./webpack/stores";
import { ApplicationStream, Stream } from "./webpack/types/stores";

View file

@ -16,7 +16,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { FluxStore } from "@webpack/types";
import { FluxStore } from "@vencord/discord-types";
export interface ApplicationStreamPreviewStore extends FluxStore {
getIsPreviewLoading: (guildId: string | bigint | null, channelId: string | bigint, ownerId: string | bigint) => boolean;

View file

@ -21,8 +21,8 @@ import { LinkIcon } from "@components/Icons";
import { copyToClipboard } from "@utils/clipboard";
import { Devs } from "@utils/constants";
import definePlugin from "@utils/types";
import type { Channel, User } from "@vencord/discord-types";
import { Menu } from "@webpack/common";
import type { Channel, User } from "discord-types/general";
interface UserContextProps {
channel: Channel;

View file

@ -6,8 +6,8 @@
import { debounce } from "@shared/debounce";
import { proxyLazy } from "@utils/lazy";
import { User } from "@vencord/discord-types";
import { useEffect, useState, zustandCreate } from "@webpack/common";
import { User } from "discord-types/general";
import { AvatarDecoration } from "../../";
import { getUsersDecorations } from "../api";

View file

@ -11,9 +11,9 @@ import { Margins } from "@utils/margins";
import { classes, copyWithToast } from "@utils/misc";
import { closeAllModals, ModalCloseButton, ModalContent, ModalFooter, ModalHeader, ModalProps, ModalRoot, ModalSize, openModal } from "@utils/modal";
import { Queue } from "@utils/Queue";
import { User } from "@vencord/discord-types";
import { findComponentByCodeLazy } from "@webpack";
import { Alerts, Button, FluxDispatcher, Forms, GuildStore, NavigationRouter, Parser, Text, Tooltip, useEffect, UserStore, UserUtils, useState } from "@webpack/common";
import { User } from "discord-types/general";
import { Decoration, getPresets, Preset } from "../../lib/api";
import { GUILD_ID, INVITE_KEY } from "../../lib/constants";

View file

@ -25,9 +25,9 @@ import { Logger } from "@utils/Logger";
import { Margins } from "@utils/margins";
import { ModalContent, ModalHeader, ModalRoot, openModalLazy } from "@utils/modal";
import definePlugin from "@utils/types";
import { Guild } from "@vencord/discord-types";
import { findByCodeLazy, findStoreLazy } from "@webpack";
import { Constants, EmojiStore, FluxDispatcher, Forms, GuildStore, IconUtils, Menu, PermissionsBits, PermissionStore, React, RestAPI, Toasts, Tooltip, UserStore } from "@webpack/common";
import { Guild } from "discord-types/general";
import { Promisable } from "type-fest";
const StickersStore = findStoreLazy("StickersStore");

View file

@ -23,10 +23,9 @@ import { ApngBlendOp, ApngDisposeOp, importApngJs } from "@utils/dependencies";
import { getCurrentGuild, getEmojiURL } from "@utils/discord";
import { Logger } from "@utils/Logger";
import definePlugin, { OptionType, Patch } from "@utils/types";
import type { Emoji, Message } from "@vencord/discord-types";
import { findByCodeLazy, findByPropsLazy, findStoreLazy, proxyLazyWebpack } from "@webpack";
import { Alerts, ChannelStore, DraftType, EmojiStore, FluxDispatcher, Forms, GuildMemberStore, lodash, Parser, PermissionsBits, PermissionStore, UploadHandler, UserSettingsActionCreators, UserStore } from "@webpack/common";
import type { Emoji } from "@webpack/types";
import type { Message } from "discord-types/general";
import { applyPalette, GIFEncoder, quantize } from "gifenc";
import type { ReactElement, ReactNode } from "react";
@ -813,7 +812,6 @@ export default definePlugin({
let isUsableTwitchSubEmote = false;
if (e.managed && e.guildId) {
// @ts-ignore outdated type
const myRoles = GuildMemberStore.getSelfMember(e.guildId)?.roles ?? [];
isUsableTwitchSubEmote = e.roles.some(r => myRoles.includes(r));
}

View file

@ -25,16 +25,12 @@ import { Devs } from "@utils/constants";
import { Margins } from "@utils/margins";
import { classes, copyWithToast } from "@utils/misc";
import definePlugin, { OptionType } from "@utils/types";
import { User } from "@vencord/discord-types";
import { findComponentByCodeLazy } from "@webpack";
import { Button, ColorPicker, Flex, Forms, React, Text, UserProfileStore, UserStore, useState } from "@webpack/common";
import { User } from "discord-types/general";
import { ReactElement } from "react";
import virtualMerge from "virtual-merge";
interface UserProfile extends User {
themeColors?: Array<number>;
}
interface Colors {
primary: number;
accent: number;
@ -220,7 +216,7 @@ export default definePlugin({
</Forms.FormSection>);
},
settings,
colorDecodeHook(user: UserProfile) {
colorDecodeHook(user: User) {
if (user) {
// don't replace colors if already set with nitro
if (settings.store.nitroFirst && user.themeColors) return user;

View file

@ -18,8 +18,8 @@
import { Devs } from "@utils/constants";
import definePlugin from "@utils/types";
import { Emoji } from "@vencord/discord-types";
import { EmojiStore } from "@webpack/common";
import { Emoji } from "@webpack/types";
interface EmojiAutocompleteState {
query?: {

View file

@ -18,8 +18,8 @@
import { Devs } from "@utils/constants";
import definePlugin from "@utils/types";
import { Channel, User } from "@vencord/discord-types";
import { GuildStore } from "@webpack/common";
import { Channel, User } from "discord-types/general";
export default definePlugin({
name: "ForceOwnerCrown",

View file

@ -22,9 +22,9 @@ import { Devs } from "@utils/constants";
import { getIntlMessage } from "@utils/discord";
import { NoopComponent } from "@utils/react";
import definePlugin from "@utils/types";
import { Message } from "@vencord/discord-types";
import { filters, findByCodeLazy, waitFor } from "@webpack";
import { ChannelStore, ContextMenuApi, UserStore } from "@webpack/common";
import { Message } from "discord-types/general";
const useMessageMenu = findByCodeLazy(".MESSAGE,commandTargetId:");

View file

@ -19,9 +19,9 @@
import { definePluginSettings } from "@api/Settings";
import { Devs } from "@utils/constants";
import definePlugin, { OptionType } from "@utils/types";
import { Channel, Message } from "@vencord/discord-types";
import { findLazy } from "@webpack";
import { ContextMenuApi, FluxDispatcher, Menu, MessageActions } from "@webpack/common";
import { Channel, Message } from "discord-types/general";
interface Sticker {
id: string;

View file

@ -25,8 +25,8 @@ import { ImageInvisible, ImageVisible } from "@components/Icons";
import { Devs } from "@utils/constants";
import { classes } from "@utils/misc";
import definePlugin from "@utils/types";
import { MessageSnapshot } from "@vencord/discord-types";
import { ChannelStore } from "@webpack/common";
import { MessageSnapshot } from "@webpack/types";
const KEY = "HideAttachments_HiddenIds";
@ -56,7 +56,7 @@ export default definePlugin({
}],
renderMessagePopoverButton(msg) {
// @ts-ignore - discord-types lags behind discord.
// @ts-expect-error - discord-types lags behind discord.
const hasAttachmentsInShapshots = msg.messageSnapshots.some(
(snapshot: MessageSnapshot) => snapshot?.message.attachments.length
);

View file

@ -30,9 +30,9 @@ import { disableStyle, enableStyle } from "@api/Styles";
import { Logger } from "@utils/Logger";
import { canonicalizeFind, canonicalizeReplacement } from "@utils/patches";
import { Patch, Plugin, PluginDef, ReporterTestable, StartAt } from "@utils/types";
import { FluxEvents } from "@vencord/discord-types";
import { FluxDispatcher } from "@webpack/common";
import { patches } from "@webpack/patcher";
import { FluxEvents } from "@webpack/types";
import Plugins from "~plugins";

View file

@ -23,8 +23,8 @@ import ErrorBoundary from "@components/ErrorBoundary";
import { Devs } from "@utils/constants";
import { getStegCloak } from "@utils/dependencies";
import definePlugin, { OptionType, ReporterTestable } from "@utils/types";
import { Message } from "@vencord/discord-types";
import { ChannelStore, Constants, RestAPI, Tooltip } from "@webpack/common";
import { Message } from "discord-types/general";
import { buildDecModal } from "./components/DecryptionModal";
import { buildEncModal } from "./components/EncryptionModal";

View file

@ -23,8 +23,8 @@ import { classNameFactory } from "@api/Styles";
import ErrorBoundary from "@components/ErrorBoundary";
import { Devs } from "@utils/constants";
import definePlugin, { OptionType } from "@utils/types";
import { FluxStore } from "@vencord/discord-types";
import { findStoreLazy } from "@webpack";
import { FluxStore } from "@webpack/types";
import { MemberCount } from "./MemberCount";

View file

@ -10,8 +10,8 @@ import { definePluginSettings } from "@api/Settings";
import ErrorBoundary from "@components/ErrorBoundary";
import { Devs } from "@utils/constants";
import definePlugin, { OptionType } from "@utils/types";
import { User } from "@vencord/discord-types";
import { GuildRoleStore, SelectedGuildStore, useState } from "@webpack/common";
import { User } from "discord-types/general";
const settings = definePluginSettings({
showAtSymbol: {

View file

@ -9,9 +9,9 @@ import ErrorBoundary from "@components/ErrorBoundary";
import { Devs } from "@utils/constants";
import { isNonNullish } from "@utils/guards";
import definePlugin, { OptionType } from "@utils/types";
import { Message } from "@vencord/discord-types";
import { findComponentByCodeLazy } from "@webpack";
import { SnowflakeUtils, Tooltip } from "@webpack/common";
import { Message } from "discord-types/general";
type FillValue = ("status-danger" | "status-warning" | "status-positive" | "text-muted");
type Fill = [FillValue, FillValue, FillValue];

View file

@ -24,6 +24,7 @@ import { Devs } from "@utils/constants.js";
import { classes } from "@utils/misc";
import { Queue } from "@utils/Queue";
import definePlugin, { OptionType } from "@utils/types";
import { Channel, Message } from "@vencord/discord-types";
import { findByPropsLazy, findComponentByCodeLazy } from "@webpack";
import {
Button,
@ -39,7 +40,6 @@ import {
Text,
UserStore
} from "@webpack/common";
import { Channel, Message } from "discord-types/general";
import { JSX } from "react";
const messageCache = new Map<string, {
@ -217,7 +217,7 @@ function withEmbeddedBy(message: Message, embeddedBy: string[]) {
return new Proxy(message, {
get(_, prop) {
if (prop === "vencordEmbeddedBy") return embeddedBy;
// @ts-ignore ts so bad
// @ts-expect-error ts so bad
return Reflect.get(...arguments);
}
});
@ -225,7 +225,7 @@ function withEmbeddedBy(message: Message, embeddedBy: string[]) {
function MessageEmbedAccessory({ message }: { message: Message; }) {
// @ts-ignore
// @ts-expect-error
const embeddedBy: string[] = message.vencordEmbeddedBy ?? [];
const accessories = [] as (JSX.Element | null)[];

View file

@ -28,9 +28,9 @@ import { getIntlMessage } from "@utils/discord";
import { Logger } from "@utils/Logger";
import { classes } from "@utils/misc";
import definePlugin, { OptionType } from "@utils/types";
import { Message } from "@vencord/discord-types";
import { findByPropsLazy } from "@webpack";
import { ChannelStore, FluxDispatcher, Menu, MessageStore, Parser, SelectedChannelStore, Timestamp, UserStore, useStateFromStores } from "@webpack/common";
import { Message } from "discord-types/general";
import overlayStyle from "./deleteStyleOverlay.css?managed";
import textStyle from "./deleteStyleText.css?managed";

View file

@ -92,7 +92,7 @@ export default definePlugin({
// TODO(OptionType.CUSTOM Related): Remove DataStore tags migration once enough time has passed
const oldTags = await DataStore.get<Tag[]>(DATA_KEY);
if (oldTags != null) {
// @ts-ignore
// @ts-expect-error
settings.store.tagsList = Object.fromEntries(oldTags.map(oldTag => (delete oldTag.enabled, [oldTag.name, oldTag])));
await DataStore.del(DATA_KEY);
}
@ -211,7 +211,7 @@ export default definePlugin({
description: Object.values(getTags())
.map(tag => `\`${tag.name}\`: ${tag.message.slice(0, 72).replaceAll("\\n", " ")}${tag.message.length > 72 ? "..." : ""}`)
.join("\n") || `${EMOTE} Woops! There are no tags yet, use \`/tags create\` to create one!`,
// @ts-ignore
// @ts-expect-error
color: 0xd77f7f,
type: "rich",
}

View file

@ -23,9 +23,9 @@ import { Devs } from "@utils/constants";
import { isNonNullish } from "@utils/guards";
import { Logger } from "@utils/Logger";
import definePlugin from "@utils/types";
import { Channel, User } from "@vencord/discord-types";
import { findByPropsLazy, findComponentByCodeLazy } from "@webpack";
import { Avatar, ChannelStore, Clickable, IconUtils, RelationshipStore, ScrollerThin, Text, useMemo, UserStore } from "@webpack/common";
import { Channel, User } from "discord-types/general";
import { JSX } from "react";
const SelectedChannelActionCreators = findByPropsLazy("selectPrivateChannel");

View file

@ -24,9 +24,9 @@ import { definePluginSettings } from "@api/Settings";
import { CogWheel } from "@components/Icons";
import { Devs } from "@utils/constants";
import definePlugin, { OptionType } from "@utils/types";
import { Guild } from "@vencord/discord-types";
import { findByCodeLazy, findByPropsLazy, mapMangledModuleLazy } from "@webpack";
import { Menu } from "@webpack/common";
import { Guild } from "discord-types/general";
const { updateGuildNotificationSettings } = findByPropsLazy("updateGuildNotificationSettings");
const { toggleShowAllChannels } = mapMangledModuleLazy(".onboardExistingMember(", {

View file

@ -21,8 +21,8 @@ import { Devs } from "@utils/constants";
import { runtimeHashMessageKey } from "@utils/intlHash";
import { Logger } from "@utils/Logger";
import definePlugin, { OptionType } from "@utils/types";
import { Message } from "@vencord/discord-types";
import { i18n, RelationshipStore } from "@webpack/common";
import { Message } from "discord-types/general";
interface MessageDeleteProps {
// Internal intl message for BLOCKED_MESSAGE_COUNT

View file

@ -19,7 +19,7 @@
import { definePluginSettings } from "@api/Settings";
import { Devs } from "@utils/constants";
import definePlugin, { OptionType } from "@utils/types";
import type { Message } from "discord-types/general";
import type { Message } from "@vencord/discord-types";
const settings = definePluginSettings({
userList: {

View file

@ -7,8 +7,8 @@
import { definePluginSettings } from "@api/Settings";
import { Devs } from "@utils/constants";
import definePlugin, { OptionType } from "@utils/types";
import { MessageJSON } from "@vencord/discord-types";
import { ChannelStore, ReadStateStore, UserStore } from "@webpack/common";
import { MessageJSON } from "discord-types/general";
const enum ChannelType {
DM = 1,

View file

@ -27,7 +27,6 @@ function showDisableInvites(guildId: string) {
if (!guild) return false;
return (
// @ts-expect-error
!hasGuildFeature(guild, "INVITES_DISABLED") &&
PermissionStore.getGuildPermissionProps(guild).canManageRoles
);

View file

@ -22,10 +22,9 @@ import { InfoIcon, OwnerCrownIcon } from "@components/Icons";
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 { findByCodeLazy } from "@webpack";
import { ContextMenuApi, FluxDispatcher, GuildMemberStore, GuildRoleStore, i18n, Menu, PermissionsBits, ScrollerThin, Text, Tooltip, useEffect, useMemo, UserStore, useState, useStateFromStores } from "@webpack/common";
import { UnicodeEmoji } from "@webpack/types";
import type { Guild, Role, User } from "discord-types/general";
import { settings } from "..";
import { cl, getGuildPermissionSpecMap } from "../utils";

View file

@ -19,9 +19,9 @@
import ErrorBoundary from "@components/ErrorBoundary";
import { getIntlMessage } from "@utils/discord";
import { classes } from "@utils/misc";
import type { Guild, GuildMember } from "@vencord/discord-types";
import { filters, findBulk, proxyLazyWebpack } from "@webpack";
import { PermissionsBits, Text, Tooltip, useMemo, UserStore } from "@webpack/common";
import type { Guild, GuildMember } from "discord-types/general";
import { PermissionsSortOrder, settings } from "..";
import { cl, getGuildPermissionSpecMap, getSortedRoles, sortUserRoles } from "../utils";

View file

@ -25,9 +25,9 @@ import { SafetyIcon } from "@components/Icons";
import { Devs } from "@utils/constants";
import { classes } from "@utils/misc";
import definePlugin, { OptionType } from "@utils/types";
import type { Guild, GuildMember } from "@vencord/discord-types";
import { findByPropsLazy } from "@webpack";
import { Button, ChannelStore, Dialog, GuildMemberStore, GuildRoleStore, GuildStore, match, Menu, PermissionsBits, Popout, TooltipContainer, useRef, UserStore } from "@webpack/common";
import type { Guild, GuildMember } from "discord-types/general";
import openRolesAndUsersPermissionsModal, { PermissionType, RoleOrUserPermission } from "./components/RolesAndUsersPermissions";
import UserPermissions from "./components/UserPermissions";
@ -71,7 +71,7 @@ function MenuItem(guildId: string, id?: string, type?: MenuItemParentType) {
const { permissions, header } = match(type)
.returnType<{ permissions: RoleOrUserPermission[], header: string; }>()
.with(MenuItemParentType.User, () => {
const member = GuildMemberStore.getMember(guildId, id!);
const member = GuildMemberStore.getMember(guildId, id!)!;
const permissions: RoleOrUserPermission[] = getSortedRoles(guild, member)
.map(role => ({

View file

@ -17,9 +17,9 @@
*/
import { classNameFactory } from "@api/Styles";
import { Guild, GuildMember, Role } from "@vencord/discord-types";
import { findByPropsLazy } from "@webpack";
import { GuildRoleStore } from "@webpack/common";
import { Guild, GuildMember, Role } from "discord-types/general";
import { PermissionsSortOrder, settings } from ".";
import { PermissionType } from "./components/RolesAndUsersPermissions";

View file

@ -16,10 +16,11 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { ApplicationCommandInputType, ApplicationCommandOptionType, Argument, CommandContext, findOption, sendBotMessage } from "@api/Commands";
import { ApplicationCommandInputType, ApplicationCommandOptionType, findOption, sendBotMessage } from "@api/Commands";
import { Devs } from "@utils/constants";
import { makeLazy } from "@utils/lazy";
import definePlugin from "@utils/types";
import { CommandArgument, CommandContext } from "@vencord/discord-types";
import { findByPropsLazy } from "@webpack";
import { DraftType, UploadHandler, UploadManager, UserUtils } from "@webpack/common";
import { applyPalette, GIFEncoder, quantize } from "gifenc";
@ -54,7 +55,7 @@ function loadImage(source: File | string) {
});
}
async function resolveImage(options: Argument[], ctx: CommandContext, noServerPfp: boolean): Promise<File | string | null> {
async function resolveImage(options: CommandArgument[], ctx: CommandContext, noServerPfp: boolean): Promise<File | string | null> {
for (const opt of options) {
switch (opt.name) {
case "image":
@ -177,6 +178,8 @@ export default definePlugin({
}
gif.finish();
// @ts-ignore This causes a type error on *only some* typescript versions.
// usage adheres to mdn https://developer.mozilla.org/en-US/docs/Web/API/File/File#parameters
const file = new File([gif.bytesView()], "petpet.gif", { type: "image/gif" });
// Immediately after the command finishes, Discord clears all input, including pending attachments.
// Thus, setTimeout is needed to make this execute after Discord cleared the input

View file

@ -11,9 +11,9 @@ import ErrorBoundary from "@components/ErrorBoundary";
import { Devs } from "@utils/constants";
import { classes } from "@utils/misc";
import definePlugin, { OptionType, StartAt } from "@utils/types";
import { Channel } from "@vencord/discord-types";
import { findByPropsLazy, findStoreLazy } from "@webpack";
import { Clickable, ContextMenuApi, FluxDispatcher, Menu, React } from "@webpack/common";
import { Channel } from "discord-types/general";
import { contextMenus } from "./components/contextMenu";
import { openCategoryModal, requireSettingsMenu } from "./components/CreateCategoryModal";

View file

@ -25,9 +25,9 @@ import { Settings } from "@api/Settings";
import ErrorBoundary from "@components/ErrorBoundary";
import { Devs } from "@utils/constants";
import definePlugin, { OptionType } from "@utils/types";
import { User } from "@vencord/discord-types";
import { filters, findStoreLazy, mapMangledModuleLazy } from "@webpack";
import { PresenceStore, Tooltip, UserStore } from "@webpack/common";
import { User } from "discord-types/general";
export interface Session {
sessionId: string;

View file

@ -20,9 +20,9 @@ import { ChatBarButton, ChatBarButtonFactory } from "@api/ChatButtons";
import { generateId, sendBotMessage } from "@api/Commands";
import { Devs } from "@utils/constants";
import definePlugin, { StartAt } from "@utils/types";
import { MessageAttachment } from "@vencord/discord-types";
import { findByPropsLazy } from "@webpack";
import { DraftStore, DraftType, SelectedChannelStore, UserStore, useStateFromStores } from "@webpack/common";
import { MessageAttachment } from "discord-types/general";
const UploadStore = findByPropsLazy("getUploads");

View file

@ -19,8 +19,8 @@
import { definePluginSettings } from "@api/Settings";
import { Devs } from "@utils/constants";
import definePlugin, { OptionType } from "@utils/types";
import { Message } from "@vencord/discord-types";
import { ChannelStore, ComponentDispatch, FluxDispatcher as Dispatcher, MessageActions, MessageStore, PermissionsBits, PermissionStore, SelectedChannelStore, UserStore } from "@webpack/common";
import { Message } from "discord-types/general";
import NoBlockedMessagesPlugin from "plugins/noBlockedMessages";
import NoReplyMentionPlugin from "plugins/noReplyMention";

View file

@ -22,9 +22,9 @@ import { addServerListElement, removeServerListElement, ServerListRenderPosition
import ErrorBoundary from "@components/ErrorBoundary";
import { Devs } from "@utils/constants";
import definePlugin from "@utils/types";
import { Channel } from "@vencord/discord-types";
import { findStoreLazy } from "@webpack";
import { Button, FluxDispatcher, GuildChannelStore, GuildStore, React, ReadStateStore } from "@webpack/common";
import { Channel } from "discord-types/general";
interface ThreadJoined {
channel: Channel;

View file

@ -16,7 +16,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { Channel } from "discord-types/general";
import { Channel } from "@vencord/discord-types";
export interface ChannelDelete {
type: "CHANNEL_DELETE";

View file

@ -19,9 +19,9 @@
import { DataStore, Notices } from "@api/index";
import { showNotification } from "@api/Notifications";
import { getUniqueUsername, openUserProfile } from "@utils/discord";
import { FluxStore } from "@vencord/discord-types";
import { findStoreLazy } from "@webpack";
import { ChannelStore, GuildMemberStore, GuildStore, RelationshipStore, UserStore, UserUtils } from "@webpack/common";
import { FluxStore } from "@webpack/types";
import settings from "./settings";
import { ChannelType, RelationshipType, SimpleGroupChannel, SimpleGuild } from "./types";

View file

@ -9,9 +9,9 @@ import "./style.css";
import ErrorBoundary from "@components/ErrorBoundary";
import { Devs } from "@utils/constants";
import definePlugin from "@utils/types";
import type { Message } from "@vencord/discord-types";
import { findByPropsLazy } from "@webpack";
import { DateUtils, Timestamp } from "@webpack/common";
import type { Message } from "discord-types/general";
import type { HTMLAttributes } from "react";
const MessageClasses = findByPropsLazy("separator", "latin24CompactTimeStamp");

View file

@ -24,9 +24,9 @@ import { NotesIcon, OpenExternalIcon } from "@components/Icons";
import { Devs } from "@utils/constants";
import { classes } from "@utils/misc";
import definePlugin from "@utils/types";
import { Guild, User } from "@vencord/discord-types";
import { findByPropsLazy } from "@webpack";
import { Alerts, Button, Menu, Parser, TooltipContainer } from "@webpack/common";
import { Guild, User } from "discord-types/general";
import { Auth, initAuth, updateAuth } from "./auth";
import { openReviewsModal } from "./components/ReviewModal";

View file

@ -111,7 +111,6 @@ export default definePlugin({
// SUMMARIES_ENABLED feature is not in discord-types
const guild = GuildStore.getGuild(channel.guild_id);
// @ts-expect-error
return hasGuildFeature(guild, "SUMMARIES_ENABLED_GA");
}
});

View file

@ -11,9 +11,9 @@ import { getGuildAcronym, openImageModal, openUserProfile } from "@utils/discord
import { classes } from "@utils/misc";
import { ModalRoot, ModalSize, openModal } from "@utils/modal";
import { useAwaiter } from "@utils/react";
import { Guild, User } from "@vencord/discord-types";
import { findByPropsLazy, findComponentByCodeLazy } from "@webpack";
import { FluxDispatcher, Forms, GuildChannelStore, GuildMemberStore, GuildRoleStore, IconUtils, Parser, PresenceStore, RelationshipStore, ScrollerThin, SnowflakeUtils, TabBar, Timestamp, useEffect, UserStore, UserUtils, useState, useStateFromStores } from "@webpack/common";
import { Guild, User } from "discord-types/general";
const IconClasses = findByPropsLazy("icon", "acronym", "childWrapper");
const FriendRow = findComponentByCodeLazy("discriminatorClass:", ".isMobileOnline", "getAvatarURL");

View file

@ -7,8 +7,8 @@
import { findGroupChildrenByChildId, NavContextMenuPatchCallback } from "@api/ContextMenu";
import { Devs } from "@utils/constants";
import definePlugin from "@utils/types";
import { Guild } from "@vencord/discord-types";
import { Menu } from "@webpack/common";
import { Guild } from "discord-types/general";
import { openGuildInfoModal } from "./GuildInfoModal";

View file

@ -25,9 +25,9 @@ import { CopyIcon, LinkIcon } from "@components/Icons";
import { Devs } from "@utils/constants";
import { copyWithToast } from "@utils/misc";
import definePlugin, { OptionType } from "@utils/types";
import { User } from "@vencord/discord-types";
import { findByCodeLazy, findByPropsLazy } from "@webpack";
import { Tooltip, UserProfileStore } from "@webpack/common";
import { User } from "discord-types/general";
import { VerifiedIcon } from "./VerifiedIcon";

View file

@ -20,9 +20,9 @@ import { Settings } from "@api/Settings";
import ErrorBoundary from "@components/ErrorBoundary";
import { classes } from "@utils/misc";
import { formatDuration } from "@utils/text";
import type { Channel } from "@vencord/discord-types";
import { findByPropsLazy, findComponentByCodeLazy } from "@webpack";
import { EmojiStore, FluxDispatcher, GuildMemberStore, GuildStore, Parser, PermissionsBits, PermissionStore, SnowflakeUtils, Text, Timestamp, Tooltip, useEffect, useState } from "@webpack/common";
import type { Channel } from "discord-types/general";
import openRolesAndUsersPermissionsModal, { PermissionType, RoleOrUserPermission } from "../../permissionsViewer/components/RolesAndUsersPermissions";
import { sortPermissionOverwrites } from "../../permissionsViewer/utils";

View file

@ -25,9 +25,9 @@ import { Devs } from "@utils/constants";
import { classes } from "@utils/misc";
import { canonicalizeMatch } from "@utils/patches";
import definePlugin, { OptionType } from "@utils/types";
import type { Channel, Role } from "@vencord/discord-types";
import { findByPropsLazy } from "@webpack";
import { ChannelStore, PermissionsBits, PermissionStore, Tooltip } from "@webpack/common";
import type { Channel, Role } from "discord-types/general";
import HiddenChannelLockScreen from "./components/HiddenChannelLockScreen";

View file

@ -10,7 +10,7 @@ import { definePluginSettings } from "@api/Settings";
import ErrorBoundary from "@components/ErrorBoundary";
import { Devs } from "@utils/constants";
import definePlugin, { OptionType } from "@utils/types";
import { Message, User } from "discord-types/general";
import { Message, User } from "@vencord/discord-types";
interface UsernameProps {
author: { nick: string; };
@ -62,7 +62,7 @@ export default definePlugin({
const user = userOverride ?? message.author;
let { username } = user;
if (settings.store.displayNames)
username = (user as any).globalName || username;
username = user.globalName || username;
const { nick } = author;
const prefix = withMentionPrefix ? "@" : "";

View file

@ -12,9 +12,9 @@ import { Devs } from "@utils/constants";
import { getIntlMessage } from "@utils/discord";
import { canonicalizeMatch } from "@utils/patches";
import definePlugin, { OptionType } from "@utils/types";
import { Message } from "@vencord/discord-types";
import { findComponentLazy } from "@webpack";
import { ChannelStore, GuildMemberStore, Text, Tooltip } from "@webpack/common";
import { Message } from "discord-types/general";
import { FunctionComponent, ReactNode } from "react";
const countDownFilter = canonicalizeMatch("#{intl::MAX_AGE_NEVER}");

View file

@ -23,8 +23,8 @@ import { classNameFactory } from "@api/Styles";
import ErrorBoundary from "@components/ErrorBoundary";
import { Devs } from "@utils/constants";
import definePlugin, { OptionType } from "@utils/types";
import { User } from "@vencord/discord-types";
import { DateUtils, RelationshipStore, Text, TooltipContainer } from "@webpack/common";
import { User } from "discord-types/general";
import { PropsWithChildren } from "react";
const formatter = new Intl.DateTimeFormat(undefined, {

View file

@ -16,10 +16,11 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { ApplicationCommandInputType, Command, findOption, OptionalMessageOption, sendBotMessage } from "@api/Commands";
import { ApplicationCommandInputType, findOption, OptionalMessageOption, sendBotMessage } from "@api/Commands";
import { Devs } from "@utils/constants";
import { sendMessage } from "@utils/discord";
import definePlugin from "@utils/types";
import { Command } from "@vencord/discord-types";
import { findByPropsLazy } from "@webpack";
import { FluxDispatcher, MessageActions } from "@webpack/common";

View file

@ -6,8 +6,8 @@
import { Devs } from "@utils/constants";
import definePlugin from "@utils/types";
import { Message } from "@vencord/discord-types";
import { UserStore } from "@webpack/common";
import { Message } from "discord-types/general";
export default definePlugin({

View file

@ -16,8 +16,8 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { Message } from "@vencord/discord-types";
import { Parser, useEffect, useState } from "@webpack/common";
import { Message } from "discord-types/general";
import { TranslateIcon } from "./TranslateIcon";
import { cl, TranslationValue } from "./utils";

View file

@ -56,7 +56,7 @@ function TypingIndicator({ channelId, guildId }: { channelId: string; guildId: s
return oldKeys.length === currentKeys.length && currentKeys.every(key => old[key] != null);
}
);
const currentChannelId: string = useStateFromStores([SelectedChannelStore], () => SelectedChannelStore.getChannelId());
const currentChannelId = useStateFromStores([SelectedChannelStore], () => SelectedChannelStore.getChannelId());
if (!settings.store.includeMutedChannels) {
const isChannelMuted = UserGuildSettingsStore.isChannelMuted(guildId, channelId);

View file

@ -21,8 +21,8 @@ import ErrorBoundary from "@components/ErrorBoundary";
import { Devs } from "@utils/constants";
import { openUserProfile } from "@utils/discord";
import definePlugin, { OptionType } from "@utils/types";
import { User } from "@vencord/discord-types";
import { Avatar, GuildMemberStore, React, RelationshipStore } from "@webpack/common";
import { User } from "discord-types/general";
import { PropsWithChildren } from "react";
import managedStyle from "./style.css?managed";

View file

@ -20,8 +20,8 @@ import { findGroupChildrenByChildId, NavContextMenuPatchCallback } from "@api/Co
import { ImageInvisible, ImageVisible } from "@components/Icons";
import { Devs } from "@utils/constants";
import definePlugin from "@utils/types";
import { MessageSnapshot } from "@vencord/discord-types";
import { Constants, Menu, PermissionsBits, PermissionStore, RestAPI, UserStore } from "@webpack/common";
import { MessageSnapshot } from "@webpack/types";
const EMBED_SUPPRESSED = 1 << 2;

View file

@ -20,9 +20,9 @@ import { getUserSettingLazy } from "@api/UserSettings";
import ErrorBoundary from "@components/ErrorBoundary";
import { getIntlMessage } from "@utils/discord";
import { classes } from "@utils/misc";
import { Message } from "@vencord/discord-types";
import { findByPropsLazy } from "@webpack";
import { Tooltip, UserStore } from "@webpack/common";
import { Message } from "discord-types/general";
import { settings } from "./settings";
import { useFormattedPronouns } from "./utils";

View file

@ -7,9 +7,9 @@
import { classNameFactory } from "@api/Styles";
import ErrorBoundary from "@components/ErrorBoundary";
import { classes } from "@utils/misc";
import { Channel } from "@vencord/discord-types";
import { filters, findByCodeLazy, findByPropsLazy, findComponentByCodeLazy, findStoreLazy, mapMangledModuleLazy } from "@webpack";
import { ChannelRouter, ChannelStore, GuildStore, IconUtils, match, P, PermissionsBits, PermissionStore, React, showToast, Text, Toasts, Tooltip, useMemo, UserStore, useStateFromStores } from "@webpack/common";
import { Channel } from "discord-types/general";
const cl = classNameFactory("vc-uvs-");

View file

@ -6,10 +6,9 @@
import { Devs } from "@utils/constants";
import definePlugin from "@utils/types";
import { Channel, Message, User } from "@vencord/discord-types";
import { findByCodeLazy } from "@webpack";
import { FluxDispatcher, RestAPI } from "@webpack/common";
import { Message, User } from "discord-types/general";
import { Channel } from "discord-types/general/index.js";
const enum ReferencedMessageState {
Loaded,

View file

@ -144,7 +144,14 @@ function playSample(tempSettings: any, type: string) {
const currentUser = UserStore.getCurrentUser();
const myGuildId = SelectedGuildStore.getGuildId();
speak(formatText(s[type + "Message"], currentUser.username, "general", (currentUser as any).globalName ?? currentUser.username, GuildMemberStore.getNick(myGuildId, currentUser.id) ?? currentUser.username), s);
speak(formatText(
s[type + "Message"],
currentUser.username,
"general",
currentUser.globalName ?? currentUser.username,
GuildMemberStore.getNick(myGuildId!, currentUser.id) ?? currentUser.username),
s
);
}
export default definePlugin({
@ -177,7 +184,7 @@ export default definePlugin({
const template = settings.store[type + "Message"];
const user = isMe && !settings.store.sayOwnName ? "" : UserStore.getUser(userId).username;
const displayName = user && ((UserStore.getUser(userId) as any).globalName ?? user);
const nickname = user && (GuildMemberStore.getNick(myGuildId, userId) ?? user);
const nickname = user && (GuildMemberStore.getNick(myGuildId!, userId) ?? user);
const channel = ChannelStore.getChannel(id).name;
speak(formatText(template, user, channel, displayName, nickname));

View file

@ -22,8 +22,8 @@ import { ImageIcon } from "@components/Icons";
import { Devs } from "@utils/constants";
import { openImageModal } from "@utils/discord";
import definePlugin, { OptionType } from "@utils/types";
import type { Channel, Guild, User } from "@vencord/discord-types";
import { GuildMemberStore, IconUtils, Menu } from "@webpack/common";
import type { Channel, Guild, User } from "discord-types/general";
interface UserContextProps {

View file

@ -27,8 +27,8 @@ import { Margins } from "@utils/margins";
import { copyWithToast } from "@utils/misc";
import { closeModal, ModalCloseButton, ModalContent, ModalFooter, ModalHeader, ModalRoot, ModalSize, openModal } from "@utils/modal";
import definePlugin, { OptionType } from "@utils/types";
import { Message } from "@vencord/discord-types";
import { Button, ChannelStore, Forms, GuildRoleStore, Menu, Text } from "@webpack/common";
import { Message } from "discord-types/general";
const CopyIcon = () => {

View file

@ -22,10 +22,9 @@ import { sleep } from "@utils/misc";
import { Queue } from "@utils/Queue";
import { useForceUpdater } from "@utils/react";
import definePlugin from "@utils/types";
import { CustomEmoji, Message, ReactionEmoji, User } from "@vencord/discord-types";
import { findByPropsLazy, findComponentByCodeLazy } from "@webpack";
import { ChannelStore, Constants, FluxDispatcher, React, RestAPI, Tooltip, useEffect, useLayoutEffect } from "@webpack/common";
import { CustomEmoji } from "@webpack/types";
import { Message, ReactionEmoji, User } from "discord-types/general";
const UserSummaryItem = findComponentByCodeLazy("defaultRenderUser", "showDefaultAvatarsForNullUsers");
const AvatarStyles = findByPropsLazy("moreUsers", "emptyUser", "avatarContainer", "clickableAvatar");

View file

@ -9,9 +9,9 @@ import { makeRange } from "@components/PluginSettings/components";
import { Devs } from "@utils/constants";
import { Logger } from "@utils/Logger";
import definePlugin, { OptionType, PluginNative, ReporterTestable } from "@utils/types";
import type { Channel, Embed, GuildMember, MessageAttachment, User } from "@vencord/discord-types";
import { findByCodeLazy, findLazy } from "@webpack";
import { Button, ChannelStore, GuildRoleStore, GuildStore, UserStore } from "@webpack/common";
import type { Channel, Embed, GuildMember, MessageAttachment, User } from "discord-types/general";
const ChannelTypes = findLazy(m => m.ANNOUNCEMENT_THREAD === 10);

View file

@ -1,6 +1,5 @@
/* eslint-disable */
const self = module.exports;
/**
* apng-canvas v2.1.2
*
@ -549,11 +548,7 @@ const self = module.exports;
}).call(
this,
Y("VCmEsw"),
"undefined" != typeof self
? self
: "undefined" != typeof window
? window
: {}
module.exports
);
},
{ VCmEsw: 2 },
@ -880,11 +875,7 @@ const self = module.exports;
});
}).call(
this,
"undefined" != typeof self
? self
: "undefined" != typeof window
? window
: {}
module.exports
);
},
{ "./loader": 6, "./parser": 7, "./support-test": 8 },
@ -1153,11 +1144,7 @@ const self = module.exports;
};
}).call(
this,
"undefined" != typeof self
? self
: "undefined" != typeof window
? window
: {}
module.exports
);
},
{ "es6-promise": 1 },

View file

@ -17,9 +17,8 @@
*/
import { MessageObject } from "@api/MessageEvents";
import { Channel, Guild, GuildFeatures, Message, User } from "@vencord/discord-types";
import { ChannelActionCreators, ChannelStore, ComponentDispatch, Constants, FluxDispatcher, GuildStore, i18n, IconUtils, InviteActions, MessageActions, RestAPI, SelectedChannelStore, SelectedGuildStore, UserProfileActions, UserProfileStore, UserSettingsActionCreators, UserUtils } from "@webpack/common";
import { Channel, Guild, Message, User } from "discord-types/general";
import GuildFeatures from "discord-types/other/Constants";
import { Except } from "type-fest";
import { runtimeHashMessageKey } from "./intlHash";
@ -228,6 +227,6 @@ export function getGuildAcronym(guild: Guild): string {
.replace(/\s/g, "");
}
export function hasGuildFeature(guild: Guild, feature: keyof GuildFeatures["GuildFeatures"]): boolean {
export function hasGuildFeature(guild: Guild, feature: GuildFeatures): boolean {
return guild.features?.has(feature) ?? false;
}

View file

@ -18,14 +18,13 @@
import { ProfileBadge } from "@api/Badges";
import { ChatBarButtonFactory } from "@api/ChatButtons";
import { Command } from "@api/Commands";
import { NavContextMenuPatchCallback } from "@api/ContextMenu";
import { MemberListDecoratorFactory } from "@api/MemberListDecorators";
import { MessageAccessoryFactory } from "@api/MessageAccessories";
import { MessageDecorationFactory } from "@api/MessageDecorations";
import { MessageClickListener, MessageEditListener, MessageSendListener } from "@api/MessageEvents";
import { MessagePopoverButtonFactory } from "@api/MessagePopover";
import { FluxEvents } from "@webpack/types";
import { Command, FluxEvents } from "@vencord/discord-types";
import { ReactNode } from "react";
import { Promisable } from "type-fest";

View file

@ -16,9 +16,8 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import * as t from "@vencord/discord-types";
import { findByPropsLazy, findLazy } from "@webpack";
import * as t from "./types/classes";
export const ModalImageClasses: t.ImageModalClasses = findLazy(m => m.image && m.modal && !m.applicationIcon);
export const ButtonWrapperClasses: t.ButtonWrapperClasses = findByPropsLazy("buttonWrapper", "buttonContent");

View file

@ -17,10 +17,10 @@
*/
import { LazyComponent } from "@utils/lazyReact";
import * as t from "@vencord/discord-types";
import { filters, mapMangledModuleLazy, waitFor } from "@webpack";
import { waitForComponent } from "./internal";
import * as t from "./types/components";
const FormTitle = waitForComponent<t.FormTitle>("FormTitle", filters.componentByCode('["defaultMargin".concat', '="h5"'));

View file

@ -21,8 +21,5 @@ export * from "./components";
export * from "./menu";
export * from "./react";
export * from "./stores";
export * as ComponentTypes from "./types/components.d";
export * as MenuTypes from "./types/menu.d";
export * as UtilTypes from "./types/utils.d";
export * from "./userSettings";
export * from "./utils";

View file

@ -16,10 +16,9 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import type * as t from "@vencord/discord-types";
import { filters, mapMangledModuleLazy, waitFor, wreq } from "@webpack";
import type * as t from "./types/menu";
export const Menu = {} as t.Menu;
// Relies on .name properties added by the MenuItemDemanglerAPI

View file

@ -16,11 +16,10 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import * as t from "@vencord/discord-types";
import { findByCodeLazy, findByPropsLazy, waitFor } from "@webpack";
import type * as Stores from "discord-types/stores";
import { waitForStore } from "./internal";
import * as t from "./types/stores";
export const Flux: t.Flux = findByPropsLazy("connectStores");
@ -28,7 +27,7 @@ export type GenericStore = t.FluxStore & Record<string, any>;
export const DraftType = findByPropsLazy("ChannelMessage", "SlashCommand");
export let MessageStore: Omit<Stores.MessageStore, "getMessages"> & GenericStore & {
export let MessageStore: Omit<t.MessageStore, "getMessages"> & GenericStore & {
getMessages(chanId: string): any;
};
@ -41,12 +40,12 @@ export let PresenceStore: GenericStore;
export let GuildStore: t.GuildStore;
export let GuildRoleStore: t.GuildRoleStore;
export let GuildMemberStore: Stores.GuildMemberStore & t.FluxStore;
export let UserStore: Stores.UserStore & t.FluxStore;
export let GuildMemberStore: t.GuildMemberStore;
export let UserStore: t.UserStore;
export let UserProfileStore: GenericStore;
export let SelectedChannelStore: Stores.SelectedChannelStore & t.FluxStore;
export let SelectedGuildStore: t.FluxStore & Record<string, any>;
export let ChannelStore: Stores.ChannelStore & t.FluxStore;
export let SelectedChannelStore: t.SelectedChannelStore;
export let SelectedGuildStore: t.SelectedGuildStore;
export let ChannelStore: t.ChannelStore;
export let RelationshipStore: t.RelationshipStore;
export let EmojiStore: t.EmojiStore;
@ -55,14 +54,7 @@ export let WindowStore: t.WindowStore;
export let DraftStore: t.DraftStore;
/**
* React hook that returns stateful data for one or more stores
* You might need a custom comparator (4th argument) if your store data is an object
* @param stores The stores to listen to
* @param mapper A function that returns the data you need
* @param dependencies An array of reactive values which the hook depends on. Use this if your mapper or equality function depends on the value of another hook
* @param isEqual A custom comparator for the data returned by mapper
*
* @example const user = useStateFromStores([UserStore], () => UserStore.getCurrentUser(), null, (old, current) => old.id === current.id);
* @see jsdoc of {@link t.useStateFromStores}
*/
export const useStateFromStores: t.useStateFromStores = findByCodeLazy("useStateFromStores");

View file

@ -1,39 +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/>.
*/
export interface ImageModalClasses {
image: string,
modal: string,
}
export interface ButtonWrapperClasses {
hoverScale: string;
buttonWrapper: string;
button: string;
iconMask: string;
buttonContent: string;
icon: string;
pulseIcon: string;
pulseButton: string;
notificationDot: string;
sparkleContainer: string;
sparkleStar: string;
sparklePlus: string;
sparkle: string;
active: string;
}

View file

@ -1,545 +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 type { ComponentClass, ComponentPropsWithRef, ComponentType, CSSProperties, FunctionComponent, HtmlHTMLAttributes, HTMLProps, JSX, KeyboardEvent, MouseEvent, PointerEvent, PropsWithChildren, ReactNode, Ref, RefObject } from "react";
export type TextVariant = "heading-sm/normal" | "heading-sm/medium" | "heading-sm/semibold" | "heading-sm/bold" | "heading-md/normal" | "heading-md/medium" | "heading-md/semibold" | "heading-md/bold" | "heading-lg/normal" | "heading-lg/medium" | "heading-lg/semibold" | "heading-lg/bold" | "heading-xl/normal" | "heading-xl/medium" | "heading-xl/bold" | "heading-xxl/normal" | "heading-xxl/medium" | "heading-xxl/bold" | "eyebrow" | "heading-deprecated-14/normal" | "heading-deprecated-14/medium" | "heading-deprecated-14/bold" | "text-xxs/normal" | "text-xxs/medium" | "text-xxs/semibold" | "text-xxs/bold" | "text-xs/normal" | "text-xs/medium" | "text-xs/semibold" | "text-xs/bold" | "text-sm/normal" | "text-sm/medium" | "text-sm/semibold" | "text-sm/bold" | "text-md/normal" | "text-md/medium" | "text-md/semibold" | "text-md/bold" | "text-lg/normal" | "text-lg/medium" | "text-lg/semibold" | "text-lg/bold" | "display-sm" | "display-md" | "display-lg" | "code";
export type FormTextTypes = Record<"DEFAULT" | "INPUT_PLACEHOLDER" | "DESCRIPTION" | "LABEL_BOLD" | "LABEL_SELECTED" | "LABEL_DESCRIPTOR" | "ERROR" | "SUCCESS", string>;
export type HeadingTag = `h${1 | 2 | 3 | 4 | 5 | 6}`;
export type Margins = Record<"marginTop16" | "marginTop8" | "marginBottom8" | "marginTop20" | "marginBottom20", string>;
export type TextProps = PropsWithChildren<HtmlHTMLAttributes<HTMLDivElement> & {
variant?: TextVariant;
tag?: "div" | "span" | "p" | "strong" | HeadingTag;
selectable?: boolean;
lineClamp?: number;
}>;
export type Text = ComponentType<TextProps>;
export type Heading = ComponentType<TextProps>;
export type FormTitle = ComponentType<HTMLProps<HTMLTitleElement> & PropsWithChildren<{
/** default is h5 */
tag?: HeadingTag;
faded?: boolean;
disabled?: boolean;
required?: boolean;
error?: ReactNode;
}>>;
export type FormSection = ComponentType<PropsWithChildren<{
/** default is h5 */
tag?: HeadingTag;
className?: string;
titleClassName?: string;
titleId?: string;
title?: ReactNode;
disabled?: boolean;
htmlFor?: unknown;
}>>;
export type FormDivider = ComponentType<{
className?: string;
style?: CSSProperties;
}>;
export type FormText = ComponentType<PropsWithChildren<{
disabled?: boolean;
selectable?: boolean;
/** defaults to FormText.Types.DEFAULT */
type?: string;
}> & TextProps> & { Types: FormTextTypes; };
export type Tooltip = ComponentType<{
text: ReactNode | ComponentType;
children: FunctionComponent<{
onClick(): void;
onMouseEnter(): void;
onMouseLeave(): void;
onContextMenu(): void;
onFocus(): void;
onBlur(): void;
"aria-label"?: string;
}>;
"aria-label"?: string;
allowOverflow?: boolean;
forceOpen?: boolean;
hide?: boolean;
hideOnClick?: boolean;
shouldShow?: boolean;
spacing?: number;
/** Tooltip.Colors.BLACK */
color?: string;
/** TooltipPositions.TOP */
position?: PopoutPosition;
tooltipClassName?: string;
tooltipContentClassName?: string;
}> & {
Colors: Record<"BLACK" | "BRAND" | "CUSTOM" | "GREEN" | "GREY" | "PRIMARY" | "RED" | "YELLOW", string>;
};
export type TooltipPositions = Record<"BOTTOM" | "CENTER" | "LEFT" | "RIGHT" | "TOP" | "WINDOW_CENTER", string>;
export type TooltipContainer = ComponentType<PropsWithChildren<{
text: ReactNode;
element?: "div" | "span";
"aria-label"?: string | false;
delay?: number;
/** Tooltip.Colors.BLACK */
color?: string;
/** TooltipPositions.TOP */
position?: PopoutPosition;
spacing?: number;
className?: string;
tooltipClassName?: string | null;
tooltipContentClassName?: string | null;
allowOverflow?: boolean;
forceOpen?: boolean;
hideOnClick?: boolean;
disableTooltipPointerEvents?: boolean;
}>>;
export type Card = ComponentType<PropsWithChildren<HTMLProps<HTMLDivElement> & {
editable?: boolean;
outline?: boolean;
/** Card.Types.PRIMARY */
type?: string;
}>> & {
Types: Record<"BRAND" | "CUSTOM" | "DANGER" | "PRIMARY" | "SUCCESS" | "WARNING", string>;
};
export type ComboboxPopout = ComponentType<PropsWithChildren<{
value: Set<any>;
placeholder: string;
children(query: string): ReactNode[];
onChange(value: any): void;
itemToString?: (item: any) => string;
onClose?(): void;
className?: string;
listClassName?: string;
autoFocus?: boolean;
multiSelect?: boolean;
maxVisibleItems?: number;
showScrollbar?: boolean;
}>>;
export interface ButtonProps extends PropsWithChildren<Omit<HTMLProps<HTMLButtonElement>, "size">> {
/** Button.Looks.FILLED */
look?: string;
/** Button.Colors.BRAND */
color?: string;
/** Button.Sizes.MEDIUM */
size?: string;
/** Button.BorderColors.BLACK */
borderColor?: string;
wrapperClassName?: string;
className?: string;
innerClassName?: string;
buttonRef?: Ref<HTMLButtonElement>;
focusProps?: any;
submitting?: boolean;
submittingStartedLabel?: string;
submittingFinishedLabel?: string;
}
export type Button = ComponentType<ButtonProps> & {
BorderColors: Record<"BLACK" | "BRAND" | "BRAND_NEW" | "GREEN" | "LINK" | "PRIMARY" | "RED" | "TRANSPARENT" | "WHITE" | "YELLOW", string>;
Colors: Record<"BRAND" | "RED" | "GREEN" | "YELLOW" | "PRIMARY" | "LINK" | "WHITE" | "BLACK" | "TRANSPARENT" | "BRAND_NEW" | "CUSTOM", string>;
Hovers: Record<"DEFAULT" | "BRAND" | "RED" | "GREEN" | "YELLOW" | "PRIMARY" | "LINK" | "WHITE" | "BLACK" | "TRANSPARENT", string>;
Looks: Record<"FILLED" | "INVERTED" | "OUTLINED" | "LINK" | "BLANK", string>;
Sizes: Record<"NONE" | "TINY" | "SMALL" | "MEDIUM" | "LARGE" | "XLARGE" | "MIN" | "MAX" | "ICON", string>;
Link: any;
};
export type Switch = ComponentType<PropsWithChildren<{
value: boolean;
onChange(value: boolean): void;
disabled?: boolean;
hideBorder?: boolean;
className?: string;
style?: CSSProperties;
note?: ReactNode;
tooltipNote?: ReactNode;
}>>;
export type CheckboxAligns = {
CENTER: "center";
TOP: "top";
};
export type CheckboxTypes = {
DEFAULT: "default";
INVERTED: "inverted";
GHOST: "ghost";
ROW: "row";
};
export type Checkbox = ComponentType<PropsWithChildren<{
value: boolean;
onChange(event: PointerEvent, value: boolean): void;
align?: "center" | "top";
disabled?: boolean;
displayOnly?: boolean;
readOnly?: boolean;
reverse?: boolean;
shape?: string;
size?: number;
type?: "default" | "inverted" | "ghost" | "row";
}>> & {
Shapes: Record<"BOX" | "ROUND" | "SMALL_BOX", string>;
Aligns: CheckboxAligns;
Types: CheckboxTypes;
};
export type Timestamp = ComponentType<PropsWithChildren<{
timestamp: Date;
isEdited?: boolean;
className?: string;
id?: string;
cozyAlt?: boolean;
compact?: boolean;
isInline?: boolean;
isVisibleOnlyOnHover?: boolean;
}>>;
export type TextInput = ComponentType<PropsWithChildren<{
name?: string;
onChange?(value: string, name?: string): void;
placeholder?: string;
editable?: boolean;
/** defaults to 999. Pass null to disable this default */
maxLength?: number | null;
error?: string;
inputClassName?: string;
inputPrefix?: string;
inputRef?: Ref<HTMLInputElement>;
prefixElement?: ReactNode;
focusProps?: any;
/** TextInput.Sizes.DEFAULT */
size?: string;
} & Omit<HTMLProps<HTMLInputElement>, "onChange" | "maxLength">>> & {
Sizes: Record<"DEFAULT" | "MINI", string>;
};
export type TextArea = ComponentType<Omit<HTMLProps<HTMLTextAreaElement>, "onChange"> & {
onChange(v: string): void;
}>;
interface SelectOption {
disabled?: boolean;
value: any;
label: string;
key?: React.Key;
default?: boolean;
}
export type Select = ComponentType<PropsWithChildren<{
placeholder?: string;
options: ReadonlyArray<SelectOption>; // TODO
/**
* - 0 ~ Filled
* - 1 ~ Custom
*/
look?: 0 | 1;
className?: string;
popoutClassName?: string;
popoutPosition?: PopoutPosition;
optionClassName?: string;
autoFocus?: boolean;
isDisabled?: boolean;
clearable?: boolean;
closeOnSelect?: boolean;
hideIcon?: boolean;
select(value: any): void;
isSelected(value: any): boolean;
serialize(value: any): string;
clear?(): void;
maxVisibleItems?: number;
popoutWidth?: number;
onClose?(): void;
onOpen?(): void;
renderOptionLabel?(option: SelectOption): ReactNode;
/** discord stupid this gets all options instead of one yeah */
renderOptionValue?(option: SelectOption[]): ReactNode;
"aria-label"?: boolean;
"aria-labelledby"?: boolean;
}>>;
export type SearchableSelect = ComponentType<PropsWithChildren<{
placeholder?: string;
options: ReadonlyArray<SelectOption>; // TODO
value?: SelectOption;
/**
* - 0 ~ Filled
* - 1 ~ Custom
*/
look?: 0 | 1;
className?: string;
popoutClassName?: string;
wrapperClassName?: string;
popoutPosition?: PopoutPosition;
optionClassName?: string;
autoFocus?: boolean;
isDisabled?: boolean;
clearable?: boolean;
closeOnSelect?: boolean;
clearOnSelect?: boolean;
multi?: boolean;
onChange(value: any): void;
onSearchChange?(value: string): void;
onClose?(): void;
onOpen?(): void;
onBlur?(): void;
renderOptionPrefix?(option: SelectOption): ReactNode;
renderOptionSuffix?(option: SelectOption): ReactNode;
filter?(option: SelectOption[], query: string): SelectOption[];
centerCaret?: boolean;
debounceTime?: number;
maxVisibleItems?: number;
popoutWidth?: number;
"aria-labelledby"?: boolean;
}>>;
export type Slider = ComponentClass<PropsWithChildren<{
initialValue: number;
defaultValue?: number;
keyboardStep?: number;
maxValue?: number;
minValue?: number;
markers?: number[];
stickToMarkers?: boolean;
/** 0 above, 1 below */
markerPosition?: 0 | 1;
orientation?: "horizontal" | "vertical";
getAriaValueText?(currentValue: number): string;
renderMarker?(marker: number): ReactNode;
onMarkerRender?(marker: number): ReactNode;
onValueRender?(value: number): ReactNode;
onValueChange?(value: number): void;
asValueChanges?(value: number): void;
className?: string;
disabled?: boolean;
handleSize?: number;
mini?: boolean;
hideBubble?: boolean;
fillStyles?: CSSProperties;
barStyles?: CSSProperties;
grabberStyles?: CSSProperties;
grabberClassName?: string;
barClassName?: string;
"aria-hidden"?: boolean;
"aria-label"?: string;
"aria-labelledby"?: string;
"aria-describedby"?: string;
}>>;
// TODO - type maybe idk probably not that useful other than the constants
export type Flex = ComponentType<PropsWithChildren<any>> & {
Align: Record<"START" | "END" | "CENTER" | "STRETCH" | "BASELINE", string>;
Direction: Record<"VERTICAL" | "HORIZONTAL" | "HORIZONTAL_REVERSE", string>;
Justify: Record<"START" | "END" | "CENTER" | "BETWEEN" | "AROUND", string>;
Wrap: Record<"NO_WRAP" | "WRAP" | "WRAP_REVERSE", string>;
};
declare enum PopoutAnimation {
NONE = "1",
TRANSLATE = "2",
SCALE = "3",
FADE = "4"
}
type PopoutPosition = "top" | "bottom" | "left" | "right" | "center" | "window_center";
export type Popout = ComponentType<{
children(
thing: {
"aria-controls": string;
"aria-expanded": boolean;
onClick(event: MouseEvent<HTMLElement>): void;
onKeyDown(event: KeyboardEvent<HTMLElement>): void;
onMouseDown(event: MouseEvent<HTMLElement>): void;
},
data: {
isShown: boolean;
position: PopoutPosition;
}
): ReactNode;
shouldShow?: boolean;
targetElementRef: RefObject<any>;
renderPopout(args: {
closePopout(): void;
isPositioned: boolean;
nudge: number;
position: PopoutPosition;
setPopoutRef(ref: any): void;
updatePosition(): void;
}): ReactNode;
onRequestOpen?(): void;
onRequestClose?(): void;
/** "center" and others */
align?: "left" | "right" | "center";
/** Popout.Animation */
animation?: PopoutAnimation;
autoInvert?: boolean;
nudgeAlignIntoViewport?: boolean;
/** "bottom" and others */
position?: PopoutPosition;
positionKey?: string;
spacing?: number;
}> & {
Animation: typeof PopoutAnimation;
};
export type Dialog = ComponentType<JSX.IntrinsicElements["div"]>;
type Resolve = (data: { theme: "light" | "dark", saturation: number; }) => {
hex(): string;
hsl(): string;
int(): number;
spring(): string;
};
export type useToken = (color: {
css: string;
resolve: Resolve;
}) => ReturnType<Resolve>;
export type Paginator = ComponentType<{
currentPage: number;
maxVisiblePages: number;
pageSize: number;
totalCount: number;
onPageChange?(page: number): void;
hideMaxPage?: boolean;
}>;
export type MaskedLink = ComponentType<PropsWithChildren<{
href: string;
rel?: string;
target?: string;
title?: string,
className?: string;
tabIndex?: number;
onClick?(): void;
trusted?: boolean;
messageId?: string;
channelId?: string;
}>>;
export type ScrollerThin = ComponentType<PropsWithChildren<{
className?: string;
style?: CSSProperties;
dir?: "ltr";
orientation?: "horizontal" | "vertical" | "auto";
paddingFix?: boolean;
fade?: boolean;
onClose?(): void;
onScroll?(): void;
}>>;
export type Clickable = <T extends "a" | "div" | "span" | "li" = "div">(props: PropsWithChildren<ComponentPropsWithRef<T>> & {
tag?: T;
}) => ReactNode;
export type Avatar = ComponentType<PropsWithChildren<{
className?: string;
src?: string;
size?: "SIZE_16" | "SIZE_20" | "SIZE_24" | "SIZE_32" | "SIZE_40" | "SIZE_48" | "SIZE_56" | "SIZE_80" | "SIZE_120";
statusColor?: string;
statusTooltip?: string;
statusBackdropColor?: string;
isMobile?: boolean;
isTyping?: boolean;
isSpeaking?: boolean;
typingIndicatorRef?: unknown;
"aria-hidden"?: boolean;
"aria-label"?: string;
}>>;
type FocusLock = ComponentType<PropsWithChildren<{
containerRef: Ref<HTMLElement>;
}>>;
export type Icon = ComponentType<JSX.IntrinsicElements["svg"] & {
size?: string;
colorClass?: string;
} & Record<string, any>>;
export type ColorPicker = ComponentType<{
color: number | null;
showEyeDropper?: boolean;
suggestedColors?: string[];
label?: ReactNode;
onChange(value: number | null): void;
}>;

File diff suppressed because one or more lines are too long

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/>.
*/
export * from "./classes";
export * from "./components";
export * from "./fluxEvents";
export * from "./menu";
export * from "./stores";
export * from "./utils";

View file

@ -1,96 +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 type { ComponentType, CSSProperties, MouseEvent, PropsWithChildren, ReactNode, UIEvent } from "react";
type RC<C> = ComponentType<PropsWithChildren<C & Record<string, any>>>;
export interface Menu {
Menu: RC<{
navId: string;
onClose(): void;
className?: string;
style?: CSSProperties;
hideScroller?: boolean;
onSelect?(): void;
}>;
MenuSeparator: ComponentType;
MenuGroup: RC<{
label?: string;
}>;
MenuItem: RC<{
id: string;
label: ReactNode;
action?(e: MouseEvent): void;
icon?: ComponentType<any>;
color?: string;
render?: ComponentType<any>;
onChildrenScroll?: Function;
childRowHeight?: number;
listClassName?: string;
disabled?: boolean;
}>;
MenuCheckboxItem: RC<{
id: string;
label: string;
checked: boolean;
action?(e: MouseEvent): void;
disabled?: boolean;
}>;
MenuRadioItem: RC<{
id: string;
group: string;
label: string;
checked: boolean;
action?(e: MouseEvent): void;
disabled?: boolean;
}>;
MenuControlItem: RC<{
id: string;
interactive?: boolean;
}>;
MenuSliderControl: RC<{
minValue: number,
maxValue: number,
value: number,
onChange(value: number): void,
renderValue?(value: number): string,
}>;
MenuSearchControl: RC<{
query: string
onChange(query: string): void;
placeholder?: string;
}>;
}
export interface ContextMenuApi {
closeContextMenu(): void;
openContextMenu(
event: UIEvent,
render?: Menu["Menu"],
options?: { enableSpellCheck?: boolean; },
renderLazy?: () => Promise<Menu["Menu"]>
): void;
openContextMenuLazy(
event: UIEvent,
renderLazy?: () => Promise<Menu["Menu"]>,
options?: { enableSpellCheck?: boolean; }
): void;
}

View file

@ -1,259 +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 { Channel, Guild, Role } from "discord-types/general";
import { FluxDispatcher, FluxEvents } from "./utils";
type GenericFunction = (...args: any[]) => any;
export class FluxStore {
constructor(dispatcher: FluxDispatcher, eventHandlers?: Partial<Record<FluxEvents, (data: any) => void>>);
addChangeListener(callback: () => void): void;
addReactChangeListener(callback: () => void): void;
removeChangeListener(callback: () => void): void;
removeReactChangeListener(callback: () => void): void;
emitChange(): void;
getDispatchToken(): string;
getName(): string;
initialize(): void;
initializeIfNeeded(): void;
registerActionHandlers: GenericFunction;
syncWith: GenericFunction;
waitFor: GenericFunction;
__getLocalVars(): Record<string, any>;
static getAll(): FluxStore[];
}
export class FluxEmitter {
constructor();
changeSentinel: number;
changedStores: Set<FluxStore>;
isBatchEmitting: boolean;
isDispatching: boolean;
isPaused: boolean;
pauseTimer: NodeJS.Timeout | null;
reactChangedStores: Set<FluxStore>;
batched(batch: (...args: any[]) => void): void;
destroy(): void;
emit(): void;
emitNonReactOnce(): void;
emitReactOnce(): void;
getChangeSentinel(): number;
getIsPaused(): boolean;
injectBatchEmitChanges(batch: (...args: any[]) => void): void;
markChanged(store: FluxStore): void;
pause(): void;
resume(): void;
}
export interface Flux {
Store: typeof FluxStore;
Emitter: FluxEmitter;
}
export class WindowStore extends FluxStore {
isElementFullScreen(): boolean;
isFocused(): boolean;
windowSize(): Record<"width" | "height", number>;
}
type Emoji = CustomEmoji | UnicodeEmoji;
export interface CustomEmoji {
allNamesString: string;
animated: boolean;
available: boolean;
guildId: string;
id: string;
managed: boolean;
name: string;
originalName?: string;
require_colons: boolean;
roles: string[];
type: 1;
}
export interface UnicodeEmoji {
diversityChildren: Record<any, any>;
emojiObject: {
names: string[];
surrogates: string;
unicodeVersion: number;
};
index: number;
surrogates: string;
type: 0;
uniqueName: string;
useSpriteSheet: boolean;
get allNamesString(): string;
get animated(): boolean;
get defaultDiversityChild(): any;
get hasDiversity(): boolean | undefined;
get hasDiversityParent(): boolean | undefined;
get hasMultiDiversity(): boolean | undefined;
get hasMultiDiversityParent(): boolean | undefined;
get managed(): boolean;
get name(): string;
get names(): string[];
get optionallyDiverseSequence(): string | undefined;
get unicodeVersion(): number;
get url(): string;
}
export class EmojiStore extends FluxStore {
getCustomEmojiById(id?: string | null): CustomEmoji;
getUsableCustomEmojiById(id?: string | null): CustomEmoji;
getGuilds(): Record<string, {
id: string;
_emojiMap: Record<string, CustomEmoji>;
_emojis: CustomEmoji[];
get emojis(): CustomEmoji[];
get rawEmojis(): CustomEmoji[];
_usableEmojis: CustomEmoji[];
get usableEmojis(): CustomEmoji[];
_emoticons: any[];
get emoticons(): any[];
}>;
getGuildEmoji(guildId?: string | null): CustomEmoji[];
getNewlyAddedEmoji(guildId?: string | null): CustomEmoji[];
getTopEmoji(guildId?: string | null): CustomEmoji[];
getTopEmojisMetadata(guildId?: string | null): {
emojiIds: string[];
topEmojisTTL: number;
};
hasPendingUsage(): boolean;
hasUsableEmojiInAnyGuild(): boolean;
searchWithoutFetchingLatest(data: any): any;
getSearchResultsOrder(...args: any[]): any;
getState(): {
pendingUsages: { key: string, timestamp: number; }[];
};
searchWithoutFetchingLatest(data: {
channel: Channel,
query: string;
count?: number;
intention: number;
includeExternalGuilds?: boolean;
matchComparator?(name: string): boolean;
}): Record<"locked" | "unlocked", Emoji[]>;
getDisambiguatedEmojiContext(): {
backfillTopEmojis: Record<any, any>;
customEmojis: Record<string, CustomEmoji>;
emojisById: Record<string, CustomEmoji>;
emojisByName: Record<string, CustomEmoji>;
emoticonRegex: RegExp | null;
emoticonsByName: Record<string, any>;
escapedEmoticonNames: string;
favoriteNamesAndIds?: any;
favorites?: any;
frequentlyUsed?: any;
groupedCustomEmojis: Record<string, CustomEmoji[]>;
guildId?: string;
isFavoriteEmojiWithoutFetchingLatest(e: Emoji): boolean;
newlyAddedEmoji: Record<string, CustomEmoji[]>;
topEmojis?: any;
unicodeAliases: Record<string, string>;
get favoriteEmojisWithoutFetchingLatest(): Emoji[];
};
}
export interface DraftObject {
channelId: string;
timestamp: number;
draft: string;
}
interface DraftState {
[userId: string]: {
[channelId: string]: {
[key in DraftType]?: Omit<DraftObject, "channelId">;
} | undefined;
} | undefined;
}
export class DraftStore extends FluxStore {
getDraft(channelId: string, type: DraftType): string;
getRecentlyEditedDrafts(type: DraftType): DraftObject[];
getState(): DraftState;
getThreadDraftWithParentMessageId?(arg: any): any;
getThreadSettings(channelId: string): any | null;
}
export enum DraftType {
ChannelMessage,
ThreadSettings,
FirstThreadMessage,
ApplicationLauncherCommand,
Poll,
SlashCommand,
}
export class GuildStore extends FluxStore {
getGuild(guildId: string): Guild;
getGuildCount(): number;
getGuilds(): Record<string, Guild>;
getGuildIds(): string[];
}
export class GuildRoleStore extends FluxStore {
getRole(guildId: string, roleId: string): Role;
getRoles(guildId: string): Record<string, Role>;
getAllGuildRoles(): Record<string, Record<string, Role>>;
}
export class ThemeStore extends FluxStore {
theme: "light" | "dark" | "darker" | "midnight";
darkSidebar: boolean;
isSystemThemeAvailable: boolean;
systemPrefersColorScheme: "light" | "dark";
systemTheme: null;
}
export type useStateFromStores = <T>(
stores: any[],
mapper: () => T,
dependencies?: any,
isEqual?: (old: T, newer: T) => boolean
) => T;
export class RelationshipStore extends FluxStore {
getFriendIDs(): string[];
getIgnoredIDs(): string[];
getBlockedIDs(): string[];
getPendingCount(): number;
getRelationshipCount(): number;
/** Related to friend nicknames. */
getNickname(userId: string): string;
/** @returns Enum value from constants.RelationshipTypes */
getRelationshipType(userId: string): number;
isFriend(userId: string): boolean;
isBlocked(userId: string): boolean;
isIgnored(userId: string): boolean;
getSince(userId: string): string;
/** @returns Format: [userId: Enum value from constants.RelationshipTypes] */
getMutableRelationships(): Map<string, number>;
}

Some files were not shown because too many files have changed in this diff Show more