diff --git a/src/components/Icons.tsx b/src/components/Icons.tsx index 0aea2c5e0..c0ff49a33 100644 --- a/src/components/Icons.tsx +++ b/src/components/Icons.tsx @@ -827,3 +827,141 @@ export const BookmarkIcon = (props?: any) => { ); }; + +export function RobotIcon(props: IconProps) { + return ( + + + + + ); +} + +export function HeadphonesIcon(props: IconProps) { + return ( + + + + ); +} + +export function ShieldIcon(props: IconProps) { + return ( + + + + + ); +} + +export function CircleQuestionIcon(props: IconProps) { + return ( + + + + + ); +} + +export function AttachmentIcon(props: IconProps) { + return ( + + + + ); +} + +export function StickerIcon(props: IconProps) { + return ( + + + + + ); +} + +export function GifIcon(props: IconProps) { + return ( + + + + ); +} + +export function VideoIcon(props: IconProps) { + return ( + + + + ); +} diff --git a/src/equicordplugins/commandPalette/registry.tsx b/src/equicordplugins/commandPalette/registry.tsx index 313dd242c..2007fc3bc 100644 --- a/src/equicordplugins/commandPalette/registry.tsx +++ b/src/equicordplugins/commandPalette/registry.tsx @@ -8,6 +8,7 @@ import { DataStore } from "@api/index"; import { isPluginEnabled, plugins, startPlugin, stopPlugin } from "@api/PluginManager"; import { Settings, SettingsStore } from "@api/Settings"; import { getUserSettingLazy } from "@api/UserSettings"; +import { HeadphonesIcon } from "@components/Icons"; import { openPluginModal } from "@components/settings/tabs"; import { toggleEnabled } from "@equicordplugins/equicordHelper/utils"; import { copyWithToast } from "@utils/discord"; @@ -15,7 +16,7 @@ import { Logger } from "@utils/Logger"; import type { Plugin } from "@utils/types"; import { changes, checkForUpdates } from "@utils/updater"; import { Guild } from "@vencord/discord-types"; -import { findByPropsLazy, findComponentByCodeLazy, findStoreLazy } from "@webpack"; +import { findByPropsLazy, findStoreLazy } from "@webpack"; import { Alerts, ChannelActionCreators, ChannelRouter, ChannelStore, ComponentDispatch, FluxDispatcher, GuildStore, IconUtils, MediaEngineStore, MessageStore, NavigationRouter, React, ReadStateStore, ReadStateUtils, SelectedChannelStore, SelectedGuildStore, SettingsRouter, StreamerModeStore, Toasts, useEffect, UserStore, VoiceActions } from "@webpack/common"; import type { FC, ReactElement, ReactNode } from "react"; @@ -800,7 +801,6 @@ const runtimeCleanupCallbacks: Array<() => void> = []; const NotificationSettingsActionCreators = findByPropsLazy("updateGuildNotificationSettings", "updateChannelOverrideSettings"); const GuildSettingsActions = findByPropsLazy("open", "selectRole", "updateGuild"); const GuildMembershipActions = findByPropsLazy("leaveGuild"); -const HeadphonesIcon = findComponentByCodeLazy("4.1-2.13h1.86A9"); const UserGuildSettingsStore = findStoreLazy("UserGuildSettingsStore"); const NotificationsInboxStore = findStoreLazy("NotificationsInboxStore") as NotificationsInboxStoreLike; const RecentMentionsStore = findStoreLazy("RecentMentionsStore") as RecentMentionsStoreLike; diff --git a/src/equicordplugins/equicordHelper/index.tsx b/src/equicordplugins/equicordHelper/index.tsx index c36754fd4..e32fc9cc3 100644 --- a/src/equicordplugins/equicordHelper/index.tsx +++ b/src/equicordplugins/equicordHelper/index.tsx @@ -9,14 +9,14 @@ import { HeaderBarButton } from "@api/HeaderBar"; import { addMessagePreSendListener, removeMessagePreSendListener } from "@api/MessageEvents"; import { isPluginEnabled } from "@api/PluginManager"; import { definePluginSettings, migratePluginToSettings, Settings } from "@api/Settings"; -import { WarningIcon } from "@components/Icons"; +import { ShieldIcon, WarningIcon } from "@components/Icons"; import customRPC from "@plugins/customRPC"; import { Devs, EquicordDevs, GUILD_ID, SUPPORT_CHANNEL_ID, SUPPORT_CHANNEL_IDS, VC_SUPPORT_CHANNEL_IDS } from "@utils/constants"; import { isAnyPluginDev } from "@utils/misc"; import { t } from "@utils/translation"; import definePlugin, { OptionType } from "@utils/types"; import { StandingState } from "@vencord/discord-types/enums"; -import { findByCodeLazy, findComponentByCodeLazy, findStoreLazy } from "@webpack"; +import { findByCodeLazy, findStoreLazy } from "@webpack"; import { Alerts, ApplicationCommandIndexStore, NavigationRouter, React, SettingsRouter, UserStore, useStateFromStores } from "@webpack/common"; import { ComponentType } from "react"; @@ -31,7 +31,6 @@ let clicked = false; const SafetyHubStore = findStoreLazy("SafetyHubStore"); const fetchSafetyHub: () => Promise = findByCodeLazy("SAFETY_HUB_FETCH_START"); -const ShieldIcon = findComponentByCodeLazy("0 0 1-1.29-.88c-.36-.33-.7-.73-.88-1.13-.33-."); const StandingConfig: Record; }> = { [StandingState.ALL_GOOD]: { label: t("equicord.equicordHelper.standing.allGood"), hoverColor: "var(--status-positive)", Icon: ShieldIcon }, diff --git a/src/equicordplugins/hideMessages/index.tsx b/src/equicordplugins/hideMessages/index.tsx index 3a9c70c37..d480a4d15 100644 --- a/src/equicordplugins/hideMessages/index.tsx +++ b/src/equicordplugins/hideMessages/index.tsx @@ -6,16 +6,13 @@ import { findGroupChildrenByChildId, NavContextMenuPatchCallback } from "@api/ContextMenu"; import { definePluginSettings } from "@api/Settings"; +import { EyeIcon } from "@components/Icons"; import { EquicordDevs } from "@utils/constants"; import { t } from "@utils/translation"; -import definePlugin, { IconComponent, OptionType } from "@utils/types"; +import definePlugin, { OptionType } from "@utils/types"; import { Message } from "@vencord/discord-types"; -import { findComponentByCodeLazy } from "@webpack"; import { ChannelStore, FluxDispatcher, Menu } from "@webpack/common"; -const EyeIconLazy = findComponentByCodeLazy("0-.78-.41l-9.53 6.35c-.42.28-.96.28-1.38"); -const EyeIcon: IconComponent = props => ; - const hideMessage = (messageId: string, channelId: string) => { FluxDispatcher.dispatch({ type: "MESSAGE_DELETE", diff --git a/src/equicordplugins/messagePeek/index.tsx b/src/equicordplugins/messagePeek/index.tsx index d61d36028..99d4a4cc8 100644 --- a/src/equicordplugins/messagePeek/index.tsx +++ b/src/equicordplugins/messagePeek/index.tsx @@ -9,7 +9,7 @@ import "./style.css"; import { DecoratorProps } from "@api/MemberListDecorators"; import { isPluginEnabled } from "@api/PluginManager"; import { definePluginSettings } from "@api/Settings"; -import { ImageIcon, Microphone } from "@components/Icons"; +import { AttachmentIcon, GifIcon, ImageIcon, Microphone, StickerIcon, VideoIcon } from "@components/Icons"; import betterActivities from "@equicordplugins/betterActivities"; import showMeYourName from "@plugins/showMeYourName"; import { Devs, EquicordDevs } from "@utils/constants"; @@ -46,11 +46,11 @@ type IconType = AttachmentType | "voice" | "sticker"; const Icons: Record> = { image: ImageIcon, - file: findComponentByCodeLazy("9.86 0l.54.55a6.99 6.99"), + file: AttachmentIcon, voice: Microphone, - sticker: findComponentByCodeLazy("1-.5.5H6a4 4 0 0 1-4-4V6a4 4 0 0 1 4-4Zm.5 8a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3ZM19"), - gif: findComponentByCodeLazy("3.18 0 0 1-1.12-1.35A4.88 4.8"), - video: findComponentByCodeLazy(" 3-3v-2.12a1"), + sticker: StickerIcon, + gif: GifIcon, + video: VideoIcon, }; const ATTACHMENT_LABELS: Record = { diff --git a/src/equicordplugins/replyPingControl/index.ts b/src/equicordplugins/replyPingControl/index.ts index bc246b829..b73d117e9 100644 --- a/src/equicordplugins/replyPingControl/index.ts +++ b/src/equicordplugins/replyPingControl/index.ts @@ -22,6 +22,11 @@ export const settings = definePluginSettings({ description: "Comma-separated list of User IDs to always receive reply pings from", default: "", disabled: () => settings.store.alwaysPingOnReply, + }, + replyPingBlacklist: { + type: OptionType.STRING, + description: "Comma-separated list of User IDs to never receive reply pings from", + default: "", } }); @@ -29,7 +34,7 @@ export default definePlugin({ name: "ReplyPingControl", description: t("equicord.replyPingControl.description"), tags: ["Chat", "Notifications"], - authors: [Devs.ant0n, EquicordDevs.MrDiamond], + authors: [Devs.ant0n, EquicordDevs.MrDiamond, EquicordDevs.keircn], settings, patches: [{ @@ -47,10 +52,17 @@ export default definePlugin({ const repliedMessage = this.getRepliedMessage(message); if (!repliedMessage || repliedMessage.author.id !== user.id) return; - const whitelist = settings.store.replyPingWhitelist.split(",").map(id => id.trim()); - const isWhitelisted = settings.store.replyPingWhitelist.includes(message.author.id); + const { replyPingBlacklist, replyPingWhitelist, alwaysPingOnReply } = settings.plain; + const authorId = message.author.id; - if (isWhitelisted || settings.store.alwaysPingOnReply) { + if (replyPingBlacklist && replyPingBlacklist.split(",").some(id => id.trim() === authorId)) { + message.mentions = message.mentions.filter(mention => mention.id !== user.id); + return; + } + + const isWhitelisted = replyPingWhitelist && replyPingWhitelist.split(",").some(id => id.trim() === authorId); + + if (isWhitelisted || alwaysPingOnReply) { if (!message.mentions.some(mention => mention.id === user.id)) { message.mentions.push(user as any); } diff --git a/src/equicordplugins/sidebarChat/index.tsx b/src/equicordplugins/sidebarChat/index.tsx index 7f2e48aa3..38579e0f1 100644 --- a/src/equicordplugins/sidebarChat/index.tsx +++ b/src/equicordplugins/sidebarChat/index.tsx @@ -15,13 +15,14 @@ import { getCurrentChannel } from "@utils/discord"; import { t } from "@utils/translation"; import definePlugin from "@utils/types"; import { Channel, Guild, User } from "@vencord/discord-types"; +import { ChannelType } from "@vencord/discord-types/enums"; import { DefaultExtractAndLoadChunksRegex, extractAndLoadChunksLazy, findByPropsLazy, findComponentByCodeLazy, findCssClassesLazy, - findStoreLazy + findStoreLazy, } from "@webpack"; import { ChannelActionCreators, @@ -39,35 +40,18 @@ import { RelationshipStore, SelectedChannelStore, SelectedGuildStore, - ThemeStore, useCallback, useEffect, useLayoutEffect, UserStore, useState, - useStateFromStores + useStateFromStores, } from "@webpack/common"; -import { - getOpenPopoutWindowKeys, - getPersistedPopoutChannelIds, - getPopoutWindowKey, - isPopoutWindowOpen, - settings, - SidebarStore, - syncPersistedPopoutWindows -} from "./store"; +import { getOpenPopoutWindowKeys, getPersistedPopoutChannelIds, getPopoutWindowKey, isPopoutWindowOpen, settings, SidebarStore, syncPersistedPopoutWindows } from "./store"; const cl = classNameFactory("vc-sidebar-chat-"); -const themeParents: Record = { darker: "dark", midnight: "dark" }; -function getThemeClasses(theme: string) { - const parent = themeParents[theme]; - return parent - ? `theme-${parent} theme-${theme} images-${parent}` - : `theme-${theme} images-${theme}`; -} - const HeaderBar = findComponentByCodeLazy("toolbarClassName:", "}),onDoubleClick:"); const ForumView = findComponentByCodeLazy("sidebarState"); @@ -89,8 +73,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-"); +const ChannelHeader = findComponentByCodeLazy("`channel-${"); const PopoutWindow = findComponentByCodeLazy("Missing guestWindow reference"); +const FullChannelView = findComponentByCodeLazy("showFollowButton:"); const WanderingCubesLoading = findComponentByCodeLazy('="wanderingCubes"'); const ChatInputTypes = findByPropsLazy("FORM", "NORMAL"); @@ -307,8 +292,8 @@ const UserContextPatch: NavContextMenuPatchCallback = (children, args: { user: U const ChannelContextPatch: NavContextMenuPatchCallback = (children, args: { channel: Channel; }) => { const checks = [ args.channel, - args.channel.type !== 4, // categories - PermissionStore.can(PermissionsBits.VIEW_CHANNEL, args.channel), + args.channel.type !== ChannelType.GUILD_CATEGORY, + PermissionStore.can(PermissionsBits.VIEW_CHANNEL, args.channel) || args.channel.type === ChannelType.GROUP_DM, ]; if (checks.some(check => !check)) return; children.push(createSidebarChatContextMenuItem(args.channel.id, args.channel.guild_id)); @@ -331,29 +316,50 @@ export default definePlugin({ group: true, replacement: [ { - match: /if\(null!=.{0,50}ROLE_SUBSCRIPTIONS/, - replace: "const vc_SidebarChat=$self.renderSidebar();$&" + match: /ChannelRenderer"\),/, + replace: "$&vc_SidebarChat=$self.renderSidebar()," }, { - match: /=>(\(0,\i\.jsxs?\)\(\i,{}\))/, - replace: "=>[$1, vc_SidebarChat]" + match: /return(\(0,\i\.jsxs?\)\(\i,{}\))}/, + replace: "return [$1, vc_SidebarChat]}" }, { match: /(?<=guild_products.{0,1600})(case \i\.\i.{0,50}return)(.+?\}\));(?=.+?params\.messageId)/g, replace: "$1[$2, vc_SidebarChat];", - predicate: () => settings.store.patchCommunity + predicate: () => settings.store.patchCommunity, }, { match: /(case \i\.\i\.GAME_SERVERS:.{0,50}\.CHANNEL.{0,25}return)(.*?);/, replace: "$1[$2, vc_SidebarChat];", - predicate: () => settings.store.patchCommunity - } - ] + predicate: () => settings.store.patchCommunity, + }, + ], }, ], - settings, + headerBarButton: { + icon: WindowLaunchIcon, + render: () => ( + <> + + + + ) + }, + stop() { + clearPersistedPopoutRestoreLoop(); + syncPersistedPopoutWindows(); + for (const windowKey of getOpenPopoutWindowKeys()) { + PopoutActions.close(windowKey); + } + }, + + async start() { + restorePersistedPopouts(); + }, + + settings, contextMenus: { "user-context": UserContextPatch, "channel-context": ChannelContextPatch, @@ -455,28 +461,11 @@ export default definePlugin({ ); }, - headerBarButton: { - icon: WindowLaunchIcon, - render: () => ( - <> - - - - ) - }, - stop() { - clearPersistedPopoutRestoreLoop(); - syncPersistedPopoutWindows(); - for (const windowKey of getOpenPopoutWindowKeys()) { - PopoutActions.close(windowKey); - } - }, - async start() { - restorePersistedPopouts(); - } }); const Header = ({ guild, channel }: { guild: Guild; channel: Channel; }) => { + const recipientId = channel.isPrivate() ? channel.getRecipientId() as string : null; + const name = useStateFromStores([UserStore, RelationshipStore], () => getChannelTitle(channel), [channel.id, channel.name]); const parentChannel = useStateFromStores( @@ -484,7 +473,6 @@ const Header = ({ guild, channel }: { guild: Guild; channel: Channel; }) => { [channel?.parent_id] ); - // @ts-ignore const closeSidebar = () => FluxDispatcher.dispatch({ type: "VC_SIDEBAR_CHAT_CLOSE", }); const isPopoutOpen = useStateFromStores( @@ -543,51 +531,15 @@ const RenderPopout = ErrorBoundary.wrap(({ channel, name, windowKey }: { channel }); }, [channel?.id]); - const theme = useStateFromStores([ThemeStore], () => ThemeStore?.theme ?? "dark"); - const guild = useStateFromStores([GuildStore], () => channel.guild_id ? GuildStore.getGuild(channel.guild_id) : null, [channel.guild_id]); - - const [View, setViewComponent] = useState(null); - - useEffect(() => { - if (!channel) return; - - if (channel.isForumLikeChannel()) { - requireForumView().then(() => { - setViewComponent( - - ); - }); - - setViewComponent( -
- -
- ); - } else { - setViewComponent( - - ); - } - }, [channel, guild]); - return ( -
- {View} +
+
); diff --git a/src/equicordplugins/songLink.desktop/SongLinker.tsx b/src/equicordplugins/songLink.desktop/SongLinker.tsx index 87a212fb0..1807eee2f 100644 --- a/src/equicordplugins/songLink.desktop/SongLinker.tsx +++ b/src/equicordplugins/songLink.desktop/SongLinker.tsx @@ -6,14 +6,12 @@ import { BaseText } from "@components/BaseText"; import { Card } from "@components/Card"; -import { findComponentByCodeLazy } from "@webpack"; +import { HeadphonesIcon } from "@components/Icons"; import { Button, useEffect, useState } from "@webpack/common"; import pl, { Native, settings, SongLinkResult } from "."; import Providers from "./Providers"; -const HeadphonesIcon = findComponentByCodeLazy("4.1-2.13h1.86A9"); - export default function SongLinker({ url }: { url: string; }) { const [songData, setSongData] = useState(); diff --git a/src/equicordplugins/triviaAI/index.tsx b/src/equicordplugins/triviaAI/index.tsx index e44b814e8..9eaa4aaf8 100644 --- a/src/equicordplugins/triviaAI/index.tsx +++ b/src/equicordplugins/triviaAI/index.tsx @@ -5,19 +5,16 @@ */ import { findGroupChildrenByChildId, NavContextMenuPatchCallback } from "@api/ContextMenu"; +import { RobotIcon } from "@components/Icons"; import { EquicordDevs } from "@utils/constants"; import { t } from "@utils/translation"; -import definePlugin, { IconComponent } from "@utils/types"; +import definePlugin from "@utils/types"; import { Message } from "@vencord/discord-types"; -import { findComponentByCodeLazy } from "@webpack"; import { ChannelStore, Menu } from "@webpack/common"; import { settings } from "./settings"; import { getPayload, getResponse, handleResponse } from "./utils"; -const RobotIconLazy = findComponentByCodeLazy("14.93-4H15a1 "); -const RobotIcon: IconComponent = props => ; - const messageCtxPatch: NavContextMenuPatchCallback = (children, { message }: { message: Message; }) => { const payload = getPayload(message); if (!payload) return; diff --git a/src/plugins/_api/nicknameIcons.ts b/src/plugins/_api/nicknameIcons.ts index 8f8b1fa49..a4ac2f593 100644 --- a/src/plugins/_api/nicknameIcons.ts +++ b/src/plugins/_api/nicknameIcons.ts @@ -18,7 +18,7 @@ export default definePlugin({ replacement: [ { match: /(?<=children:\i\}\):\i,)null!=\i/, - replace: "($&||Vencord.Api.NicknameIcons._renderIcons({userId:arguments[0].user?.id})?.length)" + replace: "($&||!!Vencord.Api.NicknameIcons._renderIcons({userId:arguments[0].user?.id})?.length)" }, { match: /(?<=shouldUnderlineOnHover:null.{0,300})children:(\i)(?=\}\)\])/, diff --git a/src/plugins/crashHandler/index.ts b/src/plugins/crashHandler/index.ts index 0d471c9e3..0006c8f33 100644 --- a/src/plugins/crashHandler/index.ts +++ b/src/plugins/crashHandler/index.ts @@ -16,6 +16,7 @@ * along with this program. If not, see . */ +import { DataStore } from "@api/index"; import { showNotification } from "@api/Notifications"; import { definePluginSettings } from "@api/Settings"; import { Devs } from "@utils/constants"; @@ -77,6 +78,8 @@ export default definePlugin({ ], handleCrash(_this: any, errorState: any) { + DataStore.del("KeepCurrentChannel_previousData"); + if (IS_DEV) { try { if (errorState?.info && "componentStack" in errorState.info) { diff --git a/src/plugins/permissionsViewer/index.tsx b/src/plugins/permissionsViewer/index.tsx index 1d809e3e0..c31a794c3 100644 --- a/src/plugins/permissionsViewer/index.tsx +++ b/src/plugins/permissionsViewer/index.tsx @@ -36,7 +36,7 @@ import openRolesAndUsersPermissionsModal from "./components/RolesAndUsersPermiss import UserPermissions from "./components/UserPermissions"; import { getSortedRolesForMember, sortPermissionOverwrites } from "./utils"; -const PopoutClasses = findCssClassesLazy("container", "scroller", "list"); +const PopoutClasses = findCssClassesLazy("container", "popoutRoleDot"); export const enum PermissionsSortOrder { HighestRole, diff --git a/src/plugins/reviewDB/components/ReviewModal.tsx b/src/plugins/reviewDB/components/ReviewModal.tsx index d7c1467d9..8690c85ce 100644 --- a/src/plugins/reviewDB/components/ReviewModal.tsx +++ b/src/plugins/reviewDB/components/ReviewModal.tsx @@ -33,7 +33,8 @@ import ReviewComponent from "./ReviewComponent"; import ReviewsView, { ReviewsInputComponent } from "./ReviewsView"; const Paginator = findComponentByCodeLazy>('rel:"prev",children:'); -const requirePaginator = extractAndLoadChunksLazy(['name:"SearchResults"'], new RegExp(`${DefaultExtractAndLoadChunksRegex.source}.{0,30}?name:"SearchResults"`)); +// This matches a massive module with ~230k chars so we need an anchor before to prevent REDOS +const requirePaginator = extractAndLoadChunksLazy(['name:"SearchResults"'], new RegExp(`name:"StageChannelCall",renderLoader:.+?(?:${DefaultExtractAndLoadChunksRegex.source}).{0,30}?name:"SearchResults"`)); function Modal({ modalProps, modalKey, discordId, name, type }: { modalProps: any; modalKey: string, discordId: string; name: string; type: ReviewType; }) { const [data, setData] = useState(); diff --git a/src/plugins/showHiddenChannels/index.tsx b/src/plugins/showHiddenChannels/index.tsx index 90b952163..7801fa971 100644 --- a/src/plugins/showHiddenChannels/index.tsx +++ b/src/plugins/showHiddenChannels/index.tsx @@ -241,7 +241,7 @@ export default definePlugin({ }, { // Make the state of the old version of unreads box not include hidden channels - find: "ignoreRecents:!0", + find: "GUILD_EVENT)}),[", replacement: { match: /(?<=\.id\)\))(?=&&\(0,\i\.\i\)\((\i)\))/, replace: "&&!$self.isHiddenChannel($1)" diff --git a/src/plugins/superReactionTweaks/index.ts b/src/plugins/superReactionTweaks/index.ts index 8e500802b..f3f2f676f 100644 --- a/src/plugins/superReactionTweaks/index.ts +++ b/src/plugins/superReactionTweaks/index.ts @@ -54,7 +54,7 @@ export default definePlugin({ { find: ".EMOJI_PICKER_CONSTANTS_EMOJI_CONTAINER_PADDING_HORIZONTAL)", replacement: { - match: /(openPopoutType:void 0(?=.+?isBurstReaction:(\i).+?;(\i===\i\.\i.REACTION)).+?\[\2,\i\]=\i\.useState\().+?\)/, + match: /(openPopoutType:void 0(?=.+?isBurstReaction:(\i).+?;(\i===\i\.\i\.REACTION)&&\i\.push\().+?\[\2,\i\]=\i\.useState\()!1\)/, replace: (_, rest, _isBurstReactionVariable, isReactionIntention) => `${rest}$self.shouldSuperReactByDefault&&${isReactionIntention})` } }