mirror of
https://github.com/zoriya/flood.git
synced 2026-05-29 09:41:49 +00:00
SettingsModal: migrate to Functional Component
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import {lazy, Suspense} from 'react';
|
||||
import {FC, lazy, Suspense} from 'react';
|
||||
|
||||
import packageJSON from '../../../../../../package.json';
|
||||
|
||||
@@ -8,7 +8,7 @@ const AboutMarkdown = lazy(() =>
|
||||
|
||||
const FLOOD_PROJECT_URL = 'https://github.com/jesec/flood';
|
||||
|
||||
const AboutTab = () => (
|
||||
const AboutTab: FC = () => (
|
||||
<Suspense fallback={null}>
|
||||
<AboutMarkdown
|
||||
FloodVersion={() => packageJSON.version}
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
import {FormattedMessage} from 'react-intl';
|
||||
import {FormEvent} from 'react';
|
||||
import {FC, FormEvent, useState} from 'react';
|
||||
|
||||
import {Form, FormRow, Textbox} from '@client/ui';
|
||||
import SettingStore from '@client/stores/SettingStore';
|
||||
|
||||
import {FloodSettings} from '@shared/types/FloodSettings';
|
||||
import {ClientSettings} from '@shared/types/ClientSettings';
|
||||
|
||||
import {getChangedClientSetting, handleClientSettingChange} from './SettingsUtils';
|
||||
import ModalFormSectionHeader from '../ModalFormSectionHeader';
|
||||
import SettingsTab from './SettingsTab';
|
||||
|
||||
const processSpeedsForDisplay = (speeds: number[]): string | undefined => {
|
||||
if (!speeds || speeds.length === 0) {
|
||||
@@ -26,98 +29,104 @@ const processSpeedsForSave = (speeds = ''): number[] => {
|
||||
.map((speed) => Number(speed));
|
||||
};
|
||||
|
||||
export default class BandwidthTab extends SettingsTab {
|
||||
handleFormChange = ({
|
||||
event,
|
||||
formData,
|
||||
}: {
|
||||
event: Event | FormEvent<HTMLFormElement>;
|
||||
formData: Record<string, unknown>;
|
||||
}) => {
|
||||
const inputElement = event.target as HTMLInputElement;
|
||||
|
||||
if (inputElement.name === 'dropdownPresetDownload' || inputElement.name === 'dropdownPresetUpload') {
|
||||
this.props.onSettingsChange({
|
||||
speedLimits: {
|
||||
download: processSpeedsForSave(formData.dropdownPresetDownload as string),
|
||||
upload: processSpeedsForSave(formData.dropdownPresetUpload as string),
|
||||
},
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
this.handleClientSettingChange(event);
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Form onChange={this.handleFormChange}>
|
||||
<ModalFormSectionHeader>
|
||||
<FormattedMessage id="settings.bandwidth.transferrate.heading" />
|
||||
</ModalFormSectionHeader>
|
||||
<FormRow>
|
||||
<Textbox
|
||||
defaultValue={
|
||||
SettingStore.floodSettings.speedLimits != null
|
||||
? processSpeedsForDisplay(SettingStore.floodSettings.speedLimits.download)
|
||||
: 0
|
||||
}
|
||||
label={<FormattedMessage id="settings.bandwidth.transferrate.dropdown.preset.download.label" />}
|
||||
id="dropdownPresetDownload"
|
||||
/>
|
||||
</FormRow>
|
||||
<FormRow>
|
||||
<Textbox
|
||||
defaultValue={
|
||||
SettingStore.floodSettings.speedLimits != null
|
||||
? processSpeedsForDisplay(SettingStore.floodSettings.speedLimits.upload)
|
||||
: 0
|
||||
}
|
||||
label={<FormattedMessage id="settings.bandwidth.transferrate.dropdown.preset.upload.label" />}
|
||||
id="dropdownPresetUpload"
|
||||
/>
|
||||
</FormRow>
|
||||
<FormRow>
|
||||
<Textbox
|
||||
defaultValue={this.getChangedClientSetting('throttleGlobalDownSpeed')}
|
||||
label={<FormattedMessage id="settings.bandwidth.transferrate.global.throttle.download" />}
|
||||
id="throttleGlobalDownSpeed"
|
||||
/>
|
||||
<Textbox
|
||||
defaultValue={this.getChangedClientSetting('throttleGlobalUpSpeed')}
|
||||
label={<FormattedMessage id="settings.bandwidth.transferrate.global.throttle.upload" />}
|
||||
id="throttleGlobalUpSpeed"
|
||||
/>
|
||||
</FormRow>
|
||||
<ModalFormSectionHeader>
|
||||
<FormattedMessage id="settings.bandwidth.slots.heading" />
|
||||
</ModalFormSectionHeader>
|
||||
<FormRow>
|
||||
<Textbox
|
||||
defaultValue={this.getChangedClientSetting('throttleMaxUploads')}
|
||||
label={<FormattedMessage id="settings.bandwidth.slots.upload.label" />}
|
||||
id="throttleMaxUploads"
|
||||
/>
|
||||
<Textbox
|
||||
defaultValue={this.getChangedClientSetting('throttleMaxUploadsGlobal')}
|
||||
label={<FormattedMessage id="settings.bandwidth.slots.upload.global.label" />}
|
||||
id="throttleMaxUploadsGlobal"
|
||||
/>
|
||||
</FormRow>
|
||||
<FormRow>
|
||||
<Textbox
|
||||
defaultValue={this.getChangedClientSetting('throttleMaxDownloads')}
|
||||
label={<FormattedMessage id="settings.bandwidth.slots.download.label" />}
|
||||
id="throttleMaxDownloads"
|
||||
/>
|
||||
<Textbox
|
||||
defaultValue={this.getChangedClientSetting('throttleMaxDownloadsGlobal')}
|
||||
label={<FormattedMessage id="settings.bandwidth.slots.download.global.label" />}
|
||||
id="throttleMaxDownloadsGlobal"
|
||||
/>
|
||||
</FormRow>
|
||||
</Form>
|
||||
);
|
||||
}
|
||||
interface BandwidthTabProps {
|
||||
onSettingsChange: (changeSettings: Partial<FloodSettings>) => void;
|
||||
onClientSettingsChange: (changeSettings: Partial<ClientSettings>) => void;
|
||||
}
|
||||
|
||||
const BandwidthTab: FC<BandwidthTabProps> = ({onSettingsChange, onClientSettingsChange}: BandwidthTabProps) => {
|
||||
const [changedClientSettings, setChangedClientSettings] = useState<Partial<ClientSettings>>({});
|
||||
|
||||
return (
|
||||
<Form
|
||||
onChange={({event, formData}: {event: Event | FormEvent<HTMLFormElement>; formData: Record<string, unknown>}) => {
|
||||
const inputElement = event.target as HTMLInputElement;
|
||||
|
||||
if (inputElement.name === 'dropdownPresetDownload' || inputElement.name === 'dropdownPresetUpload') {
|
||||
onSettingsChange({
|
||||
speedLimits: {
|
||||
download: processSpeedsForSave(formData.dropdownPresetDownload as string),
|
||||
upload: processSpeedsForSave(formData.dropdownPresetUpload as string),
|
||||
},
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const newChangedClientSettings = {
|
||||
...changedClientSettings,
|
||||
...handleClientSettingChange(event),
|
||||
};
|
||||
|
||||
setChangedClientSettings(newChangedClientSettings);
|
||||
onClientSettingsChange(newChangedClientSettings);
|
||||
}}>
|
||||
<ModalFormSectionHeader>
|
||||
<FormattedMessage id="settings.bandwidth.transferrate.heading" />
|
||||
</ModalFormSectionHeader>
|
||||
<FormRow>
|
||||
<Textbox
|
||||
defaultValue={
|
||||
SettingStore.floodSettings.speedLimits != null
|
||||
? processSpeedsForDisplay(SettingStore.floodSettings.speedLimits.download)
|
||||
: 0
|
||||
}
|
||||
label={<FormattedMessage id="settings.bandwidth.transferrate.dropdown.preset.download.label" />}
|
||||
id="dropdownPresetDownload"
|
||||
/>
|
||||
</FormRow>
|
||||
<FormRow>
|
||||
<Textbox
|
||||
defaultValue={
|
||||
SettingStore.floodSettings.speedLimits != null
|
||||
? processSpeedsForDisplay(SettingStore.floodSettings.speedLimits.upload)
|
||||
: 0
|
||||
}
|
||||
label={<FormattedMessage id="settings.bandwidth.transferrate.dropdown.preset.upload.label" />}
|
||||
id="dropdownPresetUpload"
|
||||
/>
|
||||
</FormRow>
|
||||
<FormRow>
|
||||
<Textbox
|
||||
defaultValue={getChangedClientSetting(changedClientSettings, 'throttleGlobalDownSpeed')}
|
||||
label={<FormattedMessage id="settings.bandwidth.transferrate.global.throttle.download" />}
|
||||
id="throttleGlobalDownSpeed"
|
||||
/>
|
||||
<Textbox
|
||||
defaultValue={getChangedClientSetting(changedClientSettings, 'throttleGlobalUpSpeed')}
|
||||
label={<FormattedMessage id="settings.bandwidth.transferrate.global.throttle.upload" />}
|
||||
id="throttleGlobalUpSpeed"
|
||||
/>
|
||||
</FormRow>
|
||||
<ModalFormSectionHeader>
|
||||
<FormattedMessage id="settings.bandwidth.slots.heading" />
|
||||
</ModalFormSectionHeader>
|
||||
<FormRow>
|
||||
<Textbox
|
||||
defaultValue={getChangedClientSetting(changedClientSettings, 'throttleMaxUploads')}
|
||||
label={<FormattedMessage id="settings.bandwidth.slots.upload.label" />}
|
||||
id="throttleMaxUploads"
|
||||
/>
|
||||
<Textbox
|
||||
defaultValue={getChangedClientSetting(changedClientSettings, 'throttleMaxUploadsGlobal')}
|
||||
label={<FormattedMessage id="settings.bandwidth.slots.upload.global.label" />}
|
||||
id="throttleMaxUploadsGlobal"
|
||||
/>
|
||||
</FormRow>
|
||||
<FormRow>
|
||||
<Textbox
|
||||
defaultValue={getChangedClientSetting(changedClientSettings, 'throttleMaxDownloads')}
|
||||
label={<FormattedMessage id="settings.bandwidth.slots.download.label" />}
|
||||
id="throttleMaxDownloads"
|
||||
/>
|
||||
<Textbox
|
||||
defaultValue={getChangedClientSetting(changedClientSettings, 'throttleMaxDownloadsGlobal')}
|
||||
label={<FormattedMessage id="settings.bandwidth.slots.download.global.label" />}
|
||||
id="throttleMaxDownloadsGlobal"
|
||||
/>
|
||||
</FormRow>
|
||||
</Form>
|
||||
);
|
||||
};
|
||||
|
||||
export default BandwidthTab;
|
||||
|
||||
@@ -1,116 +1,134 @@
|
||||
import {FC, useState} from 'react';
|
||||
import {FormattedMessage} from 'react-intl';
|
||||
|
||||
import {Checkbox, Form, FormRow, Textbox} from '@client/ui';
|
||||
|
||||
import ModalFormSectionHeader from '../ModalFormSectionHeader';
|
||||
import SettingsTab from './SettingsTab';
|
||||
import {ClientSettings} from '@shared/types/ClientSettings';
|
||||
|
||||
export default class ConnectivityTab extends SettingsTab {
|
||||
render() {
|
||||
return (
|
||||
<Form onChange={({event}) => this.handleClientSettingChange(event)}>
|
||||
<ModalFormSectionHeader>
|
||||
<FormattedMessage id="settings.connectivity.incoming.heading" />
|
||||
</ModalFormSectionHeader>
|
||||
<FormRow>
|
||||
<Textbox
|
||||
defaultValue={this.getChangedClientSetting('networkPortRange')}
|
||||
id="networkPortRange"
|
||||
label={<FormattedMessage id="settings.connectivity.port.range.label" />}
|
||||
width="one-quarter"
|
||||
/>
|
||||
<Checkbox
|
||||
defaultChecked={this.getChangedClientSetting('networkPortRandom')}
|
||||
grow={false}
|
||||
id="networkPortRandom"
|
||||
labelOffset
|
||||
matchTextboxHeight>
|
||||
<FormattedMessage id="settings.connectivity.port.randomize.label" />
|
||||
</Checkbox>
|
||||
<Checkbox
|
||||
defaultChecked={this.getChangedClientSetting('networkPortOpen')}
|
||||
grow={false}
|
||||
id="networkPortOpen"
|
||||
labelOffset
|
||||
matchTextboxHeight>
|
||||
<FormattedMessage id="settings.connectivity.port.open.label" />
|
||||
</Checkbox>
|
||||
</FormRow>
|
||||
<FormRow>
|
||||
<Textbox
|
||||
defaultValue={this.getChangedClientSetting('networkLocalAddress')}
|
||||
id="networkLocalAddress"
|
||||
label={<FormattedMessage id="settings.connectivity.ip.hostname.label" />}
|
||||
/>
|
||||
<Textbox
|
||||
defaultValue={this.getChangedClientSetting('networkHttpMaxOpen')}
|
||||
id="networkHttpMaxOpen"
|
||||
label={<FormattedMessage id="settings.connectivity.max.http.connections" />}
|
||||
/>
|
||||
</FormRow>
|
||||
<ModalFormSectionHeader>
|
||||
<FormattedMessage id="settings.connectivity.dpd.heading" />
|
||||
</ModalFormSectionHeader>
|
||||
<FormRow>
|
||||
<Textbox
|
||||
defaultValue={this.getChangedClientSetting('dhtPort')}
|
||||
id="dhtPort"
|
||||
label={<FormattedMessage id="settings.connectivity.dht.port.label" />}
|
||||
width="one-quarter"
|
||||
/>
|
||||
<Checkbox
|
||||
defaultChecked={this.getChangedClientSetting('dht')}
|
||||
grow={false}
|
||||
id="dht"
|
||||
labelOffset
|
||||
matchTextboxHeight>
|
||||
<FormattedMessage id="settings.connectivity.dht.label" />
|
||||
</Checkbox>
|
||||
<Checkbox
|
||||
defaultChecked={this.getChangedClientSetting('protocolPex')}
|
||||
grow={false}
|
||||
id="protocolPex"
|
||||
labelOffset
|
||||
matchTextboxHeight>
|
||||
<FormattedMessage id="settings.connectivity.peer.exchange.label" />
|
||||
</Checkbox>
|
||||
</FormRow>
|
||||
<ModalFormSectionHeader>
|
||||
<FormattedMessage id="settings.connectivity.peers.heading" />
|
||||
</ModalFormSectionHeader>
|
||||
<FormRow>
|
||||
<Textbox
|
||||
defaultValue={this.getChangedClientSetting('throttleMinPeersNormal')}
|
||||
id="throttleMinPeersNormal"
|
||||
label={<FormattedMessage id="settings.connectivity.peers.min.label" />}
|
||||
/>
|
||||
<Textbox
|
||||
defaultValue={this.getChangedClientSetting('throttleMaxPeersNormal')}
|
||||
id="throttleMaxPeersNormal"
|
||||
label={<FormattedMessage id="settings.connectivity.peers.max.label" />}
|
||||
/>
|
||||
</FormRow>
|
||||
<FormRow>
|
||||
<Textbox
|
||||
defaultValue={this.getChangedClientSetting('throttleMinPeersSeed')}
|
||||
id="throttleMinPeersSeed"
|
||||
label={<FormattedMessage id="settings.connectivity.peers.seeding.min.label" />}
|
||||
/>
|
||||
<Textbox
|
||||
defaultValue={this.getChangedClientSetting('throttleMaxPeersSeed')}
|
||||
id="throttleMaxPeersSeed"
|
||||
label={<FormattedMessage id="settings.connectivity.peers.seeding.max.label" />}
|
||||
/>
|
||||
</FormRow>
|
||||
<FormRow>
|
||||
<Textbox
|
||||
defaultValue={this.getChangedClientSetting('trackersNumWant')}
|
||||
id="trackersNumWant"
|
||||
label={<FormattedMessage id="settings.connectivity.peers.desired.label" />}
|
||||
width="one-half"
|
||||
/>
|
||||
</FormRow>
|
||||
</Form>
|
||||
);
|
||||
}
|
||||
import {getChangedClientSetting, handleClientSettingChange} from './SettingsUtils';
|
||||
import ModalFormSectionHeader from '../ModalFormSectionHeader';
|
||||
|
||||
interface ConnectivityTabProps {
|
||||
onClientSettingsChange: (changeSettings: Partial<ClientSettings>) => void;
|
||||
}
|
||||
|
||||
const ConnectivityTab: FC<ConnectivityTabProps> = ({onClientSettingsChange}: ConnectivityTabProps) => {
|
||||
const [changedClientSettings, setChangedClientSettings] = useState<Partial<ClientSettings>>({});
|
||||
|
||||
return (
|
||||
<Form
|
||||
onChange={({event}) => {
|
||||
const newChangedClientSettings = {
|
||||
...changedClientSettings,
|
||||
...handleClientSettingChange(event),
|
||||
};
|
||||
|
||||
setChangedClientSettings(newChangedClientSettings);
|
||||
onClientSettingsChange(newChangedClientSettings);
|
||||
}}>
|
||||
<ModalFormSectionHeader>
|
||||
<FormattedMessage id="settings.connectivity.incoming.heading" />
|
||||
</ModalFormSectionHeader>
|
||||
<FormRow>
|
||||
<Textbox
|
||||
defaultValue={getChangedClientSetting(changedClientSettings, 'networkPortRange')}
|
||||
id="networkPortRange"
|
||||
label={<FormattedMessage id="settings.connectivity.port.range.label" />}
|
||||
width="one-quarter"
|
||||
/>
|
||||
<Checkbox
|
||||
defaultChecked={getChangedClientSetting(changedClientSettings, 'networkPortRandom')}
|
||||
grow={false}
|
||||
id="networkPortRandom"
|
||||
labelOffset
|
||||
matchTextboxHeight>
|
||||
<FormattedMessage id="settings.connectivity.port.randomize.label" />
|
||||
</Checkbox>
|
||||
<Checkbox
|
||||
defaultChecked={getChangedClientSetting(changedClientSettings, 'networkPortOpen')}
|
||||
grow={false}
|
||||
id="networkPortOpen"
|
||||
labelOffset
|
||||
matchTextboxHeight>
|
||||
<FormattedMessage id="settings.connectivity.port.open.label" />
|
||||
</Checkbox>
|
||||
</FormRow>
|
||||
<FormRow>
|
||||
<Textbox
|
||||
defaultValue={getChangedClientSetting(changedClientSettings, 'networkLocalAddress')}
|
||||
id="networkLocalAddress"
|
||||
label={<FormattedMessage id="settings.connectivity.ip.hostname.label" />}
|
||||
/>
|
||||
<Textbox
|
||||
defaultValue={getChangedClientSetting(changedClientSettings, 'networkHttpMaxOpen')}
|
||||
id="networkHttpMaxOpen"
|
||||
label={<FormattedMessage id="settings.connectivity.max.http.connections" />}
|
||||
/>
|
||||
</FormRow>
|
||||
<ModalFormSectionHeader>
|
||||
<FormattedMessage id="settings.connectivity.dpd.heading" />
|
||||
</ModalFormSectionHeader>
|
||||
<FormRow>
|
||||
<Textbox
|
||||
defaultValue={getChangedClientSetting(changedClientSettings, 'dhtPort')}
|
||||
id="dhtPort"
|
||||
label={<FormattedMessage id="settings.connectivity.dht.port.label" />}
|
||||
width="one-quarter"
|
||||
/>
|
||||
<Checkbox
|
||||
defaultChecked={getChangedClientSetting(changedClientSettings, 'dht')}
|
||||
grow={false}
|
||||
id="dht"
|
||||
labelOffset
|
||||
matchTextboxHeight>
|
||||
<FormattedMessage id="settings.connectivity.dht.label" />
|
||||
</Checkbox>
|
||||
<Checkbox
|
||||
defaultChecked={getChangedClientSetting(changedClientSettings, 'protocolPex')}
|
||||
grow={false}
|
||||
id="protocolPex"
|
||||
labelOffset
|
||||
matchTextboxHeight>
|
||||
<FormattedMessage id="settings.connectivity.peer.exchange.label" />
|
||||
</Checkbox>
|
||||
</FormRow>
|
||||
<ModalFormSectionHeader>
|
||||
<FormattedMessage id="settings.connectivity.peers.heading" />
|
||||
</ModalFormSectionHeader>
|
||||
<FormRow>
|
||||
<Textbox
|
||||
defaultValue={getChangedClientSetting(changedClientSettings, 'throttleMinPeersNormal')}
|
||||
id="throttleMinPeersNormal"
|
||||
label={<FormattedMessage id="settings.connectivity.peers.min.label" />}
|
||||
/>
|
||||
<Textbox
|
||||
defaultValue={getChangedClientSetting(changedClientSettings, 'throttleMaxPeersNormal')}
|
||||
id="throttleMaxPeersNormal"
|
||||
label={<FormattedMessage id="settings.connectivity.peers.max.label" />}
|
||||
/>
|
||||
</FormRow>
|
||||
<FormRow>
|
||||
<Textbox
|
||||
defaultValue={getChangedClientSetting(changedClientSettings, 'throttleMinPeersSeed')}
|
||||
id="throttleMinPeersSeed"
|
||||
label={<FormattedMessage id="settings.connectivity.peers.seeding.min.label" />}
|
||||
/>
|
||||
<Textbox
|
||||
defaultValue={getChangedClientSetting(changedClientSettings, 'throttleMaxPeersSeed')}
|
||||
id="throttleMaxPeersSeed"
|
||||
label={<FormattedMessage id="settings.connectivity.peers.seeding.max.label" />}
|
||||
/>
|
||||
</FormRow>
|
||||
<FormRow>
|
||||
<Textbox
|
||||
defaultValue={getChangedClientSetting(changedClientSettings, 'trackersNumWant')}
|
||||
id="trackersNumWant"
|
||||
label={<FormattedMessage id="settings.connectivity.peers.desired.label" />}
|
||||
width="one-half"
|
||||
/>
|
||||
</FormRow>
|
||||
</Form>
|
||||
);
|
||||
};
|
||||
|
||||
export default ConnectivityTab;
|
||||
|
||||
@@ -1,56 +1,74 @@
|
||||
import {FC, useState} from 'react';
|
||||
import {FormattedMessage} from 'react-intl';
|
||||
|
||||
import {Checkbox, Form, FormRow, Textbox} from '@client/ui';
|
||||
|
||||
import ModalFormSectionHeader from '../ModalFormSectionHeader';
|
||||
import SettingsTab from './SettingsTab';
|
||||
import {ClientSettings} from '@shared/types/ClientSettings';
|
||||
|
||||
export default class ResourcesTab extends SettingsTab {
|
||||
render() {
|
||||
return (
|
||||
<Form onChange={({event}) => this.handleClientSettingChange(event)}>
|
||||
<ModalFormSectionHeader>
|
||||
<FormattedMessage id="settings.resources.disk.heading" />
|
||||
</ModalFormSectionHeader>
|
||||
<FormRow>
|
||||
<Textbox
|
||||
defaultValue={this.getChangedClientSetting('directoryDefault')}
|
||||
id="directoryDefault"
|
||||
label={<FormattedMessage id="settings.resources.disk.download.location.label" />}
|
||||
/>
|
||||
</FormRow>
|
||||
<FormRow>
|
||||
<Textbox
|
||||
defaultValue={this.getChangedClientSetting('networkMaxOpenFiles')}
|
||||
id="networkMaxOpenFiles"
|
||||
label={<FormattedMessage id="settings.resources.max.open.files" />}
|
||||
width="one-half"
|
||||
/>
|
||||
<Checkbox
|
||||
defaultChecked={this.getChangedClientSetting('piecesHashOnCompletion')}
|
||||
grow={false}
|
||||
id="piecesHashOnCompletion"
|
||||
labelOffset
|
||||
matchTextboxHeight>
|
||||
<FormattedMessage id="settings.resources.disk.check.hash.label" />
|
||||
</Checkbox>
|
||||
</FormRow>
|
||||
<ModalFormSectionHeader>
|
||||
<FormattedMessage id="settings.resources.memory.heading" />
|
||||
</ModalFormSectionHeader>
|
||||
<FormRow>
|
||||
<Textbox
|
||||
defaultValue={this.getChangedClientSetting('piecesMemoryMax')}
|
||||
id="piecesMemoryMax"
|
||||
label={
|
||||
<div>
|
||||
<FormattedMessage id="settings.resources.memory.max.label" /> <em className="unit">(MB)</em>
|
||||
</div>
|
||||
}
|
||||
width="one-half"
|
||||
/>
|
||||
</FormRow>
|
||||
</Form>
|
||||
);
|
||||
}
|
||||
import {getChangedClientSetting, handleClientSettingChange} from './SettingsUtils';
|
||||
import ModalFormSectionHeader from '../ModalFormSectionHeader';
|
||||
|
||||
interface ResourcesTabProps {
|
||||
onClientSettingsChange: (changeSettings: Partial<ClientSettings>) => void;
|
||||
}
|
||||
|
||||
const ResourcesTab: FC<ResourcesTabProps> = ({onClientSettingsChange}: ResourcesTabProps) => {
|
||||
const [changedClientSettings, setChangedClientSettings] = useState<Partial<ClientSettings>>({});
|
||||
|
||||
return (
|
||||
<Form
|
||||
onChange={({event}) => {
|
||||
const newChangedClientSettings = {
|
||||
...changedClientSettings,
|
||||
...handleClientSettingChange(event),
|
||||
};
|
||||
|
||||
setChangedClientSettings(newChangedClientSettings);
|
||||
onClientSettingsChange(newChangedClientSettings);
|
||||
}}>
|
||||
<ModalFormSectionHeader>
|
||||
<FormattedMessage id="settings.resources.disk.heading" />
|
||||
</ModalFormSectionHeader>
|
||||
<FormRow>
|
||||
<Textbox
|
||||
defaultValue={getChangedClientSetting(changedClientSettings, 'directoryDefault')}
|
||||
id="directoryDefault"
|
||||
label={<FormattedMessage id="settings.resources.disk.download.location.label" />}
|
||||
/>
|
||||
</FormRow>
|
||||
<FormRow>
|
||||
<Textbox
|
||||
defaultValue={getChangedClientSetting(changedClientSettings, 'networkMaxOpenFiles')}
|
||||
id="networkMaxOpenFiles"
|
||||
label={<FormattedMessage id="settings.resources.max.open.files" />}
|
||||
width="one-half"
|
||||
/>
|
||||
<Checkbox
|
||||
defaultChecked={getChangedClientSetting(changedClientSettings, 'piecesHashOnCompletion')}
|
||||
grow={false}
|
||||
id="piecesHashOnCompletion"
|
||||
labelOffset
|
||||
matchTextboxHeight>
|
||||
<FormattedMessage id="settings.resources.disk.check.hash.label" />
|
||||
</Checkbox>
|
||||
</FormRow>
|
||||
<ModalFormSectionHeader>
|
||||
<FormattedMessage id="settings.resources.memory.heading" />
|
||||
</ModalFormSectionHeader>
|
||||
<FormRow>
|
||||
<Textbox
|
||||
defaultValue={getChangedClientSetting(changedClientSettings, 'piecesMemoryMax')}
|
||||
id="piecesMemoryMax"
|
||||
label={
|
||||
<div>
|
||||
<FormattedMessage id="settings.resources.memory.max.label" /> <em className="unit">(MB)</em>
|
||||
</div>
|
||||
}
|
||||
width="one-half"
|
||||
/>
|
||||
</FormRow>
|
||||
</Form>
|
||||
);
|
||||
};
|
||||
|
||||
export default ResourcesTab;
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
import {Component, FormEvent} from 'react';
|
||||
import {WrappedComponentProps} from 'react-intl';
|
||||
|
||||
import type {ClientSetting, ClientSettings} from '@shared/types/ClientSettings';
|
||||
import type {FloodSettings} from '@shared/types/FloodSettings';
|
||||
|
||||
import SettingStore from '../../../stores/SettingStore';
|
||||
|
||||
interface SettingsTabProps extends WrappedComponentProps {
|
||||
onSettingsChange: (changeSettings: Partial<FloodSettings>) => void;
|
||||
onClientSettingsChange: (changeSettings: Partial<ClientSettings>) => void;
|
||||
}
|
||||
|
||||
interface SettingsTabStates {
|
||||
changedClientSettings: Partial<ClientSettings>;
|
||||
}
|
||||
|
||||
class SettingsTab extends Component<SettingsTabProps, SettingsTabStates> {
|
||||
constructor(props: SettingsTabProps) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
changedClientSettings: {},
|
||||
};
|
||||
}
|
||||
|
||||
getChangedClientSetting<T extends ClientSetting>(property: T): ClientSettings[T] | undefined {
|
||||
if (this.state.changedClientSettings[property] != null) {
|
||||
return this.state.changedClientSettings[property] as ClientSettings[T];
|
||||
}
|
||||
|
||||
return SettingStore.clientSettings?.[property];
|
||||
}
|
||||
|
||||
handleClientSettingChange(event: FormEvent<HTMLFormElement> | Event) {
|
||||
const inputElement = event.target as HTMLInputElement;
|
||||
const property = inputElement.name as ClientSetting;
|
||||
const {value, type, checked} = inputElement;
|
||||
|
||||
let changedClientSetting: Partial<ClientSettings> = {};
|
||||
if (type === 'checkbox') {
|
||||
changedClientSetting = {[property]: checked};
|
||||
} else {
|
||||
changedClientSetting = {[property]: value};
|
||||
}
|
||||
|
||||
this.setState((prev) => ({
|
||||
changedClientSettings: {
|
||||
...prev.changedClientSettings,
|
||||
changedClientSetting,
|
||||
},
|
||||
}));
|
||||
this.props.onClientSettingsChange(changedClientSetting);
|
||||
}
|
||||
}
|
||||
|
||||
export default SettingsTab;
|
||||
@@ -0,0 +1,31 @@
|
||||
import {FormEvent} from 'react';
|
||||
|
||||
import type {ClientSetting, ClientSettings} from '@shared/types/ClientSettings';
|
||||
|
||||
import SettingStore from '../../../stores/SettingStore';
|
||||
|
||||
export const getChangedClientSetting = <T extends ClientSetting>(
|
||||
changedClientSettings: Partial<ClientSettings>,
|
||||
property: T,
|
||||
): ClientSettings[T] | undefined => {
|
||||
if (changedClientSettings[property] != null) {
|
||||
return changedClientSettings[property] as ClientSettings[T];
|
||||
}
|
||||
|
||||
return SettingStore.clientSettings?.[property];
|
||||
};
|
||||
|
||||
export const handleClientSettingChange = (event: FormEvent<HTMLFormElement> | Event): Partial<ClientSettings> => {
|
||||
const inputElement = event.target as HTMLInputElement;
|
||||
const property = inputElement.name as ClientSetting;
|
||||
const {value, type, checked} = inputElement;
|
||||
|
||||
let changedClientSetting: Partial<ClientSettings> = {};
|
||||
if (type === 'checkbox') {
|
||||
changedClientSetting = {[property]: checked};
|
||||
} else {
|
||||
changedClientSetting = {[property]: value};
|
||||
}
|
||||
|
||||
return changedClientSetting;
|
||||
};
|
||||
@@ -1,5 +1,5 @@
|
||||
import {FormattedMessage, injectIntl} from 'react-intl';
|
||||
import {FormEvent} from 'react';
|
||||
import {FormattedMessage, useIntl} from 'react-intl';
|
||||
import {FC, useState} from 'react';
|
||||
|
||||
import {Form, FormRow, Select, SelectItem, Radio} from '@client/ui';
|
||||
import Languages from '@client/constants/Languages';
|
||||
@@ -10,122 +10,101 @@ import type {Language} from '@client/constants/Languages';
|
||||
import type {FloodSettings} from '@shared/types/FloodSettings';
|
||||
|
||||
import ModalFormSectionHeader from '../ModalFormSectionHeader';
|
||||
import SettingsTab from './SettingsTab';
|
||||
import TorrentContextMenuActionsList from './lists/TorrentContextMenuActionsList';
|
||||
import TorrentListColumnsList from './lists/TorrentListColumnsList';
|
||||
|
||||
class UITab extends SettingsTab {
|
||||
torrentListViewSize = SettingStore.floodSettings.torrentListViewSize;
|
||||
selectedLanguage = SettingStore.floodSettings.language;
|
||||
UITagSelectorMode = SettingStore.floodSettings.UITagSelectorMode;
|
||||
|
||||
getLanguageSelectOptions() {
|
||||
return Object.keys(Languages).map((languageID) => (
|
||||
<SelectItem key={languageID} id={languageID}>
|
||||
{Languages[languageID as 'auto'].id != null
|
||||
? this.props.intl.formatMessage({
|
||||
id: Languages[languageID as 'auto'].id,
|
||||
})
|
||||
: Languages[languageID as Language]}
|
||||
</SelectItem>
|
||||
));
|
||||
}
|
||||
|
||||
handleFormChange = ({
|
||||
event,
|
||||
formData,
|
||||
}: {
|
||||
event: Event | FormEvent<HTMLFormElement>;
|
||||
formData: Record<string, unknown>;
|
||||
}) => {
|
||||
const inputElement = event.target as HTMLInputElement;
|
||||
|
||||
if (inputElement.type === 'radio') {
|
||||
this.torrentListViewSize = formData['ui-torrent-size'] as FloodSettings['torrentListViewSize'];
|
||||
this.UITagSelectorMode = formData['ui-tag-selector-mode'] as FloodSettings['UITagSelectorMode'];
|
||||
this.props.onSettingsChange({
|
||||
torrentListViewSize: this.torrentListViewSize,
|
||||
UITagSelectorMode: this.UITagSelectorMode,
|
||||
});
|
||||
}
|
||||
|
||||
if (inputElement.name === 'language') {
|
||||
this.selectedLanguage = formData.language as FloodSettings['language'];
|
||||
if (this.selectedLanguage === 'translate') {
|
||||
SettingStore.saveFloodSettings({language: 'translate'});
|
||||
} else {
|
||||
this.props.onSettingsChange({language: this.selectedLanguage});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Form onChange={this.handleFormChange}>
|
||||
<ModalFormSectionHeader key="locale-header">
|
||||
<FormattedMessage id="settings.ui.language" />
|
||||
</ModalFormSectionHeader>
|
||||
<FormRow key="locale-selection">
|
||||
<Select disabled={this.selectedLanguage === 'translate'} defaultID={this.selectedLanguage} id="language">
|
||||
{this.getLanguageSelectOptions()}
|
||||
</Select>
|
||||
</FormRow>
|
||||
<ModalFormSectionHeader>
|
||||
<FormattedMessage id="settings.ui.tag.selector.mode" />
|
||||
</ModalFormSectionHeader>
|
||||
<FormRow>
|
||||
<Radio
|
||||
defaultChecked={this.UITagSelectorMode === 'single'}
|
||||
groupID="ui-tag-selector-mode"
|
||||
id="single"
|
||||
width="auto">
|
||||
<FormattedMessage id="settings.ui.tag.selector.mode.single" />
|
||||
</Radio>
|
||||
<Radio
|
||||
defaultChecked={this.UITagSelectorMode === 'multi'}
|
||||
groupID="ui-tag-selector-mode"
|
||||
id="multi"
|
||||
width="auto">
|
||||
<FormattedMessage id="settings.ui.tag.selector.mode.multi" />
|
||||
</Radio>
|
||||
</FormRow>
|
||||
<ModalFormSectionHeader>
|
||||
<FormattedMessage id="settings.ui.torrent.list" />
|
||||
</ModalFormSectionHeader>
|
||||
<FormRow>
|
||||
<Radio
|
||||
defaultChecked={this.torrentListViewSize === 'expanded'}
|
||||
groupID="ui-torrent-size"
|
||||
id="expanded"
|
||||
width="auto">
|
||||
<FormattedMessage id="settings.ui.torrent.size.expanded" />
|
||||
</Radio>
|
||||
<Radio
|
||||
defaultChecked={this.torrentListViewSize === 'condensed'}
|
||||
groupID="ui-torrent-size"
|
||||
id="condensed"
|
||||
width="auto">
|
||||
<FormattedMessage id="settings.ui.torrent.size.condensed" />
|
||||
</Radio>
|
||||
</FormRow>
|
||||
<ModalFormSectionHeader>
|
||||
<FormattedMessage id="settings.ui.displayed.details" />
|
||||
</ModalFormSectionHeader>
|
||||
<FormRow>
|
||||
<TorrentListColumnsList
|
||||
torrentListViewSize={this.torrentListViewSize}
|
||||
onSettingsChange={this.props.onSettingsChange}
|
||||
/>
|
||||
</FormRow>
|
||||
<ModalFormSectionHeader>
|
||||
<FormattedMessage id="settings.ui.displayed.context.menu.items" />
|
||||
</ModalFormSectionHeader>
|
||||
<FormRow>
|
||||
<TorrentContextMenuActionsList onSettingsChange={this.props.onSettingsChange} />
|
||||
</FormRow>
|
||||
</Form>
|
||||
);
|
||||
}
|
||||
interface UITabProps {
|
||||
onSettingsChange: (changeSettings: Partial<FloodSettings>) => void;
|
||||
}
|
||||
|
||||
export default injectIntl(UITab);
|
||||
const UITab: FC<UITabProps> = ({onSettingsChange}: UITabProps) => {
|
||||
const intl = useIntl();
|
||||
const [torrentListViewSize, setTorrentListViewSize] = useState(SettingStore.floodSettings.torrentListViewSize);
|
||||
const [selectedLanguage, setSelectedLanguage] = useState(SettingStore.floodSettings.language);
|
||||
const [UITagSelectorMode, setUITagSelectorMode] = useState(SettingStore.floodSettings.UITagSelectorMode);
|
||||
|
||||
return (
|
||||
<Form
|
||||
onChange={({event, formData}) => {
|
||||
const inputElement = event.target as HTMLInputElement;
|
||||
|
||||
if (inputElement.type === 'radio') {
|
||||
setTorrentListViewSize(formData['ui-torrent-size'] as FloodSettings['torrentListViewSize']);
|
||||
setUITagSelectorMode(formData['ui-tag-selector-mode'] as FloodSettings['UITagSelectorMode']);
|
||||
onSettingsChange({
|
||||
torrentListViewSize,
|
||||
UITagSelectorMode,
|
||||
});
|
||||
}
|
||||
|
||||
if (inputElement.name === 'language') {
|
||||
const newSelectedLanguage = formData.language as FloodSettings['language'];
|
||||
if (newSelectedLanguage === 'translate') {
|
||||
SettingStore.saveFloodSettings({language: 'translate'});
|
||||
} else {
|
||||
setSelectedLanguage(newSelectedLanguage);
|
||||
onSettingsChange({
|
||||
language: selectedLanguage,
|
||||
});
|
||||
}
|
||||
}
|
||||
}}>
|
||||
<ModalFormSectionHeader key="locale-header">
|
||||
<FormattedMessage id="settings.ui.language" />
|
||||
</ModalFormSectionHeader>
|
||||
<FormRow key="locale-selection">
|
||||
<Select disabled={selectedLanguage === 'translate'} defaultID={selectedLanguage} id="language">
|
||||
{Object.keys(Languages).map((languageID) => (
|
||||
<SelectItem key={languageID} id={languageID}>
|
||||
{Languages[languageID as 'auto'].id != null
|
||||
? intl.formatMessage({
|
||||
id: Languages[languageID as 'auto'].id,
|
||||
})
|
||||
: Languages[languageID as Language]}
|
||||
</SelectItem>
|
||||
))}
|
||||
</Select>
|
||||
</FormRow>
|
||||
<ModalFormSectionHeader>
|
||||
<FormattedMessage id="settings.ui.tag.selector.mode" />
|
||||
</ModalFormSectionHeader>
|
||||
<FormRow>
|
||||
<Radio defaultChecked={UITagSelectorMode === 'single'} groupID="ui-tag-selector-mode" id="single" width="auto">
|
||||
<FormattedMessage id="settings.ui.tag.selector.mode.single" />
|
||||
</Radio>
|
||||
<Radio defaultChecked={UITagSelectorMode === 'multi'} groupID="ui-tag-selector-mode" id="multi" width="auto">
|
||||
<FormattedMessage id="settings.ui.tag.selector.mode.multi" />
|
||||
</Radio>
|
||||
</FormRow>
|
||||
<ModalFormSectionHeader>
|
||||
<FormattedMessage id="settings.ui.torrent.list" />
|
||||
</ModalFormSectionHeader>
|
||||
<FormRow>
|
||||
<Radio defaultChecked={torrentListViewSize === 'expanded'} groupID="ui-torrent-size" id="expanded" width="auto">
|
||||
<FormattedMessage id="settings.ui.torrent.size.expanded" />
|
||||
</Radio>
|
||||
<Radio
|
||||
defaultChecked={torrentListViewSize === 'condensed'}
|
||||
groupID="ui-torrent-size"
|
||||
id="condensed"
|
||||
width="auto">
|
||||
<FormattedMessage id="settings.ui.torrent.size.condensed" />
|
||||
</Radio>
|
||||
</FormRow>
|
||||
<ModalFormSectionHeader>
|
||||
<FormattedMessage id="settings.ui.displayed.details" />
|
||||
</ModalFormSectionHeader>
|
||||
<FormRow>
|
||||
<TorrentListColumnsList torrentListViewSize={torrentListViewSize} onSettingsChange={onSettingsChange} />
|
||||
</FormRow>
|
||||
<ModalFormSectionHeader>
|
||||
<FormattedMessage id="settings.ui.displayed.context.menu.items" />
|
||||
</ModalFormSectionHeader>
|
||||
<FormRow>
|
||||
<TorrentContextMenuActionsList onSettingsChange={onSettingsChange} />
|
||||
</FormRow>
|
||||
</Form>
|
||||
);
|
||||
};
|
||||
|
||||
export default UITab;
|
||||
|
||||
Reference in New Issue
Block a user