mirror of
https://github.com/austinried/subtracks.git
synced 2025-12-27 09:09:29 +01:00
fixed progress hook with my own state wrap/update
This commit is contained in:
parent
b5473ee568
commit
49b5ce3f6c
@ -2,8 +2,15 @@ import { useAtomValue } from 'jotai/utils'
|
||||
import React from 'react'
|
||||
import { StatusBar, StyleSheet, Text, useWindowDimensions, View } from 'react-native'
|
||||
import FastImage from 'react-native-fast-image'
|
||||
import TrackPlayer, { State, useProgress } from 'react-native-track-player'
|
||||
import { queueNameAtom, currentTrackAtom, playerStateAtom, useNext, usePrevious } from '../state/trackplayer'
|
||||
import TrackPlayer, { State } from 'react-native-track-player'
|
||||
import {
|
||||
queueNameAtom,
|
||||
currentTrackAtom,
|
||||
playerStateAtom,
|
||||
useNext,
|
||||
usePrevious,
|
||||
useProgress,
|
||||
} from '../state/trackplayer'
|
||||
import colors from '../styles/colors'
|
||||
import text, { Font } from '../styles/text'
|
||||
import { formatDuration } from '../util'
|
||||
@ -100,7 +107,7 @@ const infoStyles = StyleSheet.create({
|
||||
})
|
||||
|
||||
const SeekBar = () => {
|
||||
const { position, duration } = useProgress(250)
|
||||
const { position, duration } = useProgress()
|
||||
|
||||
let progress = 0
|
||||
if (duration > 0) {
|
||||
|
||||
@ -2,12 +2,16 @@ import { useAppState } from '@react-native-community/hooks'
|
||||
import { useAtomValue, useUpdateAtom } from 'jotai/utils'
|
||||
import React, { useEffect } from 'react'
|
||||
import { View } from 'react-native'
|
||||
import TrackPlayer, { Event, State, useTrackPlayerEvents } from 'react-native-track-player'
|
||||
import { Event, State, useProgress, useTrackPlayerEvents } from 'react-native-track-player'
|
||||
import {
|
||||
currentTrackAtom,
|
||||
playerStateAtom,
|
||||
progressAtom,
|
||||
progressSubsAtom,
|
||||
queueWriteAtom,
|
||||
useRefreshCurrentTrack,
|
||||
useRefreshPlayerState,
|
||||
useRefreshProgress,
|
||||
useRefreshQueue,
|
||||
} from '../state/trackplayer'
|
||||
|
||||
@ -67,13 +71,14 @@ const CurrentTrackState = () => {
|
||||
|
||||
const PlayerState = () => {
|
||||
const setPlayerState = useUpdateAtom(playerStateAtom)
|
||||
const refreshPlayerState = useRefreshPlayerState()
|
||||
|
||||
const update = async (payload?: Payload) => {
|
||||
if (payload?.type === Event.RemoteStop) {
|
||||
setPlayerState(State.None)
|
||||
return
|
||||
}
|
||||
setPlayerState(payload?.state || (await TrackPlayer.getState()))
|
||||
await refreshPlayerState()
|
||||
}
|
||||
|
||||
return <TrackPlayerEventResponder events={[Event.PlaybackState, Event.RemoteStop]} update={update} />
|
||||
@ -94,6 +99,41 @@ const QueueState = () => {
|
||||
return <TrackPlayerEventResponder events={[Event.RemoteStop]} update={update} />
|
||||
}
|
||||
|
||||
const ProgressHook = () => {
|
||||
const setProgress = useUpdateAtom(progressAtom)
|
||||
const progress = useProgress(250)
|
||||
|
||||
useEffect(() => {
|
||||
setProgress(progress)
|
||||
}, [setProgress, progress])
|
||||
|
||||
return <></>
|
||||
}
|
||||
|
||||
const ProgressState = () => {
|
||||
const setProgress = useUpdateAtom(progressAtom)
|
||||
const refreshProgress = useRefreshProgress()
|
||||
const progressSubs = useAtomValue(progressSubsAtom)
|
||||
|
||||
const update = async (payload?: Payload) => {
|
||||
if (payload) {
|
||||
setProgress({ position: 0, duration: 0, buffered: 0 })
|
||||
return
|
||||
}
|
||||
await refreshProgress()
|
||||
}
|
||||
|
||||
if (progressSubs > 0) {
|
||||
return (
|
||||
<>
|
||||
<ProgressHook />
|
||||
<TrackPlayerEventResponder events={[Event.RemoteStop]} update={update} />
|
||||
</>
|
||||
)
|
||||
}
|
||||
return <TrackPlayerEventResponder events={[Event.RemoteStop]} update={update} />
|
||||
}
|
||||
|
||||
const Debug = () => {
|
||||
const value = useAtomValue(currentTrackAtom)
|
||||
|
||||
@ -109,6 +149,7 @@ const TrackPlayerState = () => (
|
||||
<CurrentTrackState />
|
||||
<PlayerState />
|
||||
<QueueState />
|
||||
<ProgressState />
|
||||
<Debug />
|
||||
</View>
|
||||
)
|
||||
|
||||
@ -1,7 +1,8 @@
|
||||
import { atom } from 'jotai'
|
||||
import TrackPlayer, { State, Track } from 'react-native-track-player'
|
||||
import equal from 'fast-deep-equal'
|
||||
import { useUpdateAtom } from 'jotai/utils'
|
||||
import { atom } from 'jotai'
|
||||
import { useAtomValue, useUpdateAtom } from 'jotai/utils'
|
||||
import { useEffect } from 'react'
|
||||
import TrackPlayer, { State, Track } from 'react-native-track-player'
|
||||
import { Song } from '../models/music'
|
||||
import { PromiseQueue } from '../util'
|
||||
|
||||
@ -12,6 +13,12 @@ type TrackExt = Track & {
|
||||
|
||||
type OptionalTrackExt = TrackExt | undefined
|
||||
|
||||
type Progress = {
|
||||
position: number
|
||||
duration: number
|
||||
buffered: number
|
||||
}
|
||||
|
||||
const playerState = atom<State>(State.None)
|
||||
export const playerStateAtom = atom<State, State>(
|
||||
get => get(playerState),
|
||||
@ -33,7 +40,7 @@ export const currentTrackAtom = atom<OptionalTrackExt, OptionalTrackExt>(
|
||||
)
|
||||
|
||||
const _queue = atom<TrackExt[]>([])
|
||||
export const queueAtom = atom<TrackExt[]>(get => get(_queue))
|
||||
export const queueReadAtom = atom<TrackExt[]>(get => get(_queue))
|
||||
export const queueWriteAtom = atom<TrackExt[], TrackExt[]>(
|
||||
get => get(_queue),
|
||||
(get, set, update) => {
|
||||
@ -51,6 +58,25 @@ export const queueNameAtom = atom<string | undefined>(get => {
|
||||
return undefined
|
||||
})
|
||||
|
||||
const _progress = atom<Progress>({ position: 0, duration: 0, buffered: 0 })
|
||||
export const progressAtom = atom<Progress, Progress>(
|
||||
get => get(_progress),
|
||||
(get, set, update) => {
|
||||
if (!equal(get(_progress), update)) {
|
||||
set(_progress, update)
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
const progressSubs = atom(0)
|
||||
export const progressSubsAtom = atom(get => get(progressSubs))
|
||||
const addProgressSub = atom(null, (get, set) => {
|
||||
set(progressSubs, get(progressSubs) + 1)
|
||||
})
|
||||
const removeProgressSub = atom(null, (get, set) => {
|
||||
set(progressSubs, get(progressSubs) - 1)
|
||||
})
|
||||
|
||||
const trackPlayerCommands = new PromiseQueue(1)
|
||||
|
||||
const getQueue = async (): Promise<TrackExt[]> => {
|
||||
@ -61,6 +87,23 @@ const getTrack = async (index: number): Promise<TrackExt> => {
|
||||
return ((await TrackPlayer.getTrack(index)) as TrackExt) || undefined
|
||||
}
|
||||
|
||||
const getPlayerState = async (): Promise<State> => {
|
||||
return (await TrackPlayer.getState()) || State.None
|
||||
}
|
||||
|
||||
const getProgress = async (): Promise<Progress> => {
|
||||
const [position, duration, buffered] = await Promise.all([
|
||||
TrackPlayer.getPosition(),
|
||||
TrackPlayer.getDuration(),
|
||||
TrackPlayer.getBufferedPosition(),
|
||||
])
|
||||
return {
|
||||
position: position || 0,
|
||||
duration: duration || 0,
|
||||
buffered: buffered || 0,
|
||||
}
|
||||
}
|
||||
|
||||
export const useRefreshQueue = () => {
|
||||
const setQueue = useUpdateAtom(queueWriteAtom)
|
||||
|
||||
@ -84,6 +127,24 @@ export const useRefreshCurrentTrack = () => {
|
||||
})
|
||||
}
|
||||
|
||||
export const useRefreshPlayerState = () => {
|
||||
const setPlayerState = useUpdateAtom(playerStateAtom)
|
||||
|
||||
return () =>
|
||||
trackPlayerCommands.enqueue(async () => {
|
||||
setPlayerState(await getPlayerState())
|
||||
})
|
||||
}
|
||||
|
||||
export const useRefreshProgress = () => {
|
||||
const setProgress = useUpdateAtom(progressAtom)
|
||||
|
||||
return () =>
|
||||
trackPlayerCommands.enqueue(async () => {
|
||||
setProgress(await getProgress())
|
||||
})
|
||||
}
|
||||
|
||||
export const usePrevious = () => {
|
||||
const setCurrentTrack = useUpdateAtom(currentTrackAtom)
|
||||
|
||||
@ -179,6 +240,19 @@ export const useSetQueue = () => {
|
||||
})
|
||||
}
|
||||
|
||||
export const useProgress = () => {
|
||||
const progress = useAtomValue(progressAtom)
|
||||
const addSub = useUpdateAtom(addProgressSub)
|
||||
const removeSub = useUpdateAtom(removeProgressSub)
|
||||
|
||||
useEffect(() => {
|
||||
addSub()
|
||||
return removeSub
|
||||
}, [addSub, removeSub])
|
||||
|
||||
return progress
|
||||
}
|
||||
|
||||
function mapSongToTrack(song: Song, queueName: string): TrackExt {
|
||||
return {
|
||||
id: song.id,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user