2019-05-14 04:51:33 +02:00
|
|
|
// @flow
|
|
|
|
import * as React from 'react';
|
2022-01-02 21:33:11 +01:00
|
|
|
import { shell } from 'electron';
|
|
|
|
import * as remote from '@electron/remote';
|
2019-05-14 04:51:33 +02:00
|
|
|
import Button from 'component/button';
|
2019-07-01 23:00:20 +02:00
|
|
|
import CopyableText from 'component/copyableText';
|
2019-06-21 23:29:22 +02:00
|
|
|
import AdmZip from 'adm-zip';
|
|
|
|
import path from 'path';
|
2019-09-27 22:03:05 +02:00
|
|
|
import Card from 'component/common/card';
|
2019-10-01 06:53:33 +02:00
|
|
|
import I18nMessage from 'component/i18nMessage';
|
2019-05-14 04:51:33 +02:00
|
|
|
|
|
|
|
type Props = {
|
|
|
|
daemonSettings: {
|
|
|
|
wallet_dir: ?string,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2019-06-21 23:29:22 +02:00
|
|
|
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) {
|
2019-07-21 23:31:22 +02:00
|
|
|
console.error(err); // eslint-disable-line no-console
|
2019-06-21 23:29:22 +02:00
|
|
|
this.showErrorMessage(__('The wallet folder could not be added to the zip archive.'));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
try {
|
|
|
|
zip.writeZip(outputPath);
|
|
|
|
} catch (err) {
|
2019-07-21 23:31:22 +02:00
|
|
|
console.error(err); // eslint-disable-line no-console
|
2019-06-21 23:29:22 +02:00
|
|
|
this.showErrorMessage(__('There was a problem writing the zip archive to disk.'));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-12-10 20:49:00 +01:00
|
|
|
this.showSuccessMessage(__('Saved zip archive to %outputPath%', { outputPath }));
|
2019-06-21 23:29:22 +02:00
|
|
|
|
|
|
|
shell.showItemInFolder(outputPath);
|
|
|
|
}
|
|
|
|
|
2019-05-14 04:51:33 +02:00
|
|
|
render() {
|
2019-07-21 23:31:22 +02:00
|
|
|
const { daemonSettings = {} } = this.props;
|
2019-05-14 04:51:33 +02:00
|
|
|
const { wallet_dir: lbryumWalletDir } = daemonSettings;
|
|
|
|
|
|
|
|
return (
|
2019-09-27 22:03:05 +02:00
|
|
|
<Card
|
2020-08-26 22:28:33 +02:00
|
|
|
title={__('Backup your LBRY wallet')}
|
2019-09-27 22:03:05 +02:00
|
|
|
subtitle={
|
|
|
|
<ul>
|
|
|
|
<li>
|
|
|
|
{__(
|
2020-09-02 22:08:37 +02:00
|
|
|
'Your LBRY Credits, channels, and publishes are controllable by you and only you, via wallet file(s) stored locally on your computer.'
|
2019-09-27 22:03:05 +02:00
|
|
|
)}
|
|
|
|
</li>
|
|
|
|
<li>
|
|
|
|
{__(
|
2019-11-01 18:27:01 +01:00
|
|
|
'If Sync is on, LBRY will backup your wallet and preferences. If disabled, you are responsible for keeping a backup.'
|
2019-09-27 22:03:05 +02:00
|
|
|
)}
|
|
|
|
</li>
|
|
|
|
<li>
|
|
|
|
{__(
|
2019-10-01 06:53:33 +02:00
|
|
|
'However, it is easy to back up manually. To backup your wallet, make a copy of the folder listed below:'
|
2019-09-27 22:03:05 +02:00
|
|
|
)}
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
|
|
}
|
|
|
|
actions={
|
|
|
|
<React.Fragment>
|
|
|
|
<CopyableText copyable={lbryumWalletDir} snackMessage={__('Path copied.')} />
|
|
|
|
<p className="help">
|
2019-10-01 06:53:33 +02:00
|
|
|
<I18nMessage
|
|
|
|
tokens={{
|
|
|
|
helpLink: (
|
|
|
|
<Button
|
|
|
|
button="link"
|
|
|
|
href="https://lbry.com/faq/how-to-backup-wallet"
|
|
|
|
label={__('see this article')}
|
|
|
|
/>
|
|
|
|
),
|
|
|
|
}}
|
|
|
|
>
|
2020-09-04 19:14:48 +02:00
|
|
|
Access to these files are equivalent to having access to your Credits, channels, and publishes. Keep any
|
2020-08-26 22:28:33 +02:00
|
|
|
copies you make of your wallet in a secure place. For more details on backing up and best practices
|
|
|
|
%helpLink%.
|
2019-10-01 06:53:33 +02:00
|
|
|
</I18nMessage>
|
2019-09-27 22:03:05 +02:00
|
|
|
</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
|
2019-12-09 18:25:13 +01:00
|
|
|
button="primary"
|
2019-09-27 22:03:05 +02:00
|
|
|
label={__('Create Backup')}
|
|
|
|
onClick={() => this.backupWalletDir(lbryumWalletDir)}
|
|
|
|
/>
|
2020-10-16 01:06:05 +02:00
|
|
|
<Button button="link" label={__('Open Folder')} onClick={() => shell.openPath(lbryumWalletDir)} />
|
2019-09-27 22:03:05 +02:00
|
|
|
</div>
|
|
|
|
</React.Fragment>
|
|
|
|
}
|
|
|
|
/>
|
2019-05-14 04:51:33 +02:00
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export default WalletBackup;
|