Copy path, open, and backup buttons for wallet on Help page #2587
2 changed files with 92 additions and 2 deletions
|
@ -68,6 +68,7 @@
|
|||
"@reach/tabs": "^0.1.5",
|
||||
"@reach/tooltip": "^0.2.1",
|
||||
"@types/three": "^0.93.1",
|
||||
"adm-zip": "^0.4.13",
|
||||
"async-exit-hook": "^2.0.1",
|
||||
"babel-eslint": "^10.0.1",
|
||||
"babel-loader": "^8.0.5",
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
// @flow
|
||||
import * as React from 'react';
|
||||
import { shell, remote } from 'electron';
|
||||
import Button from 'component/button';
|
||||
import CopyableText from 'component/copyableText';
|
||||
import AdmZip from 'adm-zip';
|
||||
import path from 'path';
|
||||
|
||||
type Props = {
|
||||
daemonSettings: {
|
||||
|
@ -8,7 +12,78 @@ type Props = {
|
|||
},
|
||||
};
|
||||
|
||||
class WalletBackup extends React.PureComponent<Props> {
|
||||
type State = {
|
||||
errorMessage: ?string,
|
||||
successMessage: ?string,
|
||||
};
|
||||
|
||||
class WalletBackup extends React.PureComponent<Props, State> {
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
errorMessage: null,
|
||||
successMessage: null,
|
||||
};
|
||||
}
|
||||
|
||||
showErrorMessage(message: string) {
|
||||
this.setState({ errorMessage: message });
|
||||
}
|
||||
|
||||
showSuccessMessage(message: string) {
|
||||
this.setState({ successMessage: message });
|
||||
}
|
||||
|
||||
clearMessages() {
|
||||
this.setState({ errorMessage: null, successMessage: null });
|
||||
}
|
||||
|
||||
backupWalletDir(lbryumWalletDir: ?string) {
|
||||
this.clearMessages();
|
||||
|
||||
if (!lbryumWalletDir) {
|
||||
this.showErrorMessage(__('No wallet folder was found.'));
|
||||
return;
|
||||
}
|
||||
|
||||
// Colon fails on Windows. Backups should be portable, so replace it on other platforms, too.
|
||||
const filenameTime = new Date().toISOString().replace(/:/g, '-');
|
||||
|
||||
const outputFilename = [path.basename(lbryumWalletDir), '-', filenameTime, '.zip'].join('');
|
||||
|
||||
// Prefer placing backup in user's Downloads folder, then their home folder, and finally
|
||||
// right next to the lbryum folder itself.
|
||||
let outputDir = path.dirname(lbryumWalletDir);
|
||||
if (remote && remote.app) {
|
||||
outputDir = remote.app.getPath('downloads') || remote.app.getPath('home') || outputDir;
|
||||
}
|
||||
|
||||
const outputPath = path.join(outputDir, outputFilename);
|
||||
|
||||
const zip = new AdmZip();
|
||||
|
||||
try {
|
||||
zip.addLocalFolder(lbryumWalletDir);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
this.showErrorMessage(__('The wallet folder could not be added to the zip archive.'));
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
zip.writeZip(outputPath);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
this.showErrorMessage(__('There was a problem writing the zip archive to disk.'));
|
||||
return;
|
||||
}
|
||||
|
||||
this.showSuccessMessage(__('Saved zip archive to ' + outputPath));
|
||||
|
||||
shell.showItemInFolder(outputPath);
|
||||
}
|
||||
|
||||
render() {
|
||||
const { daemonSettings } = this.props;
|
||||
const { wallet_dir: lbryumWalletDir } = daemonSettings;
|
||||
|
@ -44,7 +119,7 @@ class WalletBackup extends React.PureComponent<Props> {
|
|||
'However, it is fairly easy to back up manually. To backup your wallet, make a copy of the folder listed below:'
|
||||
)}
|
||||
</p>
|
||||
<p className="card__message">{lbryumWalletDir}</p>
|
||||
<CopyableText copyable={lbryumWalletDir} snackMessage={__('Path copied.')} />
|
||||
<p>
|
||||
{__(
|
||||
'Access to these files are equivalent to having access to your credits. Keep any copies you make of your wallet in a secure place.'
|
||||
|
@ -55,6 +130,20 @@ class WalletBackup extends React.PureComponent<Props> {
|
|||
<Button button="link" href="https://lbry.com/faq/how-to-backup-wallet" label={__('see this article')} />
|
||||
.
|
||||
</p>
|
||||
<p className={'card__message card__message--error' + (this.state.errorMessage ? '' : ' hidden')}>
|
||||
{this.state.errorMessage}
|
||||
</p>
|
||||
<p className={'card__message card__message--success' + (this.state.successMessage ? '' : ' hidden')}>
|
||||
{this.state.successMessage}
|
||||
</p>
|
||||
<div className="card__actions">
|
||||
<Button button="primary" label={__('Open Folder')} onClick={() => shell.openItem(lbryumWalletDir)} />
|
||||
<Button
|
||||
button="primary"
|
||||
label={__('Create Backup')}
|
||||
onClick={() => this.backupWalletDir(lbryumWalletDir)}
|
||||
/>
|
||||
Madiator2011
commented
Hi @seanyesmunt , when looking through the source for other uses of doToast, I noticed some components (like the wallet address) use a CopyableText component that provides the copy button right next to the text field. I have replaced the copy button I added with the use of this CopyableText component. Also, I thought I should mention, I haven't been able to test on the master branch due to an Thanks! Hi @seanyesmunt , when looking through the source for other uses of doToast, I noticed some components (like the wallet address) use a CopyableText component that provides the copy button right next to the text field. I have replaced the copy button I added with the use of this CopyableText component.
Also, I thought I should mention, I haven't been able to test on the master branch due to an `npm install` error referencing an unknown commit in lbry-redux: b3bf3f6d53410ff1c5415b51ca425341e364959f, so I've been testing on 0.33.2 for now.
Thanks!
@jcamp0x2a sorry about that. I just pushed a commit that fixes that. Should be good to go now. @jcamp0x2a sorry about that. I just pushed a commit that fixes that. Should be good to go now.
|
||||
</div>
|
||||
</div>
|
||||
</React.Fragment>
|
||||
)}
|
||||
|
|
Loading…
Reference in a new issue
Instead of showing the success message for copy, lets use
doToast({ message: "..." })
, that's what we use for other places that have a copy button. It also won't remove the success message after creating a backup.