Sadan's Patch Fixes

Co-Authored-By: sadan <117494111+sadan4@users.noreply.github.com>
This commit is contained in:
thororen 2026-10-01 21:09:14 -04:00
parent 96334432fa
commit 6c7fed05cd
No known key found for this signature in database
6 changed files with 84 additions and 22 deletions

View file

@ -416,3 +416,48 @@ export interface EmojiUtils {
triggerFullscreenAnimation(emoji: any, node: HTMLElement): void;
applyPlatformToThemedEmojiColorPalette(colors: any): any;
}
export interface OpenUserSettingsOpts {
/**
* a *sub*section of settings to navigate to
*
* to navigate to a top-level section, use the navigationTarget parameter of {@link SettingsRouter.openUserSettings} instead
*
* discord has an enum with all the possible values (go dig in the openUserSettings source)
*/
path?: string;
/**
* modal stacking behavior, defaults to "replaceAll"
*/
stackingBehavior?: "replaceAll" | "stack" | "replace";
// ... misc analytics options
}
export interface SettingsRouter {
openUserSettings(navigationTarget?: string, opts?: OpenUserSettingsOpts, onOpen?: () => void): Promise<void>;
}
export interface OpenUserProfileModalOpts {
userId: string;
guildId?: string | null;
originGuildId?: string | null;
channelId?: string | null;
messageId?: string | null;
roleId?: string | null;
sessionId?: unknown | null;
joinRequestId?: unknown;
tabSection?: unknown;
scrollTarget?: unknown;
hideRestrictedProfile?: boolean;
sourceAnalyticsLocations?: string[];
appContext?: unknown;
/**
* defaults to null
*/
customStatusPrompt?: unknown;
onModalOpen?: unknown;
}
export interface UserProfileModalActionCreators {
openUserProfileModal(opts: OpenUserProfileModalOpts): Promise<void>;
}

View file

@ -218,14 +218,22 @@ export default definePlugin({
settings,
openRoleContextMenu,
patches: [
// 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
// This patch is completely overwritten by RoleColorEverywhere, but RoleColorEverywhere handles it itself
// member list role headers (in threads)
{
find: 'tutorialId:"whos-online',
replacement: {
match: /(?<=#{intl::CHANNEL_MEMBERS_A11Y_LABEL}.{0,200}?"aria-hidden":!0,)children:.{0,200}?(?:—|\\u2014) ",\i\]\}\)\]/,
replace: "onContextMenu:e=>$self.openRoleContextMenu(e,arguments[0]),$&"
}
},
// member list role headers
{
find: "?null:new Intl.NumberFormat",
replacement: {
match: /(?<=#{intl::CHANNEL_MEMBERS_A11Y_LABEL},\{title:\i,count:\i\}\)\}\),\(0,\i\.jsxs\)\("div",\{)/,
replace: "onContextMenu:e=>$self.openRoleContextMenu(e,arguments[0]),"
}
}
],

View file

@ -16,9 +16,11 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { isPluginEnabled } from "@api/PluginManager";
import { definePluginSettings, Settings } from "@api/Settings";
import ErrorBoundary from "@components/ErrorBoundary";
import { getCustomColorString } from "@equicordplugins/customUserColors";
import BetterRoleContext from "@plugins/betterRoleContext";
import { Devs } from "@utils/constants";
import { Logger } from "@utils/Logger";
import definePlugin, { makeRange, OptionType } from "@utils/types";
@ -103,23 +105,24 @@ export default definePlugin({
],
predicate: () => settings.store.chatMentions
},
// Member List Role Headers
// Member List Role Headers (in threads)
{
find: 'tutorialId:"whos-online',
replacement: [
{
match: /(#{intl::CHANNEL_MEMBERS_A11Y_LABEL}.+}\):null,).{0,100}?(?:—|\\u2014) ",\i\]\}\)\]/,
match: /(#{intl::CHANNEL_MEMBERS_A11Y_LABEL}.{0,200}?}\):null,).{0,200}?(?:—|\\u2014) ",\i\]\}\)\]/,
replace: "$1$self.RoleGroupColor(arguments[0])]"
},
],
predicate: () => settings.store.memberList
},
// Member List Role Headers
{
find: "#{intl::THREAD_BROWSER_PRIVATE}",
find: "?null:new Intl.NumberFormat",
replacement: [
{
match: /children:\[\i," (?:—|\\u2014) ",\i\]/,
replace: "children:[$self.RoleGroupColor(arguments[0])]"
match: /\(0,\i\.jsx\)\("span",\{[^}]+\}\),null==\i\?null:\(0,\i\.jsxs\)\("span",\{children:\["\\xa0\\u2014 ",\i\]\}\)\]/,
replace: "$self.RoleGroupColor(arguments[0])]"
},
],
predicate: () => settings.store.memberList
@ -129,7 +132,7 @@ export default definePlugin({
find: "#{intl::GUEST_NAME_SUFFIX})]",
replacement: [
{
match: /#{intl::GUEST_NAME_SUFFIX}.{0,50}?"".{0,100}\](?=\}\))(?<=guildId:(\i),.+?user:(\i).+?)/,
match: /#{intl::GUEST_NAME_SUFFIX}.{0,50}?""\](?<=guildId:(\i),.+?user:(\i).+?)/,
replace: "$&,style:$self.getColorStyle($2.id,$1),"
}
],
@ -221,13 +224,18 @@ export default definePlugin({
RoleGroupColor: ErrorBoundary.wrap(({ id, count, title, guildId, label }: { id: string; count: number; title: string; guildId: string; label: string; }) => {
const role = GuildRoleStore.getRole(guildId, id);
// we overwrite the context menu event added by BetterRoleContext in our patch
const wantsRoleContext = isPluginEnabled(BetterRoleContext.name);
return (
<span style={{
color: role?.colorString,
fontWeight: "unset",
letterSpacing: ".05em"
}}>
<span
style={{
color: role?.colorString,
fontWeight: "unset",
letterSpacing: ".05em"
}}
onContextMenu={wantsRoleContext ? e => BetterRoleContext.openRoleContextMenu(e, { guildId, id }) : undefined}
>
{title ?? label} &mdash; {count}
</span>
);

View file

@ -15,9 +15,11 @@ export default definePlugin({
patches: [
{
find: ".stickers,previewSticker:",
// This function is a util func from another module
// but it only has once use here so it's inlined
find: ".CREATE_FORUM_POST||function(",
replacement: {
match: /if\(\i\.\i\.getUploadCount/,
match: /(?<=\){)if\(\i\.\i\.getUploadCount/,
replace: "return true;$&",
}
}

View file

@ -186,10 +186,6 @@ export async function openUserProfile(id: string) {
userId: id,
guildId,
channelId: SelectedChannelStore.getChannelId(),
analyticsLocation: {
page: guildId ? "Guild Channel" : "DM Channel",
section: "Profile Popout"
}
});
}

View file

@ -169,8 +169,9 @@ export const ChannelRouter: t.ChannelRouter = mapMangledModuleLazy('"Thread must
transitionToThread: filters.byCode('"Thread must have a parent ID."')
});
export let SettingsRouter: any;
waitFor(["openUserSettings", "USER_SETTINGS_MODAL_KEY"], m => SettingsRouter = m);
export const SettingsRouter: t.SettingsRouter = mapMangledModuleLazy('type:"USER_SETTINGS_MODAL_OPEN"', {
openUserSettings: filters.byCode('type:"USER_SETTINGS_MODAL_OPEN"')
});
export const PermissionsBits: t.PermissionsBits = findLazy(m => typeof m.ADMINISTRATOR === "bigint");
@ -184,7 +185,9 @@ export const { zustandPersist } = mapMangledModuleLazy(".onRehydrateStorage)?",
export const MessageActions = findByPropsLazy("editMessage", "sendMessage");
export const MessageCache = findByPropsLazy("clearCache", "_channelMessages");
export const UserProfileActions = findByPropsLazy("openUserProfileModal", "closeUserProfileModal");
export const UserProfileActions: t.UserProfileModalActionCreators = mapMangledModuleLazy(".log(`Failed to fetch profile for $", {
openUserProfileModal: filters.byCode('type:"USER_PROFILE_MODAL_OPEN"')
});
export const InviteActions = findByPropsLazy("resolveInvite");
export const ChannelActionCreators = findByPropsLazy("openPrivateChannel");