From e99ef13c8103baff3d7635b6fcc0e397cd3b320e Mon Sep 17 00:00:00 2001 From: justjxke Date: Sun, 13 Sep 2026 18:59:38 +0100 Subject: [PATCH] SidebarChat: fix scrolling and popouts (#1356) * SidebarChat: fix scrolling and popouts Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com> * [autofix.ci] apply automated fixes * SidebarChat: improve patch targetting --------- Co-authored-by: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> --- src/equicordplugins/sidebarChat/index.tsx | 55 +++++++++++++++++++---- src/plugins/addAttachments/index.tsx | 1 - 2 files changed, 46 insertions(+), 10 deletions(-) diff --git a/src/equicordplugins/sidebarChat/index.tsx b/src/equicordplugins/sidebarChat/index.tsx index fff6ab888..a385a4994 100644 --- a/src/equicordplugins/sidebarChat/index.tsx +++ b/src/equicordplugins/sidebarChat/index.tsx @@ -18,6 +18,7 @@ import { findByPropsLazy, findComponentByCodeLazy, findCssClassesLazy, + mapMangledModuleLazy, } from "@webpack"; import { ChannelActionCreators, @@ -69,7 +70,9 @@ const ArrowsLeftRightIcon = ({ color, ...rest }) => { const WindowLaunchIcon = findComponentByCodeLazy("1-1h6a1 1 0 1 0 0-2H5Z"); const XSmallIcon = findComponentByCodeLazy("1.4L12 13.42l5.3 5.3Z"); const Chat = findComponentByCodeLazy("filterAfterTimestamp:", "chatInputType"); -const Resize = findComponentByCodeLazy("sidebarType:", "RESIZE_HANDLE_WIDTH)"); +const SidebarComponents = mapMangledModuleLazy("ChannelChatResizableSidebar", { + Resize: (value: unknown) => typeof value === "function" +}); const ChannelHeader = findComponentByCodeLazy("`channel-${"); const PopoutWindow = findComponentByCodeLazy("Missing guestWindow reference"); const FullChannelView = findComponentByCodeLazy("showFollowButton:"); @@ -104,7 +107,15 @@ function getChannelTitle(channel: Channel | null | undefined) { function canOpenPopout(channel: Channel) { if (channel.isPrivate()) return true; - return !channel.isCategory() && !channel.isDirectory() && !channel.isVocal(); + return !channel.isCategory() && !channel.isDirectory(); +} + +function getMainChatChannelId() { + const channelId = SelectedChannelStore.getChannelId(); + const sidebar = ChannelSectionStore.getSidebarState(channelId); + return sidebar && typeof sidebar === "object" && "channelId" in sidebar && typeof sidebar.channelId === "string" + ? sidebar.channelId + : channelId; } function getPopoutMenuLabel(channelId: string) { @@ -315,11 +326,25 @@ export default definePlugin({ replace: "$&vc_SidebarChat=$self.renderSidebar()," }, { - match: /:(\(0,\i\.jsxs?\)\(\i,{}\))}(?<=default:.{0,300})/, - replace: ":[$1, vc_SidebarChat]}" + match: /(?<=return )null!=\i&&\i\?\(0,\i\.jsx\)\(\i,\{channel:\i\},\i\.id\):\(0,\i\.jsx\)\(\i,\{\}\)(?=\},)/, + replace: "[$&,vc_SidebarChat]" }, ], }, + { + find: "loadComplete: resetting state for channelId=", + group: true, + replacement: [ + { + match: /truncateTop\(\i\)\{(?=.{0,100}?this\._array\.length-\i;return)/, + replace: "$&if($self.hasMultipleChatViews(this.channelId))return this;" + }, + { + match: /truncateBottom\(\i\)\{(?=.{0,100}?return this\._array\.length<=\i\?this:this\.mutate\()/, + replace: "$&if($self.hasMultipleChatViews(this.channelId))return this;" + } + ] + }, ], managedStyle: style, settings, @@ -361,6 +386,16 @@ export default definePlugin({ restorePersistedPopouts(); }, + hasMultipleChatViews(channelId: string) { + const mainChannelId = SelectedChannelStore.getChannelId(); + const sidebarHidden = ChannelSectionStore.getSidebarState(mainChannelId) + || ChannelSectionStore.getGuildSidebarState(SelectedGuildStore.getGuildId() ?? undefined); + const views = Number(channelId === mainChannelId || channelId === getMainChatChannelId()) + + Number(!sidebarHidden && channelId === SidebarStore.getState().channelId) + + Number(isPopoutWindowOpen(channelId)); + return views > 1; + }, + renderSidebar() { const { guild, channel /* width*/ } = useStateFromStores( [SidebarStore, GuildStore, ChannelStore], () => { @@ -436,13 +471,13 @@ export default definePlugin({ return ( -
{View} - + ); }, @@ -524,7 +559,9 @@ const RenderPopout = ErrorBoundary.wrap(({ channel, name, windowKey }: { channel channelId={channel.id} >
- + {channel.isGuildVocal() + ? + : }
); @@ -532,9 +569,9 @@ const RenderPopout = ErrorBoundary.wrap(({ channel, name, windowKey }: { channel function PopoutHeaderButton() { const channelState = useStateFromStores( - [SelectedChannelStore, ChannelStore, PopoutWindowStore], + [SelectedChannelStore, ChannelSectionStore, ChannelStore, PopoutWindowStore], () => { - const channelId = SelectedChannelStore.getChannelId(); + const channelId = getMainChatChannelId(); const channel = channelId ? ChannelStore.getChannel(channelId) : null; return { diff --git a/src/plugins/addAttachments/index.tsx b/src/plugins/addAttachments/index.tsx index 4e6dfd4d7..8982b138c 100644 --- a/src/plugins/addAttachments/index.tsx +++ b/src/plugins/addAttachments/index.tsx @@ -74,7 +74,6 @@ async function addAttachments(channelId: string, messageId: string, existingAtta ) ); - const msg = MessageStore.getMessage(channelId, messageId); await RestAPI.patch({