diff --git a/src/api/ContextMenu.ts b/src/api/ContextMenu.ts index 16f9f32b5..4e5213164 100644 --- a/src/api/ContextMenu.ts +++ b/src/api/ContextMenu.ts @@ -118,7 +118,12 @@ interface ContextMenuProps { onClose: (callback: (...args: Array) => any) => void; } +const patchedMenus = new WeakSet(); + export function _patchContextMenu(props: ContextMenuProps) { + if (patchedMenus.has(props)) return; + patchedMenus.add(props); + props.contextMenuApiArguments ??= []; const contextMenuPatches = navPatches.get(props.navId); diff --git a/src/plugins/devCompanion.dev.tsx b/src/plugins/devCompanion.dev.tsx index b84dd75dc..e9b739426 100644 --- a/src/plugins/devCompanion.dev.tsx +++ b/src/plugins/devCompanion.dev.tsx @@ -238,8 +238,6 @@ function initWs(isManual = false) { } const contextMenuPatch: NavContextMenuPatchCallback = kids => { - if (kids.some(k => k?.props?.id === NAV_ID)) return; - kids.unshift( child?.props?.id === "emote-cloner")) - group.push(buildMenuItem(favoriteableId, name, isGifUrl(itemHref ?? itemSrc))); + if (group) group.push(buildMenuItem(favoriteableId, name, isGifUrl(itemHref ?? itemSrc))); }; const expressionPickerPatch: NavContextMenuPatchCallback = (children, props: { target: HTMLElement; }) => { @@ -230,8 +229,7 @@ const expressionPickerPatch: NavContextMenuPatchCallback = (children, props: { t const firstChild = props.target.firstChild as HTMLImageElement; - if (!children.some(c => c?.props?.id === "emote-cloner")) - children.push(buildMenuItem(id, name, firstChild && isGifUrl(firstChild.src))); + children.push(buildMenuItem(id, name, firstChild && isGifUrl(firstChild.src))); }; export default definePlugin({ diff --git a/src/plugins/fakeNitro.tsx b/src/plugins/fakeNitro.tsx index c2b81d122..4a4f47d6d 100644 --- a/src/plugins/fakeNitro.tsx +++ b/src/plugins/fakeNitro.tsx @@ -136,6 +136,11 @@ const settings = definePluginSettings({ default: true, restartNeeded: true }, + transformCompoundSentence: { + description: "Whether to transform fake stickers and emojis in compound sentences (sentences with more content than just the fake emoji or sticker link)", + type: OptionType.BOOLEAN, + default: false + }, enableStreamQualityBypass: { description: "Allow streaming in nitro quality", type: OptionType.BOOLEAN, @@ -305,45 +310,6 @@ export default definePlugin({ } ], - options: { - enableEmojiBypass: { - description: "Allow sending fake emojis", - type: OptionType.BOOLEAN, - default: true, - restartNeeded: true, - }, - emojiSize: { - description: "Size of the emojis when sending", - type: OptionType.SLIDER, - default: 48, - markers: [32, 48, 64, 128, 160, 256, 512], - }, - transformEmojis: { - description: "Whether to transform fake emojis into real ones", - type: OptionType.BOOLEAN, - default: true, - restartNeeded: true, - }, - enableStickerBypass: { - description: "Allow sending fake stickers", - type: OptionType.BOOLEAN, - default: true, - restartNeeded: true, - }, - stickerSize: { - description: "Size of the stickers when sending", - type: OptionType.SLIDER, - default: 160, - markers: [32, 64, 128, 160, 256, 512], - }, - enableStreamQualityBypass: { - description: "Allow streaming in nitro quality", - type: OptionType.BOOLEAN, - default: true, - restartNeeded: true, - } - }, - get guildId() { return getCurrentGuild()?.id; }, @@ -419,7 +385,7 @@ export default definePlugin({ }, patchFakeNitroEmojisOrRemoveStickersLinks(content: Array, inline: boolean) { - if (content.length > 1) return content; + if (content.length > 1 && !settings.store.transformCompoundSentence) return content; const newContent: Array = []; @@ -442,7 +408,7 @@ export default definePlugin({ const emojiName = EmojiStore.getCustomEmojiById(fakeNitroMatch[1])?.name ?? url?.searchParams.get("name") ?? "FakeNitroEmoji"; newContent.push(Parser.defaultRules.customEmoji.react({ - jumboable: !inline, + jumboable: !inline && content.length === 1, animated: fakeNitroMatch[2] === "gif", emojiId: fakeNitroMatch[1], name: emojiName, @@ -466,8 +432,8 @@ export default definePlugin({ newContent.push(element); } - const firstTextElementIdx = newContent.findIndex(element => typeof element === "string"); - if (firstTextElementIdx !== -1) newContent[firstTextElementIdx] = newContent[firstTextElementIdx].trimStart(); + const firstContent = newContent[0]; + if (typeof firstContent === "string") newContent[0] = firstContent.trimStart(); return newContent; }, @@ -476,7 +442,8 @@ export default definePlugin({ const itemsToMaybePush: Array = []; const contentItems = message.content.split(/\s/); - if (contentItems.length === 1) itemsToMaybePush.push(contentItems[0]); + if (contentItems.length === 1 && !settings.store.transformCompoundSentence) itemsToMaybePush.push(contentItems[0]); + else itemsToMaybePush.push(...contentItems); itemsToMaybePush.push(...message.attachments.filter(attachment => attachment.content_type === "image/gif").map(attachment => attachment.url)); @@ -517,7 +484,7 @@ export default definePlugin({ }, shouldIgnoreEmbed(embed: Message["embeds"][number], message: Message) { - if (message.content.split(/\s/).length > 1) return false; + if (message.content.split(/\s/).length > 1 && !settings.store.transformCompoundSentence) return false; switch (embed.type) { case "image": { diff --git a/src/plugins/imageZoom/index.tsx b/src/plugins/imageZoom/index.tsx index 6014756a2..d65df08b5 100644 --- a/src/plugins/imageZoom/index.tsx +++ b/src/plugins/imageZoom/index.tsx @@ -76,56 +76,54 @@ export const settings = definePluginSettings({ const imageContextMenuPatch: NavContextMenuPatchCallback = (children, _) => { - if (!children.some(child => child?.props?.id === "image-zoom")) { - children.push( - - {/* thanks SpotifyControls */} - ( - settings.store.zoom = value, 100)} - /> - )} - /> - ( - settings.store.size = value, 100)} - /> - )} - /> - ( - settings.store.zoomSpeed = value, 100)} - renderValue={(value: number) => `${value.toFixed(3)}x`} - /> - )} - /> - - ); - } + children.push( + + {/* thanks SpotifyControls */} + ( + settings.store.zoom = value, 100)} + /> + )} + /> + ( + settings.store.size = value, 100)} + /> + )} + /> + ( + settings.store.zoomSpeed = value, 100)} + renderValue={(value: number) => `${value.toFixed(3)}x`} + /> + )} + /> + + ); }; export default definePlugin({ diff --git a/src/plugins/messageLogger/index.tsx b/src/plugins/messageLogger/index.tsx index 8199271a3..808fd3431 100644 --- a/src/plugins/messageLogger/index.tsx +++ b/src/plugins/messageLogger/index.tsx @@ -49,7 +49,6 @@ const patchMessageContextMenu: NavContextMenuPatchCallback = (children, props) = const { deleted, editHistory, id, channel_id } = message; if (!deleted && !editHistory?.length) return; - if (children.some(c => c?.props?.id === MENU_ITEM_ID)) return; children.push(( { const pronouns = await bulkFetchPronouns(ids); for (const id of ids) { // Call all callbacks for the id - requestQueue[id].forEach(c => c(pronouns[id])); + requestQueue[id]?.forEach(c => c(pronouns[id])); delete requestQueue[id]; } }); diff --git a/src/plugins/reverseImageSearch.tsx b/src/plugins/reverseImageSearch.tsx index 4e0a3614d..74b261994 100644 --- a/src/plugins/reverseImageSearch.tsx +++ b/src/plugins/reverseImageSearch.tsx @@ -43,7 +43,7 @@ const imageContextMenuPatch: NavContextMenuPatchCallback = (children, props) => const src = itemHref ?? itemSrc; const group = findGroupChildrenByChildId("copy-link", children); - if (group && !group.some(child => child?.props?.id === "search-image")) { + if (group) { group.push(( { - if (seen.has(children)) return; - seen.add(children); - const memberAvatar = GuildMemberStore.getMember(guildId!, user.id)?.avatar || null; children.splice(1, 0, ( @@ -111,9 +106,6 @@ const UserContext: NavContextMenuPatchCallback = (children, { user, guildId }: U }; const GuildContext: NavContextMenuPatchCallback = (children, { guild: { id, icon, banner } }: GuildContextProps) => { - if (seen.has(children)) return; - seen.add(children); - if (!banner && !icon) return; // before copy id (if it exists)