diff --git a/package.json b/package.json index 01fe3552b..1bc01bac3 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "vencord", "private": "true", - "version": "1.8.8", + "version": "1.8.9", "description": "The cutest Discord client mod", "homepage": "https://github.com/Vendicated/Vencord#readme", "bugs": { diff --git a/src/debug/runReporter.ts b/src/debug/runReporter.ts index 9135b5e81..798ea00e1 100644 --- a/src/debug/runReporter.ts +++ b/src/debug/runReporter.ts @@ -4,6 +4,7 @@ * SPDX-License-Identifier: GPL-3.0-or-later */ +import { SYM_LAZY_COMPONENT_INNER } from "@utils/lazyReact"; import { Logger } from "@utils/Logger"; import { SYM_PROXY_INNER_GET, SYM_PROXY_INNER_VALUE } from "@utils/proxyInner"; import * as Webpack from "@webpack"; @@ -81,8 +82,8 @@ async function runReporter() { result = findResult[SYM_PROXY_INNER_VALUE]; } - if (findResult.$$vencordInner != null) { - result = findResult.$$vencordInner(); + if (findResult[SYM_LAZY_COMPONENT_INNER] != null) { + result = findResult[SYM_LAZY_COMPONENT_INNER](); } } diff --git a/src/plugins/experiments/index.tsx b/src/plugins/experiments/index.tsx index a8499ca60..ab2d04a97 100644 --- a/src/plugins/experiments/index.tsx +++ b/src/plugins/experiments/index.tsx @@ -16,12 +16,13 @@ * along with this program. If not, see . */ +import { definePluginSettings } from "@api/Settings"; import { disableStyle, enableStyle } from "@api/Styles"; import ErrorBoundary from "@components/ErrorBoundary"; import { ErrorCard } from "@components/ErrorCard"; import { Devs } from "@utils/constants"; import { Margins } from "@utils/margins"; -import definePlugin from "@utils/types"; +import definePlugin, { OptionType } from "@utils/types"; import { findByProps } from "@webpack"; import { Forms, React } from "@webpack/common"; @@ -29,6 +30,15 @@ import hideBugReport from "./hideBugReport.css?managed"; const KbdStyles = findByProps("key", "removeBuildOverride"); +const settings = definePluginSettings({ + toolbarDevMenu: { + type: OptionType.BOOLEAN, + description: "Change the Help (?) toolbar button (top right in chat) to Discord's developer menu", + default: false, + restartNeeded: true + } +}); + export default definePlugin({ name: "Experiments", description: "Enable Access to Experiments & other dev-only features in Discord!", @@ -40,6 +50,8 @@ export default definePlugin({ Devs.Nuckyz ], + settings, + patches: [ { find: "Object.defineProperties(this,{isDeveloper", @@ -68,6 +80,16 @@ export default definePlugin({ replacement: { match: /\i\.isStaff\(\)/, replace: "true" + }, + predicate: () => settings.store.toolbarDevMenu + }, + + // makes the Favourites Server experiment allow favouriting DMs and threads + { + find: "useCanFavoriteChannel", + replacement: { + match: /!\(\i\.isDM\(\)\|\|\i\.isThread\(\)\)/, + replace: "true", } } ], diff --git a/src/plugins/fakeNitro/index.tsx b/src/plugins/fakeNitro/index.tsx index 30aa5f63c..40e344cea 100644 --- a/src/plugins/fakeNitro/index.tsx +++ b/src/plugins/fakeNitro/index.tsx @@ -337,7 +337,7 @@ export default definePlugin({ { // Call our function to decide whether the embed should be ignored or not predicate: () => settings.store.transformEmojis || settings.store.transformStickers, - match: /(renderEmbeds\((\i)\){)(.+?embeds\.map\((\i)=>{)/, + match: /(renderEmbeds\((\i)\){)(.+?embeds\.map\(\((\i),\i\)?=>{)/, replace: (_, rest1, message, rest2, embed) => `${rest1}const fakeNitroMessage=${message};${rest2}if($self.shouldIgnoreEmbed(${embed},fakeNitroMessage))return null;` }, { diff --git a/src/plugins/messageLinkEmbeds/index.tsx b/src/plugins/messageLinkEmbeds/index.tsx index d3d14b3e5..43a370339 100644 --- a/src/plugins/messageLinkEmbeds/index.tsx +++ b/src/plugins/messageLinkEmbeds/index.tsx @@ -280,6 +280,8 @@ function getChannelLabelAndIconUrl(channel: Channel) { } function ChannelMessageEmbedAccessory({ message, channel }: MessageEmbedProps): JSX.Element | null { + const compact = TextAndImagesSettingsStores.MessageDisplayCompact.useSetting(); + const dmReceiver = UserStore.getUser(ChannelStore.getChannel(channel.id).recipients?.[0]); const [channelLabel, iconUrl] = getChannelLabelAndIconUrl(channel); @@ -304,6 +306,7 @@ function ChannelMessageEmbedAccessory({ message, channel }: MessageEmbedProps): message={message} channel={channel} subscribeToComponentDispatch={false} + compact={compact} /> )} diff --git a/src/plugins/messageLogger/index.tsx b/src/plugins/messageLogger/index.tsx index 12a1e920d..e2da7ce79 100644 --- a/src/plugins/messageLogger/index.tsx +++ b/src/plugins/messageLogger/index.tsx @@ -302,7 +302,7 @@ export default definePlugin({ replace: "$1" + ".update($3,m =>" + " (($2.message.flags & 64) === 64 || $self.shouldIgnore($2.message, true)) ? m :" + - " $2.message.content !== m.editHistory?.[0]?.content && $2.message.content !== m.content ?" + + " $2.message.edited_timestamp && $2.message.content !== m.content ?" + " m.set('editHistory',[...(m.editHistory || []), $self.makeEdit($2.message, m)]) :" + " m" + ")" + diff --git a/src/plugins/moreUserTags/index.tsx b/src/plugins/moreUserTags/index.tsx index d60414ff5..2710e840c 100644 --- a/src/plugins/moreUserTags/index.tsx +++ b/src/plugins/moreUserTags/index.tsx @@ -19,6 +19,7 @@ import { definePluginSettings } from "@api/Settings"; import { Flex } from "@components/Flex"; import { Devs } from "@utils/constants"; +import { LazyComponentType } from "@utils/lazyReact"; import { Margins } from "@utils/margins"; import definePlugin, { OptionType } from "@utils/types"; import { findByProps, findComponentByCode } from "@webpack"; @@ -56,7 +57,7 @@ const PermissionUtil = findByProps("computePermissions", "canEveryoneRole") as { computePermissions({ ...args }): bigint; }; -const Tag = findComponentByCode(".DISCORD_SYSTEM_MESSAGE_BOT_TAG_TOOLTIP_OFFICIAL,") as React.ComponentType<{ type?: number, className?: string, useRemSizes?: boolean; }> & { Types: Record; }; +const Tag = findComponentByCode(".DISCORD_SYSTEM_MESSAGE_BOT_TAG_TOOLTIP_OFFICIAL,") as LazyComponentType<{ type?: number, className?: string, useRemSizes?: boolean; }> & { Types: Record; }; const isWebhook = (message: Message, user: User) => !!message?.webhookId && user.isNonUserBot(); diff --git a/src/plugins/pinDms/components/CreateCategoryModal.tsx b/src/plugins/pinDms/components/CreateCategoryModal.tsx index ea73ec724..e82cd194e 100644 --- a/src/plugins/pinDms/components/CreateCategoryModal.tsx +++ b/src/plugins/pinDms/components/CreateCategoryModal.tsx @@ -6,7 +6,7 @@ import { classNameFactory } from "@api/Styles"; import { ModalContent, ModalFooter, ModalHeader, ModalProps, ModalRoot, openModalLazy } from "@utils/modal"; -import { extractAndLoadChunksLazy, findComponentByCode } from "@webpack"; +import { extractAndLoadChunksLazy, findComponentByCode, findExportedComponent } from "@webpack"; import { Button, Forms, Text, TextInput, Toasts, useEffect, useState } from "@webpack/common"; import { DEFAULT_COLOR, SWATCHES } from "../constants"; @@ -31,7 +31,7 @@ interface ColorPickerWithSwatchesProps { } const ColorPicker = findComponentByCode(".Messages.USER_SETTINGS_PROFILE_COLOR_SELECT_COLOR", ".BACKGROUND_PRIMARY)"); -const ColorPickerWithSwatches = findComponentByCode("presets,", "customColor:"); +const ColorPickerWithSwatches = findExportedComponent("ColorPicker", "CustomColorPicker"); export const requireSettingsMenu = extractAndLoadChunksLazy(['name:"UserSettings"'], /createPromise:.{0,20}Promise\.all\((\[\i\.\i\(".+?"\).+?\])\).then\(\i\.bind\(\i,"(.+?)"\)\).{0,50}"UserSettings"/); diff --git a/src/plugins/resurrectHome/README.md b/src/plugins/resurrectHome/README.md deleted file mode 100644 index 2d26635d2..000000000 --- a/src/plugins/resurrectHome/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# ResurrectHome - -Brings back the phased out [Server Home](https://support.discord.com/hc/en-us/articles/6156116949911-Server-Home-Beta) feature! - -![](https://github.com/Vendicated/Vencord/assets/61953774/98d5d667-bbb9-48b8-872d-c9b3980f6506) diff --git a/src/plugins/resurrectHome/index.tsx b/src/plugins/resurrectHome/index.tsx deleted file mode 100644 index 884d66e5d..000000000 --- a/src/plugins/resurrectHome/index.tsx +++ /dev/null @@ -1,195 +0,0 @@ -/* - * Vencord, a modification for Discord's desktop app - * Copyright (c) 2023 Vendicated and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ - -import { findGroupChildrenByChildId } from "@api/ContextMenu"; -import { definePluginSettings } from "@api/Settings"; -import ErrorBoundary from "@components/ErrorBoundary"; -import { Devs } from "@utils/constants"; -import definePlugin, { OptionType } from "@utils/types"; -import { findByProps } from "@webpack"; -import { Button, Menu, Tooltip, useEffect, useState } from "@webpack/common"; - -const ChannelRowClasses = findByProps("modeConnected", "modeLocked", "icon"); - -let currentShouldViewServerHome = false; -const shouldViewServerHomeStates = new Set>>(); - -function ViewServerHomeButton() { - return ( - - {tooltipProps => ( - - )} - - ); -} - -function useForceServerHome() { - const { forceServerHome } = settings.use(["forceServerHome"]); - const [shouldViewServerHome, setShouldViewServerHome] = useState(currentShouldViewServerHome); - - useEffect(() => { - shouldViewServerHomeStates.add(setShouldViewServerHome); - - return () => { - shouldViewServerHomeStates.delete(setShouldViewServerHome); - }; - }, []); - - return shouldViewServerHome || forceServerHome; -} - -function useDisableViewServerHome() { - useEffect(() => () => { - currentShouldViewServerHome = false; - for (const setState of shouldViewServerHomeStates) { - setState(false); - } - }, []); -} - -const settings = definePluginSettings({ - forceServerHome: { - type: OptionType.BOOLEAN, - description: "Force the Server Guide to be the Server Home tab when it is enabled.", - default: false - } -}); - -export default definePlugin({ - name: "ResurrectHome", - description: "Re-enables the Server Home tab when there isn't a Server Guide. Also has an option to force the Server Home over the Server Guide, which is accessible through right-clicking a server.", - authors: [Devs.Dolfies, Devs.Nuckyz], - settings, - - patches: [ - // Force home deprecation override - { - find: "GuildFeatures.GUILD_HOME_DEPRECATION_OVERRIDE", - all: true, - replacement: [ - { - match: /\i\.hasFeature\(\i\.GuildFeatures\.GUILD_HOME_DEPRECATION_OVERRIDE\)/g, - replace: "true" - } - ], - }, - // Disable feedback prompts - { - find: "GuildHomeFeedbackExperiment.definition.id", - replacement: [ - { - match: /return{showFeedback:.+?,setOnDismissedFeedback:(\i)}/, - replace: "return{showFeedback:false,setOnDismissedFeedback:$1}" - } - ] - }, - // This feature was never finished, so the patch is disabled - - // Enable guild feed render mode selector - // { - // find: "2022-01_home_feed_toggle", - // replacement: [ - // { - // match: /showSelector:!1/, - // replace: "showSelector:true" - // } - // ] - // }, - - // Fix focusMessage clearing previously cached messages and causing a loop when fetching messages around home messages - { - find: '"MessageActionCreators"', - replacement: { - match: /focusMessage\(\i\){.+?(?=focus:{messageId:(\i)})/, - replace: "$&after:$1," - } - }, - // Force Server Home instead of Server Guide - { - find: "61eef9_2", - replacement: { - match: /getMutableGuildChannelsForGuild\(\i\);return\(0,\i\.useStateFromStores\).+?\]\)(?=}function)/, - replace: m => `${m}&&!$self.useForceServerHome()` - } - }, - // Add View Server Home Button to Server Guide - { - find: "487e85_1", - replacement: { - match: /(?<=text:(\i)\?\i\.\i\.Messages\.SERVER_GUIDE:\i\.\i\.Messages\.GUILD_HOME,)/, - replace: "trailing:$self.ViewServerHomeButton({serverGuide:$1})," - } - }, - // Disable view Server Home override when the Server Home is unmouted - { - find: "69386d_5", - replacement: { - match: /location:"69386d_5".+?;/, - replace: "$&$self.useDisableViewServerHome();" - } - } - ], - - ViewServerHomeButton: ErrorBoundary.wrap(({ serverGuide }: { serverGuide?: boolean; }) => { - if (serverGuide !== true) return null; - - return ; - }), - - useForceServerHome, - useDisableViewServerHome, - - contextMenus: { - "guild-context"(children, props) { - const { forceServerHome } = settings.use(["forceServerHome"]); - - if (!props?.guild) return; - - const group = findGroupChildrenByChildId("hide-muted-channels", children); - - group?.unshift( - settings.store.forceServerHome = !forceServerHome} - /> - ); - } - } -}); diff --git a/src/plugins/showConnections/index.tsx b/src/plugins/showConnections/index.tsx index 2f490a467..952f28175 100644 --- a/src/plugins/showConnections/index.tsx +++ b/src/plugins/showConnections/index.tsx @@ -210,9 +210,9 @@ export default definePlugin({ } }, { - find: "autoFocusNote:!0})", + find: ".UserProfileTypes.BITE_SIZE,onOpenProfile", replacement: { - match: /{autoFocusNote:!1}\)}\)(?<=user:(\i),bio:null==(\i)\?.+?)/, + match: /currentUser:\i,guild:\i,onOpenProfile:.+?}\)(?=])(?<=user:(\i),bio:null==(\i)\?.+?)/, replace: "$&,$self.profilePopoutComponent({ user: $1, displayProfile: $2, simplified: true })" } } diff --git a/src/plugins/showHiddenChannels/index.tsx b/src/plugins/showHiddenChannels/index.tsx index 0ea842954..6dcabe878 100644 --- a/src/plugins/showHiddenChannels/index.tsx +++ b/src/plugins/showHiddenChannels/index.tsx @@ -73,9 +73,8 @@ export default definePlugin({ find: '"placeholder-channel-id"', replacement: [ // Remove the special logic for channels we don't have access to - // FIXME Remove variable matcher from threadsIds when it hits stable { - match: /if\(!\i\.\i\.can\(\i\.\i\.VIEW_CHANNEL.+?{if\(this\.id===\i\).+?threadIds:(?:\[\]|\i)}}/, + match: /if\(!\i\.\i\.can\(\i\.\i\.VIEW_CHANNEL.+?{if\(this\.id===\i\).+?threadIds:\[\]}}/, replace: "" }, // Do not check for unreads when selecting the render level if the channel is hidden diff --git a/src/plugins/viewIcons/index.tsx b/src/plugins/viewIcons/index.tsx index 9d1745116..a0ee5bcf9 100644 --- a/src/plugins/viewIcons/index.tsx +++ b/src/plugins/viewIcons/index.tsx @@ -184,7 +184,7 @@ export default definePlugin({ patches: [ // Profiles Modal pfp - ...["User Profile Modal - Context Menu", ".UserProfileTypes.FULL_SIZE,hasProfileEffect:"].map(find => ({ + ...[".UserProfileTypes.MODAL,hasProfileEffect", ".UserProfileTypes.FULL_SIZE,hasProfileEffect:"].map(find => ({ find, replacement: { match: /\{src:(\i)(?=,avatarDecoration)/, diff --git a/src/utils/constants.ts b/src/utils/constants.ts index a288341a0..459c0266e 100644 --- a/src/utils/constants.ts +++ b/src/utils/constants.ts @@ -37,7 +37,7 @@ export const Devs = /* #__PURE__*/ Object.freeze({ id: 0n, }, Ven: { - name: "Vendicated", + name: "Vee", id: 343383572805058560n }, Arjix: { @@ -326,7 +326,7 @@ export const Devs = /* #__PURE__*/ Object.freeze({ id: 305288513941667851n }, ImLvna: { - name: "Luna <3", + name: "lillith <3", id: 799319081723232267n }, rad: { diff --git a/src/utils/lazyReact.tsx b/src/utils/lazyReact.tsx index 3a8a9ebc0..20988e1ec 100644 --- a/src/utils/lazyReact.tsx +++ b/src/utils/lazyReact.tsx @@ -6,6 +6,10 @@ import { makeLazy } from "./lazy"; +export type LazyComponentType = React.ComponentType & Record; + +export const SYM_LAZY_COMPONENT_INNER = Symbol.for("vencord.lazyComponent.inner"); + /** * A lazy component. The factory method is called on first render. * @@ -13,10 +17,10 @@ import { makeLazy } from "./lazy"; * @param attempts How many times to try to get the component before giving up * @returns Result of factory function */ -export function LazyComponent(factory: () => React.ComponentType, attempts = 5) { +export function LazyComponent(factory: () => LazyComponentType, attempts = 5) { const get = makeLazy(factory, attempts, { isIndirect: true }); - let InnerComponent = null as React.ComponentType | null; + let InnerComponent = null as LazyComponentType | null; let lazyFailedLogged = false; const LazyComponent = (props: T) => { @@ -39,5 +43,7 @@ export function LazyComponent(factory: () => React.Compo return InnerComponent && ; }; - return LazyComponent as React.ComponentType; + LazyComponent[SYM_LAZY_COMPONENT_INNER] = () => InnerComponent; + + return LazyComponent as LazyComponentType; } diff --git a/src/webpack/common/types/menu.d.ts b/src/webpack/common/types/menu.d.ts index 0b8ab5c66..d5f92d630 100644 --- a/src/webpack/common/types/menu.d.ts +++ b/src/webpack/common/types/menu.d.ts @@ -18,7 +18,7 @@ import type { ComponentType, CSSProperties, MouseEvent, PropsWithChildren, ReactNode, UIEvent } from "react"; -type RC = ComponentType>>; +type RC = ComponentType>>; export interface Menu { Menu: RC<{ diff --git a/src/webpack/webpack.tsx b/src/webpack/webpack.tsx index ba657cb1f..30527d85d 100644 --- a/src/webpack/webpack.tsx +++ b/src/webpack/webpack.tsx @@ -5,7 +5,7 @@ */ import { makeLazy, proxyLazy } from "@utils/lazy"; -import { LazyComponent } from "@utils/lazyReact"; +import { LazyComponent, LazyComponentType, SYM_LAZY_COMPONENT_INNER } from "@utils/lazyReact"; import { Logger } from "@utils/Logger"; import { canonicalizeMatch } from "@utils/patches"; import { ProxyInner, proxyInner, SYM_PROXY_INNER_VALUE } from "@utils/proxyInner"; @@ -204,13 +204,13 @@ export function find(filter: FilterFn, callback: (module: ModuleE * @param parse A function that takes the found component as its first argument and returns a component. Useful if you want to wrap the found component in something. Defaults to the original component * @returns The component if found, or a noop component */ -export function findComponent(filter: FilterFn, parse: (component: ModuleExports) => React.ComponentType = m => m, { isIndirect = false }: { isIndirect?: boolean; } = {}) { +export function findComponent(filter: FilterFn, parse: (component: ModuleExports) => LazyComponentType = m => m, { isIndirect = false }: { isIndirect?: boolean; } = {}) { if (typeof filter !== "function") throw new Error("Invalid filter. Expected a function got " + typeof filter); if (typeof parse !== "function") throw new Error("Invalid component parse. Expected a function got " + typeof parse); - let InnerComponent = null as React.ComponentType | null; + let InnerComponent = null as LazyComponentType | null; let findFailedLogged = false; const WrapperComponent = (props: T) => { @@ -222,23 +222,21 @@ export function findComponent(filter: FilterFn, parse: ( return InnerComponent && ; }; + WrapperComponent[SYM_LAZY_COMPONENT_INNER] = () => InnerComponent; + waitFor(filter, (v: any) => { const parsedComponent = parse(v); InnerComponent = parsedComponent; Object.assign(WrapperComponent, parsedComponent); }, { isIndirect: true }); - if (IS_REPORTER) { - WrapperComponent.$$vencordInner = () => InnerComponent; - - if (!isIndirect) { - webpackSearchHistory.push(["findComponent", [WrapperComponent, filter]]); - } + if (IS_REPORTER && !isIndirect) { + webpackSearchHistory.push(["findComponent", [WrapperComponent, filter]]); } if (InnerComponent !== null) return InnerComponent; - return WrapperComponent as React.ComponentType; + return WrapperComponent as LazyComponentType; } /** @@ -251,13 +249,13 @@ export function findComponent(filter: FilterFn, parse: ( * @param parse A function that takes the found component as its first argument and returns a component. Useful if you want to wrap the found component in something. Defaults to the original component * @returns The component if found, or a noop component */ -export function findExportedComponent(...props: string[] | [...string[], (component: ModuleExports) => React.ComponentType]) { - const parse = (typeof props.at(-1) === "function" ? props.pop() : m => m) as (component: ModuleExports) => React.ComponentType; +export function findExportedComponent(...props: string[] | [...string[], (component: ModuleExports) => LazyComponentType]) { + const parse = (typeof props.at(-1) === "function" ? props.pop() : m => m) as (component: ModuleExports) => LazyComponentType; const newProps = props as string[]; const filter = filters.byProps(...newProps); - let InnerComponent = null as React.ComponentType | null; + let InnerComponent = null as LazyComponentType | null; let findFailedLogged = false; const WrapperComponent = (props: T) => { @@ -269,6 +267,7 @@ export function findExportedComponent(...props: string[] return InnerComponent && ; }; + WrapperComponent[SYM_LAZY_COMPONENT_INNER] = () => InnerComponent; waitFor(filter, (v: any) => { const parsedComponent = parse(v[newProps[0]]); @@ -277,13 +276,12 @@ export function findExportedComponent(...props: string[] }, { isIndirect: true }); if (IS_REPORTER) { - WrapperComponent.$$vencordInner = () => InnerComponent; webpackSearchHistory.push(["findExportedComponent", [WrapperComponent, ...newProps]]); } if (InnerComponent !== null) return InnerComponent; - return WrapperComponent as React.ComponentType; + return WrapperComponent as LazyComponentType; } /** @@ -296,8 +294,8 @@ export function findExportedComponent(...props: string[] * @param parse A function that takes the found component as its first argument and returns a component. Useful if you want to wrap the found component in something. Defaults to the original component * @returns The component if found, or a noop component */ -export function findComponentByCode(...code: string[] | [...string[], (component: ModuleExports) => React.ComponentType]) { - const parse = (typeof code.at(-1) === "function" ? code.pop() : m => m) as (component: ModuleExports) => React.ComponentType; +export function findComponentByCode(...code: string[] | [...string[], (component: ModuleExports) => LazyComponentType]) { + const parse = (typeof code.at(-1) === "function" ? code.pop() : m => m) as (component: ModuleExports) => LazyComponentType; const newCode = code as string[]; const ComponentResult = findComponent(filters.componentByCode(...newCode), parse, { isIndirect: true }); @@ -526,7 +524,7 @@ export function webpackDependantLazy(factory: () => T, attempts?: * @param attempts How many times to try to get the component before giving up * @returns Result of factory function */ -export function webpackDependantLazyComponent(factory: () => any, attempts?: number) { +export function webpackDependantLazyComponent(factory: () => any, attempts?: number) { if (IS_REPORTER) webpackSearchHistory.push(["webpackDependantLazyComponent", [factory]]); return LazyComponent(factory, attempts);