From cb99d03f9853ce109be5c27ac166a138b06e836f Mon Sep 17 00:00:00 2001 From: Natsumi Date: Tue, 10 Feb 2026 16:52:35 +1300 Subject: [PATCH] Discord profile badge --- Dotnet/AppApi/Common/AppApiCommon.cs | 12 +++++++++++ src/app.css | 5 +++++ .../dialogs/UserDialog/UserSummaryHeader.vue | 21 ++++++++++++++++++- src/localization/en.json | 4 +++- src/shared/utils/common.js | 12 +++++++++++ src/stores/user.js | 8 +++++++ src/types/api/user.d.ts | 1 + src/types/globals.d.ts | 1 + 8 files changed, 62 insertions(+), 2 deletions(-) diff --git a/Dotnet/AppApi/Common/AppApiCommon.cs b/Dotnet/AppApi/Common/AppApiCommon.cs index 9e5089c1..bea75399 100644 --- a/Dotnet/AppApi/Common/AppApiCommon.cs +++ b/Dotnet/AppApi/Common/AppApiCommon.cs @@ -46,6 +46,18 @@ namespace VRCX } } + public void OpenDiscordProfile(string discordId) + { + if (!long.TryParse(discordId, out _)) + throw new Exception("Invalid user ID"); + + var uri = $"discord://-/users/{discordId}"; + Process.Start(new ProcessStartInfo(uri) + { + UseShellExecute = true + }); + } + public string GetLaunchCommand() { var command = StartupArgs.LaunchArguments.LaunchCommand; diff --git a/src/app.css b/src/app.css index b4738361..80c63aca 100644 --- a/src/app.css +++ b/src/app.css @@ -291,6 +291,11 @@ i.x-status-icon.red { border-color: #3b82f6 !important; } +.x-tag-discord { + color: #7289da; + border-color: #7289da !important; +} + .x-tag-border-left { border-left: 0.8px solid; margin-left: 5px; diff --git a/src/components/dialogs/UserDialog/UserSummaryHeader.vue b/src/components/dialogs/UserDialog/UserSummaryHeader.vue index 7620af5b..f4a1a5de 100644 --- a/src/components/dialogs/UserDialog/UserSummaryHeader.vue +++ b/src/components/dialogs/UserDialog/UserSummaryHeader.vue @@ -121,6 +121,19 @@ {{ userDialog.mutualFriendCount }} + + + + {{ t('dialog.user.tags.discord') }} + + { + console.error('Failed to open Discord profile:', err); + toast.error('Failed to open Discord profile!'); + }); +} + /** * * @param {object} ref @@ -537,6 +548,7 @@ export { buildTreeData, replaceBioSymbols, openExternalLink, + openDiscordProfile, getBundleDateSize, openFolderGeneric, debounce diff --git a/src/stores/user.js b/src/stores/user.js index 9d9f214d..005506a8 100644 --- a/src/stores/user.js +++ b/src/stores/user.js @@ -92,6 +92,11 @@ export const useUserStore = defineStore('User', () => { currentAvatarThumbnailImageUrl: '', date_joined: '', developerType: '', + discordDetails: { + global_name: '', + id: '' + }, + discordId: '', displayName: '', emailVerified: false, fallbackAvatar: '', @@ -491,6 +496,7 @@ export const useUserStore = defineStore('User', () => { currentAvatarThumbnailImageUrl: '', date_joined: '', developerType: '', + discordId: '', displayName: '', friendKey: '', friendRequestStatus: '', @@ -1836,6 +1842,7 @@ export const useUserStore = defineStore('User', () => { currentAvatarThumbnailImageUrl: '', date_joined: '', developerType: '', + discordId: '', displayName: '', emailVerified: false, fallbackAvatar: '', @@ -1991,6 +1998,7 @@ export const useUserStore = defineStore('User', () => { currentAvatarThumbnailImageUrl: json.currentAvatarThumbnailImageUrl, date_joined: json.date_joined, developerType: json.developerType, + discordId: json.discordId, displayName: json.displayName, friendKey: json.friendKey, // json.friendRequestStatus - missing from currentUser diff --git a/src/types/api/user.d.ts b/src/types/api/user.d.ts index f327401b..b2bcc613 100644 --- a/src/types/api/user.d.ts +++ b/src/types/api/user.d.ts @@ -133,6 +133,7 @@ interface GetUserResponse { currentAvatarThumbnailImageUrl: string; date_joined: string; developerType: string; + discordId: string; displayName: string; friendKey: string; friendRequestStatus?: string; diff --git a/src/types/globals.d.ts b/src/types/globals.d.ts index 1bab4d94..8d01df4d 100644 --- a/src/types/globals.d.ts +++ b/src/types/globals.d.ts @@ -191,6 +191,7 @@ declare global { // Common Functions GetColourFromUserID(userId: string): Promise; OpenLink(url: string): Promise; + OpenDiscordProfile(discordId: string): Promise; GetLaunchCommand(): Promise; IPCAnnounceStart(): Promise; SendIpc(type: string, data: string): Promise;