Files
notesnook/apps/mobile/src/components/RecoveryKeyDialog/index.js

267 lines
7.3 KiB
JavaScript
Raw Normal View History

2020-09-24 17:39:53 +05:00
import React, {createRef} from 'react';
import {Clipboard, Text, View} from 'react-native';
import QRCode from 'react-native-qrcode-svg';
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
import RNFetchBlob from 'rn-fetch-blob';
import {LOGO_BASE64} from '../../assets/images/assets';
2020-10-28 11:26:58 +05:00
import {
2020-10-28 15:15:35 +05:00
eSendEvent,
2020-10-28 11:26:58 +05:00
eSubscribeEvent,
eUnSubscribeEvent,
ToastEvent,
} from '../../services/EventManager';
2020-10-28 15:15:35 +05:00
import {eOpenRecoveryKeyDialog, eOpenResultDialog} from '../../utils/Events';
2020-10-13 17:02:14 +05:00
import {dWidth} from '../../utils';
2020-09-24 17:39:53 +05:00
import ActionSheet from '../ActionSheet';
import {Button} from '../Button';
import Seperator from '../Seperator';
import {Toast} from '../Toast';
2020-10-28 11:26:58 +05:00
import {SIZE, WEIGHT} from '../../utils/SizeUtils';
import {db} from '../../utils/DB';
import Storage from '../../utils/storage';
2020-09-24 17:39:53 +05:00
class RecoveryKeyDialog extends React.Component {
constructor(props) {
super(props);
this.state = {
key: null,
2020-09-24 17:39:53 +05:00
};
this.actionSheetRef = createRef();
this.svg = createRef();
2020-10-28 11:26:58 +05:00
this.user;
2020-10-28 15:15:35 +05:00
this.signup = false;
2020-09-24 17:39:53 +05:00
}
2020-10-28 15:15:35 +05:00
open = (signup) => {
if (signup) {
this.signup = true;
}
2020-09-24 17:39:53 +05:00
this.actionSheetRef.current?._setModalVisible(true);
};
close = () => {
this.actionSheetRef.current?._setModalVisible(false);
2020-10-28 15:52:15 +05:00
if (this.signup) {
2020-10-28 15:15:35 +05:00
setTimeout(() => {
eSendEvent(eOpenResultDialog, {
title: 'Welcome!',
paragraph: 'Your 14 day trial for Notesnook Pro is activated',
icon: 'checkbox-marked-circle',
button: 'Thank You!',
});
}, 500);
}
2020-09-24 17:39:53 +05:00
};
async componentDidMount() {
eSubscribeEvent(eOpenRecoveryKeyDialog, this.open);
}
async componentWillUnmount() {
eUnSubscribeEvent(eOpenRecoveryKeyDialog, this.open);
}
2020-10-28 11:26:58 +05:00
saveQRCODE = async () => {
if ((await Storage.requestPermission()) === false) {
ToastEvent.show('Storage access not granted!', 'error', 'local');
return;
}
2020-09-24 17:39:53 +05:00
2020-10-28 11:26:58 +05:00
this.svg.current?.toDataURL(async (data) => {
let path = await Storage.checkAndCreateDir('/');
let fileName = 'nn_' + this.user.username + '_recovery_key_qrcode.png';
RNFetchBlob.fs.writeFile(path + fileName, data, 'base64').then((res) => {
RNFetchBlob.fs
.scanFile([
{
path: path + fileName,
mime: 'image/png',
},
])
.then((r) => {
ToastEvent.show(
'Recovery key saved to Gallery as ' + path + fileName,
'success',
'local',
);
});
});
2020-09-24 17:39:53 +05:00
});
};
2020-10-28 11:26:58 +05:00
saveToTextFile = async () => {
if ((await Storage.requestPermission()) === false) {
ToastEvent.show('Storage access not granted!', 'error', 'local');
return;
}
let path = await Storage.checkAndCreateDir('/');
let fileName = 'nn_' + this.user.username + '_recovery_key.txt';
RNFetchBlob.fs
.writeFile(path + fileName, this.state.key, 'utf8')
.then((r) => {
ToastEvent.show(
'Recovery key saved as ' + path + fileName,
'success',
'local',
);
})
.catch((e) => {});
};
onOpen = async () => {
let k = await db.user.key();
this.user = await db.user.get();
console.log(k);
if (k) {
this.setState({
key: k.key,
});
}
};
2020-09-24 17:39:53 +05:00
render() {
const {colors} = this.props;
return (
<ActionSheet
containerStyle={{
backgroundColor: colors.bg,
width: '100%',
alignSelf: 'center',
borderRadius: 10,
}}
2020-10-28 15:15:35 +05:00
closeOnTouchBackdrop={false}
2020-10-28 11:26:58 +05:00
onOpen={this.onOpen}
2020-09-24 17:39:53 +05:00
ref={this.actionSheetRef}
initialOffsetFromBottom={1}>
<View
style={{
2020-10-13 17:02:14 +05:00
width: dWidth,
2020-09-24 17:39:53 +05:00
backgroundColor: colors.bg,
justifyContent: 'space-between',
paddingHorizontal: 12,
borderRadius: 10,
paddingTop: 10,
}}>
2020-09-24 23:01:35 +05:00
<Text
numberOfLines={2}
style={{
fontFamily: WEIGHT.bold,
fontSize: SIZE.xl,
width: '85%',
maxWidth: '85%',
paddingRight: 10,
marginTop: 10,
color: colors.heading,
}}>
Your Recovery Key
</Text>
2020-09-24 17:39:53 +05:00
<View
style={{
2020-09-24 23:01:35 +05:00
backgroundColor: colors.nav,
2020-09-24 17:39:53 +05:00
borderRadius: 5,
2020-09-24 23:01:35 +05:00
padding: 10,
marginTop: 10,
2020-09-24 17:39:53 +05:00
}}>
<Text
numberOfLines={2}
style={{
fontFamily: WEIGHT.regular,
fontSize: SIZE.md,
width: '100%',
maxWidth: '100%',
paddingRight: 10,
color: colors.icon,
}}>
{this.state.key}
</Text>
2020-09-24 23:01:35 +05:00
</View>
<Seperator />
<View
style={{
alignSelf: 'center',
marginBottom: 15,
flexDirection: 'row',
width: '100%',
justifyContent: 'space-between',
}}>
{this.state.key ? (
<QRCode
getRef={this.svg}
2020-10-13 17:02:14 +05:00
size={dWidth / 2.2}
value={this.state.key}
logo={{uri: LOGO_BASE64}}
logoBorderRadius={10}
/>
) : null}
2020-09-24 23:01:35 +05:00
2020-09-24 17:39:53 +05:00
<Seperator />
<View
style={{
2020-09-24 23:01:35 +05:00
alignItems: 'center',
2020-10-13 17:02:14 +05:00
width: dWidth / 2.2,
2020-09-24 23:01:35 +05:00
justifyContent: 'center',
2020-09-24 17:39:53 +05:00
}}>
2020-09-24 23:01:35 +05:00
<Button
title="Save to Gallery"
onPress={this.saveQRCODE}
width="100%"
height={40}
/>
<Seperator />
2020-09-24 17:39:53 +05:00
<Button
2020-10-28 11:26:58 +05:00
onPress={this.saveToTextFile}
2020-09-24 23:01:35 +05:00
title="Save as Text File"
width="100%"
height={40}
2020-09-24 17:39:53 +05:00
/>
2020-09-24 23:01:35 +05:00
<Seperator />
2020-09-24 17:39:53 +05:00
<Button
onPress={() => {
Clipboard.setString(this.state.key);
2020-10-28 11:26:58 +05:00
ToastEvent.show('Copied!', 'success', 'local');
2020-09-24 17:39:53 +05:00
}}
2020-09-24 23:01:35 +05:00
title="Copy Key"
width="100%"
height={40}
2020-09-24 17:39:53 +05:00
/>
</View>
</View>
<Seperator />
<View
style={{
flexDirection: 'row',
padding: 10,
borderRadius: 10,
}}>
<Icon color={colors.errorText} size={SIZE.lg} name="alert-circle" />
<Text
style={{
color: colors.errorText,
fontFamily: WEIGHT.regular,
marginLeft: 10,
fontSize: SIZE.sm,
width: '90%',
}}>
We request you to save your recovery key and keep it in multiple
places. If you forget your password, you can only recover your
data or reset your password using this recovery key.
</Text>
</View>
2020-10-28 15:15:35 +05:00
<Seperator />
<Button
title="I have saved the key."
width="100%"
height={50}
onPress={this.close}
/>
2020-09-24 17:39:53 +05:00
<Toast context="local" />
</View>
</ActionSheet>
);
}
}
export default RecoveryKeyDialog;