mirror of
https://github.com/Vendicated/Vencord.git
synced 2025-01-09 09:26:22 +00:00
Add React eslint & update depencenies
This commit is contained in:
parent
48a9aef2eb
commit
44c178ddd7
56 changed files with 1776 additions and 1532 deletions
|
@ -4,10 +4,9 @@
|
||||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// @ts-check
|
|
||||||
|
|
||||||
import stylistic from "@stylistic/eslint-plugin";
|
import stylistic from "@stylistic/eslint-plugin";
|
||||||
import pathAlias from "eslint-plugin-path-alias";
|
import pathAlias from "eslint-plugin-path-alias";
|
||||||
|
import react from "eslint-plugin-react";
|
||||||
import header from "eslint-plugin-simple-header";
|
import header from "eslint-plugin-simple-header";
|
||||||
import simpleImportSort from "eslint-plugin-simple-import-sort";
|
import simpleImportSort from "eslint-plugin-simple-import-sort";
|
||||||
import unusedImports from "eslint-plugin-unused-imports";
|
import unusedImports from "eslint-plugin-unused-imports";
|
||||||
|
@ -15,6 +14,22 @@ import tseslint from "typescript-eslint";
|
||||||
|
|
||||||
export default tseslint.config(
|
export default tseslint.config(
|
||||||
{ ignores: ["dist", "browser", "packages/vencord-types"] },
|
{ ignores: ["dist", "browser", "packages/vencord-types"] },
|
||||||
|
{
|
||||||
|
files: ["src/**/*.{tsx,ts,mts,mjs,js,jsx}", "eslint.config.mjs"],
|
||||||
|
settings: {
|
||||||
|
react: {
|
||||||
|
version: "18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
...react.configs.flat.recommended,
|
||||||
|
rules: {
|
||||||
|
...react.configs.flat.recommended.rules,
|
||||||
|
"react/react-in-jsx-scope": "off",
|
||||||
|
"react/prop-types": "off",
|
||||||
|
"react/display-name": "off",
|
||||||
|
"react/no-unescaped-entities": "off",
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
files: ["src/**/*.{tsx,ts,mts,mjs,js,jsx}", "eslint.config.mjs"],
|
files: ["src/**/*.{tsx,ts,mts,mjs,js,jsx}", "eslint.config.mjs"],
|
||||||
plugins: {
|
plugins: {
|
||||||
|
@ -23,7 +38,7 @@ export default tseslint.config(
|
||||||
"@typescript-eslint": tseslint.plugin,
|
"@typescript-eslint": tseslint.plugin,
|
||||||
"simple-import-sort": simpleImportSort,
|
"simple-import-sort": simpleImportSort,
|
||||||
"unused-imports": unusedImports,
|
"unused-imports": unusedImports,
|
||||||
"path-alias": pathAlias,
|
"path-alias": pathAlias
|
||||||
},
|
},
|
||||||
settings: {
|
settings: {
|
||||||
"import/resolver": {
|
"import/resolver": {
|
||||||
|
|
51
package.json
51
package.json
|
@ -41,48 +41,49 @@
|
||||||
"@vap/shiki": "0.10.5",
|
"@vap/shiki": "0.10.5",
|
||||||
"fflate": "^0.8.2",
|
"fflate": "^0.8.2",
|
||||||
"gifenc": "github:mattdesl/gifenc#64842fca317b112a8590f8fef2bf3825da8f6fe3",
|
"gifenc": "github:mattdesl/gifenc#64842fca317b112a8590f8fef2bf3825da8f6fe3",
|
||||||
"monaco-editor": "^0.50.0",
|
"monaco-editor": "^0.52.2",
|
||||||
"nanoid": "^5.0.7",
|
"nanoid": "^5.0.9",
|
||||||
"virtual-merge": "^1.0.1"
|
"virtual-merge": "^1.0.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@stylistic/eslint-plugin": "^2.6.1",
|
"@stylistic/eslint-plugin": "^2.12.1",
|
||||||
"@types/chrome": "^0.0.269",
|
"@types/chrome": "^0.0.287",
|
||||||
"@types/diff": "^5.2.1",
|
"@types/diff": "^6.0.0",
|
||||||
"@types/lodash": "^4.17.7",
|
"@types/lodash": "^4.17.13",
|
||||||
"@types/node": "^22.0.3",
|
"@types/node": "^22.10.2",
|
||||||
"@types/react": "^18.3.3",
|
"@types/react": "^19.0.2",
|
||||||
"@types/react-dom": "^18.3.0",
|
"@types/react-dom": "^19.0.2",
|
||||||
"@types/yazl": "^2.4.5",
|
"@types/yazl": "^2.4.5",
|
||||||
"diff": "^5.2.0",
|
"diff": "^7.0.0",
|
||||||
"discord-types": "^1.3.26",
|
"discord-types": "^1.3.26",
|
||||||
"esbuild": "^0.15.18",
|
"esbuild": "^0.15.18",
|
||||||
"eslint": "^9.8.0",
|
"eslint": "^9.17.0",
|
||||||
"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-simple-header": "^1.1.1",
|
"eslint-plugin-react": "^7.37.2",
|
||||||
|
"eslint-plugin-simple-header": "^1.2.1",
|
||||||
"eslint-plugin-simple-import-sort": "^12.1.1",
|
"eslint-plugin-simple-import-sort": "^12.1.1",
|
||||||
"eslint-plugin-unused-imports": "^4.0.1",
|
"eslint-plugin-unused-imports": "^4.1.4",
|
||||||
"highlight.js": "10.7.3",
|
"highlight.js": "11.7.0",
|
||||||
"html-minifier-terser": "^7.2.0",
|
"html-minifier-terser": "^7.2.0",
|
||||||
"moment": "^2.30.1",
|
"moment": "^2.22.2",
|
||||||
"puppeteer-core": "^22.15.0",
|
"puppeteer-core": "^23.11.1",
|
||||||
"standalone-electron-types": "^1.0.0",
|
"standalone-electron-types": "^1.0.0",
|
||||||
"stylelint": "^16.8.1",
|
"stylelint": "^16.12.0",
|
||||||
"stylelint-config-standard": "^36.0.1",
|
"stylelint-config-standard": "^36.0.1",
|
||||||
"ts-patch": "^3.2.1",
|
"ts-patch": "^3.3.0",
|
||||||
"ts-pattern": "^5.3.1",
|
"ts-pattern": "^5.6.0",
|
||||||
"tsx": "^4.16.5",
|
"tsx": "^4.19.2",
|
||||||
"type-fest": "^4.23.0",
|
"type-fest": "^4.30.2",
|
||||||
"typescript": "^5.5.4",
|
"typescript": "^5.7.2",
|
||||||
"typescript-eslint": "^8.0.0",
|
"typescript-eslint": "^8.18.1",
|
||||||
"typescript-transform-paths": "^3.4.7",
|
"typescript-transform-paths": "^3.5.2",
|
||||||
"zip-local": "^0.3.5"
|
"zip-local": "^0.3.5"
|
||||||
},
|
},
|
||||||
"packageManager": "pnpm@9.1.0",
|
"packageManager": "pnpm@9.1.0",
|
||||||
"pnpm": {
|
"pnpm": {
|
||||||
"patchedDependencies": {
|
"patchedDependencies": {
|
||||||
"eslint@9.8.0": "patches/eslint@9.8.0.patch",
|
"eslint@9.17.0": "patches/eslint@9.17.0.patch",
|
||||||
"eslint-plugin-path-alias@2.1.0": "patches/eslint-plugin-path-alias@2.1.0.patch"
|
"eslint-plugin-path-alias@2.1.0": "patches/eslint-plugin-path-alias@2.1.0.patch"
|
||||||
},
|
},
|
||||||
"peerDependencyRules": {
|
"peerDependencyRules": {
|
||||||
|
|
3018
pnpm-lock.yaml
3018
pnpm-lock.yaml
File diff suppressed because it is too large
Load diff
|
@ -11,7 +11,7 @@ import { Logger } from "@utils/Logger";
|
||||||
import { waitFor } from "@webpack";
|
import { waitFor } from "@webpack";
|
||||||
import { Button, ButtonLooks, ButtonWrapperClasses, Tooltip } from "@webpack/common";
|
import { Button, ButtonLooks, ButtonWrapperClasses, Tooltip } from "@webpack/common";
|
||||||
import { Channel } from "discord-types/general";
|
import { Channel } from "discord-types/general";
|
||||||
import { HTMLProps, MouseEventHandler, ReactNode } from "react";
|
import { HTMLProps, JSX, MouseEventHandler, ReactNode } from "react";
|
||||||
|
|
||||||
let ChannelTextAreaClasses: Record<"button" | "buttonContainer", string>;
|
let ChannelTextAreaClasses: Record<"button" | "buttonContainer", string>;
|
||||||
waitFor(["buttonContainer", "channelTextArea"], m => ChannelTextAreaClasses = m);
|
waitFor(["buttonContainer", "channelTextArea"], m => ChannelTextAreaClasses = m);
|
||||||
|
|
|
@ -24,13 +24,13 @@ import type { ReactElement } from "react";
|
||||||
* @param children The rendered context menu elements
|
* @param children The rendered context menu elements
|
||||||
* @param args Any arguments passed into making the context menu, like the guild, channel, user or message for example
|
* @param args Any arguments passed into making the context menu, like the guild, channel, user or message for example
|
||||||
*/
|
*/
|
||||||
export type NavContextMenuPatchCallback = (children: Array<ReactElement | null>, ...args: Array<any>) => void;
|
export type NavContextMenuPatchCallback = (children: Array<ReactElement<any> | null>, ...args: Array<any>) => void;
|
||||||
/**
|
/**
|
||||||
* @param navId The navId of the context menu being patched
|
* @param navId The navId of the context menu being patched
|
||||||
* @param children The rendered context menu elements
|
* @param children The rendered context menu elements
|
||||||
* @param args Any arguments passed into making the context menu, like the guild, channel, user or message for example
|
* @param args Any arguments passed into making the context menu, like the guild, channel, user or message for example
|
||||||
*/
|
*/
|
||||||
export type GlobalContextMenuPatchCallback = (navId: string, children: Array<ReactElement | null>, ...args: Array<any>) => void;
|
export type GlobalContextMenuPatchCallback = (navId: string, children: Array<ReactElement<any> | null>, ...args: Array<any>) => void;
|
||||||
|
|
||||||
const ContextMenuLogger = new Logger("ContextMenu");
|
const ContextMenuLogger = new Logger("ContextMenu");
|
||||||
|
|
||||||
|
@ -70,7 +70,7 @@ export function addGlobalContextMenuPatch(patch: GlobalContextMenuPatchCallback)
|
||||||
* @returns Whether the patch was successfully removed from the context menu(s)
|
* @returns Whether the patch was successfully removed from the context menu(s)
|
||||||
*/
|
*/
|
||||||
export function removeContextMenuPatch<T extends string | Array<string>>(navId: T, patch: NavContextMenuPatchCallback): T extends string ? boolean : Array<boolean> {
|
export function removeContextMenuPatch<T extends string | Array<string>>(navId: T, patch: NavContextMenuPatchCallback): T extends string ? boolean : Array<boolean> {
|
||||||
const navIds = Array.isArray(navId) ? navId : [navId as string];
|
const navIds: string[] = Array.isArray(navId) ? navId : [navId];
|
||||||
|
|
||||||
const results = navIds.map(id => navPatches.get(id)?.delete(patch) ?? false);
|
const results = navIds.map(id => navPatches.get(id)?.delete(patch) ?? false);
|
||||||
|
|
||||||
|
@ -92,7 +92,7 @@ export function removeGlobalContextMenuPatch(patch: GlobalContextMenuPatchCallba
|
||||||
* @param children The context menu children
|
* @param children The context menu children
|
||||||
* @param matchSubstring Whether to check if the id is a substring of the child id
|
* @param matchSubstring Whether to check if the id is a substring of the child id
|
||||||
*/
|
*/
|
||||||
export function findGroupChildrenByChildId(id: string | string[], children: Array<ReactElement | null | undefined>, matchSubstring = false): Array<ReactElement | null | undefined> | null {
|
export function findGroupChildrenByChildId(id: string | string[], children: Array<ReactElement<any> | null | undefined>, matchSubstring = false): Array<ReactElement<any> | null | undefined> | null {
|
||||||
for (const child of children) {
|
for (const child of children) {
|
||||||
if (child == null) continue;
|
if (child == null) continue;
|
||||||
|
|
||||||
|
@ -124,7 +124,7 @@ export function findGroupChildrenByChildId(id: string | string[], children: Arra
|
||||||
interface ContextMenuProps {
|
interface ContextMenuProps {
|
||||||
contextMenuApiArguments?: Array<any>;
|
contextMenuApiArguments?: Array<any>;
|
||||||
navId: string;
|
navId: string;
|
||||||
children: Array<ReactElement | null>;
|
children: Array<ReactElement<any> | null>;
|
||||||
"aria-label": string;
|
"aria-label": string;
|
||||||
onSelect: (() => void) | undefined;
|
onSelect: (() => void) | undefined;
|
||||||
onClose: (callback: (...args: Array<any>) => any) => void;
|
onClose: (callback: (...args: Array<any>) => any) => void;
|
||||||
|
@ -162,7 +162,7 @@ export function _usePatchContextMenu(props: ContextMenuProps) {
|
||||||
return props;
|
return props;
|
||||||
}
|
}
|
||||||
|
|
||||||
function cloneMenuChildren(obj: ReactElement | Array<ReactElement | null> | null) {
|
function cloneMenuChildren(obj: ReactElement<any> | Array<ReactElement<any> | null> | null) {
|
||||||
if (Array.isArray(obj)) {
|
if (Array.isArray(obj)) {
|
||||||
return obj.map(cloneMenuChildren);
|
return obj.map(cloneMenuChildren);
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Channel, User } from "discord-types/general/index.js";
|
import { Channel, User } from "discord-types/general/index.js";
|
||||||
|
import { JSX } from "react";
|
||||||
|
|
||||||
interface DecoratorProps {
|
interface DecoratorProps {
|
||||||
activities: any[];
|
activities: any[];
|
||||||
|
|
|
@ -16,6 +16,8 @@
|
||||||
* 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 { JSX } from "react";
|
||||||
|
|
||||||
export type AccessoryCallback = (props: Record<string, any>) => JSX.Element | null | Array<JSX.Element | null>;
|
export type AccessoryCallback = (props: Record<string, any>) => JSX.Element | null | Array<JSX.Element | null>;
|
||||||
export type Accessory = {
|
export type Accessory = {
|
||||||
callback: AccessoryCallback;
|
callback: AccessoryCallback;
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Channel, Message } from "discord-types/general/index.js";
|
import { Channel, Message } from "discord-types/general/index.js";
|
||||||
|
import { JSX } from "react";
|
||||||
|
|
||||||
interface DecorationProps {
|
interface DecorationProps {
|
||||||
author: {
|
author: {
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Logger } from "@utils/Logger";
|
import { Logger } from "@utils/Logger";
|
||||||
|
import { JSX } from "react";
|
||||||
|
|
||||||
const logger = new Logger("ServerListAPI");
|
const logger = new Logger("ServerListAPI");
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@ import { Logger } from "@utils/Logger";
|
||||||
import { mergeDefaults } from "@utils/mergeDefaults";
|
import { mergeDefaults } from "@utils/mergeDefaults";
|
||||||
import { putCloudSettings } from "@utils/settingsSync";
|
import { putCloudSettings } from "@utils/settingsSync";
|
||||||
import { DefinedSettings, OptionType, SettingsChecks, SettingsDefinition } from "@utils/types";
|
import { DefinedSettings, OptionType, SettingsChecks, SettingsDefinition } from "@utils/types";
|
||||||
import { React } from "@webpack/common";
|
import { React, useEffect } from "@webpack/common";
|
||||||
|
|
||||||
import plugins from "~plugins";
|
import plugins from "~plugins";
|
||||||
|
|
||||||
|
@ -192,7 +192,7 @@ export const Settings = SettingsStore.store;
|
||||||
export function useSettings(paths?: UseSettings<Settings>[]) {
|
export function useSettings(paths?: UseSettings<Settings>[]) {
|
||||||
const [, forceUpdate] = React.useReducer(() => ({}), {});
|
const [, forceUpdate] = React.useReducer(() => ({}), {});
|
||||||
|
|
||||||
React.useEffect(() => {
|
useEffect(() => {
|
||||||
if (paths) {
|
if (paths) {
|
||||||
paths.forEach(p => SettingsStore.addChangeListener(p, forceUpdate));
|
paths.forEach(p => SettingsStore.addChangeListener(p, forceUpdate));
|
||||||
return () => paths.forEach(p => SettingsStore.removeChangeListener(p, forceUpdate));
|
return () => paths.forEach(p => SettingsStore.removeChangeListener(p, forceUpdate));
|
||||||
|
@ -200,7 +200,7 @@ export function useSettings(paths?: UseSettings<Settings>[]) {
|
||||||
SettingsStore.addGlobalChangeListener(forceUpdate);
|
SettingsStore.addGlobalChangeListener(forceUpdate);
|
||||||
return () => SettingsStore.removeGlobalChangeListener(forceUpdate);
|
return () => SettingsStore.removeGlobalChangeListener(forceUpdate);
|
||||||
}
|
}
|
||||||
}, []);
|
}, [paths]);
|
||||||
|
|
||||||
return SettingsStore.store;
|
return SettingsStore.store;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export function Badge({ text, color }): JSX.Element {
|
export function Badge({ text, color }) {
|
||||||
return (
|
return (
|
||||||
<div className="vc-plugins-badge" style={{
|
<div className="vc-plugins-badge" style={{
|
||||||
backgroundColor: color,
|
backgroundColor: color,
|
||||||
|
|
|
@ -20,6 +20,7 @@ import { Logger } from "@utils/Logger";
|
||||||
import { Margins } from "@utils/margins";
|
import { Margins } from "@utils/margins";
|
||||||
import { LazyComponent } from "@utils/react";
|
import { LazyComponent } from "@utils/react";
|
||||||
import { React } from "@webpack/common";
|
import { React } from "@webpack/common";
|
||||||
|
import { ReactElement } from "react";
|
||||||
|
|
||||||
import { ErrorCard } from "./ErrorCard";
|
import { ErrorCard } from "./ErrorCard";
|
||||||
|
|
||||||
|
@ -80,10 +81,11 @@ const ErrorBoundary = LazyComponent(() => {
|
||||||
if (this.props.noop) return null;
|
if (this.props.noop) return null;
|
||||||
|
|
||||||
if (this.props.fallback)
|
if (this.props.fallback)
|
||||||
return <this.props.fallback
|
return (
|
||||||
children={this.props.children}
|
<this.props.fallback {...this.state}>
|
||||||
{...this.state}
|
{this.props.children}
|
||||||
/>;
|
</this.props.fallback>
|
||||||
|
);
|
||||||
|
|
||||||
const msg = this.props.message || "An error occurred while rendering this Component. More info can be found below and in your console.";
|
const msg = this.props.message || "An error occurred while rendering this Component. More info can be found below and in your console.";
|
||||||
|
|
||||||
|
@ -105,7 +107,7 @@ const ErrorBoundary = LazyComponent(() => {
|
||||||
};
|
};
|
||||||
}) as
|
}) as
|
||||||
React.ComponentType<React.PropsWithChildren<Props>> & {
|
React.ComponentType<React.PropsWithChildren<Props>> & {
|
||||||
wrap<T extends object = any>(Component: React.ComponentType<T>, errorBoundaryProps?: Omit<Props<T>, "wrappedProps">): React.FunctionComponent<T>;
|
wrap<T extends object = any>(Component: React.ComponentType<T>, errorBoundaryProps?: Omit<Props<T>, "wrappedProps">): (props: T) => ReactElement<any>;
|
||||||
};
|
};
|
||||||
|
|
||||||
ErrorBoundary.wrap = (Component, errorBoundaryProps) => props => (
|
ErrorBoundary.wrap = (Component, errorBoundaryProps) => props => (
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { CSSProperties } from "react";
|
import { CSSProperties, JSX } from "react";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
columns: number;
|
columns: number;
|
||||||
|
|
|
@ -27,7 +27,7 @@ export function Heart() {
|
||||||
>
|
>
|
||||||
<path
|
<path
|
||||||
fill="#db61a2"
|
fill="#db61a2"
|
||||||
fill-rule="evenodd"
|
fillRule="evenodd"
|
||||||
d="M4.25 2.5c-1.336 0-2.75 1.164-2.75 3 0 2.15 1.58 4.144 3.365 5.682A20.565 20.565 0 008 13.393a20.561 20.561 0 003.135-2.211C12.92 9.644 14.5 7.65 14.5 5.5c0-1.836-1.414-3-2.75-3-1.373 0-2.609.986-3.029 2.456a.75.75 0 01-1.442 0C6.859 3.486 5.623 2.5 4.25 2.5zM8 14.25l-.345.666-.002-.001-.006-.003-.018-.01a7.643 7.643 0 01-.31-.17 22.075 22.075 0 01-3.434-2.414C2.045 10.731 0 8.35 0 5.5 0 2.836 2.086 1 4.25 1 5.797 1 7.153 1.802 8 3.02 8.847 1.802 10.203 1 11.75 1 13.914 1 16 2.836 16 5.5c0 2.85-2.045 5.231-3.885 6.818a22.08 22.08 0 01-3.744 2.584l-.018.01-.006.003h-.002L8 14.25zm0 0l.345.666a.752.752 0 01-.69 0L8 14.25z"
|
d="M4.25 2.5c-1.336 0-2.75 1.164-2.75 3 0 2.15 1.58 4.144 3.365 5.682A20.565 20.565 0 008 13.393a20.561 20.561 0 003.135-2.211C12.92 9.644 14.5 7.65 14.5 5.5c0-1.836-1.414-3-2.75-3-1.373 0-2.609.986-3.029 2.456a.75.75 0 01-1.442 0C6.859 3.486 5.623 2.5 4.25 2.5zM8 14.25l-.345.666-.002-.001-.006-.003-.018-.01a7.643 7.643 0 01-.31-.17 22.075 22.075 0 01-3.434-2.414C2.045 10.731 0 8.35 0 5.5 0 2.836 2.086 1 4.25 1 5.797 1 7.153 1.802 8 3.02 8.847 1.802 10.203 1 11.75 1 13.914 1 16 2.836 16 5.5c0 2.85-2.045 5.231-3.885 6.818a22.08 22.08 0 01-3.744 2.584l-.018.01-.006.003h-.002L8 14.25zm0 0l.345.666a.752.752 0 01-.69 0L8 14.25z"
|
||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
|
|
|
@ -20,7 +20,7 @@ import "./iconStyles.css";
|
||||||
|
|
||||||
import { getIntlMessage } from "@utils/discord";
|
import { getIntlMessage } from "@utils/discord";
|
||||||
import { classes } from "@utils/misc";
|
import { classes } from "@utils/misc";
|
||||||
import type { PropsWithChildren } from "react";
|
import type { JSX, PropsWithChildren } from "react";
|
||||||
|
|
||||||
interface BaseIconProps extends IconProps {
|
interface BaseIconProps extends IconProps {
|
||||||
viewBox: string;
|
viewBox: string;
|
||||||
|
@ -55,7 +55,7 @@ export function LinkIcon({ height = 24, width = 24, className }: IconProps) {
|
||||||
className={classes(className, "vc-link-icon")}
|
className={classes(className, "vc-link-icon")}
|
||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 24"
|
||||||
>
|
>
|
||||||
<g fill="none" fill-rule="evenodd">
|
<g fill="none" fillRule="evenodd">
|
||||||
<path fill="currentColor" d="M10.59 13.41c.41.39.41 1.03 0 1.42-.39.39-1.03.39-1.42 0a5.003 5.003 0 0 1 0-7.07l3.54-3.54a5.003 5.003 0 0 1 7.07 0 5.003 5.003 0 0 1 0 7.07l-1.49 1.49c.01-.82-.12-1.64-.4-2.42l.47-.48a2.982 2.982 0 0 0 0-4.24 2.982 2.982 0 0 0-4.24 0l-3.53 3.53a2.982 2.982 0 0 0 0 4.24zm2.82-4.24c.39-.39 1.03-.39 1.42 0a5.003 5.003 0 0 1 0 7.07l-3.54 3.54a5.003 5.003 0 0 1-7.07 0 5.003 5.003 0 0 1 0-7.07l1.49-1.49c-.01.82.12 1.64.4 2.43l-.47.47a2.982 2.982 0 0 0 0 4.24 2.982 2.982 0 0 0 4.24 0l3.53-3.53a2.982 2.982 0 0 0 0-4.24.973.973 0 0 1 0-1.42z" />
|
<path fill="currentColor" d="M10.59 13.41c.41.39.41 1.03 0 1.42-.39.39-1.03.39-1.42 0a5.003 5.003 0 0 1 0-7.07l3.54-3.54a5.003 5.003 0 0 1 7.07 0 5.003 5.003 0 0 1 0 7.07l-1.49 1.49c.01-.82-.12-1.64-.4-2.42l.47-.48a2.982 2.982 0 0 0 0-4.24 2.982 2.982 0 0 0-4.24 0l-3.53 3.53a2.982 2.982 0 0 0 0 4.24zm2.82-4.24c.39-.39 1.03-.39 1.42 0a5.003 5.003 0 0 1 0 7.07l-3.54 3.54a5.003 5.003 0 0 1-7.07 0 5.003 5.003 0 0 1 0-7.07l1.49-1.49c-.01.82.12 1.64.4 2.43l-.47.47a2.982 2.982 0 0 0 0 4.24 2.982 2.982 0 0 0 4.24 0l3.53-3.53a2.982 2.982 0 0 0 0-4.24.973.973 0 0 1 0-1.42z" />
|
||||||
<rect width={width} height={height} />
|
<rect width={width} height={height} />
|
||||||
</g>
|
</g>
|
||||||
|
@ -122,8 +122,8 @@ export function InfoIcon(props: IconProps) {
|
||||||
>
|
>
|
||||||
<path
|
<path
|
||||||
fill="currentColor"
|
fill="currentColor"
|
||||||
fill-rule="evenodd"
|
fillRule="evenodd"
|
||||||
d="M23 12a11 11 0 1 1-22 0 11 11 0 0 1 22 0Zm-9.5-4.75a1.25 1.25 0 1 1-2.5 0 1.25 1.25 0 0 1 2.5 0Zm-.77 3.96a1 1 0 1 0-1.96-.42l-1.04 4.86a2.77 2.77 0 0 0 4.31 2.83l.24-.17a1 1 0 1 0-1.16-1.62l-.24.17a.77.77 0 0 1-1.2-.79l1.05-4.86Z" clip-rule="evenodd"
|
d="M23 12a11 11 0 1 1-22 0 11 11 0 0 1 22 0Zm-9.5-4.75a1.25 1.25 0 1 1-2.5 0 1.25 1.25 0 0 1 2.5 0Zm-.77 3.96a1 1 0 1 0-1.96-.42l-1.04 4.86a2.77 2.77 0 0 0 4.31 2.83l.24-.17a1 1 0 1 0-1.16-1.62l-.24.17a.77.77 0 0 1-1.2-.79l1.05-4.86Z" clipRule="evenodd"
|
||||||
/>
|
/>
|
||||||
</Icon>
|
</Icon>
|
||||||
);
|
);
|
||||||
|
@ -212,9 +212,9 @@ export function CogWheel(props: IconProps) {
|
||||||
>
|
>
|
||||||
<path
|
<path
|
||||||
fill="currentColor"
|
fill="currentColor"
|
||||||
fill-rule="evenodd"
|
fillRule="evenodd"
|
||||||
d="M10.56 1.1c-.46.05-.7.53-.64.98.18 1.16-.19 2.2-.98 2.53-.8.33-1.79-.15-2.49-1.1-.27-.36-.78-.52-1.14-.24-.77.59-1.45 1.27-2.04 2.04-.28.36-.12.87.24 1.14.96.7 1.43 1.7 1.1 2.49-.33.8-1.37 1.16-2.53.98-.45-.07-.93.18-.99.64a11.1 11.1 0 0 0 0 2.88c.06.46.54.7.99.64 1.16-.18 2.2.19 2.53.98.33.8-.14 1.79-1.1 2.49-.36.27-.52.78-.24 1.14.59.77 1.27 1.45 2.04 2.04.36.28.87.12 1.14-.24.7-.95 1.7-1.43 2.49-1.1.8.33 1.16 1.37.98 2.53-.07.45.18.93.64.99a11.1 11.1 0 0 0 2.88 0c.46-.06.7-.54.64-.99-.18-1.16.19-2.2.98-2.53.8-.33 1.79.14 2.49 1.1.27.36.78.52 1.14.24.77-.59 1.45-1.27 2.04-2.04.28-.36.12-.87-.24-1.14-.96-.7-1.43-1.7-1.1-2.49.33-.8 1.37-1.16 2.53-.98.45.07.93-.18.99-.64a11.1 11.1 0 0 0 0-2.88c-.06-.46-.54-.7-.99-.64-1.16.18-2.2-.19-2.53-.98-.33-.8.14-1.79 1.1-2.49.36-.27.52-.78.24-1.14a11.07 11.07 0 0 0-2.04-2.04c-.36-.28-.87-.12-1.14.24-.7.96-1.7 1.43-2.49 1.1-.8-.33-1.16-1.37-.98-2.53.07-.45-.18-.93-.64-.99a11.1 11.1 0 0 0-2.88 0ZM16 12a4 4 0 1 1-8 0 4 4 0 0 1 8 0Z"
|
d="M10.56 1.1c-.46.05-.7.53-.64.98.18 1.16-.19 2.2-.98 2.53-.8.33-1.79-.15-2.49-1.1-.27-.36-.78-.52-1.14-.24-.77.59-1.45 1.27-2.04 2.04-.28.36-.12.87.24 1.14.96.7 1.43 1.7 1.1 2.49-.33.8-1.37 1.16-2.53.98-.45-.07-.93.18-.99.64a11.1 11.1 0 0 0 0 2.88c.06.46.54.7.99.64 1.16-.18 2.2.19 2.53.98.33.8-.14 1.79-1.1 2.49-.36.27-.52.78-.24 1.14.59.77 1.27 1.45 2.04 2.04.36.28.87.12 1.14-.24.7-.95 1.7-1.43 2.49-1.1.8.33 1.16 1.37.98 2.53-.07.45.18.93.64.99a11.1 11.1 0 0 0 2.88 0c.46-.06.7-.54.64-.99-.18-1.16.19-2.2.98-2.53.8-.33 1.79.14 2.49 1.1.27.36.78.52 1.14.24.77-.59 1.45-1.27 2.04-2.04.28-.36.12-.87-.24-1.14-.96-.7-1.43-1.7-1.1-2.49.33-.8 1.37-1.16 2.53-.98.45.07.93-.18.99-.64a11.1 11.1 0 0 0 0-2.88c-.06-.46-.54-.7-.99-.64-1.16.18-2.2-.19-2.53-.98-.33-.8.14-1.79 1.1-2.49.36-.27.52-.78.24-1.14a11.07 11.07 0 0 0-2.04-2.04c-.36-.28-.87-.12-1.14.24-.7.96-1.7 1.43-2.49 1.1-.8-.33-1.16-1.37-.98-2.53.07-.45-.18-.93-.64-.99a11.1 11.1 0 0 0-2.88 0ZM16 12a4 4 0 1 1-8 0 4 4 0 0 1 8 0Z"
|
||||||
clip-rule="evenodd"
|
clipRule="evenodd"
|
||||||
/>
|
/>
|
||||||
</Icon>
|
</Icon>
|
||||||
);
|
);
|
||||||
|
@ -262,7 +262,7 @@ export function PlusIcon(props: IconProps) {
|
||||||
viewBox="0 0 18 18"
|
viewBox="0 0 18 18"
|
||||||
>
|
>
|
||||||
<polygon
|
<polygon
|
||||||
fill-rule="nonzero"
|
fillRule="nonzero"
|
||||||
fill="currentColor"
|
fill="currentColor"
|
||||||
points="15 10 10 10 10 15 8 15 8 10 3 10 3 8 8 8 8 3 10 3 10 8 15 8"
|
points="15 10 10 10 10 15 8 15 8 10 3 10 3 8 8 8 8 3 10 3 10 8 15 8"
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -44,7 +44,7 @@ function ContributorModal({ user }: { user: User; }) {
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!profile && !user.bot && user.id)
|
if (!profile && !user.bot && user.id)
|
||||||
fetchUserProfile(user.id);
|
fetchUserProfile(user.id);
|
||||||
}, [user.id]);
|
}, [user.id, user.bot, profile]);
|
||||||
|
|
||||||
const githubName = profile?.connectedAccounts?.find(a => a.type === "github")?.name;
|
const githubName = profile?.connectedAccounts?.find(a => a.type === "github")?.name;
|
||||||
const website = profile?.connectedAccounts?.find(a => a.type === "domain")?.name;
|
const website = profile?.connectedAccounts?.find(a => a.type === "domain")?.name;
|
||||||
|
|
|
@ -109,7 +109,7 @@ export default function PluginModal({ plugin, onRestartNeeded, onClose, transiti
|
||||||
setAuthors(a => [...a, author]);
|
setAuthors(a => [...a, author]);
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
}, []);
|
}, [plugin.authors]);
|
||||||
|
|
||||||
async function saveAndClose() {
|
async function saveAndClose() {
|
||||||
if (!plugin.options) {
|
if (!plugin.options) {
|
||||||
|
|
|
@ -35,6 +35,7 @@ import { useAwaiter } from "@utils/react";
|
||||||
import { Plugin } from "@utils/types";
|
import { Plugin } from "@utils/types";
|
||||||
import { findByPropsLazy } from "@webpack";
|
import { findByPropsLazy } from "@webpack";
|
||||||
import { Alerts, Button, Card, Forms, lodash, Parser, React, Select, Text, TextInput, Toasts, Tooltip, useMemo } from "@webpack/common";
|
import { Alerts, Button, Card, Forms, lodash, Parser, React, Select, Text, TextInput, Toasts, Tooltip, useMemo } from "@webpack/common";
|
||||||
|
import { JSX } from "react";
|
||||||
|
|
||||||
import Plugins, { ExcludedPlugins } from "~plugins";
|
import Plugins, { ExcludedPlugins } from "~plugins";
|
||||||
|
|
||||||
|
@ -387,7 +388,7 @@ function makeDependencyList(deps: string[]) {
|
||||||
return (
|
return (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
<Forms.FormText>This plugin is required by:</Forms.FormText>
|
<Forms.FormText>This plugin is required by:</Forms.FormText>
|
||||||
{deps.map((dep: string) => <Forms.FormText className={cl("dep-text")}>{dep}</Forms.FormText>)}
|
{deps.map((dep: string) => <Forms.FormText key={dep} className={cl("dep-text")}>{dep}</Forms.FormText>)}
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -111,9 +111,9 @@ function ReplacementComponent({ module, match, replacement, setReplacementError
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderDiff() {
|
function renderDiff() {
|
||||||
return diff?.map(p => {
|
return diff?.map((p, idx) => {
|
||||||
const color = p.added ? "lime" : p.removed ? "red" : "grey";
|
const color = p.added ? "lime" : p.removed ? "red" : "grey";
|
||||||
return <div style={{ color, userSelect: "text", wordBreak: "break-all", lineBreak: "anywhere" }}>{p.value}</div>;
|
return <div key={idx} style={{ color, userSelect: "text", wordBreak: "break-all", lineBreak: "anywhere" }}>{p.value}</div>;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -61,7 +61,7 @@ function withDispatcher(dispatcher: React.Dispatch<React.SetStateAction<boolean>
|
||||||
title: "Oops!",
|
title: "Oops!",
|
||||||
body: (
|
body: (
|
||||||
<ErrorCard>
|
<ErrorCard>
|
||||||
{err.split("\n").map(line => <div>{Parser.parse(line)}</div>)}
|
{err.split("\n").map((line, idx) => <div key={idx}>{Parser.parse(line)}</div>)}
|
||||||
</ErrorCard>
|
</ErrorCard>
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
@ -87,7 +87,7 @@ function Changes({ updates, repo, repoPending }: CommonProps & { updates: typeof
|
||||||
return (
|
return (
|
||||||
<Card style={{ padding: "0 0.5em" }}>
|
<Card style={{ padding: "0 0.5em" }}>
|
||||||
{updates.map(({ hash, author, message }) => (
|
{updates.map(({ hash, author, message }) => (
|
||||||
<div style={{
|
<div key={hash} style={{
|
||||||
marginTop: "0.5em",
|
marginTop: "0.5em",
|
||||||
marginBottom: "0.5em"
|
marginBottom: "0.5em"
|
||||||
}}>
|
}}>
|
||||||
|
|
|
@ -34,6 +34,7 @@ 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, RelationshipStore, showToast, Text, Toasts, UserStore } from "@webpack/common";
|
||||||
|
import { JSX } from "react";
|
||||||
|
|
||||||
import gitHash from "~git-hash";
|
import gitHash from "~git-hash";
|
||||||
import plugins, { PluginMeta } from "~plugins";
|
import plugins, { PluginMeta } from "~plugins";
|
||||||
|
|
|
@ -99,7 +99,7 @@ export const UnknownIcon = (props: React.PropsWithChildren<SVGProps<SVGSVGElemen
|
||||||
fill="currentColor"
|
fill="currentColor"
|
||||||
viewBox="0 0 16 16"
|
viewBox="0 0 16 16"
|
||||||
>
|
>
|
||||||
<path fill-rule="evenodd" d="M4.475 5.458c-.284 0-.514-.237-.47-.517C4.28 3.24 5.576 2 7.825 2c2.25 0 3.767 1.36 3.767 3.215 0 1.344-.665 2.288-1.79 2.973-1.1.659-1.414 1.118-1.414 2.01v.03a.5.5 0 0 1-.5.5h-.77a.5.5 0 0 1-.5-.495l-.003-.2c-.043-1.221.477-2.001 1.645-2.712 1.03-.632 1.397-1.135 1.397-2.028 0-.979-.758-1.698-1.926-1.698-1.009 0-1.71.529-1.938 1.402-.066.254-.278.461-.54.461h-.777ZM7.496 14c.622 0 1.095-.474 1.095-1.09 0-.618-.473-1.092-1.095-1.092-.606 0-1.087.474-1.087 1.091S6.89 14 7.496 14Z" />
|
<path fillRule="evenodd" d="M4.475 5.458c-.284 0-.514-.237-.47-.517C4.28 3.24 5.576 2 7.825 2c2.25 0 3.767 1.36 3.767 3.215 0 1.344-.665 2.288-1.79 2.973-1.1.659-1.414 1.118-1.414 2.01v.03a.5.5 0 0 1-.5.5h-.77a.5.5 0 0 1-.5-.495l-.003-.2c-.043-1.221.477-2.001 1.645-2.712 1.03-.632 1.397-1.135 1.397-2.028 0-.979-.758-1.698-1.926-1.698-1.009 0-1.71.529-1.938 1.402-.066.254-.278.461-.54.461h-.777ZM7.496 14c.622 0 1.095-.474 1.095-1.09 0-.618-.473-1.092-1.095-1.092-.606 0-1.087.474-1.087 1.091S6.89 14 7.496 14Z" />
|
||||||
</svg>
|
</svg>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -173,7 +173,7 @@ export default definePlugin({
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
map(render: (item: SettingsEntry) => ReactElement) {
|
map(render: (item: SettingsEntry) => ReactElement<any>) {
|
||||||
return items
|
return items
|
||||||
.filter(a => a.items.length > 0)
|
.filter(a => a.items.length > 0)
|
||||||
.map(({ label, items }) => {
|
.map(({ label, items }) => {
|
||||||
|
@ -181,11 +181,14 @@ export default definePlugin({
|
||||||
if (label) {
|
if (label) {
|
||||||
return (
|
return (
|
||||||
<Menu.MenuItem
|
<Menu.MenuItem
|
||||||
|
key={label}
|
||||||
id={label.replace(/\W/, "_")}
|
id={label.replace(/\W/, "_")}
|
||||||
label={label}
|
label={label}
|
||||||
children={children}
|
|
||||||
action={children[0].props.action}
|
action={children[0].props.action}
|
||||||
/>);
|
>
|
||||||
|
{children}
|
||||||
|
</Menu.MenuItem>
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
return children;
|
return children;
|
||||||
}
|
}
|
||||||
|
|
|
@ -132,7 +132,10 @@ function makeShortcuts() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Common.ReactDOM.render(Common.React.createElement(component, props), doc.body.appendChild(document.createElement("div")));
|
const root = Common.ReactDOM.createRoot(doc.body.appendChild(document.createElement("div")));
|
||||||
|
root.render(Common.React.createElement(component, props));
|
||||||
|
|
||||||
|
doc.addEventListener("close", () => root.unmount(), { once: true });
|
||||||
},
|
},
|
||||||
|
|
||||||
preEnable: (plugin: string) => (Vencord.Settings.plugins[plugin] ??= { enabled: true }).enabled = true,
|
preEnable: (plugin: string) => (Vencord.Settings.plugins[plugin] ??= { enabled: true }).enabled = true,
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { React } from "@webpack/common";
|
import { React } from "@webpack/common";
|
||||||
|
import { JSX } from "react";
|
||||||
|
|
||||||
import { cl } from "../";
|
import { cl } from "../";
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
import { classes } from "@utils/misc";
|
import { classes } from "@utils/misc";
|
||||||
import { findByPropsLazy } from "@webpack";
|
import { findByPropsLazy } from "@webpack";
|
||||||
import { React } from "@webpack/common";
|
import { React } from "@webpack/common";
|
||||||
|
import { JSX } from "react";
|
||||||
|
|
||||||
import { cl } from "../";
|
import { cl } from "../";
|
||||||
import Grid, { GridProps } from "./Grid";
|
import Grid, { GridProps } from "./Grid";
|
||||||
|
|
|
@ -211,7 +211,7 @@ function CloneModal({ data }: { data: Sticker | Emoji; }) {
|
||||||
alignItems: "center"
|
alignItems: "center"
|
||||||
}}>
|
}}>
|
||||||
{guilds.map(g => (
|
{guilds.map(g => (
|
||||||
<Tooltip text={g.name}>
|
<Tooltip key={g.id} text={g.name}>
|
||||||
{({ onMouseLeave, onMouseEnter }) => (
|
{({ onMouseLeave, onMouseEnter }) => (
|
||||||
<div
|
<div
|
||||||
onMouseLeave={onMouseLeave}
|
onMouseLeave={onMouseLeave}
|
||||||
|
|
|
@ -514,7 +514,7 @@ export default definePlugin({
|
||||||
return array.filter(item => item != null);
|
return array.filter(item => item != null);
|
||||||
},
|
},
|
||||||
|
|
||||||
ensureChildrenIsArray(child: ReactElement) {
|
ensureChildrenIsArray(child: ReactElement<any>) {
|
||||||
if (!Array.isArray(child.props.children)) child.props.children = [child.props.children];
|
if (!Array.isArray(child.props.children)) child.props.children = [child.props.children];
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -524,7 +524,7 @@ export default definePlugin({
|
||||||
|
|
||||||
let nextIndex = content.length;
|
let nextIndex = content.length;
|
||||||
|
|
||||||
const transformLinkChild = (child: ReactElement) => {
|
const transformLinkChild = (child: ReactElement<any>) => {
|
||||||
if (settings.store.transformEmojis) {
|
if (settings.store.transformEmojis) {
|
||||||
const fakeNitroMatch = child.props.href.match(fakeNitroEmojiRegex);
|
const fakeNitroMatch = child.props.href.match(fakeNitroEmojiRegex);
|
||||||
if (fakeNitroMatch) {
|
if (fakeNitroMatch) {
|
||||||
|
@ -558,7 +558,7 @@ export default definePlugin({
|
||||||
return child;
|
return child;
|
||||||
};
|
};
|
||||||
|
|
||||||
const transformChild = (child: ReactElement) => {
|
const transformChild = (child: ReactElement<any>) => {
|
||||||
if (child?.props?.trusted != null) return transformLinkChild(child);
|
if (child?.props?.trusted != null) return transformLinkChild(child);
|
||||||
if (child?.props?.children != null) {
|
if (child?.props?.children != null) {
|
||||||
if (!Array.isArray(child.props.children)) {
|
if (!Array.isArray(child.props.children)) {
|
||||||
|
@ -574,7 +574,7 @@ export default definePlugin({
|
||||||
return child;
|
return child;
|
||||||
};
|
};
|
||||||
|
|
||||||
const modifyChild = (child: ReactElement) => {
|
const modifyChild = (child: ReactElement<any>) => {
|
||||||
const newChild = transformChild(child);
|
const newChild = transformChild(child);
|
||||||
|
|
||||||
if (newChild?.type === "ul" || newChild?.type === "ol") {
|
if (newChild?.type === "ul" || newChild?.type === "ol") {
|
||||||
|
@ -601,7 +601,7 @@ export default definePlugin({
|
||||||
return newChild;
|
return newChild;
|
||||||
};
|
};
|
||||||
|
|
||||||
const modifyChildren = (children: Array<ReactElement>) => {
|
const modifyChildren = (children: Array<ReactElement<any>>) => {
|
||||||
for (const [index, child] of children.entries()) children[index] = modifyChild(child);
|
for (const [index, child] of children.entries()) children[index] = modifyChild(child);
|
||||||
|
|
||||||
children = this.clearEmptyArrayItems(children);
|
children = this.clearEmptyArrayItems(children);
|
||||||
|
|
|
@ -29,6 +29,7 @@ import definePlugin, { OptionType } from "@utils/types";
|
||||||
import { extractAndLoadChunksLazy, findComponentByCodeLazy } from "@webpack";
|
import { extractAndLoadChunksLazy, findComponentByCodeLazy } from "@webpack";
|
||||||
import { Button, Flex, Forms, React, Text, UserProfileStore, UserStore, useState } from "@webpack/common";
|
import { Button, Flex, Forms, React, Text, UserProfileStore, UserStore, useState } from "@webpack/common";
|
||||||
import { User } from "discord-types/general";
|
import { User } from "discord-types/general";
|
||||||
|
import { ReactElement } from "react";
|
||||||
import virtualMerge from "virtual-merge";
|
import virtualMerge from "virtual-merge";
|
||||||
|
|
||||||
interface UserProfile extends User {
|
interface UserProfile extends User {
|
||||||
|
@ -87,7 +88,7 @@ const settings = definePluginSettings({
|
||||||
|
|
||||||
interface ColorPickerProps {
|
interface ColorPickerProps {
|
||||||
color: number | null;
|
color: number | null;
|
||||||
label: React.ReactElement;
|
label: ReactElement<any>;
|
||||||
showEyeDropper?: boolean;
|
showEyeDropper?: boolean;
|
||||||
suggestedColors?: string[];
|
suggestedColors?: string[];
|
||||||
onChange(value: number | null): void;
|
onChange(value: number | null): void;
|
||||||
|
|
|
@ -24,6 +24,7 @@ import { debounce } from "@shared/debounce";
|
||||||
import { Devs } from "@utils/constants";
|
import { Devs } from "@utils/constants";
|
||||||
import definePlugin, { OptionType } from "@utils/types";
|
import definePlugin, { OptionType } from "@utils/types";
|
||||||
import { Menu, ReactDOM } from "@webpack/common";
|
import { Menu, ReactDOM } from "@webpack/common";
|
||||||
|
import { JSX } from "react";
|
||||||
import type { Root } from "react-dom/client";
|
import type { Root } from "react-dom/client";
|
||||||
|
|
||||||
import { Magnifier, MagnifierProps } from "./components/Magnifier";
|
import { Magnifier, MagnifierProps } from "./components/Magnifier";
|
||||||
|
|
|
@ -41,6 +41,7 @@ import {
|
||||||
UserStore
|
UserStore
|
||||||
} from "@webpack/common";
|
} from "@webpack/common";
|
||||||
import { Channel, Message } from "discord-types/general";
|
import { Channel, Message } from "discord-types/general";
|
||||||
|
import { JSX } from "react";
|
||||||
|
|
||||||
const messageCache = new Map<string, {
|
const messageCache = new Map<string, {
|
||||||
message?: Message;
|
message?: Message;
|
||||||
|
@ -347,10 +348,10 @@ function AutomodEmbedAccessory(props: MessageEmbedProps): JSX.Element | null {
|
||||||
? parse(message.content)
|
? parse(message.content)
|
||||||
: [noContent(message.attachments.length, message.embeds.length)]
|
: [noContent(message.attachments.length, message.embeds.length)]
|
||||||
}
|
}
|
||||||
{images.map(a => {
|
{images.map((a, idx) => {
|
||||||
const { width, height } = computeWidthAndHeight(a.width, a.height);
|
const { width, height } = computeWidthAndHeight(a.width, a.height);
|
||||||
return (
|
return (
|
||||||
<div>
|
<div key={idx}>
|
||||||
<img src={a.url} width={width} height={height} />
|
<img src={a.url} width={width} height={height} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -69,6 +69,7 @@ export function HistoryModal({ modalProps, message }: { modalProps: ModalProps;
|
||||||
|
|
||||||
{timestamps.map((timestamp, index) => (
|
{timestamps.map((timestamp, index) => (
|
||||||
<TabBar.Item
|
<TabBar.Item
|
||||||
|
key={index}
|
||||||
className="vc-settings-tab-bar-item"
|
className="vc-settings-tab-bar-item"
|
||||||
id={index}
|
id={index}
|
||||||
>
|
>
|
||||||
|
|
|
@ -169,8 +169,8 @@ export default definePlugin({
|
||||||
|
|
||||||
return Settings.plugins.MessageLogger.inlineEdits && (
|
return Settings.plugins.MessageLogger.inlineEdits && (
|
||||||
<>
|
<>
|
||||||
{message.editHistory?.map(edit => (
|
{message.editHistory?.map((edit, idx) => (
|
||||||
<div className="messagelogger-edited">
|
<div key={idx} className="messagelogger-edited">
|
||||||
{parseEditContent(edit.content, message)}
|
{parseEditContent(edit.content, message)}
|
||||||
<Timestamp
|
<Timestamp
|
||||||
timestamp={edit.timestamp}
|
timestamp={edit.timestamp}
|
||||||
|
@ -304,7 +304,7 @@ export default definePlugin({
|
||||||
{...props}
|
{...props}
|
||||||
className={classes("messagelogger-edit-marker", className)}
|
className={classes("messagelogger-edit-marker", className)}
|
||||||
onClick={() => openHistoryModal(message)}
|
onClick={() => openHistoryModal(message)}
|
||||||
aria-role="button"
|
role="button"
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
</span>
|
</span>
|
||||||
|
|
|
@ -114,7 +114,7 @@ function SettingsComponent() {
|
||||||
return (
|
return (
|
||||||
<Flex flexDirection="column">
|
<Flex flexDirection="column">
|
||||||
{tags.map(t => (
|
{tags.map(t => (
|
||||||
<Card style={{ padding: "1em 1em 0" }}>
|
<Card key={t.name} style={{ padding: "1em 1em 0" }}>
|
||||||
<Forms.FormTitle style={{ width: "fit-content" }}>
|
<Forms.FormTitle style={{ width: "fit-content" }}>
|
||||||
<Tooltip text={t.description}>
|
<Tooltip text={t.description}>
|
||||||
{({ onMouseEnter, onMouseLeave }) => (
|
{({ onMouseEnter, onMouseLeave }) => (
|
||||||
|
|
|
@ -24,6 +24,7 @@ import definePlugin from "@utils/types";
|
||||||
import { findByPropsLazy, findComponentByCodeLazy } from "@webpack";
|
import { findByPropsLazy, findComponentByCodeLazy } from "@webpack";
|
||||||
import { Avatar, ChannelStore, Clickable, IconUtils, RelationshipStore, ScrollerThin, useMemo, UserStore } from "@webpack/common";
|
import { Avatar, ChannelStore, Clickable, IconUtils, RelationshipStore, ScrollerThin, useMemo, UserStore } from "@webpack/common";
|
||||||
import { Channel, User } from "discord-types/general";
|
import { Channel, User } from "discord-types/general";
|
||||||
|
import { JSX } from "react";
|
||||||
|
|
||||||
const SelectedChannelActionCreators = findByPropsLazy("selectPrivateChannel");
|
const SelectedChannelActionCreators = findByPropsLazy("selectPrivateChannel");
|
||||||
const UserUtils = findByPropsLazy("getGlobalName");
|
const UserUtils = findByPropsLazy("getGlobalName");
|
||||||
|
@ -55,6 +56,7 @@ function getMutualGDMCountText(user: User) {
|
||||||
function renderClickableGDMs(mutualDms: Channel[], onClose: () => void) {
|
function renderClickableGDMs(mutualDms: Channel[], onClose: () => void) {
|
||||||
return mutualDms.map(c => (
|
return mutualDms.map(c => (
|
||||||
<Clickable
|
<Clickable
|
||||||
|
key={c.id}
|
||||||
className={ProfileListClasses.listRow}
|
className={ProfileListClasses.listRow}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
onClose();
|
onClose();
|
||||||
|
|
|
@ -113,6 +113,7 @@ function RolesAndUsersPermissionsComponent({ permissions, guild, modalProps, hea
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
|
key={index}
|
||||||
className={cl("modal-list-item-btn")}
|
className={cl("modal-list-item-btn")}
|
||||||
onClick={() => selectItem(index)}
|
onClick={() => selectItem(index)}
|
||||||
role="button"
|
role="button"
|
||||||
|
@ -178,7 +179,7 @@ function RolesAndUsersPermissionsComponent({ permissions, guild, modalProps, hea
|
||||||
<div className={cl("modal-divider")} />
|
<div className={cl("modal-divider")} />
|
||||||
<ScrollerThin className={cl("modal-perms")} orientation="auto">
|
<ScrollerThin className={cl("modal-perms")} orientation="auto">
|
||||||
{Object.values(PermissionsBits).map(bit => (
|
{Object.values(PermissionsBits).map(bit => (
|
||||||
<div className={cl("modal-perms-item")}>
|
<div key={bit} className={cl("modal-perms-item")}>
|
||||||
<div className={cl("modal-perms-item-icon")}>
|
<div className={cl("modal-perms-item-icon")}>
|
||||||
{(() => {
|
{(() => {
|
||||||
const { permissions, overwriteAllow, overwriteDeny } = selectedItem;
|
const { permissions, overwriteAllow, overwriteDeny } = selectedItem;
|
||||||
|
|
|
@ -192,6 +192,7 @@ function UserPermissionsComponent({ guild, guildMember, closePopout }: { guild:
|
||||||
<div className={classes(RoleRootClasses.root)}>
|
<div className={classes(RoleRootClasses.root)}>
|
||||||
{userPermissions.map(({ permission, roleColor, roleName }) => (
|
{userPermissions.map(({ permission, roleColor, roleName }) => (
|
||||||
<Tooltip
|
<Tooltip
|
||||||
|
key={permission}
|
||||||
text={<GrantedByTooltip roleName={roleName} roleColor={roleColor} />}
|
text={<GrantedByTooltip roleName={roleName} roleColor={roleColor} />}
|
||||||
tooltipClassName={cl("granted-by-container")}
|
tooltipClassName={cl("granted-by-container")}
|
||||||
tooltipContentClassName={cl("granted-by-content")}
|
tooltipContentClassName={cl("granted-by-content")}
|
||||||
|
|
|
@ -33,7 +33,8 @@ function createPinMenuItem(channelId: string) {
|
||||||
{
|
{
|
||||||
categories.map(category => (
|
categories.map(category => (
|
||||||
<Menu.MenuItem
|
<Menu.MenuItem
|
||||||
id={`pin-category-${category.name}`}
|
key={category.id}
|
||||||
|
id={`pin-category-${category.id}`}
|
||||||
label={category.name}
|
label={category.name}
|
||||||
action={() => addChannelToCategory(channelId, category.id).then(forceUpdate)}
|
action={() => addChannelToCategory(channelId, category.id).then(forceUpdate)}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -159,7 +159,7 @@ export default LazyComponent(() => {
|
||||||
onClick={() => openBlockModal()}
|
onClick={() => openBlockModal()}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{review.sender.badges.map(badge => <ReviewBadge {...badge} />)}
|
{review.sender.badges.map((badge, idx) => <ReviewBadge key={idx} {...badge} />)}
|
||||||
|
|
||||||
{
|
{
|
||||||
!settings.store.hideTimestamps && review.type !== ReviewType.System && (
|
!settings.store.hideTimestamps && review.type !== ReviewType.System && (
|
||||||
|
@ -170,7 +170,13 @@ export default LazyComponent(() => {
|
||||||
|
|
||||||
<div className={cl("review-comment")}>
|
<div className={cl("review-comment")}>
|
||||||
{(review.comment.length > 200 && !showAll)
|
{(review.comment.length > 200 && !showAll)
|
||||||
? [Parser.parseGuildEventDescription(review.comment.substring(0, 200)), "...", <br />, (<a onClick={() => setShowAll(true)}>Read more</a>)]
|
? (
|
||||||
|
<>
|
||||||
|
{Parser.parseGuildEventDescription(review.comment.substring(0, 200))}...
|
||||||
|
<br />
|
||||||
|
<a onClick={() => setShowAll(true)}>Read more</a>]
|
||||||
|
</>
|
||||||
|
)
|
||||||
: Parser.parseGuildEventDescription(review.comment)}
|
: Parser.parseGuildEventDescription(review.comment)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -147,7 +147,7 @@ const ChatBarIcon: ChatBarButton = ({ isMainChat }) => {
|
||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 24"
|
||||||
style={{ scale: "1.2" }}
|
style={{ scale: "1.2" }}
|
||||||
>
|
>
|
||||||
<g fill="none" fill-rule="evenodd">
|
<g fill="none" fillRule="evenodd">
|
||||||
<path fill="currentColor" d="M19 3h-1V1h-2v2H8V1H6v2H5c-1.11 0-1.99.9-1.99 2L3 19a2 2 0 0 0 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16H5V8h14v11zM7 10h5v5H7v-5z" />
|
<path fill="currentColor" d="M19 3h-1V1h-2v2H8V1H6v2H5c-1.11 0-1.99.9-1.99 2L3 19a2 2 0 0 0 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16H5V8h14v11zM7 10h5v5H7v-5z" />
|
||||||
<rect width="24" height="24" />
|
<rect width="24" height="24" />
|
||||||
</g>
|
</g>
|
||||||
|
|
|
@ -247,6 +247,7 @@ function UserList(type: "friends" | "blocked", guild: Guild, ids: string[], setC
|
||||||
<ScrollerThin fade className={cl("scroller")}>
|
<ScrollerThin fade className={cl("scroller")}>
|
||||||
{members.map(id =>
|
{members.map(id =>
|
||||||
<FriendRow
|
<FriendRow
|
||||||
|
key={id}
|
||||||
user={UserStore.getUser(id)}
|
user={UserStore.getUser(id)}
|
||||||
status={PresenceStore.getStatus(id) || "offline"}
|
status={PresenceStore.getStatus(id) || "offline"}
|
||||||
onSelect={() => openUserProfile(id)}
|
onSelect={() => openUserProfile(id)}
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Clipboard } from "@webpack/common";
|
import { Clipboard } from "@webpack/common";
|
||||||
|
import { JSX } from "react";
|
||||||
|
|
||||||
import { cl } from "../utils/misc";
|
import { cl } from "../utils/misc";
|
||||||
import { CopyButton } from "./CopyButton";
|
import { CopyButton } from "./CopyButton";
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
|
|
||||||
import type { IThemedToken } from "@vap/shiki";
|
import type { IThemedToken } from "@vap/shiki";
|
||||||
import { hljs } from "@webpack/common";
|
import { hljs } from "@webpack/common";
|
||||||
|
import { JSX } from "react";
|
||||||
|
|
||||||
import { cl } from "../utils/misc";
|
import { cl } from "../utils/misc";
|
||||||
import { ThemeBase } from "./Highlighter";
|
import { ThemeBase } from "./Highlighter";
|
||||||
|
@ -41,12 +42,12 @@ export const Code = ({
|
||||||
|
|
||||||
if (useHljs) {
|
if (useHljs) {
|
||||||
try {
|
try {
|
||||||
const { value: hljsHtml } = hljs.highlight(lang!, content, true);
|
const { value: hljsHtml } = hljs.highlight(content, { language: lang!, ignoreIllegals: true });
|
||||||
lines = hljsHtml
|
lines = hljsHtml
|
||||||
.split("\n")
|
.split("\n")
|
||||||
.map((line, i) => <span key={i} dangerouslySetInnerHTML={{ __html: line }} />);
|
.map((line, i) => <span key={i} dangerouslySetInnerHTML={{ __html: line }} />);
|
||||||
} catch {
|
} catch {
|
||||||
lines = content.split("\n").map(line => <span>{line}</span>);
|
lines = content.split("\n").map((line, idx) => <span key={idx}>{line}</span>);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const renderTokens =
|
const renderTokens =
|
||||||
|
@ -55,11 +56,11 @@ export const Code = ({
|
||||||
.split("\n")
|
.split("\n")
|
||||||
.map(line => [{ color: theme.plainColor, content: line } as IThemedToken]);
|
.map(line => [{ color: theme.plainColor, content: line } as IThemedToken]);
|
||||||
|
|
||||||
lines = renderTokens.map(line => {
|
lines = renderTokens.map((line, idx) => {
|
||||||
// [Cynthia] this makes it so when you highlight the codeblock
|
// [Cynthia] this makes it so when you highlight the codeblock
|
||||||
// empty lines are also selected and copied when you Ctrl+C.
|
// empty lines are also selected and copied when you Ctrl+C.
|
||||||
if (line.length === 0) {
|
if (line.length === 0) {
|
||||||
return <span>{"\n"}</span>;
|
return <span key={idx}>{"\n"}</span>;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -97,7 +97,7 @@ function ConnectionsComponent({ id, theme }: { id: string, theme: string; }) {
|
||||||
gap: getSpacingPx(settings.store.iconSpacing),
|
gap: getSpacingPx(settings.store.iconSpacing),
|
||||||
flexWrap: "wrap"
|
flexWrap: "wrap"
|
||||||
}}>
|
}}>
|
||||||
{connections.map(connection => <CompactConnectionComponent connection={connection} theme={theme} />)}
|
{connections.map(connection => <CompactConnectionComponent connection={connection} theme={theme} key={connection.id} />)}
|
||||||
</Flex>
|
</Flex>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -137,6 +137,7 @@ function CompactConnectionComponent({ connection, theme }: { connection: Connect
|
||||||
className="vc-user-connection"
|
className="vc-user-connection"
|
||||||
href={url}
|
href={url}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
|
rel="noreferrer"
|
||||||
onClick={e => {
|
onClick={e => {
|
||||||
if (Vencord.Plugins.isPluginEnabled("OpenInApp")) {
|
if (Vencord.Plugins.isPluginEnabled("OpenInApp")) {
|
||||||
const OpenInApp = Vencord.Plugins.plugins.OpenInApp as any as typeof import("../openInApp").default;
|
const OpenInApp = Vencord.Plugins.plugins.OpenInApp as any as typeof import("../openInApp").default;
|
||||||
|
|
|
@ -268,7 +268,7 @@ function HiddenChannelLockScreen({ channel }: { channel: ExtendedChannel; }) {
|
||||||
<div className="shc-lock-screen-tags-container">
|
<div className="shc-lock-screen-tags-container">
|
||||||
<Text variant="text-lg/bold">Available tags:</Text>
|
<Text variant="text-lg/bold">Available tags:</Text>
|
||||||
<div className="shc-lock-screen-tags">
|
<div className="shc-lock-screen-tags">
|
||||||
{availableTags.map(tag => <TagComponent tag={tag} />)}
|
{availableTags.map(tag => <TagComponent tag={tag} key={tag.id} />)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
|
@ -84,13 +84,12 @@ export default definePlugin({
|
||||||
],
|
],
|
||||||
|
|
||||||
TooltipWrapper: ErrorBoundary.wrap(({ message, children, text }: { message: Message; children: FunctionComponent<any>; text: ReactNode; }) => {
|
TooltipWrapper: ErrorBoundary.wrap(({ message, children, text }: { message: Message; children: FunctionComponent<any>; text: ReactNode; }) => {
|
||||||
if (settings.store.displayStyle === DisplayStyle.Tooltip) return <Tooltip
|
if (settings.store.displayStyle === DisplayStyle.Tooltip)
|
||||||
children={children}
|
return <Tooltip text={renderTimeout(message, false)}>{children}</Tooltip>;
|
||||||
text={renderTimeout(message, false)}
|
|
||||||
/>;
|
|
||||||
return (
|
return (
|
||||||
<div className="vc-std-wrapper">
|
<div className="vc-std-wrapper">
|
||||||
<Tooltip text={text} children={children} />
|
<Tooltip text={text}>{children}</Tooltip>
|
||||||
<Text variant="text-md/normal" color="status-danger">
|
<Text variant="text-md/normal" color="status-danger">
|
||||||
{renderTimeout(message, true)} timeout remaining
|
{renderTimeout(message, true)} timeout remaining
|
||||||
</Text>
|
</Text>
|
||||||
|
|
|
@ -78,7 +78,7 @@ const SilentMessageToggle: ChatBarButton = ({ isMainChat }) => {
|
||||||
{!enabled && <>
|
{!enabled && <>
|
||||||
<mask id="vc-silent-msg-mask">
|
<mask id="vc-silent-msg-mask">
|
||||||
<path fill="#fff" d="M0 0h24v24H0Z" />
|
<path fill="#fff" d="M0 0h24v24H0Z" />
|
||||||
<path stroke="#000" stroke-width="5.99068" d="M0 24 24 0" />
|
<path stroke="#000" strokeWidth="5.99068" d="M0 24 24 0" />
|
||||||
</mask>
|
</mask>
|
||||||
<path fill="var(--status-danger)" d="m21.178 1.70703 1.414 1.414L4.12103 21.593l-1.414-1.415L21.178 1.70703Z" />
|
<path fill="var(--status-danger)" d="m21.178 1.70703 1.414 1.414L4.12103 21.593l-1.414-1.415L21.178 1.70703Z" />
|
||||||
</>}
|
</>}
|
||||||
|
|
|
@ -120,8 +120,8 @@ function ServerTrace({ trace }: ServerTraceProps) {
|
||||||
<Forms.FormSection title="Server Trace" tag="h2">
|
<Forms.FormSection title="Server Trace" tag="h2">
|
||||||
<code>
|
<code>
|
||||||
<Flex flexDirection="column" style={{ color: "var(--header-primary)", gap: 5, userSelect: "text" }}>
|
<Flex flexDirection="column" style={{ color: "var(--header-primary)", gap: 5, userSelect: "text" }}>
|
||||||
{lines.map(line => (
|
{lines.map((line, idx) => (
|
||||||
<span>{line}</span>
|
<span key={idx}>{line}</span>
|
||||||
))}
|
))}
|
||||||
</Flex>
|
</Flex>
|
||||||
</code>
|
</code>
|
||||||
|
|
|
@ -133,11 +133,14 @@ export default definePlugin({
|
||||||
|
|
||||||
let element = 0;
|
let element = 0;
|
||||||
|
|
||||||
return children.map(c =>
|
return children.map(c => {
|
||||||
c.type === "strong" || (typeof c !== "string" && !React.isValidElement(c))
|
const user = users[element++];
|
||||||
? <TypingUser guildId={guildId} user={users[element++]} />
|
|
||||||
: c
|
if (c.type === "strong" || (typeof c !== "string" && !React.isValidElement(c)))
|
||||||
);
|
return <TypingUser key={user.id} guildId={guildId} user={user} />;
|
||||||
|
|
||||||
|
return c;
|
||||||
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@ import { wordsToTitle } from "@utils/text";
|
||||||
import definePlugin, { OptionType, PluginOptionsItem, ReporterTestable } from "@utils/types";
|
import definePlugin, { OptionType, PluginOptionsItem, ReporterTestable } from "@utils/types";
|
||||||
import { findByPropsLazy } from "@webpack";
|
import { findByPropsLazy } from "@webpack";
|
||||||
import { Button, ChannelStore, Forms, GuildMemberStore, SelectedChannelStore, SelectedGuildStore, useMemo, UserStore } from "@webpack/common";
|
import { Button, ChannelStore, Forms, GuildMemberStore, SelectedChannelStore, SelectedGuildStore, useMemo, UserStore } from "@webpack/common";
|
||||||
|
import { ReactElement } from "react";
|
||||||
|
|
||||||
interface VoiceState {
|
interface VoiceState {
|
||||||
userId: string;
|
userId: string;
|
||||||
|
@ -289,7 +290,7 @@ export default definePlugin({
|
||||||
description: "Undeafen Message (only self for now)",
|
description: "Undeafen Message (only self for now)",
|
||||||
default: "{{USER}} undeafened"
|
default: "{{USER}} undeafened"
|
||||||
}
|
}
|
||||||
};
|
} satisfies Record<string, PluginOptionsItem>;
|
||||||
},
|
},
|
||||||
|
|
||||||
settingsAboutComponent({ tempSettings: s }) {
|
settingsAboutComponent({ tempSettings: s }) {
|
||||||
|
@ -303,7 +304,7 @@ export default definePlugin({
|
||||||
[],
|
[],
|
||||||
);
|
);
|
||||||
|
|
||||||
let errorComponent: React.ReactElement | null = null;
|
let errorComponent: ReactElement<any> | null = null;
|
||||||
if (!hasVoices) {
|
if (!hasVoices) {
|
||||||
let error = "No narrator voices found. ";
|
let error = "No narrator voices found. ";
|
||||||
error += navigator.platform?.toLowerCase().includes("linux")
|
error += navigator.platform?.toLowerCase().includes("linux")
|
||||||
|
|
|
@ -23,7 +23,7 @@ import { Queue } from "@utils/Queue";
|
||||||
import { useForceUpdater } from "@utils/react";
|
import { useForceUpdater } from "@utils/react";
|
||||||
import definePlugin from "@utils/types";
|
import definePlugin from "@utils/types";
|
||||||
import { findByPropsLazy, findComponentByCodeLazy } from "@webpack";
|
import { findByPropsLazy, findComponentByCodeLazy } from "@webpack";
|
||||||
import { ChannelStore, Constants, FluxDispatcher, React, RestAPI, Tooltip } from "@webpack/common";
|
import { ChannelStore, Constants, FluxDispatcher, React, RestAPI, Tooltip, useEffect, useLayoutEffect } from "@webpack/common";
|
||||||
import { CustomEmoji } from "@webpack/types";
|
import { CustomEmoji } from "@webpack/types";
|
||||||
import { Message, ReactionEmoji, User } from "discord-types/general";
|
import { Message, ReactionEmoji, User } from "discord-types/general";
|
||||||
|
|
||||||
|
@ -134,18 +134,21 @@ export default definePlugin({
|
||||||
renderUsers(props: RootObject) {
|
renderUsers(props: RootObject) {
|
||||||
return props.message.reactions.length > 10 ? null : (
|
return props.message.reactions.length > 10 ? null : (
|
||||||
<ErrorBoundary noop>
|
<ErrorBoundary noop>
|
||||||
<this._renderUsers {...props} />
|
<this.UsersComponent {...props} />
|
||||||
</ErrorBoundary>
|
</ErrorBoundary>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
_renderUsers({ message, emoji, type }: RootObject) {
|
|
||||||
|
UsersComponent({ message, emoji, type }: RootObject) {
|
||||||
const forceUpdate = useForceUpdater();
|
const forceUpdate = useForceUpdater();
|
||||||
React.useLayoutEffect(() => { // bc need to prevent autoscrolling
|
|
||||||
|
useLayoutEffect(() => { // bc need to prevent autoscrolling
|
||||||
if (Scroll?.scrollCounter > 0) {
|
if (Scroll?.scrollCounter > 0) {
|
||||||
Scroll.setAutomaticAnchor(null);
|
Scroll.setAutomaticAnchor(null);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
React.useEffect(() => {
|
|
||||||
|
useEffect(() => {
|
||||||
const cb = (e: any) => {
|
const cb = (e: any) => {
|
||||||
if (e.messageId === message.id)
|
if (e.messageId === message.id)
|
||||||
forceUpdate();
|
forceUpdate();
|
||||||
|
@ -153,7 +156,7 @@ export default definePlugin({
|
||||||
FluxDispatcher.subscribe("MESSAGE_REACTION_ADD_USERS", cb);
|
FluxDispatcher.subscribe("MESSAGE_REACTION_ADD_USERS", cb);
|
||||||
|
|
||||||
return () => FluxDispatcher.unsubscribe("MESSAGE_REACTION_ADD_USERS", cb);
|
return () => FluxDispatcher.unsubscribe("MESSAGE_REACTION_ADD_USERS", cb);
|
||||||
}, [message.id]);
|
}, [message.id, forceUpdate]);
|
||||||
|
|
||||||
const reactions = getReactionsWithQueue(message, emoji, type);
|
const reactions = getReactionsWithQueue(message, emoji, type);
|
||||||
const users = Object.values(reactions).filter(Boolean) as User[];
|
const users = Object.values(reactions).filter(Boolean) as User[];
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { findByPropsLazy, findModuleId, proxyLazyWebpack, wreq } from "@webpack";
|
import { findByPropsLazy, findModuleId, proxyLazyWebpack, wreq } from "@webpack";
|
||||||
import type { ComponentType, PropsWithChildren, ReactNode, Ref } from "react";
|
import type { ComponentType, PropsWithChildren, ReactElement, Ref } from "react";
|
||||||
|
|
||||||
import { LazyComponent } from "./react";
|
import { LazyComponent } from "./react";
|
||||||
|
|
||||||
|
@ -47,7 +47,7 @@ export interface ModalOptions {
|
||||||
onCloseCallback?: (() => void);
|
onCloseCallback?: (() => void);
|
||||||
}
|
}
|
||||||
|
|
||||||
type RenderFunction = (props: ModalProps) => ReactNode;
|
type RenderFunction = (props: ModalProps) => ReactElement<any>;
|
||||||
|
|
||||||
export const Modals = findByPropsLazy("ModalRoot", "ModalCloseButton") as {
|
export const Modals = findByPropsLazy("ModalRoot", "ModalCloseButton") as {
|
||||||
ModalRoot: ComponentType<PropsWithChildren<{
|
ModalRoot: ComponentType<PropsWithChildren<{
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { React, useEffect, useMemo, useReducer, useState } from "@webpack/common";
|
import { React, useEffect, useMemo, useReducer, useState } from "@webpack/common";
|
||||||
|
import { ActionDispatch } from "react";
|
||||||
|
|
||||||
import { checkIntersecting } from "./misc";
|
import { checkIntersecting } from "./misc";
|
||||||
|
|
||||||
|
@ -117,8 +118,8 @@ export function useAwaiter<T>(factory: () => Promise<T>, providedOpts?: AwaiterO
|
||||||
/**
|
/**
|
||||||
* Returns a function that can be used to force rerender react components
|
* Returns a function that can be used to force rerender react components
|
||||||
*/
|
*/
|
||||||
export function useForceUpdater(): () => void;
|
export function useForceUpdater(): ActionDispatch<[]>;
|
||||||
export function useForceUpdater(withDep: true): [unknown, () => void];
|
export function useForceUpdater(withDep: true): [any, ActionDispatch<[]>];
|
||||||
export function useForceUpdater(withDep?: true) {
|
export function useForceUpdater(withDep?: true) {
|
||||||
const r = useReducer(x => x + 1, 0);
|
const r = useReducer(x => x + 1, 0);
|
||||||
return withDep ? r : r[1];
|
return withDep ? r : r[1];
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
import { Command } from "@api/Commands";
|
import { Command } from "@api/Commands";
|
||||||
import { NavContextMenuPatchCallback } from "@api/ContextMenu";
|
import { NavContextMenuPatchCallback } from "@api/ContextMenu";
|
||||||
import { FluxEvents } from "@webpack/types";
|
import { FluxEvents } from "@webpack/types";
|
||||||
|
import { JSX } from "react";
|
||||||
import { Promisable } from "type-fest";
|
import { Promisable } from "type-fest";
|
||||||
|
|
||||||
// exists to export default definePlugin({...})
|
// exists to export default definePlugin({...})
|
||||||
|
|
|
@ -48,7 +48,7 @@ export const Constants: t.Constants = mapMangledModuleLazy('ME:"/users/@me"', {
|
||||||
export const RestAPI: t.RestAPI = findLazy(m => typeof m === "object" && m.del && m.put);
|
export const RestAPI: t.RestAPI = findLazy(m => typeof m === "object" && m.del && m.put);
|
||||||
export const moment: typeof import("moment") = findByPropsLazy("parseTwoDigitYear");
|
export const moment: typeof import("moment") = findByPropsLazy("parseTwoDigitYear");
|
||||||
|
|
||||||
export const hljs: typeof import("highlight.js") = findByPropsLazy("highlight", "registerLanguage");
|
export const hljs: typeof import("highlight.js").default = findByPropsLazy("highlight", "registerLanguage");
|
||||||
|
|
||||||
export const { match, P }: Pick<typeof import("ts-pattern"), "match" | "P"> = mapMangledModuleLazy("@ts-pattern/matcher", {
|
export const { match, P }: Pick<typeof import("ts-pattern"), "match" | "P"> = mapMangledModuleLazy("@ts-pattern/matcher", {
|
||||||
match: filters.byCode("return new"),
|
match: filters.byCode("return new"),
|
||||||
|
|
Loading…
Reference in a new issue