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;