diff --git a/src/i18n/locales/en.json b/src/i18n/locales/en.json index 7580e53a..714743c4 100644 --- a/src/i18n/locales/en.json +++ b/src/i18n/locales/en.json @@ -544,6 +544,10 @@ "discordDisplayType_description": "changes what you are listening to in your status", "discordDisplayType_songname": "song name", "discordDisplayType_artistname": "artist name(s)", + "discordLinkType": "{{discord}} presence links", + "discordLinkType_description": "adds external links to {{lastfm}} or {{musicbrainz}} to the song and artist fields in {{discord}} rich presence. {{musicbrainz}} is the most accurate but requires tags and doesn't provide artist links while {{lastfm}} should always provide a link. makes no extra network requests", + "discordLinkType_none": "$t(common.none)", + "discordLinkType_mbz_lastfm": "{{musicbrainz}} with {{lastfm}} fallback", "doubleClickBehavior": "queue all searched tracks when double clicking", "doubleClickBehavior_description": "if true, all matching tracks in a track search will be queued. otherwise, only the clicked one will be queued", "enableRemote": "enable remote control server", diff --git a/src/renderer/features/discord-rpc/use-discord-rpc.ts b/src/renderer/features/discord-rpc/use-discord-rpc.ts index 63ba35bf..cfb7f015 100644 --- a/src/renderer/features/discord-rpc/use-discord-rpc.ts +++ b/src/renderer/features/discord-rpc/use-discord-rpc.ts @@ -5,6 +5,7 @@ import { useCallback, useEffect, useState } from 'react'; import { controller } from '/@/renderer/api/controller'; import { DiscordDisplayType, + DiscordLinkType, getServerById, useAppStore, useDiscordSettings, @@ -77,6 +78,34 @@ export const useDiscordRpc = () => { type: discordSettings.showAsListening ? 2 : 0, }; + if ( + (discordSettings.linkType == DiscordLinkType.LAST_FM || + discordSettings.linkType == DiscordLinkType.MBZ_LAST_FM) && + song?.artistName + ) { + activity.stateUrl = + 'https://www.last.fm/music/' + encodeURIComponent(song.artists[0].name); + activity.detailsUrl = + 'https://www.last.fm/music/' + + encodeURIComponent(song.albumArtists[0].name) + + '/' + + encodeURIComponent(song.album || '_') + + '/' + + encodeURIComponent(song.name); + } + + if ( + discordSettings.linkType == DiscordLinkType.MBZ || + discordSettings.linkType == DiscordLinkType.MBZ_LAST_FM + ) { + if (song?.mbzTrackId) { + activity.detailsUrl = 'https://musicbrainz.org/track/' + song.mbzTrackId; + } else if (song?.mbzRecordingId) { + activity.detailsUrl = + 'https://musicbrainz.org/recording/' + song.mbzRecordingId; + } + } + if ((current[2] as PlayerStatus) === PlayerStatus.PLAYING) { if (start && end) { activity.startTimestamp = start; @@ -145,6 +174,7 @@ export const useDiscordRpc = () => { generalSettings.lastfmApiKey, discordSettings.clientId, discordSettings.displayType, + discordSettings.linkType, lastUniqueId, ], ); diff --git a/src/renderer/features/settings/components/window/discord-settings.tsx b/src/renderer/features/settings/components/window/discord-settings.tsx index c721c57d..254f826c 100644 --- a/src/renderer/features/settings/components/window/discord-settings.tsx +++ b/src/renderer/features/settings/components/window/discord-settings.tsx @@ -7,6 +7,7 @@ import { } from '/@/renderer/features/settings/components/settings-section'; import { DiscordDisplayType, + DiscordLinkType, useDiscordSettings, useGeneralSettings, useSettingsStoreActions, @@ -162,6 +163,54 @@ export const DiscordSettings = () => { }), isHidden: !isElectron(), title: t('setting.discordDisplayType', { + discord: 'Discord', + musicbrainz: 'musicbrainz', + postProcess: 'sentenceCase', + }), + }, + { + control: ( +