diff --git a/src/i18n/resources/en.json b/src/i18n/resources/en.json index 532e78599a..f7da4f6d09 100644 --- a/src/i18n/resources/en.json +++ b/src/i18n/resources/en.json @@ -444,7 +444,15 @@ "hide-duration-left": "Hide duration left", "hide-github-button": "Hide GitHub link Button", "play-on-youtube-music": "Play on YouTube Music", - "set-inactivity-timeout": "Set inactivity timeout" + "set-inactivity-timeout": "Set inactivity timeout", + "set-status-display-type": { + "label": "Status text", + "submenu": { + "youtube-music": "Listening to YouTube Music", + "artist": "Listening to {artist}", + "title": "Listening to {song title}" + } + } }, "name": "Discord Rich Presence", "prompt": { diff --git a/src/plugins/discord/constants.ts b/src/plugins/discord/constants.ts index c2abcc022a..e66c92ca4a 100644 --- a/src/plugins/discord/constants.ts +++ b/src/plugins/discord/constants.ts @@ -23,3 +23,13 @@ export enum TimerKey { UpdateTimeout = 'updateTimeout', // Timer for throttled activity updates DiscordConnectRetry = 'discordConnectRetry', // Timer for Discord connection retries } + +/** + * An enum for Discord's activity.status_display_type field, governing which field of the activity should be used after + * "Listening to..." in the user's Discord status. + */ +export const DiscordStatusDisplayType = { + YOUTUBE_MUSIC: 0, + ARTIST: 1, + TITLE: 2, +} as const; diff --git a/src/plugins/discord/discord-service.ts b/src/plugins/discord/discord-service.ts index 65d5344680..60bc52a516 100644 --- a/src/plugins/discord/discord-service.ts +++ b/src/plugins/discord/discord-service.ts @@ -98,8 +98,9 @@ export class DiscordService { const activityInfo: SetActivity = { type: ActivityType.Listening, + statusDisplayType: config.statusDisplayType, details: truncateString(songInfo.title, 128), // Song title - detailsUrl: songInfo.url, + detailsUrl: songInfo.url ?? undefined, state: truncateString(songInfo.artist, 128), // Artist name stateUrl: songInfo.artistUrl, largeImageKey: songInfo.imageSrc ?? undefined, diff --git a/src/plugins/discord/index.ts b/src/plugins/discord/index.ts index 6fefbdc9ca..c76e0eace6 100644 --- a/src/plugins/discord/index.ts +++ b/src/plugins/discord/index.ts @@ -2,6 +2,7 @@ import { createPlugin } from '@/utils'; import { backend } from './main'; import { onMenu } from './menu'; import { t } from '@/i18n'; +import { DiscordStatusDisplayType } from './constants'; export type DiscordPluginConfig = { enabled: boolean; @@ -33,6 +34,10 @@ export type DiscordPluginConfig = { * Hide the "duration left" in the rich presence */ hideDurationLeft: boolean; + /** + * Controls which field is displayed in the Discord status text + */ + statusDisplayType: (typeof DiscordStatusDisplayType)[keyof typeof DiscordStatusDisplayType]; }; export default createPlugin({ @@ -47,6 +52,7 @@ export default createPlugin({ playOnYouTubeMusic: true, hideGitHubButton: false, hideDurationLeft: false, + statusDisplayType: DiscordStatusDisplayType.ARTIST, } as DiscordPluginConfig, menu: onMenu, backend, diff --git a/src/plugins/discord/menu.ts b/src/plugins/discord/menu.ts index 25a34fe3a4..bcdf68d95e 100644 --- a/src/plugins/discord/menu.ts +++ b/src/plugins/discord/menu.ts @@ -12,11 +12,18 @@ import type { MenuContext } from '@/types/contexts'; import type { DiscordPluginConfig } from './index'; import type { MenuTemplate } from '@/menu'; +import { DiscordStatusDisplayType } from './constants'; const registerRefreshOnce = singleton((refreshMenu: () => void) => { discordService?.registerRefreshCallback(refreshMenu); }); +const DiscordStatusDisplayTypeLabels = { + [DiscordStatusDisplayType.YOUTUBE_MUSIC]: "plugins.discord.menu.set-status-display-type.submenu.youtube-music", + [DiscordStatusDisplayType.ARTIST]: "plugins.discord.menu.set-status-display-type.submenu.artist", + [DiscordStatusDisplayType.TITLE]: "plugins.discord.menu.set-status-display-type.submenu.title", +} + export const onMenu = async ({ window, getConfig, @@ -92,6 +99,19 @@ export const onMenu = async ({ label: t('plugins.discord.menu.set-inactivity-timeout'), click: () => setInactivityTimeout(window, config), }, + { + label: t('plugins.discord.menu.set-status-display-type.label'), + submenu: Object.values(DiscordStatusDisplayType).map((statusDisplayType) => ({ + label: t(DiscordStatusDisplayTypeLabels[statusDisplayType]), + type: 'radio', + checked: config.statusDisplayType == statusDisplayType, + click() { + setConfig({ + statusDisplayType + }); + }, + })), + }, ]; };