import Button from '@app/components/Button' import GradientScrollView from '@app/components/GradientScrollView' import Header from '@app/components/Header' import PressableOpacity from '@app/components/PressableOpacity' import SettingsItem from '@app/components/SettingsItem' import SettingsSwitch from '@app/components/SettingsSwitch' import TextInput from '@app/components/TextInput' import { withSuspenseMemo } from '@app/components/withSuspense' import { useResetImageCache, useSwitchActiveServer } from '@app/hooks/settings' import { Server } from '@app/models/settings' import { useStore, useStoreDeep } from '@app/state/store' import colors from '@app/styles/colors' import font from '@app/styles/font' import { useNavigation } from '@react-navigation/core' import React, { useCallback, useState } from 'react' import { useTranslation } from 'react-i18next' import { KeyboardTypeOptions, Linking, Modal, Pressable, StyleSheet, Text, View } from 'react-native' import { ScrollView } from 'react-native-gesture-handler' import { useSafeAreaInsets } from 'react-native-safe-area-context' import Icon from 'react-native-vector-icons/MaterialCommunityIcons' import { version } from '../../package.json' const ServerItem = withSuspenseMemo<{ server: Server }>(({ server }) => { const activeServerId = useStore(store => store.settings.activeServerId) const switchActiveServer = useSwitchActiveServer() const navigation = useNavigation() const { t } = useTranslation() const setActive = useCallback(() => { switchActiveServer(server.id) }, [server.id, switchActiveServer]) return ( navigation.navigate('server', { id: server.id, title: t('settings.servers.actions.edit') })}> {activeServerId === server.id ? ( ) : ( )} ) }) const ModalChoice = React.memo<{ text: string value: any setValue: (value: any) => void current: boolean closeModal?: () => void }>(({ text, value, setValue, current, closeModal }) => { const onPress = useCallback(() => { setValue(value) if (closeModal) { closeModal() } }, [closeModal, setValue, value]) return ( {current ? ( ) : ( )} {text} ) }) const BitrateModal = withSuspenseMemo<{ title: string bitrate: number setBitrate: (bitrate: number) => void }>(({ title, bitrate, setBitrate }) => { const { t } = useTranslation() const [visible, setVisible] = useState(false) const toggleModal = useCallback(() => setVisible(!visible), [visible]) const bitrateText = useCallback( (value: number) => value === 0 ? t('settings.network.values.unlimitedKbps') : t('settings.network.values.kbps', { value }), [t], ) const BitrateChoice: React.FC<{ value: number }> = useCallback( ({ value }) => { return ( ) }, [bitrate, toggleModal, setBitrate, bitrateText], ) return ( <>
{title}
) }) const SettingsTextModal = React.memo<{ title: string value: string setValue: (text: string) => void subtitle: (value: string) => string keyboardType?: KeyboardTypeOptions }>(({ title, value, setValue, subtitle, 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]) return ( <>
{title}
) }) const SettingsContent = withSuspenseMemo(() => { const { t } = useTranslation() const servers = useStoreDeep(store => store.settings.servers) const scrobble = useStore(store => store.settings.scrobble) const setScrobble = useStore(store => store.setScrobble) const maxBitrateWifi = useStore(store => store.settings.maxBitrateWifi) const setMaxBitrateWifi = useStore(store => store.setMaxBitrateWifi) const maxBitrateMobile = useStore(store => store.settings.maxBitrateMobile) const setMaxBitrateMobile = useStore(store => store.setMaxBitrateMobile) const minBuffer = useStore(store => store.settings.minBuffer) const setMinBuffer = useStore(store => store.setMinBuffer) const maxBuffer = useStore(store => store.settings.maxBuffer) const setMaxBuffer = useStore(store => store.setMaxBuffer) const [clearing, setClearing] = useState(false) const resetImageCache = useResetImageCache() const navigation = useNavigation() const clear = useCallback(async () => { setClearing(true) await resetImageCache() setClearing(false) }, [resetImageCache]) const setMinBufferText = useCallback((text: string) => setMinBuffer(parseFloat(text)), [setMinBuffer]) const setMaxBufferText = useCallback((text: string) => setMaxBuffer(parseFloat(text)), [setMaxBuffer]) const secondsText = useCallback((value: string) => t('settings.network.values.seconds', { value }), [t]) return (
{t('settings.servers.name')}
{Object.values(servers).map(s => ( ))}