From 212d9e9f5561c19c901daf0eb471cf92a70918a2 Mon Sep 17 00:00:00 2001 From: jeffvli Date: Fri, 28 Nov 2025 14:29:27 -0800 Subject: [PATCH] add mpris --- .../player/components/audio-players.tsx | 2 + .../features/player/hooks/use-mpris.ts | 68 +++++++++++++++++++ 2 files changed, 70 insertions(+) create mode 100644 src/renderer/features/player/hooks/use-mpris.ts diff --git a/src/renderer/features/player/components/audio-players.tsx b/src/renderer/features/player/components/audio-players.tsx index cc045b53c..b8cbbd2f5 100644 --- a/src/renderer/features/player/components/audio-players.tsx +++ b/src/renderer/features/player/components/audio-players.tsx @@ -5,6 +5,7 @@ import { UserFavoriteEventPayload, UserRatingEventPayload } from '/@/renderer/ev import { useDiscordRpc } from '/@/renderer/features/discord-rpc/use-discord-rpc'; import { MpvPlayer } from '/@/renderer/features/player/audio-player/mpv-player'; import { WebPlayer } from '/@/renderer/features/player/audio-player/web-player'; +import { useMPRIS } from '/@/renderer/features/player/hooks/use-mpris'; import { usePowerSaveBlocker } from '/@/renderer/features/player/hooks/use-power-save-blocker'; import { useScrobble } from '/@/renderer/features/player/hooks/use-scrobble'; import { @@ -23,6 +24,7 @@ export const AudioPlayers = () => { useScrobble(); usePowerSaveBlocker(); useDiscordRpc(); + useMPRIS(); // Listen to favorite and rating events to update queue songs useEffect(() => { diff --git a/src/renderer/features/player/hooks/use-mpris.ts b/src/renderer/features/player/hooks/use-mpris.ts new file mode 100644 index 000000000..43d61e868 --- /dev/null +++ b/src/renderer/features/player/hooks/use-mpris.ts @@ -0,0 +1,68 @@ +import isElectron from 'is-electron'; +import { useEffect } from 'react'; + +import { usePlayerEvents } from '/@/renderer/features/player/audio-player/hooks/use-player-events'; +import { usePlayerStore } from '/@/renderer/store'; + +const ipc = isElectron() ? window.api.ipc : null; +const utils = isElectron() ? window.api.utils : null; +const mpris = isElectron() && utils?.isLinux() ? window.api.mpris : null; + +export const useMPRIS = () => { + const player = usePlayerStore(); + + useEffect(() => { + if (!mpris) { + return; + } + + mpris?.requestToggleRepeat(() => { + player.toggleRepeat(); + }); + + mpris?.requestToggleShuffle(() => { + player.toggleShuffle(); + }); + + return () => { + ipc?.removeAllListeners('mpris-request-toggle-repeat'); + ipc?.removeAllListeners('mpris-request-toggle-shuffle'); + }; + }, [player]); + + usePlayerEvents( + { + onPlayerProgress: (properties) => { + if (!mpris) { + return; + } + + const timestamp = properties.timestamp; + mpris?.updatePosition(timestamp); + }, + onPlayerRepeat: () => { + if (!mpris) { + return; + } + + mpris?.toggleRepeat(); + }, + onPlayerSeek: (properties) => { + if (!mpris) { + return; + } + + const seconds = properties.seconds; + mpris?.updateSeek(seconds); + }, + onPlayerShuffle: () => { + if (!mpris) { + return; + } + + mpris?.toggleShuffle(); + }, + }, + [], + ); +};