From d7ac418e05f43255c42ea115c9c352cf214753d5 Mon Sep 17 00:00:00 2001 From: V Date: Fri, 23 Jun 2023 18:09:43 +0200 Subject: [PATCH] Fix some plugins displaying legacy discriminators (username#0000) --- .../components/RolesAndUsersPermissions.tsx | 3 +- src/plugins/relationshipNotifier/functions.ts | 13 ++++++-- src/plugins/relationshipNotifier/utils.ts | 18 ++++++++--- .../reviewDB/components/ReviewComponent.tsx | 5 +-- src/plugins/reviewDB/utils.tsx | 13 +------- src/plugins/typingTweaks.tsx | 14 ++------- src/utils/discord.tsx | 31 +++++++++++++++++-- src/webpack/common/types/stores.d.ts | 9 ++++++ 8 files changed, 71 insertions(+), 35 deletions(-) diff --git a/src/plugins/permissionsViewer/components/RolesAndUsersPermissions.tsx b/src/plugins/permissionsViewer/components/RolesAndUsersPermissions.tsx index b6d2538fe..8d4b15790 100644 --- a/src/plugins/permissionsViewer/components/RolesAndUsersPermissions.tsx +++ b/src/plugins/permissionsViewer/components/RolesAndUsersPermissions.tsx @@ -19,6 +19,7 @@ import ErrorBoundary from "@components/ErrorBoundary"; import { Flex } from "@components/Flex"; import { InfoIcon, OwnerCrownIcon } from "@components/Icons"; +import { getUniqueUsername } from "@utils/discord"; import { ModalCloseButton, ModalContent, ModalHeader, ModalProps, ModalRoot, ModalSize, openModal } from "@utils/modal"; import { ContextMenu, FluxDispatcher, GuildMemberStore, Menu, PermissionsBits, Text, Tooltip, useEffect, UserStore, useState, useStateFromStores } from "@webpack/common"; import type { Guild } from "discord-types/general"; @@ -136,7 +137,7 @@ function RolesAndUsersPermissionsComponent({ permissions, guild, modalProps, hea permission.type === PermissionType.Role ? role?.name || "Unknown Role" : permission.type === PermissionType.User - ? user?.tag || "Unknown User" + ? (user && getUniqueUsername(user)) || "Unknown User" : ( @owner diff --git a/src/plugins/relationshipNotifier/functions.ts b/src/plugins/relationshipNotifier/functions.ts index c9ec6e3ac..104436a8c 100644 --- a/src/plugins/relationshipNotifier/functions.ts +++ b/src/plugins/relationshipNotifier/functions.ts @@ -16,6 +16,7 @@ * along with this program. If not, see . */ +import { getUniqueUsername, openUserProfile } from "@utils/discord"; import { UserUtils } from "@webpack/common"; import settings from "./settings"; @@ -43,11 +44,19 @@ export async function onRelationshipRemove({ relationship: { type, id } }: Relat switch (type) { case RelationshipType.FRIEND: if (settings.store.friends) - notify(`${user.tag} removed you as a friend.`, user.getAvatarURL(undefined, undefined, false)); + notify( + `${getUniqueUsername(user)} removed you as a friend.`, + user.getAvatarURL(undefined, undefined, false), + () => openUserProfile(user.id) + ); break; case RelationshipType.FRIEND_REQUEST: if (settings.store.friendRequestCancels) - notify(`A friend request from ${user.tag} has been removed.`, user.getAvatarURL(undefined, undefined, false)); + notify( + `A friend request from ${getUniqueUsername(user)} has been removed.`, + user.getAvatarURL(undefined, undefined, false), + () => openUserProfile(user.id) + ); break; } } diff --git a/src/plugins/relationshipNotifier/utils.ts b/src/plugins/relationshipNotifier/utils.ts index 60fb0c6be..d5fd1da7c 100644 --- a/src/plugins/relationshipNotifier/utils.ts +++ b/src/plugins/relationshipNotifier/utils.ts @@ -18,6 +18,7 @@ import { DataStore, Notices } from "@api/index"; import { showNotification } from "@api/Notifications"; +import { getUniqueUsername, openUserProfile } from "@utils/discord"; import { ChannelStore, GuildMemberStore, GuildStore, RelationshipStore, UserStore, UserUtils } from "@webpack/common"; import settings from "./settings"; @@ -69,7 +70,11 @@ export async function syncAndRunChecks() { const user = await UserUtils.fetchUser(id).catch(() => void 0); if (user) - notify(`You are no longer friends with ${user.tag}.`, user.getAvatarURL(undefined, undefined, false)); + notify( + `You are no longer friends with ${getUniqueUsername(user)}.`, + user.getAvatarURL(undefined, undefined, false), + () => openUserProfile(user.id) + ); } } @@ -79,20 +84,25 @@ export async function syncAndRunChecks() { const user = await UserUtils.fetchUser(id).catch(() => void 0); if (user) - notify(`Friend request from ${user.tag} has been revoked.`, user.getAvatarURL(undefined, undefined, false)); + notify( + `Friend request from ${getUniqueUsername(user)} has been revoked.`, + user.getAvatarURL(undefined, undefined, false), + () => openUserProfile(user.id) + ); } } } } -export function notify(text: string, icon?: string) { +export function notify(text: string, icon?: string, onClick?: () => void) { if (settings.store.notices) Notices.showNotice(text, "OK", () => Notices.popNotice()); showNotification({ title: "Relationship Notifier", body: text, - icon + icon, + onClick }); } diff --git a/src/plugins/reviewDB/components/ReviewComponent.tsx b/src/plugins/reviewDB/components/ReviewComponent.tsx index ddcae0aac..a23d6547c 100644 --- a/src/plugins/reviewDB/components/ReviewComponent.tsx +++ b/src/plugins/reviewDB/components/ReviewComponent.tsx @@ -16,6 +16,7 @@ * along with this program. If not, see . */ +import { openUserProfile } from "@utils/discord"; import { classes } from "@utils/misc"; import { LazyComponent } from "@utils/react"; import { filters, findBulk } from "@webpack"; @@ -24,7 +25,7 @@ import { Alerts, moment, Timestamp, UserStore } from "@webpack/common"; import { Review, ReviewType } from "../entities"; import { deleteReview, reportReview } from "../reviewDbApi"; import { settings } from "../settings"; -import { canDeleteReview, cl, openUserProfileModal, showToast } from "../utils"; +import { canDeleteReview, cl, showToast } from "../utils"; import { DeleteButton, ReportButton } from "./MessageButton"; import ReviewBadge from "./ReviewBadge"; @@ -49,7 +50,7 @@ export default LazyComponent(() => { return function ReviewComponent({ review, refetch }: { review: Review; refetch(): void; }) { function openModal() { - openUserProfileModal(review.sender.discordID); + openUserProfile(review.sender.discordID); } function delReview() { diff --git a/src/plugins/reviewDB/utils.tsx b/src/plugins/reviewDB/utils.tsx index da800b0bc..a9c8ca57b 100644 --- a/src/plugins/reviewDB/utils.tsx +++ b/src/plugins/reviewDB/utils.tsx @@ -20,24 +20,13 @@ import { classNameFactory } from "@api/Styles"; import { Logger } from "@utils/Logger"; import { openModal } from "@utils/modal"; import { findByProps } from "@webpack"; -import { FluxDispatcher, React, SelectedChannelStore, Toasts, UserUtils } from "@webpack/common"; +import { React, Toasts } from "@webpack/common"; import { Review, UserType } from "./entities"; import { settings } from "./settings"; export const cl = classNameFactory("vc-rdb-"); -export async function openUserProfileModal(userId: string) { - await UserUtils.fetchUser(userId); - - await FluxDispatcher.dispatch({ - type: "USER_PROFILE_MODAL_OPEN", - userId, - channelId: SelectedChannelStore.getChannelId(), - analyticsLocation: "Explosive Hotel" - }); -} - export function authorize(callback?: any) { const { OAuth2AuthorizeModal } = findByProps("OAuth2AuthorizeModal"); diff --git a/src/plugins/typingTweaks.tsx b/src/plugins/typingTweaks.tsx index b206831ef..b76f4931f 100644 --- a/src/plugins/typingTweaks.tsx +++ b/src/plugins/typingTweaks.tsx @@ -19,13 +19,13 @@ import { definePluginSettings } from "@api/Settings"; import ErrorBoundary from "@components/ErrorBoundary"; import { Devs } from "@utils/constants"; +import { openUserProfile } from "@utils/discord"; import definePlugin, { OptionType } from "@utils/types"; import { findByCodeLazy } from "@webpack"; -import { GuildMemberStore, React, RelationshipStore, SelectedChannelStore } from "@webpack/common"; +import { GuildMemberStore, React, RelationshipStore } from "@webpack/common"; import { User } from "discord-types/general"; const Avatar = findByCodeLazy(".typingIndicatorRef", "svg"); -const openProfile = findByCodeLazy("friendToken", "USER_PROFILE_MODAL_OPEN"); const settings = definePluginSettings({ showAvatars: { @@ -64,15 +64,7 @@ const TypingUser = ErrorBoundary.wrap(function ({ user, guildId }: Props) { { - openProfile({ - userId: user.id, - guildId, - channelId: SelectedChannelStore.getChannelId(), - analyticsLocation: { - page: guildId ? "Guild Channel" : "DM Channel", - section: "Profile Popout" - } - }); + openUserProfile(user.id); }} style={{ display: "grid", diff --git a/src/utils/discord.tsx b/src/utils/discord.tsx index 275264542..4f4326b65 100644 --- a/src/utils/discord.tsx +++ b/src/utils/discord.tsx @@ -17,9 +17,9 @@ */ import { MessageObject } from "@api/MessageEvents"; -import { findByPropsLazy, findLazy } from "@webpack"; -import { ChannelStore, ComponentDispatch, GuildStore, MaskedLink, ModalImageClasses, PrivateChannelsStore, SelectedChannelStore } from "@webpack/common"; -import { Guild, Message } from "discord-types/general"; +import { findByCodeLazy, findByPropsLazy, findLazy } from "@webpack"; +import { ChannelStore, ComponentDispatch, GuildStore, MaskedLink, ModalImageClasses, PrivateChannelsStore, SelectedChannelStore, SelectedGuildStore, UserUtils } from "@webpack/common"; +import { Guild, Message, User } from "discord-types/general"; import { ImageModal, ModalRoot, ModalSize, openModal } from "./modal"; @@ -99,3 +99,28 @@ export function openImageModal(url: string, props?: Partial )); } + +const openProfile = findByCodeLazy("friendToken", "USER_PROFILE_MODAL_OPEN"); + +export async function openUserProfile(id: string) { + const user = await UserUtils.fetchUser(id); + if (!user) throw new Error("No such user: " + id); + + const guildId = SelectedGuildStore.getGuildId(); + openProfile({ + userId: id, + guildId, + channelId: SelectedChannelStore.getChannelId(), + analyticsLocation: { + page: guildId ? "Guild Channel" : "DM Channel", + section: "Profile Popout" + } + }); +} + +/** + * Get the unique username for a user. Returns user.username for pomelo people, user.tag otherwise + */ +export function getUniqueUsername(user: User) { + return user.discriminator === "0" ? user.username : user.tag; +} diff --git a/src/webpack/common/types/stores.d.ts b/src/webpack/common/types/stores.d.ts index db60b63ff..3771150fe 100644 --- a/src/webpack/common/types/stores.d.ts +++ b/src/webpack/common/types/stores.d.ts @@ -20,14 +20,23 @@ import { Channel } from "discord-types/general"; import { FluxDispatcher, FluxEvents } from "./utils"; +type GenericFunction = (...args: any[]) => any; + export class FluxStore { constructor(dispatcher: FluxDispatcher, eventHandlers?: Partial void>>); + addChangeListener(callback: () => void): void; + addReactChangeListener(callback: () => void): void; + removeChangeListener(callback: () => void): void; + removeReactChangeListener(callback: () => void): void; emitChange(): void; getDispatchToken(): string; getName(): string; initialize(): void; initializeIfNeeded(): void; + registerActionHandlers: GenericFunction; + syncWith: GenericFunction; + waitFor: GenericFunction; __getLocalVars(): Record; }