Merge remote-tracking branch 'upstream/main'
This commit is contained in:
commit
c7489bfa88
32 changed files with 182 additions and 472 deletions
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "vencord",
|
"name": "vencord",
|
||||||
"private": "true",
|
"private": "true",
|
||||||
"version": "1.9.7",
|
"version": "1.9.8",
|
||||||
"description": "The cutest Discord client mod",
|
"description": "The cutest Discord client mod",
|
||||||
"homepage": "https://github.com/Vendicated/Vencord#readme",
|
"homepage": "https://github.com/Vendicated/Vencord#readme",
|
||||||
"bugs": {
|
"bugs": {
|
||||||
|
|
|
@ -134,7 +134,7 @@ export async function loadLazyChunks() {
|
||||||
const allChunks = [] as number[];
|
const allChunks = [] as number[];
|
||||||
|
|
||||||
// Matches "id" or id:
|
// Matches "id" or id:
|
||||||
for (const currentMatch of wreq!.u.toString().matchAll(/(?:"([\deE]+?)")|(?:([\deE]+?):)/g)) {
|
for (const currentMatch of wreq!.u.toString().matchAll(/(?:"([\deE]+?)"(?![,}]))|(?:([\deE]+?):)/g)) {
|
||||||
const id = currentMatch[1] ?? currentMatch[2];
|
const id = currentMatch[1] ?? currentMatch[2];
|
||||||
if (id == null) continue;
|
if (id == null) continue;
|
||||||
|
|
||||||
|
|
|
@ -62,34 +62,6 @@ export default definePlugin({
|
||||||
authors: [Devs.Megu, Devs.Ven, Devs.TheSun],
|
authors: [Devs.Megu, Devs.Ven, Devs.TheSun],
|
||||||
required: true,
|
required: true,
|
||||||
patches: [
|
patches: [
|
||||||
/* Patch the badge list component on user profiles */
|
|
||||||
{
|
|
||||||
find: 'id:"premium",',
|
|
||||||
replacement: [
|
|
||||||
{
|
|
||||||
match: /&&(\i)\.push\(\{id:"premium".+?\}\);/,
|
|
||||||
replace: "$&$1.unshift(...$self.getBadges(arguments[0]));",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
// alt: "", aria-hidden: false, src: originalSrc
|
|
||||||
match: /alt:" ","aria-hidden":!0,src:(?=(\i)\.src)/,
|
|
||||||
// ...badge.props, ..., src: badge.image ?? ...
|
|
||||||
replace: "...$1.props,$& $1.image??"
|
|
||||||
},
|
|
||||||
// replace their component with ours if applicable
|
|
||||||
{
|
|
||||||
match: /(?<=text:(\i)\.description,spacing:12,.{0,50})children:/,
|
|
||||||
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) }),$&"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
|
|
||||||
/* new profiles */
|
|
||||||
{
|
{
|
||||||
find: ".FULL_SIZE]:26",
|
find: ".FULL_SIZE]:26",
|
||||||
replacement: {
|
replacement: {
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
# AutomodContext
|
|
||||||
|
|
||||||
Allows you to jump to the messages surrounding an automod hit
|
|
||||||
|
|
||||||
![Visualization](https://github.com/Vendicated/Vencord/assets/61953774/d13740c8-2062-4553-b975-82fd3d6cc08b)
|
|
|
@ -1,73 +0,0 @@
|
||||||
/*
|
|
||||||
* Vencord, a Discord client mod
|
|
||||||
* Copyright (c) 2024 Vendicated and contributors
|
|
||||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
*/
|
|
||||||
|
|
||||||
import ErrorBoundary from "@components/ErrorBoundary";
|
|
||||||
import { Devs } from "@utils/constants";
|
|
||||||
import definePlugin from "@utils/types";
|
|
||||||
import { findByPropsLazy } from "@webpack";
|
|
||||||
import { Button, ChannelStore, Text } from "@webpack/common";
|
|
||||||
|
|
||||||
const { selectChannel } = findByPropsLazy("selectChannel", "selectVoiceChannel");
|
|
||||||
|
|
||||||
function jumpToMessage(channelId: string, messageId: string) {
|
|
||||||
const guildId = ChannelStore.getChannel(channelId)?.guild_id;
|
|
||||||
|
|
||||||
selectChannel({
|
|
||||||
guildId,
|
|
||||||
channelId,
|
|
||||||
messageId,
|
|
||||||
jumpType: "INSTANT"
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function findChannelId(message: any): string | null {
|
|
||||||
const { embeds: [embed] } = message;
|
|
||||||
const channelField = embed.fields.find(({ rawName }) => rawName === "channel_id");
|
|
||||||
|
|
||||||
if (!channelField) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return channelField.rawValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
export default definePlugin({
|
|
||||||
name: "AutomodContext",
|
|
||||||
description: "Allows you to jump to the messages surrounding an automod hit.",
|
|
||||||
authors: [Devs.JohnyTheCarrot],
|
|
||||||
|
|
||||||
patches: [
|
|
||||||
{
|
|
||||||
find: ".Messages.GUILD_AUTOMOD_REPORT_ISSUES",
|
|
||||||
replacement: {
|
|
||||||
match: /\.Messages\.ACTIONS.+?}\)(?=,(\(0.{0,40}\.dot.*?}\)),)/,
|
|
||||||
replace: (m, dot) => `${m},${dot},$self.renderJumpButton({message:arguments[0].message})`
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
|
|
||||||
renderJumpButton: ErrorBoundary.wrap(({ message }: { message: any; }) => {
|
|
||||||
const channelId = findChannelId(message);
|
|
||||||
|
|
||||||
if (!channelId) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Button
|
|
||||||
style={{ padding: "2px 8px" }}
|
|
||||||
look={Button.Looks.LINK}
|
|
||||||
size={Button.Sizes.SMALL}
|
|
||||||
color={Button.Colors.LINK}
|
|
||||||
onClick={() => jumpToMessage(channelId, message.id)}
|
|
||||||
>
|
|
||||||
<Text color="text-link" variant="text-xs/normal">
|
|
||||||
Jump to Surrounding
|
|
||||||
</Text>
|
|
||||||
</Button>
|
|
||||||
);
|
|
||||||
}, { noop: true })
|
|
||||||
});
|
|
|
@ -17,13 +17,9 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { definePluginSettings, Settings } from "@api/Settings";
|
import { definePluginSettings, Settings } from "@api/Settings";
|
||||||
import ErrorBoundary from "@components/ErrorBoundary";
|
|
||||||
import { Devs } from "@utils/constants";
|
import { Devs } from "@utils/constants";
|
||||||
import { canonicalizeMatch } from "@utils/patches";
|
import { canonicalizeMatch } from "@utils/patches";
|
||||||
import definePlugin, { OptionType } from "@utils/types";
|
import definePlugin, { OptionType } from "@utils/types";
|
||||||
import { findByPropsLazy } from "@webpack";
|
|
||||||
|
|
||||||
const UserPopoutSectionCssClasses = findByPropsLazy("section", "lastSection");
|
|
||||||
|
|
||||||
const settings = definePluginSettings({
|
const settings = definePluginSettings({
|
||||||
hide: {
|
hide: {
|
||||||
|
@ -72,23 +68,9 @@ export default definePlugin({
|
||||||
match: /\.NOTE_PLACEHOLDER,/,
|
match: /\.NOTE_PLACEHOLDER,/,
|
||||||
replace: "$&spellCheck:!$self.noSpellCheck,"
|
replace: "$&spellCheck:!$self.noSpellCheck,"
|
||||||
}
|
}
|
||||||
},
|
|
||||||
{
|
|
||||||
find: ".popularApplicationCommandIds,",
|
|
||||||
replacement: {
|
|
||||||
match: /lastSection:(!?\i)}\),/,
|
|
||||||
replace: "$&$self.patchPadding({lastSection:$1}),"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
||||||
patchPadding: ErrorBoundary.wrap(({ lastSection }) => {
|
|
||||||
if (!lastSection) return null;
|
|
||||||
return (
|
|
||||||
<div className={UserPopoutSectionCssClasses.lastSection} ></div>
|
|
||||||
);
|
|
||||||
}),
|
|
||||||
|
|
||||||
get noSpellCheck() {
|
get noSpellCheck() {
|
||||||
return settings.store.noSpellCheck;
|
return settings.store.noSpellCheck;
|
||||||
}
|
}
|
||||||
|
|
|
@ -121,7 +121,7 @@ export default definePlugin({
|
||||||
{
|
{
|
||||||
find: "UserProfileStore",
|
find: "UserProfileStore",
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /(?<=getUserProfile\(\i\){return )(\i\[\i\])/,
|
match: /(?<=getUserProfile\(\i\){return )(.+?)(?=})/,
|
||||||
replace: "$self.colorDecodeHook($1)"
|
replace: "$self.colorDecodeHook($1)"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -16,7 +16,6 @@ const containerWrapper = findByPropsLazy("memberSinceWrapper");
|
||||||
const container = findByPropsLazy("memberSince");
|
const container = findByPropsLazy("memberSince");
|
||||||
const getCreatedAtDate = findByCodeLazy('month:"short",day:"numeric"');
|
const getCreatedAtDate = findByCodeLazy('month:"short",day:"numeric"');
|
||||||
const locale = findByPropsLazy("getLocale");
|
const locale = findByPropsLazy("getLocale");
|
||||||
const lastSection = findByPropsLazy("lastSection");
|
|
||||||
const section = findLazy((m: any) => m.section !== void 0 && m.heading !== void 0 && Object.values(m).length === 2);
|
const section = findLazy((m: any) => m.section !== void 0 && m.heading !== void 0 && Object.values(m).length === 2);
|
||||||
|
|
||||||
export default definePlugin({
|
export default definePlugin({
|
||||||
|
@ -24,31 +23,7 @@ export default definePlugin({
|
||||||
description: "Shows when you became friends with someone in the user popout",
|
description: "Shows when you became friends with someone in the user popout",
|
||||||
authors: [Devs.Elvyra, Devs.Antti],
|
authors: [Devs.Elvyra, Devs.Antti],
|
||||||
patches: [
|
patches: [
|
||||||
// User popup - old layout
|
// DM User Sidebar
|
||||||
{
|
|
||||||
find: ".USER_PROFILE}};return",
|
|
||||||
replacement: {
|
|
||||||
match: /,{userId:(\i.id).{0,30}}\)/,
|
|
||||||
replace: "$&,$self.friendsSinceOld({ userId: $1 })"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// DM User Sidebar - old layout
|
|
||||||
{
|
|
||||||
find: ".PROFILE_PANEL,",
|
|
||||||
replacement: {
|
|
||||||
match: /,{userId:([^,]+?)}\)/,
|
|
||||||
replace: "$&,$self.friendsSinceOld({ userId: $1 })"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// User Profile Modal - old layout
|
|
||||||
{
|
|
||||||
find: ".userInfoSectionHeader,",
|
|
||||||
replacement: {
|
|
||||||
match: /(\.Messages\.USER_PROFILE_MEMBER_SINCE.+?userId:(.+?),textClassName:)(\i\.userInfoText)}\)/,
|
|
||||||
replace: (_, rest, userId, textClassName) => `${rest}!$self.getFriendSince(${userId}) ? ${textClassName} : void 0 }), $self.friendsSinceOld({ userId: ${userId}, textClassName: ${textClassName} })`
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// DM User Sidebar - new layout
|
|
||||||
{
|
{
|
||||||
find: ".PANEL}),nicknameIcons",
|
find: ".PANEL}),nicknameIcons",
|
||||||
replacement: {
|
replacement: {
|
||||||
|
@ -56,7 +31,7 @@ export default definePlugin({
|
||||||
replace: "$&,$self.friendsSinceNew({userId:$1,isSidebar:true})"
|
replace: "$&,$self.friendsSinceNew({userId:$1,isSidebar:true})"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// User Profile Modal - new layout
|
// User Profile Modal
|
||||||
{
|
{
|
||||||
find: "action:\"PRESS_APP_CONNECTION\"",
|
find: "action:\"PRESS_APP_CONNECTION\"",
|
||||||
replacement: {
|
replacement: {
|
||||||
|
@ -77,39 +52,6 @@ export default definePlugin({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
friendsSinceOld: ErrorBoundary.wrap(({ userId, textClassName }: { userId: string; textClassName?: string; }) => {
|
|
||||||
if (!RelationshipStore.isFriend(userId)) return null;
|
|
||||||
|
|
||||||
const friendsSince = RelationshipStore.getSince(userId);
|
|
||||||
if (!friendsSince) return null;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className={lastSection.section}>
|
|
||||||
<Heading variant="eyebrow">
|
|
||||||
Friends Since
|
|
||||||
</Heading>
|
|
||||||
|
|
||||||
<div className={containerWrapper.memberSinceWrapper}>
|
|
||||||
{!!getCurrentChannel()?.guild_id && (
|
|
||||||
<svg
|
|
||||||
aria-hidden="true"
|
|
||||||
width="16"
|
|
||||||
height="16"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
fill="var(--interactive-normal)"
|
|
||||||
>
|
|
||||||
<path d="M13 10a4 4 0 1 0 0-8 4 4 0 0 0 0 8Z" />
|
|
||||||
<path d="M3 5v-.75C3 3.56 3.56 3 4.25 3s1.24.56 1.33 1.25C6.12 8.65 9.46 12 13 12h1a8 8 0 0 1 8 8 2 2 0 0 1-2 2 .21.21 0 0 1-.2-.15 7.65 7.65 0 0 0-1.32-2.3c-.15-.2-.42-.06-.39.17l.25 2c.02.15-.1.28-.25.28H9a2 2 0 0 1-2-2v-2.22c0-1.57-.67-3.05-1.53-4.37A15.85 15.85 0 0 1 3 5Z" />
|
|
||||||
</svg>
|
|
||||||
)}
|
|
||||||
<Text variant="text-sm/normal" className={textClassName}>
|
|
||||||
{getCreatedAtDate(friendsSince, locale.getLocale())}
|
|
||||||
</Text>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}, { noop: true }),
|
|
||||||
|
|
||||||
friendsSinceNew: ErrorBoundary.wrap(({ userId, isSidebar }: { userId: string; isSidebar: boolean; }) => {
|
friendsSinceNew: ErrorBoundary.wrap(({ userId, isSidebar }: { userId: string; isSidebar: boolean; }) => {
|
||||||
if (!RelationshipStore.isFriend(userId)) return null;
|
if (!RelationshipStore.isFriend(userId)) return null;
|
||||||
|
|
||||||
|
|
|
@ -5,9 +5,10 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { getCurrentChannel } from "@utils/discord";
|
import { getCurrentChannel } from "@utils/discord";
|
||||||
|
import { isObjectEmpty } from "@utils/misc";
|
||||||
import { SelectedChannelStore, Tooltip, useEffect, useStateFromStores } from "@webpack/common";
|
import { SelectedChannelStore, Tooltip, useEffect, useStateFromStores } from "@webpack/common";
|
||||||
|
|
||||||
import { ChannelMemberStore, cl, GuildMemberCountStore, numberFormat } from ".";
|
import { ChannelMemberStore, cl, GuildMemberCountStore, numberFormat, ThreadMemberListStore } from ".";
|
||||||
import { OnlineMemberCountStore } from "./OnlineMemberCountStore";
|
import { OnlineMemberCountStore } from "./OnlineMemberCountStore";
|
||||||
|
|
||||||
export function MemberCount({ isTooltip, tooltipGuildId }: { isTooltip?: true; tooltipGuildId?: string; }) {
|
export function MemberCount({ isTooltip, tooltipGuildId }: { isTooltip?: true; tooltipGuildId?: string; }) {
|
||||||
|
@ -30,10 +31,19 @@ export function MemberCount({ isTooltip, tooltipGuildId }: { isTooltip?: true; t
|
||||||
() => ChannelMemberStore.getProps(guildId, currentChannel?.id)
|
() => ChannelMemberStore.getProps(guildId, currentChannel?.id)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const threadGroups = useStateFromStores(
|
||||||
|
[ThreadMemberListStore],
|
||||||
|
() => ThreadMemberListStore.getMemberListSections(currentChannel.id)
|
||||||
|
);
|
||||||
|
|
||||||
if (!isTooltip && (groups.length >= 1 || groups[0].id !== "unknown")) {
|
if (!isTooltip && (groups.length >= 1 || groups[0].id !== "unknown")) {
|
||||||
onlineCount = groups.reduce((total, curr) => total + (curr.id === "offline" ? 0 : curr.count), 0);
|
onlineCount = groups.reduce((total, curr) => total + (curr.id === "offline" ? 0 : curr.count), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!isTooltip && threadGroups && !isObjectEmpty(threadGroups)) {
|
||||||
|
onlineCount = Object.values(threadGroups).reduce((total, curr) => total + (curr.sectionId === "offline" ? 0 : curr.userIds.length), 0);
|
||||||
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
OnlineMemberCountStore.ensureCount(guildId);
|
OnlineMemberCountStore.ensureCount(guildId);
|
||||||
}, [guildId]);
|
}, [guildId]);
|
||||||
|
|
|
@ -32,6 +32,10 @@ export const GuildMemberCountStore = findStoreLazy("GuildMemberCountStore") as F
|
||||||
export const ChannelMemberStore = findStoreLazy("ChannelMemberStore") as FluxStore & {
|
export const ChannelMemberStore = findStoreLazy("ChannelMemberStore") as FluxStore & {
|
||||||
getProps(guildId: string, channelId: string): { groups: { count: number; id: string; }[]; };
|
getProps(guildId: string, channelId: string): { groups: { count: number; id: string; }[]; };
|
||||||
};
|
};
|
||||||
|
export const ThreadMemberListStore = findStoreLazy("ThreadMemberListStore") as FluxStore & {
|
||||||
|
getMemberListSections(channelId: string): { [sectionId: string]: { sectionId: string; userIds: string[]; }; };
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
const settings = definePluginSettings({
|
const settings = definePluginSettings({
|
||||||
toolTip: {
|
toolTip: {
|
||||||
|
|
|
@ -247,9 +247,9 @@ export default definePlugin({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
find: 'copyMetaData:"User Tag"',
|
find: ".Messages.USER_PROFILE_PRONOUNS",
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /(?=,botClass:)/,
|
match: /(?=,hideBotTag:!0)/,
|
||||||
replace: ",moreTags_channelId:arguments[0].moreTags_channelId"
|
replace: ",moreTags_channelId:arguments[0].moreTags_channelId"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -58,20 +58,6 @@ export default definePlugin({
|
||||||
authors: [Devs.amia],
|
authors: [Devs.amia],
|
||||||
|
|
||||||
patches: [
|
patches: [
|
||||||
{
|
|
||||||
find: ".Messages.MUTUAL_GUILDS_WITH_END_COUNT", // Note: the module is lazy-loaded
|
|
||||||
replacement: {
|
|
||||||
match: /(?<=\.tabBarItem.{0,50}MUTUAL_GUILDS.+?}\),)(?=.+?(\(0,\i\.jsxs?\)\(.{0,100}id:))/,
|
|
||||||
replace: '$self.isBotOrSelf(arguments[0].user)?null:$1"MUTUAL_GDMS",children:$self.getMutualGDMCountText(arguments[0].user)}),'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
find: ".USER_INFO_CONNECTIONS:case",
|
|
||||||
replacement: {
|
|
||||||
match: /(?<={user:(\i),onClose:(\i)}\);)(?=case \i\.\i\.MUTUAL_FRIENDS)/,
|
|
||||||
replace: "case \"MUTUAL_GDMS\":return $self.renderMutualGDMs({user: $1, onClose: $2});"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
find: ".MUTUAL_FRIENDS?(",
|
find: ".MUTUAL_FRIENDS?(",
|
||||||
replacement: [
|
replacement: [
|
||||||
|
@ -87,9 +73,6 @@ export default definePlugin({
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
||||||
isBotOrSelf,
|
|
||||||
getMutualGDMCountText,
|
|
||||||
|
|
||||||
pushSection(sections: any[], user: User) {
|
pushSection(sections: any[], user: User) {
|
||||||
if (isBotOrSelf(user) || sections[IS_PATCHED]) return;
|
if (isBotOrSelf(user) || sections[IS_PATCHED]) return;
|
||||||
|
|
||||||
|
|
3
src/plugins/noMaskedUrlPaste/README.md
Normal file
3
src/plugins/noMaskedUrlPaste/README.md
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
# NoMaskedUrlPaste
|
||||||
|
|
||||||
|
Pasting a link while you have text selected will NOT paste your link as a masked link.
|
23
src/plugins/noMaskedUrlPaste/index.ts
Normal file
23
src/plugins/noMaskedUrlPaste/index.ts
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
/*
|
||||||
|
* Vencord, a Discord client mod
|
||||||
|
* Copyright (c) 2023 Vendicated and contributors
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { Devs } from "@utils/constants.js";
|
||||||
|
import definePlugin from "@utils/types";
|
||||||
|
|
||||||
|
export default definePlugin({
|
||||||
|
name: "NoMaskedUrlPaste",
|
||||||
|
authors: [Devs.CatNoir],
|
||||||
|
description: "Pasting a link while having text selected will not paste as masked URL",
|
||||||
|
patches: [
|
||||||
|
{
|
||||||
|
find: ".selection,preventEmojiSurrogates:",
|
||||||
|
replacement: {
|
||||||
|
match: /if\(null!=\i.selection&&\i.\i.isExpanded\(\i.selection\)\)/,
|
||||||
|
replace: "if(false)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
});
|
|
@ -18,36 +18,21 @@
|
||||||
|
|
||||||
import { Devs } from "@utils/constants";
|
import { Devs } from "@utils/constants";
|
||||||
import definePlugin from "@utils/types";
|
import definePlugin from "@utils/types";
|
||||||
|
import { UserStore } from "@webpack/common";
|
||||||
|
|
||||||
export default definePlugin({
|
export default definePlugin({
|
||||||
name: "NoProfileThemes",
|
name: "NoProfileThemes",
|
||||||
description: "Completely removes Nitro profile themes",
|
description: "Completely removes Nitro profile themes from everyone but yourself",
|
||||||
authors: [Devs.TheKodeToad],
|
authors: [Devs.TheKodeToad],
|
||||||
patches: [
|
patches: [
|
||||||
{
|
|
||||||
find: ".NITRO_BANNER,",
|
|
||||||
replacement: {
|
|
||||||
// = isPremiumAtLeast(user.premiumType, TIER_2)
|
|
||||||
match: /=(?=\i\.\i\.isPremiumAtLeast\(null==(\i))/,
|
|
||||||
// = user.banner && isPremiumAtLeast(user.premiumType, TIER_2)
|
|
||||||
replace: "=(arguments[0]?.bannerSrc||$1?.banner)&&"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
find: ".avatarPositionPremiumNoBanner,default:",
|
|
||||||
replacement: {
|
|
||||||
// premiumUserWithoutBanner: foo().avatarPositionPremiumNoBanner, default: foo().avatarPositionNormal
|
|
||||||
match: /\.avatarPositionPremiumNoBanner(?=,default:\i\.(\i))/,
|
|
||||||
// premiumUserWithoutBanner: foo().avatarPositionNormal...
|
|
||||||
replace: ".$1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
find: "hasThemeColors(){",
|
find: "hasThemeColors(){",
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /get canUsePremiumProfileCustomization\(\){return /,
|
match: /get canUsePremiumProfileCustomization\(\){return /,
|
||||||
replace: "$&false &&"
|
replace: "$&$self.isCurrentUser(this.userId)&&"
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
]
|
],
|
||||||
|
|
||||||
|
isCurrentUser: (userId: string) => userId === UserStore.getCurrentUser()?.id,
|
||||||
});
|
});
|
||||||
|
|
|
@ -35,15 +35,17 @@ interface UserPermission {
|
||||||
|
|
||||||
type UserPermissions = Array<UserPermission>;
|
type UserPermissions = Array<UserPermission>;
|
||||||
|
|
||||||
const Classes = proxyLazyWebpack(() =>
|
const { RoleRootClasses, RoleClasses, RoleBorderClasses } = proxyLazyWebpack(() => {
|
||||||
Object.assign({}, ...findBulk(
|
const [RoleRootClasses, RoleClasses, RoleBorderClasses] = findBulk(
|
||||||
filters.byProps("roles", "rolePill", "rolePillBorder"),
|
filters.byProps("root", "showMoreButton", "collapseButton"),
|
||||||
filters.byProps("roleCircle", "dotBorderBase", "dotBorderColor"),
|
filters.byProps("role", "roleCircle", "roleName"),
|
||||||
filters.byProps("roleNameOverflow", "root", "roleName", "roleRemoveButton")
|
filters.byProps("roleCircle", "dot", "dotBorderColor")
|
||||||
))
|
) as Record<string, string>[];
|
||||||
) as Record<"roles" | "rolePill" | "rolePillBorder" | "desaturateUserColors" | "flex" | "alignCenter" | "justifyCenter" | "svg" | "background" | "dot" | "dotBorderColor" | "roleCircle" | "dotBorderBase" | "flex" | "alignCenter" | "justifyCenter" | "wrap" | "root" | "role" | "roleRemoveButton" | "roleDot" | "roleFlowerStar" | "roleRemoveIcon" | "roleRemoveIconFocused" | "roleVerifiedIcon" | "roleName" | "roleNameOverflow" | "actionButton" | "overflowButton" | "addButton" | "addButtonIcon" | "overflowRolesPopout" | "overflowRolesPopoutArrowWrapper" | "overflowRolesPopoutArrow" | "popoutBottom" | "popoutTop" | "overflowRolesPopoutHeader" | "overflowRolesPopoutHeaderIcon" | "overflowRolesPopoutHeaderText" | "roleIcon", string>;
|
|
||||||
|
|
||||||
function UserPermissionsComponent({ guild, guildMember, showBorder, forceOpen = false }: { guild: Guild; guildMember: GuildMember; showBorder: boolean; forceOpen?: boolean; }) {
|
return { RoleRootClasses, RoleClasses, RoleBorderClasses };
|
||||||
|
});
|
||||||
|
|
||||||
|
function UserPermissionsComponent({ guild, guildMember, forceOpen = false }: { guild: Guild; guildMember: GuildMember; forceOpen?: boolean; }) {
|
||||||
const stns = settings.use(["permissionsSortOrder"]);
|
const stns = settings.use(["permissionsSortOrder"]);
|
||||||
|
|
||||||
const [rolePermissions, userPermissions] = useMemo(() => {
|
const [rolePermissions, userPermissions] = useMemo(() => {
|
||||||
|
@ -91,8 +93,6 @@ function UserPermissionsComponent({ guild, guildMember, showBorder, forceOpen =
|
||||||
return [rolePermissions, userPermissions];
|
return [rolePermissions, userPermissions];
|
||||||
}, [stns.permissionsSortOrder]);
|
}, [stns.permissionsSortOrder]);
|
||||||
|
|
||||||
const { root, role, roleRemoveButton, roleNameOverflow, roles, rolePill, rolePillBorder, roleCircle, roleName } = Classes;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ExpandableHeader
|
<ExpandableHeader
|
||||||
forceOpen={forceOpen}
|
forceOpen={forceOpen}
|
||||||
|
@ -130,18 +130,18 @@ function UserPermissionsComponent({ guild, guildMember, showBorder, forceOpen =
|
||||||
</Tooltip>)
|
</Tooltip>)
|
||||||
]}>
|
]}>
|
||||||
{userPermissions.length > 0 && (
|
{userPermissions.length > 0 && (
|
||||||
<div className={classes(root, roles)}>
|
<div className={classes(RoleRootClasses.root)}>
|
||||||
{userPermissions.map(({ permission, roleColor }) => (
|
{userPermissions.map(({ permission, roleColor }) => (
|
||||||
<div className={classes(role, rolePill, showBorder ? rolePillBorder : null)}>
|
<div className={classes(RoleClasses.role)}>
|
||||||
<div className={roleRemoveButton}>
|
<div className={RoleClasses.roleRemoveButton}>
|
||||||
<span
|
<span
|
||||||
className={roleCircle}
|
className={classes(RoleBorderClasses.roleCircle, RoleClasses.roleCircle)}
|
||||||
style={{ backgroundColor: roleColor }}
|
style={{ backgroundColor: roleColor }}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className={roleName}>
|
<div className={RoleClasses.roleName}>
|
||||||
<Text
|
<Text
|
||||||
className={roleNameOverflow}
|
className={RoleClasses.roleNameOverflow}
|
||||||
variant="text-xs/medium"
|
variant="text-xs/medium"
|
||||||
>
|
>
|
||||||
{permission}
|
{permission}
|
||||||
|
|
|
@ -169,13 +169,6 @@ export default definePlugin({
|
||||||
settings,
|
settings,
|
||||||
|
|
||||||
patches: [
|
patches: [
|
||||||
{
|
|
||||||
find: ".popularApplicationCommandIds,",
|
|
||||||
replacement: {
|
|
||||||
match: /showBorder:(.{0,60})}\),(?<=guild:(\i),guildMember:(\i),.+?)/,
|
|
||||||
replace: (m, showBoder, guild, guildMember) => `${m}$self.UserPermissions(${guild},${guildMember},${showBoder}),`
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
find: ".VIEW_ALL_ROLES,",
|
find: ".VIEW_ALL_ROLES,",
|
||||||
replacement: {
|
replacement: {
|
||||||
|
@ -185,16 +178,13 @@ export default definePlugin({
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
||||||
UserPermissions: (guild: Guild, guildMember: GuildMember | undefined, showBorder: boolean) =>
|
|
||||||
!!guildMember && <UserPermissions guild={guild} guildMember={guildMember} showBorder={showBorder} />,
|
|
||||||
|
|
||||||
ViewPermissionsButton: ErrorBoundary.wrap(({ guild, guildMember }: { guild: Guild; guildMember: GuildMember; }) => (
|
ViewPermissionsButton: ErrorBoundary.wrap(({ guild, guildMember }: { guild: Guild; guildMember: GuildMember; }) => (
|
||||||
<Popout
|
<Popout
|
||||||
position="bottom"
|
position="bottom"
|
||||||
align="center"
|
align="center"
|
||||||
renderPopout={() => (
|
renderPopout={() => (
|
||||||
<Dialog className={PopoutClasses.container} style={{ width: "500px" }}>
|
<Dialog className={PopoutClasses.container} style={{ width: "500px" }}>
|
||||||
<UserPermissions guild={guild} guildMember={guildMember} showBorder forceOpen />
|
<UserPermissions guild={guild} guildMember={guildMember} forceOpen />
|
||||||
</Dialog>
|
</Dialog>
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
|
|
|
@ -26,11 +26,6 @@ import { CompactPronounsChatComponentWrapper, PronounsChatComponentWrapper } fro
|
||||||
import { useProfilePronouns } from "./pronoundbUtils";
|
import { useProfilePronouns } from "./pronoundbUtils";
|
||||||
import { settings } from "./settings";
|
import { settings } from "./settings";
|
||||||
|
|
||||||
const PRONOUN_TOOLTIP_PATCH = {
|
|
||||||
match: /text:(.{0,10}.Messages\.USER_PROFILE_PRONOUNS)(?=,)/,
|
|
||||||
replace: '$& + (typeof vcPronounSource !== "undefined" ? ` (${vcPronounSource})` : "")'
|
|
||||||
};
|
|
||||||
|
|
||||||
export default definePlugin({
|
export default definePlugin({
|
||||||
name: "PronounDB",
|
name: "PronounDB",
|
||||||
authors: [Devs.Tyman, Devs.TheKodeToad, Devs.Ven, Devs.Elvyra],
|
authors: [Devs.Tyman, Devs.TheKodeToad, Devs.Ven, Devs.Elvyra],
|
||||||
|
@ -51,26 +46,23 @@ export default definePlugin({
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
// Patch the profile popout username header to use our pronoun hook instead of Discord's pronouns
|
|
||||||
{
|
{
|
||||||
find: ".pronouns,children",
|
find: ".Messages.USER_PROFILE_PRONOUNS",
|
||||||
|
group: true,
|
||||||
replacement: [
|
replacement: [
|
||||||
{
|
{
|
||||||
match: /{user:(\i),[^}]*,pronouns:(\i),[^}]*}=\i.*?;(?=return)/,
|
match: /\.PANEL},/,
|
||||||
replace: "$&let vcPronounSource;[$2,vcPronounSource]=$self.useProfilePronouns($1.id);"
|
replace: "$&[vcPronoun,vcPronounSource,vcHasPendingPronouns]=$self.useProfilePronouns(arguments[0].user?.id),"
|
||||||
},
|
},
|
||||||
PRONOUN_TOOLTIP_PATCH
|
|
||||||
]
|
|
||||||
},
|
|
||||||
// Patch the profile modal username header to use our pronoun hook instead of Discord's pronouns
|
|
||||||
{
|
{
|
||||||
find: ".nameTagSmall)",
|
match: /text:\i\.\i.Messages.USER_PROFILE_PRONOUNS/,
|
||||||
replacement: [
|
replace: '$&+vcHasPendingPronouns?"":` (${vcPronounSource})`'
|
||||||
{
|
|
||||||
match: /\.getName\(\i\);(?<=displayProfile.{0,200})/,
|
|
||||||
replace: "$&const [vcPronounce,vcPronounSource]=$self.useProfilePronouns(arguments[0].user.id,true);if(arguments[0].displayProfile&&vcPronounce)arguments[0].displayProfile.pronouns=vcPronounce;"
|
|
||||||
},
|
},
|
||||||
PRONOUN_TOOLTIP_PATCH
|
{
|
||||||
|
match: /(\.pronounsText.+?children:)(\i)/,
|
||||||
|
replace: "$1vcHasPendingPronouns?$2:vcPronoun"
|
||||||
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
|
@ -21,13 +21,16 @@ import { debounce } from "@shared/debounce";
|
||||||
import { VENCORD_USER_AGENT } from "@shared/vencordUserAgent";
|
import { VENCORD_USER_AGENT } from "@shared/vencordUserAgent";
|
||||||
import { getCurrentChannel } from "@utils/discord";
|
import { getCurrentChannel } from "@utils/discord";
|
||||||
import { useAwaiter } from "@utils/react";
|
import { useAwaiter } from "@utils/react";
|
||||||
|
import { findStoreLazy } from "@webpack";
|
||||||
import { UserProfileStore, UserStore } from "@webpack/common";
|
import { UserProfileStore, UserStore } from "@webpack/common";
|
||||||
|
|
||||||
import { settings } from "./settings";
|
import { settings } from "./settings";
|
||||||
import { CachePronouns, PronounCode, PronounMapping, PronounsResponse } from "./types";
|
import { CachePronouns, PronounCode, PronounMapping, PronounsResponse } from "./types";
|
||||||
|
|
||||||
type PronounsWithSource = [string | null, string];
|
const UserSettingsAccountStore = findStoreLazy("UserSettingsAccountStore");
|
||||||
const EmptyPronouns: PronounsWithSource = [null, ""];
|
|
||||||
|
type PronounsWithSource = [pronouns: string | null, source: string, hasPendingPronouns: boolean];
|
||||||
|
const EmptyPronouns: PronounsWithSource = [null, "", false];
|
||||||
|
|
||||||
export const enum PronounsFormat {
|
export const enum PronounsFormat {
|
||||||
Lowercase = "LOWERCASE",
|
Lowercase = "LOWERCASE",
|
||||||
|
@ -75,13 +78,15 @@ export function useFormattedPronouns(id: string, useGlobalProfile: boolean = fal
|
||||||
onError: e => console.error("Fetching pronouns failed: ", e)
|
onError: e => console.error("Fetching pronouns failed: ", e)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const hasPendingPronouns = UserSettingsAccountStore.getPendingPronouns() != null;
|
||||||
|
|
||||||
if (settings.store.pronounSource === PronounSource.PreferDiscord && discordPronouns)
|
if (settings.store.pronounSource === PronounSource.PreferDiscord && discordPronouns)
|
||||||
return [discordPronouns, "Discord"];
|
return [discordPronouns, "Discord", hasPendingPronouns];
|
||||||
|
|
||||||
if (result && result !== PronounMapping.unspecified)
|
if (result && result !== PronounMapping.unspecified)
|
||||||
return [result, "PronounDB"];
|
return [result, "PronounDB", hasPendingPronouns];
|
||||||
|
|
||||||
return [discordPronouns, "Discord"];
|
return [discordPronouns, "Discord", hasPendingPronouns];
|
||||||
}
|
}
|
||||||
|
|
||||||
export function useProfilePronouns(id: string, useGlobalProfile: boolean = false): PronounsWithSource {
|
export function useProfilePronouns(id: string, useGlobalProfile: boolean = false): PronounsWithSource {
|
||||||
|
@ -147,7 +152,7 @@ async function bulkFetchPronouns(ids: string[]): Promise<PronounsResponse> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function extractPronouns(pronounSet?: { [locale: string]: PronounCode[] }): string {
|
export function extractPronouns(pronounSet?: { [locale: string]: PronounCode[]; }): string {
|
||||||
if (!pronounSet || !pronounSet.en) return PronounMapping.unspecified;
|
if (!pronounSet || !pronounSet.en) return PronounMapping.unspecified;
|
||||||
// PronounDB returns an empty set instead of {sets: {en: ["unspecified"]}}.
|
// PronounDB returns an empty set instead of {sets: {en: ["unspecified"]}}.
|
||||||
const pronouns = pronounSet.en;
|
const pronouns = pronounSet.en;
|
||||||
|
|
|
@ -20,18 +20,16 @@ import "./style.css";
|
||||||
|
|
||||||
import { NavContextMenuPatchCallback } from "@api/ContextMenu";
|
import { NavContextMenuPatchCallback } from "@api/ContextMenu";
|
||||||
import ErrorBoundary from "@components/ErrorBoundary";
|
import ErrorBoundary from "@components/ErrorBoundary";
|
||||||
import { ExpandableHeader } from "@components/ExpandableHeader";
|
|
||||||
import { NotesIcon, OpenExternalIcon } from "@components/Icons";
|
import { NotesIcon, OpenExternalIcon } from "@components/Icons";
|
||||||
import { Devs } from "@utils/constants";
|
import { Devs } from "@utils/constants";
|
||||||
import { classes } from "@utils/misc";
|
import { classes } from "@utils/misc";
|
||||||
import definePlugin from "@utils/types";
|
import definePlugin from "@utils/types";
|
||||||
import { findByPropsLazy } from "@webpack";
|
import { findByPropsLazy } from "@webpack";
|
||||||
import { Alerts, Button, Menu, Parser, TooltipContainer, useState } from "@webpack/common";
|
import { Alerts, Button, Menu, Parser, TooltipContainer } from "@webpack/common";
|
||||||
import { Guild, User } from "discord-types/general";
|
import { Guild, User } from "discord-types/general";
|
||||||
|
|
||||||
import { Auth, initAuth, updateAuth } from "./auth";
|
import { Auth, initAuth, updateAuth } from "./auth";
|
||||||
import { openReviewsModal } from "./components/ReviewModal";
|
import { openReviewsModal } from "./components/ReviewModal";
|
||||||
import ReviewsView from "./components/ReviewsView";
|
|
||||||
import { NotificationType } from "./entities";
|
import { NotificationType } from "./entities";
|
||||||
import { getCurrentUserInfo, readNotification } from "./reviewDbApi";
|
import { getCurrentUserInfo, readNotification } from "./reviewDbApi";
|
||||||
import { settings } from "./settings";
|
import { settings } from "./settings";
|
||||||
|
@ -79,17 +77,24 @@ export default definePlugin({
|
||||||
|
|
||||||
patches: [
|
patches: [
|
||||||
{
|
{
|
||||||
find: "showBorder:null",
|
find: ".BITE_SIZE,user:",
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /user:(\i),setNote:\i,canDM.+?\}\)/,
|
match: /{profileType:\i\.\i\.BITE_SIZE,children:\[/,
|
||||||
replace: "$&,$self.getReviewsComponent($1)"
|
replace: "$&$self.BiteSizeReviewsButton({user:arguments[0].user}),"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
find: ".BITE_SIZE,user:",
|
find: ".FULL_SIZE,user:",
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /(?<=\.BITE_SIZE,children:\[)\(0,\i\.jsx\)\(\i\.\i,\{user:(\i),/,
|
match: /{profileType:\i\.\i\.FULL_SIZE,children:\[/,
|
||||||
replace: "$self.BiteSizeReviewsButton({user:$1}),$&"
|
replace: "$&$self.BiteSizeReviewsButton({user:arguments[0].user}),"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
find: ".PANEL,isInteractionSource:",
|
||||||
|
replacement: {
|
||||||
|
match: /{profileType:\i\.\i\.PANEL,children:\[/,
|
||||||
|
replace: "$&$self.BiteSizeReviewsButton({user:arguments[0].user}),"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
@ -148,31 +153,6 @@ export default definePlugin({
|
||||||
}, 4000);
|
}, 4000);
|
||||||
},
|
},
|
||||||
|
|
||||||
getReviewsComponent: ErrorBoundary.wrap((user: User) => {
|
|
||||||
const [reviewCount, setReviewCount] = useState<number>();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<ExpandableHeader
|
|
||||||
headerText="User Reviews"
|
|
||||||
onMoreClick={() => openReviewsModal(user.id, user.username)}
|
|
||||||
moreTooltipText={
|
|
||||||
reviewCount && reviewCount > 50
|
|
||||||
? `View all ${reviewCount} reviews`
|
|
||||||
: "Open Review Modal"
|
|
||||||
}
|
|
||||||
onDropDownClick={state => settings.store.reviewsDropdownState = !state}
|
|
||||||
defaultState={settings.store.reviewsDropdownState}
|
|
||||||
>
|
|
||||||
<ReviewsView
|
|
||||||
discordId={user.id}
|
|
||||||
name={user.username}
|
|
||||||
onFetchReviews={r => setReviewCount(r.reviewCount)}
|
|
||||||
showInput
|
|
||||||
/>
|
|
||||||
</ExpandableHeader>
|
|
||||||
);
|
|
||||||
}, { message: "Failed to render Reviews" }),
|
|
||||||
|
|
||||||
BiteSizeReviewsButton: ErrorBoundary.wrap(({ user }: { user: User; }) => {
|
BiteSizeReviewsButton: ErrorBoundary.wrap(({ user }: { user: User; }) => {
|
||||||
return (
|
return (
|
||||||
<TooltipContainer text="View Reviews">
|
<TooltipContainer text="View Reviews">
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
# ShowAllRoles
|
|
||||||
|
|
||||||
Display all roles on the new profiles instead of limiting them to the default two rows.
|
|
||||||
|
|
||||||
![image](https://github.com/Vendicated/Vencord/assets/71079641/3f021f03-c6f9-4fe5-83ac-a1891b5e4b37)
|
|
||||||
|
|
|
@ -1,23 +0,0 @@
|
||||||
/*
|
|
||||||
* Vencord, a Discord client mod
|
|
||||||
* Copyright (c) 2024 Vendicated and contributors
|
|
||||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { Devs } from "@utils/constants";
|
|
||||||
import definePlugin from "@utils/types";
|
|
||||||
|
|
||||||
export default definePlugin({
|
|
||||||
name: "ShowAllRoles",
|
|
||||||
description: "Show all roles in new profiles.",
|
|
||||||
authors: [Devs.Luna],
|
|
||||||
patches: [
|
|
||||||
{
|
|
||||||
find: ".Messages.VIEW_ALL_ROLES",
|
|
||||||
replacement: {
|
|
||||||
match: /(\i)\.slice\(0,\i\)/,
|
|
||||||
replace: "$1"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
});
|
|
|
@ -25,15 +25,12 @@ import { CopyIcon, LinkIcon } from "@components/Icons";
|
||||||
import { Devs } from "@utils/constants";
|
import { Devs } from "@utils/constants";
|
||||||
import { copyWithToast } from "@utils/misc";
|
import { copyWithToast } from "@utils/misc";
|
||||||
import definePlugin, { OptionType } from "@utils/types";
|
import definePlugin, { OptionType } from "@utils/types";
|
||||||
import { findByCodeLazy, findByPropsLazy, findComponentByCodeLazy, findStoreLazy } from "@webpack";
|
import { findByCodeLazy, findByPropsLazy } from "@webpack";
|
||||||
import { Text, Tooltip, UserProfileStore } from "@webpack/common";
|
import { Tooltip, UserProfileStore } from "@webpack/common";
|
||||||
import { User } from "discord-types/general";
|
import { User } from "discord-types/general";
|
||||||
|
|
||||||
import { VerifiedIcon } from "./VerifiedIcon";
|
import { VerifiedIcon } from "./VerifiedIcon";
|
||||||
|
|
||||||
const Section = findComponentByCodeLazy(".lastSection", "children:");
|
|
||||||
const ThemeStore = findStoreLazy("ThemeStore");
|
|
||||||
|
|
||||||
const useLegacyPlatformType: (platform: string) => string = findByCodeLazy(".TWITTER_LEGACY:");
|
const useLegacyPlatformType: (platform: string) => string = findByCodeLazy(".TWITTER_LEGACY:");
|
||||||
const platforms: { get(type: string): ConnectionPlatform; } = findByPropsLazy("isSupported", "getByUrl");
|
const platforms: { get(type: string): ConnectionPlatform; } = findByPropsLazy("isSupported", "getByUrl");
|
||||||
const getProfileThemeProps = findByCodeLazy(".getPreviewThemeColors", "primaryColor:");
|
const getProfileThemeProps = findByCodeLazy(".getPreviewThemeColors", "primaryColor:");
|
||||||
|
@ -76,7 +73,7 @@ interface ConnectionPlatform {
|
||||||
}
|
}
|
||||||
|
|
||||||
const profilePopoutComponent = ErrorBoundary.wrap(
|
const profilePopoutComponent = ErrorBoundary.wrap(
|
||||||
(props: { user: User; displayProfile?: any; simplified?: boolean; }) => (
|
(props: { user: User; displayProfile?: any; }) => (
|
||||||
<ConnectionsComponent
|
<ConnectionsComponent
|
||||||
{...props}
|
{...props}
|
||||||
id={props.user.id}
|
id={props.user.id}
|
||||||
|
@ -86,17 +83,7 @@ const profilePopoutComponent = ErrorBoundary.wrap(
|
||||||
{ noop: true }
|
{ noop: true }
|
||||||
);
|
);
|
||||||
|
|
||||||
const profilePanelComponent = ErrorBoundary.wrap(
|
function ConnectionsComponent({ id, theme }: { id: string, theme: string; }) {
|
||||||
(props: { id: string; simplified?: boolean; }) => (
|
|
||||||
<ConnectionsComponent
|
|
||||||
{...props}
|
|
||||||
theme={ThemeStore.theme}
|
|
||||||
/>
|
|
||||||
),
|
|
||||||
{ noop: true }
|
|
||||||
);
|
|
||||||
|
|
||||||
function ConnectionsComponent({ id, theme, simplified }: { id: string, theme: string, simplified?: boolean; }) {
|
|
||||||
const profile = UserProfileStore.getUserProfile(id);
|
const profile = UserProfileStore.getUserProfile(id);
|
||||||
if (!profile)
|
if (!profile)
|
||||||
return null;
|
return null;
|
||||||
|
@ -105,31 +92,14 @@ function ConnectionsComponent({ id, theme, simplified }: { id: string, theme: st
|
||||||
if (!connections?.length)
|
if (!connections?.length)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
const connectionsContainer = (
|
return (
|
||||||
<Flex style={{
|
<Flex style={{
|
||||||
marginTop: !simplified ? "8px" : undefined,
|
|
||||||
gap: getSpacingPx(settings.store.iconSpacing),
|
gap: getSpacingPx(settings.store.iconSpacing),
|
||||||
flexWrap: "wrap"
|
flexWrap: "wrap"
|
||||||
}}>
|
}}>
|
||||||
{connections.map(connection => <CompactConnectionComponent connection={connection} theme={theme} />)}
|
{connections.map(connection => <CompactConnectionComponent connection={connection} theme={theme} />)}
|
||||||
</Flex>
|
</Flex>
|
||||||
);
|
);
|
||||||
|
|
||||||
if (simplified)
|
|
||||||
return connectionsContainer;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Section>
|
|
||||||
<Text
|
|
||||||
tag="h2"
|
|
||||||
variant="eyebrow"
|
|
||||||
style={{ color: "var(--header-primary)" }}
|
|
||||||
>
|
|
||||||
Connections
|
|
||||||
</Text>
|
|
||||||
{connectionsContainer}
|
|
||||||
</Section>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function CompactConnectionComponent({ connection, theme }: { connection: Connection, theme: string; }) {
|
function CompactConnectionComponent({ connection, theme }: { connection: Connection, theme: string; }) {
|
||||||
|
@ -194,31 +164,17 @@ export default definePlugin({
|
||||||
name: "ShowConnections",
|
name: "ShowConnections",
|
||||||
description: "Show connected accounts in user popouts",
|
description: "Show connected accounts in user popouts",
|
||||||
authors: [Devs.TheKodeToad],
|
authors: [Devs.TheKodeToad],
|
||||||
|
settings,
|
||||||
|
|
||||||
patches: [
|
patches: [
|
||||||
{
|
{
|
||||||
find: "{isUsingGuildBio:null!==(",
|
find: ".hasAvatarForGuild(null==",
|
||||||
replacement: {
|
|
||||||
match: /,theme:\i\}\)(?=,.{0,150}setNote:)/,
|
|
||||||
replace: "$&,$self.profilePopoutComponent({ user: arguments[0].user, displayProfile: arguments[0].displayProfile })"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
find: ".PROFILE_PANEL,",
|
|
||||||
replacement: {
|
|
||||||
// createElement(Divider, {}), createElement(NoteComponent)
|
|
||||||
match: /\(0,\i\.jsx\)\(\i\.\i,\{\}\).{0,100}setNote:(?=.+?channelId:(\i).id)/,
|
|
||||||
replace: "$self.profilePanelComponent({ id: $1.recipients[0] }),$&"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
find: '"BiteSizeProfileBody"',
|
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /currentUser:\i,guild:\i}\)(?<=user:(\i),bio:null==(\i)\?.+?)/,
|
match: /currentUser:\i,guild:\i}\)(?<=user:(\i),bio:null==(\i)\?.+?)/,
|
||||||
replace: "$&,$self.profilePopoutComponent({ user: $1, displayProfile: $2, simplified: true })"
|
replace: "$&,$self.profilePopoutComponent({ user: $1, displayProfile: $2 })"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
settings,
|
|
||||||
profilePopoutComponent,
|
profilePopoutComponent,
|
||||||
profilePanelComponent
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -18,12 +18,11 @@
|
||||||
|
|
||||||
import "./VoiceChannelSection.css";
|
import "./VoiceChannelSection.css";
|
||||||
|
|
||||||
import { findByCodeLazy, findByPropsLazy } from "@webpack";
|
import { findByPropsLazy } from "@webpack";
|
||||||
import { Button, Forms, PermissionStore, Toasts } from "@webpack/common";
|
import { Button, Forms, PermissionStore, Toasts } from "@webpack/common";
|
||||||
import { Channel } from "discord-types/general";
|
import { Channel } from "discord-types/general";
|
||||||
|
|
||||||
const ChannelActions = findByPropsLazy("selectChannel", "selectVoiceChannel");
|
const ChannelActions = findByPropsLazy("selectChannel", "selectVoiceChannel");
|
||||||
const UserPopoutSection = findByCodeLazy(".lastSection", "children:");
|
|
||||||
|
|
||||||
const CONNECT = 1n << 20n;
|
const CONNECT = 1n << 20n;
|
||||||
|
|
||||||
|
@ -34,7 +33,8 @@ interface VoiceChannelFieldProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
export const VoiceChannelSection = ({ channel, label, showHeader }: VoiceChannelFieldProps) => (
|
export const VoiceChannelSection = ({ channel, label, showHeader }: VoiceChannelFieldProps) => (
|
||||||
<UserPopoutSection>
|
// @TODO The div is supposed to be a UserPopoutSection
|
||||||
|
<div>
|
||||||
{showHeader && <Forms.FormTitle className="vc-uvs-header">In a voice channel</Forms.FormTitle>}
|
{showHeader && <Forms.FormTitle className="vc-uvs-header">In a voice channel</Forms.FormTitle>}
|
||||||
<Button
|
<Button
|
||||||
className="vc-uvs-button"
|
className="vc-uvs-button"
|
||||||
|
@ -57,5 +57,5 @@ export const VoiceChannelSection = ({ channel, label, showHeader }: VoiceChannel
|
||||||
>
|
>
|
||||||
{label}
|
{label}
|
||||||
</Button>
|
</Button>
|
||||||
</UserPopoutSection>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -84,7 +84,7 @@ export default definePlugin({
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
patchPopout: ({ user }: UserProps) => {
|
patchProfilePopout: ({ user }: UserProps) => {
|
||||||
const isSelfUser = user.id === UserStore.getCurrentUser().id;
|
const isSelfUser = user.id === UserStore.getCurrentUser().id;
|
||||||
return (
|
return (
|
||||||
<div className={isSelfUser ? "vc-uvs-popout-margin-self" : ""}>
|
<div className={isSelfUser ? "vc-uvs-popout-margin-self" : ""}>
|
||||||
|
@ -94,21 +94,7 @@ export default definePlugin({
|
||||||
},
|
},
|
||||||
|
|
||||||
patches: [
|
patches: [
|
||||||
// above message box
|
// @TODO Maybe patch UserVoiceShow in simplified profile popout
|
||||||
{
|
// @TODO Patch new profile modal
|
||||||
find: ".popularApplicationCommandIds,",
|
|
||||||
replacement: {
|
|
||||||
match: /(?<=,)(?=!\i&&!\i&&.{0,50}setNote:)/,
|
|
||||||
replace: "$self.patchPopout(arguments[0]),",
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// below username
|
|
||||||
{
|
|
||||||
find: ".Messages.MUTUAL_GUILDS_WITH_END_COUNT", // Lazy-loaded
|
|
||||||
replacement: {
|
|
||||||
match: /\.body.+?displayProfile:\i}\),/,
|
|
||||||
replace: "$&$self.patchModal(arguments[0]),",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
|
@ -57,14 +57,7 @@ export default definePlugin({
|
||||||
settings,
|
settings,
|
||||||
patches: [
|
patches: [
|
||||||
{
|
{
|
||||||
find: ".NITRO_BANNER,",
|
find: '.banner)==null?"COMPLETE"',
|
||||||
replacement: {
|
|
||||||
match: /\?\(0,\i\.jsx\)\(\i,{type:\i,shown/,
|
|
||||||
replace: "&&$self.shouldShowBadge(arguments[0])$&"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
find: ".banner)==null",
|
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /(?<=void 0:)\i.getPreviewBanner\(\i,\i,\i\)/,
|
match: /(?<=void 0:)\i.getPreviewBanner\(\i,\i,\i\)/,
|
||||||
replace: "$self.patchBannerUrl(arguments[0])||$&"
|
replace: "$self.patchBannerUrl(arguments[0])||$&"
|
||||||
|
@ -109,10 +102,6 @@ export default definePlugin({
|
||||||
if (this.userHasBackground(displayProfile?.userId)) return this.getImageUrl(displayProfile?.userId);
|
if (this.userHasBackground(displayProfile?.userId)) return this.getImageUrl(displayProfile?.userId);
|
||||||
},
|
},
|
||||||
|
|
||||||
shouldShowBadge({ displayProfile, user }: any) {
|
|
||||||
return displayProfile?.banner && (!this.userHasBackground(user.id) || settings.store.nitroFirst);
|
|
||||||
},
|
|
||||||
|
|
||||||
userHasBackground(userId: string) {
|
userHasBackground(userId: string) {
|
||||||
return !!this.data?.users[userId];
|
return !!this.data?.users[userId];
|
||||||
},
|
},
|
||||||
|
|
|
@ -192,31 +192,12 @@ export default definePlugin({
|
||||||
},
|
},
|
||||||
all: true
|
all: true
|
||||||
},
|
},
|
||||||
// Old Profiles Modal pfp
|
|
||||||
{
|
|
||||||
find: ".MODAL,hasProfileEffect",
|
|
||||||
replacement: {
|
|
||||||
match: /\{src:(\i)(?=,avatarDecoration)/,
|
|
||||||
replace: "{src:$1,onClick:()=>$self.openImage($1)"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// Banners
|
// Banners
|
||||||
...[".NITRO_BANNER,", "=!1,canUsePremiumCustomization:"].map(find => ({
|
|
||||||
find,
|
|
||||||
replacement: {
|
|
||||||
// style: { backgroundImage: shouldShowBanner ? "url(".concat(bannerUrl,
|
|
||||||
match: /style:\{(?=backgroundImage:(null!=\i)\?"url\("\.concat\((\i),)/,
|
|
||||||
replace:
|
|
||||||
// onClick: () => shouldShowBanner && ev.target.style.backgroundImage && openImage(bannerUrl), style: { cursor: shouldShowBanner ? "pointer" : void 0,
|
|
||||||
'onClick:ev=>$1&&ev.target.style.backgroundImage&&$self.openImage($2),style:{cursor:$1?"pointer":void 0,'
|
|
||||||
}
|
|
||||||
})),
|
|
||||||
// Old User DMs "User Profile" popup in the right
|
|
||||||
{
|
{
|
||||||
find: ".avatarPositionPanel",
|
find: 'backgroundColor:"COMPLETE"',
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /(avatarWrapperNonUserBot.{0,50})onClick:(\i\|\|\i)\?void 0(?<=,avatarSrc:(\i).+?)/,
|
match: /(\.banner,.+?),style:{(?=.+?backgroundImage:null!=(\i)\?"url\("\.concat\(\2,)/,
|
||||||
replace: "$1style:($2)?{cursor:\"pointer\"}:{},onClick:$2?()=>{$self.openImage($3)}"
|
replace: (_, rest, bannerSrc) => `${rest},onClick:()=>${bannerSrc}!=null&&$self.openImage(${bannerSrc}),style:{cursor:${bannerSrc}!=null?"pointer":void 0,`
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// Group DMs top small & large icon
|
// Group DMs top small & large icon
|
||||||
|
|
|
@ -35,6 +35,7 @@ export default definePlugin({
|
||||||
if (hasCtrl) switch (e.key) {
|
if (hasCtrl) switch (e.key) {
|
||||||
case "t":
|
case "t":
|
||||||
case "T":
|
case "T":
|
||||||
|
if (!IS_VESKTOP) return;
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
if (e.shiftKey) {
|
if (e.shiftKey) {
|
||||||
if (SelectedGuildStore.getGuildId()) NavigationRouter.transitionToGuild("@me");
|
if (SelectedGuildStore.getGuildId()) NavigationRouter.transitionToGuild("@me");
|
||||||
|
@ -47,14 +48,15 @@ export default definePlugin({
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case "Tab":
|
||||||
|
if (!IS_VESKTOP) return;
|
||||||
|
const handler = e.shiftKey ? KeyBinds.SERVER_PREV : KeyBinds.SERVER_NEXT;
|
||||||
|
handler.action(e);
|
||||||
|
break;
|
||||||
case ",":
|
case ",":
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
SettingsRouter.open("My Account");
|
SettingsRouter.open("My Account");
|
||||||
break;
|
break;
|
||||||
case "Tab":
|
|
||||||
const handler = e.shiftKey ? KeyBinds.SERVER_PREV : KeyBinds.SERVER_NEXT;
|
|
||||||
handler.action(e);
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
if (e.key >= "1" && e.key <= "9") {
|
if (e.key >= "1" && e.key <= "9") {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
19
src/webpack/common/types/utils.d.ts
vendored
19
src/webpack/common/types/utils.d.ts
vendored
|
@ -223,9 +223,26 @@ export interface Constants {
|
||||||
FriendsSections: Record<string, string>;
|
FriendsSections: Record<string, string>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type ActiveView = LiteralUnion<"emoji" | "gif" | "sticker" | "soundboard", string>;
|
||||||
|
|
||||||
|
export interface ExpressionPickerStoreState extends Record<PropertyKey, any> {
|
||||||
|
activeView: ActiveView | null;
|
||||||
|
lastActiveView: ActiveView | null;
|
||||||
|
activeViewType: any | null;
|
||||||
|
searchQuery: string;
|
||||||
|
isSearchSuggestion: boolean,
|
||||||
|
pickerId: string;
|
||||||
|
}
|
||||||
|
|
||||||
export interface ExpressionPickerStore {
|
export interface ExpressionPickerStore {
|
||||||
|
openExpressionPicker(activeView: ActiveView, activeViewType?: any): void;
|
||||||
closeExpressionPicker(activeViewType?: any): void;
|
closeExpressionPicker(activeViewType?: any): void;
|
||||||
openExpressionPicker(activeView: LiteralUnion<"emoji" | "gif" | "sticker", string>, activeViewType?: any): void;
|
toggleMultiExpressionPicker(activeViewType?: any): void;
|
||||||
|
toggleExpressionPicker(activeView: ActiveView, activeViewType?: any): void;
|
||||||
|
setExpressionPickerView(activeView: ActiveView): void;
|
||||||
|
setSearchQuery(searchQuery: string, isSearchSuggestion?: boolean): void;
|
||||||
|
useExpressionPickerStore(): ExpressionPickerStoreState;
|
||||||
|
useExpressionPickerStore<T>(selector: (state: ExpressionPickerStoreState) => T): T;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface BrowserWindowFeatures {
|
export interface BrowserWindowFeatures {
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { canonicalizeMatch } from "@utils/patches";
|
|
||||||
import type { Channel } from "discord-types/general";
|
import type { Channel } from "discord-types/general";
|
||||||
|
|
||||||
// eslint-disable-next-line path-alias/no-relative
|
// eslint-disable-next-line path-alias/no-relative
|
||||||
|
@ -162,11 +161,14 @@ export const InviteActions = findByPropsLazy("resolveInvite");
|
||||||
|
|
||||||
export const IconUtils: t.IconUtils = findByPropsLazy("getGuildBannerURL", "getUserAvatarURL");
|
export const IconUtils: t.IconUtils = findByPropsLazy("getGuildBannerURL", "getUserAvatarURL");
|
||||||
|
|
||||||
const openExpressionPickerMatcher = canonicalizeMatch(/setState\({activeView:\i,activeViewType:/);
|
|
||||||
// TODO: type
|
|
||||||
export const ExpressionPickerStore: t.ExpressionPickerStore = mapMangledModuleLazy("expression-picker-last-active-view", {
|
export const ExpressionPickerStore: t.ExpressionPickerStore = mapMangledModuleLazy("expression-picker-last-active-view", {
|
||||||
|
openExpressionPicker: filters.byCode(/setState\({activeView:(?:(?!null)\i),activeViewType:/),
|
||||||
closeExpressionPicker: filters.byCode("setState({activeView:null"),
|
closeExpressionPicker: filters.byCode("setState({activeView:null"),
|
||||||
openExpressionPicker: m => typeof m === "function" && openExpressionPickerMatcher.test(m.toString()),
|
toggleMultiExpressionPicker: filters.byCode(".EMOJI,"),
|
||||||
|
toggleExpressionPicker: filters.byCode(/getState\(\)\.activeView===\i\?\i\(\):\i\(/),
|
||||||
|
setExpressionPickerView: filters.byCode(/setState\({activeView:\i,lastActiveView:/),
|
||||||
|
setSearchQuery: filters.byCode("searchQuery:"),
|
||||||
|
useExpressionPickerStore: filters.byCode("Object.is")
|
||||||
});
|
});
|
||||||
|
|
||||||
export const PopoutActions: t.PopoutActions = mapMangledModuleLazy('type:"POPOUT_WINDOW_OPEN"', {
|
export const PopoutActions: t.PopoutActions = mapMangledModuleLazy('type:"POPOUT_WINDOW_OPEN"', {
|
||||||
|
|
|
@ -233,7 +233,7 @@ function patchFactories(factories: Record<string, (module: any, exports: any, re
|
||||||
logger.error("Error while firing callback for Webpack subscription:\n", err, filter, callback);
|
logger.error("Error while firing callback for Webpack subscription:\n", err, filter, callback);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} as any as { toString: () => string, original: any, (...args: any[]): void; };
|
} as any as { toString: () => string, original: any, (...args: any[]): void; $$vencordPatchedSource?: string; };
|
||||||
|
|
||||||
factory.toString = originalMod.toString.bind(originalMod);
|
factory.toString = originalMod.toString.bind(originalMod);
|
||||||
factory.original = originalMod;
|
factory.original = originalMod;
|
||||||
|
@ -354,5 +354,17 @@ function patchFactories(factories: Record<string, (module: any, exports: any, re
|
||||||
|
|
||||||
if (!patch.all) patches.splice(i--, 1);
|
if (!patch.all) patches.splice(i--, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (IS_DEV) {
|
||||||
|
if (mod !== originalMod) {
|
||||||
|
factory.$$vencordPatchedSource = String(mod);
|
||||||
|
} else if (wreq != null) {
|
||||||
|
const existingFactory = wreq.m[id];
|
||||||
|
|
||||||
|
if (existingFactory != null) {
|
||||||
|
factory.$$vencordPatchedSource = existingFactory.$$vencordPatchedSource;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,15 +38,15 @@ export let cache: WebpackInstance["c"];
|
||||||
|
|
||||||
export type FilterFn = (mod: any) => boolean;
|
export type FilterFn = (mod: any) => boolean;
|
||||||
|
|
||||||
type PropsFilter = Array<string>;
|
export type PropsFilter = Array<string>;
|
||||||
type CodeFilter = Array<string | RegExp>;
|
export type CodeFilter = Array<string | RegExp>;
|
||||||
type StoreNameFilter = string;
|
export type StoreNameFilter = string;
|
||||||
|
|
||||||
const stringMatches = (s: string, filter: CodeFilter) =>
|
export const stringMatches = (s: string, filter: CodeFilter) =>
|
||||||
filter.every(f =>
|
filter.every(f =>
|
||||||
typeof f === "string"
|
typeof f === "string"
|
||||||
? s.includes(f)
|
? s.includes(f)
|
||||||
: f.test(s)
|
: (f.global && (f.lastIndex = 0), f.test(s))
|
||||||
);
|
);
|
||||||
|
|
||||||
export const filters = {
|
export const filters = {
|
||||||
|
@ -258,6 +258,8 @@ export const findBulk = traceFunction("findBulk", function findBulk(...filterFns
|
||||||
* @returns string or null
|
* @returns string or null
|
||||||
*/
|
*/
|
||||||
export const findModuleId = traceFunction("findModuleId", function findModuleId(...code: CodeFilter) {
|
export const findModuleId = traceFunction("findModuleId", function findModuleId(...code: CodeFilter) {
|
||||||
|
code = code.map(canonicalizeMatch);
|
||||||
|
|
||||||
for (const id in wreq.m) {
|
for (const id in wreq.m) {
|
||||||
if (stringMatches(wreq.m[id].toString(), code)) return id;
|
if (stringMatches(wreq.m[id].toString(), code)) return id;
|
||||||
}
|
}
|
||||||
|
@ -452,12 +454,9 @@ export function findExportedComponentLazy<T extends object = any>(...props: Prop
|
||||||
* })
|
* })
|
||||||
*/
|
*/
|
||||||
export const mapMangledModule = traceFunction("mapMangledModule", function mapMangledModule<S extends string>(code: string | RegExp | CodeFilter, mappers: Record<S, FilterFn>): Record<S, any> {
|
export const mapMangledModule = traceFunction("mapMangledModule", function mapMangledModule<S extends string>(code: string | RegExp | CodeFilter, mappers: Record<S, FilterFn>): Record<S, any> {
|
||||||
if (!Array.isArray(code)) code = [code];
|
|
||||||
code = code.map(canonicalizeMatch);
|
|
||||||
|
|
||||||
const exports = {} as Record<S, any>;
|
const exports = {} as Record<S, any>;
|
||||||
|
|
||||||
const id = findModuleId(...code);
|
const id = findModuleId(...Array.isArray(code) ? code : [code]);
|
||||||
if (id === null)
|
if (id === null)
|
||||||
return exports;
|
return exports;
|
||||||
|
|
||||||
|
@ -606,6 +605,8 @@ export function waitFor(filter: string | PropsFilter | FilterFn, callback: Callb
|
||||||
* @returns Mapping of found modules
|
* @returns Mapping of found modules
|
||||||
*/
|
*/
|
||||||
export function search(...code: CodeFilter) {
|
export function search(...code: CodeFilter) {
|
||||||
|
code = code.map(canonicalizeMatch);
|
||||||
|
|
||||||
const results = {} as Record<number, Function>;
|
const results = {} as Record<number, Function>;
|
||||||
const factories = wreq.m;
|
const factories = wreq.m;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue