diff --git a/browser/userscript.meta.js b/browser/userscript.meta.js index 5b2a39be6..1d986aaee 100644 --- a/browser/userscript.meta.js +++ b/browser/userscript.meta.js @@ -5,6 +5,7 @@ // @author Vendicated (https://github.com/Vendicated) // @namespace https://github.com/Vendicated/Vencord // @supportURL https://github.com/Vendicated/Vencord +// @icon https://raw.githubusercontent.com/Vendicated/Vencord/refs/heads/main/browser/icon.png // @license GPL-3.0 // @match *://*.discord.com/* // @grant GM_xmlhttpRequest diff --git a/package.json b/package.json index 65a2f4512..d5b23e57c 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "vencord", "private": "true", - "version": "1.9.9", + "version": "1.10.7", "description": "The cutest Discord client mod", "homepage": "https://github.com/Vendicated/Vencord#readme", "bugs": { @@ -35,6 +35,7 @@ "testTsc": "tsc --noEmit" }, "dependencies": { + "@intrnl/xxhash64": "^0.1.2", "@sapphi-red/web-noise-suppressor": "0.3.5", "@vap/core": "0.0.12", "@vap/shiki": "0.10.5", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index eaa6b537c..a62c40cd6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -16,6 +16,9 @@ importers: .: dependencies: + '@intrnl/xxhash64': + specifier: ^0.1.2 + version: 0.1.2 '@sapphi-red/web-noise-suppressor': specifier: 0.3.5 version: 0.3.5 @@ -537,6 +540,9 @@ packages: resolution: {integrity: sha512-d2CGZR2o7fS6sWB7DG/3a95bGKQyHMACZ5aW8qGkkqQpUoZV6C0X7Pc7l4ZNMZkfNBf4VWNe9E1jRsf0G146Ew==} engines: {node: '>=18.18'} + '@intrnl/xxhash64@0.1.2': + resolution: {integrity: sha512-1+lx7j99fdph+uy3EnjQyr39KQZ7LP56+aWOr6finJWpgYpvb7XrhFUqDwnEk/wpPC98nCjAT6RulpW3crWjlg==} + '@jridgewell/gen-mapping@0.3.5': resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} engines: {node: '>=6.0.0'} @@ -2939,6 +2945,8 @@ snapshots: '@humanwhocodes/retry@0.3.0': {} + '@intrnl/xxhash64@0.1.2': {} + '@jridgewell/gen-mapping@0.3.5': dependencies: '@jridgewell/set-array': 1.2.1 diff --git a/scripts/generateReport.ts b/scripts/generateReport.ts index 2ec9fba7c..c18bc14a3 100644 --- a/scripts/generateReport.ts +++ b/scripts/generateReport.ts @@ -225,7 +225,7 @@ page.on("console", async e => { plugin, type, id, - match: regex.replace(/\[A-Za-z_\$\]\[\\w\$\]\*/g, "\\i"), + match: regex.replace(/\(\?:\[A-Za-z_\$\]\[\\w\$\]\*\)/g, "\\i"), error: await maybeGetError(e.args()[3]) }); diff --git a/src/api/Commands/index.ts b/src/api/Commands/index.ts index ef4db171c..e5803ba02 100644 --- a/src/api/Commands/index.ts +++ b/src/api/Commands/index.ts @@ -16,6 +16,7 @@ * along with this program. If not, see . */ +import { Logger } from "@utils/Logger"; import { makeCodeblock } from "@utils/text"; import { sendBotMessage } from "./commandHelpers"; @@ -46,10 +47,10 @@ export let RequiredMessageOption: Option = ReqPlaceholder; export const _init = function (cmds: Command[]) { try { BUILT_IN = cmds; - OptionalMessageOption = cmds.find(c => c.name === "shrug")!.options![0]; - RequiredMessageOption = cmds.find(c => c.name === "me")!.options![0]; + OptionalMessageOption = cmds.find(c => (c.untranslatedName || c.displayName) === "shrug")!.options![0]; + RequiredMessageOption = cmds.find(c => (c.untranslatedName || c.displayName) === "me")!.options![0]; } catch (e) { - console.error("Failed to load CommandsApi"); + new Logger("CommandsAPI").error("Failed to load CommandsApi", e, " - cmds is", cmds); } return cmds; } as never; @@ -138,6 +139,8 @@ export function registerCommand(command: C, plugin: string) { throw new Error(`Command '${command.name}' already exists.`); command.isVencordCommand = true; + command.untranslatedName ??= command.name; + command.untranslatedDescription ??= command.description; command.id ??= `-${BUILT_IN.length + 1}`; command.applicationId ??= "-1"; // BUILT_IN; command.type ??= ApplicationCommandType.CHAT_INPUT; diff --git a/src/api/Commands/types.ts b/src/api/Commands/types.ts index bd349e250..70b73775a 100644 --- a/src/api/Commands/types.ts +++ b/src/api/Commands/types.ts @@ -93,8 +93,10 @@ export interface Command { isVencordCommand?: boolean; name: string; + untranslatedName?: string; displayName?: string; description: string; + untranslatedDescription?: string; displayDescription?: string; options?: Option[]; diff --git a/src/api/ContextMenu.ts b/src/api/ContextMenu.ts index fdd4facf4..114942ff6 100644 --- a/src/api/ContextMenu.ts +++ b/src/api/ContextMenu.ts @@ -90,19 +90,20 @@ export function removeGlobalContextMenuPatch(patch: GlobalContextMenuPatchCallba * A helper function for finding the children array of a group nested inside a context menu based on the id(s) of its children * @param id The id of the child. If an array is specified, all ids will be tried * @param children The context menu children + * @param matchSubstring Whether to check if the id is a substring of the child id */ -export function findGroupChildrenByChildId(id: string | string[], children: Array): Array | null { +export function findGroupChildrenByChildId(id: string | string[], children: Array, matchSubstring = false): Array | null { for (const child of children) { if (child == null) continue; if (Array.isArray(child)) { - const found = findGroupChildrenByChildId(id, child); + const found = findGroupChildrenByChildId(id, child, matchSubstring); if (found !== null) return found; } if ( - (Array.isArray(id) && id.some(id => child.props?.id === id)) - || child.props?.id === id + (Array.isArray(id) && id.some(id => matchSubstring ? child.props?.id?.includes(id) : child.props?.id === id)) + || (matchSubstring ? child.props?.id?.includes(id) : child.props?.id === id) ) return children; let nextChildren = child.props?.children; @@ -112,7 +113,7 @@ export function findGroupChildrenByChildId(id: string | string[], children: Arra child.props.children = nextChildren; } - const found = findGroupChildrenByChildId(id, nextChildren); + const found = findGroupChildrenByChildId(id, nextChildren, matchSubstring); if (found !== null) return found; } } diff --git a/src/components/Icons.tsx b/src/components/Icons.tsx index fa142a18c..d0d2ecbe8 100644 --- a/src/components/Icons.tsx +++ b/src/components/Icons.tsx @@ -18,9 +18,8 @@ import "./iconStyles.css"; -import { getTheme, Theme } from "@utils/discord"; +import { getIntlMessage, getTheme, Theme } from "@utils/discord"; import { classes } from "@utils/misc"; -import { i18n } from "@webpack/common"; import type { PropsWithChildren } from "react"; interface BaseIconProps extends IconProps { @@ -133,7 +132,7 @@ export function InfoIcon(props: IconProps) { export function OwnerCrownIcon(props: IconProps) { return ( . */ +import { Margins } from "@utils/margins"; +import { wordsFromCamel, wordsToTitle } from "@utils/text"; import { OptionType, PluginOptionNumber } from "@utils/types"; import { Forms, React, TextInput } from "@webpack/common"; @@ -54,7 +56,8 @@ export function SettingNumericComponent({ option, pluginSettings, definedSetting return ( - {option.description} + {wordsToTitle(wordsFromCamel(id))} + {option.description} . */ +import { Margins } from "@utils/margins"; +import { wordsFromCamel, wordsToTitle } from "@utils/text"; import { PluginOptionSelect } from "@utils/types"; import { Forms, React, Select } from "@webpack/common"; @@ -44,7 +46,8 @@ export function SettingSelectComponent({ option, pluginSettings, definedSettings return ( - {option.description} + {wordsToTitle(wordsFromCamel(id))} + {option.description}