feat: discord presence display type

This commit is contained in:
mae taylor 2025-08-01 16:43:34 +01:00
parent 7ff74b8d5e
commit 76770de7d8
No known key found for this signature in database
GPG key ID: 3C80D76BA7A3B9BD
4 changed files with 69 additions and 2 deletions

View file

@ -529,6 +529,10 @@
"discordServeImage_description": "share cover art for {{discord}} rich presence from server itself, only available for jellyfin and navidrome", "discordServeImage_description": "share cover art for {{discord}} rich presence from server itself, only available for jellyfin and navidrome",
"discordUpdateInterval": "{{discord}} rich presence update interval", "discordUpdateInterval": "{{discord}} rich presence update interval",
"discordUpdateInterval_description": "the time in seconds between each update (minimum 15 seconds)", "discordUpdateInterval_description": "the time in seconds between each update (minimum 15 seconds)",
"discordDisplayType": "{{discord}} presence display type",
"discordDisplayType_description": "changes what you are listening to in your status",
"discordDisplayType_songname": "song name",
"discordDisplayType_artistname": "artist name(s)",
"doubleClickBehavior": "queue all searched tracks when double clicking", "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", "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", "enableRemote": "enable remote control server",

View file

@ -1,9 +1,10 @@
import { SetActivity } from '@xhayper/discord-rpc'; import { SetActivity, StatusDisplayType } from '@xhayper/discord-rpc';
import isElectron from 'is-electron'; import isElectron from 'is-electron';
import { useCallback, useEffect, useState } from 'react'; import { useCallback, useEffect, useState } from 'react';
import { controller } from '/@/renderer/api/controller'; import { controller } from '/@/renderer/api/controller';
import { import {
DiscordDisplayType,
getServerById, getServerById,
useDiscordSetttings, useDiscordSetttings,
useGeneralSettings, useGeneralSettings,
@ -54,6 +55,12 @@ export const useDiscordRpc = () => {
const artists = song?.artists.map((artist) => artist.name).join(', '); const artists = song?.artists.map((artist) => artist.name).join(', ');
const statusDisplayMap = {
[DiscordDisplayType.ARTIST_NAME]: StatusDisplayType.STATE,
[DiscordDisplayType.FEISHIN]: StatusDisplayType.NAME,
[DiscordDisplayType.SONG_NAME]: StatusDisplayType.DETAILS,
};
const activity: SetActivity = { const activity: SetActivity = {
details: song?.name.padEnd(2, ' ') || 'Idle', details: song?.name.padEnd(2, ' ') || 'Idle',
instance: false, instance: false,
@ -61,7 +68,8 @@ export const useDiscordRpc = () => {
largeImageText: song?.album || 'Unknown album', largeImageText: song?.album || 'Unknown album',
smallImageKey: undefined, smallImageKey: undefined,
smallImageText: current[2] as string, smallImageText: current[2] as string,
state: (artists && `By ${artists}`) || 'Unknown artist', state: artists || 'Unknown artist',
statusDisplayType: statusDisplayMap[discordSettings.displayType],
// I would love to use the actual type as opposed to hardcoding to 2, // I would love to use the actual type as opposed to hardcoding to 2,
// but manually installing the discord-types package appears to break things // but manually installing the discord-types package appears to break things
type: discordSettings.showAsListening ? 2 : 0, type: discordSettings.showAsListening ? 2 : 0,
@ -134,6 +142,7 @@ export const useDiscordRpc = () => {
discordSettings.showPaused, discordSettings.showPaused,
generalSettings.lastfmApiKey, generalSettings.lastfmApiKey,
discordSettings.clientId, discordSettings.clientId,
discordSettings.displayType,
lastUniqueId, lastUniqueId,
], ],
); );

View file

@ -6,10 +6,12 @@ import {
SettingsSection, SettingsSection,
} from '/@/renderer/features/settings/components/settings-section'; } from '/@/renderer/features/settings/components/settings-section';
import { import {
DiscordDisplayType,
useDiscordSetttings, useDiscordSetttings,
useGeneralSettings, useGeneralSettings,
useSettingsStoreActions, useSettingsStoreActions,
} from '/@/renderer/store'; } from '/@/renderer/store';
import { Select } from '/@/shared/components/select/select';
import { Switch } from '/@/shared/components/switch/switch'; import { Switch } from '/@/shared/components/switch/switch';
import { TextInput } from '/@/shared/components/text-input/text-input'; import { TextInput } from '/@/shared/components/text-input/text-input';
@ -120,6 +122,50 @@ export const DiscordSettings = () => {
postProcess: 'sentenceCase', postProcess: 'sentenceCase',
}), }),
}, },
{
control: (
<Select
aria-label={t('setting.discordDisplayType')}
clearable={false}
data={[
{ label: 'Feishin', value: DiscordDisplayType.FEISHIN },
{
label: t('setting.discordDisplayType', {
context: 'songname',
postProcess: 'sentenceCase',
}),
value: DiscordDisplayType.SONG_NAME,
},
{
label: t('setting.discordDisplayType_artistname', {
context: 'artistname',
postProcess: 'sentenceCase',
}),
value: DiscordDisplayType.ARTIST_NAME,
},
]}
defaultValue={settings.displayType}
onChange={(e) => {
if (!e) return;
setSettings({
discord: {
...settings,
displayType: e as DiscordDisplayType,
},
});
}}
/>
),
description: t('setting.discordDisplayType', {
context: 'description',
postProcess: 'sentenceCase',
}),
isHidden: !isElectron(),
title: t('setting.discordDisplayType', {
discord: 'Discord',
postProcess: 'sentenceCase',
}),
},
{ {
control: ( control: (
<Switch <Switch

View file

@ -157,6 +157,12 @@ export enum BindingActions {
ZOOM_OUT = 'zoomOut', ZOOM_OUT = 'zoomOut',
} }
export enum DiscordDisplayType {
ARTIST_NAME = 'artist',
FEISHIN = 'feishin',
SONG_NAME = 'song',
}
export enum GenreTarget { export enum GenreTarget {
ALBUM = 'album', ALBUM = 'album',
TRACK = 'track', TRACK = 'track',
@ -198,6 +204,7 @@ export interface SettingsState {
}; };
discord: { discord: {
clientId: string; clientId: string;
displayType: DiscordDisplayType;
enabled: boolean; enabled: boolean;
showAsListening: boolean; showAsListening: boolean;
showPaused: boolean; showPaused: boolean;
@ -353,6 +360,7 @@ const initialState: SettingsState = {
}, },
discord: { discord: {
clientId: '1165957668758900787', clientId: '1165957668758900787',
displayType: DiscordDisplayType.FEISHIN,
enabled: false, enabled: false,
showAsListening: false, showAsListening: false,
showPaused: true, showPaused: true,