From 5ecd39f324544112edb8174c968154346e3aefd0 Mon Sep 17 00:00:00 2001 From: cxntered Date: Sun, 7 Sep 2025 05:29:38 +1000 Subject: [PATCH] feat(api-server): send shuffle state over websocket (#3837) --- src/plugins/api-server/backend/main.ts | 1 + src/plugins/api-server/backend/routes/websocket.ts | 12 ++++++++++++ src/providers/song-info-front.ts | 2 ++ 3 files changed, 15 insertions(+) diff --git a/src/plugins/api-server/backend/main.ts b/src/plugins/api-server/backend/main.ts index 0e45dca5..4430e5f3 100644 --- a/src/plugins/api-server/backend/main.ts +++ b/src/plugins/api-server/backend/main.ts @@ -35,6 +35,7 @@ export const backend = createBackend({ ctx.ipc.send('ytmd:setup-repeat-changed-listener'); ctx.ipc.send('ytmd:setup-like-changed-listener'); ctx.ipc.send('ytmd:setup-volume-changed-listener'); + ctx.ipc.send('ytmd:setup-shuffle-changed-listener'); }); ctx.ipc.on( diff --git a/src/plugins/api-server/backend/routes/websocket.ts b/src/plugins/api-server/backend/routes/websocket.ts index 880762e3..d3a03d06 100644 --- a/src/plugins/api-server/backend/routes/websocket.ts +++ b/src/plugins/api-server/backend/routes/websocket.ts @@ -23,6 +23,7 @@ enum DataTypes { PositionChanged = 'POSITION_CHANGED', VolumeChanged = 'VOLUME_CHANGED', RepeatChanged = 'REPEAT_CHANGED', + ShuffleChanged = 'SHUFFLE_CHANGED', } type PlayerState = { @@ -32,11 +33,13 @@ type PlayerState = { position: number; volume: number; repeat: RepeatMode; + shuffle: boolean; }; export const register = (app: HonoApp, nodeWebSocket: NodeWebSocket) => { let volumeState: VolumeState | undefined = undefined; let repeat: RepeatMode = 'NONE'; + let shuffle = false; let lastSongInfo: SongInfo | undefined = undefined; const sockets = new Set>(); @@ -51,10 +54,12 @@ export const register = (app: HonoApp, nodeWebSocket: NodeWebSocket) => { songInfo, volumeState, repeat, + shuffle, }: { songInfo?: SongInfo; volumeState?: VolumeState; repeat: RepeatMode; + shuffle: boolean; }): PlayerState => ({ song: songInfo, isPlaying: songInfo ? !songInfo.isPaused : false, @@ -62,6 +67,7 @@ export const register = (app: HonoApp, nodeWebSocket: NodeWebSocket) => { position: songInfo?.elapsedSeconds ?? 0, volume: volumeState?.state ?? 100, repeat, + shuffle, }); registerCallback((songInfo, event) => { @@ -100,6 +106,11 @@ export const register = (app: HonoApp, nodeWebSocket: NodeWebSocket) => { send(DataTypes.PositionChanged, { position: t }); }); + ipcMain.on('ytmd:shuffle-changed', (_, newShuffle: boolean) => { + shuffle = newShuffle; + send(DataTypes.ShuffleChanged, { shuffle }); + }); + app.openapi( createRoute({ method: 'get', @@ -124,6 +135,7 @@ export const register = (app: HonoApp, nodeWebSocket: NodeWebSocket) => { songInfo: lastSongInfo, volumeState, repeat, + shuffle, }), }), ); diff --git a/src/providers/song-info-front.ts b/src/providers/song-info-front.ts index 680e9449..2012351d 100644 --- a/src/providers/song-info-front.ts +++ b/src/providers/song-info-front.ts @@ -145,6 +145,7 @@ export const setupShuffleChangedListener = singleton(() => { observer.observe(playerBar, { attributes: true, + attributeFilter: ['shuffle-on'], childList: false, subtree: false, }); @@ -168,6 +169,7 @@ export const setupFullScreenChangedListener = singleton(() => { observer.observe(playerBar, { attributes: true, + attributeFilter: ['player-fullscreened'], childList: false, subtree: false, });