Merge branch 'dev'

This commit is contained in:
thororen1234 2026-02-05 12:32:31 -05:00
commit a29beac69d
No known key found for this signature in database
96 changed files with 338 additions and 270 deletions

View file

@ -24,7 +24,7 @@ export default definePlugin({
// Uses the audio as-is if external, otherwise checks for an internal Discord sound.
// Also force loads the internal sounds module to account for the second patch group below,
// as well as accounting for not calling the module in this patch when this.type is not DISCORD.
match: /(let \i=class.{0,900}?new Audio;\i.src=)((\i\(\d+\)).{0,50}concat\()this.name(,".mp3"\)\))/,
match: /(let \i=class.{0,900}?new Audio;\i.src=)((\i\(\d+\))(?:\(`\.\/\$\{|.{0,50}concat\())this.name((?:\}\.mp3`|,".mp3"\))\))/,
replace: "$3;$1this.type!==$self.AudioType.DISCORD?this.audio:$2this.audio$4"
},
{

View file

@ -4,13 +4,13 @@
* SPDX-License-Identifier: GPL-3.0-or-later
*/
import { EquicordDevs } from "@utils/constants";
import { Devs } from "@utils/constants";
import definePlugin from "@utils/types";
export default definePlugin({
name: "HeaderBarAPI",
description: "API to add buttons to the header bar and channel toolbar.",
authors: [EquicordDevs.prism],
authors: [Devs.prism],
patches: [
{
@ -23,7 +23,7 @@ export default definePlugin({
{
find: "Missing channel in Channel.renderHeaderToolbar",
replacement: {
match: /(?<=renderHeaderToolbar",\(\)=>\{.{1,200}let (\i)=\[\];)/,
match: /(?<=renderHeaderToolbar"\);let (\i)=\[\];)/,
replace: "Vencord.Api.HeaderBar._addChannelToolbarButtons($1);"
}
}

View file

@ -6,7 +6,7 @@
import { isPluginEnabled } from "@api/PluginManager";
import betterUserArea from "@equicordplugins/betterUserArea";
import { EquicordDevs } from "@utils/constants";
import { Devs } from "@utils/constants";
import definePlugin from "@utils/types";
import { findCssClassesLazy } from "@webpack";
@ -15,7 +15,7 @@ const { iconForeground } = findCssClassesLazy("iconForeground", "autocompleteRow
export default definePlugin({
name: "UserAreaAPI",
description: "API to add buttons to the user area panel.",
authors: [EquicordDevs.prism],
authors: [Devs.prism],
patches: [
{

View file

@ -65,8 +65,8 @@ export default definePlugin({
find: "role:\"listitem\",innerRef",
replacement: {
// We cant access the user id here, so we take the banner property we set earlier
match: /focusProps.\i\}=(\i).*?children:\[/,
replace: "$&$1.banner,"
match: /children:\[(?=.{0,100}\.MEMBER_LIST)/,
replace: "$&arguments[0].banner,"
}
}
],

View file

@ -27,20 +27,19 @@ export default definePlugin({
patches: [
{
// Patch activity icons
find: "isBlockedOrIgnored(null",
find: '"ActivityStatus"),',
replacement: [
{
match: /(?<=className:\i,children:\[).*?(?=\i\(\),\i&&)/,
match: /(?<=className:\i,children:\[).*?(?=\i\(\),\i&&)/g,
replace: "",
predicate: () => settings.store.removeGameActivityStatus,
},
{
match: /(?<=hideTooltip:.{0,4}}=(\i).*?{}\))\]/,
match: /(?<=hideTooltip:.{0,4}}=(\i).*?{}\))\]/g,
replace: ",$self.patchActivityList($1)]",
predicate: () => settings.store.memberList,
}
],
all: true
},
{
// Show all activities in the user popout/sidebar

View file

@ -33,7 +33,7 @@ function lurk(id: string) {
export default definePlugin({
name: "BetterInvites",
description: "See invites expiration date, view inviter profile and preview discoverable servers before joining by clicking their name",
description: "See invites expiration date, view inviter profile and preview servers before joining by clicking the name",
authors: [EquicordDevs.iamme, Devs.thororen],
patches: [
{

View file

@ -5,7 +5,7 @@
*/
import { definePluginSettings } from "@api/Settings";
import { EquicordDevs } from "@utils/constants";
import { Devs } from "@utils/constants";
import definePlugin, { OptionType } from "@utils/types";
const settings = definePluginSettings({
@ -50,7 +50,7 @@ const settings = definePluginSettings({
export default definePlugin({
name: "BetterUserArea",
description: "Customize and make the user area more clean.",
authors: [EquicordDevs.prism],
authors: [Devs.prism],
settings,
patches: [
{

View file

@ -73,10 +73,10 @@ export default definePlugin({
authors: [EquicordDevs.catcraft],
patches: [
{
find: '"_channelMessages",{})',
find: "_channelMessages={}",
predicate: () => settings.store.blockedWords !== "",
replacement: {
match: /static commit\((.{1,2})\){/g,
match: /static commit\((\i)\)\{/g,
replace: "$&$1=$self.blockMessagesWithKeywords($1);"
}
},

View file

@ -61,12 +61,12 @@ export default definePlugin({
find: '"AppView"',
replacement: [
{
match: /(\?void 0:(\i)\.channelId.{0,600})"div",{(?=className:\i\.\i)/,
match: /((\i\?.params)\?\.channelId.{0,600})"div",{(?=className:\i\.\i)/,
replace: "$1$self.render,{currentChannel:$2,",
predicate: () => settings.store.tabBarPosition === "top"
},
{
match: /(\?void 0:(\i)\.channelId.{0,300})"div",{/,
match: /((\i\?.params)\?.channelId.{0,300})"div",{/,
replace: "$1$self.render,{currentChannel:$2,",
predicate: () => settings.store.tabBarPosition === "bottom"
}
@ -74,9 +74,9 @@ export default definePlugin({
},
// intercept channel navigation to switch/create tabs
{
find: '"transitionToGuild - Transitioning to "',
find: "`transitionToGuild - Transitioning to",
replacement: {
match: /(\i\((\i),(\i),\i,\i\)\{)(.{0,25}"transitionToGuild)/,
match: /(\i\((\i),(\i),\i,\i\)\{)(.{0,25}`transitionToGuild)/,
replace: "$1$self.handleNavigation($2,$3);$4"
}
},
@ -106,7 +106,7 @@ export default definePlugin({
},
// prevent issues with the pins/inbox popouts being too tall
{
find: "renderCloseButton()",
find: "#{intl::JUMP}),onClick:",
replacement: {
match: /\i&&\((\i).maxHeight.{0,5}\)/,
replace: "$&;$1.maxHeight-=$self.containerHeight"

View file

@ -0,0 +1,29 @@
/*
* Vencord, a Discord client mod
* Copyright (c) 2026 Vendicated and contributors
* SPDX-License-Identifier: GPL-3.0-or-later
*/
import { EquicordDevs } from "@utils/constants";
import definePlugin from "@utils/types";
export default definePlugin({
name: "CleanerChannelGroups",
description: "Hides all channels in collapsed categories, even if they have unread messages.",
authors: [EquicordDevs.justjxke],
patches: [
{
find: '"placeholder-channel-id"',
replacement: [
{
match: /this\.category\.isCollapsed&&\(.{0,600}?\)\?\{renderLevel:3,threadIds:/,
replace: "this.category.isCollapsed?{renderLevel:3,threadIds:"
},
{
match: /(?<=!this.category.isCollapsed.{0,50}\i=)(\i\(this\.record,.{0,5},\i\.hideMutedChannels\);)/,
replace: "this.category.isCollapsed?[]:$1"
}
]
}
]
});

View file

@ -217,7 +217,7 @@ export default definePlugin({
{
find: "getFriendIDs(){",
replacement: {
match: /return \i\.friends/,
match: /\?\?\[\]\)\),\i\.friends/,
replace: "$&.filter(id => !$self.shouldHideUser(id))"
}
},

View file

@ -7,7 +7,7 @@
import "./styles.css";
import SettingsPlugin, { settingsSectionMap } from "@plugins/_core/settings";
import { EquicordDevs } from "@utils/constants";
import { Devs } from "@utils/constants";
import definePlugin, { StartAt } from "@utils/types";
import { openUserSettingsPanel } from "@webpack/common";
@ -40,7 +40,7 @@ function ComponentsIcon(props: React.SVGProps<SVGSVGElement>) {
export default definePlugin({
name: "Components",
description: "Adds a new tab to settings to browse Discord components.",
authors: [EquicordDevs.prism],
authors: [Devs.prism],
dependencies: ["Settings"],
startAt: StartAt.WebpackReady,
toolboxActions: {

View file

@ -26,7 +26,7 @@ export let colors: Record<string, string> = {};
})();
// needed for color picker to be available without opening settings (ty pindms!!)
const requireSettingsMenu = extractAndLoadChunksLazy(['name:"UserSettings"'], /createPromise:.{0,20}(\i\.\i\("?.+?"?\).*?).then\(\i\.bind\(\i,"?(.+?)"?\)\).{0,50}"UserSettings"/);
const requireSettingsMenu = extractAndLoadChunksLazy(['"AppSkeleton"'], /createPromise:.{0,20}(\i\.\i\("?.+?"?\).*?).then\(\i\.bind\(\i,"?(.+?)"?\)\).{0,50}\}\),(?=.{0,15}createPromise.*?\}\),)/);
const ColorIcon = () => {
return (
<svg

View file

@ -54,7 +54,7 @@ export default definePlugin({
replace: "$1arguments[0]?.collected?.isDragging?$self.dragItem():$2",
},
{
match: /\[(\i\.\i)\](?=.{0,5}\[null!=)/,
match: /\[(\i\.\i)\](?=.{0,5}\[\i\?\?)/,
replace: '[arguments[0].collected.isDragging?"":$1]',
},
{
@ -62,11 +62,11 @@ export default definePlugin({
replace: "$1,[collected,drag]=$self.drag(arguments[0])",
},
{
match: /(onFocus".{0,50}\(\i,{ref:)(\i),/,
match: /(onFocus:.{0,50}\(\i,{ref:)(\i),/,
replace: '$1arguments[0]?.descriptor?.category==="FAVORITES"?drag:$2,collected:collected,',
},
{
match: /(,\{key:\i,ref:\i)(?=\}\),)/,
match: /(key:\i,ref:\i)(?=\},\i)/,
replace: '$1,style:{position:"relative"}',
},
{

View file

@ -8,7 +8,7 @@ import "./styles.css";
import { definePluginSettings } from "@api/Settings";
import { Button } from "@components/Button";
import { EquicordDevs, IS_MAC } from "@utils/constants";
import { Devs, IS_MAC } from "@utils/constants";
import { classNameFactory } from "@utils/css";
import { copyWithToast } from "@utils/discord";
import definePlugin, { OptionType } from "@utils/types";
@ -449,7 +449,7 @@ function onToggle(e: KeyboardEvent) {
export default definePlugin({
name: "ElementHighlighter",
description: "Highlight and inspect elements easily.",
authors: [EquicordDevs.prism],
authors: [Devs.prism],
settings,
start() {

View file

@ -68,18 +68,18 @@ export default definePlugin({
find: "Unknown resolution:",
replacement: [
{
match: /throw Error\("Unknown resolution: ".concat\((\i)\)\)/,
match: /throw Error\(`Unknown resolution: \$\{(\i)\}`\)/,
replace: "return $1;"
},
{
match: /throw Error\("Unknown frame rate: ".concat\((\i)\)\)/,
match: /throw Error\(`Unknown frame rate: \$\{(\i)\}`\)/,
replace: "return $1;"
}
]
},
// When focused on voice channel or group chat voice call
{
find: /\i\?\i.\i.SELF_VIDEO/,
find: ".STATUS_WARNING_BACKGROUND})})",
predicate: () => settings.store.noMirroredCamera,
replacement: {
match: /mirror:\i/,
@ -115,7 +115,7 @@ export default definePlugin({
},
},
{
find: ".buttons.length)>=1",
find: ".USER_PROFILE_ACTIVITY_BUTTONS),",
predicate: () => settings.store.showYourOwnActivityButtons && !isPluginEnabled(customRPC.name),
replacement: {
match: /.getId\(\)===\i.id/,

View file

@ -10,7 +10,7 @@ import { playAudio } from "@api/AudioPlayer";
import { NavContextMenuPatchCallback } from "@api/ContextMenu";
import { definePluginSettings } from "@api/Settings";
import { Button } from "@components/Button";
import { EquicordDevs } from "@utils/constants";
import { Devs } from "@utils/constants";
import { classNameFactory } from "@utils/css";
import definePlugin, { OptionType } from "@utils/types";
import { findComponentByCodeLazy } from "@webpack";
@ -104,7 +104,7 @@ let original: typeof ChannelActions.selectVoiceChannel;
export default definePlugin({
name: "ExitSounds",
description: "Play soundboard sounds when you disconnect from voice.",
authors: [EquicordDevs.prism],
authors: [Devs.prism],
dependencies: ["AudioPlayerAPI"],
settings,

View file

@ -93,9 +93,9 @@ export default definePlugin({
},
// Add a proxyUrl prop alongside the src prop, which is used for video thumbnails.
{
find: '"renderOverlayContent","renderLinkComponent"',
find: /disableArrowKeySeek:\i\}\)\}/,
replacement: {
match: /src:\i(?=\})/,
match: /src:\i(?=,\.\.\.\i)/,
replace: "$&,proxyUrl:this.props.src"
}
}

View file

@ -20,7 +20,7 @@ function formatMessageDate(timestamp: string | Date): string {
return `${month}/${day}/${year}`;
}
const GroupDmsRecipientsIcon = findComponentByCodeLazy("\"recipients\",\"size\",");
const GroupDmsRecipientsIcon = findComponentByCodeLazy('["aria-hidden"],"aria-label":');
const SelectedChannelActionCreators = findByPropsLazy("selectPrivateChannel");
function GroupDmsIcon({ channel }: { channel: Channel; }) {

View file

@ -86,7 +86,7 @@ export default definePlugin({
patches: [
// User Popout
{
find: ".hasAvatarForGuild(null==",
find: /onOpenUserProfileModal:\i\}\),\i/,
replacement: {
match: /userId:\i\.id,guild:\i.{0,15}\}\).{0,100}(?=\])/,
replace: "$&,$self.ProfilePopoutComponent(arguments[0])"

View file

@ -89,7 +89,7 @@ export default definePlugin({
{
find: "#{intl::INCOMING_CALL_ELLIPSIS}",
replacement: {
match: /\(\i\)\)\),className:\i\.\i\}\)/,
match: /(?<=onCallJoined:\(\).{0,150})\(\i\)\}\),className:\i\.\i\}\)/,
replace: "$&,$self.renderIgnore(arguments[0].channel)"
}
}

View file

@ -52,7 +52,7 @@ export default definePlugin({
find: ".GUILD_CREATE_INVITE_SUGGESTION,defaultMaxAge",
replacement: [
{
match: /(?<=maxAge:)null!=\(\i=null!=\i\?\i:\i\)\?\i:\i.\i/,
match: /(?<=maxAge:)\i\?\?\i\?\?\i\.\i/,
replace: "$self.settings.store.inviteDuration"
},
{
@ -60,7 +60,7 @@ export default definePlugin({
replace: "$self.settings.store.maxUses"
},
{
match: /(?<=temporary:)null!=\i&&\i/,
match: /(?<=temporary:)\i\?\?!1/,
replace: "$self.settings.store.temporaryMembership"
}
]

View file

@ -113,7 +113,7 @@ export default definePlugin({
// Detects paste events triggered inside of Discord's text input.
find: ",origin:\"clipboard\"});",
replacement: {
match: /(?<="handlePaste",(\i)=>{)(?=var)/,
match: /(?<=handlePaste=(\i)=>{)(?=let)/,
replace: "if($self.isPastingDisabled(true)){$1.preventDefault?.();$1.stopPropagation?.();return;}"
}
},

View file

@ -42,12 +42,9 @@ export default definePlugin({
// Changes text md rule regex, so it stops right before hsl( | rgb(
// Without it discord will try to pass a string without those to color rule
{
find: ".defaultRules.text)",
group: true,
find: ".defaultRules.text,match",
replacement: {
// $)/)
match: /\$\)\//,
// hsl(|rgb(|$&
replace: requiredFirstCharacters.join("|") + "|$&"
}
},

View file

@ -261,7 +261,7 @@ export default definePlugin({
]
},
{
find: "THREAD_STARTER_MESSAGE?null==",
find: ".PREMIUM_REFERRAL&&(",
replacement: {
match: /deleted:\i\.deleted, editHistory:\i\.editHistory,/,
replace: "deleted:$self.getDeleted(...arguments), editHistory:$self.getEdited(...arguments),"

View file

@ -47,10 +47,10 @@ export default definePlugin({
}]
},
{
find: ".gifts)",
find: ".GIFT_PROMOTION]).",
replacement: [
{
match: /(?<=(,\(null==\(\i=\i\.stickers\)\?void 0.*?\i\.push\(\(.{0,100})\},"sticker"\)\))/,
match: /(?<=(,\i\.stickers\?\.button.{0,50}\i\.push\(\(.{0,100})\},"sticker"\)\))/,
replace: "$1,stickersType:\"stickers+\"},\"stickers+\"))"
},
]

View file

@ -29,8 +29,8 @@ export default definePlugin({
{
find: '="ABOVE"',
replacement: {
match: /:300/,
replace: ":0",
match: /\?\?300/,
replace: "??0",
}
},
{

View file

@ -11,7 +11,7 @@ import { findByCodeLazy, findByPropsLazy } from "@webpack";
import { ChannelStore, GuildStore, RelationshipStore, UserStore } from "@webpack/common";
const { getName } = findByPropsLazy("getName", "useName", "getNickname");
const computeChannelName = findByCodeLazy(".isThread())return'\"'.concat(");
const computeChannelName = findByCodeLazy(".isThread())return`\"");
const ChannelTypes = findByPropsLazy("DM", "GUILD_TEXT", "PUBLIC_THREAD", "UNKNOWN");
const ChannelTypesSets = findByPropsLazy("THREADS", "GUILD_TEXTUAL", "ALL_DMS");

View file

@ -168,68 +168,77 @@ export async function getCurrentProfile(guildId?: string): Promise<Omit<ProfileP
};
}
export function loadPresetAsPending(preset: ProfilePreset, guildId?: string) {
function jsonEq(a: any, b: any): boolean {
if (a === b) return true;
return JSON.stringify(a) === JSON.stringify(b);
}
function customStatusEq(a: CustomStatus | null | undefined, b: CustomStatus | null | undefined): boolean {
if (a == null && b == null) return true;
if (a == null || b == null) return false;
return a.text === b.text
&& String(a.emojiId ?? "") === String(b.emojiId ?? "")
&& a.emojiName === b.emojiName
&& String(a.expiresAtMs ?? "0") === String(b.expiresAtMs ?? "0");
}
export async function loadPresetAsPending(preset: ProfilePreset, guildId?: string) {
try {
if (preset.avatarDataUrl) {
const current = await getCurrentProfile(guildId);
if (preset.avatarDataUrl && preset.avatarDataUrl !== current.avatarDataUrl) {
dispatch("USER_SETTINGS_ACCOUNT_SET_PENDING_AVATAR", { guildId, avatar: preset.avatarDataUrl });
}
if (preset.bannerDataUrl) {
if (preset?.bannerDataUrl && preset.bannerDataUrl !== current.bannerDataUrl) {
dispatch("USER_SETTINGS_ACCOUNT_SET_PENDING_BANNER", { guildId, banner: preset.bannerDataUrl });
}
if (preset.bio !== undefined) {
if (preset?.bio && preset.bio !== current.bio) {
dispatch("USER_SETTINGS_ACCOUNT_SET_PENDING_BIO", { guildId, bio: preset.bio });
}
if (preset.pronouns !== undefined) {
if (preset?.pronouns && preset.pronouns !== current.pronouns) {
dispatch("USER_SETTINGS_ACCOUNT_SET_PENDING_PRONOUNS", { guildId, pronouns: preset.pronouns });
}
if (preset.themeColors !== undefined) {
dispatch("USER_SETTINGS_ACCOUNT_SET_PENDING_THEME_COLORS", {
guildId,
themeColors: Array.isArray(preset.themeColors) ? preset.themeColors.map(Number) : null
});
}
if (preset.globalName !== undefined) {
if (preset?.globalName && preset.globalName !== current.globalName) {
dispatch("USER_SETTINGS_ACCOUNT_SET_PENDING_GLOBAL_NAME", { globalName: preset.globalName });
}
if (preset.avatarDecoration !== undefined) {
if (preset?.avatarDecoration && !jsonEq(preset.avatarDecoration, current.avatarDecoration)) {
dispatch("USER_SETTINGS_ACCOUNT_SET_PENDING_COLLECTIBLES_ITEM", {
guildId,
item: { type: 0, value: preset.avatarDecoration }
});
}
if (preset.profileEffect !== undefined) {
if (preset?.profileEffect && !jsonEq(preset.profileEffect, current.profileEffect)) {
dispatch("USER_SETTINGS_ACCOUNT_SET_PENDING_COLLECTIBLES_ITEM", {
guildId,
item: { type: 1, value: preset.profileEffect }
});
}
if (preset.nameplate !== undefined) {
if (preset?.nameplate && !jsonEq(preset.nameplate, current.nameplate)) {
dispatch("USER_SETTINGS_ACCOUNT_SET_PENDING_COLLECTIBLES_ITEM", {
guildId,
item: { type: 2, value: preset.nameplate }
});
}
if (preset.displayNameStyles) {
if (preset?.displayNameStyles && !jsonEq(preset.displayNameStyles, current.displayNameStyles)) {
dispatch("USER_SETTINGS_ACCOUNT_SET_PENDING_DISPLAY_NAME_STYLES", {
guildId,
displayNameStyles: preset.displayNameStyles
});
}
if (preset.primaryGuildId !== undefined && !guildId) {
if (preset?.primaryGuildId && !guildId && preset.primaryGuildId !== current.primaryGuildId) {
dispatch("USER_SETTINGS_SET_PENDING_PRIMARY_GUILD_ID", { primaryGuildId: preset.primaryGuildId });
}
if (preset.customStatus && !guildId) {
if (preset.customStatus && !guildId && !customStatusEq(preset.customStatus, current.customStatus)) {
CustomStatusSettings.updateSetting({
text: preset.customStatus.text || "",
expiresAtMs: preset.customStatus.expiresAtMs || "0",

View file

@ -1050,6 +1050,7 @@ function getQuestPanelTitleText(quest: Quest): string | null {
}
function getQuestPanelOverride(): Quest | null {
settings.use(["triggerQuestsRerender"]);
let closestQuest: Quest | null = null;
let closestTimeRemaining = Infinity;
@ -1079,20 +1080,15 @@ function getQuestPanelOverride(): Quest | null {
});
if (!closestQuest) {
const completedQuests = Array.from(QuestsStore.quests.values() as Quest[]).filter(q => q.userStatus?.completedAt).sort((a, b) => {
const aTime = new Date(a.userStatus?.completedAt as string);
const bTime = new Date(b.userStatus?.completedAt as string);
return bTime.getTime() - aTime.getTime();
});
const completedUnclaimedQuests = (Array.from(QuestsStore.quests.values()) as Quest[])
.filter(q => q.userStatus?.completedAt && getQuestStatus(q) === QuestStatus.Unclaimed)
.sort((a, b) => {
const aTime = new Date(a.userStatus?.completedAt as string).getTime();
const bTime = new Date(b.userStatus?.completedAt as string).getTime();
return bTime - aTime;
});
completedQuests.forEach(quest => {
const completedQuest = quest.userStatus?.completedAt;
const questStatus = getQuestStatus(quest);
if (completedQuest && questStatus === QuestStatus.Unclaimed) {
closestQuest = quest;
}
});
closestQuest = completedUnclaimedQuests[0] ?? null;
}
return closestQuest;
@ -1255,11 +1251,11 @@ export default definePlugin({
{
// Hides the Quest icon from members list items when
// a user is playing a game tied to an active Quest.
find: "),\"activity-\".concat",
find: '"ActivityStatus")',
group: true,
replacement: [
{
match: /(?<=voiceActivityChannel:\i\?\i:null}\);)/,
match: /(?<=\i\)&&"xs"===\i;)/,
replace: "const shouldHideMembersListActivelyPlayingIcon=$self.shouldHideMembersListActivelyPlayingIcon();"
},
{
@ -1288,8 +1284,8 @@ export default definePlugin({
// Allows in-progress Quests to still show.
find: "QUESTS_BAR,questId",
replacement: {
match: /return null==(\i)\?null:\(/,
replace: "return !$self.shouldHideQuestPopup($1)&&("
match: /(?=if\(null==(\i)\)return null;)(.{0,125}?quest:\i}\);return)/,
replace: "const hidePopup=$self.shouldHideQuestPopup($1);$2!hidePopup&&"
}
},
{
@ -1312,15 +1308,15 @@ export default definePlugin({
{
// Replaces the default displayed Quest with the soonest to
// be completed Quest which is actively being auto-completed.
find: "questDeliveryOverride)?",
find: '"useQuestBarQuest"})',
replacement: {
match: /(?<=null}\);return )(\i\?\i:\i)/,
match: /(?<=null\);return )(\i\?\i:\i)/,
replace: "$self.getQuestPanelOverride()??($1)"
}
},
{
// Hides the Friends List "Active Now" promotion.
find: '"application-stream-"',
find: "`application-stream-",
group: true,
replacement: [
{
@ -1345,7 +1341,7 @@ export default definePlugin({
},
{
// QUESTS_FETCH_QUEST_TO_DELIVER_BEGIN
match: /(?=var.{0,150}QUESTS_FETCH_QUEST_TO_DELIVER_BEGIN)/,
match: /(?=let.{0,150}QUESTS_FETCH_QUEST_TO_DELIVER_BEGIN)/,
replace: "if($self.shouldPreventFetchingQuests())return;"
}
]
@ -1356,7 +1352,7 @@ export default definePlugin({
// - Also see anywhere DynamicDropdown is used for refactoring.
//
// Various patches to the SearchableSelect component.
find: '"onSearchChange",',
find: ".popoutLayerContext,renderPopout:",
group: true,
replacement: [
{
@ -1386,8 +1382,8 @@ export default definePlugin({
},
{
// Makes use of the custom popoutClassName prop if provided.
match: /(?<=onKeyDown"]\);return.{0,30}?className:\i\(\)\()/,
replace: "arguments[0]?.popoutClassName,"
match: /"aria-busy":!0,className:\i\(\)\(/,
replace: "$&arguments[0]?.popoutClassName,"
},
{
// Passes the custom optionClassName prop to the row renderer.
@ -1411,13 +1407,13 @@ export default definePlugin({
// Formats the Orbs balance on the Quests page with locale string formatting.
find: '("BalanceCounter")',
replacement: {
match: /(?<=\i=>"".concat\(\i).toFixed\(0\)(?=\)\))/,
match: /(?<=`\$\{\i).toFixed\(0\)(?=\}`)/,
replace: ".toLocaleString(undefined,{maximumFractionDigits:0})"
}
},
{
// Adds a maxDigits prop to the LowerBadge component which allows for not truncating, or for truncating at a specific threshold.
find: '"renderBadgeCount"])',
find: ".INTERACTIVE_TEXT_ACTIVE.css,shape",
group: true,
replacement: [
{
@ -1434,13 +1430,13 @@ export default definePlugin({
// Makes use of the custom prop if provided by using custom logic for negatives and truncation.
// If the prop is not provided, assume default behavior for native badges or other plugins not
// utilizing the custom prop.
match: /function (\i\((\i))\){return (.{0,100}?k\+"\))/,
replace: "function $1,maxDigits){return maxDigits===undefined?($3):$self.formatLowerBadge($2,maxDigits)[0]"
match: /(?<=function \i\((\i))(\){return )(\i<1e3.{0,60}?k\+`)/,
replace: ",maxDigits$2maxDigits===undefined?($3):$self.formatLowerBadge($1,maxDigits)[0]"
}
]
},
{
find: "id:\"quest-tile-\".concat",
find: "id:`quest-tile-",
group: true,
replacement: [
{
@ -1481,7 +1477,7 @@ export default definePlugin({
},
{
// Adds the "Questify" sort option to the sort dropdown.
find: '" has no rewards configured"',
find: "has no rewards configured`",
replacement: {
match: /(?=case (\i.\i).SUGGESTED)/,
replace: "case $1.QUESTIFY:return \"Questify\";"
@ -1528,7 +1524,7 @@ export default definePlugin({
},
{
// Set the initial filters.
match: /(get\(\i\)\)\)\?\i:)(\i)/,
match: /(get\(\i\)\)\?\?)(\i)/,
replace: "$1$self.getLastFilterChoices()??$2"
},
{
@ -1616,7 +1612,7 @@ export default definePlugin({
replace: "const questifyText=$self.getQuestUnacceptedButtonText(arguments[0].quest);"
},
{
match: /(?<=}\),)(null==\i\|\|\i\(\))/,
match: /(?<=}\),)(\i\?\.\(\))/,
replace: "!$self.processQuestForAutoComplete(arguments[0].quest)&&($1)"
},
{

View file

@ -14,9 +14,9 @@ import { formatLowerBadge } from "./misc";
// GuildlessServerListItem's built-in pill does not support unread state.
export const GuildlessServerListItemComponent = findComponentByCodeLazy("tooltip:", "lowerBadgeSize:");
export const GuildedServerListItemPillComponent = findComponentByCodeLazy('"pill":"empty"');
export const ServerListItemLowerBadgeComponent = findComponentByCodeLazy("BADGE_NOTIFICATION_BACKGROUND", '"renderBadgeCount"');
export const ServerListItemLowerBadgeComponent = findComponentByCodeLazy("BADGE_NOTIFICATION_BACKGROUND", "let{count:");
export const ServerListItemUpperBadgeComponent = findComponentByCodeLazy("{icon:", ".ROUND,disableColor");
export const RadioGroup = findComponentByCodeLazy(',["label","description"');
export const RadioGroup = findComponentByCodeLazy(",{label:", ",description:", ",required:", ",errorMessage:", ",children:");
export const QuestTile = findComponentByCodeLazy(".rowIndex,trackGuildAndChannelMetadata");
export enum QuestRewardType {

View file

@ -8,7 +8,7 @@ import { definePluginSettings, Settings, SettingsStore } from "@api/Settings";
import { HeadingSecondary } from "@components/Heading";
import { Paragraph } from "@components/Paragraph";
import { debounce } from "@shared/debounce";
import { EquicordDevs, IS_MAC } from "@utils/constants";
import { Devs, IS_MAC } from "@utils/constants";
import definePlugin, { OptionType, StartAt } from "@utils/types";
import { showToast, Toasts } from "@webpack/common";
@ -244,7 +244,7 @@ const handleThemeNamesChange = () => settings.store.autoRefresh && debouncedRefr
export default definePlugin({
name: "QuickThemeSwitcher",
description: "Quickly switch between themes using keyboard shortcuts.",
authors: [EquicordDevs.prism],
authors: [Devs.prism],
settings,
startAt: StartAt.DOMContentLoaded,
settingsAboutComponent: () => (

View file

@ -58,7 +58,7 @@ const settings = definePluginSettings({
export default definePlugin({
name: "Quoter",
description: "Adds the ability to create an inspirational quote image from a message.",
authors: [Devs.Samwich, Devs.thororen, EquicordDevs.neoarz, EquicordDevs.prism],
authors: [Devs.Samwich, Devs.thororen, EquicordDevs.neoarz, Devs.prism],
settings,
async start() {

View file

@ -11,7 +11,7 @@ import { Canvas } from "./components/Canvas";
import { Toolbar } from "./components/Toolbar";
import { imageToBlob, urlToImage } from "./utils/canvas";
const FileUpload = findComponentByCodeLazy(".currentTarget.files)", "lineClamp:1");
const FileUpload = findComponentByCodeLazy(".currentTarget.files", "lineClamp:1");
export const Editor = (props: { url?: string; }) => {
const [file, setFile] = useState<File | undefined>(undefined);

View file

@ -17,7 +17,7 @@ import RemixModal from "./RemixModal";
import css from "./styles.css?managed";
const requireCreateStickerModal = extractAndLoadChunksLazy([".CREATE_STICKER_MODAL,", "isDisplayingIndividualStickers"]);
const requireSettingsMenu = extractAndLoadChunksLazy(['name:"UserSettings"'], /createPromise:.{0,20}(\i\.\i\("?.+?"?\).*?).then\(\i\.bind\(\i,"?(.+?)"?\)\).{0,50}"UserSettings"/);
const requireSettingsMenu = extractAndLoadChunksLazy(['"AppSkeleton"'], /createPromise:.{0,20}(\i\.\i\("?.+?"?\).*?).then\(\i\.bind\(\i,"?(.+?)"?\)\).{0,50}\}\),(?=.{0,15}createPromise.*?\}\),)/);
const PendingReplyStore = findStoreLazy("PendingReplyStore");
const validMediaTypes = ["image/png", "image/jpeg", "image/jpg", "image/webp"];

View file

@ -8,7 +8,7 @@ import "./styles.css";
import { MessageOptions } from "@api/MessageEvents";
import { definePluginSettings } from "@api/Settings";
import { EquicordDevs } from "@utils/constants";
import { Devs, EquicordDevs } from "@utils/constants";
import definePlugin, { OptionType } from "@utils/types";
import { isScheduleModeEnabled, ScheduledMessagesButton, setScheduleModeEnabled } from "./components/ChatBarButton";
@ -86,7 +86,7 @@ function handleReactionEvent(event: FluxReactionEvent): void {
export default definePlugin({
name: "ScheduledMessages",
description: "Schedule messages to be sent at a specific time or after a delay.",
authors: [EquicordDevs.mmeta, EquicordDevs.prism],
authors: [EquicordDevs.mmeta, Devs.prism],
settings,
flux: {

View file

@ -4,13 +4,13 @@
* SPDX-License-Identifier: GPL-3.0-or-later
*/
import { EquicordDevs } from "@utils/constants";
import { Devs } from "@utils/constants";
import definePlugin from "@utils/types";
export default definePlugin({
name: "ShowSongName",
description: "Shows song name instead of artist for Spotify activity",
authors: [EquicordDevs.prism],
authors: [Devs.prism],
patches: [
{

View file

@ -69,9 +69,9 @@ const WindowLaunchIcon = findComponentByCodeLazy("1-1h6a1 1 0 1 0 0-2H5Z");
const XSmallIcon = findComponentByCodeLazy("1.4L12 13.42l5.3 5.3Z");
const Chat = findComponentByCodeLazy("filterAfterTimestamp:", "chatInputType");
const Resize = findComponentByCodeLazy("sidebarType:", "RESIZE_HANDLE_WIDTH)");
const ChannelHeader = findComponentByCodeLazy(".GUILD_ANNOUNCEMENT", '"channel-".concat');
const ChannelHeader = findComponentByCodeLazy(".GUILD_ANNOUNCEMENT", "`channel-");
const PopoutWindow = findComponentByCodeLazy("Missing guestWindow reference");
const FullChannelView = findComponentByCodeLazy("showFollowButton:(null");
const FullChannelView = findComponentByCodeLazy(/showFollowButton:\i\?\.type===/);
const WanderingCubesLoading = findComponentByCodeLazy('="wanderingCubes"');
const ChatInputTypes = findByPropsLazy("FORM", "NORMAL");
@ -82,7 +82,7 @@ const ChannelSectionStore = findStoreLazy("ChannelSectionStore");
const requireChannelContextMenu = extractAndLoadChunksLazy(
["&&this.handleActivitiesPopoutClose(),"],
new RegExp(DefaultExtractAndLoadChunksRegex.source + ".{1,150}isFavorite")
new RegExp(DefaultExtractAndLoadChunksRegex.source + ".{1,250}hasActiveThread")
);
const requireForumView = extractAndLoadChunksLazy(

View file

@ -134,9 +134,9 @@ export default definePlugin({
},
{
find: '(this,"hideAutocomplete"', // disable file conversion
find: ".onHideAutocomplete?", // disable file conversion
replacement: {
match: /if\(\i.length>\i\)/,
match: /(?<=getData\(\i\.type\);)if\(\i.length>\i\)/,
replace: "if(false)",
},
}

View file

@ -152,7 +152,7 @@ export default definePlugin({
{
find: '"CustomStatusModalWithPreview"',
replacement: {
match: /(?<=(\i)\.state\).*?)\{text:\i\.\i\.\i\(\i\.\i#{intl::SAVE}\)/,
match: /(?<=(\i)\?\.state\?\?.*?)\{text:\i\.\i\.\i\(\i\.\i#{intl::SAVE}\)/,
replace: "$self.renderRememberButton($1),$&"
}
},

View file

@ -133,9 +133,9 @@ export default definePlugin({
authors: [Devs.Samwich],
patches: [
{
find: /\i\.\i\.STICKER_MESSAGE/,
find: ".STICKERS_CONSTANTS_STICKER_DIMENSION)",
replacement: {
match: /}\),\(null!=\i\?\i:(\i)\)\.name]}\);/,
match: /}\),\(\i\?\?\i\)\.name\]\}\);/,
replace: "$& if($self.isBlocked($1.id)) return($self.blockedComponent($1));"
}
}

View file

@ -14,7 +14,7 @@ export default definePlugin({
dependencies: ["MessageUpdaterAPI"],
patches: [
{
find: "}renderEmbeds(",
find: "renderEmbeds(",
replacement: {
match: /(?<=renderEmbeds\(\i\){.+?embeds\.map\(\((\i),\i\)?=>{)/,
replace: "$&if($self.isTidalEmbed($1))return null;"

View file

@ -60,7 +60,7 @@ export default definePlugin({
predicate: () => settings.store.globalMention || settings.store.onlyDMUsers,
},
{
match: /(?<=\i=)\i\.recipients\.map\(.{0,100}:null\}\}\)/,
match: /(?<=\i=)\i\.recipients\.map\(.{0,100}\?\?null\}\)\)/,
replace: "$self.useFilter(true)",
}
],

View file

@ -14,7 +14,7 @@ import { ReadStateStore, useStateFromStores } from "@webpack/common";
const UserGuildSettingsStore = findStoreLazy("UserGuildSettingsStore");
const JoinedThreadsStore = findStoreLazy("JoinedThreadsStore");
const NumberBadge = findComponentByCodeLazy("BADGE_NOTIFICATION_BACKGROUND", '"renderBadgeCount"');
const NumberBadge = findComponentByCodeLazy("BADGE_NOTIFICATION_BACKGROUND", "let{count:");
const settings = definePluginSettings({
showOnMutedChannels: {

View file

@ -10,7 +10,7 @@ import { definePluginSettings } from "@api/Settings";
import { Button } from "@components/Button";
import ErrorBoundary from "@components/ErrorBoundary";
import { Heading } from "@components/Heading";
import { EquicordDevs } from "@utils/constants";
import { Devs } from "@utils/constants";
import { classNameFactory } from "@utils/css";
import definePlugin, { OptionType } from "@utils/types";
import { findComponentByCodeLazy } from "@webpack";
@ -121,14 +121,14 @@ function getMatchingPattern(url: string): PatternEntry | null {
export default definePlugin({
name: "UrlHighlighter",
description: "Highlights URLs in messages that match your patterns.",
authors: [EquicordDevs.prism],
authors: [Devs.prism],
settings,
patches: [
{
find: '"messageId","channelId"',
find: ".MASKED_LINK),",
replacement: {
match: /,children:null!=\i\?\i:\i/,
match: /,children:\i\?\?\i/,
replace: "$&,...$self.getProps(arguments[0])"
}
}

View file

@ -29,7 +29,7 @@ const cl = classNameFactory("vc-userpfp-");
const DONO_URL = "https://ko-fi.com/coolesding";
const INVITE_LINK = "userpfp-1129784704267210844";
export const requireSettingsMenu = extractAndLoadChunksLazy(['name:"UserSettings"'], /createPromise:.{0,20}(\i\.\i\("?.+?"?\).*?).then\(\i\.bind\(\i,"?(.+?)"?\)\).{0,50}"UserSettings"/);
export const requireSettingsMenu = extractAndLoadChunksLazy(['"AppSkeleton"'], /createPromise:.{0,20}(\i\.\i\("?.+?"?\).*?).then\(\i\.bind\(\i,"?(.+?)"?\)\).{0,50}\}\),(?=.{0,15}createPromise.*?\}\),)/);
export const KEY_DATASTORE = "vencord-custom-avatars";
export const data = { avatars: {} as Record<string, string> };

View file

@ -52,11 +52,6 @@ export default definePlugin({
{
find: "#{intl::COMMANDS_OPTIONAL_COUNT}",
replacement: [
{
// ...children: p?.name
match: /(?<=:(\i)\.displayDescription\}.{0,200}children:).{0,50}\.name(?=\}\))/,
replace: "$1.plugin||($&)"
},
{
match: /children:(?=\i\?\?\i\?\.name)(?<=command:(\i),.+?)/,
replace: "children:$1.plugin??"

View file

@ -13,7 +13,8 @@ export default definePlugin({
description: "Allows you to omit either width or height when opening an image modal",
patches: [
{
find: ".renderLinkComponent)?",
// TODO: bundler compat
find: /\.renderLinkComponent[)?]\?/,
replacement: {
// widthAndHeightPassed = w != null && w !== 0 && h == null || h === 0
match: /(?<=\i=)(null!=\i&&0!==\i)&&(null!=\i&&0!==\i)/,

View file

@ -27,7 +27,7 @@ export default definePlugin({
patches: [
{
// Message accessories have a custom logic to decide if they should render again, so we need to make it not ignore changed message reference
find: "}renderEmbeds(",
find: "}renderStickersAccessories(",
replacement: {
match: /(?<=this.props,\i,\[)"message",/,
replace: ""

View file

@ -26,7 +26,7 @@ export default definePlugin({
"Change GIF alt text from simply being 'GIF' to containing the gif tags / filename",
patches: [
{
find: '"onCloseImage",',
find: ".modalContext})};",
replacement: {
match: /(return.{0,10}\.jsx.{0,50}isWindowFocused)/,
replace:

View file

@ -25,11 +25,13 @@ export default definePlugin({
settings,
patches: [
{
find: '"state",{resultType:',
replacement: [{
match: /(?<="state",{resultType:)null/,
replace: '"Favorites"'
}]
find: "renderHeaderContent(){",
replacement: [
{
match: /(?<=state={resultType:)null/,
replace: '"Favorites"'
}
]
},
{
find: "#{intl::NO_GIF_FAVORITES_HOW_TO_FAVORITE}",

View file

@ -23,15 +23,14 @@ import { definePluginSettings } from "@api/Settings";
import ErrorBoundary from "@components/ErrorBoundary";
import { Devs } from "@utils/constants";
import definePlugin, { OptionType } from "@utils/types";
import { findByPropsLazy, findComponentByCodeLazy, findCssClassesLazy, findStoreLazy } from "@webpack";
import { Constants, React, RestAPI, Tooltip } from "@webpack/common";
import { findComponentByCodeLazy, findCssClassesLazy, findStoreLazy } from "@webpack";
import { Constants, React, RestAPI, SettingsRouter, Tooltip } from "@webpack/common";
import { RenameButton } from "./components/RenameButton";
import { Session, SessionInfo } from "./types";
import { fetchNamesFromDataStore, getDefaultName, GetOsColor, GetPlatformIcon, savedSessionsCache, saveSessionsToDataStore } from "./utils";
const AuthSessionsStore = findStoreLazy("AuthSessionsStore");
const UserSettingsModal = findByPropsLazy("saveAccountChanges", "open");
const TimestampClasses = findCssClassesLazy("timestamp", "blockquoteContainer");
const SessionIconClasses = findCssClassesLazy("sessionIcon");
@ -175,7 +174,7 @@ export default definePlugin({
title: "BetterSessions",
body: `New session:\n${session.client_info.os} · ${session.client_info.platform} · ${session.client_info.location}`,
permanent: true,
onClick: () => UserSettingsModal.open("Sessions")
onClick: () => SettingsRouter.openUserSettings("sessions_panel")
});
}

View file

@ -101,8 +101,13 @@ export default definePlugin({
find: "this.renderArtisanalHack()",
replacement: [
{ // Fade in on layer
match: /(?<=\((\i),"contextType",\i\.\i\);)/,
replace: "$1=$self.Layer;",
// class Layer {
// static contextType = ...;
// ...
// }
// class OtherClass {
match: /(static contextType=\i\.\i;.+?})(?=class)(?<=class (\i).+?)/,
replace: (_, before, Layer) => `${before};${Layer}=$self.Layer;`,
predicate: () => settings.store.disableFade
},
{ // Lazy-load contents
@ -129,8 +134,8 @@ export default definePlugin({
{ // Load menu TOC eagerly
find: "#{intl::USER_SETTINGS_WITH_BUILD_OVERRIDE}",
replacement: {
match: /(\i)\(this,"handleOpenSettingsContextMenu",.{0,100}?null!=\i&&.{0,100}?(await [^};]*?\)\)).*?,(?=\1\(this)/,
replace: "$&(async ()=>$2)(),"
match: /(?=handleOpenSettingsContextMenu=.{0,100}?null!=\i&&.{0,100}?(await [^};]*?\)\)))/,
replace: "_vencordBetterSettingsEagerLoad=(async ()=>$1)();"
},
predicate: () => settings.store.eagerLoad
},

View file

@ -49,7 +49,7 @@ export default definePlugin({
patches: [
{
find: "}renderEmbeds(",
find: "}renderStickersAccessories(",
replacement: [
{
match: /(\.renderReactions\(\i\).+?className:)/,

View file

@ -148,10 +148,12 @@ export default definePlugin({
},
{
find: "is not a valid locale.",
replacement: {
match: /\i\.error(?=\(""\.concat\(\i," is not a valid locale."\)\))/,
replace: "$self.Noop"
}
replacement: [
{
match: /\i\.error(?=\(`\$\{\i\} is not a valid locale.`)/,
replace: "$self.Noop"
}
]
},
{
find: '"AppCrashedFatalReport: getLastCrash not supported."',
@ -162,10 +164,12 @@ export default definePlugin({
},
{
find: "RPCServer:WSS",
replacement: {
match: /\i\.error\("Error: "\.concat\((\i)\.message/,
replace: '!$1.message.includes("EADDRINUSE")&&$&'
}
replacement: [
{
match: /\i\.error\(`Error: \$\{(\i)\.message\}/,
replace: '!$1.message.includes("EADDRINUSE")&&$&'
}
]
},
{
find: "Tried getting Dispatch instance before instantiated",
@ -183,17 +187,21 @@ export default definePlugin({
},
{
find: "failed to send analytics events",
replacement: {
match: /console\.error\("\[analytics\] failed to send analytics events query: "\.concat\(\i\)\)/,
replace: ""
}
replacement: [
{
match: /console\.error\(`\[analytics\] failed to send analytics events query: \$\{\i\}`\)/,
replace: ""
}
]
},
{
find: "Slow dispatch on",
replacement: {
match: /\i\.totalTime>\i&&\i\.verbose\("Slow dispatch on ".+?\)\);/,
replace: ""
}
replacement: [
{
match: /\i\.totalTime>\i&&\i\.verbose\([`"]Slow dispatch on.{0,55}\);/,
replace: ""
},
]
},
// Patches Discord generic logger function
{

View file

@ -249,11 +249,13 @@ export default definePlugin({
patches: [
{
find: 'this,"_changeCallbacks",',
replacement: {
match: /\i\(this,"_changeCallbacks",/,
replace: "Reflect.defineProperty(this,Symbol.toStringTag,{value:this.getName(),configurable:!0,writable:!0,enumerable:!1}),$&"
}
find: "&&this.initializeIfNeeded()",
replacement: [
{
match: /\i&&this\.initializeIfNeeded\(\)/,
replace: "$&,Reflect.defineProperty(this,Symbol.toStringTag,{value:this.getName(),configurable:!0,writable:!0,enumerable:!1})"
}
]
}
],

View file

@ -227,7 +227,7 @@ export default definePlugin({
// Discord hides buttons on your own Rich Presence for some reason. This patch disables that behaviour
patches: [
{
find: ".buttons.length)>=1",
find: ".USER_PROFILE_ACTIVITY_BUTTONS),",
replacement: {
match: /.getId\(\)===\i.id/,
replace: "$& && false"

View file

@ -50,7 +50,7 @@ export default definePlugin({
find: "80,onlyAnimateOnHoverOrFocus:!",
replacement: [
{
match: /(?<==)\i=>{let{children.{20,200}isSelected:\i=!1\}=\i/,
match: /(?<==)\i=>{let{children.{20,200}isSelected:\i=!1.{0,5}\}=\i/,
replace: "$self.DecorationGridItem=$&",
},
{
@ -104,7 +104,7 @@ export default definePlugin({
find,
replacement: [
{
match: /(?<=userValue.{0,25}void 0:)((\i)\.avatarDecoration)/,
match: /(?<=userValue:)((\i)(?:.{0,10})?\.avatarDecoration)/,
replace: "$self.useUserDecorAvatarDecoration($2)??$1"
}
]
@ -114,7 +114,7 @@ export default definePlugin({
find: "#{intl::PREMIUM_UPSELL_PROFILE_AVATAR_DECO_INLINE_UPSELL_DESCRIPTION}",
replacement: {
match: /(#{intl::PREMIUM_UPSELL_PROFILE_AVATAR_DECO_INLINE_UPSELL_DESCRIPTION}.+?return null!=(\i)&&\()(null==\i)/,
replace: (_, rest, avatarDecoration, hasPurchase) => `${rest}(${avatarDecoration}.skuId!==$self.SKU_ID&&${hasPurchase})`
replace: (_, rest, avatarDecoration, hasPurchase) => `${rest}(${avatarDecoration}.skuId!==$self.SKU_ID&&${avatarDecoration}.skuId!==$self.RAW_SKU_ID&&${hasPurchase})`
}
}
],
@ -140,6 +140,7 @@ export default definePlugin({
},
SKU_ID,
RAW_SKU_ID,
useUserDecorAvatarDecoration,

View file

@ -19,7 +19,7 @@ import { closeAllModals, ModalCloseButton, ModalContent, ModalFooter, ModalHeade
import { filters, findComponentByCodeLazy, mapMangledModuleLazy } from "@webpack";
import { Button, FluxDispatcher, GuildStore, NavigationRouter, TextInput, useEffect, useMemo, UserStore, useState } from "@webpack/common";
const FileUpload = findComponentByCodeLazy(".currentTarget.files)", "lineClamp:1");
const FileUpload = findComponentByCodeLazy(".currentTarget.files", "lineClamp:1");
const { HelpMessage, HelpMessageTypes } = mapMangledModuleLazy('POSITIVE="positive', {
HelpMessageTypes: filters.byProps("POSITIVE", "WARNING", "INFO"),

View file

@ -51,6 +51,7 @@ export default definePlugin({
authors: [Devs.Ven, Devs.sadan],
reporterTestable: ReporterTestable.None,
isModified: true,
settings,
toolboxActions: {
Reconnect() {

View file

@ -20,7 +20,7 @@ import { React } from "@webpack/common";
import hideBugReport from "./hideBugReport.css?managed";
const KbdStyles = findByPropsLazy("key", "combo");
const BugReporterExperiment = findLazy(m => m?.definition?.id === "2024-09_bug_reporter");
const BugReporterExperiment = findLazy(m => m?.definition?.name === "2026-01-bug-reporter");
const modKey = IS_MAC ? "cmd" : "ctrl";
const altKey = IS_MAC ? "opt" : "alt";
@ -100,6 +100,7 @@ export default definePlugin({
find: "Clear Treatment ",
replacement: [
{
// TODO: stable compat optional chaining remove once some time has passed
match: /\i\??\.isStaff\(\)/,
replace: "true"
},
@ -130,7 +131,7 @@ export default definePlugin({
},
{
// Expands the experiment regex to allow negative numbers as well as text in the last segment of the URL.
find: "?\"dev://experiment/\".concat",
find: '"^dev://experiment/',
replacement: {
match: /(\[0-9\]\+)/,
replace: "[a-zA-Z0-9-]+"
@ -139,11 +140,6 @@ export default definePlugin({
{
find: ".EXPERIMENT_TREATMENT&&null",
replacement: [
{
// Uses the label instead of the value for the button text in the experiment embed.
match: /"Clear Treatment ".concat\((\i).value\):"Apply Treatment ".concat\(\i.value\)/,
replace: '"Clear Treatment: ".concat($1.label):"Apply Treatment: ".concat($1.label)'
},
{
// Allow linking experiments by their label instead of their value.
match: /(?<=find\(\i=>)((\i).value===\i)/,
@ -160,7 +156,7 @@ export default definePlugin({
return !!labelCleaned && urlEndCleaned !== undefined && labelCleaned === urlEndCleaned;
},
start: () => !BugReporterExperiment.getCurrentConfig().hasBugReporterAccess && enableStyle(hideBugReport),
start: () => !BugReporterExperiment.getConfig().hasBugReporterAccess && enableStyle(hideBugReport),
stop: () => disableStyle(hideBugReport),
settingsAboutComponent: () => {

View file

@ -299,13 +299,13 @@ export default definePlugin({
{
// Patch the rendered message content to add fake nitro emojis or remove sticker links
predicate: () => settings.store.transformEmojis || settings.store.transformStickers,
match: /(?=return\{hasSpoilerEmbeds:\i,.{0,15}content:(\i))/,
match: /(?=return{hasSpoilerEmbeds:\i,hasBailedAst:\i,content:(\i))/,
replace: (_, content) => `${content}=$self.patchFakeNitroEmojisOrRemoveStickersLinks(${content},arguments[2]?.formatInline);`
}
]
},
{
find: "}renderEmbeds(",
find: "}renderStickersAccessories(",
replacement: [
{
// Call our function to decide whether the embed should be ignored or not

View file

@ -34,7 +34,7 @@ interface CopyIdMenuItemProps {
}
let CopyIdMenuItem: (props: CopyIdMenuItemProps) => React.ReactElement | null = NoopComponent;
waitFor(filters.componentByCode('"devmode-copy-id-".concat'), m => CopyIdMenuItem = m);
waitFor(filters.componentByCode('"cannot copy null text"'), m => CopyIdMenuItem = m);
function MessageMenu({ message, channel, onHeightUpdate }) {
const canReport = message.author &&

View file

@ -28,7 +28,7 @@ export default definePlugin({
patches: [
{
// Same find as RoleColorEverywhere chatbox mentions
find: ':"text":',
find: '"text":"locked"',
replacement: {
match: /(hidePersonalInformation\).+?)(if\(null!=\i\){.+?return \i)(?=})/,
replace: "$1return $self.UserMentionComponent({...arguments[0],originalComponent:()=>{$2}});"

View file

@ -29,10 +29,10 @@ export default definePlugin({
authors: [Devs.Ven],
patches: [{
find: '"handleSelectGIF",',
find: "handleSelectGIF=",
replacement: {
match: /"handleSelectGIF",(\i)=>\{/,
replace: '"handleSelectGIF",$1=>{if (!this.props.className) return $self.handleSelect($1);'
match: /handleSelectGIF=(\i)=>\{/,
replace: "$&if (!this.props.className) return $self.handleSelect($1);"
}
}],

View file

@ -162,7 +162,7 @@ export default definePlugin({
patches: [
{
find: ".renderLinkComponent)?",
find: "disableArrowKeySeek:!0",
replacement: [
{
match: /useFullWidth:!0,shouldLink:/,

View file

@ -66,11 +66,11 @@ export default definePlugin({
find: "#{intl::LOADING_DID_YOU_KNOW}",
replacement: [
{
match: /"_loadingText".+?(?=(\i)\[.{0,10}\.random)/,
match: /_loadingText.+?(?=(\i)\[.{0,10}\.random)/,
replace: "$&$self.mutateQuotes($1),"
},
{
match: /"_eventLoadingText".+?(?=(\i)\[.{0,10}\.random)/,
match: /_eventLoadingText.+?(?=(\i)\[.{0,10}\.random)/,
replace: "$&$self.mutateQuotes($1),",
predicate: () => settings.store.replaceEvents
}

View file

@ -52,10 +52,12 @@ export default definePlugin({
patches: [{
// HEY THOR UPDATE SHOW ME YOUR NAME IF THIS SHIT CHANGES TY :)
find: ".USER_MENTION)",
replacement: {
match: /"@"\.concat\((null!=\i\?\i:\i)\)(?<=\.useName\((\i)\).+?)/,
replace: "$self.renderUsername({username:$1,user:$2,showMeYourNameMention:typeof showMeYourNameMention!=='undefined'?showMeYourNameMention:undefined})"
}
replacement: [
{
match: /children:`@\$\{(\i\?\?\i)\}`(?<=\.useName\((\i)\).+?)/,
replace: "children:$self.renderUsername({username:$1,user:$2,showMeYourNameMention:typeof showMeYourNameMention!=='undefined'?showMeYourNameMention:undefined})"
}
]
},
{
find: ".ROLE_MENTION)",
@ -66,9 +68,9 @@ export default definePlugin({
},
{
// show avatar in the chat input box
find: '.hasUniqueUsername()?null:"#"',
find: ".hasUniqueUsername()?null:`#",
replacement: {
match: /(?<=,(\i)\).{0,55})"@"\.concat\((\i)\)/,
match: /(?<=,(\i)\).{0,55})`@\$\{(\i)\}`/,
replace: "$self.renderInputMention($2,$1)"
}
}],

View file

@ -200,6 +200,11 @@ const settings = definePluginSettings({
markers: makeRange(50, 500, 50),
default: 150
},
deferDoubleClickForTriple: {
type: OptionType.BOOLEAN,
description: "Delay double-click to allow triple-click actions (disables triple-click when off)",
default: true
},
selectionHoldTimeout: {
type: OptionType.NUMBER,
description: "Timeout to allow text selection (ms)",
@ -538,6 +543,12 @@ export default definePlugin({
}
if (isTripleClick) {
if (!settings.store.deferDoubleClickForTriple) {
mouseDownCount = 0;
doubleClickDetected = false;
secondMouseDownTime = 0;
return;
}
if (doubleClickTimeout) {
clearTimeout(doubleClickTimeout);
doubleClickTimeout = null;
@ -556,7 +567,14 @@ export default definePlugin({
}
const canDoubleClick = (isModifierPressed(doubleClickModifier) || doubleClickModifier === "NONE") && doubleClickAction !== "NONE";
const canTripleClick = isModifierPressed(tripleClickModifier) && tripleClickAction !== "NONE";
const canTripleClick =
settings.store.deferDoubleClickForTriple &&
isModifierPressed(tripleClickModifier) &&
tripleClickAction !== "NONE";
const shouldDeferDoubleClick =
canDoubleClick &&
canTripleClick &&
doubleClickModifier === tripleClickModifier;
if (isDoubleClick) {
doubleClickFired = true;
@ -576,7 +594,7 @@ export default definePlugin({
}
};
if (canTripleClick && canDoubleClick) {
if (shouldDeferDoubleClick) {
if (doubleClickTimeout) {
clearTimeout(doubleClickTimeout);
}
@ -613,8 +631,10 @@ export default definePlugin({
secondMouseDownTime = 0;
};
const hasDoubleClickAction = settings.store.doubleClickAction !== "NONE" || settings.store.doubleClickOthersAction !== "NONE";
if (hasDoubleClickAction && singleClickModifier === "NONE") {
const canDoubleClickWithCurrentModifier =
doubleClickAction !== "NONE" &&
(doubleClickModifier === "NONE" || isModifierPressed(doubleClickModifier));
if (canDoubleClickWithCurrentModifier && singleClickModifier === "NONE") {
singleClickTimeout = setTimeout(() => {
executeSingleClick();
singleClickTimeout = null;

View file

@ -715,7 +715,7 @@ export default definePlugin({
{
// Updated message transformer(?)
find: "THREAD_STARTER_MESSAGE?null==",
find: ".PREMIUM_REFERRAL&&(",
replacement: [
{
// Pass through editHistory & deleted & original attachments to the "edited message" transformer

View file

@ -106,7 +106,7 @@ export default definePlugin({
]
})),
{
find: '"forum-post-action-bar-"',
find: "`forum-post-action-bar-",
replacement: [
{
match: /(?<=\);)(let \i=null,\i=\[\],\i=(\i))/,

View file

@ -15,8 +15,8 @@ export default definePlugin({
{
find: "#{intl::COPY_MESSAGE_LINK}",
replacement: {
match: /\.concat\(location\.host\)/,
replace: ".concat($self.normalizeHost(location.host))",
match: /(?<=(?:.concat\(|\/\/\$\{))location\.host/,
replace: "$self.normalizeHost(location.host)",
},
},
],

View file

@ -47,7 +47,7 @@ const settings = definePluginSettings({
export default definePlugin({
name: "OnePingPerDM",
description: "If unread messages are sent by a user in DMs multiple times, you'll only receive one audio ping. Read the messages to reset the limit",
description: "If unread messages are sent by a user in DMs multiple times, you'll only receive one audio ping.",
authors: [Devs.ProffDea],
isModified: true,
settings,

View file

@ -26,7 +26,8 @@ interface ColorPickerWithSwatchesProps {
const ColorPickerWithSwatches = findComponentByCodeLazy<ColorPickerWithSwatchesProps>('id:"color-picker"');
export const requireSettingsMenu = extractAndLoadChunksLazy(['name:"UserSettings"'], /createPromise:.{0,20}(\i\.\i\("?.+?"?\).*?).then\(\i\.bind\(\i,"?(.+?)"?\)\).{0,50}"UserSettings"/);
// 701663 this is terrible imo
export const requireSettingsMenu = extractAndLoadChunksLazy(['"AppSkeleton"'], /createPromise:.{0,20}(\i\.\i\("?.+?"?\).*?).then\(\i\.bind\(\i,"?(.+?)"?\)\).{0,50}\}\),(?=.{0,15}createPromise.*?\}\),)/);
const cl = classNameFactory("vc-pindms-modal-");

View file

@ -73,7 +73,7 @@ export default definePlugin({
patches: [
{
find: '"private-channels-".concat(',
find: '"dm-quick-launcher"===',
replacement: [
{
// Filter out pinned channels from the private channel list
@ -88,15 +88,15 @@ export default definePlugin({
// Rendering
{
match: /"renderRow",(\i)=>{(?<="renderDM",.+?(\i\.\i),\{channel:.+?)/,
match: /renderRow(?:",|=)(\i)=>{(?<=renderDM(?:",|=).+?(\i\.\i),\{channel:.+?)/,
replace: "$&if($self.isChannelIndex($1.section, $1.row))return $self.renderChannel($1.section,$1.row,$2)();"
},
{
match: /"renderSection",(\i)=>{/,
match: /renderSection(?:",|=)(\i)=>{/,
replace: "$&if($self.isCategoryIndex($1.section))return $self.renderCategory($1);"
},
{
match: /"renderSection".{0,300}?"span",{/,
match: /renderSection(?:",|=).{0,300}?"span",{/,
replace: "$&...$self.makeSpanProps(),"
},
@ -106,7 +106,7 @@ export default definePlugin({
replace: "$1($2-$self.categoryLen())"
},
{
match: /"getRowHeight",\((\i),(\i)\)=>{/,
match: /getRowHeight(?:",|=)\((\i),(\i)\)=>{/,
replace: "$&if($self.isChannelHidden($1,$2))return 0;"
},

View file

@ -40,8 +40,7 @@ export interface Session {
const SessionsStore = findStoreLazy("SessionsStore") as {
getSessions(): Record<string, Session>;
};
const { useStatusFillColor } = mapMangledModuleLazy(".concat(.5625*", {
const { useStatusFillColor } = mapMangledModuleLazy("translate(${.5625*", {
useStatusFillColor: filters.byCode(".hex")
});
@ -261,8 +260,8 @@ export default definePlugin({
},
{
// Fix sizes for mobile indicators which aren't online
match: /(?<=\(\i\.status,)(\i)(?=,(\i),\i\))/,
replace: (_, userStatus, isMobile) => `${isMobile}?"online":${userStatus}`
match: /(?<=\(\i\.status,)(\i)(?=,\{.{0,15}isMobile:(\i))/,
replace: '$2?"online":$1'
},
{
// Make isMobile true no matter the status

View file

@ -32,7 +32,7 @@ export default definePlugin({
{
find: ".removeObscurity,",
replacement: {
match: /(?<="removeObscurity",(\i)=>{)/,
match: /(?<=removeObscurity(?:",|=)(\i)=>{)/,
replace: (_, event) => `$self.reveal(${event});`
}
}

View file

@ -32,7 +32,7 @@ const Transforms = findByPropsLazy("insertNodes", "textToText");
const Editor = findByPropsLazy("start", "end", "toSlateRange");
const ChatInputTypes = findByPropsLazy("FORM", "USER_PROFILE");
const InputComponent = findComponentByCodeLazy("editorClassName", "CHANNEL_TEXT_AREA");
const createChannelRecordFromServer = findByCodeLazy(".GUILD_TEXT])", "fromServer)");
const createChannelRecordFromServer = findByCodeLazy(".GUILD_TEXT]", "fromServer)");
interface UserProps {
discordId: string;

View file

@ -93,7 +93,7 @@ export default definePlugin({
// Slate
{
// Same find as FullUserInChatbox
find: ':"text":',
find: '"text":"locked"',
replacement: [
{
match: /let\{id:(\i),guildId:\i,channelId:(\i)[^}]*\}.*?\.\i,{(?=children)/,

View file

@ -159,7 +159,7 @@ export default definePlugin({
all: true,
// Render null instead of the buttons if the channel is hidden
replacement: {
match: /(?<="renderOpenChatButton",\(\)=>{)/,
match: /(?<=renderOpenChatButton(?:",|=)\(\)=>{)/,
replace: "if($self.isHiddenChannel(this.props.channel))return null;"
}
},
@ -223,7 +223,7 @@ export default definePlugin({
},
{
// Hide the new version of unreads box for hidden channels
find: '"ChannelListUnreadsStore",',
find: '"ChannelListUnreadsStore"',
replacement: {
match: /(?<=\.id\)\))(?=&&\(0,\i\.\i\)\((\i)\))/,
replace: (_, channel) => `&&!$self.isHiddenChannel(${channel})`
@ -250,19 +250,19 @@ export default definePlugin({
find: "Missing channel in Channel.renderHeaderToolbar",
replacement: [
{
match: /"renderHeaderToolbar",\(\)=>{.+?case \i\.\i\.GUILD_TEXT:(?=.+?(\i\.push.{0,50}channel:(\i)},"notifications"\)\)))(?<=isLurking:(\i).+?)/,
match: /renderHeaderToolbar(?:",|=)\(\)=>{.+?case \i\.\i\.GUILD_TEXT:(?=.+?(\i\.push.{0,50}channel:(\i)},"notifications"\)\)))(?<=isLurking:(\i).+?)/,
replace: (m, pushNotificationButtonExpression, channel, isLurking) => `${m}if(!${isLurking}&&$self.isHiddenChannel(${channel})){${pushNotificationButtonExpression};break;}`
},
{
match: /"renderHeaderToolbar",\(\)=>{.+?case \i\.\i\.GUILD_MEDIA:(?=.+?(\i\.push.{0,40}channel:(\i)},"notifications"\)\)))(?<=isLurking:(\i).+?)/,
match: /renderHeaderToolbar(?:",|=)\(\)=>{.+?case \i\.\i\.GUILD_MEDIA:(?=.+?(\i\.push.{0,40}channel:(\i)},"notifications"\)\)))(?<=isLurking:(\i).+?)/,
replace: (m, pushNotificationButtonExpression, channel, isLurking) => `${m}if(!${isLurking}&&$self.isHiddenChannel(${channel})){${pushNotificationButtonExpression};break;}`
},
{
match: /"renderMobileToolbar",\(\)=>{.+?case \i\.\i\.GUILD_DIRECTORY:(?<=let{channel:(\i).+?)/,
match: /renderMobileToolbar(?:",|=)\(\)=>{.+?case \i\.\i\.GUILD_DIRECTORY:(?<=let{channel:(\i).+?)/,
replace: (m, channel) => `${m}if($self.isHiddenChannel(${channel}))break;`
},
{
match: /(?<="renderHeaderBar",\(\)=>{.+?hideSearch:(\i)\.isDirectory\(\))/,
match: /(?<=renderHeaderBar(?:",|=)\(\)=>{.+?hideSearch:(\i)\.isDirectory\(\))/,
replace: (_, channel) => `||$self.isHiddenChannel(${channel})`
},
{
@ -355,7 +355,7 @@ export default definePlugin({
{
// Show only the plus text without overflowed children amount
// if the overflow amount is <= 0 and the component is used inside the HiddenChannelLockScreen
match: /(?<="\+"\.concat\()\i/,
match: /(?<=`\+\$\{)\i(?=\})/,
replace: overflowTextAmount => "" +
`$self.isHiddenChannel(typeof shcChannel!=="undefined"?shcChannel:void 0,true)&&(${overflowTextAmount}-1)<=0?"":${overflowTextAmount}`
}

View file

@ -52,7 +52,7 @@ export default definePlugin({
},
},
{
find: "INVITES_DISABLED))||",
find: /\.INVITES_DISABLED\)(?:\))?\|\|/,
predicate: () => settings.store.showInvitesPaused,
replacement: {
match: /\i\.\i\.can\(\i\.\i.MANAGE_GUILD,\i\)/,

View file

@ -894,7 +894,7 @@ const settings = definePluginSettings({
export default definePlugin({
name: "ShowMeYourName",
description: "Display any permutation of custom nicknames, friend nicknames, server nicknames, display names, and usernames in chat.",
authors: [Devs.Rini, Devs.TheKodeToad, EquicordDevs.Etorix, Devs.sadan, EquicordDevs.prism],
authors: [Devs.Rini, Devs.TheKodeToad, EquicordDevs.Etorix, Devs.sadan, Devs.prism],
tags: ["SMYN", "Nicknames", "Custom Nicknames",],
isModified: true,
settings,
@ -934,7 +934,7 @@ export default definePlugin({
replace: "const showMeYourNameMention=$self.getMentionNameElement(arguments[0]);$1"
},
{
match: /(?<=onContextMenu:\i\},\i\),{children:)/,
match: /(?<=onContextMenu:\i,\.\.\.\i,children:)/,
replace: "showMeYourNameMention??",
predicate: () => !isPluginEnabled(mentionAvatars.name),
}
@ -985,7 +985,7 @@ export default definePlugin({
// Replace names in reaction tooltips.
find: "reactionTooltip1,",
replacement: {
match: /(\i.\i.getName\((\i),null==(?:.{0,15}?)(\i)\))/,
match: /(\i.\i.getName\((\i),\i\?\.id,(\i)\))/,
replace: "$self.getMemberListProfilesReactionsVoiceNameText({user:$3,guildId:$2,type:\"reactionsTooltip\"})??($1)"
}
},

View file

@ -51,7 +51,7 @@ export default definePlugin({
},
},
{
find: '"displayName","SpotifyStore")',
find: "}getPlayableComputerDevices(){",
replacement: [
{
predicate: () => settings.store.noSpotifyAutoPause,

View file

@ -266,7 +266,7 @@ export default definePlugin({
{
find: "!1,hideSimpleEmbedContent",
replacement: {
match: /(let{toAST:.{0,125}?)\(null!=\i\?\i:\i\).content/,
match: /(let{toAST:.{0,125}?)\(\i\?\?\i\).content/,
replace: "const textReplaceContent=$self.modifyIncomingMessage(arguments[2]?.contentMessage??arguments[1]);$1textReplaceContent"
}
},

View file

@ -39,10 +39,12 @@ export default definePlugin({
// popout profiles
{
find: "#{intl::LABEL_WITH_ONLINE_STATUS}",
replacement: {
match: /src:null!=\i\?(\i).{1,50}"aria-hidden":!0/,
replace: "$&,style:$self.getAvatarStyles($1)"
}
replacement: [
{
match: /src:(\i)\?\?void 0.{1,50}"aria-hidden":!0/,
replace: "$&,style:$self.getAvatarStyles($1)"
}
]
},
// chat avatars
{

View file

@ -131,7 +131,7 @@ export default definePlugin({
replace: "$self.renderTypingUsers({ users: arguments[0]?.typingUserObjects, guildId: arguments[0]?.channel?.guild_id, children: $& })"
},
{
match: /(?<=function \i\(\i\)\{)(?=[^}]+?\{channel:\i,isThreadCreation:\i=!1\})/,
match: /(?<=function \i\(\i\)\{)(?=[^}]+?\{channel:\i,isThreadCreation:\i=!1,...\i\})/,
replace: "let typingUserObjects = $self.useTypingUsers(arguments[0]?.channel);"
},
{
@ -150,7 +150,7 @@ export default definePlugin({
]
},
{
find: "\"handleDismissInviteEducation\"",
find: "this.handleDismissInviteEducation",
predicate: () => settings.store.amITyping,
replacement: {
match: /\i\.default\.getCurrentUser\(\)/,

View file

@ -44,7 +44,7 @@ export default definePlugin({
replacement: [
{
// Add next to username (compact mode)
match: /className:\i\(\)\(\i\.className(?:,\i\.clickable)?,\i\)}\)\),(?=\i)/g,
match: /className:\i\(\)\(\i\.className(?:,\i\.\i)?,\i\)\}\)(?:\))?,(?=\i)/g,
replace: "$&$self.CompactPronounsChatComponentWrapper(arguments[0]),",
},
]

View file

@ -58,9 +58,9 @@ export default definePlugin({
settings,
patches: [
{
find: '.banner)==null?"COMPLETE"',
find: ':"SHOULD_LOAD");',
replacement: {
match: /(?<=void 0:)\i.getPreviewBanner\(\i,\i,\i\)/,
match: /\i(?:\?)?.getPreviewBanner\(\i,\i,\i\)(?=.{0,100}"COMPLETE")/,
replace: "$self.patchBannerUrl(arguments[0])||$&"
}

View file

@ -44,10 +44,12 @@ export default definePlugin({
},
{
find: "ReferencedMessageStore",
replacement: {
match: /constructor\(\)\{\i\(this,"_channelCaches",new Map\)/,
replace: "$&;$self.setReplyStore(this);"
}
replacement: [
{
match: /_channelCaches=new Map;/,
replace: "$&_=$self.setReplyStore(this);"
}
]
}
],

View file

@ -205,10 +205,12 @@ export default definePlugin({
// Banners
{
find: 'backgroundColor:"COMPLETE"',
replacement: {
match: /(overflow:"visible",.{0,125}?!1\),)style:{(?=.+?backgroundImage:null!=(\i)\?"url\("\.concat\(\2,)/,
replace: (_, rest, bannerSrc) => `${rest}onClick:()=>${bannerSrc}!=null&&$self.openBanner(${bannerSrc}),style:{cursor:${bannerSrc}!=null?"pointer":void 0,`
}
replacement: [
{
match: /(overflow:"visible",.{0,125}?!1\),)style:{(?=.+?backgroundImage:null!=(\i)\?`url\(\$\{\2\}\))/,
replace: (_, rest, bannerSrc) => `${rest}onClick:()=>${bannerSrc}!=null&&$self.openBanner(${bannerSrc}),style:{cursor:${bannerSrc}!=null?"pointer":void 0,`
}
]
},
// Group DMs top small & large icon
{

View file

@ -282,7 +282,7 @@ export const settings = definePluginSettings({
export default definePlugin({
name: "VoiceMessages",
description: "Allows you to send voice messages like on mobile. To do so, right click the upload button and click Send Voice Message.",
authors: [Devs.Ven, Devs.Vap, Devs.Nickyux, EquicordDevs.Z1xus, EquicordDevs.prism],
authors: [Devs.Ven, Devs.Vap, Devs.Nickyux, EquicordDevs.Z1xus, Devs.prism],
settings,
contextMenus: {

View file

@ -24,9 +24,9 @@ import { saveFile } from "@utils/web";
import { filters, mapMangledModuleLazy } from "@webpack";
import { ComponentDispatch } from "@webpack/common";
const ctxMenuCallbacks = mapMangledModuleLazy('.tagName)==="TEXTAREA"||', {
contextMenuCallbackWeb: filters.byCode('.tagName)==="INPUT"||'),
contextMenuCallbackNative: filters.byCode('.tagName)==="TEXTAREA"||')
const ctxMenuCallbacks = mapMangledModuleLazy('closest("[contenteditable=true]")', {
contextMenuCallbackWeb: filters.byCode('"[contenteditable=true]"'),
contextMenuCallbackNative: filters.byCode('.getPropertyValue("-webkit-user-select")')
});
async function fetchImage(url: string) {

View file

@ -18,17 +18,17 @@ export default definePlugin({
find: "x-google-max-bitrate",
replacement: [
{
match: /"x-google-max-bitrate=".concat\(\i\)/,
replace: '"x-google-max-bitrate=".concat("80_000")'
match: /`x-google-max-bitrate=\$\{\i\}`/,
replace: '"x-google-max-bitrate=80_000"'
},
{
match: ";level-asymmetry-allowed=1",
replace: ";b=AS:800000;level-asymmetry-allowed=1"
},
{
match: /;usedtx=".concat\((\i)\?"0":"1"\)/,
replace: '$&.concat($1?";stereo=1;sprop-stereo=1":"")'
}
match: /;usedtx=\$\{(\i)\?"0":"1"\}/,
replace: '$&${$1?";stereo=1;sprop-stereo=1":""}'
},
]
}
]

View file

@ -110,7 +110,7 @@ export default definePlugin({
find: "cleanAutomaticAnchor(){",
replacement: {
match: /constructor\(\i\)\{(?=.{0,100}automaticAnchor)/,
match: /constructor\(\i\)\{(?=.{0,100}(?:automaticAnchor|\.messages\.loadingMore))/,
replace: "$&$self.setScrollObj(this);"
}
}

View file

@ -107,7 +107,7 @@ waitFor(m => {
}
const str = String(m);
return str.includes(".resolve({theme:null") && !str.includes("useMemo");
return str.includes(".resolve({theme:") && str.includes('"refresh-fast-follow-avatars"') && !str.includes("useMemo");
}, m => useToken = m);
export const MaskedLink = waitForComponent<t.MaskedLink>("MaskedLink", filters.componentByCode("MASKED_LINK)"));

View file

@ -147,7 +147,7 @@ export const UploadHandler = {
export const ApplicationAssetUtils = mapMangledModuleLazy("getAssetImage: size must === [", {
fetchAssetIds: filters.byCode('.startsWith("http:")', ".dispatch({"),
getAssetFromImageURL: filters.byCode("].serialize(", ',":"'),
getAssetFromImageURL: filters.byCode("].serialize(", ":null"),
getAssetImage: filters.byCode("getAssetImage: size must === ["),
getAssets: filters.byCode(".assets")
});
@ -164,7 +164,7 @@ export const ChannelRouter: t.ChannelRouter = mapMangledModuleLazy('"Thread must
});
export let SettingsRouter: any;
waitFor(["open", "saveAccountChanges"], m => SettingsRouter = m);
waitFor(["openUserSettings", "USER_SETTINGS_MODAL_KEY"], m => SettingsRouter = m);
export const PermissionsBits: t.PermissionsBits = findLazy(m => typeof m.ADMINISTRATOR === "bigint");