Merge pull request #2596 from lbryio/wallet-backup-buttons-rebase
Rebase of #2587
This commit is contained in:
commit
d27286278a
4 changed files with 101 additions and 3 deletions
|
@ -68,6 +68,7 @@
|
||||||
"@reach/tabs": "^0.1.5",
|
"@reach/tabs": "^0.1.5",
|
||||||
"@reach/tooltip": "^0.2.1",
|
"@reach/tooltip": "^0.2.1",
|
||||||
"@types/three": "^0.93.1",
|
"@types/three": "^0.93.1",
|
||||||
|
"adm-zip": "^0.4.13",
|
||||||
"async-exit-hook": "^2.0.1",
|
"async-exit-hook": "^2.0.1",
|
||||||
"babel-eslint": "^10.0.1",
|
"babel-eslint": "^10.0.1",
|
||||||
"babel-loader": "^8.0.5",
|
"babel-loader": "^8.0.5",
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
// @flow
|
// @flow
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
|
import { shell, remote } from 'electron';
|
||||||
import Button from 'component/button';
|
import Button from 'component/button';
|
||||||
|
import CopyableText from 'component/copyableText';
|
||||||
|
import AdmZip from 'adm-zip';
|
||||||
|
import path from 'path';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
daemonSettings: {
|
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() {
|
render() {
|
||||||
const { daemonSettings } = this.props;
|
const { daemonSettings } = this.props;
|
||||||
const { wallet_dir: lbryumWalletDir } = daemonSettings;
|
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:'
|
'However, it is fairly easy to back up manually. To backup your wallet, make a copy of the folder listed below:'
|
||||||
)}
|
)}
|
||||||
</p>
|
</p>
|
||||||
<p className="card__message">{lbryumWalletDir}</p>
|
<CopyableText copyable={lbryumWalletDir} snackMessage={__('Path copied.')} />
|
||||||
<p>
|
<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.'
|
'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')} />
|
<Button button="link" href="https://lbry.com/faq/how-to-backup-wallet" label={__('see this article')} />
|
||||||
.
|
.
|
||||||
</p>
|
</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="inverse" label={__('Open Folder')} onClick={() => shell.openItem(lbryumWalletDir)} />
|
||||||
|
<Button
|
||||||
|
button="inverse"
|
||||||
|
label={__('Create Backup')}
|
||||||
|
onClick={() => this.backupWalletDir(lbryumWalletDir)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
)}
|
)}
|
||||||
|
|
|
@ -458,5 +458,8 @@
|
||||||
"This will appear as a tip for \"Original LBRY porn - Nude Hot Girl masturbates FREE\".": "This will appear as a tip for \"Original LBRY porn - Nude Hot Girl masturbates FREE\".",
|
"This will appear as a tip for \"Original LBRY porn - Nude Hot Girl masturbates FREE\".": "This will appear as a tip for \"Original LBRY porn - Nude Hot Girl masturbates FREE\".",
|
||||||
"You sent 25 LBC as a tip, Mahalo!": "You sent 25 LBC as a tip, Mahalo!",
|
"You sent 25 LBC as a tip, Mahalo!": "You sent 25 LBC as a tip, Mahalo!",
|
||||||
"LBRY names cannot contain that symbol ($, #, @)": "LBRY names cannot contain that symbol ($, #, @)",
|
"LBRY names cannot contain that symbol ($, #, @)": "LBRY names cannot contain that symbol ($, #, @)",
|
||||||
"Invalid character %s in name: %s.": "Invalid character %s in name: %s."
|
"Invalid character %s in name: %s.": "Invalid character %s in name: %s.",
|
||||||
|
"Path copied.": "Path copied.",
|
||||||
|
"Open Folder": "Open Folder",
|
||||||
|
"Create Backup": "Create Backup"
|
||||||
}
|
}
|
|
@ -1267,6 +1267,11 @@ acorn@^6.0.5, acorn@^6.0.7:
|
||||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.1.1.tgz#7d25ae05bb8ad1f9b699108e1094ecd7884adc1f"
|
resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.1.1.tgz#7d25ae05bb8ad1f9b699108e1094ecd7884adc1f"
|
||||||
integrity sha512-jPTiwtOxaHNaAPg/dmrJ/beuzLRnXtB0kQPQ8JpotKJgTB6rX6c8mlf315941pyjBSaPg8NHXS9fhP4u17DpGA==
|
integrity sha512-jPTiwtOxaHNaAPg/dmrJ/beuzLRnXtB0kQPQ8JpotKJgTB6rX6c8mlf315941pyjBSaPg8NHXS9fhP4u17DpGA==
|
||||||
|
|
||||||
|
adm-zip@^0.4.13:
|
||||||
|
version "0.4.13"
|
||||||
|
resolved "https://registry.yarnpkg.com/adm-zip/-/adm-zip-0.4.13.tgz#597e2f8cc3672151e1307d3e95cddbc75672314a"
|
||||||
|
integrity sha512-fERNJX8sOXfel6qCBCMPvZLzENBEhZTzKqg6vrOW5pvoEaQuJhRU4ndTAh6lHOxn1I6jnz2NHra56ZODM751uw==
|
||||||
|
|
||||||
aes-decrypter@3.0.0:
|
aes-decrypter@3.0.0:
|
||||||
version "3.0.0"
|
version "3.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/aes-decrypter/-/aes-decrypter-3.0.0.tgz#7848a1c145b9fdbf57ae3e2b5b1bc7cf0644a8fb"
|
resolved "https://registry.yarnpkg.com/aes-decrypter/-/aes-decrypter-3.0.0.tgz#7848a1c145b9fdbf57ae3e2b5b1bc7cf0644a8fb"
|
||||||
|
|
Loading…
Reference in a new issue