Plugin

AccountPanelServerProfile

Right click your account panel in the bottom left to view your profile in the current server

Appearance Servers
index.tsx
Download

Source

src/plugins/accountPanelServerProfile/index.tsx
1/*
2 * FiveCord — a Discord client mod
3 * Copyright (c) 2025 FiveCord
4 * SPDX-License-Identifier: GPL-3.0-or-later
5 */
6
7import { definePluginSettings } from "@api/Settings";
8import ErrorBoundary from "@components/ErrorBoundary";
9import { Devs } from "@utils/constants";
10import { getCurrentChannel } from "@utils/discord";
11import definePlugin, { OptionType } from "@utils/types";
12import { User } from "@vencord/discord-types";
13import { findComponentByCodeLazy } from "@webpack";
14import { ContextMenuApi, Menu } from "@webpack/common";
15
16interface UserProfileProps {
17 popoutProps: Record<string, any>;
18 currentUser: User;
19 originalRenderPopout: () => React.ReactNode;
20}
21
22const UserProfile = findComponentByCodeLazy(".isNonUserBot()?", ",onClickContainer:");
23
24let openAlternatePopout = false;
25let accountPanelRef: React.RefObject<HTMLDivElement | null> = { current: null };
26
27const AccountPanelContextMenu = ErrorBoundary.wrap(() => {
28 const { prioritizeServerProfile } = settings.use(["prioritizeServerProfile"]);
29
30 return (
31 <Menu.Menu
32 navId="vc-ap-server-profile"
33 onClose={ContextMenuApi.closeContextMenu}
34 >
35 <Menu.MenuItem
36 id="vc-ap-view-alternate-popout"
37 label={prioritizeServerProfile ? "View Account Profile" : "View Server Profile"}
38 disabled={getCurrentChannel()?.getGuildId() == null}
39 action={e => {
40 openAlternatePopout = true;
41 accountPanelRef.current?.click();
42 }}
43 />
44 <Menu.MenuCheckboxItem
45 id="vc-ap-prioritize-server-profile"
46 label="Prioritize Server Profile"
47 checked={prioritizeServerProfile}
48 action={() => settings.store.prioritizeServerProfile = !prioritizeServerProfile}
49 />
50 </Menu.Menu>
51 );
52}, { noop: true });
53
54const settings = definePluginSettings({
55 prioritizeServerProfile: {
56 type: OptionType.BOOLEAN,
57 description: "Prioritize Server Profile when left clicking your account panel",
58 default: false
59 }
60});
61
62export default definePlugin({
63 name: "AccountPanelServerProfile",
64 description: "Right click your account panel in the bottom left to view your profile in the current server",
65 tags: ["Appearance", "Servers"],
66 authors: [Devs.Nuckyz, Devs.relitrix],
67 settings,
68
69 patches: [
70 {
71 find: "handleOpenSettingsContextMenu=",
72 group: true,
73 replacement: [
74 {
75 match: /(\.AVATAR,children:.+?renderPopout:\((\i),\i\)=>)\{(.+?)\}(?=,position)(?<=currentUser:(\i).+?)/,
76 replace: (_, rest, popoutProps, originalPopout, currentUser) => `${rest}$self.UserProfile({popoutProps:${popoutProps},currentUser:${currentUser},originalRenderPopout:()=>{${originalPopout}}})`
77 },
78 {
79 match: /\.AVATAR,children:.+?onRequestClose:\(\)=>\{/,
80 replace: "$&$self.onPopoutClose();"
81 },
82 {
83 match: /ref:(\i),style:\i(?=.{0,250}#{intl::USER_PROFILE_ACCOUNT_POPOUT_BUTTON_A11Y_LABEL})/,
84 replace: "$&,onContextMenu:($self.grabRef($1),$self.openAccountPanelContextMenu)"
85 }
86 ]
87 }
88 ],
89
90 get accountPanelRef() {
91 return accountPanelRef;
92 },
93
94 grabRef(ref: React.RefObject<HTMLDivElement>) {
95 accountPanelRef = ref;
96 return ref;
97 },
98
99 openAccountPanelContextMenu(event: React.UIEvent) {
100 ContextMenuApi.openContextMenu(event, AccountPanelContextMenu);
101 },
102
103 onPopoutClose() {
104 openAlternatePopout = false;
105 },
106
107 UserProfile: ErrorBoundary.wrap(({ popoutProps, currentUser, originalRenderPopout }: UserProfileProps) => {
108 if (
109 (settings.store.prioritizeServerProfile && openAlternatePopout) ||
110 (!settings.store.prioritizeServerProfile && !openAlternatePopout)
111 ) {
112 return originalRenderPopout();
113 }
114
115 const currentChannel = getCurrentChannel();
116 if (currentChannel?.getGuildId() == null || !UserProfile.$$vencordGetWrappedComponent()) {
117 return originalRenderPopout();
118 }
119
120 return (
121 <UserProfile
122 {...popoutProps}
123 user={currentUser}
124 currentUser={currentUser}
125 guildId={currentChannel.getGuildId()}
126 channelId={currentChannel.id}
127 />
128 );
129 }, { noop: true })
130});
131