mirror of
https://github.com/zoriya/flood.git
synced 2026-06-06 20:12:19 +00:00
SpeedLimitDropdown: migrate to Functional Component
This commit is contained in:
@@ -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 ? <FormattedMessage id="speed.unlimited" /> : <Size value={bytes} isSpeed precision={1} />;
|
||||
|
||||
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<WrappedComponentProps> {
|
||||
static handleItemSelect(item: DropdownItem<TransferDirection>) {
|
||||
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 (
|
||||
<button
|
||||
className="sidebar__icon-button sidebar__icon-button--interactive
|
||||
sidebar__icon-button--limits"
|
||||
title={this.props.intl.formatMessage(MESSAGES.speedLimits)}
|
||||
type="button">
|
||||
<LimitsIcon />
|
||||
<FormattedMessage {...MESSAGES.speedLimits} />
|
||||
</button>
|
||||
);
|
||||
}
|
||||
|
||||
getDropdownTrigger(): React.ReactNode {
|
||||
const label = this.props.intl.formatMessage(MESSAGES.speedLimits);
|
||||
|
||||
return (
|
||||
<Tooltip
|
||||
content={label}
|
||||
position="bottom"
|
||||
ref={(node) => {
|
||||
this.tooltipRef = node;
|
||||
}}
|
||||
wrapperClassName="sidebar__icon-button tooltip__wrapper">
|
||||
<LimitsIcon />
|
||||
</Tooltip>
|
||||
);
|
||||
}
|
||||
|
||||
getHumanReadableSpeed(bytes: number): React.ReactNode {
|
||||
if (bytes === 0) {
|
||||
return this.props.intl.formatMessage(MESSAGES.unlimited);
|
||||
}
|
||||
return <Size value={bytes} isSpeed precision={1} />;
|
||||
}
|
||||
|
||||
getSpeedList(direction: TransferDirection): Array<DropdownItem<TransferDirection>> {
|
||||
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<TransferDirection, number> = {
|
||||
download: throttleGlobalDownSpeed,
|
||||
upload: throttleGlobalUpSpeed,
|
||||
};
|
||||
|
||||
const speeds: number[] = speedLimits[direction];
|
||||
|
||||
let insertCurrentThrottle = true;
|
||||
const items: Array<DropdownItem<TransferDirection>> = 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<number>;
|
||||
upload: Array<number>;
|
||||
};
|
||||
throttleGlobalDownSpeed: number;
|
||||
throttleGlobalUpSpeed: number;
|
||||
}): Array<DropdownItem<TransferDirection>> => {
|
||||
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 (
|
||||
<Dropdown
|
||||
dropdownWrapperClass="dropdown dropdown--speed-limits sidebar__action"
|
||||
handleItemSelect={SpeedLimitDropdown.handleItemSelect}
|
||||
header={this.getDropdownHeader()}
|
||||
menuItems={this.getDropdownMenus()}
|
||||
onOpen={this.handleDropdownOpen}
|
||||
trigger={this.getDropdownTrigger()}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
const currentThrottle: Record<TransferDirection, number> = {
|
||||
download: throttleGlobalDownSpeed,
|
||||
upload: throttleGlobalUpSpeed,
|
||||
};
|
||||
|
||||
export default injectIntl(SpeedLimitDropdown);
|
||||
const speeds: number[] = speedLimits[direction];
|
||||
|
||||
let insertCurrentThrottle = true;
|
||||
const items: Array<DropdownItem<TransferDirection>> = 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: <HumanReadableSpeed bytes={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: <HumanReadableSpeed bytes={currentThrottle[direction]} />,
|
||||
property: direction,
|
||||
selected: true,
|
||||
selectable: true,
|
||||
value: currentThrottle[direction],
|
||||
});
|
||||
}
|
||||
|
||||
items.unshift(heading);
|
||||
|
||||
return items;
|
||||
};
|
||||
|
||||
const SpeedLimitDropdown: FC = observer(() => {
|
||||
const intl = useIntl();
|
||||
const tooltipRef = useRef<Tooltip>(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 (
|
||||
<Dropdown
|
||||
dropdownWrapperClass="dropdown dropdown--speed-limits sidebar__action"
|
||||
handleItemSelect={(item) => {
|
||||
if (item.value != null) {
|
||||
if (item.property === 'download') {
|
||||
ClientActions.saveSetting('throttleGlobalDownSpeed', item.value);
|
||||
} else if (item.property === 'upload') {
|
||||
ClientActions.saveSetting('throttleGlobalUpSpeed', item.value);
|
||||
}
|
||||
}
|
||||
}}
|
||||
header={
|
||||
<button
|
||||
className="sidebar__icon-button sidebar__icon-button--interactive
|
||||
sidebar__icon-button--limits"
|
||||
title={label}
|
||||
type="button">
|
||||
<LimitsIcon />
|
||||
{label}
|
||||
</button>
|
||||
}
|
||||
menuItems={[
|
||||
getSpeedList({direction: 'download', ...speedListOptions}),
|
||||
getSpeedList({direction: 'upload', ...speedListOptions}),
|
||||
]}
|
||||
onOpen={() => {
|
||||
if (tooltipRef.current != null) {
|
||||
tooltipRef.current.dismissTooltip();
|
||||
}
|
||||
}}
|
||||
trigger={
|
||||
<Tooltip
|
||||
content={label}
|
||||
position="bottom"
|
||||
ref={tooltipRef}
|
||||
wrapperClassName="sidebar__icon-button tooltip__wrapper">
|
||||
<LimitsIcon />
|
||||
</Tooltip>
|
||||
}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
||||
export default SpeedLimitDropdown;
|
||||
|
||||
Reference in New Issue
Block a user