diff --git a/src/plugins/accountPanelServerProfile/README.md b/src/plugins/accountPanelServerProfile/README.md new file mode 100644 index 000000000..f837864b7 --- /dev/null +++ b/src/plugins/accountPanelServerProfile/README.md @@ -0,0 +1,7 @@ +# AccountPanelServerProfile + +Right click your account panel in the bottom left to view your profile in the current server + +![](https://github.com/user-attachments/assets/3228497d-488f-479c-93d2-a32ccdb08f0f) + +![](https://github.com/user-attachments/assets/6fc45363-d95f-4810-812f-2f9fb28b41b5) diff --git a/src/plugins/accountPanelServerProfile/index.tsx b/src/plugins/accountPanelServerProfile/index.tsx new file mode 100644 index 000000000..fe5df48ad --- /dev/null +++ b/src/plugins/accountPanelServerProfile/index.tsx @@ -0,0 +1,134 @@ +/* + * Vencord, a Discord client mod + * Copyright (c) 2024 Vendicated and contributors + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +import { definePluginSettings } from "@api/Settings"; +import ErrorBoundary from "@components/ErrorBoundary"; +import { Devs } from "@utils/constants"; +import { getCurrentChannel } from "@utils/discord"; +import definePlugin, { OptionType } from "@utils/types"; +import { findByPropsLazy, findComponentByCodeLazy } from "@webpack"; +import { ContextMenuApi, Menu, useEffect, useRef } from "@webpack/common"; +import { User } from "discord-types/general"; + +interface UserProfileProps { + popoutProps: Record; + currentUser: User; + originalPopout: () => React.ReactNode; +} + +const UserProfile = findComponentByCodeLazy("UserProfilePopoutWrapper: user cannot be undefined"); +const styles = findByPropsLazy("accountProfilePopoutWrapper"); + +let openAlternatePopout = false; +let accountPanelRef: React.MutableRefObject | null> = { current: null }; + +const AccountPanelContextMenu = ErrorBoundary.wrap(() => { + const { prioritizeServerProfile } = settings.use(["prioritizeServerProfile"]); + + return ( + + { + openAlternatePopout = true; + accountPanelRef.current?.props.onMouseDown(); + accountPanelRef.current?.props.onClick(e); + }} + /> + settings.store.prioritizeServerProfile = !prioritizeServerProfile} + /> + + ); +}, { noop: true }); + +const settings = definePluginSettings({ + prioritizeServerProfile: { + type: OptionType.BOOLEAN, + description: "Prioritize Server Profile when left clicking your account panel", + default: false + } +}); + +export default definePlugin({ + name: "AccountPanelServerProfile", + description: "Right click your account panel in the bottom left to view your profile in the current server", + authors: [Devs.Nuckyz, Devs.relitrix], + settings, + + patches: [ + { + find: ".Messages.ACCOUNT_SPEAKING_WHILE_MUTED", + group: true, + replacement: [ + { + match: /(?<=\.SIZE_32\)}\);)/, + replace: "$self.useAccountPanelRef();" + }, + { + match: /(\.AVATAR,children:.+?renderPopout:(\i)=>){(.+?)}(?=,position)(?<=currentUser:(\i).+?)/, + replace: (_, rest, popoutProps, originalPopout, currentUser) => `${rest}$self.UserProfile({popoutProps:${popoutProps},currentUser:${currentUser},originalPopout:()=>{${originalPopout}}})` + }, + { + match: /\.AVATAR,children:.+?(?=renderPopout:)/, + replace: "$&onRequestClose:$self.onPopoutClose," + }, + { + match: /(?<=.avatarWrapper,)/, + replace: "ref:$self.accountPanelRef,onContextMenu:$self.openAccountPanelContextMenu," + } + ] + } + ], + + get accountPanelRef() { + return accountPanelRef; + }, + + useAccountPanelRef() { + useEffect(() => () => { + accountPanelRef.current = null; + }, []); + + return (accountPanelRef = useRef(null)); + }, + + openAccountPanelContextMenu(event: React.UIEvent) { + ContextMenuApi.openContextMenu(event, AccountPanelContextMenu); + }, + + onPopoutClose() { + openAlternatePopout = false; + }, + + UserProfile: ErrorBoundary.wrap(({ popoutProps, currentUser, originalPopout }: UserProfileProps) => { + if ( + (settings.store.prioritizeServerProfile && openAlternatePopout) || + (!settings.store.prioritizeServerProfile && !openAlternatePopout) + ) { + return originalPopout(); + } + + const currentChannel = getCurrentChannel(); + if (currentChannel?.getGuildId() == null) { + return originalPopout(); + } + + return ( +
+ +
+ ); + }, { noop: true }) +}); diff --git a/src/plugins/customRPC/index.tsx b/src/plugins/customRPC/index.tsx index eebcd4ddb..f4b9ab060 100644 --- a/src/plugins/customRPC/index.tsx +++ b/src/plugins/customRPC/index.tsx @@ -26,12 +26,11 @@ import { Margins } from "@utils/margins"; import { classes } from "@utils/misc"; import { useAwaiter } from "@utils/react"; import definePlugin, { OptionType } from "@utils/types"; -import { findByCodeLazy, findByPropsLazy, findComponentByCodeLazy } from "@webpack"; +import { findByCodeLazy, findComponentByCodeLazy } from "@webpack"; import { ApplicationAssetUtils, Button, FluxDispatcher, Forms, GuildStore, React, SelectedChannelStore, SelectedGuildStore, UserStore } from "@webpack/common"; const useProfileThemeStyle = findByCodeLazy("profileThemeStyle:", "--profile-gradient-primary-color"); const ActivityComponent = findComponentByCodeLazy("onOpenGameProfile"); -const ActivityClassName = findByPropsLazy("activity", "buttonColor"); const ShowCurrentGame = getUserSettingLazy("status", "showCurrentGame")!; @@ -436,8 +435,8 @@ export default definePlugin({ -
- {activity[0] && + {activity[0] && } diff --git a/src/plugins/index.ts b/src/plugins/index.ts index e6caf7340..ac6821a63 100644 --- a/src/plugins/index.ts +++ b/src/plugins/index.ts @@ -66,14 +66,14 @@ export function addPatch(newPatch: Omit, pluginName: string) { patch.replacement = [patch.replacement]; } - patch.replacement = patch.replacement.filter(({ predicate }) => !predicate || predicate()); - if (IS_REPORTER) { patch.replacement.forEach(r => { delete r.predicate; }); } + patch.replacement = patch.replacement.filter(({ predicate }) => !predicate || predicate()); + patches.push(patch); } diff --git a/src/plugins/sortFriendRequests/index.tsx b/src/plugins/sortFriendRequests/index.tsx index 7033591bd..64eb13fe5 100644 --- a/src/plugins/sortFriendRequests/index.tsx +++ b/src/plugins/sortFriendRequests/index.tsx @@ -48,7 +48,7 @@ export default definePlugin({ find: ".Messages.FRIEND_REQUEST_CANCEL", replacement: { predicate: () => settings.store.showDates, - match: /subText:(\i)(?=,className:\i\.userInfo}\))(?<=user:(\i).+?)/, + match: /subText:(\i)(?<=user:(\i).+?)/, replace: (_, subtext, user) => `subText:$self.makeSubtext(${subtext},${user})` } }], @@ -66,7 +66,7 @@ export default definePlugin({ makeSubtext(text: string, user: User) { const since = this.getSince(user); return ( - + {text} {!isNaN(since.getTime()) && Received — {since.toDateString()}} diff --git a/src/plugins/timeBarAllActivities/index.tsx b/src/plugins/timeBarAllActivities/index.tsx index 04f7ff9e7..91b1bc2f1 100644 --- a/src/plugins/timeBarAllActivities/index.tsx +++ b/src/plugins/timeBarAllActivities/index.tsx @@ -40,7 +40,7 @@ export default definePlugin({ settings, patches: [ { - find: ".Messages.USER_ACTIVITY_PLAYING", + find: ".gameState,children:", replacement: [ // Insert Spotify time bar component { diff --git a/src/utils/constants.ts b/src/utils/constants.ts index b7714dec4..145ae9be5 100644 --- a/src/utils/constants.ts +++ b/src/utils/constants.ts @@ -39,7 +39,8 @@ export const Devs = /* #__PURE__*/ Object.freeze({ }, Arjix: { name: "ArjixWasTaken", - id: 674710789138939916n + id: 674710789138939916n, + badge: false }, Cyn: { name: "Cynosphere", @@ -570,6 +571,10 @@ export const Devs = /* #__PURE__*/ Object.freeze({ name: "niko", id: 341377368075796483n, }, + relitrix: { + name: "Relitrix", + id: 423165393901715456n, + }, RamziAH: { name: "RamziAH", id: 1279957227612147747n,