Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

1.11.6 #45

Open
wants to merge 15 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "vencord",
"private": "true",
"version": "1.11.5",
"version": "1.11.6",
"description": "The cutest Discord client mod",
"homepage": "https://github.com/Vendicated/Vencord#readme",
"bugs": {
Expand Down
10 changes: 4 additions & 6 deletions src/plugins/_api/badges/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -73,19 +73,17 @@ export default definePlugin({
find: ".description,delay:",
replacement: [
{
// alt: "", aria-hidden: false, src: originalSrc
match: /alt:" ","aria-hidden":!0,src:(?=.{0,20}(\i)\.icon)/,
// ...badge.props, ..., src: badge.image ?? ...
replace: "...$1.props,$& $1.image??"
match: /(alt:" ","aria-hidden":!0,src:)(.{0,20}(\i)\.icon\))/,
replace: (_, rest, originalSrc, badge) => `...${badge}.props,${rest}${badge}.image??(${originalSrc})`
},
{
match: /(?<="aria-label":(\i)\.description,.{0,200})children:/,
replace: "children:$1.component ? $self.renderBadgeComponent({ ...$1 }) :"
replace: "children:$1.component?$self.renderBadgeComponent({...$1}) :"
},
// conditionally override their onClick with badge.onClick if it exists
{
match: /href:(\i)\.link/,
replace: "...($1.onClick && { onClick: vcE => $1.onClick(vcE, $1) }),$&"
replace: "...($1.onClick&&{onClick:vcE=>$1.onClick(vcE,$1)}),$&"
}
]
}
Expand Down
2 changes: 1 addition & 1 deletion src/plugins/_api/chatButtons.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export default definePlugin({
find: '"sticker")',
replacement: {
// 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
? `${m}(Vencord.Api.ChatButtons._injectButtons(${children},arguments[0]),true)&&`
: `${m}(Vencord.Api.ChatButtons._injectButtons(${children},arguments[0]),false)||`
Expand Down
9 changes: 8 additions & 1 deletion src/plugins/_api/dynamicImageModalApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,18 @@ export default definePlugin({
description: "Allows you to omit either width or height when opening an image modal",
patches: [
{
find: "SCALE_DOWN:",
find: ".contain,SCALE_DOWN:",
replacement: {
match: /(?<="IMAGE"===\i\?)\i(?=\?)/,
replace: "true"
}
},
{
find: ".dimensionlessImage,",
replacement: {
match: /(?<="IMAGE"===\i&&\(\i=)\i(?=\?)/,
replace: "true"
}
}
]
});
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,11 @@
*/

import { definePluginSettings } from "@api/Settings";
import { ErrorBoundary, Flex } from "@components/index";
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 NoopLogger = {
Expand All @@ -24,6 +27,48 @@ const NoopLogger = {

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({
disableLoggers: {
type: OptionType.BOOLEAN,
Expand All @@ -45,6 +90,18 @@ const settings = definePluginSettings({
logAllow.clear();
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
})
}
});

Expand All @@ -61,8 +118,9 @@ export default definePlugin({
},

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: [
Expand Down Expand Up @@ -136,13 +194,13 @@ export default definePlugin({
replace: ""
}
},
// Patches discords generic logger function
// Patches Discord generic logger function
{
find: "Σ:",
predicate: () => settings.store.disableLoggers,
replacement: {
match: /(?<=&&)(?=console)/,
replace: "$self.shouldLog(arguments[0])&&"
replace: "$self.shouldLog(arguments[0],arguments[1])&&"
}
},
{
Expand Down
8 changes: 1 addition & 7 deletions src/plugins/consoleShortcuts/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -153,13 +153,7 @@ function makeShortcuts() {
openModal: { getter: () => ModalAPI.openModal },
openModalLazy: { getter: () => ModalAPI.openModalLazy },

Stores: {
getter: () => Object.fromEntries(
Common.Flux.Store.getAll()
.map(store => [store.getName(), store] as const)
.filter(([name]) => name.length > 1)
)
}
Stores: Webpack.fluxStores
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Simplified Stores implementation by using cached fluxStores.

Good refactor that replaces a complex dynamic getter implementation with a direct reference to the cached Webpack.fluxStores. This change:

  • Improves performance by using pre-cached stores instead of dynamically constructing the object
  • Simplifies the code and reduces potential points of failure
  • Leverages existing functionality from the webpack module

};
}

Expand Down
10 changes: 9 additions & 1 deletion src/plugins/crashHandler/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,15 @@ export default definePlugin({
} catch (err) {
CrashHandlerLogger.debug("Failed to pop all layers.", err);
}
try {
FluxDispatcher.dispatch({
type: "DEV_TOOLS_SETTINGS_UPDATE",
settings: { displayTools: false, lastOpenTabId: "analytics" }
});
} catch (err) {
CrashHandlerLogger.debug("Failed to close DevTools.", err);
}

if (settings.store.attemptToNavigateToHome) {
try {
NavigationRouter.transitionToGuild("@me");
Expand All @@ -181,7 +190,6 @@ export default definePlugin({
}
}


// Set isRecovering to false before setting the state to allow us to handle the next crash error correcty, in case it happens
setImmediate(() => isRecovering = false);

Expand Down
2 changes: 1 addition & 1 deletion src/plugins/gameActivityToggle/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ export default definePlugin({
{
find: "#{intl::ACCOUNT_SPEAKING_WHILE_MUTED}",
replacement: {
match: /this\.renderNameZone\(\).+?children:\[/,
match: /className:\i\.buttons,.{0,50}children:\[/,
replace: "$&$self.GameActivityToggleButton(),"
}
}
Expand Down
31 changes: 29 additions & 2 deletions src/plugins/imageZoom/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -165,8 +165,35 @@ export default definePlugin({
{
find: ".contain,SCALE_DOWN:",
replacement: {
match: /\.slide,\i\),/g,
replace: `$&id:"${ELEMENT_ID}",`
match: /imageClassName:/,
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"
}
Comment on lines +192 to 197
Copy link

@coderabbitai coderabbitai bot Mar 2, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fixed media viewer options visibility when zoomed.

This patch ensures that media viewer options remain visible even when zoomed in with Discord's default feature by forcing the hidden class condition to return false.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

whats the actual issue youre addressing here?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Scyye The issue being addressed is that normally when you zoom into an image using Discord's built-in zoom feature, the media viewer options (like the download button, fullscreen button, etc.) disappear because Discord hides them.

This patch forces those controls to remain visible even when zoomed in, giving users better access to those options while they're examining zoomed images. Without this fix, users would have to zoom out first just to access those controls, which creates a poor user experience.

},

Expand Down
4 changes: 2 additions & 2 deletions src/plugins/showMeYourName/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ export default definePlugin({
{
find: '?"@":""',
replacement: {
match: /(?<=onContextMenu:\i,children:).*?\)}/,
replace: "$self.renderUsername(arguments[0])}"
match: /(?<=children:)\(\i\?"@":""\)\+\i(?=,|\})/,
replace: "$self.renderUsername(arguments[0])"
}
},
],
Expand Down
9 changes: 7 additions & 2 deletions src/utils/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import { MessageDecorationFactory } from "@api/MessageDecorations";
import { MessageClickListener, MessageEditListener, MessageSendListener } from "@api/MessageEvents";
import { MessagePopoverButtonFactory } from "@api/MessagePopover";
import { FluxEvents } from "@webpack/types";
import { JSX } from "react";
import { ReactNode } from "react";
import { Promisable } from "type-fest";

// exists to export default definePlugin({...})
Expand Down Expand Up @@ -202,6 +202,10 @@ export const enum ReporterTestable {
FluxEvents = 1 << 4
}

export function defineDefault<T = any>(value: T) {
return value;
}

export const enum OptionType {
STRING,
NUMBER,
Expand Down Expand Up @@ -334,7 +338,8 @@ export interface IPluginOptionComponentProps {

export interface PluginSettingComponentDef {
type: OptionType.COMPONENT;
component: (props: IPluginOptionComponentProps) => JSX.Element;
component: (props: IPluginOptionComponentProps) => ReactNode | Promise<ReactNode>;
default?: any;
}

/** Maps a `PluginSettingDef` to its value type */
Expand Down
1 change: 1 addition & 0 deletions src/webpack/common/components.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ export const Forms = {
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 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:", {
Tooltip: filters.componentByCode("this.renderTooltip()]"),
Expand Down
32 changes: 31 additions & 1 deletion src/webpack/common/types/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
* 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, PropsWithRef, 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";
Expand Down Expand Up @@ -197,6 +197,36 @@ export type Switch = ComponentType<PropsWithChildren<{
tooltipNote?: ReactNode;
}>>;

export type CheckboxAligns = {
CENTER: "center";
TOP: "top";
};

export type CheckboxTypes = {
DEFAULT: "default";
INVERTED: "inverted";
GHOST: "ghost";
ROW: "row";
};

export type Checkbox = ComponentType<PropsWithChildren<{
value: boolean;
onChange(event: PointerEvent, value: boolean): void;

align?: "center" | "top";
disabled?: boolean;
displayOnly?: boolean;
readOnly?: boolean;
reverse?: boolean;
shape?: string;
size?: number;
type?: "default" | "inverted" | "ghost" | "row";
}>> & {
Shapes: Record<"BOX" | "ROUND" | "SMALL_BOX", string>;
Aligns: CheckboxAligns;
Types: CheckboxTypes;
};

export type Timestamp = ComponentType<PropsWithChildren<{
timestamp: Date;
isEdited?: boolean;
Expand Down
24 changes: 21 additions & 3 deletions src/webpack/webpack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { makeLazy, proxyLazy } from "@utils/lazy";
import { LazyComponent } from "@utils/lazyReact";
import { Logger } from "@utils/Logger";
import { canonicalizeMatch } from "@utils/patches";
import { FluxStore } from "@webpack/types";

import { traceFunction } from "../debug/Tracer";
import { Flux } from "./common";
Expand All @@ -37,6 +38,8 @@ export const onceReady = new Promise<void>(r => _resolveReady = r);
export let wreq: WebpackRequire;
export let cache: WebpackRequire["c"];

export const fluxStores: Record<string, FluxStore> = {};

export type FilterFn = (mod: any) => boolean;

export type PropsFilter = Array<string>;
Expand Down Expand Up @@ -428,9 +431,24 @@ export function findByCodeLazy(...code: CodeFilter) {
* Find a store by its displayName
*/
export function findStore(name: StoreNameFilter) {
const res = Flux.Store.getAll
? Flux.Store.getAll().find(filters.byStoreName(name))
: find(filters.byStoreName(name), { isIndirect: true });
let res = fluxStores[name] as any;
if (res == null) {
for (const store of Flux.Store.getAll?.() ?? []) {
const storeName = store.getName();

if (storeName === name) {
res = store;
}

if (fluxStores[storeName] == null) {
fluxStores[storeName] = store;
}
}

if (res == null) {
res = find(filters.byStoreName(name), { isIndirect: true });
}
}

if (!res)
handleModuleNotFound("findStore", name);
Expand Down
Loading