Plugin
AccountPanelServerProfile
Right click your account panel in the bottom left to view your profile in the current server
1
/*2
* FiveCord — a Discord client mod3
* Copyright (c) 2025 FiveCord4
* SPDX-License-Identifier: GPL-3.0-or-later5
*/6
7
import { definePluginSettings } from "@api/Settings";8
import ErrorBoundary from "@components/ErrorBoundary";9
import { Devs } from "@utils/constants";10
import { getCurrentChannel } from "@utils/discord";11
import definePlugin, { OptionType } from "@utils/types";12
import { User } from "@vencord/discord-types";13
import { findComponentByCodeLazy } from "@webpack";14
import { ContextMenuApi, Menu } from "@webpack/common";15
16
interface UserProfileProps {17
popoutProps: Record<string, any>;18
currentUser: User;19
originalRenderPopout: () => React.ReactNode;20
}21
22
const UserProfile = findComponentByCodeLazy(".isNonUserBot()?", ",onClickContainer:");23
24
let openAlternatePopout = false;25
let accountPanelRef: React.RefObject<HTMLDivElement | null> = { current: null };26
27
const AccountPanelContextMenu = ErrorBoundary.wrap(() => {28
const { prioritizeServerProfile } = settings.use(["prioritizeServerProfile"]);29
30
return (31
<Menu.Menu32
navId="vc-ap-server-profile"33
onClose={ContextMenuApi.closeContextMenu}34
>35
<Menu.MenuItem36
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.MenuCheckboxItem45
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
54
const settings = definePluginSettings({55
prioritizeServerProfile: {56
type: OptionType.BOOLEAN,57
description: "Prioritize Server Profile when left clicking your account panel",58
default: false59
}60
});61
62
export 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
<UserProfile122
{...popoutProps}123
user={currentUser}124
currentUser={currentUser}125
guildId={currentChannel.getGuildId()}126
channelId={currentChannel.id}127
/>128
);129
}, { noop: true })130
});131