mirror of
https://github.com/Psychotoxical/psysonic.git
synced 2026-07-21 23:05:46 +00:00
feat(discord): show track title in Discord member list (configurable name template) (#885)
* feat(discord): override activity name in member list with track title (configurable template)
The Discord member list and the collapsed Rich Presence card display the
activity's `name` field next to the music icon. Without an override
Discord falls back to the registered application name ("Psysonic"), so
the line reads "Psysonic" while every track plays instead of the actual
track title that comparable players show.
Add a fourth user-configurable template `discordTemplateName` (Settings ->
Integrations -> Discord Rich Presence). The Rust side passes it through
`Activity::new().name(...)` when the rendered template is non-empty; an
empty template falls back to Discord's default application name. Default
template is "{title}".
Tauri boundary: additive optional `nameTemplate` field on the existing
`discord_update_presence` command. Existing call sites that omit it keep
working -- the Rust handler applies the same "{title}" fallback.
* i18n(settings): discord name template label in all locales
Adds the discordTemplateName label across en, de, fr, es, nl, nb, ro,
zh, ru -- shown next to the new "User list line (name)" template input
under Discord Rich Presence.
* docs(release): CHANGELOG and credits for discord name template (PR #885)
This commit is contained in:
committed by
GitHub
parent
403979b35d
commit
455aec4def
@@ -18,6 +18,7 @@ export function setupDiscordPresence(): () => void {
|
||||
let discordPrevTemplateDetails: string | null = null;
|
||||
let discordPrevTemplateState: string | null = null;
|
||||
let discordPrevTemplateLargeText: string | null = null;
|
||||
let discordPrevTemplateName: string | null = null;
|
||||
let discordPrevCoverSource: string | null = null;
|
||||
const discordServerCoverCache = new Map<string, string | null>();
|
||||
|
||||
@@ -30,6 +31,7 @@ export function setupDiscordPresence(): () => void {
|
||||
discordTemplateDetails,
|
||||
discordTemplateState,
|
||||
discordTemplateLargeText,
|
||||
discordTemplateName,
|
||||
} = useAuthStore.getState();
|
||||
|
||||
if (!discordRichPresence || !currentTrack) {
|
||||
@@ -41,6 +43,7 @@ export function setupDiscordPresence(): () => void {
|
||||
discordPrevTemplateDetails = null;
|
||||
discordPrevTemplateState = null;
|
||||
discordPrevTemplateLargeText = null;
|
||||
discordPrevTemplateName = null;
|
||||
invoke('discord_clear_presence').catch(() => {});
|
||||
}
|
||||
return;
|
||||
@@ -52,7 +55,8 @@ export function setupDiscordPresence(): () => void {
|
||||
const detailsTemplateChanged = discordTemplateDetails !== discordPrevTemplateDetails;
|
||||
const stateTemplateChanged = discordTemplateState !== discordPrevTemplateState;
|
||||
const largeTextTemplateChanged = discordTemplateLargeText !== discordPrevTemplateLargeText;
|
||||
if (!trackChanged && !playingChanged && !coverSourceChanged && !detailsTemplateChanged && !stateTemplateChanged && !largeTextTemplateChanged) return;
|
||||
const nameTemplateChanged = discordTemplateName !== discordPrevTemplateName;
|
||||
if (!trackChanged && !playingChanged && !coverSourceChanged && !detailsTemplateChanged && !stateTemplateChanged && !largeTextTemplateChanged && !nameTemplateChanged) return;
|
||||
|
||||
discordPrevTrackId = currentTrack.id;
|
||||
discordPrevIsPlaying = isPlaying;
|
||||
@@ -61,6 +65,7 @@ export function setupDiscordPresence(): () => void {
|
||||
discordPrevTemplateDetails = discordTemplateDetails;
|
||||
discordPrevTemplateState = discordTemplateState;
|
||||
discordPrevTemplateLargeText = discordTemplateLargeText;
|
||||
discordPrevTemplateName = discordTemplateName;
|
||||
|
||||
const sendPresence = (coverArtUrl: string | null) => {
|
||||
invoke('discord_update_presence', {
|
||||
@@ -74,6 +79,7 @@ export function setupDiscordPresence(): () => void {
|
||||
detailsTemplate: discordTemplateDetails,
|
||||
stateTemplate: discordTemplateState,
|
||||
largeTextTemplate: discordTemplateLargeText,
|
||||
nameTemplate: discordTemplateName,
|
||||
}).catch(() => {});
|
||||
};
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ export function createDiscordSettingsActions(set: SetState): Pick<
|
||||
| 'setDiscordTemplateDetails'
|
||||
| 'setDiscordTemplateState'
|
||||
| 'setDiscordTemplateLargeText'
|
||||
| 'setDiscordTemplateName'
|
||||
> {
|
||||
return {
|
||||
setDiscordRichPresence: (v) => set({ discordRichPresence: v }),
|
||||
@@ -20,5 +21,6 @@ export function createDiscordSettingsActions(set: SetState): Pick<
|
||||
setDiscordTemplateDetails: (v) => set({ discordTemplateDetails: v }),
|
||||
setDiscordTemplateState: (v) => set({ discordTemplateState: v }),
|
||||
setDiscordTemplateLargeText: (v) => set({ discordTemplateLargeText: v }),
|
||||
setDiscordTemplateName: (v) => set({ discordTemplateName: v }),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -98,6 +98,7 @@ describe('trivial pass-through setters', () => {
|
||||
['setDiscordTemplateDetails', 'discordTemplateDetails', '{artist} — {title}'],
|
||||
['setDiscordTemplateState', 'discordTemplateState', '{album}'],
|
||||
['setDiscordTemplateLargeText', 'discordTemplateLargeText', 'Hi'],
|
||||
['setDiscordTemplateName', 'discordTemplateName', '{title} — {artist}'],
|
||||
])('%s stores a string value', (setter, key, value) => {
|
||||
(useAuthStore.getState() as unknown as Record<string, (v: unknown) => void>)[setter](value);
|
||||
expect((useAuthStore.getState() as unknown as Record<string, unknown>)[key]).toBe(value);
|
||||
|
||||
@@ -75,6 +75,7 @@ export const useAuthStore = create<AuthState>()(
|
||||
discordTemplateDetails: '{artist}',
|
||||
discordTemplateState: '{title}',
|
||||
discordTemplateLargeText: '{album}',
|
||||
discordTemplateName: '{title}',
|
||||
useCustomTitlebar: false,
|
||||
preloadMiniPlayer: false,
|
||||
linuxWebkitKineticScroll: true,
|
||||
|
||||
@@ -128,6 +128,10 @@ export interface AuthState {
|
||||
discordTemplateDetails: string;
|
||||
discordTemplateState: string;
|
||||
discordTemplateLargeText: string;
|
||||
/** Template for Discord activity name (overrides the registered application
|
||||
* name in the user list / collapsed presence). Default "{title}".
|
||||
* Empty string falls back to "Psysonic". */
|
||||
discordTemplateName: string;
|
||||
useCustomTitlebar: boolean;
|
||||
/** Pre-build the mini-player webview at app start on Linux/macOS so content is available instantly
|
||||
* on first open. Ignored on Windows — that platform always pre-creates as a hang workaround. */
|
||||
@@ -311,6 +315,7 @@ export interface AuthState {
|
||||
setDiscordTemplateDetails: (v: string) => void;
|
||||
setDiscordTemplateState: (v: string) => void;
|
||||
setDiscordTemplateLargeText: (v: string) => void;
|
||||
setDiscordTemplateName: (v: string) => void;
|
||||
setUseCustomTitlebar: (v: boolean) => void;
|
||||
setPreloadMiniPlayer: (v: boolean) => void;
|
||||
setLinuxWebkitKineticScroll: (v: boolean) => void;
|
||||
|
||||
Reference in New Issue
Block a user