← Public packages
@kentcdodds/spotify
Spotify playback, playlist, search, library, and device helpers.
src/exports/playback-controller.ts
85 lines · 3.0 KB · TypeScriptimport {
pausePlayback,
startOrResumePlayback,
} from '../lib/spotify-api.ts'
import type { PlaybackControllerParams } from '../lib/export-types.ts'
import { buildRemoteState } from '../lib/remote-state.ts'
import spotifyAddToQueue from './add-to-queue.ts'
import getSpotifyQueue from './get-queue.ts'
import playPause from './play-pause.ts'
import spotifySetVolume from './set-volume.ts'
import spotifySkip from './skip.ts'
import spotifyTransferPlayback from './transfer-playback.ts'
/**
* Run a remote Spotify playback action and return human-friendly state.
* All params accept an optional `account` ('personal' | 'family', default 'personal').
* @returns Remote state object with playback summary; queue actions include queue data.
* @example
* import playbackController from 'kody:@kentcdodds/spotify/playback-controller'
* const state = await playbackController({ action: 'status', account: 'personal' })
* // => { message: null, isPlaying: true, track: { name: '...' }, devices: [...] }
*/
async function playbackController(params: PlaybackControllerParams = {}) {
const action = params.action ?? 'status'
const account = params.account
switch (action) {
case 'status':
case 'state':
return await buildRemoteState({ account })
case 'queue': {
const [state, queue] = await Promise.all([
buildRemoteState({ account }),
getSpotifyQueue(params),
])
return { ...state, queue }
}
case 'play':
await startOrResumePlayback({
...params,
account,
fallbackDeviceId: params.fallbackDeviceId,
})
return await buildRemoteState({ account, message: 'Playback resumed.' })
case 'pause':
await pausePlayback({ ...params, account })
return await buildRemoteState({ account, message: 'Playback paused.' })
case 'play-pause': {
const result = await playPause(params)
const message =
result.action === 'paused'
? 'Playback paused.'
: result.action === 'resumed'
? 'Playback resumed.'
: 'Playback started on the fallback device.'
return await buildRemoteState({ account, message })
}
case 'next':
await spotifySkip({ ...params, direction: 'next' })
return await buildRemoteState({ account, message: 'Skipped to the next track.' })
case 'previous':
await spotifySkip({ ...params, direction: 'previous' })
return await buildRemoteState({ account, message: 'Returned to the previous track.' })
case 'transfer':
await spotifyTransferPlayback(params)
return await buildRemoteState({
account,
message: 'Playback transferred to the selected device.',
})
case 'set-volume':
await spotifySetVolume(params)
return await buildRemoteState({ account, message: 'Volume updated.' })
case 'add-to-queue': {
await spotifyAddToQueue(params)
const [state, queue] = await Promise.all([
buildRemoteState({ account, message: 'Added the item to the queue.' }),
getSpotifyQueue(params),
])
return { ...state, queue }
}
default:
throw new Error('Unknown Spotify controller action: ' + String(action))
}
}
export default playbackController