mirror of
https://github.com/austinried/subtracks.git
synced 2025-12-27 00:59:28 +01:00
added settings for min/max buffer
This commit is contained in:
parent
694d730ebd
commit
c83fb43140
38
app/components/TextInput.tsx
Normal file
38
app/components/TextInput.tsx
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
import colors from '@app/styles/colors'
|
||||||
|
import font from '@app/styles/font'
|
||||||
|
import React from 'react'
|
||||||
|
import { TextInput as ReactTextInput, StyleSheet, StyleProp, TextStyle, KeyboardTypeOptions } from 'react-native'
|
||||||
|
|
||||||
|
const TextInput = React.memo<{
|
||||||
|
style?: StyleProp<TextStyle>
|
||||||
|
value?: string
|
||||||
|
placeholder?: string
|
||||||
|
onChangeText?: (text: string) => void
|
||||||
|
onSubmitEditing?: () => void
|
||||||
|
keyboardType?: KeyboardTypeOptions
|
||||||
|
}>(({ style, value, placeholder, onChangeText, onSubmitEditing, keyboardType }) => {
|
||||||
|
return (
|
||||||
|
<ReactTextInput
|
||||||
|
style={[style, styles.textInput]}
|
||||||
|
placeholder={placeholder}
|
||||||
|
placeholderTextColor="grey"
|
||||||
|
selectionColor={colors.text.secondary}
|
||||||
|
value={value}
|
||||||
|
onChangeText={onChangeText}
|
||||||
|
onSubmitEditing={onSubmitEditing}
|
||||||
|
keyboardType={keyboardType}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
textInput: {
|
||||||
|
width: '100%',
|
||||||
|
backgroundColor: '#515151',
|
||||||
|
fontFamily: font.regular,
|
||||||
|
fontSize: 18,
|
||||||
|
color: colors.text.primary,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
export default TextInput
|
||||||
@ -16,4 +16,6 @@ export interface AppSettings {
|
|||||||
estimateContentLength: boolean
|
estimateContentLength: boolean
|
||||||
maxBitrateWifi: number
|
maxBitrateWifi: number
|
||||||
maxBitrateMobile: number
|
maxBitrateMobile: number
|
||||||
|
minBuffer: number
|
||||||
|
maxBuffer: number
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,6 +3,7 @@ import GradientScrollView from '@app/components/GradientScrollView'
|
|||||||
import Header from '@app/components/Header'
|
import Header from '@app/components/Header'
|
||||||
import ListItem from '@app/components/ListItem'
|
import ListItem from '@app/components/ListItem'
|
||||||
import NothingHere from '@app/components/NothingHere'
|
import NothingHere from '@app/components/NothingHere'
|
||||||
|
import TextInput from '@app/components/TextInput'
|
||||||
import { useActiveServerRefresh } from '@app/hooks/server'
|
import { useActiveServerRefresh } from '@app/hooks/server'
|
||||||
import { ListableItem, SearchResults, Song } from '@app/models/music'
|
import { ListableItem, SearchResults, Song } from '@app/models/music'
|
||||||
import { selectMusic } from '@app/state/music'
|
import { selectMusic } from '@app/state/music'
|
||||||
@ -13,7 +14,7 @@ import font from '@app/styles/font'
|
|||||||
import { useNavigation } from '@react-navigation/native'
|
import { useNavigation } from '@react-navigation/native'
|
||||||
import debounce from 'lodash.debounce'
|
import debounce from 'lodash.debounce'
|
||||||
import React, { useCallback, useMemo, useState } from 'react'
|
import React, { useCallback, useMemo, useState } from 'react'
|
||||||
import { ActivityIndicator, StatusBar, StyleSheet, TextInput, View } from 'react-native'
|
import { ActivityIndicator, StatusBar, StyleSheet, View } from 'react-native'
|
||||||
|
|
||||||
const SongItem = React.memo<{ item: Song }>(({ item }) => {
|
const SongItem = React.memo<{ item: Song }>(({ item }) => {
|
||||||
const setQueue = useStore(selectTrackPlayer.setQueue)
|
const setQueue = useStore(selectTrackPlayer.setQueue)
|
||||||
@ -113,14 +114,7 @@ const Search = () => {
|
|||||||
<GradientScrollView style={styles.scroll} contentContainerStyle={styles.scrollContentContainer}>
|
<GradientScrollView style={styles.scroll} contentContainerStyle={styles.scrollContentContainer}>
|
||||||
<View style={styles.content}>
|
<View style={styles.content}>
|
||||||
<View style={styles.inputBar}>
|
<View style={styles.inputBar}>
|
||||||
<TextInput
|
<TextInput style={styles.textInput} placeholder="Search" value={text} onChangeText={onChangeText} />
|
||||||
style={styles.textInput}
|
|
||||||
placeholder="Search"
|
|
||||||
placeholderTextColor="grey"
|
|
||||||
selectionColor={colors.text.secondary}
|
|
||||||
value={text}
|
|
||||||
onChangeText={onChangeText}
|
|
||||||
/>
|
|
||||||
<ActivityIndicator
|
<ActivityIndicator
|
||||||
animating={refreshing}
|
animating={refreshing}
|
||||||
size="small"
|
size="small"
|
||||||
@ -154,16 +148,6 @@ const styles = StyleSheet.create({
|
|||||||
right: 16,
|
right: 16,
|
||||||
bottom: 15,
|
bottom: 15,
|
||||||
},
|
},
|
||||||
textInput: {
|
|
||||||
width: '100%',
|
|
||||||
backgroundColor: '#515151',
|
|
||||||
fontFamily: font.regular,
|
|
||||||
fontSize: 18,
|
|
||||||
color: colors.text.primary,
|
|
||||||
marginTop: 20,
|
|
||||||
paddingHorizontal: 12,
|
|
||||||
paddingRight: 46,
|
|
||||||
},
|
|
||||||
noResults: {
|
noResults: {
|
||||||
width: '100%',
|
width: '100%',
|
||||||
},
|
},
|
||||||
@ -176,6 +160,11 @@ const styles = StyleSheet.create({
|
|||||||
marginTop: 5,
|
marginTop: 5,
|
||||||
marginBottom: 10,
|
marginBottom: 10,
|
||||||
},
|
},
|
||||||
|
textInput: {
|
||||||
|
marginTop: 20,
|
||||||
|
paddingHorizontal: 12,
|
||||||
|
paddingRight: 46,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
export default Search
|
export default Search
|
||||||
|
|||||||
@ -4,6 +4,7 @@ import Header from '@app/components/Header'
|
|||||||
import PressableOpacity from '@app/components/PressableOpacity'
|
import PressableOpacity from '@app/components/PressableOpacity'
|
||||||
import SettingsItem from '@app/components/SettingsItem'
|
import SettingsItem from '@app/components/SettingsItem'
|
||||||
import SettingsSwitch from '@app/components/SettingsSwitch'
|
import SettingsSwitch from '@app/components/SettingsSwitch'
|
||||||
|
import TextInput from '@app/components/TextInput'
|
||||||
import { useSwitchActiveServer } from '@app/hooks/server'
|
import { useSwitchActiveServer } from '@app/hooks/server'
|
||||||
import { Server } from '@app/models/settings'
|
import { Server } from '@app/models/settings'
|
||||||
import { selectCache } from '@app/state/cache'
|
import { selectCache } from '@app/state/cache'
|
||||||
@ -13,7 +14,7 @@ import colors from '@app/styles/colors'
|
|||||||
import font from '@app/styles/font'
|
import font from '@app/styles/font'
|
||||||
import { useNavigation } from '@react-navigation/core'
|
import { useNavigation } from '@react-navigation/core'
|
||||||
import React, { useCallback, useState } from 'react'
|
import React, { useCallback, useState } from 'react'
|
||||||
import { Modal, Pressable, StatusBar, StyleSheet, Text, View } from 'react-native'
|
import { KeyboardTypeOptions, Modal, Pressable, StatusBar, StyleSheet, Text, View } from 'react-native'
|
||||||
import { ScrollView } from 'react-native-gesture-handler'
|
import { ScrollView } from 'react-native-gesture-handler'
|
||||||
import Icon from 'react-native-vector-icons/MaterialCommunityIcons'
|
import Icon from 'react-native-vector-icons/MaterialCommunityIcons'
|
||||||
|
|
||||||
@ -105,7 +106,7 @@ const BitrateModal = React.memo<{
|
|||||||
<>
|
<>
|
||||||
<SettingsItem title={title} subtitle={bitrateString(bitrate)} onPress={toggleModal} />
|
<SettingsItem title={title} subtitle={bitrateString(bitrate)} onPress={toggleModal} />
|
||||||
<Modal animationType="fade" transparent={true} visible={visible} onRequestClose={toggleModal}>
|
<Modal animationType="fade" transparent={true} visible={visible} onRequestClose={toggleModal}>
|
||||||
<Pressable style={{ flex: 1 }} onPress={toggleModal}>
|
<Pressable style={styles.modalBackdrop} onPress={toggleModal}>
|
||||||
<View style={styles.centeredView}>
|
<View style={styles.centeredView}>
|
||||||
<Pressable style={styles.modalView}>
|
<Pressable style={styles.modalView}>
|
||||||
<Header style={styles.modalHeader}>{title}</Header>
|
<Header style={styles.modalHeader}>{title}</Header>
|
||||||
@ -130,6 +131,66 @@ const BitrateModal = React.memo<{
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const SettingsTextModal = React.memo<{
|
||||||
|
title: string
|
||||||
|
value: string
|
||||||
|
setValue: (text: string) => void
|
||||||
|
getUnit?: (text: string) => string
|
||||||
|
keyboardType?: KeyboardTypeOptions
|
||||||
|
}>(({ title, value, setValue, getUnit, keyboardType }) => {
|
||||||
|
const [visible, setVisible] = useState(false)
|
||||||
|
const [inputText, setInputText] = useState(value)
|
||||||
|
|
||||||
|
const toggleModal = useCallback(() => setVisible(!visible), [visible])
|
||||||
|
|
||||||
|
const submit = useCallback(() => {
|
||||||
|
setValue(inputText)
|
||||||
|
toggleModal()
|
||||||
|
}, [inputText, setValue, toggleModal])
|
||||||
|
|
||||||
|
const getSubtitle = useCallback(() => {
|
||||||
|
if (!getUnit) {
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
return value + ' ' + getUnit(value)
|
||||||
|
}, [getUnit, value])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<SettingsItem title={title} subtitle={getSubtitle()} onPress={toggleModal} />
|
||||||
|
<Modal animationType="fade" transparent={true} visible={visible} onRequestClose={toggleModal}>
|
||||||
|
<Pressable style={styles.modalBackdrop} onPress={toggleModal}>
|
||||||
|
<View style={styles.centeredView}>
|
||||||
|
<Pressable style={styles.modalView}>
|
||||||
|
<Header style={styles.modalHeader}>{title}</Header>
|
||||||
|
<View style={styles.modalTextInputLine}>
|
||||||
|
<TextInput
|
||||||
|
style={styles.modalTextInput}
|
||||||
|
value={inputText}
|
||||||
|
onChangeText={setInputText}
|
||||||
|
onSubmitEditing={submit}
|
||||||
|
keyboardType={keyboardType}
|
||||||
|
/>
|
||||||
|
<PressableOpacity style={styles.modalTextSubmit} onPress={submit} hitSlop={10}>
|
||||||
|
<Icon name="content-save-edit" color="white" size={32} />
|
||||||
|
</PressableOpacity>
|
||||||
|
</View>
|
||||||
|
</Pressable>
|
||||||
|
</View>
|
||||||
|
</Pressable>
|
||||||
|
</Modal>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
function secondsUnit(seconds: string): string {
|
||||||
|
const numberValue = parseFloat(seconds)
|
||||||
|
if (Math.abs(numberValue) !== 1) {
|
||||||
|
return 'seconds'
|
||||||
|
}
|
||||||
|
return 'second'
|
||||||
|
}
|
||||||
|
|
||||||
const SettingsContent = React.memo(() => {
|
const SettingsContent = React.memo(() => {
|
||||||
const servers = useStore(selectSettings.servers)
|
const servers = useStore(selectSettings.servers)
|
||||||
const scrobble = useStore(selectSettings.scrobble)
|
const scrobble = useStore(selectSettings.scrobble)
|
||||||
@ -143,6 +204,11 @@ const SettingsContent = React.memo(() => {
|
|||||||
const maxBitrateMobile = useStore(selectSettings.maxBitrateMobile)
|
const maxBitrateMobile = useStore(selectSettings.maxBitrateMobile)
|
||||||
const setMaxBitrateMobile = useStore(selectSettings.setMaxBitrateMobile)
|
const setMaxBitrateMobile = useStore(selectSettings.setMaxBitrateMobile)
|
||||||
|
|
||||||
|
const minBuffer = useStore(selectSettings.minBuffer)
|
||||||
|
const setMinBuffer = useStore(selectSettings.setMinBuffer)
|
||||||
|
const maxBuffer = useStore(selectSettings.maxBuffer)
|
||||||
|
const setMaxBuffer = useStore(selectSettings.setMaxBuffer)
|
||||||
|
|
||||||
const clearImageCache = useStore(selectCache.clearImageCache)
|
const clearImageCache = useStore(selectCache.clearImageCache)
|
||||||
const [clearing, setClearing] = useState(false)
|
const [clearing, setClearing] = useState(false)
|
||||||
|
|
||||||
@ -163,6 +229,9 @@ const SettingsContent = React.memo(() => {
|
|||||||
waitForClear()
|
waitForClear()
|
||||||
}, [clearImageCache])
|
}, [clearImageCache])
|
||||||
|
|
||||||
|
const setMinBufferText = useCallback((text: string) => setMinBuffer(parseFloat(text)), [setMinBuffer])
|
||||||
|
const setMaxBufferText = useCallback((text: string) => setMaxBuffer(parseFloat(text)), [setMaxBuffer])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={styles.content}>
|
<View style={styles.content}>
|
||||||
<Header>Servers</Header>
|
<Header>Servers</Header>
|
||||||
@ -184,6 +253,20 @@ const SettingsContent = React.memo(() => {
|
|||||||
value={estimateContentLength}
|
value={estimateContentLength}
|
||||||
setValue={setEstimateContentLength}
|
setValue={setEstimateContentLength}
|
||||||
/>
|
/>
|
||||||
|
<SettingsTextModal
|
||||||
|
title="Minimum buffer time"
|
||||||
|
value={minBuffer.toString()}
|
||||||
|
setValue={setMinBufferText}
|
||||||
|
getUnit={secondsUnit}
|
||||||
|
keyboardType="numeric"
|
||||||
|
/>
|
||||||
|
<SettingsTextModal
|
||||||
|
title="Maximum buffer time"
|
||||||
|
value={maxBuffer.toString()}
|
||||||
|
setValue={setMaxBufferText}
|
||||||
|
getUnit={secondsUnit}
|
||||||
|
keyboardType="numeric"
|
||||||
|
/>
|
||||||
<Header style={styles.header}>Music</Header>
|
<Header style={styles.header}>Music</Header>
|
||||||
<SettingsSwitch
|
<SettingsSwitch
|
||||||
title="Scrobble plays"
|
title="Scrobble plays"
|
||||||
@ -234,6 +317,9 @@ const styles = StyleSheet.create({
|
|||||||
button: {
|
button: {
|
||||||
marginTop: 16,
|
marginTop: 16,
|
||||||
},
|
},
|
||||||
|
modalBackdrop: {
|
||||||
|
flex: 1,
|
||||||
|
},
|
||||||
centeredView: {
|
centeredView: {
|
||||||
flex: 1,
|
flex: 1,
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
@ -269,6 +355,18 @@ const styles = StyleSheet.create({
|
|||||||
modalScroll: {
|
modalScroll: {
|
||||||
maxHeight: 475,
|
maxHeight: 475,
|
||||||
},
|
},
|
||||||
|
modalTextInputLine: {
|
||||||
|
flexDirection: 'row',
|
||||||
|
margin: 20,
|
||||||
|
},
|
||||||
|
modalTextInput: {
|
||||||
|
flex: 1,
|
||||||
|
paddingLeft: 12,
|
||||||
|
},
|
||||||
|
modalTextSubmit: {
|
||||||
|
marginLeft: 15,
|
||||||
|
// backgroundColor: 'green',
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
export default Settings
|
export default Settings
|
||||||
|
|||||||
@ -18,6 +18,8 @@ export type SettingsSlice = {
|
|||||||
setEstimateContentLength: (estimateContentLength: boolean) => void
|
setEstimateContentLength: (estimateContentLength: boolean) => void
|
||||||
setMaxBitrateWifi: (maxBitrateWifi: number) => void
|
setMaxBitrateWifi: (maxBitrateWifi: number) => void
|
||||||
setMaxBitrateMobile: (maxBitrateMobile: number) => void
|
setMaxBitrateMobile: (maxBitrateMobile: number) => void
|
||||||
|
setMinBuffer: (minBuffer: number) => void
|
||||||
|
setMaxBuffer: (maxBuffer: number) => void
|
||||||
|
|
||||||
pingServer: (server?: Server) => Promise<boolean>
|
pingServer: (server?: Server) => Promise<boolean>
|
||||||
}
|
}
|
||||||
@ -46,6 +48,11 @@ export const selectSettings = {
|
|||||||
maxBitrateMobile: (state: SettingsSlice) => state.settings.maxBitrateMobile,
|
maxBitrateMobile: (state: SettingsSlice) => state.settings.maxBitrateMobile,
|
||||||
setMaxBitrateMobile: (state: SettingsSlice) => state.setMaxBitrateMobile,
|
setMaxBitrateMobile: (state: SettingsSlice) => state.setMaxBitrateMobile,
|
||||||
|
|
||||||
|
minBuffer: (state: SettingsSlice) => state.settings.minBuffer,
|
||||||
|
setMinBuffer: (state: SettingsSlice) => state.setMinBuffer,
|
||||||
|
maxBuffer: (state: SettingsSlice) => state.settings.maxBuffer,
|
||||||
|
setMaxBuffer: (state: SettingsSlice) => state.setMaxBuffer,
|
||||||
|
|
||||||
pingServer: (state: SettingsSlice) => state.pingServer,
|
pingServer: (state: SettingsSlice) => state.pingServer,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,6 +66,8 @@ export const createSettingsSlice = (set: SetState<Store>, get: GetState<Store>):
|
|||||||
estimateContentLength: true,
|
estimateContentLength: true,
|
||||||
maxBitrateWifi: 0,
|
maxBitrateWifi: 0,
|
||||||
maxBitrateMobile: 192,
|
maxBitrateMobile: 192,
|
||||||
|
minBuffer: 3,
|
||||||
|
maxBuffer: 60,
|
||||||
},
|
},
|
||||||
|
|
||||||
setActiveServer: async (id, force) => {
|
setActiveServer: async (id, force) => {
|
||||||
@ -122,6 +131,7 @@ export const createSettingsSlice = (set: SetState<Store>, get: GetState<Store>):
|
|||||||
)
|
)
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
|
||||||
if (get().settings.activeServer === server.id) {
|
if (get().settings.activeServer === server.id) {
|
||||||
get().setActiveServer(server.id)
|
get().setActiveServer(server.id)
|
||||||
}
|
}
|
||||||
@ -141,6 +151,7 @@ export const createSettingsSlice = (set: SetState<Store>, get: GetState<Store>):
|
|||||||
state.settings.estimateContentLength = estimateContentLength
|
state.settings.estimateContentLength = estimateContentLength
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
|
||||||
get().rebuildQueue()
|
get().rebuildQueue()
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -150,6 +161,7 @@ export const createSettingsSlice = (set: SetState<Store>, get: GetState<Store>):
|
|||||||
state.settings.maxBitrateWifi = maxBitrateWifi
|
state.settings.maxBitrateWifi = maxBitrateWifi
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
|
||||||
if (get().netState === 'wifi') {
|
if (get().netState === 'wifi') {
|
||||||
get().rebuildQueue()
|
get().rebuildQueue()
|
||||||
}
|
}
|
||||||
@ -161,11 +173,40 @@ export const createSettingsSlice = (set: SetState<Store>, get: GetState<Store>):
|
|||||||
state.settings.maxBitrateMobile = maxBitrateMobile
|
state.settings.maxBitrateMobile = maxBitrateMobile
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
|
||||||
if (get().netState === 'mobile') {
|
if (get().netState === 'mobile') {
|
||||||
get().rebuildQueue()
|
get().rebuildQueue()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setMinBuffer: minBuffer => {
|
||||||
|
if (minBuffer === get().settings.minBuffer) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
set(
|
||||||
|
produce<SettingsSlice>(state => {
|
||||||
|
state.settings.minBuffer = Math.max(1, Math.min(minBuffer, state.settings.maxBuffer / 2))
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
|
||||||
|
get().rebuildQueue()
|
||||||
|
},
|
||||||
|
|
||||||
|
setMaxBuffer: maxBuffer => {
|
||||||
|
if (maxBuffer === get().settings.maxBuffer) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
set(
|
||||||
|
produce<SettingsSlice>(state => {
|
||||||
|
state.settings.maxBuffer = Math.min(5 * 60, Math.max(maxBuffer, state.settings.minBuffer * 2))
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
|
||||||
|
get().rebuildQueue()
|
||||||
|
},
|
||||||
|
|
||||||
pingServer: async server => {
|
pingServer: async server => {
|
||||||
let client: SubsonicApiClient
|
let client: SubsonicApiClient
|
||||||
if (server) {
|
if (server) {
|
||||||
|
|||||||
@ -2,7 +2,7 @@ import { NoClientError } from '@app/models/error'
|
|||||||
import { Song } from '@app/models/music'
|
import { Song } from '@app/models/music'
|
||||||
import PromiseQueue from '@app/util/PromiseQueue'
|
import PromiseQueue from '@app/util/PromiseQueue'
|
||||||
import produce from 'immer'
|
import produce from 'immer'
|
||||||
import TrackPlayer, { RepeatMode, State, Track } from 'react-native-track-player'
|
import TrackPlayer, { PlayerOptions, RepeatMode, State, Track } from 'react-native-track-player'
|
||||||
import { GetState, SetState } from 'zustand'
|
import { GetState, SetState } from 'zustand'
|
||||||
import { Store } from './store'
|
import { Store } from './store'
|
||||||
|
|
||||||
@ -67,6 +67,8 @@ export type TrackPlayerSlice = {
|
|||||||
rebuildQueue: () => Promise<void>
|
rebuildQueue: () => Promise<void>
|
||||||
buildStreamUri: (id: string) => string
|
buildStreamUri: (id: string) => string
|
||||||
resetTrackPlayerState: () => void
|
resetTrackPlayerState: () => void
|
||||||
|
|
||||||
|
getPlayerOptions: () => PlayerOptions
|
||||||
}
|
}
|
||||||
|
|
||||||
export const selectTrackPlayer = {
|
export const selectTrackPlayer = {
|
||||||
@ -200,7 +202,7 @@ export const createTrackPlayerSlice = (set: SetState<Store>, get: GetState<Store
|
|||||||
return trackPlayerCommands.enqueue(async () => {
|
return trackPlayerCommands.enqueue(async () => {
|
||||||
const shuffled = shuffle !== undefined ? shuffle : !!get().shuffleOrder
|
const shuffled = shuffle !== undefined ? shuffle : !!get().shuffleOrder
|
||||||
|
|
||||||
await TrackPlayer.setupPlayer()
|
await TrackPlayer.setupPlayer(get().getPlayerOptions())
|
||||||
await TrackPlayer.reset()
|
await TrackPlayer.reset()
|
||||||
|
|
||||||
if (songs.length === 0) {
|
if (songs.length === 0) {
|
||||||
@ -298,6 +300,7 @@ export const createTrackPlayerSlice = (set: SetState<Store>, get: GetState<Store
|
|||||||
const queueContextType = get().queueContextType
|
const queueContextType = get().queueContextType
|
||||||
|
|
||||||
await TrackPlayer.reset()
|
await TrackPlayer.reset()
|
||||||
|
await TrackPlayer.setupPlayer(get().getPlayerOptions())
|
||||||
|
|
||||||
try {
|
try {
|
||||||
for (const track of queue) {
|
for (const track of queue) {
|
||||||
@ -356,6 +359,14 @@ export const createTrackPlayerSlice = (set: SetState<Store>, get: GetState<Store
|
|||||||
progress: { position: 0, duration: 0, buffered: 0 },
|
progress: { position: 0, duration: 0, buffered: 0 },
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
|
getPlayerOptions: () => {
|
||||||
|
return {
|
||||||
|
minBuffer: get().settings.minBuffer,
|
||||||
|
playBuffer: get().settings.minBuffer / 2,
|
||||||
|
maxBuffer: get().settings.maxBuffer,
|
||||||
|
}
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
export const getQueue = async (): Promise<TrackExt[]> => {
|
export const getQueue = async (): Promise<TrackExt[]> => {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user