diff --git a/src/equicordplugins/equicordHelper/index.tsx b/src/equicordplugins/equicordHelper/index.tsx index a736a719e..32cee7826 100644 --- a/src/equicordplugins/equicordHelper/index.tsx +++ b/src/equicordplugins/equicordHelper/index.tsx @@ -4,13 +4,14 @@ * SPDX-License-Identifier: GPL-3.0-or-later */ +import { ApplicationCommandInputType, sendBotMessage } from "@api/Commands"; import { isPluginEnabled } from "@api/PluginManager"; import { definePluginSettings } from "@api/Settings"; 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 definePlugin, { OptionType } from "@utils/types"; -import { Alerts, NavigationRouter, UserStore } from "@webpack/common"; +import { Alerts, ApplicationCommandIndexStore, NavigationRouter, UserStore } from "@webpack/common"; import { PluginButtons } from "./pluginButtons"; import { PluginCards } from "./pluginCards"; @@ -47,13 +48,18 @@ const settings = definePluginSettings({ description: "Disable the default hang status when joining voice channels", restartNeeded: true, default: false, + }, + refreshSlashCommands: { + type: OptionType.BOOLEAN, + description: "Refreshes Slash Commands to show newly added commands without restarting your client.", + default: false, } }); export default definePlugin({ name: "EquicordHelper", description: "Used to provide support, fix discord caused crashes, and other misc features.", - authors: [Devs.thororen, EquicordDevs.nyx, EquicordDevs.Naibuu, EquicordDevs.keyages], + authors: [Devs.thororen, EquicordDevs.nyx, EquicordDevs.Naibuu, EquicordDevs.keyages, EquicordDevs.SerStars], required: true, settings, patches: [ @@ -179,5 +185,24 @@ export default definePlugin({ }); } }, - } + }, + commands: [ + { + name: "refresh_commands", + description: "Refresh Slash Commands", + inputType: ApplicationCommandInputType.BUILT_IN, + predicate: () => settings.store.refreshSlashCommands, + execute: async (opts, ctx) => { + try { + sendBotMessage(ctx.channel.id, { content: "Refreshing Slash Commands..." }); + ApplicationCommandIndexStore.indices = {}; + sendBotMessage(ctx.channel.id, { content: "Slash Commands refreshed successfully." }); + } + catch (e) { + console.error("[refreshSlashCommands] Failed to refresh commands:", e); + sendBotMessage(ctx.channel.id, { content: "Failed to refresh commands. Check console for details." }); + } + } + } + ] }); diff --git a/src/equicordplugins/signature/index.tsx b/src/equicordplugins/signature/index.tsx index ea1cce069..918cfc179 100644 --- a/src/equicordplugins/signature/index.tsx +++ b/src/equicordplugins/signature/index.tsx @@ -127,6 +127,7 @@ export default definePlugin({ }, commands: [{ + name: "Signature", description: "Toggle your signature", inputType: ApplicationCommandInputType.BUILT_IN, @@ -144,7 +145,8 @@ export default definePlugin({ content: settings.store.isEnabled ? "Signature enabled!" : "Signature disabled!", }); }, - }], + } + ], }); // text processing injection processor diff --git a/src/plugins/anonymiseFileNames/index.tsx b/src/plugins/anonymiseFileNames/index.tsx index cd92ef311..1109d28a7 100644 --- a/src/plugins/anonymiseFileNames/index.tsx +++ b/src/plugins/anonymiseFileNames/index.tsx @@ -150,23 +150,25 @@ export default definePlugin({ upload.filename = newFilename; }, - commands: [{ - name: "Spoiler", - description: "Toggle your spoiler", - inputType: ApplicationCommandInputType.BUILT_IN, - options: [ - { - name: "value", - description: "Toggle your Spoiler (default is toggle)", - required: false, - type: ApplicationCommandOptionType.BOOLEAN, + commands: [ + { + name: "Spoiler", + description: "Toggle your spoiler", + inputType: ApplicationCommandInputType.BUILT_IN, + options: [ + { + name: "value", + description: "Toggle your Spoiler (default is toggle)", + required: false, + type: ApplicationCommandOptionType.BOOLEAN, + }, + ], + execute: async (args, ctx) => { + settings.store.spoilerMessages = !!findOption(args, "value", !settings.store.spoilerMessages); + sendBotMessage(ctx.channel.id, { + content: settings.store.spoilerMessages ? "Spoiler enabled!" : "Spoiler disabled!", + }); }, - ], - execute: async (args, ctx) => { - settings.store.spoilerMessages = !!findOption(args, "value", !settings.store.spoilerMessages); - sendBotMessage(ctx.channel.id, { - content: settings.store.spoilerMessages ? "Spoiler enabled!" : "Spoiler disabled!", - }); - }, - }], + } + ], }); diff --git a/src/plugins/silentTyping/index.tsx b/src/plugins/silentTyping/index.tsx index b225152b7..25171131a 100644 --- a/src/plugins/silentTyping/index.tsx +++ b/src/plugins/silentTyping/index.tsx @@ -342,96 +342,98 @@ export default definePlugin({ }, ], - commands: [{ - name: "silent-typing", - description: "Hide your typing indicator from chat.", - inputType: ApplicationCommandInputType.BUILT_IN, + commands: [ + { + name: "silent-typing", + description: "Hide your typing indicator from chat.", + inputType: ApplicationCommandInputType.BUILT_IN, - options: [ - { - name: "toggle", - description: "Toggle functionality globally, for the channel, or for the guild.", - required: false, - type: ApplicationCommandOptionType.STRING, - choices: [ - { name: "Global", label: "Global", value: "global" }, - { name: "Channel", label: "Channel", value: "channel" }, - { name: "Guild", label: "Guild", value: "guild" }, - ] - }, - { - name: "chat-bar-indicators", - description: "Hide other users' typing indicators from above the chat bar.", - required: false, - type: ApplicationCommandOptionType.BOOLEAN, - }, - { - name: "members-list-indicators", - description: "Hide other users' typing indicators from the members list.", - required: false, - type: ApplicationCommandOptionType.BOOLEAN, - }, - { - name: "chat-icon", - description: "Show an icon in the chat bar for toggling the plugin on the go.", - required: false, - type: ApplicationCommandOptionType.BOOLEAN, - }, - { - name: "chat-context-menu", - description: "Show a dropdown in the chat context menu to toggle plugin settings on the go.", - required: false, - type: ApplicationCommandOptionType.BOOLEAN, - }, - { - name: "default-hidden", - description: "Whether to hide typing in DMs/channels/guilds by default or not.", - required: false, - type: ApplicationCommandOptionType.BOOLEAN, - } - ], - - execute: async (args, ctx) => { - let updated = false; - const location = findOption(args, "toggle"); - - if (typeof location === "string") { - updated = true; - - if (location === "global") { - toggleGlobal(); - } else { - const locationId = location === "guild" ? ctx.channel.guild_id : ctx.channel.id; - toggleLocation(locationId, getEffectiveList(), settings.store.defaultHidden); + options: [ + { + name: "toggle", + description: "Toggle functionality globally, for the channel, or for the guild.", + required: false, + type: ApplicationCommandOptionType.STRING, + choices: [ + { name: "Global", label: "Global", value: "global" }, + { name: "Channel", label: "Channel", value: "channel" }, + { name: "Guild", label: "Guild", value: "guild" }, + ] + }, + { + name: "chat-bar-indicators", + description: "Hide other users' typing indicators from above the chat bar.", + required: false, + type: ApplicationCommandOptionType.BOOLEAN, + }, + { + name: "members-list-indicators", + description: "Hide other users' typing indicators from the members list.", + required: false, + type: ApplicationCommandOptionType.BOOLEAN, + }, + { + name: "chat-icon", + description: "Show an icon in the chat bar for toggling the plugin on the go.", + required: false, + type: ApplicationCommandOptionType.BOOLEAN, + }, + { + name: "chat-context-menu", + description: "Show a dropdown in the chat context menu to toggle plugin settings on the go.", + required: false, + type: ApplicationCommandOptionType.BOOLEAN, + }, + { + name: "default-hidden", + description: "Whether to hide typing in DMs/channels/guilds by default or not.", + required: false, + type: ApplicationCommandOptionType.BOOLEAN, } - } + ], - const updateChatIcon = findOption(args, "chat-icon"); + execute: async (args, ctx) => { + let updated = false; + const location = findOption(args, "toggle"); - if (typeof updateChatIcon === "boolean") { - updated = true; - settings.store.chatIcon = !!updateChatIcon; - } + if (typeof location === "string") { + updated = true; - const updateChatContextMenu = findOption(args, "chat-context-menu"); + if (location === "global") { + toggleGlobal(); + } else { + const locationId = location === "guild" ? ctx.channel.guild_id : ctx.channel.id; + toggleLocation(locationId, getEffectiveList(), settings.store.defaultHidden); + } + } - if (typeof updateChatContextMenu === "boolean") { - updated = true; - settings.store.chatContextMenu = !!updateChatContextMenu; - } + const updateChatIcon = findOption(args, "chat-icon"); - const updateDefaultHidden = findOption(args, "default-hidden"); + if (typeof updateChatIcon === "boolean") { + updated = true; + settings.store.chatIcon = !!updateChatIcon; + } - if (typeof updateDefaultHidden === "boolean") { - updated = true; - settings.store.defaultHidden = !!updateDefaultHidden; - } + const updateChatContextMenu = findOption(args, "chat-context-menu"); - sendBotMessage(ctx.channel.id, { - content: updated ? "Silent typing settings updated." : "No changes made to silent typing settings.", - }); - }, - }], + if (typeof updateChatContextMenu === "boolean") { + updated = true; + settings.store.chatContextMenu = !!updateChatContextMenu; + } + + const updateDefaultHidden = findOption(args, "default-hidden"); + + if (typeof updateDefaultHidden === "boolean") { + updated = true; + settings.store.defaultHidden = !!updateDefaultHidden; + } + + sendBotMessage(ctx.channel.id, { + content: updated ? "Silent typing settings updated." : "No changes made to silent typing settings.", + }); + }, + } + ], async startTyping(channelId: string) { if (checkEnabled(channelId)) return; diff --git a/src/webpack/common/stores.ts b/src/webpack/common/stores.ts index f1ea29a93..30457f3dc 100644 --- a/src/webpack/common/stores.ts +++ b/src/webpack/common/stores.ts @@ -78,6 +78,7 @@ export let InviteStore: t.InviteStore; export let LocaleStore: t.LocaleStore; export let RTCConnectionStore: t.RTCConnectionStore; export let SoundboardStore: t.SoundboardStore; +export let ApplicationCommandIndexStore: GenericStore; /** * @see jsdoc of {@link t.useStateFromStores} @@ -128,6 +129,7 @@ waitForStore("InviteStore", m => InviteStore = m); waitForStore("LocaleStore", m => LocaleStore = m); waitForStore("RTCConnectionStore", m => RTCConnectionStore = m); waitForStore("SoundboardStore", m => SoundboardStore = m); +waitForStore("ApplicationCommandIndexStore", m => ApplicationCommandIndexStore = m); waitForStore("ThemeStore", m => { ThemeStore = m; // Importing this directly causes all webpack commons to be imported, which can easily cause circular dependencies.