import { useTranslation } from 'react-i18next' import TextField from '@material-ui/core/TextField' import { Box, Button, CircularProgress, FormControlLabel, FormGroup, FormHelperText, InputAdornment, InputLabel, MenuItem, Select, Switch, } from '@material-ui/core' import { styled } from '@material-ui/core/styles' import { useEffect, useMemo, useState } from 'react' import { SecondarySettingsContent, SettingSectionLabel } from './style' // Create a styled status message component const StatusMessage = styled('div')(({ theme, severity }) => ({ padding: theme.spacing(1.5, 2), marginTop: theme.spacing(1), borderRadius: theme.shape.borderRadius, display: 'flex', justifyContent: 'space-between', alignItems: 'center', backgroundColor: severity === 'error' ? '#f44336' : severity === 'success' ? '#4caf50' : severity === 'info' ? '#2196f3' : '#ff9800', color: 'white', '& button': { color: 'white', minWidth: 'auto', padding: '4px 8px', marginLeft: theme.spacing(1), }, })) export default function SecondarySettingsComponent({ settings, inputForm }) { const { t } = useTranslation() const [storageSettings, setStorageSettings] = useState({ settings: 'json', viewed: 'bbolt', }) const [storageStatus, setStorageStatus] = useState({ message: '', type: '' }) const [loading, setLoading] = useState(false) const { RetrackersMode, TorrentDisconnectTimeout, EnableDebug, EnableDLNA, EnableIPv6, FriendlyName, ForceEncrypt, DisableTCP, DisableUTP, DisableUPNP, DisableDHT, DisablePEX, DisableUpload, DownloadRateLimit, UploadRateLimit, ConnectionsLimit, PeersListenPort, ResponsiveMode, SslPort, SslCert, SslKey, ShowFSActiveTorr, EnableProxy, ProxyHosts, } = settings || {} // Local state for ProxyHosts text input const [proxyHostsText, setProxyHostsText] = useState('') // Sync proxyHostsText with ProxyHosts when settings change useEffect(() => { const textValue = Array.isArray(ProxyHosts) ? ProxyHosts.join(', ') : ProxyHosts || '' setProxyHostsText(textValue) }, [ProxyHosts]) // Use useMemo to compute basePath once const basePath = useMemo(() => { if (typeof window !== 'undefined') { return window.location.pathname.split('/')[1] || '' } return '' }, []) // Helper function to build API URL const getApiUrl = useMemo( () => endpoint => { const prefix = basePath ? `/${basePath}` : '' return `${prefix}${endpoint}` }, [basePath], ) useEffect(() => { const loadStorageSettings = async () => { try { const response = await fetch(getApiUrl('/storage/settings')) // /api/storage/settings if (response.ok) { const prefs = await response.json() setStorageSettings(prefs) } } catch (error) { // eslint-disable-line no-console } } loadStorageSettings() }, [getApiUrl]) // Handle storage settings change const handleStorageChange = event => { const { name, value } = event.target setStorageSettings(prev => ({ ...prev, [name]: value, })) } // Save storage settings - add better error handling const saveStorageSettings = async () => { setLoading(true) setStorageStatus({ message: t('SettingsDialog.Saving'), type: 'info' }) try { const response = await fetch(getApiUrl('/storage/settings'), { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(storageSettings), }) const result = await response.json() if (!response.ok) { throw new Error(result.error || 'Failed to save settings') } if (result.status === 'ok') { setStorageStatus({ message: t('SettingsDialog.StorageSettingsSaved'), type: 'success', }) } else { setStorageStatus({ message: t('SettingsDialog.SaveError') + (result.error || 'Unknown error'), type: 'error', }) } } catch (error) { setStorageStatus({ message: t('SettingsDialog.SaveError') + error.message, type: 'error', }) } finally { setLoading(false) } } return ( {t('SettingsDialog.AdditionalSettings')} } label='IPv6' labelPlacement='start' /> {t('SettingsDialog.EnableIPv6Hint')} } label='TCP (Transmission Control Protocol)' labelPlacement='start' /> {t('SettingsDialog.DisableTCPHint')} } label='μTP (Micro Transport Protocol)' labelPlacement='start' /> {t('SettingsDialog.DisableUTPHint')} } label='PEX (Peer Exchange)' labelPlacement='start' /> {t('SettingsDialog.DisablePEXHint')} } label={t('SettingsDialog.ForceEncrypt')} labelPlacement='start' /> {t('SettingsDialog.ForceEncryptHint')} {t('Seconds')}, }} value={TorrentDisconnectTimeout} type='number' variant='outlined' fullWidth />

} label={t('SettingsDialog.DHT')} labelPlacement='start' /> {t('SettingsDialog.DisableDHTHint')} {t('Kilobytes')}, }} value={DownloadRateLimit} type='number' variant='outlined' fullWidth />
} label={t('SettingsDialog.Upload')} labelPlacement='start' /> {t('SettingsDialog.UploadHint')} {t('Kilobytes')}, }} value={UploadRateLimit} type='number' variant='outlined' fullWidth />
} label='UPnP (Universal Plug and Play)' labelPlacement='start' /> {t('SettingsDialog.DisableUPNPHint')} } label={t('SettingsDialog.EnableDebug')} labelPlacement='start' /> {t('SettingsDialog.EnableDebugHint')} } label={t('SettingsDialog.ResponsiveMode')} labelPlacement='start' /> {t('SettingsDialog.ResponsiveModeHint')}
{t('SettingsDialog.RetrackersMode')} {t('SettingsDialog.RetrackersModeHint')} {/* DLNA Section */} {t('DLNA')} } label={t('SettingsDialog.DLNA')} labelPlacement='start' /> {/* HTTPS Section */} {t('HTTPS')}


{/* TorrFS */} {t('TorrFS')} } label={t('SettingsDialog.ShowFSActiveTorr')} labelPlacement='start' /> {t('SettingsDialog.ShowFSActiveTorrHint')} {/* Storage Settings Section */} {t('SettingsDialog.StorageConfiguration')} {t('SettingsDialog.SettingsStorage')} {t('SettingsDialog.SettingsStorageHint')} {t('SettingsDialog.ViewedHistoryStorage')} {t('SettingsDialog.ViewedStorageHint')} {storageStatus.message && ( {storageStatus.message} )} {/* ProxyP2P */} {t('Proxy')} } label={t('SettingsDialog.EnableProxy')} labelPlacement='start' /> {t('SettingsDialog.EnableProxyHint')} {/* Proxy hosts */} { setProxyHostsText(e.target.value) }} onBlur={e => { const inputValue = e.target.value.trim() const hostsArray = inputValue === '' ? [] : inputValue .split(',') .map(s => s.trim()) .filter(s => s !== '') inputForm({ target: { id: 'ProxyHosts', value: hostsArray, }, }) }} margin='normal' id='ProxyHosts' label={t('SettingsDialog.ProxyHosts')} helperText={t('SettingsDialog.ProxyHostsHint')} value={proxyHostsText} type='text' variant='outlined' fullWidth />
) }