TransferData: migrate to Functional Component

This commit is contained in:
Jesse Chan
2021-01-06 11:20:11 +08:00
parent e9cfb34ad9
commit ce6a6adf68
2 changed files with 76 additions and 120 deletions
@@ -1,108 +1,80 @@
import {observer} from 'mobx-react';
import {FC, useState, useRef, useEffect} from 'react';
import Measure from 'react-measure';
import * as React from 'react';
import {observer} from 'mobx-react';
import {reaction} from 'mobx';
import ClientStatusStore from '../../stores/ClientStatusStore';
import TransferDataStore from '../../stores/TransferDataStore';
import TransferRateDetails from './TransferRateDetails';
import TransferRateGraph from './TransferRateGraph';
import type {TransferRateGraphInspectorPoint} from './TransferRateGraph';
interface TransferDataStates {
graphInspectorPoint: TransferRateGraphInspectorPoint | null;
sidebarWidth: number;
}
const TransferData: FC = observer(() => {
const [graphInspectorPoint, setGraphInspectorPoint] = useState<TransferRateGraphInspectorPoint | null>(null);
const [sidebarWidth, setSidebarWidth] = useState<number>(0);
const rateGraphRef = useRef<TransferRateGraph>(null);
@observer
class TransferData extends React.Component<unknown, TransferDataStates> {
rateGraphRef: TransferRateGraph | null = null;
constructor(props: unknown) {
super(props);
this.state = {
graphInspectorPoint: null,
sidebarWidth: 0,
};
}
handleGraphHover = (graphInspectorPoint: TransferDataStates['graphInspectorPoint']) => {
this.setState({graphInspectorPoint});
};
handleGraphMouseOut = () => {
this.setState({graphInspectorPoint: null});
};
handleMouseMove = (event: React.MouseEvent) => {
if (
this.rateGraphRef != null &&
ClientStatusStore.isConnected &&
event &&
event.nativeEvent &&
event.nativeEvent.clientX != null
) {
this.rateGraphRef.handleMouseMove(event.nativeEvent.clientX);
}
};
handleMouseOut = () => {
if (this.rateGraphRef != null && ClientStatusStore.isConnected) {
this.rateGraphRef.handleMouseOut();
}
};
handleMouseOver = () => {
if (this.rateGraphRef != null && ClientStatusStore.isConnected) {
this.rateGraphRef.handleMouseOver();
}
};
renderTransferRateGraph() {
const {sidebarWidth} = this.state;
if (!ClientStatusStore.isConnected) return null;
return (
<TransferRateGraph
height={150}
id="transfer-rate-graph"
onMouseOut={this.handleGraphMouseOut}
onHover={this.handleGraphHover}
ref={(ref) => {
this.rateGraphRef = ref;
}}
width={sidebarWidth}
/>
useEffect(() => {
const dispose = reaction(
() => TransferDataStore.transferRates,
() => {
if (rateGraphRef.current != null) {
rateGraphRef.current.handleTransferHistoryChange();
}
},
);
}
render() {
const {graphInspectorPoint} = this.state;
return dispose;
}, []);
return (
<Measure
offset
onResize={(contentRect) => {
if (contentRect.offset != null) {
this.setState({sidebarWidth: contentRect.offset.width});
}
}}>
{({measureRef}) => (
<div ref={measureRef} className="client-stats__wrapper sidebar__item">
<div
className="client-stats"
onMouseMove={this.handleMouseMove}
onMouseOut={this.handleMouseOut}
onMouseOver={this.handleMouseOver}>
<TransferRateDetails inspectorPoint={graphInspectorPoint} />
{this.renderTransferRateGraph()}
</div>
return (
<Measure
offset
onResize={(contentRect) => {
if (contentRect.offset != null) {
setSidebarWidth(contentRect.offset.width);
}
}}>
{({measureRef}) => (
<div ref={measureRef} className="client-stats__wrapper sidebar__item">
<div
className="client-stats"
onMouseMove={(event) => {
if (rateGraphRef.current != null && event?.nativeEvent?.clientX != null) {
rateGraphRef.current.handleMouseMove(event.nativeEvent.clientX);
}
}}
onMouseOut={() => {
if (rateGraphRef.current != null) {
rateGraphRef.current.handleMouseOut();
}
}}
onMouseOver={() => {
if (rateGraphRef.current != null) {
rateGraphRef.current.handleMouseOver();
}
}}>
<TransferRateDetails inspectorPoint={graphInspectorPoint} />
{ClientStatusStore.isConnected && (
<TransferRateGraph
height={150}
id="transfer-rate-graph"
onMouseOut={() => {
setGraphInspectorPoint(null);
}}
onHover={(inspectorPoint) => {
setGraphInspectorPoint(inspectorPoint);
}}
ref={rateGraphRef}
width={sidebarWidth}
/>
)}
</div>
)}
</Measure>
);
}
}
</div>
)}
</Measure>
);
});
export default TransferData;
@@ -1,15 +1,20 @@
import {area, curveMonotoneX, line} from 'd3-shape';
import {Component, FC} from 'react';
import {max} from 'd3-array';
import {observer} from 'mobx-react';
import {reaction} from 'mobx';
import {ScaleLinear, scaleLinear} from 'd3-scale';
import {Selection, select} from 'd3-selection';
import * as React from 'react';
import type {TransferDirection} from '@shared/types/TransferData';
import TransferDataStore, {TRANSFER_DIRECTIONS} from '../../stores/TransferDataStore';
const TransferRateGraphGradient: FC<{direction: TransferDirection}> = ({direction}: {direction: TransferDirection}) => (
<linearGradient id={`graph__gradient--${direction}`} x1="0%" y1="0%" x2="0%" y2="100%">
<stop className={`graph__gradient--top graph__gradient--top--${direction}`} offset="0%" />
<stop className={`graph__gradient--bottom graph__gradient--bottom--${direction}`} offset="100%" />
</linearGradient>
);
export interface TransferRateGraphInspectorPoint {
uploadSpeed: number;
downloadSpeed: number;
@@ -24,17 +29,7 @@ interface TransferRateGraphProps {
onMouseOut: () => void;
}
@observer
class TransferRateGraph extends React.Component<TransferRateGraphProps> {
private static getGradient(slug: TransferDirection): React.ReactNode {
return (
<linearGradient id={`graph__gradient--${slug}`} x1="0%" y1="0%" x2="0%" y2="100%">
<stop className={`graph__gradient--top graph__gradient--top--${slug}`} offset="0%" />
<stop className={`graph__gradient--bottom graph__gradient--bottom--${slug}`} offset="100%" />
</linearGradient>
);
}
class TransferRateGraph extends Component<TransferRateGraphProps> {
lastMouseX?: number;
xScale?: ScaleLinear<number, number>;
yScale?: ScaleLinear<number, number>;
@@ -61,17 +56,6 @@ class TransferRateGraph extends React.Component<TransferRateGraphProps> {
width: 240,
};
constructor(props: TransferRateGraphProps) {
super(props);
reaction(
() => TransferDataStore.transferRates,
() => {
this.handleTransferHistoryChange();
},
);
}
componentDidMount(): void {
this.renderGraphData();
}
@@ -263,8 +247,8 @@ class TransferRateGraph extends React.Component<TransferRateGraphProps> {
this.graphRefs.graph = ref;
}}>
<defs>
{TransferRateGraph.getGradient('upload')}
{TransferRateGraph.getGradient('download')}
<TransferRateGraphGradient direction="upload" />
<TransferRateGraphGradient direction="download" />
</defs>
</svg>
);