diff --git a/README.md b/README.md index 19f7535e..11c3bb09 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ You can join our [discord server](https://discord.gg/5Xh2W87egW) for commits, ch ### Extra included plugins
-163 additional plugins +164 additional plugins ### All Platforms @@ -172,6 +172,7 @@ You can join our [discord server](https://discord.gg/5Xh2W87egW) for commits, ch - Woof by Samwich - WriteUpperCase by Samwich & KrystalSkull - YoutubeDescription by arHSM +- LastActive by Crxa ### Web Only diff --git a/src/equicordplugins/lastActive/index.tsx b/src/equicordplugins/lastActive/index.tsx new file mode 100644 index 00000000..c07e4367 --- /dev/null +++ b/src/equicordplugins/lastActive/index.tsx @@ -0,0 +1,146 @@ +/* + * Vencord, a Discord client mod + * Copyright (c) 2025 Vendicated and contributors + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +import { NavContextMenuPatchCallback } from "@api/ContextMenu"; +import { EquicordDevs } from "@utils/constants"; +import definePlugin from "@utils/types"; +import { findByPropsLazy } from "@webpack"; +import { Menu, NavigationRouter, Toasts } from "@webpack/common"; +const MessageStore = findByPropsLazy("getMessages", "getMessage"); +const ChannelStore = findByPropsLazy("getChannel", "getDMFromUserId"); +const UserStore = findByPropsLazy("getUser", "getCurrentUser"); +const MessageActions = findByPropsLazy("fetchMessages", "searchMessages"); + +async function findLastMessageFromUser(channelId: string, userId: string) { + try { + + if (!MessageStore || !MessageActions) { + Toasts.show({ + type: Toasts.Type.FAILURE, + message: "Required Discord modules not found.", + id: Toasts.genId() + }); + return null; + } + const messageCollection = MessageStore.getMessages(channelId); + let messages = messageCollection?.toArray() || []; + let userMessage = messages.filter(m => m?.author?.id === userId).pop(); + if (userMessage) return userMessage.id; + try { + await MessageActions.fetchMessages({ + channelId: channelId, + limit: 50 + }); + + const updatedCollection = MessageStore.getMessages(channelId); + messages = updatedCollection?.toArray() || []; + userMessage = messages.filter(m => m?.author?.id === userId).pop(); + + if (userMessage) return userMessage.id; + } catch (fetchError) { + console.error("Error fetching messages:", fetchError); + } + + Toasts.show({ + type: Toasts.Type.FAILURE, + message: "Couldn't find any recent messages from this user.", + id: Toasts.genId() + }); + return null; + } catch (error) { + console.error("Error finding last message:", error); + Toasts.show({ + type: Toasts.Type.FAILURE, + message: "Failed to find messages. Check console for details.", + id: Toasts.genId() + }); + return null; + } +} +async function jumpToLastActive(channel: any, targetUserId?: string) { + try { + if (!channel) { + Toasts.show({ + type: Toasts.Type.FAILURE, + message: "Channel information not available.", + id: Toasts.genId() + }); + return; + } + const guildId = channel.guild_id !== null ? channel.guild_id : "@me"; + const channelId = channel.id; + let userId: string; + if (targetUserId) { + + userId = targetUserId; + } else { + if (!UserStore?.getCurrentUser) { + Toasts.show({ + type: Toasts.Type.FAILURE, + message: "Could not determine user. Try again later.", + id: Toasts.genId() + }); + return; + } + const currentUser = UserStore.getCurrentUser(); + if (!currentUser || !currentUser.id) { + Toasts.show({ + type: Toasts.Type.FAILURE, + message: "Could not determine current user. Try again later.", + id: Toasts.genId() + }); + return; + } + userId = currentUser.id; + } + const messageId = await findLastMessageFromUser(channelId, userId); + if (messageId) { + const url = `/channels/${guildId}/${channelId}/${messageId}`; + NavigationRouter.transitionTo(url); + } + } catch (error) { + console.error("Error in jumpToLastActive:", error); + Toasts.show({ + type: Toasts.Type.FAILURE, + message: "Failed to jump to message. Check console for details.", + id: Toasts.genId() + }); + } +} +const ChannelContextMenuPatch: NavContextMenuPatchCallback = (children, { channel }) => { + children.push( + Jump to Your Last Message} + action={() => { + jumpToLastActive(channel); + }} + /> + ); +}; +const UserContextMenuPatch: NavContextMenuPatchCallback = (children, { user, channel }) => { + if (!channel || !user?.id) return; + + children.push( + Jump to User's Last Message} + action={() => { + jumpToLastActive(channel, user.id); + }} + /> + ); +}; +export default definePlugin({ + name: "LastActive", + description: "A plugin to jump to last active message from yourself or another user in a channel/server.", + authors: [EquicordDevs.Crxa], + contextMenus: { + "channel-context": ChannelContextMenuPatch, + "user-context": UserContextMenuPatch, + "thread-context": ChannelContextMenuPatch + } +});