diff --git a/client/src/javascript/components/sidebar/SpeedLimitDropdown.tsx b/client/src/javascript/components/sidebar/SpeedLimitDropdown.tsx
index 61d216b8..2059e303 100644
--- a/client/src/javascript/components/sidebar/SpeedLimitDropdown.tsx
+++ b/client/src/javascript/components/sidebar/SpeedLimitDropdown.tsx
@@ -1,7 +1,7 @@
-import {defineMessages, FormattedMessage, injectIntl, WrappedComponentProps} from 'react-intl';
+import {FC, useRef} from 'react';
+import {FormattedMessage, IntlShape, useIntl} from 'react-intl';
import {observer} from 'mobx-react';
import sortedIndex from 'lodash/sortedIndex';
-import * as React from 'react';
import type {TransferDirection} from '@shared/types/TransferData';
@@ -14,154 +14,136 @@ import Tooltip from '../general/Tooltip';
import type {DropdownItem} from '../general/form-elements/Dropdown';
-const MESSAGES = defineMessages({
+const HumanReadableSpeed: FC<{bytes: number}> = ({bytes}: {bytes: number}) =>
+ bytes === 0 ? : ;
+
+const getSpeedList = ({
+ intl,
+ direction,
+ speedLimits,
+ throttleGlobalDownSpeed,
+ throttleGlobalUpSpeed,
+}: {
+ intl: IntlShape;
+ direction: TransferDirection;
speedLimits: {
- id: 'sidebar.button.speedlimits',
- },
- download: {
- id: 'sidebar.speedlimits.download',
- },
- upload: {
- id: 'sidebar.speedlimits.upload',
- },
- unlimited: {
- id: 'speed.unlimited',
- },
-});
-
-@observer
-class SpeedLimitDropdown extends React.Component {
- static handleItemSelect(item: DropdownItem) {
- if (item.value != null) {
- if (item.property === 'download') {
- ClientActions.saveSetting('throttleGlobalDownSpeed', item.value);
- } else if (item.property === 'upload') {
- ClientActions.saveSetting('throttleGlobalUpSpeed', item.value);
- }
- }
- }
-
- tooltipRef: Tooltip | null = null;
-
- getDropdownHeader(): React.ReactNode {
- return (
-
- );
- }
-
- getDropdownTrigger(): React.ReactNode {
- const label = this.props.intl.formatMessage(MESSAGES.speedLimits);
-
- return (
- {
- this.tooltipRef = node;
- }}
- wrapperClassName="sidebar__icon-button tooltip__wrapper">
-
-
- );
- }
-
- getHumanReadableSpeed(bytes: number): React.ReactNode {
- if (bytes === 0) {
- return this.props.intl.formatMessage(MESSAGES.unlimited);
- }
- return ;
- }
-
- getSpeedList(direction: TransferDirection): Array> {
- const {speedLimits} = SettingStore.floodSettings;
- const {throttleGlobalDownSpeed = 0, throttleGlobalUpSpeed = 0} = SettingStore.clientSettings || {};
-
- const heading = {
- className: `dropdown__label dropdown__label--${direction}`,
- ...(direction === 'download'
- ? {displayName: this.props.intl.formatMessage(MESSAGES.download)}
- : {displayName: this.props.intl.formatMessage(MESSAGES.upload)}),
- selectable: false,
- value: null,
- };
-
- const currentThrottle: Record = {
- download: throttleGlobalDownSpeed,
- upload: throttleGlobalUpSpeed,
- };
-
- const speeds: number[] = speedLimits[direction];
-
- let insertCurrentThrottle = true;
- const items: Array> = speeds.map((bytes) => {
- let selected = false;
-
- // Check if the current throttle setting exists in the preset speeds list.
- // Determine if we need to add the current throttle setting to the menu.
- if (currentThrottle && currentThrottle[direction] === bytes) {
- selected = true;
- insertCurrentThrottle = false;
- }
-
- return {
- displayName: this.getHumanReadableSpeed(bytes),
- property: direction,
- selected,
- selectable: true,
- value: bytes,
- };
- });
-
- // If the current throttle setting doesn't exist in the pre-set speeds list,
- // add it and show it as selected.
- if (insertCurrentThrottle && currentThrottle) {
- // Find the position to insert the current throttle setting so that it
- // remains sorted from lowest to highest.
- const insertionPoint = sortedIndex(speeds, currentThrottle[direction]);
-
- items.splice(insertionPoint, 0, {
- displayName: this.getHumanReadableSpeed(currentThrottle[direction]),
- property: direction,
- selected: true,
- selectable: true,
- value: currentThrottle[direction],
- });
- }
-
- items.unshift(heading);
-
- return items;
- }
-
- getDropdownMenus() {
- return [this.getSpeedList('download'), this.getSpeedList('upload')];
- }
-
- handleDropdownOpen = () => {
- if (this.tooltipRef != null) {
- this.tooltipRef.dismissTooltip();
- }
+ download: Array;
+ upload: Array;
+ };
+ throttleGlobalDownSpeed: number;
+ throttleGlobalUpSpeed: number;
+}): Array> => {
+ const heading = {
+ className: `dropdown__label dropdown__label--${direction}`,
+ ...(direction === 'download'
+ ? {displayName: intl.formatMessage({id: 'sidebar.speedlimits.download'})}
+ : {displayName: intl.formatMessage({id: 'sidebar.speedlimits.upload'})}),
+ selectable: false,
+ value: null,
};
- render() {
- return (
-
- );
- }
-}
+ const currentThrottle: Record = {
+ download: throttleGlobalDownSpeed,
+ upload: throttleGlobalUpSpeed,
+ };
-export default injectIntl(SpeedLimitDropdown);
+ const speeds: number[] = speedLimits[direction];
+
+ let insertCurrentThrottle = true;
+ const items: Array> = speeds.map((bytes) => {
+ let selected = false;
+
+ // Check if the current throttle setting exists in the preset speeds list.
+ // Determine if we need to add the current throttle setting to the menu.
+ if (currentThrottle && currentThrottle[direction] === bytes) {
+ selected = true;
+ insertCurrentThrottle = false;
+ }
+
+ return {
+ displayName: ,
+ property: direction,
+ selected,
+ selectable: true,
+ value: bytes,
+ };
+ });
+
+ // If the current throttle setting doesn't exist in the pre-set speeds list,
+ // add it and show it as selected.
+ if (insertCurrentThrottle && currentThrottle) {
+ // Find the position to insert the current throttle setting so that it
+ // remains sorted from lowest to highest.
+ const insertionPoint = sortedIndex(speeds, currentThrottle[direction]);
+
+ items.splice(insertionPoint, 0, {
+ displayName: ,
+ property: direction,
+ selected: true,
+ selectable: true,
+ value: currentThrottle[direction],
+ });
+ }
+
+ items.unshift(heading);
+
+ return items;
+};
+
+const SpeedLimitDropdown: FC = observer(() => {
+ const intl = useIntl();
+ const tooltipRef = useRef(null);
+
+ const label = intl.formatMessage({id: 'sidebar.button.speedlimits'});
+ const speedListOptions = {
+ intl,
+ speedLimits: SettingStore.floodSettings.speedLimits,
+ throttleGlobalDownSpeed: SettingStore.clientSettings?.throttleGlobalDownSpeed ?? 0,
+ throttleGlobalUpSpeed: SettingStore.clientSettings?.throttleGlobalUpSpeed ?? 0,
+ };
+
+ return (
+ {
+ if (item.value != null) {
+ if (item.property === 'download') {
+ ClientActions.saveSetting('throttleGlobalDownSpeed', item.value);
+ } else if (item.property === 'upload') {
+ ClientActions.saveSetting('throttleGlobalUpSpeed', item.value);
+ }
+ }
+ }}
+ header={
+
+ }
+ menuItems={[
+ getSpeedList({direction: 'download', ...speedListOptions}),
+ getSpeedList({direction: 'upload', ...speedListOptions}),
+ ]}
+ onOpen={() => {
+ if (tooltipRef.current != null) {
+ tooltipRef.current.dismissTooltip();
+ }
+ }}
+ trigger={
+
+
+
+ }
+ />
+ );
+});
+
+export default SpeedLimitDropdown;