Compare commits
37 commits
27ab83c179
...
93d1bb5c9f
Author | SHA1 | Date | |
---|---|---|---|
93d1bb5c9f | |||
|
93f98cee2c | ||
|
dcb31ca849 | ||
|
dcd4531327 | ||
|
188fd48659 | ||
|
1126dc6e66 | ||
|
f075fed236 | ||
|
cef806a243 | ||
|
95bd8c831c | ||
|
8ca91354ac | ||
|
b980320d0a | ||
|
d563b66842 | ||
|
d62be1b94a | ||
8085325814 | |||
|
b3bff83dd5 | ||
|
7eec2e5d5b | ||
|
d178dcc480 | ||
|
16910c95ad | ||
|
94ee0c518a | ||
|
c4fc9ac8e0 | ||
|
48868f01fe | ||
|
dcb7a593e5 | ||
|
6f5fd5d0b6 | ||
92406bd718 | |||
|
4391fcc21b | ||
|
c5300713b2 | ||
|
5eb4435463 | ||
|
c32680100e | ||
|
678da62723 | ||
|
721aca6e1a | ||
|
0f384419d5 | ||
|
11715da9e0 | ||
|
3de661585c | ||
|
e88af36be9 | ||
|
8f65d3cae9 | ||
|
aab09ac249 | ||
|
ff82532a18 |
44 changed files with 939 additions and 741 deletions
34
package.json
34
package.json
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "vencord",
|
"name": "vencord",
|
||||||
"private": "true",
|
"private": "true",
|
||||||
"version": "1.11.5",
|
"version": "1.11.7",
|
||||||
"description": "The cutest Discord client mod",
|
"description": "The cutest Discord client mod",
|
||||||
"homepage": "https://github.com/Vendicated/Vencord#readme",
|
"homepage": "https://github.com/Vendicated/Vencord#readme",
|
||||||
"bugs": {
|
"bugs": {
|
||||||
|
@ -25,8 +25,8 @@
|
||||||
"watchWeb": "pnpm buildWeb --watch",
|
"watchWeb": "pnpm buildWeb --watch",
|
||||||
"generatePluginJson": "tsx scripts/generatePluginList.ts",
|
"generatePluginJson": "tsx scripts/generatePluginList.ts",
|
||||||
"generateTypes": "tspc --emitDeclarationOnly --declaration --outDir packages/vencord-types --allowJs false",
|
"generateTypes": "tspc --emitDeclarationOnly --declaration --outDir packages/vencord-types --allowJs false",
|
||||||
"inject": "node scripts/runInstaller.mjs",
|
"inject": "node scripts/runInstaller.mjs -- --install",
|
||||||
"uninject": "node scripts/runInstaller.mjs",
|
"uninject": "node scripts/runInstaller.mjs -- --uninstall",
|
||||||
"lint": "eslint",
|
"lint": "eslint",
|
||||||
"lint-styles": "stylelint \"src/**/*.css\" --ignore-pattern src/userplugins",
|
"lint-styles": "stylelint \"src/**/*.css\" --ignore-pattern src/userplugins",
|
||||||
"lint:fix": "pnpm lint --fix",
|
"lint:fix": "pnpm lint --fix",
|
||||||
|
@ -41,22 +41,22 @@
|
||||||
"fflate": "^0.8.2",
|
"fflate": "^0.8.2",
|
||||||
"gifenc": "github:mattdesl/gifenc#64842fca317b112a8590f8fef2bf3825da8f6fe3",
|
"gifenc": "github:mattdesl/gifenc#64842fca317b112a8590f8fef2bf3825da8f6fe3",
|
||||||
"monaco-editor": "^0.52.2",
|
"monaco-editor": "^0.52.2",
|
||||||
"nanoid": "^5.0.9",
|
"nanoid": "^5.1.5",
|
||||||
"virtual-merge": "^1.0.1"
|
"virtual-merge": "^1.0.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@stylistic/eslint-plugin": "^4.0.0",
|
"@stylistic/eslint-plugin": "^4.2.0",
|
||||||
"@types/chrome": "^0.0.304",
|
"@types/chrome": "^0.0.312",
|
||||||
"@types/diff": "^7.0.1",
|
"@types/diff": "^7.0.2",
|
||||||
"@types/lodash": "^4.17.14",
|
"@types/lodash": "^4.17.14",
|
||||||
"@types/node": "^22.10.5",
|
"@types/node": "^22.13.13",
|
||||||
"@types/react": "^19.0.10",
|
"@types/react": "^19.0.10",
|
||||||
"@types/react-dom": "^19.0.4",
|
"@types/react-dom": "^19.0.4",
|
||||||
"@types/yazl": "^2.4.5",
|
"@types/yazl": "^2.4.5",
|
||||||
"diff": "^7.0.0",
|
"diff": "^7.0.0",
|
||||||
"discord-types": "^1.3.26",
|
"discord-types": "^1.3.26",
|
||||||
"esbuild": "^0.25.0",
|
"esbuild": "^0.25.1",
|
||||||
"eslint": "^9.20.1",
|
"eslint": "9.20.1",
|
||||||
"eslint-import-resolver-alias": "^1.1.2",
|
"eslint-import-resolver-alias": "^1.1.2",
|
||||||
"eslint-plugin-path-alias": "2.1.0",
|
"eslint-plugin-path-alias": "2.1.0",
|
||||||
"eslint-plugin-react": "^7.37.3",
|
"eslint-plugin-react": "^7.37.3",
|
||||||
|
@ -66,17 +66,17 @@
|
||||||
"highlight.js": "11.11.1",
|
"highlight.js": "11.11.1",
|
||||||
"html-minifier-terser": "^7.2.0",
|
"html-minifier-terser": "^7.2.0",
|
||||||
"moment": "^2.22.2",
|
"moment": "^2.22.2",
|
||||||
"puppeteer-core": "^24.2.1",
|
"puppeteer-core": "^24.4.0",
|
||||||
"standalone-electron-types": "^34.2.0",
|
"standalone-electron-types": "^34.2.0",
|
||||||
"stylelint": "^16.12.0",
|
"stylelint": "^16.17.0",
|
||||||
"stylelint-config-standard": "^37.0.0",
|
"stylelint-config-standard": "^37.0.0",
|
||||||
"ts-patch": "^3.3.0",
|
"ts-patch": "^3.3.0",
|
||||||
"ts-pattern": "^5.6.0",
|
"ts-pattern": "^5.6.0",
|
||||||
"tsx": "^4.19.2",
|
"tsx": "^4.19.3",
|
||||||
"type-fest": "^4.31.0",
|
"type-fest": "^4.38.0",
|
||||||
"typescript": "^5.7.2",
|
"typescript": "^5.8.2",
|
||||||
"typescript-eslint": "^8.19.0",
|
"typescript-eslint": "^8.28.0",
|
||||||
"typescript-transform-paths": "^3.5.3",
|
"typescript-transform-paths": "^3.5.5",
|
||||||
"zip-local": "^0.3.5"
|
"zip-local": "^0.3.5"
|
||||||
},
|
},
|
||||||
"packageManager": "pnpm@10.4.1",
|
"packageManager": "pnpm@10.4.1",
|
||||||
|
|
1172
pnpm-lock.yaml
generated
1172
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load diff
|
@ -118,8 +118,11 @@ const installerBin = await ensureBinary();
|
||||||
|
|
||||||
console.log("Now running Installer...");
|
console.log("Now running Installer...");
|
||||||
|
|
||||||
|
const argStart = process.argv.indexOf("--");
|
||||||
|
const args = argStart === -1 ? [] : process.argv.slice(argStart + 1);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
execFileSync(installerBin, {
|
execFileSync(installerBin, args, {
|
||||||
stdio: "inherit",
|
stdio: "inherit",
|
||||||
env: {
|
env: {
|
||||||
...process.env,
|
...process.env,
|
||||||
|
|
|
@ -31,6 +31,7 @@ export const commands = {} as Record<string, Command>;
|
||||||
// hack for plugins being evaluated before we can grab these from webpack
|
// hack for plugins being evaluated before we can grab these from webpack
|
||||||
const OptPlaceholder = Symbol("OptionalMessageOption") as any as Option;
|
const OptPlaceholder = Symbol("OptionalMessageOption") as any as Option;
|
||||||
const ReqPlaceholder = Symbol("RequiredMessageOption") as any as Option;
|
const ReqPlaceholder = Symbol("RequiredMessageOption") as any as Option;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Optional message option named "message" you can use in commands.
|
* Optional message option named "message" you can use in commands.
|
||||||
* Used in "tableflip" or "shrug"
|
* Used in "tableflip" or "shrug"
|
||||||
|
@ -44,11 +45,16 @@ export let OptionalMessageOption: Option = OptPlaceholder;
|
||||||
*/
|
*/
|
||||||
export let RequiredMessageOption: Option = ReqPlaceholder;
|
export let RequiredMessageOption: Option = 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: Command[]) {
|
||||||
try {
|
try {
|
||||||
BUILT_IN = cmds;
|
BUILT_IN = cmds;
|
||||||
OptionalMessageOption = cmds.find(c => (c.untranslatedName || c.displayName) === "shrug")!.options![0];
|
OptionalMessageOption = cmds.find(c => (c.untranslatedName || c.displayName) === "shrug")!.options![0];
|
||||||
RequiredMessageOption = cmds.find(c => (c.untranslatedName || c.displayName) === "me")!.options![0];
|
RequiredMessageOption = cmds.find(c => (c.untranslatedName || c.displayName) === "me")!.options![0];
|
||||||
|
commandIdOffset = Math.abs(BUILT_IN.map(x => Number(x.id)).sort((x, y) => x - y)[0]) - BUILT_IN.length;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
new Logger("CommandsAPI").error("Failed to load CommandsApi", e, " - cmds is", cmds);
|
new Logger("CommandsAPI").error("Failed to load CommandsApi", e, " - cmds is", cmds);
|
||||||
}
|
}
|
||||||
|
@ -142,7 +148,7 @@ export function registerCommand<C extends Command>(command: C, plugin: string) {
|
||||||
command.isVencordCommand = true;
|
command.isVencordCommand = true;
|
||||||
command.untranslatedName ??= command.name;
|
command.untranslatedName ??= command.name;
|
||||||
command.untranslatedDescription ??= command.description;
|
command.untranslatedDescription ??= command.description;
|
||||||
command.id ??= `-${BUILT_IN.length + 1}`;
|
command.id ??= `-${BUILT_IN.length + commandIdOffset + 1}`;
|
||||||
command.applicationId ??= "-1"; // BUILT_IN;
|
command.applicationId ??= "-1"; // BUILT_IN;
|
||||||
command.type ??= ApplicationCommandType.CHAT_INPUT;
|
command.type ??= ApplicationCommandType.CHAT_INPUT;
|
||||||
command.inputType ??= ApplicationCommandInputType.BUILT_IN_TEXT;
|
command.inputType ??= ApplicationCommandInputType.BUILT_IN_TEXT;
|
||||||
|
|
|
@ -51,6 +51,7 @@ export function SettingTextComponent({ option, pluginSettings, definedSettings,
|
||||||
onChange={handleChange}
|
onChange={handleChange}
|
||||||
placeholder={option.placeholder ?? "Enter a value"}
|
placeholder={option.placeholder ?? "Enter a value"}
|
||||||
disabled={option.disabled?.call(definedSettings) ?? false}
|
disabled={option.disabled?.call(definedSettings) ?? false}
|
||||||
|
maxLength={null}
|
||||||
{...option.componentProps}
|
{...option.componentProps}
|
||||||
/>
|
/>
|
||||||
{error && <Forms.FormText style={{ color: "var(--text-danger)" }}>{error}</Forms.FormText>}
|
{error && <Forms.FormText style={{ color: "var(--text-danger)" }}>{error}</Forms.FormText>}
|
||||||
|
|
|
@ -115,7 +115,7 @@ function VencordSettings() {
|
||||||
<SpecialCard
|
<SpecialCard
|
||||||
title="Donations"
|
title="Donations"
|
||||||
subtitle="Thank you for donating!"
|
subtitle="Thank you for donating!"
|
||||||
description="All Vencord users can see your badge! You can change it at any time by messaging @vending.machine."
|
description="You can manage your perks at any time by messaging @vending.machine."
|
||||||
cardImage={VENNIE_DONATOR_IMAGE}
|
cardImage={VENNIE_DONATOR_IMAGE}
|
||||||
backgroundImage={DONOR_BACKGROUND_IMAGE}
|
backgroundImage={DONOR_BACKGROUND_IMAGE}
|
||||||
backgroundColor="#ED87A9"
|
backgroundColor="#ED87A9"
|
||||||
|
|
|
@ -11,6 +11,11 @@
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.visual-refresh .vc-addon-card {
|
||||||
|
background-color: var(--card-primary-bg);
|
||||||
|
border: 1px solid var(--border-subtle);
|
||||||
|
}
|
||||||
|
|
||||||
.vc-addon-card-disabled {
|
.vc-addon-card-disabled {
|
||||||
opacity: 0.6;
|
opacity: 0.6;
|
||||||
}
|
}
|
||||||
|
@ -21,6 +26,11 @@
|
||||||
box-shadow: var(--elevation-high);
|
box-shadow: var(--elevation-high);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.visual-refresh .vc-addon-card:hover {
|
||||||
|
/* same as non-hover, here to overwrite the non-refresh hover background */
|
||||||
|
background-color: var(--card-primary-bg);
|
||||||
|
}
|
||||||
|
|
||||||
.vc-addon-header {
|
.vc-addon-header {
|
||||||
margin-top: auto;
|
margin-top: auto;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
|
@ -36,6 +36,14 @@
|
||||||
outline-offset: 2px;
|
outline-offset: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.visual-refresh .vc-settings-quickActions-pill {
|
||||||
|
background: var(--button-secondary-background);
|
||||||
|
}
|
||||||
|
|
||||||
|
.visual-refresh .vc-settings-quickActions-pill:hover {
|
||||||
|
background: var(--button-secondary-background-hover);
|
||||||
|
}
|
||||||
|
|
||||||
.vc-settings-quickActions-img {
|
.vc-settings-quickActions-img {
|
||||||
width: 24px;
|
width: 24px;
|
||||||
height: 24px;
|
height: 24px;
|
||||||
|
|
|
@ -101,7 +101,7 @@ if (IS_VESKTOP || !IS_VANILLA) {
|
||||||
// TODO: Restrict this to only imported packages with fixed version.
|
// TODO: Restrict this to only imported packages with fixed version.
|
||||||
// Perhaps auto generate with esbuild
|
// Perhaps auto generate with esbuild
|
||||||
csp["script-src"] ??= [];
|
csp["script-src"] ??= [];
|
||||||
csp["script-src"].push("'unsafe-eval'", "https://unpkg.com", "https://cdnjs.cloudflare.com");
|
csp["script-src"].push("'unsafe-eval'", "https://cdn.jsdelivr.net", "https://cdnjs.cloudflare.com");
|
||||||
headers[header] = [stringifyPolicy(csp)];
|
headers[header] = [stringifyPolicy(csp)];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -65,15 +65,15 @@ export default definePlugin({
|
||||||
{
|
{
|
||||||
find: ".FULL_SIZE]:26",
|
find: ".FULL_SIZE]:26",
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /(?<=(\i)=\(0,\i\.\i\)\(\i\);)return 0===\i.length\?/,
|
match: /(?=;return 0===(\i)\.length\?)(?<=(\i)\.useMemo.+?)/,
|
||||||
replace: "$1.unshift(...$self.getBadges(arguments[0].displayProfile));$&"
|
replace: ";$1=$2.useMemo(()=>[...$self.getBadges(arguments[0].displayProfile),...$1],[$1])"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
find: ".description,delay:",
|
find: "#{intl::PROFILE_USER_BADGES}",
|
||||||
replacement: [
|
replacement: [
|
||||||
{
|
{
|
||||||
match: /(alt:" ","aria-hidden":!0,src:)(.{0,20}(\i)\.icon\))/,
|
match: /(alt:" ","aria-hidden":!0,src:)(.+?)(?=,)(?<=href:(\i)\.link.+?)/,
|
||||||
replace: (_, rest, originalSrc, badge) => `...${badge}.props,${rest}${badge}.image??(${originalSrc})`
|
replace: (_, rest, originalSrc, badge) => `...${badge}.props,${rest}${badge}.image??(${originalSrc})`
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -17,7 +17,7 @@ export default definePlugin({
|
||||||
find: '"sticker")',
|
find: '"sticker")',
|
||||||
replacement: {
|
replacement: {
|
||||||
// FIXME(Bundler change related): Remove old compatiblity once enough time has passed
|
// FIXME(Bundler change related): Remove old compatiblity once enough time has passed
|
||||||
match: /return\((!)?\i\.\i(?:\|\||&&)(?=\(\i\.isDM.+?(\i)\.push)/,
|
match: /return\((!)?\i\.\i(?:\|\||&&)(?=\(.+?(\i)\.push)/,
|
||||||
replace: (m, not, children) => not
|
replace: (m, not, children) => not
|
||||||
? `${m}(Vencord.Api.ChatButtons._injectButtons(${children},arguments[0]),true)&&`
|
? `${m}(Vencord.Api.ChatButtons._injectButtons(${children},arguments[0]),true)&&`
|
||||||
: `${m}(Vencord.Api.ChatButtons._injectButtons(${children},arguments[0]),false)||`
|
: `${m}(Vencord.Api.ChatButtons._injectButtons(${children},arguments[0]),false)||`
|
||||||
|
|
|
@ -14,11 +14,18 @@ export default definePlugin({
|
||||||
description: "Allows you to omit either width or height when opening an image modal",
|
description: "Allows you to omit either width or height when opening an image modal",
|
||||||
patches: [
|
patches: [
|
||||||
{
|
{
|
||||||
find: "SCALE_DOWN:",
|
find: ".contain,SCALE_DOWN:",
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /(?<="IMAGE"===\i\?)\i(?=\?)/,
|
match: /(?<="IMAGE"===\i\?)\i(?=\?)/,
|
||||||
replace: "true"
|
replace: "true"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
find: ".dimensionlessImage,",
|
||||||
|
replacement: {
|
||||||
|
match: /(?<="IMAGE"===\i&&\(\i=)\i(?=\?)/,
|
||||||
|
replace: "true"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
|
@ -32,7 +32,7 @@ export default definePlugin({
|
||||||
{
|
{
|
||||||
find: '"Message Username"',
|
find: '"Message Username"',
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /#{intl::GUILD_COMMUNICATION_DISABLED_BOTTOM_SHEET_TITLE}.+?}\),\i(?=\])/,
|
match: /#{intl::GUILD_COMMUNICATION_DISABLED_BOTTOM_SHEET_TITLE}.+?renderPopout:.+?(?=\])/,
|
||||||
replace: "$&,Vencord.Api.MessageDecorations.__addDecorationsToMessage(arguments[0])"
|
replace: "$&,Vencord.Api.MessageDecorations.__addDecorationsToMessage(arguments[0])"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ import ErrorBoundary from "@components/ErrorBoundary";
|
||||||
import { Flex } from "@components/Flex";
|
import { Flex } from "@components/Flex";
|
||||||
import { Link } from "@components/Link";
|
import { Link } from "@components/Link";
|
||||||
import { openUpdaterModal } from "@components/VencordSettings/UpdaterTab";
|
import { openUpdaterModal } from "@components/VencordSettings/UpdaterTab";
|
||||||
import { CONTRIB_ROLE_ID, Devs, DONOR_ROLE_ID, KNOWN_ISSUES_CHANNEL_ID, REGULAR_ROLE_ID, SUPPORT_CHANNEL_ID, VENBOT_USER_ID, VENCORD_GUILD_ID } from "@utils/constants";
|
import { CONTRIB_ROLE_ID, Devs, DONOR_ROLE_ID, KNOWN_ISSUES_CHANNEL_ID, REGULAR_ROLE_ID, SUPPORT_CATEGORY_ID, SUPPORT_CHANNEL_ID, VENBOT_USER_ID, VENCORD_GUILD_ID } from "@utils/constants";
|
||||||
import { sendMessage } from "@utils/discord";
|
import { sendMessage } from "@utils/discord";
|
||||||
import { Logger } from "@utils/Logger";
|
import { Logger } from "@utils/Logger";
|
||||||
import { Margins } from "@utils/margins";
|
import { Margins } from "@utils/margins";
|
||||||
|
@ -32,7 +32,8 @@ import { onlyOnce } from "@utils/onlyOnce";
|
||||||
import { makeCodeblock } from "@utils/text";
|
import { makeCodeblock } from "@utils/text";
|
||||||
import definePlugin from "@utils/types";
|
import definePlugin from "@utils/types";
|
||||||
import { checkForUpdates, isOutdated, update } from "@utils/updater";
|
import { checkForUpdates, isOutdated, update } from "@utils/updater";
|
||||||
import { Alerts, Button, Card, ChannelStore, Forms, GuildMemberStore, Parser, RelationshipStore, showToast, Text, Toasts, UserStore } from "@webpack/common";
|
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 { JSX } from "react";
|
||||||
|
|
||||||
import gitHash from "~git-hash";
|
import gitHash from "~git-hash";
|
||||||
|
@ -42,10 +43,8 @@ import SettingsPlugin from "./settings";
|
||||||
|
|
||||||
const CodeBlockRe = /```js\n(.+?)```/s;
|
const CodeBlockRe = /```js\n(.+?)```/s;
|
||||||
|
|
||||||
const AllowedChannelIds = [
|
const AdditionalAllowedChannelIds = [
|
||||||
SUPPORT_CHANNEL_ID,
|
|
||||||
"1024286218801926184", // Vencord > #bot-spam
|
"1024286218801926184", // Vencord > #bot-spam
|
||||||
"1033680203433660458", // Vencord > #v
|
|
||||||
];
|
];
|
||||||
|
|
||||||
const TrustedRolesIds = [
|
const TrustedRolesIds = [
|
||||||
|
@ -58,6 +57,8 @@ const AsyncFunction = async function () { }.constructor;
|
||||||
|
|
||||||
const ShowCurrentGame = getUserSettingLazy<boolean>("status", "showCurrentGame")!;
|
const ShowCurrentGame = getUserSettingLazy<boolean>("status", "showCurrentGame")!;
|
||||||
|
|
||||||
|
const isSupportAllowedChannel = (channel: Channel) => channel.parent_id === SUPPORT_CATEGORY_ID || AdditionalAllowedChannelIds.includes(channel.id);
|
||||||
|
|
||||||
async function forceUpdate() {
|
async function forceUpdate() {
|
||||||
const outdated = await checkForUpdates();
|
const outdated = await checkForUpdates();
|
||||||
if (outdated) {
|
if (outdated) {
|
||||||
|
@ -155,20 +156,21 @@ export default definePlugin({
|
||||||
{
|
{
|
||||||
name: "vencord-debug",
|
name: "vencord-debug",
|
||||||
description: "Send Vencord debug info",
|
description: "Send Vencord debug info",
|
||||||
predicate: ctx => isPluginDev(UserStore.getCurrentUser()?.id) || AllowedChannelIds.includes(ctx.channel.id),
|
predicate: ctx => isPluginDev(UserStore.getCurrentUser()?.id) || isSupportAllowedChannel(ctx.channel),
|
||||||
execute: async () => ({ content: await generateDebugInfoMessage() })
|
execute: async () => ({ content: await generateDebugInfoMessage() })
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "vencord-plugins",
|
name: "vencord-plugins",
|
||||||
description: "Send Vencord plugin list",
|
description: "Send Vencord plugin list",
|
||||||
predicate: ctx => isPluginDev(UserStore.getCurrentUser()?.id) || AllowedChannelIds.includes(ctx.channel.id),
|
predicate: ctx => isPluginDev(UserStore.getCurrentUser()?.id) || isSupportAllowedChannel(ctx.channel),
|
||||||
execute: () => ({ content: generatePluginList() })
|
execute: () => ({ content: generatePluginList() })
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
||||||
flux: {
|
flux: {
|
||||||
async CHANNEL_SELECT({ channelId }) {
|
async CHANNEL_SELECT({ channelId }) {
|
||||||
if (channelId !== SUPPORT_CHANNEL_ID) return;
|
const isSupportChannel = channelId === SUPPORT_CHANNEL_ID || ChannelStore.getChannel(channelId)?.parent_id === SUPPORT_CATEGORY_ID;
|
||||||
|
if (!isSupportChannel) return;
|
||||||
|
|
||||||
const selfId = UserStore.getCurrentUser()?.id;
|
const selfId = UserStore.getCurrentUser()?.id;
|
||||||
if (!selfId || isPluginDev(selfId)) return;
|
if (!selfId || isPluginDev(selfId)) return;
|
||||||
|
@ -239,7 +241,7 @@ export default definePlugin({
|
||||||
!IS_UPDATER_DISABLED
|
!IS_UPDATER_DISABLED
|
||||||
&& (
|
&& (
|
||||||
(props.channel.id === KNOWN_ISSUES_CHANNEL_ID) ||
|
(props.channel.id === KNOWN_ISSUES_CHANNEL_ID) ||
|
||||||
(props.channel.id === SUPPORT_CHANNEL_ID && props.message.author.id === VENBOT_USER_ID)
|
(props.channel.parent_id === SUPPORT_CATEGORY_ID && props.message.author.id === VENBOT_USER_ID)
|
||||||
)
|
)
|
||||||
&& props.message.content?.includes("update");
|
&& props.message.content?.includes("update");
|
||||||
|
|
||||||
|
@ -265,7 +267,7 @@ export default definePlugin({
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (props.channel.id === SUPPORT_CHANNEL_ID) {
|
if (props.channel.parent_id === SUPPORT_CATEGORY_ID && PermissionStore.can(PermissionsBits.SEND_MESSAGES, props.channel)) {
|
||||||
if (props.message.content.includes("/vencord-debug") || props.message.content.includes("/vencord-plugins")) {
|
if (props.message.content.includes("/vencord-debug") || props.message.content.includes("/vencord-plugins")) {
|
||||||
buttons.push(
|
buttons.push(
|
||||||
<Button
|
<Button
|
||||||
|
|
|
@ -73,8 +73,8 @@ export default definePlugin({
|
||||||
group: true,
|
group: true,
|
||||||
replacement: [
|
replacement: [
|
||||||
{
|
{
|
||||||
match: /(?<=\.AVATAR_SIZE\);)/,
|
match: /let{speaking:\i/,
|
||||||
replace: "$self.useAccountPanelRef();"
|
replace: "$self.useAccountPanelRef();$&"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
match: /(\.AVATAR,children:.+?renderPopout:(\i)=>){(.+?)}(?=,position)(?<=currentUser:(\i).+?)/,
|
match: /(\.AVATAR,children:.+?renderPopout:(\i)=>){(.+?)}(?=,position)(?<=currentUser:(\i).+?)/,
|
||||||
|
|
|
@ -44,15 +44,15 @@ export default definePlugin({
|
||||||
find: "#{intl::GUILD_OWNER}),children:",
|
find: "#{intl::GUILD_OWNER}),children:",
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /(\.CUSTOM_STATUS.+?animate:)\i/,
|
match: /(\.CUSTOM_STATUS.+?animate:)\i/,
|
||||||
replace: (_, rest) => `${rest}!0`
|
replace: "$1!0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// Guild Banner
|
// Guild Banner
|
||||||
find: ".animatedBannerHoverLayer,onMouseEnter:",
|
find: ".animatedBannerHoverLayer,onMouseEnter:",
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /(?<=guildBanner:\i,animate:)\i(?=}\))/,
|
match: /(\.headerContent.+?guildBanner:\i,animate:)\i/,
|
||||||
replace: "!0"
|
replace: "$1!0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
@ -5,8 +5,11 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { definePluginSettings } from "@api/Settings";
|
import { definePluginSettings } from "@api/Settings";
|
||||||
|
import { ErrorBoundary, Flex } from "@components/index";
|
||||||
import { Devs } from "@utils/constants";
|
import { Devs } from "@utils/constants";
|
||||||
import definePlugin, { OptionType, StartAt } from "@utils/types";
|
import { Margins } from "@utils/margins";
|
||||||
|
import definePlugin, { defineDefault, OptionType, StartAt } from "@utils/types";
|
||||||
|
import { Checkbox, Forms, Text } from "@webpack/common";
|
||||||
|
|
||||||
const Noop = () => { };
|
const Noop = () => { };
|
||||||
const NoopLogger = {
|
const NoopLogger = {
|
||||||
|
@ -24,6 +27,48 @@ const NoopLogger = {
|
||||||
|
|
||||||
const logAllow = new Set();
|
const logAllow = new Set();
|
||||||
|
|
||||||
|
interface AllowLevels {
|
||||||
|
error: boolean;
|
||||||
|
warn: boolean;
|
||||||
|
trace: boolean;
|
||||||
|
log: boolean;
|
||||||
|
info: boolean;
|
||||||
|
debug: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface AllowLevelSettingProps {
|
||||||
|
settingKey: keyof AllowLevels;
|
||||||
|
}
|
||||||
|
|
||||||
|
function AllowLevelSetting({ settingKey }: AllowLevelSettingProps) {
|
||||||
|
const { allowLevel } = settings.use(["allowLevel"]);
|
||||||
|
const value = allowLevel[settingKey];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Checkbox
|
||||||
|
value={value}
|
||||||
|
onChange={(_, newValue) => settings.store.allowLevel[settingKey] = newValue}
|
||||||
|
size={20}
|
||||||
|
>
|
||||||
|
<Text variant="text-sm/normal">{settingKey[0].toUpperCase() + settingKey.slice(1)}</Text>
|
||||||
|
</Checkbox>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const AllowLevelSettings = ErrorBoundary.wrap(() => {
|
||||||
|
return (
|
||||||
|
<Forms.FormSection>
|
||||||
|
<Forms.FormTitle tag="h3">Filter List</Forms.FormTitle>
|
||||||
|
<Forms.FormText className={Margins.bottom8} type={Forms.FormText.Types.DESCRIPTION}>Always allow loggers of these types</Forms.FormText>
|
||||||
|
<Flex flexDirection="row">
|
||||||
|
{Object.keys(settings.store.allowLevel).map(key => (
|
||||||
|
<AllowLevelSetting key={key} settingKey={key as keyof AllowLevels} />
|
||||||
|
))}
|
||||||
|
</Flex>
|
||||||
|
</Forms.FormSection>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
const settings = definePluginSettings({
|
const settings = definePluginSettings({
|
||||||
disableLoggers: {
|
disableLoggers: {
|
||||||
type: OptionType.BOOLEAN,
|
type: OptionType.BOOLEAN,
|
||||||
|
@ -45,6 +90,18 @@ const settings = definePluginSettings({
|
||||||
logAllow.clear();
|
logAllow.clear();
|
||||||
newVal.split(";").map(x => x.trim()).forEach(logAllow.add.bind(logAllow));
|
newVal.split(";").map(x => x.trim()).forEach(logAllow.add.bind(logAllow));
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
allowLevel: {
|
||||||
|
type: OptionType.COMPONENT,
|
||||||
|
component: AllowLevelSettings,
|
||||||
|
default: defineDefault<AllowLevels>({
|
||||||
|
error: true,
|
||||||
|
warn: false,
|
||||||
|
trace: false,
|
||||||
|
log: false,
|
||||||
|
info: false,
|
||||||
|
debug: false
|
||||||
|
})
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -61,8 +118,9 @@ export default definePlugin({
|
||||||
},
|
},
|
||||||
|
|
||||||
NoopLogger: () => NoopLogger,
|
NoopLogger: () => NoopLogger,
|
||||||
shouldLog(logger: string) {
|
|
||||||
return logAllow.has(logger);
|
shouldLog(logger: string, level: keyof AllowLevels) {
|
||||||
|
return logAllow.has(logger) || settings.store.allowLevel[level] === true;
|
||||||
},
|
},
|
||||||
|
|
||||||
patches: [
|
patches: [
|
||||||
|
@ -136,13 +194,13 @@ export default definePlugin({
|
||||||
replace: ""
|
replace: ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// Patches discords generic logger function
|
// Patches Discord generic logger function
|
||||||
{
|
{
|
||||||
find: "Σ:",
|
find: "Σ:",
|
||||||
predicate: () => settings.store.disableLoggers,
|
predicate: () => settings.store.disableLoggers,
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /(?<=&&)(?=console)/,
|
match: /(?<=&&)(?=console)/,
|
||||||
replace: "$self.shouldLog(arguments[0])&&"
|
replace: "$self.shouldLog(arguments[0],arguments[1])&&"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
|
@ -99,7 +99,7 @@ export default definePlugin({
|
||||||
},
|
},
|
||||||
// Current user area, at bottom of channels/dm list
|
// Current user area, at bottom of channels/dm list
|
||||||
{
|
{
|
||||||
find: "renderAvatarWithPopout(){",
|
find: "#{intl::ACCOUNT_SPEAKING_WHILE_MUTED}",
|
||||||
replacement: [
|
replacement: [
|
||||||
// Use Decor avatar decoration hook
|
// Use Decor avatar decoration hook
|
||||||
{
|
{
|
||||||
|
|
|
@ -25,11 +25,14 @@ import { ModalContent, ModalHeader, ModalRoot, openModalLazy } from "@utils/moda
|
||||||
import definePlugin from "@utils/types";
|
import definePlugin from "@utils/types";
|
||||||
import { findByCodeLazy, findStoreLazy } from "@webpack";
|
import { findByCodeLazy, findStoreLazy } from "@webpack";
|
||||||
import { Constants, EmojiStore, FluxDispatcher, Forms, GuildStore, Menu, PermissionsBits, PermissionStore, React, RestAPI, Toasts, Tooltip, UserStore } from "@webpack/common";
|
import { Constants, EmojiStore, FluxDispatcher, Forms, GuildStore, Menu, PermissionsBits, PermissionStore, React, RestAPI, Toasts, Tooltip, UserStore } from "@webpack/common";
|
||||||
|
import { Guild } from "discord-types/general";
|
||||||
import { Promisable } from "type-fest";
|
import { Promisable } from "type-fest";
|
||||||
|
|
||||||
const StickersStore = findStoreLazy("StickersStore");
|
const StickersStore = findStoreLazy("StickersStore");
|
||||||
const uploadEmoji = findByCodeLazy(".GUILD_EMOJIS(", "EMOJI_UPLOAD_START");
|
const uploadEmoji = findByCodeLazy(".GUILD_EMOJIS(", "EMOJI_UPLOAD_START");
|
||||||
|
|
||||||
|
const getGuildMaxEmojiSlots = findByCodeLazy(".additionalEmojiSlots") as (guild: Guild) => number;
|
||||||
|
|
||||||
interface Sticker {
|
interface Sticker {
|
||||||
t: "Sticker";
|
t: "Sticker";
|
||||||
description: string;
|
description: string;
|
||||||
|
@ -125,7 +128,7 @@ function getGuildCandidates(data: Data) {
|
||||||
|
|
||||||
const { isAnimated } = data as Emoji;
|
const { isAnimated } = data as Emoji;
|
||||||
|
|
||||||
const emojiSlots = g.getMaxEmojiSlots();
|
const emojiSlots = getGuildMaxEmojiSlots(g);
|
||||||
const { emojis } = EmojiStore.getGuilds()[g.id];
|
const { emojis } = EmojiStore.getGuilds()[g.id];
|
||||||
|
|
||||||
let count = 0;
|
let count = 0;
|
||||||
|
|
|
@ -95,7 +95,7 @@ export default definePlugin({
|
||||||
{
|
{
|
||||||
find: "#{intl::ACCOUNT_SPEAKING_WHILE_MUTED}",
|
find: "#{intl::ACCOUNT_SPEAKING_WHILE_MUTED}",
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /this\.renderNameZone\(\).+?children:\[/,
|
match: /className:\i\.buttons,.{0,50}children:\[/,
|
||||||
replace: "$&$self.GameActivityToggleButton(),"
|
replace: "$&$self.GameActivityToggleButton(),"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -260,14 +260,7 @@ export default definePlugin({
|
||||||
replace: (m, props, nowPlaying) => `${m}$self.renderToggleGameActivityButton(${props},${nowPlaying}),`
|
replace: (m, props, nowPlaying) => `${m}$self.renderToggleGameActivityButton(${props},${nowPlaying}),`
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// Discord has 2 different components for activities. Currently, the last is the one being used
|
// Activities from the apps launcher in the bottom right of the chat bar
|
||||||
{
|
|
||||||
find: ".activityTitleText,variant",
|
|
||||||
replacement: {
|
|
||||||
match: /\.activityTitleText.+?children:(\i)\.name.*?}\),/,
|
|
||||||
replace: (m, props) => `${m}$self.renderToggleActivityButton(${props}),`
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
find: ".promotedLabelWrapperNonBanner,children",
|
find: ".promotedLabelWrapperNonBanner,children",
|
||||||
replacement: {
|
replacement: {
|
||||||
|
|
|
@ -165,8 +165,35 @@ export default definePlugin({
|
||||||
{
|
{
|
||||||
find: ".contain,SCALE_DOWN:",
|
find: ".contain,SCALE_DOWN:",
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /\.slide,\i\),/g,
|
match: /imageClassName:/,
|
||||||
replace: `$&id:"${ELEMENT_ID}",`
|
replace: `id:"${ELEMENT_ID}",$&`
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
find: ".dimensionlessImage,",
|
||||||
|
replacement: [
|
||||||
|
{
|
||||||
|
match: /className:\i\.media,/,
|
||||||
|
replace: `id:"${ELEMENT_ID}",$&`
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// This patch needs to be above the next one as it uses the zoomed class as an anchor
|
||||||
|
match: /\.zoomed]:.+?,(?=children:)/,
|
||||||
|
replace: "$&onClick:()=>{},"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
match: /className:\i\(\)\(\i\.wrapper,.+?}\),/,
|
||||||
|
replace: ""
|
||||||
|
},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
// Make media viewer options not hide when zoomed in with the default Discord feature
|
||||||
|
{
|
||||||
|
find: '="FOCUS_SENSITIVE",',
|
||||||
|
replacement: {
|
||||||
|
match: /(?<=\.hidden]:)\i/,
|
||||||
|
replace: "false"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -149,6 +149,12 @@ export default definePlugin({
|
||||||
|
|
||||||
renderChatBarButton: ChatBarIcon,
|
renderChatBarButton: ChatBarIcon,
|
||||||
|
|
||||||
|
colorCodeFromNumber(color: number): string {
|
||||||
|
return `#${[color >> 16, color >> 8, color]
|
||||||
|
.map(x => (x & 0xFF).toString(16))
|
||||||
|
.join("")}`;
|
||||||
|
},
|
||||||
|
|
||||||
// Gets the Embed of a Link
|
// Gets the Embed of a Link
|
||||||
async getEmbed(url: URL): Promise<Object | {}> {
|
async getEmbed(url: URL): Promise<Object | {}> {
|
||||||
const { body } = await RestAPI.post({
|
const { body } = await RestAPI.post({
|
||||||
|
@ -157,6 +163,8 @@ export default definePlugin({
|
||||||
urls: [url]
|
urls: [url]
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
// The endpoint returns the color as a number, but Discord expects a string
|
||||||
|
body.embeds[0].color = this.colorCodeFromNumber(body.embeds[0].color);
|
||||||
return await body.embeds[0];
|
return await body.embeds[0];
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -166,7 +174,7 @@ export default definePlugin({
|
||||||
message.embeds.push({
|
message.embeds.push({
|
||||||
type: "rich",
|
type: "rich",
|
||||||
rawTitle: "Decrypted Message",
|
rawTitle: "Decrypted Message",
|
||||||
color: "0x45f5f5",
|
color: "#45f5f5",
|
||||||
rawDescription: revealed,
|
rawDescription: revealed,
|
||||||
footer: {
|
footer: {
|
||||||
text: "Made with ❤️ by c0dine and Sammy!",
|
text: "Made with ❤️ by c0dine and Sammy!",
|
||||||
|
|
|
@ -73,17 +73,21 @@ export default definePlugin({
|
||||||
{
|
{
|
||||||
find: "#{intl::GUILD_OWNER}),children:",
|
find: "#{intl::GUILD_OWNER}),children:",
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /(?<=\.MEMBER_LIST}\),\[\]\),)(.+?color:)null!=.{0,50}?(?=,)/,
|
match: /(typingIndicatorRef:.+?},)(\i=.+?)color:null!=.{0,50}?(?=,)/,
|
||||||
replace: (_, rest) => `ircColor=$self.calculateNameColorForListContext(arguments[0]),${rest}ircColor`
|
replace: (_, rest1, rest2) => `${rest1}ircColor=$self.calculateNameColorForListContext(arguments[0]),${rest2}color:ircColor`
|
||||||
},
|
},
|
||||||
predicate: () => settings.store.memberListColors
|
predicate: () => settings.store.memberListColors
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
||||||
calculateNameColorForMessageContext(context: any) {
|
calculateNameColorForMessageContext(context: any) {
|
||||||
const id = context?.message?.author?.id;
|
const userId: string | undefined = context?.message?.author?.id;
|
||||||
const colorString = context?.author?.colorString;
|
const colorString = context?.author?.colorString;
|
||||||
const color = calculateNameColorForUser(id);
|
const color = calculateNameColorForUser(userId);
|
||||||
|
|
||||||
|
// Color preview in role settings
|
||||||
|
if (context?.message?.channel_id === "1337" && userId === "313337")
|
||||||
|
return colorString;
|
||||||
|
|
||||||
if (settings.store.applyColorOnlyInDms && !context?.channel?.isPrivate()) {
|
if (settings.store.applyColorOnlyInDms && !context?.channel?.isPrivate()) {
|
||||||
return colorString;
|
return colorString;
|
||||||
|
|
|
@ -63,11 +63,11 @@ export default definePlugin({
|
||||||
|
|
||||||
stringDelta(delta: number, showMillis: boolean) {
|
stringDelta(delta: number, showMillis: boolean) {
|
||||||
const diff: Diff = {
|
const diff: Diff = {
|
||||||
days: Math.round(delta / (60 * 60 * 24 * 1000)),
|
days: Math.floor(delta / (60 * 60 * 24 * 1000)),
|
||||||
hours: Math.round((delta / (60 * 60 * 1000)) % 24),
|
hours: Math.floor((delta / (60 * 60 * 1000)) % 24),
|
||||||
minutes: Math.round((delta / (60 * 1000)) % 60),
|
minutes: Math.floor((delta / (60 * 1000)) % 60),
|
||||||
seconds: Math.round(delta / 1000 % 60),
|
seconds: Math.floor(delta / 1000 % 60),
|
||||||
milliseconds: Math.round(delta % 1000)
|
milliseconds: Math.floor(delta % 1000)
|
||||||
};
|
};
|
||||||
|
|
||||||
const str = (k: DiffKey) => diff[k] > 0 ? `${diff[k]} ${diff[k] > 1 ? k : k.substring(0, k.length - 1)}` : null;
|
const str = (k: DiffKey) => diff[k] > 0 ? `${diff[k]} ${diff[k] > 1 ? k : k.substring(0, k.length - 1)}` : null;
|
||||||
|
|
|
@ -57,10 +57,10 @@ export default definePlugin({
|
||||||
|
|
||||||
patches: [
|
patches: [
|
||||||
{
|
{
|
||||||
find: "#{intl::BLOCKED_MESSAGES_HIDE}",
|
find: ".__invalid_blocked,",
|
||||||
replacement: [
|
replacement: [
|
||||||
{
|
{
|
||||||
match: /let\{[^}]*collapsedReason[^}]*\}/,
|
match: /let{expanded:\i,[^}]*?collapsedReason[^}]*}/,
|
||||||
replace: "if($self.shouldHide(arguments[0]))return null;$&"
|
replace: "if($self.shouldHide(arguments[0]))return null;$&"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Vencord, a modification for Discord's desktop app
|
* Vencord, a modification for Discord's desktop app
|
||||||
* Copyright (c) 2022 Vendicated and contributors
|
* Copyright (c) 2025 Vendicated and contributors
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -26,10 +26,16 @@ export default definePlugin({
|
||||||
patches: [
|
patches: [
|
||||||
{
|
{
|
||||||
find: ".nsfwAllowed=null",
|
find: ".nsfwAllowed=null",
|
||||||
replacement: {
|
replacement: [
|
||||||
match: /(?<=\.nsfwAllowed=)null!==.+?(?=[,;])/,
|
{
|
||||||
replace: "!0",
|
match: /(?<=\.nsfwAllowed=)null!==.+?(?=[,;])/,
|
||||||
},
|
replace: "true",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
match: /(?<=\.ageVerificationStatus=)null!==.+?(?=[,;])/,
|
||||||
|
replace: "3", // VERIFIED_ADULT
|
||||||
|
}
|
||||||
|
],
|
||||||
|
}
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
|
@ -25,9 +25,19 @@ export default definePlugin({
|
||||||
authors: [Devs.botato],
|
authors: [Devs.botato],
|
||||||
patches: [{
|
patches: [{
|
||||||
find: ".expandedFolderIconWrapper",
|
find: ".expandedFolderIconWrapper",
|
||||||
replacement: [{
|
replacement: [
|
||||||
match: /\(\w\|\|\w\)&&(\(.{0,40}\(.{1,3}\.animated)/,
|
// there are two elements, the first one is the plain folder icon
|
||||||
replace: "$1",
|
// the second is the four guild preview icons
|
||||||
}]
|
// always show this one (the plain icons)
|
||||||
|
{
|
||||||
|
match: /\(\i\|\|\i\)&&(\(.{0,40}\(\i\.animated)/,
|
||||||
|
replace: "$1",
|
||||||
|
},
|
||||||
|
// and never show this one (the guild preview icons)
|
||||||
|
{
|
||||||
|
match: /\(\i\|\|!\i\)&&(\(.{0,40}\(\i\.animated)/,
|
||||||
|
replace: "false&&$1",
|
||||||
|
}
|
||||||
|
]
|
||||||
}]
|
}]
|
||||||
});
|
});
|
||||||
|
|
|
@ -96,6 +96,6 @@
|
||||||
|
|
||||||
.vc-shiki-root .vc-shiki-table-cell:last-child {
|
.vc-shiki-root .vc-shiki-table-cell:last-child {
|
||||||
padding-left: 8px;
|
padding-left: 8px;
|
||||||
overflow-wrap: break-word;
|
overflow-wrap: anywhere;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,8 +50,8 @@ export default definePlugin({
|
||||||
{
|
{
|
||||||
find: '?"@":""',
|
find: '?"@":""',
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /(?<=onContextMenu:\i,children:).*?\)}/,
|
match: /(?<=children:)\(\i\?"@":""\)\+\i(?=,|\})/,
|
||||||
replace: "$self.renderUsername(arguments[0])}"
|
replace: "$self.renderUsername(arguments[0])"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import "./spotifyStyles.css";
|
import "./spotifyStyles.css";
|
||||||
|
import "./visualRefreshSpotifyStyles.css"; // TODO: merge with spotifyStyles.css and remove when old UI is discontinued
|
||||||
|
|
||||||
import { Settings } from "@api/Settings";
|
import { Settings } from "@api/Settings";
|
||||||
import { classNameFactory } from "@api/Styles";
|
import { classNameFactory } from "@api/Styles";
|
||||||
|
@ -307,8 +308,8 @@ function Info({ track }: { track: Track; }) {
|
||||||
{track.name}
|
{track.name}
|
||||||
</Forms.FormText>
|
</Forms.FormText>
|
||||||
{track.artists.some(a => a.name) && (
|
{track.artists.some(a => a.name) && (
|
||||||
<Forms.FormText variant="text-sm/normal" className={cl("ellipoverflow")}>
|
<Forms.FormText variant="text-sm/normal" className={cl(["ellipoverflow", "secondary-song-info"])}>
|
||||||
by
|
<span className={cl("song-info-prefix")}>by </span>
|
||||||
{track.artists.map((a, i) => (
|
{track.artists.map((a, i) => (
|
||||||
<React.Fragment key={a.name}>
|
<React.Fragment key={a.name}>
|
||||||
<span
|
<span
|
||||||
|
@ -325,8 +326,8 @@ function Info({ track }: { track: Track; }) {
|
||||||
</Forms.FormText>
|
</Forms.FormText>
|
||||||
)}
|
)}
|
||||||
{track.album.name && (
|
{track.album.name && (
|
||||||
<Forms.FormText variant="text-sm/normal" className={cl("ellipoverflow")}>
|
<Forms.FormText variant="text-sm/normal" className={cl(["ellipoverflow", "secondary-song-info"])}>
|
||||||
on
|
<span className={cl("song-info-prefix")}>on </span>
|
||||||
<span
|
<span
|
||||||
id={cl("album-title")}
|
id={cl("album-title")}
|
||||||
className={cl("album")}
|
className={cl("album")}
|
||||||
|
|
|
@ -32,7 +32,7 @@ function toggleHoverControls(value: boolean) {
|
||||||
export default definePlugin({
|
export default definePlugin({
|
||||||
name: "SpotifyControls",
|
name: "SpotifyControls",
|
||||||
description: "Adds a Spotify player above the account panel",
|
description: "Adds a Spotify player above the account panel",
|
||||||
authors: [Devs.Ven, Devs.afn, Devs.KraXen72, Devs.Av32000],
|
authors: [Devs.Ven, Devs.afn, Devs.KraXen72, Devs.Av32000, Devs.nin0dev],
|
||||||
options: {
|
options: {
|
||||||
hoverControls: {
|
hoverControls: {
|
||||||
description: "Show controls on hover",
|
description: "Show controls on hover",
|
||||||
|
|
|
@ -2,7 +2,9 @@
|
||||||
padding: 0.375rem 0.5rem;
|
padding: 0.375rem 0.5rem;
|
||||||
border-bottom: 1px solid var(--background-modifier-accent);
|
border-bottom: 1px solid var(--background-modifier-accent);
|
||||||
|
|
||||||
--vc-spotify-green: #1db954; /* so custom themes can easily change it */
|
--vc-spotify-green: var(--spotify, #1db954); /* so custom themes can easily change it */
|
||||||
|
--vc-spotify-green-90: color-mix(in hsl, var(--vc-spotify-green), transparent 90%);
|
||||||
|
--vc-spotify-green-80: color-mix(in hsl, var(--vc-spotify-green), transparent 80%);
|
||||||
}
|
}
|
||||||
|
|
||||||
.theme-light #vc-spotify-player {
|
.theme-light #vc-spotify-player {
|
||||||
|
|
77
src/plugins/spotifyControls/visualRefreshSpotifyStyles.css
Normal file
77
src/plugins/spotifyControls/visualRefreshSpotifyStyles.css
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
/* TODO: merge with spotifyStyles.css and remove when old UI is discontinued */
|
||||||
|
.visual-refresh {
|
||||||
|
#vc-spotify-player {
|
||||||
|
padding: 12px;
|
||||||
|
background: var(--bg-overlay-floating, var(--background-base-low, var(--background-secondary-alt)));
|
||||||
|
margin: 0;
|
||||||
|
border-top-left-radius: 10px;
|
||||||
|
border-top-right-radius: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vc-spotify-song-info-prefix {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vc-spotify-artist, .vc-spotify-album {
|
||||||
|
color: var(--header-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.vc-spotify-secondary-song-info {
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#vc-spotify-progress-bar {
|
||||||
|
position: relative;
|
||||||
|
color: var(--text-normal);
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#vc-spotify-progress-bar > [class^="slider"] {
|
||||||
|
flex-grow: 1;
|
||||||
|
width: 100%;
|
||||||
|
padding: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
#vc-spotify-progress-bar > [class^="slider"] [class^="bar"] {
|
||||||
|
height: 3px !important;
|
||||||
|
top: calc(12px - 4px / 2 + var(--bar-offset));
|
||||||
|
}
|
||||||
|
|
||||||
|
#vc-spotify-progress-bar > [class^="slider"] [class^="barFill"] {
|
||||||
|
background-color: var(--interactive-active);
|
||||||
|
}
|
||||||
|
|
||||||
|
#vc-spotify-progress-bar > [class^="slider"]:hover [class^="barFill"] {
|
||||||
|
background-color: var(--vc-spotify-green);
|
||||||
|
}
|
||||||
|
|
||||||
|
#vc-spotify-progress-bar > [class^="slider"] [class^="grabber"] {
|
||||||
|
background-color: var(--interactive-active);
|
||||||
|
width: 16px !important;
|
||||||
|
height: 16px !important;
|
||||||
|
margin-top: calc(17px/-2 + var(--bar-offset)/2);
|
||||||
|
margin-left: -0.5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vc-spotify-progress-time {
|
||||||
|
margin-top: 8px;
|
||||||
|
font-family: var(--font-code);
|
||||||
|
}
|
||||||
|
|
||||||
|
.vc-spotify-button-row {
|
||||||
|
margin-top: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vc-spotify-button {
|
||||||
|
margin: 0 2px;
|
||||||
|
border-radius: var(--radius-sm);
|
||||||
|
}
|
||||||
|
|
||||||
|
.vc-spotify-repeat-context, .vc-spotify-repeat-track, .vc-spotify-shuffle-on {
|
||||||
|
background-color: var(--vc-spotify-green-90);
|
||||||
|
}
|
||||||
|
|
||||||
|
.vc-spotify-repeat-context:hover, .vc-spotify-repeat-track:hover, .vc-spotify-shuffle-on:hover {
|
||||||
|
background-color: var(--vc-spotify-green-80);
|
||||||
|
}
|
||||||
|
}
|
|
@ -54,8 +54,8 @@ export default definePlugin({
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
||||||
getAvatarStyles(src: string) {
|
getAvatarStyles(src: string | null) {
|
||||||
if (src.startsWith("data:")) return {};
|
if (!src || src.startsWith("data:")) return {};
|
||||||
|
|
||||||
return Object.fromEntries(
|
return Object.fromEntries(
|
||||||
[128, 256, 512, 1024, 2048, 4096].map(size => [
|
[128, 256, 512, 1024, 2048, 4096].map(size => [
|
||||||
|
|
|
@ -273,7 +273,7 @@ export default definePlugin({
|
||||||
muteMessage: {
|
muteMessage: {
|
||||||
type: OptionType.STRING,
|
type: OptionType.STRING,
|
||||||
description: "Mute Message (only self for now)",
|
description: "Mute Message (only self for now)",
|
||||||
default: "{{USER}} Muted"
|
default: "{{USER}} muted"
|
||||||
},
|
},
|
||||||
unmuteMessage: {
|
unmuteMessage: {
|
||||||
type: OptionType.STRING,
|
type: OptionType.STRING,
|
||||||
|
|
|
@ -136,7 +136,7 @@ export default definePlugin({
|
||||||
// @ts-expect-error
|
// @ts-expect-error
|
||||||
if (data.sinkId != null && data.sinkId !== data.audioContext.sinkId && "setSinkId" in AudioContext.prototype) {
|
if (data.sinkId != null && data.sinkId !== data.audioContext.sinkId && "setSinkId" in AudioContext.prototype) {
|
||||||
// @ts-expect-error https://developer.mozilla.org/en-US/docs/Web/API/AudioContext/setSinkId
|
// @ts-expect-error https://developer.mozilla.org/en-US/docs/Web/API/AudioContext/setSinkId
|
||||||
data.audioContext.setSinkId(data.sinkId);
|
data.audioContext.setSinkId(data.sinkId === "default" ? "" : data.sinkId);
|
||||||
}
|
}
|
||||||
|
|
||||||
data.gainNode.gain.value = data._mute
|
data.gainNode.gain.value = data._mute
|
||||||
|
|
|
@ -42,13 +42,16 @@ const settings = definePluginSettings({
|
||||||
addBack: {
|
addBack: {
|
||||||
type: OptionType.BOOLEAN,
|
type: OptionType.BOOLEAN,
|
||||||
description: "Add back the Discord context menus for images, links and the chat input bar",
|
description: "Add back the Discord context menus for images, links and the chat input bar",
|
||||||
|
default: false,
|
||||||
|
restartNeeded: true,
|
||||||
// Web slate menu has proper spellcheck suggestions and image context menu is also pretty good,
|
// Web slate menu has proper spellcheck suggestions and image context menu is also pretty good,
|
||||||
// so disable this by default. Vesktop just doesn't, so enable by default
|
// so disable this by default. Vesktop just doesn't, so we force enable it there
|
||||||
default: IS_VESKTOP,
|
hidden: IS_VESKTOP,
|
||||||
restartNeeded: true
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const shouldAddBackMenus = () => IS_VESKTOP || settings.store.addBack;
|
||||||
|
|
||||||
const MEDIA_PROXY_URL = "https://media.discordapp.net";
|
const MEDIA_PROXY_URL = "https://media.discordapp.net";
|
||||||
const CDN_URL = "cdn.discordapp.com";
|
const CDN_URL = "cdn.discordapp.com";
|
||||||
|
|
||||||
|
@ -81,7 +84,7 @@ export default definePlugin({
|
||||||
settings,
|
settings,
|
||||||
|
|
||||||
start() {
|
start() {
|
||||||
if (settings.store.addBack) {
|
if (shouldAddBackMenus()) {
|
||||||
window.removeEventListener("contextmenu", ctxMenuCallbacks.contextMenuCallbackWeb);
|
window.removeEventListener("contextmenu", ctxMenuCallbacks.contextMenuCallbackWeb);
|
||||||
window.addEventListener("contextmenu", ctxMenuCallbacks.contextMenuCallbackNative);
|
window.addEventListener("contextmenu", ctxMenuCallbacks.contextMenuCallbackNative);
|
||||||
this.changedListeners = true;
|
this.changedListeners = true;
|
||||||
|
@ -144,7 +147,7 @@ export default definePlugin({
|
||||||
{
|
{
|
||||||
find: 'navId:"image-context"',
|
find: 'navId:"image-context"',
|
||||||
all: true,
|
all: true,
|
||||||
predicate: () => settings.store.addBack,
|
predicate: shouldAddBackMenus,
|
||||||
replacement: {
|
replacement: {
|
||||||
// return IS_DESKTOP ? React.createElement(Menu, ...)
|
// return IS_DESKTOP ? React.createElement(Menu, ...)
|
||||||
match: /return \i\.\i(?=\?|&&)/,
|
match: /return \i\.\i(?=\?|&&)/,
|
||||||
|
@ -155,7 +158,7 @@ export default definePlugin({
|
||||||
// Add back link context menu
|
// Add back link context menu
|
||||||
{
|
{
|
||||||
find: '"interactionUsernameProfile"',
|
find: '"interactionUsernameProfile"',
|
||||||
predicate: () => settings.store.addBack,
|
predicate: shouldAddBackMenus,
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /if\((?="A"===\i\.tagName&&""!==\i\.textContent)/,
|
match: /if\((?="A"===\i\.tagName&&""!==\i\.textContent)/,
|
||||||
replace: "if(false&&"
|
replace: "if(false&&"
|
||||||
|
@ -165,7 +168,7 @@ export default definePlugin({
|
||||||
// Add back slate / text input context menu
|
// Add back slate / text input context menu
|
||||||
{
|
{
|
||||||
find: 'getElementById("slate-toolbar"',
|
find: 'getElementById("slate-toolbar"',
|
||||||
predicate: () => settings.store.addBack,
|
predicate: shouldAddBackMenus,
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /(?<=handleContextMenu\(\i\)\{.{0,200}isPlatformEmbedded)\)/,
|
match: /(?<=handleContextMenu\(\i\)\{.{0,200}isPlatformEmbedded)\)/,
|
||||||
replace: "||true)"
|
replace: "||true)"
|
||||||
|
@ -173,7 +176,7 @@ export default definePlugin({
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
find: ".SLASH_COMMAND_SUGGESTIONS_TOGGLED,{",
|
find: ".SLASH_COMMAND_SUGGESTIONS_TOGGLED,{",
|
||||||
predicate: () => settings.store.addBack,
|
predicate: shouldAddBackMenus,
|
||||||
replacement: [
|
replacement: [
|
||||||
{
|
{
|
||||||
// if (!IS_DESKTOP) return null;
|
// if (!IS_DESKTOP) return null;
|
||||||
|
@ -189,7 +192,7 @@ export default definePlugin({
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
find: '"add-to-dictionary"',
|
find: '"add-to-dictionary"',
|
||||||
predicate: () => settings.store.addBack,
|
predicate: shouldAddBackMenus,
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /let\{text:\i=""/,
|
match: /let\{text:\i=""/,
|
||||||
replace: "return [null,null];$&"
|
replace: "return [null,null];$&"
|
||||||
|
|
|
@ -23,6 +23,7 @@ export const DONOR_ROLE_ID = "1042507929485586532";
|
||||||
export const CONTRIB_ROLE_ID = "1026534353167208489";
|
export const CONTRIB_ROLE_ID = "1026534353167208489";
|
||||||
export const REGULAR_ROLE_ID = "1026504932959977532";
|
export const REGULAR_ROLE_ID = "1026504932959977532";
|
||||||
export const SUPPORT_CHANNEL_ID = "1026515880080842772";
|
export const SUPPORT_CHANNEL_ID = "1026515880080842772";
|
||||||
|
export const SUPPORT_CATEGORY_ID = "1108135649699180705";
|
||||||
export const KNOWN_ISSUES_CHANNEL_ID = "1222936386626129920";
|
export const KNOWN_ISSUES_CHANNEL_ID = "1222936386626129920";
|
||||||
|
|
||||||
export interface Dev {
|
export interface Dev {
|
||||||
|
|
|
@ -69,8 +69,8 @@ export interface ApngFrameData {
|
||||||
// The below code is only used on the Desktop (electron) build of Vencord.
|
// The below code is only used on the Desktop (electron) build of Vencord.
|
||||||
// Browser (extension) builds do not contain these remote imports.
|
// Browser (extension) builds do not contain these remote imports.
|
||||||
|
|
||||||
export const shikiWorkerSrc = `https://unpkg.com/@vap/shiki-worker@0.0.8/dist/${IS_DEV ? "index.js" : "index.min.js"}`;
|
export const shikiWorkerSrc = `https://cdn.jsdelivr.net/npm/@vap/shiki-worker@0.0.8/dist/${IS_DEV ? "index.js" : "index.min.js"}`;
|
||||||
export const shikiOnigasmSrc = "https://unpkg.com/@vap/shiki@0.10.3/dist/onig.wasm";
|
export const shikiOnigasmSrc = "https://cdn.jsdelivr.net/npm/@vap/shiki@0.10.3/dist/onig.wasm";
|
||||||
|
|
||||||
// @ts-expect-error
|
// @ts-expect-error
|
||||||
export const getStegCloak = /* #__PURE__*/ makeLazy(() => import("https://unpkg.com/stegcloak-dist@1.0.0/index.js"));
|
export const getStegCloak = /* #__PURE__*/ makeLazy(() => import("https://cdn.jsdelivr.net/npm/stegcloak-dist@1.0.0/index.js"));
|
||||||
|
|
|
@ -26,7 +26,7 @@ import { MessageDecorationFactory } from "@api/MessageDecorations";
|
||||||
import { MessageClickListener, MessageEditListener, MessageSendListener } from "@api/MessageEvents";
|
import { MessageClickListener, MessageEditListener, MessageSendListener } from "@api/MessageEvents";
|
||||||
import { MessagePopoverButtonFactory } from "@api/MessagePopover";
|
import { MessagePopoverButtonFactory } from "@api/MessagePopover";
|
||||||
import { FluxEvents } from "@webpack/types";
|
import { FluxEvents } from "@webpack/types";
|
||||||
import { JSX } from "react";
|
import { ReactNode } from "react";
|
||||||
import { Promisable } from "type-fest";
|
import { Promisable } from "type-fest";
|
||||||
|
|
||||||
// exists to export default definePlugin({...})
|
// exists to export default definePlugin({...})
|
||||||
|
@ -202,6 +202,10 @@ export const enum ReporterTestable {
|
||||||
FluxEvents = 1 << 4
|
FluxEvents = 1 << 4
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function defineDefault<T = any>(value: T) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
export const enum OptionType {
|
export const enum OptionType {
|
||||||
STRING,
|
STRING,
|
||||||
NUMBER,
|
NUMBER,
|
||||||
|
@ -334,7 +338,8 @@ export interface IPluginOptionComponentProps {
|
||||||
|
|
||||||
export interface PluginSettingComponentDef {
|
export interface PluginSettingComponentDef {
|
||||||
type: OptionType.COMPONENT;
|
type: OptionType.COMPONENT;
|
||||||
component: (props: IPluginOptionComponentProps) => JSX.Element;
|
component: (props: IPluginOptionComponentProps) => ReactNode | Promise<ReactNode>;
|
||||||
|
default?: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Maps a `PluginSettingDef` to its value type */
|
/** Maps a `PluginSettingDef` to its value type */
|
||||||
|
|
|
@ -38,6 +38,7 @@ export const Forms = {
|
||||||
export const Card = waitForComponent<t.Card>("Card", filters.componentByCode(".editable),", ".outline:"));
|
export const Card = waitForComponent<t.Card>("Card", filters.componentByCode(".editable),", ".outline:"));
|
||||||
export const Button = waitForComponent<t.Button>("Button", filters.componentByCode("#{intl::A11Y_LOADING_STARTED}))),!1"));
|
export const Button = waitForComponent<t.Button>("Button", filters.componentByCode("#{intl::A11Y_LOADING_STARTED}))),!1"));
|
||||||
export const Switch = waitForComponent<t.Switch>("Switch", filters.componentByCode(".labelRow,ref:", ".disabledText"));
|
export const Switch = waitForComponent<t.Switch>("Switch", filters.componentByCode(".labelRow,ref:", ".disabledText"));
|
||||||
|
export const Checkbox = waitForComponent<t.Checkbox>("Checkbox", filters.componentByCode(".checkboxWrapperDisabled:"));
|
||||||
|
|
||||||
const Tooltips = mapMangledModuleLazy(".tooltipTop,bottom:", {
|
const Tooltips = mapMangledModuleLazy(".tooltipTop,bottom:", {
|
||||||
Tooltip: filters.componentByCode("this.renderTooltip()]"),
|
Tooltip: filters.componentByCode("this.renderTooltip()]"),
|
||||||
|
@ -94,7 +95,7 @@ waitFor(m => {
|
||||||
export const MaskedLink = waitForComponent<t.MaskedLink>("MaskedLink", filters.componentByCode("MASKED_LINK)"));
|
export const MaskedLink = waitForComponent<t.MaskedLink>("MaskedLink", filters.componentByCode("MASKED_LINK)"));
|
||||||
export const Timestamp = waitForComponent<t.Timestamp>("Timestamp", filters.componentByCode("#{intl::MESSAGE_EDITED_TIMESTAMP_A11Y_LABEL}"));
|
export const Timestamp = waitForComponent<t.Timestamp>("Timestamp", filters.componentByCode("#{intl::MESSAGE_EDITED_TIMESTAMP_A11Y_LABEL}"));
|
||||||
export const Flex = waitForComponent<t.Flex>("Flex", ["Justify", "Align", "Wrap"]);
|
export const Flex = waitForComponent<t.Flex>("Flex", ["Justify", "Align", "Wrap"]);
|
||||||
export const OAuth2AuthorizeModal = waitForComponent("OAuth2AuthorizeModal", filters.componentByCode(".authorize),children:", ".contentBackground"));
|
export const OAuth2AuthorizeModal = waitForComponent("OAuth2AuthorizeModal", filters.componentByCode(".authorize,children:", ".contentBackground"));
|
||||||
|
|
||||||
export const Animations = mapMangledModuleLazy(".assign({colorNames:", {
|
export const Animations = mapMangledModuleLazy(".assign({colorNames:", {
|
||||||
Transition: filters.componentByCode('["items","children"]', ",null,"),
|
Transition: filters.componentByCode('["items","children"]', ",null,"),
|
||||||
|
|
41
src/webpack/common/types/components.d.ts
vendored
41
src/webpack/common/types/components.d.ts
vendored
|
@ -16,7 +16,7 @@
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type { ComponentPropsWithRef, ComponentType, CSSProperties, FunctionComponent, HtmlHTMLAttributes, HTMLProps, JSX, KeyboardEvent, MouseEvent, PropsWithChildren, PropsWithRef, ReactNode, Ref } from "react";
|
import type { ComponentPropsWithRef, ComponentType, CSSProperties, FunctionComponent, HtmlHTMLAttributes, HTMLProps, JSX, KeyboardEvent, MouseEvent, PointerEvent, PropsWithChildren, ReactNode, Ref } 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 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";
|
||||||
|
@ -197,6 +197,36 @@ export type Switch = ComponentType<PropsWithChildren<{
|
||||||
tooltipNote?: 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<{
|
export type Timestamp = ComponentType<PropsWithChildren<{
|
||||||
timestamp: Date;
|
timestamp: Date;
|
||||||
isEdited?: boolean;
|
isEdited?: boolean;
|
||||||
|
@ -215,7 +245,8 @@ export type TextInput = ComponentType<PropsWithChildren<{
|
||||||
onChange?(value: string, name?: string): void;
|
onChange?(value: string, name?: string): void;
|
||||||
placeholder?: string;
|
placeholder?: string;
|
||||||
editable?: boolean;
|
editable?: boolean;
|
||||||
maxLength?: number;
|
/** defaults to 999. Pass null to disable this default */
|
||||||
|
maxLength?: number | null;
|
||||||
error?: string;
|
error?: string;
|
||||||
|
|
||||||
inputClassName?: string;
|
inputClassName?: string;
|
||||||
|
@ -227,13 +258,13 @@ export type TextInput = ComponentType<PropsWithChildren<{
|
||||||
|
|
||||||
/** TextInput.Sizes.DEFAULT */
|
/** TextInput.Sizes.DEFAULT */
|
||||||
size?: string;
|
size?: string;
|
||||||
} & Omit<HTMLProps<HTMLInputElement>, "onChange">>> & {
|
} & Omit<HTMLProps<HTMLInputElement>, "onChange" | "maxLength">>> & {
|
||||||
Sizes: Record<"DEFAULT" | "MINI", string>;
|
Sizes: Record<"DEFAULT" | "MINI", string>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TextArea = ComponentType<PropsWithRef<Omit<HTMLProps<HTMLTextAreaElement>, "onChange"> & {
|
export type TextArea = ComponentType<Omit<HTMLProps<HTMLTextAreaElement>, "onChange"> & {
|
||||||
onChange(v: string): void;
|
onChange(v: string): void;
|
||||||
}>>;
|
}>;
|
||||||
|
|
||||||
interface SelectOption {
|
interface SelectOption {
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
|
|
|
@ -142,9 +142,12 @@ export const UploadHandler = {
|
||||||
promptToUpload: findByCodeLazy("#{intl::ATTACHMENT_TOO_MANY_ERROR_TITLE}") as (files: File[], channel: Channel, draftType: Number) => void
|
promptToUpload: findByCodeLazy("#{intl::ATTACHMENT_TOO_MANY_ERROR_TITLE}") as (files: File[], channel: Channel, draftType: Number) => void
|
||||||
};
|
};
|
||||||
|
|
||||||
export const ApplicationAssetUtils = findByPropsLazy("fetchAssetIds", "getAssetImage") as {
|
export const ApplicationAssetUtils = mapMangledModuleLazy("getAssetImage: size must === [", {
|
||||||
fetchAssetIds: (applicationId: string, e: string[]) => Promise<string[]>;
|
fetchAssetIds: filters.byCode('.startsWith("http:")', ".dispatch({"),
|
||||||
};
|
getAssetFromImageURL: filters.byCode("].serialize(", ',":"'),
|
||||||
|
getAssetImage: filters.byCode("getAssetImage: size must === ["),
|
||||||
|
getAssets: filters.byCode(".assets")
|
||||||
|
});
|
||||||
|
|
||||||
export const Clipboard: t.Clipboard = mapMangledModuleLazy('queryCommandEnabled("copy")', {
|
export const Clipboard: t.Clipboard = mapMangledModuleLazy('queryCommandEnabled("copy")', {
|
||||||
copy: filters.byCode(".copy("),
|
copy: filters.byCode(".copy("),
|
||||||
|
|
Loading…
Add table
Reference in a new issue