From 17efd0f8f19e028928c02c9a42cd91bdffcb28db Mon Sep 17 00:00:00 2001 From: Jesse Chan Date: Mon, 11 Jan 2021 13:18:29 +0800 Subject: [PATCH] SpeedLimitDropdown: migrate to Functional Component --- .../components/sidebar/SpeedLimitDropdown.tsx | 280 ++++++++---------- 1 file changed, 131 insertions(+), 149 deletions(-) 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;