SettingsModal: migrate to Functional Component

This commit is contained in:
Jesse Chan
2021-01-20 22:41:39 +08:00
parent c66dd49518
commit e6448dd851
7 changed files with 429 additions and 431 deletions
@@ -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;