Merge remote-tracking branch 'upstream/dev' into dev

This commit is contained in:
thororen1234 2026-07-20 20:36:15 -04:00
commit a654b1ca06
No known key found for this signature in database
10 changed files with 46 additions and 38 deletions

View file

@ -545,6 +545,13 @@ export type ColorPicker = ComponentType<{
disabled?: boolean;
}>;
export type RoleMemberPopout = ComponentType<{
popoutProps: PopoutProps;
guildId: string;
channelId: string;
roleId: string;
}>;
export type ComponentSection = ComponentType<PropsWithChildren<{
heading?: string;
disabled?: boolean;

View file

@ -6,7 +6,7 @@
import { Devs } from "@utils/constants";
import definePlugin from "@utils/types";
import { setColorPicker, setCreateScroller, setNewCustomizationSection } from "@webpack/common";
import { setColorPicker, setCreateScroller, setNewCustomizationSection, setRoleMemberPopout } from "@webpack/common";
export default definePlugin({
name: "ConcatenatedComponentExtractor",
@ -38,10 +38,18 @@ export default definePlugin({
replace: "$&$self.setNewCustomizationSection($1);"
}
]
}
},
{
find: ".ROLE_MENTION)",
replacement: {
match: /function (\i)(?=.+?renderPopout:.{0,20}\1,\{guildId:\i,channelId:\i)/,
replace: "$self.setRoleMemberPopout($1);$&"
}
},
],
setCreateScroller,
setColorPicker,
setNewCustomizationSection
setNewCustomizationSection,
setRoleMemberPopout,
});

View file

@ -13,10 +13,9 @@ import { getCurrentChannel, getCurrentGuild, getIntlMessage, openImageModal } fr
import { isTruthy } from "@utils/guards";
import { classes } from "@utils/misc";
import definePlugin, { OptionType } from "@utils/types";
import { Guild, PopoutProps, Role } from "@vencord/discord-types";
import { Guild, Role } from "@vencord/discord-types";
import { findByCodeLazy, findByPropsLazy, findCssClassesLazy } from "@webpack";
import { ContextMenuApi, GuildRoleStore, Menu, PermissionStore, Popout, useRef } from "@webpack/common";
import { ComponentType } from "react";
import { ContextMenuApi, GuildRoleStore, Menu, PermissionStore, Popout, RoleMemberPopout, useRef } from "@webpack/common";
const GuildSettingsActions = findByPropsLazy("open", "selectRole", "updateGuild");
const MenuItemClasses = findCssClassesLazy("item", "labelContainer", "colorDefault", "label", "iconContainer");
@ -89,15 +88,6 @@ const settings = definePluginSettings({
}
});
interface RoleMemberPopoutProps {
popoutProps: PopoutProps;
guildId: string;
channelId: string;
roleId: string;
}
type RoleMemberPopout = ComponentType<RoleMemberPopoutProps>;
let RoleMemberPopout: RoleMemberPopout = () => null;
export function buildExtraRoleContextMenuItems(role: Role, guild: Guild, popoutRef?: React.RefObject<any>) {
if (!role) return { before: [], after: [] };
@ -224,13 +214,6 @@ export default definePlugin({
settings,
openRoleContextMenu,
patches: [
{
find: ".ROLE_MENTION)",
replacement: {
match: /function (\i)(?=.+?renderPopout:.{0,20}\1,\{guildId:\i,channelId:\i)/,
replace: "$self.RoleMembers=$1;$&"
}
},
// Conflicts with RoleColorEverywhere which changes the code at the end of our match. (and also uses same find & similar match)
// However, BetterRoleContext applies first (alphabetic order), so it's not an issue
{
@ -247,10 +230,6 @@ export default definePlugin({
DeveloperMode.updateSetting(true);
},
set RoleMembers(component: RoleMemberPopout) {
RoleMemberPopout = component;
},
contextMenus: {
"dev-context"(children, { id }: { id: string; }) {
const popoutRef = useRef(null);

View file

@ -16,7 +16,7 @@ import definePlugin, { OptionType } from "@utils/types";
import { Icon } from "@vencord/discord-types";
import { findCssClassesLazy } from "@webpack";
import { ComponentDispatch, FocusLock, Menu, useEffect, useRef } from "@webpack/common";
import type { HTMLAttributes, ReactNode } from "react";
import type { HTMLAttributes, ReactElement, ReactNode } from "react";
import fullHeightStyle from "./fullHeightContext.css?managed";
@ -192,7 +192,7 @@ export default definePlugin({
return <Layer {...props} />;
},
transformSettingsEntries(list) {
transformSettingsEntries(list: ReactElement<any>[]): ReactNode[] {
const items: ReactNode[] = [];
const SECTION_NAMES: Record<string, string> = {
user_section: getIntlMessage("USER_SETTINGS"),

View file

@ -116,7 +116,7 @@ export default definePlugin({
find: ".WIDGETS?",
replacement: [
{
match: /items:(\i),.+?(?=return\(0,\i\.jsxs?\)\("div)/,
match: /items:(\i),initialSection:\i,onClose:\i\}=\i.+?(?=return\(0,\i\.jsxs?\)\()/,
replace: "$&$self.pushSection($1,arguments[0].user);"
},
{

View file

@ -32,17 +32,22 @@
.vc-permviewer-modal-container {
width: 100%;
height: 100%;
height: min(760px, 80vh);
min-height: 0;
display: flex;
gap: 8px;
overflow: hidden;
}
.vc-permviewer-modal-list {
display: flex;
flex-direction: column;
gap: 2px;
flex: 0 0 200px;
max-height: 100%;
min-height: 0;
overflow: auto;
padding-right: 8px;
width: 200px;
}
.vc-permviewer-modal-list-item-btn {
@ -98,6 +103,11 @@
.vc-permviewer-modal-perms {
display: flex;
flex-direction: column;
flex: 1 1 0;
max-height: 100%;
min-width: 0;
min-height: 0;
overflow: auto;
padding-right: 8px;
}
@ -155,4 +165,4 @@
display: flex;
align-items: center;
gap: 4px;
}
}

View file

@ -212,7 +212,7 @@ export default definePlugin({
const sectionHeaderSizePx = sections.length * 40;
// (header heights + DM heights + DEFAULT_CHUNK_SIZE) * 1.5
// we multiply everything by 1.5 so it only gets unmounted after the entire list is off screen
return (sectionHeaderSizePx + sections.reduce((acc, v) => acc += v + 44, 0) + DEFAULT_CHUNK_SIZE) * 1.5;
return (sectionHeaderSizePx + sections.reduce((acc, v) => acc += v * 44, 0) + DEFAULT_CHUNK_SIZE) * 1.5;
},
isCategoryIndex(sectionIndex: number) {

View file

@ -200,8 +200,8 @@ export default definePlugin({
{
find: "return{avatarProps:{",
replacement: {
match: /(?<=avatarProps:(\i),eventHandlers:(\i).{0,100}?)return null==/,
replace: 'Object.assign($2,{style:{cursor:"pointer"},onClick:()=>$self.openAvatar($1.src)});$&',
match: /(?<=avatarProps:(\i),eventHandlers:\i.{0,100}?)return null==(?<=onOpenAvatar:(\i).+?)/,
replace: "$2&&=$self.openAvatar.bind(undefined,$1.src);$&",
}
},
// Banners

View file

@ -68,19 +68,23 @@ export const TabBar = waitForComponent("TabBar", filters.componentByCode("ref:th
// TODO: remake this component
export const Clickable = waitForComponent<t.Clickable>("Clickable", filters.componentByCode("this.context?this.renderNonInteractive():"));
export const Avatar = waitForComponent<t.Avatar>("Avatar", filters.componentByCode(".size-1.375*"));
export const UserSummaryItem = waitForComponent("UserSummaryItem", filters.componentByCode("defaultRenderUser", "showDefaultAvatarsForNullUsers"));
export let ColorPicker: t.ColorPicker = () => null;
export function setColorPicker(component: t.ColorPicker) {
ColorPicker = component;
}
export let RoleMemberPopout: t.RoleMemberPopout = () => null;
export function setRoleMemberPopout(component: t.RoleMemberPopout) {
RoleMemberPopout = component;
}
export let NewCustomizationSection: t.ComponentSection = () => null;
export function setNewCustomizationSection(component: t.ComponentSection) {
NewCustomizationSection = component;
}
export const UserSummaryItem = waitForComponent("UserSummaryItem", filters.componentByCode("defaultRenderUser", "showDefaultAvatarsForNullUsers"));
export let createScroller: ((scrollbarClassName: string, fadeClassName: string, customThemeClassName: string) => t.ScrollerThin) | undefined;
export function setCreateScroller(cs: NonNullable<typeof createScroller>) {
createScroller = cs;

View file

@ -55,7 +55,7 @@ export const stringMatches = (s: string, filter: CodeFilter) =>
);
export function makeClassNameRegex(className: string) {
return new RegExp(`(?:\\b|_)${escapeRegExp(className)}(?:\\b|_)`);
return new RegExp(`(?<=^|\\s)${escapeRegExp(className)}(?:_\\S*)?(?=$|\\s)`);
}
export const filters = {