Skip to content

Commit a4ed048

Browse files
author
Gilyoung
committed
Add copy button to the address item
1 parent 4274411 commit a4ed048

File tree

12 files changed

+148
-8
lines changed

12 files changed

+148
-8
lines changed

package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,14 @@
2323
"npm-run-all": "^4.1.3",
2424
"react": "^16.5.2",
2525
"react-addons-css-transition-group": "^15.6.2",
26+
"react-copy-to-clipboard": "^5.0.1",
2627
"react-dom": "^16.5.2",
2728
"react-modal": "^3.6.1",
2829
"react-redux": "^5.0.7",
2930
"react-router-bootstrap": "^0.24.4",
3031
"react-router-dom": "^4.3.1",
3132
"react-scripts-ts": "3.1.0",
33+
"react-toastify": "^4.4.3",
3234
"reactstrap": "^6.5.0",
3335
"redux-devtools-extension": "^2.13.5",
3436
"redux-thunk": "^2.3.0"
@@ -51,6 +53,7 @@
5153
"@types/node": "^10.11.4",
5254
"@types/react": "^16.4.14",
5355
"@types/react-addons-css-transition-group": "^15.0.5",
56+
"@types/react-copy-to-clipboard": "^4.2.6",
5457
"@types/react-dom": "^16.0.8",
5558
"@types/react-modal": "^3.2.1",
5659
"@types/react-redux": "^6.0.9",

src/components/AddressList/AddressItem/AddressItem.tsx

Lines changed: 60 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import * as React from "react";
2+
import * as CopyToClipboard from "react-copy-to-clipboard";
23
import { connect } from "react-redux";
34
import { RouteComponentProps, withRouter } from "react-router-dom";
5+
import { toast } from "react-toastify";
46
import { Action } from "redux";
57
import { ThunkDispatch } from "redux-thunk";
68
import {
@@ -13,6 +15,10 @@ import walletActions from "../../../redux/wallet/walletActions";
1315
import { getNetworkNameById } from "../../../utils/network";
1416
import { changeQuarkToCCCString } from "../../../utils/unit";
1517
import "./AddressItem.css";
18+
import * as copyBtn from "./img/icons-copy.svg";
19+
import * as copyBtnHover from "./img/icons-copyselect.svg";
20+
import * as mainnet from "./img/mainnet.svg";
21+
import * as testnet from "./img/testnet.svg";
1622

1723
interface OwnProps {
1824
walletAddress: WalletAddress;
@@ -22,16 +28,26 @@ interface OwnProps {
2228
interface DispatchProps {
2329
fetchAccountIfNeed: (address: string) => void;
2430
}
31+
interface State {
32+
isCopyHovering: boolean;
33+
}
2534

2635
type Props = RouteComponentProps & OwnProps & DispatchProps;
2736

28-
class AddressItem extends React.Component<Props> {
37+
class AddressItem extends React.Component<Props, State> {
38+
public constructor(props: Props) {
39+
super(props);
40+
this.state = {
41+
isCopyHovering: false
42+
};
43+
}
2944
public componentDidMount() {
3045
const { walletAddress, fetchAccountIfNeed } = this.props;
3146
fetchAccountIfNeed(walletAddress.address);
3247
}
3348
public render() {
3449
const { walletAddress, className, account } = this.props;
50+
const { isCopyHovering } = this.state;
3551
return (
3652
<div
3753
className={`Address-item mb-3 ${className}`}
@@ -45,9 +61,19 @@ class AddressItem extends React.Component<Props> {
4561
}`}
4662
>
4763
<div className="d-flex network-text-container">
48-
<span className="network-text ml-auto">
49-
{getNetworkNameById(walletAddress.networkId)}
50-
</span>
64+
<div className="ml-auto mb-0 d-flex align-items-center">
65+
<span className="network-text">
66+
{getNetworkNameById(walletAddress.networkId)}
67+
</span>
68+
<img
69+
className="ml-2"
70+
src={`${
71+
walletAddress.networkId === "cc"
72+
? mainnet
73+
: testnet
74+
}`}
75+
/>
76+
</div>
5177
</div>
5278
<div>
5379
<p className="address-name mb-0 mono">
@@ -62,13 +88,26 @@ class AddressItem extends React.Component<Props> {
6288
walletAddress.address.length
6389
)}
6490
</span>
91+
<CopyToClipboard
92+
text={walletAddress.address}
93+
onCopy={this.handleCopyAddress}
94+
>
95+
<img
96+
className="ml-2"
97+
src={isCopyHovering ? copyBtnHover : copyBtn}
98+
onMouseOver={this.hoverCopyBtn}
99+
onMouseOut={this.outCopyBtn}
100+
/>
101+
</CopyToClipboard>
65102
</div>
66103
{walletAddress.type === AddressType.Platform && (
67104
<div className="platform-account">
68-
{account && (
105+
{account ? (
69106
<span className="mono balance">
70107
{changeQuarkToCCCString(account.balance)} CCC
71108
</span>
109+
) : (
110+
<span className="mono balance">Loading...</span>
72111
)}
73112
</div>
74113
)}
@@ -77,12 +116,28 @@ class AddressItem extends React.Component<Props> {
77116
}
78117
private handleClick = () => {
79118
const { walletAddress, history } = this.props;
119+
const { isCopyHovering } = this.state;
120+
if (isCopyHovering) {
121+
return;
122+
}
80123
if (walletAddress.type === AddressType.Platform) {
81124
history.push(`/${walletAddress.address}/account`);
82125
} else {
83126
history.push(`/${walletAddress.address}/assets`);
84127
}
85128
};
129+
private hoverCopyBtn = () => {
130+
this.setState({ isCopyHovering: true });
131+
};
132+
private outCopyBtn = () => {
133+
this.setState({ isCopyHovering: false });
134+
};
135+
private handleCopyAddress = () => {
136+
toast.info("Copied!", {
137+
position: toast.POSITION.BOTTOM_CENTER,
138+
autoClose: 3000
139+
});
140+
};
86141
}
87142

88143
const mapStateToProps = (state: ReducerConfigure, props: OwnProps) => {
Lines changed: 3 additions & 0 deletions
Loading
Lines changed: 6 additions & 0 deletions
Loading
Lines changed: 6 additions & 0 deletions
Loading
Lines changed: 11 additions & 0 deletions
Loading
Lines changed: 12 additions & 0 deletions
Loading

src/components/App/App.scss

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,13 @@
1616
}
1717
}
1818

19+
.custom-toast {
20+
font-size: 16px;
21+
.Toastify__toast {
22+
min-height: 45px;
23+
}
24+
}
25+
1926
.slide-menu-effect-enter {
2027
transform: translate(-101%);
2128
}

src/components/App/App.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import * as ReactCSSTransitionGroup from "react-addons-css-transition-group";
1313
import * as ReactModal from "react-modal";
1414
import { connect } from "react-redux";
1515
import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
16+
import { ToastContainer } from "react-toastify";
1617
import { ReducerConfigure } from "../../redux";
1718
import Account from "../Account/Account";
1819
import AddressList from "../AddressList/AddressList";
@@ -55,6 +56,7 @@ class App extends React.Component<Props, any> {
5556
return (
5657
<Router>
5758
<div id="app" className="app" ref={this.appRef}>
59+
<ToastContainer className="custom-toast" />
5860
{isAuthenticated && <Header />}
5961
<div className="d-flex">
6062
<ReactCSSTransitionGroup

src/components/Header/Header.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,10 @@ class Header extends React.Component<Props, any> {
2424
return (
2525
<div className="Header">
2626
<div className="d-flex align-items-center h-100">
27-
<div className="menu-btn" onClick={this.handleToggleMenu}>
27+
<div
28+
className="menu-btn p-4 ml-3"
29+
onClick={this.handleToggleMenu}
30+
>
2831
<FontAwesomeIcon icon="bars" />
2932
</div>
3033
<Link to="/">

src/index.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import "bootstrap/dist/css/bootstrap.min.css";
22
import * as React from "react";
33
import * as ReactDOM from "react-dom";
44
import { Provider } from "react-redux";
5+
import "react-toastify/dist/ReactToastify.css";
56
import { applyMiddleware, createStore } from "redux";
67
import { composeWithDevTools } from "redux-devtools-extension/logOnlyInProduction";
78
import thunk from "redux-thunk";

yarn.lock

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,12 @@
9090
dependencies:
9191
"@types/react" "*"
9292

93+
"@types/react-copy-to-clipboard@^4.2.6":
94+
version "4.2.6"
95+
resolved "https://registry.yarnpkg.com/@types/react-copy-to-clipboard/-/react-copy-to-clipboard-4.2.6.tgz#d1374550dec803f17f26ec71b62783c5737bfc02"
96+
dependencies:
97+
"@types/react" "*"
98+
9399
"@types/react-dom@^16.0.8":
94100
version "16.0.8"
95101
resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-16.0.8.tgz#6e1366ed629cadf55860cbfcc25db533f5d2fa7d"
@@ -1646,7 +1652,7 @@ class-utils@^0.3.5:
16461652
isobject "^3.0.0"
16471653
static-extend "^0.1.1"
16481654

1649-
classnames@^2.2.3:
1655+
classnames@^2.2.3, classnames@^2.2.6:
16501656
version "2.2.6"
16511657
resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.2.6.tgz#43935bffdd291f326dad0a205309b38d00f650ce"
16521658

@@ -1987,6 +1993,12 @@ copy-descriptor@^0.1.0:
19871993
version "0.1.1"
19881994
resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d"
19891995

1996+
copy-to-clipboard@^3:
1997+
version "3.0.8"
1998+
resolved "https://registry.yarnpkg.com/copy-to-clipboard/-/copy-to-clipboard-3.0.8.tgz#f4e82f4a8830dce4666b7eb8ded0c9bcc313aba9"
1999+
dependencies:
2000+
toggle-selection "^1.0.3"
2001+
19902002
core-js@^2.4.0, core-js@^2.5.0:
19912003
version "2.5.7"
19922004
resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.7.tgz#f972608ff0cead68b841a16a932d0b183791814e"
@@ -6347,6 +6359,13 @@ react-addons-css-transition-group@^15.6.2:
63476359
dependencies:
63486360
react-transition-group "^1.2.0"
63496361

6362+
react-copy-to-clipboard@^5.0.1:
6363+
version "5.0.1"
6364+
resolved "https://registry.yarnpkg.com/react-copy-to-clipboard/-/react-copy-to-clipboard-5.0.1.tgz#8eae107bb400be73132ed3b6a7b4fb156090208e"
6365+
dependencies:
6366+
copy-to-clipboard "^3"
6367+
prop-types "^15.5.8"
6368+
63506369
react-dev-utils@^5.0.2:
63516370
version "5.0.2"
63526371
resolved "https://registry.yarnpkg.com/react-dev-utils/-/react-dev-utils-5.0.2.tgz#7bb68d2c4f6ffe7ed1184c5b0124fcad692774d2"
@@ -6487,6 +6506,14 @@ [email protected]:
64876506
optionalDependencies:
64886507
fsevents "^1.1.3"
64896508

6509+
react-toastify@^4.4.3:
6510+
version "4.4.3"
6511+
resolved "https://registry.yarnpkg.com/react-toastify/-/react-toastify-4.4.3.tgz#bf4a514b4a160e20ad227a95bd84c9853d1f86ca"
6512+
dependencies:
6513+
classnames "^2.2.6"
6514+
prop-types "^15.6.0"
6515+
react-transition-group "^2.4.0"
6516+
64906517
react-transition-group@^1.2.0:
64916518
version "1.2.1"
64926519
resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-1.2.1.tgz#e11f72b257f921b213229a774df46612346c7ca6"
@@ -6497,7 +6524,7 @@ react-transition-group@^1.2.0:
64976524
prop-types "^15.5.6"
64986525
warning "^3.0.0"
64996526

6500-
react-transition-group@^2.3.1:
6527+
react-transition-group@^2.3.1, react-transition-group@^2.4.0:
65016528
version "2.5.0"
65026529
resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-2.5.0.tgz#70bca0e3546102c4dc5cf3f5f57f73447cce6874"
65036530
dependencies:
@@ -7677,6 +7704,10 @@ to-regex@^3.0.1, to-regex@^3.0.2:
76777704
regex-not "^1.0.2"
76787705
safe-regex "^1.1.0"
76797706

7707+
toggle-selection@^1.0.3:
7708+
version "1.0.6"
7709+
resolved "https://registry.yarnpkg.com/toggle-selection/-/toggle-selection-1.0.6.tgz#6e45b1263f2017fa0acc7d89d78b15b8bf77da32"
7710+
76807711
toposort@^1.0.0:
76817712
version "1.0.7"
76827713
resolved "https://registry.yarnpkg.com/toposort/-/toposort-1.0.7.tgz#2e68442d9f64ec720b8cc89e6443ac6caa950029"

0 commit comments

Comments
 (0)