diff --git a/package.json b/package.json index 30f4c1586..24c7c7a29 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "equicord", "private": "true", - "version": "1.14.10.1", + "version": "1.14.11.0", "description": "The other cutest Discord client mod", "homepage": "https://github.com/Equicord/Equicord#readme", "bugs": { diff --git a/scripts/generateReport.ts b/scripts/generateReport.ts index d6373e99f..22fc571b1 100644 --- a/scripts/generateReport.ts +++ b/scripts/generateReport.ts @@ -81,7 +81,9 @@ const IGNORED_DISCORD_ERRORS = [ "Downloading the full bad domains file", /\[GatewaySocket\].{0,110}Cannot access '/, "search for 'name' in undefined", - "Attempting to set fast connect zstd when unsupported" + "Attempting to set fast connect zstd when unsupported", + /Cannot read properties of undefined \(reading 'call'\)/, + "Could not complete Remote Auth login, trying to restart with a new Remote Auth session." ] as Array; function toCodeBlock(s: string, indentation = 0, isDiscord = false) { diff --git a/src/api/SettingsSync/cloudSync.ts b/src/api/SettingsSync/cloudSync.ts index 08d7a58fa..3b65b11e0 100644 --- a/src/api/SettingsSync/cloudSync.ts +++ b/src/api/SettingsSync/cloudSync.ts @@ -21,17 +21,25 @@ import { ManifestEntry, SyncRequest, SyncResponse } from "./types"; const logger = new Logger("SettingsSync:Cloud", "#39b7e0"); const MANIFEST_STORE_KEY = "Vencord_cloudManifest"; +const API_VERSION_STORE_KEY = "Vencord_cloudApiVersions"; type ApiVersion = "v2" | "v1"; -let apiVersion: ApiVersion = "v2"; +async function loadApiVersionMap(): Promise> { + return await DataStore.get>(API_VERSION_STORE_KEY) ?? {}; +} async function getApiVersion(): Promise { - return apiVersion; + const map = await loadApiVersionMap(); + return map[getCloudUrl().origin] ?? "v2"; } async function setApiVersion(version: ApiVersion) { - apiVersion = version; + await DataStore.update>(API_VERSION_STORE_KEY, map => { + map ??= {}; + map[getCloudUrl().origin] = version; + return map; + }); } function toBase64(data: Uint8Array): string { diff --git a/src/components/settings/tabs/plugins/index.tsx b/src/components/settings/tabs/plugins/index.tsx index 708c46cf6..2909f15ab 100644 --- a/src/components/settings/tabs/plugins/index.tsx +++ b/src/components/settings/tabs/plugins/index.tsx @@ -204,14 +204,13 @@ export default function PluginSettings() { const pluginFilter = useCallback((plugin: typeof Plugins[keyof typeof Plugins], newPluginsSet: Set | null) => { const { status, tags } = searchValue; - const enabled = isPluginEnabled(plugin.name); switch (status) { case SearchStatus.DISABLED: - if (enabled) return false; + if (isPluginEnabled(plugin.name)) return false; break; case SearchStatus.ENABLED: - if (!enabled) return false; + if (!isPluginEnabled(plugin.name)) return false; break; case SearchStatus.EQUICORD: if (!PluginMeta[plugin.name].folderName.startsWith("src/equicordplugins/")) return false; @@ -236,6 +235,7 @@ export default function PluginSettings() { return ( plugin.name.toLowerCase().includes(search.replace(/\s+/g, "")) || + plugin.name.match(/[A-Z]/g)?.join("").toLowerCase().includes(search) || // acronyms like BF for BetterFolders plugin.description.toLowerCase().includes(search) || plugin.searchTerms?.some(t => t.toLowerCase().includes(search)) ); diff --git a/src/components/settings/tabs/vencord/index.tsx b/src/components/settings/tabs/vencord/index.tsx index 7ef1bf048..0eeec8e01 100644 --- a/src/components/settings/tabs/vencord/index.tsx +++ b/src/components/settings/tabs/vencord/index.tsx @@ -65,75 +65,63 @@ function EquicordSettings() { title: string; description?: string; restartRequired?: boolean; - warning: { enabled: boolean; message?: string; }; + warning?: string; } > = [ - { - key: "useQuickCss", - title: t("vencord.settings.useQuickCss.title"), - description: t("vencord.settings.useQuickCss.description"), - restartRequired: true, - warning: { enabled: false }, - }, - !IS_WEB && { - key: "enableReactDevtools", - title: t("vencord.settings.enableReactDevtools.title"), - description: t("vencord.settings.enableReactDevtools.description"), - restartRequired: true, - warning: { enabled: false }, - }, - (!IS_WEB && !IS_DISCORD_DESKTOP || !IS_WINDOWS) && { - key: "mainWindowFrameless", - title: t("equicord.mainWindowFrameless.title"), - description: t("equicord.mainWindowFrameless.description"), - restartRequired: true, - warning: { enabled: false }, - }, - !IS_WEB && - (!IS_DISCORD_DESKTOP || !IS_WINDOWS + { + key: "useQuickCss", + title: t("vencord.settings.useQuickCss.title"), + description: t("vencord.settings.useQuickCss.description"), + }, + !IS_WEB && { + key: "enableReactDevtools", + title: t("vencord.settings.enableReactDevtools.title"), + description: t("vencord.settings.enableReactDevtools.description"), + restartRequired: true, + }, + (!IS_WEB && !IS_DISCORD_DESKTOP || !IS_WINDOWS) && { + key: "mainWindowFrameless", + title: t("equicord.mainWindowFrameless.title"), + description: t("equicord.mainWindowFrameless.description"), + restartRequired: true, + }, + !IS_WEB && (!IS_DISCORD_DESKTOP || !IS_WINDOWS ? { key: "frameless", title: t("vencord.settings.frameless.title"), description: t("vencord.settings.frameless.description"), restartRequired: true, - warning: { enabled: false }, } : { key: "winNativeTitleBar", title: t("vencord.settings.winNativeTitleBar.title"), description: t("vencord.settings.winNativeTitleBar.description"), restartRequired: true, - warning: { enabled: false }, } ), - !IS_WEB && { - key: "transparent", - title: t("vencord.settings.transparent.title"), - description: t("vencord.settings.transparent.description"), - restartRequired: true, - warning: { - enabled: true, - message: IS_WINDOWS + !IS_WEB && { + key: "transparent", + title: t("vencord.settings.transparent.title"), + description: t("vencord.settings.transparent.description"), + restartRequired: true, + warning: IS_WINDOWS ? t("vencord.settings.transparent.noteWindows") : t("vencord.settings.transparent.note"), }, - }, - IS_DISCORD_DESKTOP && { - key: "disableMinSize", - title: t("vencord.settings.disableMinSize.title"), - description: t("vencord.settings.disableMinSize.description"), - restartRequired: true, - warning: { enabled: false }, - }, - !IS_WEB && + IS_DISCORD_DESKTOP && { + key: "disableMinSize", + title: t("vencord.settings.disableMinSize.title"), + description: t("vencord.settings.disableMinSize.description"), + restartRequired: true, + }, + !IS_WEB && IS_WINDOWS && { - key: "winCtrlQ", - title: t("vencord.settings.winCtrlQ.title"), - description: t("vencord.settings.winCtrlQ.description"), - restartRequired: true, - warning: { enabled: false }, - }, - ]; + key: "winCtrlQ", + title: t("vencord.settings.winCtrlQ.title"), + description: t("vencord.settings.winCtrlQ.description"), + restartRequired: true, + }, + ]; return ( @@ -265,11 +253,11 @@ function EquicordSettings() { }} title={s.title} description={ - s.warning.enabled ? ( + s.warning ? ( <> {s.description} - {s.warning.message} + {s.warning} ) : ( diff --git a/src/equicordplugins/_api/profileCollections.ts b/src/equicordplugins/_api/profileCollections.ts index b61066380..bbc51a840 100644 --- a/src/equicordplugins/_api/profileCollections.ts +++ b/src/equicordplugins/_api/profileCollections.ts @@ -13,7 +13,7 @@ export default definePlugin({ authors: [Devs.thororen], patches: [ { - find: "#{intl::XcTHmQ::raw}", + find: "#{intl::USER_PROFILE_FRIEND_REQUEST_TOAST}", replacement: { match: /user:\i,widgets:.{0,100}?\}\),/, replace: "$&Vencord.Api.ProfileCollections.renderProfileCollections(arguments[0]),", diff --git a/src/equicordplugins/_core/concatenatedModules.tsx b/src/equicordplugins/_core/concatenatedModules.tsx new file mode 100644 index 000000000..f22c20724 --- /dev/null +++ b/src/equicordplugins/_core/concatenatedModules.tsx @@ -0,0 +1,32 @@ +/* + * Vencord, a Discord client mod + * Copyright (c) 2026 Vendicated and contributors + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +import { IconsDef } from "@equicordplugins/iconViewer/types"; +import { Devs } from "@utils/constants"; +import definePlugin from "@utils/types"; + +export let iconsModule: IconsDef; + +export default definePlugin({ + name: "ConcatenatedModules", + description: "Extract modules that have been concatenated by the bundler", + authors: [Devs.thororen], + + required: true, + + patches: [ + { + find: "AngleBracketsIcon", + replacement: { + match: /\i\.\i\((\i)\),\i\.\i\(\i,\{AIcon/, + replace: "$self.iconsModule($1),$&" + } + } + ], + set iconsModule(value: any) { + iconsModule = value; + }, +}); diff --git a/src/equicordplugins/betterBanReasons/index.tsx b/src/equicordplugins/betterBanReasons/index.tsx index a86da0f1a..46976bf54 100644 --- a/src/equicordplugins/betterBanReasons/index.tsx +++ b/src/equicordplugins/betterBanReasons/index.tsx @@ -9,49 +9,83 @@ import "./styles.css"; import { definePluginSettings } from "@api/Settings"; import { Heading } from "@components/Heading"; import { DeleteIcon, PlusIcon } from "@components/Icons"; -import { Devs } from "@utils/constants"; +import { Devs, EquicordDevs } from "@utils/constants"; import { classNameFactory } from "@utils/css"; import { t } from "@utils/translation"; import definePlugin, { OptionType } from "@utils/types"; -import { Button, TextInput } from "@webpack/common"; +import { Button, Select, TextInput, useState } from "@webpack/common"; const cl = classNameFactory("vc-bbr-"); +interface BanReason { + text: string; + deleteSeconds?: number; +} + +const DELETE_DURATION_OPTIONS = [ + { label: "Discord default", value: null }, + { label: "Don't delete any", value: 0 }, + { label: "Previous hour", value: 3600 }, + { label: "Previous 6 hours", value: 21600 }, + { label: "Previous 12 hours", value: 43200 }, + { label: "Previous 24 hours", value: 86400 }, + { label: "Previous 3 days", value: 259200 }, + { label: "Previous 7 days", value: 604800 }, +]; + +function normalizeReason(r: BanReason | string): BanReason { + return typeof r === "string" ? { text: r } : r; +} + +function getStoredReasons(): BanReason[] { + return (settings.store.reasons as (BanReason | string)[]).map(normalizeReason); +} + function ReasonsComponent() { - const { reasons } = settings.store; + const [reasons, setReasons] = useState(getStoredReasons); + + const update = (next: BanReason[]) => { + setReasons(next); + settings.store.reasons = next; + }; return (
{t("equicord.betterBanReasons.ui.reasons")} {reasons.map((r, i) => ( -
+
{ - reasons[i] = v; - settings.store.reasons = reasons; - }} + value={r.text} + onChange={v => update(reasons.map((x, j) => j === i ? { ...x, text: v } : x))} placeholder={t("equicord.betterBanReasons.ui.reasonPlaceholder")} /> +
+ Message Auto-delete duration +