mirror of
https://github.com/Psychotoxical/psysonic.git
synced 2026-07-22 07:15:47 +00:00
Merge pull request #198 from kveld9/feat/DRP-enhancement
feat: discord rich presence enhancement
This commit is contained in:
@@ -539,6 +539,11 @@ export const deTranslation = {
|
||||
useCustomTitlebarDesc: 'Ersetzt die System-Titelleiste durch eine eingebaute, die zum App-Theme passt. Deaktivieren, um die native GNOME/GTK-Titelleiste zu verwenden.',
|
||||
discordAppleCovers: 'Cover über Apple Music für Discord laden',
|
||||
discordAppleCoversDesc: 'Sendet Künstler- und Albumname an die Apple-Such-API, um Cover für dein Discord-Profil zu finden. Standardmäßig aus Datenschutzgründen deaktiviert.',
|
||||
discordTemplates: 'Benutzerdefinierte Textvorlagen',
|
||||
discordTemplatesDesc: 'Passen Sie an, welche Informationen in Ihrem Discord-Profil angezeigt werden. Variablen: {title}, {artist}, {album}',
|
||||
discordTemplateDetails: 'Primäre Zeile (details)',
|
||||
discordTemplateState: 'Sekundäre Zeile (state)',
|
||||
discordTemplateLargeText: 'Album-Tooltip (largeText)',
|
||||
nowPlayingEnabled: 'Im Livefenster anzeigen',
|
||||
nowPlayingEnabledDesc: 'Überträgt den aktuell gespielten Titel an die Livehörer-Ansicht des Servers. Deaktivieren, um keine Wiedergabedaten zu senden.',
|
||||
lyricsServerFirst: 'Server-Lyrics bevorzugen',
|
||||
|
||||
@@ -541,6 +541,11 @@ export const enTranslation = {
|
||||
useCustomTitlebarDesc: 'Replace the system title bar with a built-in one that matches the app theme. Disable to use the native GNOME/GTK title bar.',
|
||||
discordAppleCovers: 'Fetch covers from Apple Music for Discord',
|
||||
discordAppleCoversDesc: 'Sends the artist and album name to Apple\'s search API to find cover art for your Discord profile. Disabled by default for privacy.',
|
||||
discordTemplates: 'Custom text templates',
|
||||
discordTemplatesDesc: 'Customize what information is shown on your Discord profile. Variables: {title}, {artist}, {album}',
|
||||
discordTemplateDetails: 'Primary line (details)',
|
||||
discordTemplateState: 'Secondary line (state)',
|
||||
discordTemplateLargeText: 'Album tooltip (largeText)',
|
||||
nowPlayingEnabled: 'Show in Now Playing',
|
||||
nowPlayingEnabledDesc: 'Broadcast your currently playing track to the server\'s live listener view. Disable to stop sending playback data.',
|
||||
lyricsServerFirst: 'Prefer server lyrics',
|
||||
|
||||
@@ -542,6 +542,11 @@ export const esTranslation = {
|
||||
useCustomTitlebarDesc: 'Reemplaza la barra de título del sistema con una integrada que coincide con el tema de la app. Desactiva para usar la barra nativa de GNOME/GTK.',
|
||||
discordAppleCovers: 'Obtener portadas de Apple Music para Discord',
|
||||
discordAppleCoversDesc: 'Envía el artista y nombre del álbum a la API de búsqueda de Apple para encontrar portadas para tu perfil de Discord. Desactivado por defecto por privacidad.',
|
||||
discordTemplates: 'Plantillas de texto personalizadas',
|
||||
discordTemplatesDesc: 'Personaliza qué información se muestra en tu perfil de Discord. Variables: {title}, {artist}, {album}',
|
||||
discordTemplateDetails: 'Línea principal (details)',
|
||||
discordTemplateState: 'Línea secundaria (state)',
|
||||
discordTemplateLargeText: 'Tooltip del álbum (largeText)',
|
||||
nowPlayingEnabled: 'Mostrar en Reproduciendo Ahora',
|
||||
nowPlayingEnabledDesc: 'Transmite tu pista actual a la vista de oyentes en vivo del servidor. Desactiva para dejar de enviar datos de reproducción.',
|
||||
lyricsServerFirst: 'Preferir letras del servidor',
|
||||
|
||||
@@ -537,6 +537,11 @@ export const frTranslation = {
|
||||
discordRichPresenceDesc: 'Affiche le titre en cours de lecture sur votre profil Discord. Discord doit être ouvert.',
|
||||
discordAppleCovers: 'Récupérer les pochettes via Apple Music pour Discord',
|
||||
discordAppleCoversDesc: 'Envoie le nom de l\'artiste et de l\'album à l\'API Apple pour trouver une pochette pour votre profil Discord. Désactivé par défaut pour des raisons de confidentialité.',
|
||||
discordTemplates: 'Modèles de texte personnalisés',
|
||||
discordTemplatesDesc: 'Personnalisez les informations affichées sur votre profil Discord. Variables : {title}, {artist}, {album}',
|
||||
discordTemplateDetails: 'Ligne principale (details)',
|
||||
discordTemplateState: 'Ligne secondaire (state)',
|
||||
discordTemplateLargeText: 'Info-bulle album (largeText)',
|
||||
nowPlayingEnabled: 'Afficher dans la fenêtre live',
|
||||
nowPlayingEnabledDesc: 'Diffuse le titre en cours de lecture vers la vue des auditeurs en direct du serveur. Désactiver pour ne pas envoyer de données de lecture.',
|
||||
lyricsServerFirst: 'Préférer les paroles du serveur',
|
||||
|
||||
@@ -536,6 +536,11 @@ export const nbTranslation = {
|
||||
discordRichPresenceDesc: 'Vis sporet som spilles i din Discord-profil. Krever at Discord kjører.',
|
||||
discordAppleCovers: 'Hent covere fra Apple Music til Discord',
|
||||
discordAppleCoversDesc: 'Sender artist- og albumnavn til Apples søke-API for å finne cover til Discord-profilen din. Deaktivert som standard av personvernhensyn.',
|
||||
discordTemplates: 'Egendefinerte tekstmaler',
|
||||
discordTemplatesDesc: 'Tilpass hvilken informasjon som vises på Discord-profilen din. Variabler: {title}, {artist}, {album}',
|
||||
discordTemplateDetails: 'Primær linje (details)',
|
||||
discordTemplateState: 'Sekundær linje (state)',
|
||||
discordTemplateLargeText: 'Album-verktøytips (largeText)',
|
||||
nowPlayingEnabled: 'Vis i "Nå spiller"',
|
||||
nowPlayingEnabledDesc: 'Send sporet som spilles av til tjenerens live-lyttervisning. Deaktiver for å stoppe sending av avspillingsdata.',
|
||||
lyricsServerFirst: 'Foretrekk server-sangtekst',
|
||||
|
||||
@@ -536,6 +536,11 @@ export const nlTranslation = {
|
||||
discordRichPresenceDesc: 'Toont het huidige nummer op je Discord-profiel. Discord moet daarvoor geopend zijn.',
|
||||
discordAppleCovers: 'Hoezen ophalen via Apple Music voor Discord',
|
||||
discordAppleCoversDesc: 'Stuurt artiest- en albumnaam naar de Apple-zoek-API om een hoes te vinden voor je Discord-profiel. Standaard uitgeschakeld vanwege privacy.',
|
||||
discordTemplates: 'Aangepaste tekstsjablonen',
|
||||
discordTemplatesDesc: 'Pas aan welke informatie wordt weergegeven op je Discord-profiel. Variabelen: {title}, {artist}, {album}',
|
||||
discordTemplateDetails: 'Primaire regel (details)',
|
||||
discordTemplateState: 'Secundaire regel (state)',
|
||||
discordTemplateLargeText: 'Album-tooltip (largeText)',
|
||||
nowPlayingEnabled: 'Weergeven in live-venster',
|
||||
nowPlayingEnabledDesc: 'Stuurt het huidige nummer naar de live-luisteraarsweergave van de server. Uitschakelen om geen afspeelgegevens te verzenden.',
|
||||
lyricsServerFirst: 'Server-songtekst voorrang geven',
|
||||
|
||||
@@ -559,6 +559,11 @@ export const ruTranslation = {
|
||||
'Показывать текущий трек в профиле и статусе Discord. Нужен запущенный клиент Discord.',
|
||||
discordAppleCovers: 'Загружать обложки через Apple Music для Discord',
|
||||
discordAppleCoversDesc: 'Отправляет имя исполнителя и альбома в Apple Music API для поиска обложки для профиля Discord. По умолчанию отключено из соображений конфиденциальности.',
|
||||
discordTemplates: 'Пользовательские шаблоны текста',
|
||||
discordTemplatesDesc: 'Настройте, какая информация отображается в профиле Discord. Переменные: {title}, {artist}, {album}',
|
||||
discordTemplateDetails: 'Основная строка (details)',
|
||||
discordTemplateState: 'Вторичная строка (state)',
|
||||
discordTemplateLargeText: 'Подсказка альбома (largeText)',
|
||||
nowPlayingEnabled: 'Показывать в «Сейчас играет»',
|
||||
nowPlayingEnabledDesc:
|
||||
'Отправлять на сервер, что вы сейчас слушаете. Отключите, чтобы не делиться этим.',
|
||||
|
||||
@@ -532,6 +532,11 @@ export const zhTranslation = {
|
||||
discordRichPresenceDesc: '在 Discord 个人资料上显示当前播放的曲目。需要 Discord 处于运行状态。',
|
||||
discordAppleCovers: '通过 Apple Music 为 Discord 获取封面',
|
||||
discordAppleCoversDesc: '将艺术家和专辑名称发送至 Apple 搜索 API,以为 Discord 个人资料查找封面图片。出于隐私考虑,默认禁用。',
|
||||
discordTemplates: '自定义文本模板',
|
||||
discordTemplatesDesc: '自定义在 Discord 个人资料上显示的信息。变量:{title}, {artist}, {album}',
|
||||
discordTemplateDetails: '主行 (details)',
|
||||
discordTemplateState: '副行 (state)',
|
||||
discordTemplateLargeText: '专辑提示 (largeText)',
|
||||
nowPlayingEnabled: '在实时窗口中显示',
|
||||
nowPlayingEnabledDesc: '将当前播放的曲目广播到服务器的实时听众视图。禁用以停止发送播放数据。',
|
||||
lyricsServerFirst: '优先使用服务器歌词',
|
||||
|
||||
@@ -1155,6 +1155,41 @@ export default function Settings() {
|
||||
<span className="toggle-track" />
|
||||
</label>
|
||||
</div>
|
||||
<div className="settings-section-divider" />
|
||||
<div style={{ paddingLeft: 16, paddingTop: 8, paddingBottom: 8 }}>
|
||||
<div style={{ fontWeight: 500, fontSize: 13, marginBottom: 8 }}>{t('settings.discordTemplates')}</div>
|
||||
<div style={{ fontSize: 12, color: 'var(--text-muted)', marginBottom: 12 }}>{t('settings.discordTemplatesDesc')}</div>
|
||||
<div className="form-group" style={{ marginBottom: '0.75rem' }}>
|
||||
<label style={{ fontSize: 12 }}>{t('settings.discordTemplateDetails')}</label>
|
||||
<input
|
||||
className="input"
|
||||
type="text"
|
||||
value={auth.discordTemplateDetails}
|
||||
onChange={e => auth.setDiscordTemplateDetails(e.target.value)}
|
||||
placeholder="{artist} - {title}"
|
||||
/>
|
||||
</div>
|
||||
<div className="form-group" style={{ marginBottom: '0.75rem' }}>
|
||||
<label style={{ fontSize: 12 }}>{t('settings.discordTemplateState')}</label>
|
||||
<input
|
||||
className="input"
|
||||
type="text"
|
||||
value={auth.discordTemplateState}
|
||||
onChange={e => auth.setDiscordTemplateState(e.target.value)}
|
||||
placeholder="{album}"
|
||||
/>
|
||||
</div>
|
||||
<div className="form-group">
|
||||
<label style={{ fontSize: 12 }}>{t('settings.discordTemplateLargeText')}</label>
|
||||
<input
|
||||
className="input"
|
||||
type="text"
|
||||
value={auth.discordTemplateLargeText}
|
||||
onChange={e => auth.setDiscordTemplateLargeText(e.target.value)}
|
||||
placeholder="{album}"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
<div className="settings-section-divider" />
|
||||
|
||||
@@ -61,6 +61,9 @@ interface AuthState {
|
||||
minimizeToTray: boolean;
|
||||
discordRichPresence: boolean;
|
||||
enableAppleMusicCoversDiscord: boolean;
|
||||
discordTemplateDetails: string;
|
||||
discordTemplateState: string;
|
||||
discordTemplateLargeText: string;
|
||||
useCustomTitlebar: boolean;
|
||||
nowPlayingEnabled: boolean;
|
||||
lyricsServerFirst: boolean;
|
||||
@@ -187,6 +190,9 @@ interface AuthState {
|
||||
setMinimizeToTray: (v: boolean) => void;
|
||||
setDiscordRichPresence: (v: boolean) => void;
|
||||
setEnableAppleMusicCoversDiscord: (v: boolean) => void;
|
||||
setDiscordTemplateDetails: (v: string) => void;
|
||||
setDiscordTemplateState: (v: string) => void;
|
||||
setDiscordTemplateLargeText: (v: string) => void;
|
||||
setUseCustomTitlebar: (v: boolean) => void;
|
||||
setNowPlayingEnabled: (v: boolean) => void;
|
||||
setLyricsServerFirst: (v: boolean) => void;
|
||||
@@ -285,6 +291,9 @@ export const useAuthStore = create<AuthState>()(
|
||||
minimizeToTray: false,
|
||||
discordRichPresence: false,
|
||||
enableAppleMusicCoversDiscord: false,
|
||||
discordTemplateDetails: '{artist} - {title}',
|
||||
discordTemplateState: '{album}',
|
||||
discordTemplateLargeText: '{album}',
|
||||
useCustomTitlebar: false,
|
||||
nowPlayingEnabled: false,
|
||||
lyricsServerFirst: true,
|
||||
@@ -407,6 +416,9 @@ export const useAuthStore = create<AuthState>()(
|
||||
setMinimizeToTray: (v) => set({ minimizeToTray: v }),
|
||||
setDiscordRichPresence: (v) => set({ discordRichPresence: v }),
|
||||
setEnableAppleMusicCoversDiscord: (v) => set({ enableAppleMusicCoversDiscord: v }),
|
||||
setDiscordTemplateDetails: (v) => set({ discordTemplateDetails: v }),
|
||||
setDiscordTemplateState: (v) => set({ discordTemplateState: v }),
|
||||
setDiscordTemplateLargeText: (v) => set({ discordTemplateLargeText: v }),
|
||||
setUseCustomTitlebar: (v) => set({ useCustomTitlebar: v }),
|
||||
setNowPlayingEnabled: (v) => set({ nowPlayingEnabled: v }),
|
||||
setLyricsServerFirst: (v: boolean) => set({ lyricsServerFirst: v }),
|
||||
|
||||
@@ -745,16 +745,28 @@ export function initAudioListeners(): () => void {
|
||||
let discordPrevTrackId: string | null = null;
|
||||
let discordPrevIsPlaying: boolean | null = null;
|
||||
let discordPrevFetchCovers: boolean | null = null;
|
||||
let discordPrevTemplateDetails: string | null = null;
|
||||
let discordPrevTemplateState: string | null = null;
|
||||
let discordPrevTemplateLargeText: string | null = null;
|
||||
|
||||
function syncDiscord() {
|
||||
const { currentTrack, isPlaying, currentTime } = usePlayerStore.getState();
|
||||
const { discordRichPresence, enableAppleMusicCoversDiscord } = useAuthStore.getState();
|
||||
const {
|
||||
discordRichPresence,
|
||||
enableAppleMusicCoversDiscord,
|
||||
discordTemplateDetails,
|
||||
discordTemplateState,
|
||||
discordTemplateLargeText,
|
||||
} = useAuthStore.getState();
|
||||
|
||||
if (!discordRichPresence || !currentTrack) {
|
||||
if (discordPrevTrackId !== null) {
|
||||
discordPrevTrackId = null;
|
||||
discordPrevIsPlaying = null;
|
||||
discordPrevFetchCovers = null;
|
||||
discordPrevTemplateDetails = null;
|
||||
discordPrevTemplateState = null;
|
||||
discordPrevTemplateLargeText = null;
|
||||
invoke('discord_clear_presence').catch(() => {});
|
||||
}
|
||||
return;
|
||||
@@ -763,24 +775,31 @@ export function initAudioListeners(): () => void {
|
||||
const trackChanged = currentTrack.id !== discordPrevTrackId;
|
||||
const playingChanged = isPlaying !== discordPrevIsPlaying;
|
||||
const coversSettingChanged = enableAppleMusicCoversDiscord !== discordPrevFetchCovers;
|
||||
if (!trackChanged && !playingChanged && !coversSettingChanged) return;
|
||||
const detailsTemplateChanged = discordTemplateDetails !== discordPrevTemplateDetails;
|
||||
const stateTemplateChanged = discordTemplateState !== discordPrevTemplateState;
|
||||
const largeTextTemplateChanged = discordTemplateLargeText !== discordPrevTemplateLargeText;
|
||||
if (!trackChanged && !playingChanged && !coversSettingChanged && !detailsTemplateChanged && !stateTemplateChanged && !largeTextTemplateChanged) return;
|
||||
|
||||
discordPrevTrackId = currentTrack.id;
|
||||
discordPrevIsPlaying = isPlaying;
|
||||
discordPrevFetchCovers = enableAppleMusicCoversDiscord;
|
||||
discordPrevTemplateDetails = discordTemplateDetails;
|
||||
discordPrevTemplateState = discordTemplateState;
|
||||
discordPrevTemplateLargeText = discordTemplateLargeText;
|
||||
|
||||
invoke('discord_update_presence', {
|
||||
title: currentTrack.title,
|
||||
artist: currentTrack.artist ?? 'Unknown Artist',
|
||||
album: currentTrack.album ?? null,
|
||||
isPlaying,
|
||||
// Pass elapsed when playing so Discord shows a live running timer.
|
||||
// Pass null when paused — Discord clears the timer.
|
||||
elapsedSecs: isPlaying ? currentTime : null,
|
||||
// coverArtUrl is intentionally not passed — Subsonic URLs require auth.
|
||||
// iTunes cover fetching is only done when explicitly opted in.
|
||||
coverArtUrl: null,
|
||||
fetchItunesCovers: enableAppleMusicCoversDiscord,
|
||||
detailsTemplate: discordTemplateDetails,
|
||||
stateTemplate: discordTemplateState,
|
||||
largeTextTemplate: discordTemplateLargeText,
|
||||
}).catch(() => {});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user