subtracks/app/state/trackplayer.ts
austinried 706e57aa77 all state migrated to zustand, jotai removed
splash page now waits on state hydration from db
2021-08-04 13:13:32 +09:00

120 lines
3.3 KiB
TypeScript

import PromiseQueue from '@app/util/PromiseQueue'
import produce from 'immer'
import TrackPlayer, { State, Track } from 'react-native-track-player'
import { GetState, SetState } from 'zustand'
import { Store } from './store'
export type TrackExt = Track & {
id: string
coverArt?: string
}
export type Progress = {
position: number
duration: number
buffered: number
}
export type TrackPlayerSlice = {
name?: string
setName: (name?: string) => void
shuffleOrder?: number[]
setShuffleOrder: (shuffleOrder?: number[]) => void
playerState: State
setPlayerState: (playerState: State) => void
currentTrack?: TrackExt
currentTrackIdx?: number
setCurrentTrackIdx: (idx?: number) => void
queue: TrackExt[]
setQueue: (queue: TrackExt[]) => void
progress: Progress
setProgress: (progress: Progress) => void
reset: () => void
}
export const selectTrackPlayer = {
name: (store: TrackPlayerSlice) => store.name,
setName: (store: TrackPlayerSlice) => store.setName,
shuffleOrder: (store: TrackPlayerSlice) => store.shuffleOrder,
setShuffleOrder: (store: TrackPlayerSlice) => store.setShuffleOrder,
shuffled: (store: TrackPlayerSlice) => !!store.shuffleOrder,
playerState: (store: TrackPlayerSlice) => store.playerState,
setPlayerState: (store: TrackPlayerSlice) => store.setPlayerState,
currentTrack: (store: TrackPlayerSlice) => store.currentTrack,
currentTrackIdx: (store: TrackPlayerSlice) => store.currentTrackIdx,
setCurrentTrackIdx: (store: TrackPlayerSlice) => store.setCurrentTrackIdx,
queue: (store: TrackPlayerSlice) => store.queue,
setQueue: (store: TrackPlayerSlice) => store.setQueue,
progress: (store: TrackPlayerSlice) => store.progress,
setProgress: (store: TrackPlayerSlice) => store.setProgress,
reset: (store: TrackPlayerSlice) => store.reset,
}
export const trackPlayerCommands = new PromiseQueue(1)
export const createTrackPlayerSlice = (set: SetState<Store>, _get: GetState<Store>): TrackPlayerSlice => ({
name: undefined,
setName: name => set({ name }),
shuffleOrder: undefined,
setShuffleOrder: shuffleOrder => set({ shuffleOrder }),
playerState: State.None,
setPlayerState: playerState => set({ playerState }),
currentTrack: undefined,
currentTrackIdx: undefined,
setCurrentTrackIdx: idx => {
set(
produce<TrackPlayerSlice>(state => {
state.currentTrackIdx = idx
state.currentTrack = idx !== undefined ? state.queue[idx] : undefined
}),
)
},
queue: [],
setQueue: queue => set({ queue }),
progress: { position: 0, duration: 0, buffered: 0 },
setProgress: progress => set({ progress }),
reset: () => {
set({
name: undefined,
shuffleOrder: undefined,
playerState: State.None,
currentTrack: undefined,
currentTrackIdx: undefined,
queue: [],
progress: { position: 0, duration: 0, buffered: 0 },
})
},
})
export const getQueue = async (): Promise<TrackExt[]> => {
return ((await TrackPlayer.getQueue()) as TrackExt[]) || []
}
export const getCurrentTrack = async (): Promise<number | undefined> => {
const current = await TrackPlayer.getCurrentTrack()
return typeof current === 'number' ? current : undefined
}
export const getPlayerState = async (): Promise<State> => {
const state = await TrackPlayer.getState()
return state || State.None
}