mirror of
https://github.com/austinried/subtracks.git
synced 2025-12-27 00:59:28 +01:00
impl repeat mode
fix position not being restored on close/open due to some bad progress updates
This commit is contained in:
parent
a0b49ec75f
commit
9dc1ac451c
@ -1,15 +1,23 @@
|
||||
import { useStore } from '@app/state/store'
|
||||
import { selectTrackPlayer } from '@app/state/trackplayer'
|
||||
import React, { useEffect } from 'react'
|
||||
import { useProgress } from 'react-native-track-player'
|
||||
import { State, useProgress } from 'react-native-track-player'
|
||||
|
||||
const ProgressHook = () => {
|
||||
const playerState = useStore(selectTrackPlayer.playerState)
|
||||
const setProgress = useStore(selectTrackPlayer.setProgress)
|
||||
const progress = useProgress(250)
|
||||
|
||||
useEffect(() => {
|
||||
if (playerState !== State.Playing) {
|
||||
return
|
||||
}
|
||||
if (progress.buffered === 0 && progress.duration === 0 && progress.position === 0) {
|
||||
return
|
||||
}
|
||||
|
||||
setProgress(progress)
|
||||
}, [setProgress, progress])
|
||||
}, [setProgress, progress, playerState])
|
||||
|
||||
return <></>
|
||||
}
|
||||
|
||||
@ -1,9 +1,16 @@
|
||||
import { useCoverArtUri } from '@app/hooks/music'
|
||||
import { Song } from '@app/models/music'
|
||||
import { useStore } from '@app/state/store'
|
||||
import { getCurrentTrack, getQueue, selectTrackPlayer, TrackExt, trackPlayerCommands } from '@app/state/trackplayer'
|
||||
import {
|
||||
getCurrentTrack,
|
||||
getQueue,
|
||||
getRepeatMode,
|
||||
selectTrackPlayer,
|
||||
TrackExt,
|
||||
trackPlayerCommands,
|
||||
} from '@app/state/trackplayer'
|
||||
import { useCallback } from 'react'
|
||||
import TrackPlayer from 'react-native-track-player'
|
||||
import TrackPlayer, { RepeatMode } from 'react-native-track-player'
|
||||
|
||||
export const usePlay = () => {
|
||||
return () => trackPlayerCommands.enqueue(() => TrackPlayer.play())
|
||||
@ -14,14 +21,11 @@ export const usePause = () => {
|
||||
}
|
||||
|
||||
export const usePrevious = () => {
|
||||
// const setCurrentTrackIdx = useStore(selectTrackPlayer.setCurrentTrackIdx)
|
||||
|
||||
return () =>
|
||||
trackPlayerCommands.enqueue(async () => {
|
||||
const [current] = await Promise.all([await TrackPlayer.getCurrentTrack(), await getQueue()])
|
||||
if (current > 0) {
|
||||
await TrackPlayer.skipToPrevious()
|
||||
// setCurrentTrackIdx(current - 1)
|
||||
} else {
|
||||
await TrackPlayer.seekTo(0)
|
||||
}
|
||||
@ -30,23 +34,44 @@ export const usePrevious = () => {
|
||||
}
|
||||
|
||||
export const useNext = () => {
|
||||
// const setCurrentTrack = useUpdateAtom(currentTrackAtom)
|
||||
|
||||
return () =>
|
||||
trackPlayerCommands.enqueue(async () => {
|
||||
const [current, queue] = await Promise.all([await TrackPlayer.getCurrentTrack(), await getQueue()])
|
||||
if (current >= queue.length - 1) {
|
||||
await TrackPlayer.skip(0)
|
||||
await TrackPlayer.pause()
|
||||
// setCurrentTrack(queue[0])
|
||||
} else {
|
||||
await TrackPlayer.skipToNext()
|
||||
// setCurrentTrack(queue[current + 1])
|
||||
await TrackPlayer.play()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export const useToggleRepeat = () => {
|
||||
const setRepeatMode = useStore(selectTrackPlayer.setRepeatMode)
|
||||
|
||||
return () =>
|
||||
trackPlayerCommands.enqueue(async () => {
|
||||
const repeatMode = await getRepeatMode()
|
||||
let nextMode = RepeatMode.Off
|
||||
|
||||
switch (repeatMode) {
|
||||
case RepeatMode.Off:
|
||||
nextMode = RepeatMode.Queue
|
||||
break
|
||||
case RepeatMode.Queue:
|
||||
nextMode = RepeatMode.Track
|
||||
break
|
||||
default:
|
||||
nextMode = RepeatMode.Off
|
||||
break
|
||||
}
|
||||
|
||||
await TrackPlayer.setRepeatMode(nextMode)
|
||||
setRepeatMode(nextMode)
|
||||
})
|
||||
}
|
||||
|
||||
export const useReset = (enqueue = true) => {
|
||||
const resetStore = useStore(selectTrackPlayer.reset)
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import React, { useCallback, useEffect } from 'react'
|
||||
import { BackHandler, StatusBar, StyleSheet, Text, View } from 'react-native'
|
||||
import { State } from 'react-native-track-player'
|
||||
import { RepeatMode, State } from 'react-native-track-player'
|
||||
import IconFA from 'react-native-vector-icons/FontAwesome'
|
||||
import IconFA5 from 'react-native-vector-icons/FontAwesome5'
|
||||
import Icon from 'react-native-vector-icons/Ionicons'
|
||||
@ -17,7 +17,7 @@ import { NativeStackScreenProps } from 'react-native-screens/native-stack'
|
||||
import { useFocusEffect } from '@react-navigation/native'
|
||||
import { useStore } from '@app/state/store'
|
||||
import { selectTrackPlayer } from '@app/state/trackplayer'
|
||||
import { useNext, usePause, usePlay, usePrevious, useToggleShuffle } from '@app/hooks/trackplayer'
|
||||
import { useNext, usePause, usePlay, usePrevious, useToggleRepeat, useToggleShuffle } from '@app/hooks/trackplayer'
|
||||
|
||||
const NowPlayingHeader = React.memo<{
|
||||
backHandler: () => void
|
||||
@ -201,6 +201,8 @@ const PlayerControls = () => {
|
||||
const previous = usePrevious()
|
||||
const shuffled = useStore(selectTrackPlayer.shuffled)
|
||||
const toggleShuffle = useToggleShuffle()
|
||||
const repeatMode = useStore(selectTrackPlayer.repeatMode)
|
||||
const toggleRepeat = useToggleRepeat()
|
||||
|
||||
let playPauseIcon: string
|
||||
let playPauseAction: undefined | (() => void)
|
||||
@ -225,8 +227,9 @@ const PlayerControls = () => {
|
||||
<View style={controlsStyles.container}>
|
||||
<View style={controlsStyles.top}>
|
||||
<View style={controlsStyles.center}>
|
||||
<PressableOpacity onPress={undefined} disabled={disabled}>
|
||||
<Icon name="repeat" size={26} color="white" />
|
||||
<PressableOpacity onPress={() => toggleRepeat()} disabled={disabled}>
|
||||
<Icon name="repeat" size={26} color={repeatMode === RepeatMode.Off ? 'white' : colors.accent} />
|
||||
<Text style={[controlsStyles.repeatExt, repeatMode === RepeatMode.Track ? { opacity: 1 } : {}]}>1</Text>
|
||||
</PressableOpacity>
|
||||
</View>
|
||||
|
||||
@ -285,6 +288,14 @@ const controlsStyles = StyleSheet.create({
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
},
|
||||
repeatExt: {
|
||||
color: colors.accent,
|
||||
fontFamily: font.bold,
|
||||
fontSize: 14,
|
||||
position: 'absolute',
|
||||
top: 26,
|
||||
opacity: 0,
|
||||
},
|
||||
})
|
||||
|
||||
type RootStackParamList = {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import PromiseQueue from '@app/util/PromiseQueue'
|
||||
import produce from 'immer'
|
||||
import TrackPlayer, { State, Track } from 'react-native-track-player'
|
||||
import TrackPlayer, { RepeatMode, State, Track } from 'react-native-track-player'
|
||||
import { GetState, SetState } from 'zustand'
|
||||
import { Store } from './store'
|
||||
|
||||
@ -22,6 +22,9 @@ export type TrackPlayerSlice = {
|
||||
shuffleOrder?: number[]
|
||||
setShuffleOrder: (shuffleOrder?: number[]) => void
|
||||
|
||||
repeatMode: RepeatMode
|
||||
setRepeatMode: (repeatMode: RepeatMode) => void
|
||||
|
||||
playerState: State
|
||||
setPlayerState: (playerState: State) => void
|
||||
|
||||
@ -48,6 +51,9 @@ export const selectTrackPlayer = {
|
||||
setShuffleOrder: (store: TrackPlayerSlice) => store.setShuffleOrder,
|
||||
shuffled: (store: TrackPlayerSlice) => !!store.shuffleOrder,
|
||||
|
||||
repeatMode: (store: TrackPlayerSlice) => store.repeatMode,
|
||||
setRepeatMode: (store: TrackPlayerSlice) => store.setRepeatMode,
|
||||
|
||||
playerState: (store: TrackPlayerSlice) => store.playerState,
|
||||
setPlayerState: (store: TrackPlayerSlice) => store.setPlayerState,
|
||||
|
||||
@ -75,6 +81,9 @@ export const createTrackPlayerSlice = (set: SetState<Store>, get: GetState<Store
|
||||
shuffleOrder: undefined,
|
||||
setShuffleOrder: shuffleOrder => set({ shuffleOrder }),
|
||||
|
||||
repeatMode: RepeatMode.Off,
|
||||
setRepeatMode: repeatMode => set({ repeatMode }),
|
||||
|
||||
playerState: State.None,
|
||||
setPlayerState: playerState => set({ playerState }),
|
||||
|
||||
@ -114,6 +123,7 @@ export const createTrackPlayerSlice = (set: SetState<Store>, get: GetState<Store
|
||||
set({
|
||||
name: undefined,
|
||||
shuffleOrder: undefined,
|
||||
repeatMode: RepeatMode.Off,
|
||||
playerState: State.None,
|
||||
currentTrack: undefined,
|
||||
currentTrackIdx: undefined,
|
||||
@ -133,6 +143,9 @@ export const getCurrentTrack = async (): Promise<number | undefined> => {
|
||||
}
|
||||
|
||||
export const getPlayerState = async (): Promise<State> => {
|
||||
const state = await TrackPlayer.getState()
|
||||
return state || State.None
|
||||
return (await TrackPlayer.getState()) || State.None
|
||||
}
|
||||
|
||||
export const getRepeatMode = async (): Promise<RepeatMode> => {
|
||||
return (await TrackPlayer.getRepeatMode()) || RepeatMode.Off
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user