From a68b849aeb68b17f6cab7c5446107ff70a582a63 Mon Sep 17 00:00:00 2001 From: Cortex <126973723+verysillycat@users.noreply.github.com> Date: Sat, 19 Oct 2024 23:22:42 -0600 Subject: [PATCH] add(equicordplugin): sidebarChat --- README.md | 3 +- src/equicordplugins/sidebarChat/index.tsx | 167 ++++++++++++++++++++++ src/equicordplugins/sidebarChat/store.ts | 49 +++++++ 3 files changed, 218 insertions(+), 1 deletion(-) create mode 100644 src/equicordplugins/sidebarChat/index.tsx create mode 100644 src/equicordplugins/sidebarChat/store.ts diff --git a/README.md b/README.md index 17cd73df..8b442b43 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ You can join our [discord server](https://discord.gg/5Xh2W87egW) for commits, ch ### Extra included plugins
-131 additional plugins +132 additional plugins - AllCallTimers by MaxHerbold & D3SOX - AltKrispSwitch by newwares @@ -110,6 +110,7 @@ You can join our [discord server](https://discord.gg/5Xh2W87egW) for commits, ch - ScreenRecorder by AutumnVN (Vesktop & Equibop only) - SearchFix by Jaxx - SekaiStickers by MaiKokain +- SidebarChat by Joona - Shakespearean by vmohammad (Dev build only) - ShowBadgesInChat by Inbestigator & KrystalSkull - Slap by Korbo diff --git a/src/equicordplugins/sidebarChat/index.tsx b/src/equicordplugins/sidebarChat/index.tsx new file mode 100644 index 00000000..daf9cc73 --- /dev/null +++ b/src/equicordplugins/sidebarChat/index.tsx @@ -0,0 +1,167 @@ +/* + * Vencord, a Discord client mod + * Copyright (c) 2024 Vendicated and contributors + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +import { NavContextMenuPatchCallback } from "@api/ContextMenu"; +import ErrorBoundary from "@components/ErrorBoundary"; +import { Devs } from "@utils/constants"; +import definePlugin from "@utils/types"; +import { filters, findByPropsLazy, findComponentByCodeLazy, mapMangledModuleLazy } from "@webpack"; +import { + ChannelRouter, + ChannelStore, + FluxDispatcher, + Icons, + Menu, + MessageActions, + PermissionsBits, + PermissionStore, + SelectedChannelStore, + useEffect, + UserStore, + useStateFromStores +} from "@webpack/common"; +import { Channel, User } from "discord-types/general"; + +import { SidebarStore } from "./store"; + + +const { HeaderBar, HeaderBarIcon } = mapMangledModuleLazy(".themedMobile]:", { + HeaderBarIcon: filters.byCode('size:"custom",'), + HeaderBar: filters.byCode(".themedMobile]:"), +}); +const Chat = findComponentByCodeLazy("filterAfterTimestamp:", "chatInputType"); +const Resize = findComponentByCodeLazy("sidebarType:", "homeSidebarWidth"); +const ChannelHeader = findComponentByCodeLazy(".Messages.HUB_DIRECTORY_CHANNEL_TITLE.format({"); +const ChatInputTypes = findByPropsLazy("FORM", "NORMAL"); +const Sidebars = findByPropsLazy("ThreadSidebar", "MessageRequestSidebar"); + + +interface ContextMenuProps { + channel: Channel; + guildId?: string; + user: User; +} + + +function MakeContextCallback(name: "user" | "channel"): NavContextMenuPatchCallback { + return (children, { user, channel, guildId }: ContextMenuProps) => { + const isUser = name === "user"; + if (isUser && !user) return; + if (!isUser && (!channel || channel.type === 4)) return; + + if (isUser && user.id === UserStore.getCurrentUser().id) return; + if (!isUser && (!PermissionStore.can(PermissionsBits.VIEW_CHANNEL, channel) && channel.type !== 3)) return; + + children.push( + { + FluxDispatcher.dispatch({ + // @ts-ignore + type: "NEW_SIDEBAR_CHAT", + isUser, + guildId: guildId || channel.guild_id, + id: isUser ? user.id : channel.id, + }); + }} + /> + ); + }; +} + +export default definePlugin({ + name: "SidebarChat", + authors: [Devs.Joona], + description: "Open a another channel or a DM as a sidebar", + patches: [ + { + find: "Missing channel in Channel.openChannelContextMenu", + replacement: [ + { + match: /this\.renderThreadSidebar\(\),/, + replace: "$&$self.renderSidebar({width:this.props.width,stockSidebarOpen:this.props.channelSidebarState || this.props.guildSidebarState})," + } + ] + } + ], + + contextMenus: { + "user-context": MakeContextCallback("user"), + "channel-context": MakeContextCallback("channel"), + "thread-context": MakeContextCallback("channel"), + "gdm-context": MakeContextCallback("channel"), + }, + + renderSidebar: ErrorBoundary.wrap(({ width, stockSidebarOpen }: { width: number, stockSidebarOpen: any; }) => { + const [guild, channel] = useStateFromStores( + [SidebarStore], + () => [SidebarStore.guild, SidebarStore.channel] + ); + + useEffect(() => { + if (channel) { + MessageActions.fetchMessages({ + channelId: channel.id, + limit: 50, + }); + } + }, [channel]); + + if (!channel || stockSidebarOpen) return null; + + return ( + + + { + const currentChannel = ChannelStore.getChannel(SelectedChannelStore.getChannelId()); + FluxDispatcher.dispatch({ + // @ts-ignore + type: "NEW_SIDEBAR_CHAT", + isUser: currentChannel.id === "1", + guildId: currentChannel?.guild_id, + id: currentChannel.id, + }); + ChannelRouter.transitionToChannel(channel.id); + }} + /> + { + FluxDispatcher.dispatch({ + // @ts-ignore + type: "CLOSE_SIDEBAR_CHAT", + }); + }} + /> + + } + > + + + + + ); + }), +}); diff --git a/src/equicordplugins/sidebarChat/store.ts b/src/equicordplugins/sidebarChat/store.ts new file mode 100644 index 00000000..c9148219 --- /dev/null +++ b/src/equicordplugins/sidebarChat/store.ts @@ -0,0 +1,49 @@ +/* + * Vencord, a Discord client mod + * Copyright (c) 2024 Vendicated and contributors + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +import { proxyLazy } from "@utils/lazy"; +import { findByPropsLazy } from "@webpack"; +import { ChannelStore, Flux, FluxDispatcher, GuildStore } from "@webpack/common"; +import { Channel, Guild } from "discord-types/general"; + +// cant destructure, otherwise context is lost +const DMChannelHandler = findByPropsLazy("getOrEnsurePrivateChannel"); + +interface SidebarData { + isUser: boolean; + guildId: string; + id: string; +} + +export const SidebarStore = proxyLazy(() => { + class SidebarStore extends Flux.Store { + public guild: Guild | null = null; + public channel: Channel | null = null; + } + + const store = new SidebarStore(FluxDispatcher, { + // @ts-ignore + async NEW_SIDEBAR_CHAT({ isUser, guildId, id }: SidebarData) { + store.guild = guildId ? GuildStore.getGuild(guildId) : null; + + if (!isUser) { + store.channel = ChannelStore.getChannel(id); + return; + } + + const channelId = await DMChannelHandler.getOrEnsurePrivateChannel(id); + store.channel = ChannelStore.getChannel(channelId); + store.emitChange(); + }, + // @ts-ignore + CLOSE_SIDEBAR_CHAT() { + store.guild = null; + store.channel = null; + } + }); + + return store; +});