From 8e4e2c42f67141224afc01f19e39a8ab973d3255 Mon Sep 17 00:00:00 2001 From: pynappo Date: Thu, 4 Sep 2025 23:58:26 -0700 Subject: [PATCH] feat(discord): add option to display artist/title in status (#3692) Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: JellyBrick --- src/i18n/resources/en.json | 10 +++++++++- src/plugins/discord/constants.ts | 10 ++++++++++ src/plugins/discord/discord-service.ts | 3 ++- src/plugins/discord/index.ts | 6 ++++++ src/plugins/discord/menu.ts | 20 ++++++++++++++++++++ 5 files changed, 47 insertions(+), 2 deletions(-) diff --git a/src/i18n/resources/en.json b/src/i18n/resources/en.json index 532e7859..f7da4f6d 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 c2abcc02..e66c92ca 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 65d53446..60bc52a5 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 6fefbdc9..c76e0eac 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 25a34fe3..bcdf68d9 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 + }); + }, + })), + }, ]; };