Update dashboard (stats, recent tracks/activity), discover, distribution, education, feed, subscription, support, search, settings, live, cloud, analytics, auth, chat, social, tracks, playlists, presence, upload, and library manager. Consistent UI patterns and error handling. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
39 lines
1.3 KiB
TypeScript
39 lines
1.3 KiB
TypeScript
/**
|
|
* usePresenceSync (v0.302 P2.1)
|
|
* Syncs current track to presence (rich presence "Écoute X")
|
|
* Call when user is authenticated
|
|
*/
|
|
import { useEffect, useRef } from 'react';
|
|
import { usePlayerStore } from '@/features/player/store/playerStore';
|
|
import { updatePresence } from '../services/presenceService';
|
|
|
|
export function usePresenceSync(enabled: boolean) {
|
|
const currentTrack = usePlayerStore((s) => s.currentTrack);
|
|
const prevTrackIdRef = useRef<string | null>(null);
|
|
|
|
useEffect(() => {
|
|
if (!enabled) return;
|
|
|
|
const trackId = currentTrack?.id ?? null;
|
|
if (trackId === prevTrackIdRef.current) return;
|
|
prevTrackIdRef.current = trackId;
|
|
|
|
// Build payload — omit fields rather than sending undefined
|
|
// (undefined serializes incorrectly and causes "invalid request body" on backend)
|
|
const payload = currentTrack
|
|
? {
|
|
status_message: `Écoute ${currentTrack.title}`,
|
|
track_id: currentTrack.id,
|
|
track_title: currentTrack.title,
|
|
}
|
|
: {
|
|
status_message: '',
|
|
track_id: null as string | null,
|
|
track_title: null as string | null,
|
|
};
|
|
|
|
updatePresence(payload).catch(() => {
|
|
// Silently ignore - presence update is best-effort
|
|
});
|
|
}, [enabled, currentTrack?.id, currentTrack?.title]);
|
|
}
|