From e091f7f700fdedd3a259747dd11bede882420bf4 Mon Sep 17 00:00:00 2001 From: prism Date: Sun, 28 Dec 2025 02:18:36 +0100 Subject: [PATCH] General Fixes (#599) * Settings: fix restart state tracking * JumpTo: refactor * Anammox: fix billing/payment tab patch --- .../settings/tabs/plugins/index.tsx | 7 +- src/equicordplugins/anammox/index.ts | 16 +-- src/equicordplugins/jumpTo/index.tsx | 117 ++++++++++++++---- 3 files changed, 105 insertions(+), 35 deletions(-) diff --git a/src/components/settings/tabs/plugins/index.tsx b/src/components/settings/tabs/plugins/index.tsx index bd2d5dfba..00d0a9b9f 100644 --- a/src/components/settings/tabs/plugins/index.tsx +++ b/src/components/settings/tabs/plugins/index.tsx @@ -150,9 +150,10 @@ export default function PluginSettings() { if (!changes.hasChanges) return; const allChanges = [...changes.getChanges()]; + const pluginNames = [...new Set(allChanges.map(s => s.split(":")[0]))]; const maxDisplay = 15; - const displayed = allChanges.slice(0, maxDisplay); - const remainingCount = allChanges.length - displayed.length; + const displayed = pluginNames.slice(0, maxDisplay); + const remainingCount = pluginNames.length - displayed.length; Alerts.show({ title: "Restart required", @@ -264,7 +265,7 @@ export default function PluginSettings() { return lodash.isEqual(newPlugins, sortedPluginNames) ? null : new Set(newPlugins); })); - const handleRestartNeeded = useCallback((name: string) => changes.handleChange(name), [changes]); + const handleRestartNeeded = useCallback((name: string, key: string) => changes.handleChange(`${name}:${key}`), [changes]); const { plugins, requiredPlugins } = useMemo(() => { const plugins = [] as JSX.Element[]; diff --git a/src/equicordplugins/anammox/index.ts b/src/equicordplugins/anammox/index.ts index 76325941b..87731a054 100644 --- a/src/equicordplugins/anammox/index.ts +++ b/src/equicordplugins/anammox/index.ts @@ -89,17 +89,11 @@ export default definePlugin({ }, { // Settings, sidebar - find: "#{intl::BILLING_SETTINGS}", - replacement: [ - { - match: /(?<=#{intl::BILLING_SETTINGS}[^,]*?,)(?=div)/, - replace: "capitalism:true," - }, - { - match: /\i\?\i:\i\.toSpliced\(3,0,\i\)/, - replace: "($&).filter(e=>!e.capitalism)", - }, - ], + find: ".BILLING_SECTION,", + replacement: { + match: /(?<=buildLayout:\(\)=>)\[.+?\]/, + replace: "[]", + }, predicate: () => settings.store.billing, }, { diff --git a/src/equicordplugins/jumpTo/index.tsx b/src/equicordplugins/jumpTo/index.tsx index 1d2279048..e74dfc913 100644 --- a/src/equicordplugins/jumpTo/index.tsx +++ b/src/equicordplugins/jumpTo/index.tsx @@ -7,51 +7,126 @@ import { NavContextMenuPatchCallback } from "@api/ContextMenu"; import { Devs } from "@utils/constants"; import definePlugin from "@utils/types"; -import { Menu, NavigationRouter, RestAPI } from "@webpack/common"; +import { Channel, Message, User } from "@vencord/discord-types"; +import { Constants, Menu, NavigationRouter, RestAPI, SelectedChannelStore, SelectedGuildStore, Toasts } from "@webpack/common"; -function jumpToFirstMessage(props) { - const guildid = props.guild_id !== null ? props.guild_id : "@me"; - const channelid = props.id; - const url = `/channels/${guildid}/${channelid}/0`; +function jumpToFirstMessage(channelId: string, guildId?: string | null) { + const url = `/channels/${guildId ?? "@me"}/${channelId}/0`; NavigationRouter.transitionTo(url); } -async function jumpToBottom(props) { - const guildid = props.guild_id ?? "@me"; - const channelid = props.id; +async function jumpToLastMessage(channelId: string, guildId?: string | null) { const res = await RestAPI.get({ - url: `/channels/${channelid}/messages?limit=1` + url: Constants.Endpoints.MESSAGES(channelId), + query: { limit: 1 } }); - const lastMessageId = res.body?.[0]?.id; - if (!lastMessageId) return; + const messageId = res.body?.[0]?.id; + if (!messageId) return; - const url = `/channels/${guildid}/${channelid}/${lastMessageId}`; + const url = `/channels/${guildId ?? "@me"}/${channelId}/${messageId}`; NavigationRouter.transitionTo(url); } -const MenuPatch: NavContextMenuPatchCallback = (children, { channel }) => { +async function jumpToUserMessage(channelId: string, guildId: string, userId: string, first: boolean) { + try { + const res = await RestAPI.get({ + url: Constants.Endpoints.SEARCH_GUILD(guildId), + query: { + author_id: userId, + channel_id: channelId, + sort_by: "timestamp", + sort_order: first ? "asc" : "desc" + } + }); + + const messageId = res.body?.messages?.[0]?.[0]?.id; + if (!messageId) { + Toasts.show({ + type: Toasts.Type.FAILURE, + message: "No messages found from this user in this channel.", + id: Toasts.genId() + }); + return; + } + + const url = `/channels/${guildId}/${channelId}/${messageId}`; + NavigationRouter.transitionTo(url); + } catch (e) { + Toasts.show({ + type: Toasts.Type.FAILURE, + message: "Failed to search for messages.", + id: Toasts.genId() + }); + } +} + +const ChannelMenuPatch: NavContextMenuPatchCallback = (children, { channel }: { channel: Channel; }) => { + if (!channel) return; + children.push( jumpToFirstMessage(channel)} + action={() => jumpToFirstMessage(channel.id, channel.guild_id)} />, jumpToBottom(channel)} + id="vc-jump-to-last" + label="Jump To Last Message" + action={() => jumpToLastMessage(channel.id, channel.guild_id)} + /> + ); +}; + +const UserMenuPatch: NavContextMenuPatchCallback = (children, { user, channel }: { user: User; channel?: Channel; }) => { + if (!user) return; + + if (!channel || channel.guild_id) return; + + children.push( + jumpToFirstMessage(channel.id, null)} + />, + jumpToLastMessage(channel.id, null)} + /> + ); +}; + +const MessageMenuPatch: NavContextMenuPatchCallback = (children, { message }: { message: Message; }) => { + if (!message) return; + + const channelId = SelectedChannelStore.getChannelId(); + const guildId = SelectedGuildStore.getGuildId(); + if (!channelId || !guildId) return; + + children.push( + jumpToUserMessage(channelId, guildId, message.author.id, true)} + />, + jumpToUserMessage(channelId, guildId, message.author.id, false)} /> ); }; export default definePlugin({ name: "JumpTo", - description: "Adds context menu options to jump to the start or bottom of a channel/DM", + description: "Adds context menu options to jump to the start or bottom of a channel/DM.", authors: [Devs.Samwich, Devs.thororen], contextMenus: { - "channel-context": MenuPatch, - "user-context": MenuPatch, - "thread-context": MenuPatch + "channel-context": ChannelMenuPatch, + "gdm-context": ChannelMenuPatch, + "thread-context": ChannelMenuPatch, + "user-context": UserMenuPatch, + "message": MessageMenuPatch } });