feat(api-server): send shuffle state over websocket (#3837)

This commit is contained in:
cxntered
2025-09-07 05:29:38 +10:00
committed by GitHub
parent eb50596961
commit 5ecd39f324
3 changed files with 15 additions and 0 deletions

View File

@ -35,6 +35,7 @@ export const backend = createBackend<BackendType, APIServerConfig>({
ctx.ipc.send('ytmd:setup-repeat-changed-listener'); ctx.ipc.send('ytmd:setup-repeat-changed-listener');
ctx.ipc.send('ytmd:setup-like-changed-listener'); ctx.ipc.send('ytmd:setup-like-changed-listener');
ctx.ipc.send('ytmd:setup-volume-changed-listener'); ctx.ipc.send('ytmd:setup-volume-changed-listener');
ctx.ipc.send('ytmd:setup-shuffle-changed-listener');
}); });
ctx.ipc.on( ctx.ipc.on(

View File

@ -23,6 +23,7 @@ enum DataTypes {
PositionChanged = 'POSITION_CHANGED', PositionChanged = 'POSITION_CHANGED',
VolumeChanged = 'VOLUME_CHANGED', VolumeChanged = 'VOLUME_CHANGED',
RepeatChanged = 'REPEAT_CHANGED', RepeatChanged = 'REPEAT_CHANGED',
ShuffleChanged = 'SHUFFLE_CHANGED',
} }
type PlayerState = { type PlayerState = {
@ -32,11 +33,13 @@ type PlayerState = {
position: number; position: number;
volume: number; volume: number;
repeat: RepeatMode; repeat: RepeatMode;
shuffle: boolean;
}; };
export const register = (app: HonoApp, nodeWebSocket: NodeWebSocket) => { export const register = (app: HonoApp, nodeWebSocket: NodeWebSocket) => {
let volumeState: VolumeState | undefined = undefined; let volumeState: VolumeState | undefined = undefined;
let repeat: RepeatMode = 'NONE'; let repeat: RepeatMode = 'NONE';
let shuffle = false;
let lastSongInfo: SongInfo | undefined = undefined; let lastSongInfo: SongInfo | undefined = undefined;
const sockets = new Set<WSContext<WebSocket>>(); const sockets = new Set<WSContext<WebSocket>>();
@ -51,10 +54,12 @@ export const register = (app: HonoApp, nodeWebSocket: NodeWebSocket) => {
songInfo, songInfo,
volumeState, volumeState,
repeat, repeat,
shuffle,
}: { }: {
songInfo?: SongInfo; songInfo?: SongInfo;
volumeState?: VolumeState; volumeState?: VolumeState;
repeat: RepeatMode; repeat: RepeatMode;
shuffle: boolean;
}): PlayerState => ({ }): PlayerState => ({
song: songInfo, song: songInfo,
isPlaying: songInfo ? !songInfo.isPaused : false, isPlaying: songInfo ? !songInfo.isPaused : false,
@ -62,6 +67,7 @@ export const register = (app: HonoApp, nodeWebSocket: NodeWebSocket) => {
position: songInfo?.elapsedSeconds ?? 0, position: songInfo?.elapsedSeconds ?? 0,
volume: volumeState?.state ?? 100, volume: volumeState?.state ?? 100,
repeat, repeat,
shuffle,
}); });
registerCallback((songInfo, event) => { registerCallback((songInfo, event) => {
@ -100,6 +106,11 @@ export const register = (app: HonoApp, nodeWebSocket: NodeWebSocket) => {
send(DataTypes.PositionChanged, { position: t }); send(DataTypes.PositionChanged, { position: t });
}); });
ipcMain.on('ytmd:shuffle-changed', (_, newShuffle: boolean) => {
shuffle = newShuffle;
send(DataTypes.ShuffleChanged, { shuffle });
});
app.openapi( app.openapi(
createRoute({ createRoute({
method: 'get', method: 'get',
@ -124,6 +135,7 @@ export const register = (app: HonoApp, nodeWebSocket: NodeWebSocket) => {
songInfo: lastSongInfo, songInfo: lastSongInfo,
volumeState, volumeState,
repeat, repeat,
shuffle,
}), }),
}), }),
); );

View File

@ -145,6 +145,7 @@ export const setupShuffleChangedListener = singleton(() => {
observer.observe(playerBar, { observer.observe(playerBar, {
attributes: true, attributes: true,
attributeFilter: ['shuffle-on'],
childList: false, childList: false,
subtree: false, subtree: false,
}); });
@ -168,6 +169,7 @@ export const setupFullScreenChangedListener = singleton(() => {
observer.observe(playerBar, { observer.observe(playerBar, {
attributes: true, attributes: true,
attributeFilter: ['player-fullscreened'],
childList: false, childList: false,
subtree: false, subtree: false,
}); });