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

449 lines
12 KiB
JavaScript
Raw Normal View History

2020-03-03 15:37:48 +05:00
import React, {Component, createRef} from 'react';
2020-03-10 23:19:16 +05:00
import {View, Text, TouchableOpacity, Modal, ToastAndroid} from 'react-native';
2019-12-14 19:26:44 +05:00
import {SIZE, ph, pv, opacity, WEIGHT} from '../../common/common';
2020-02-11 20:33:36 +05:00
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
2020-01-17 21:05:38 +05:00
import {TextInput} from 'react-native-gesture-handler';
2020-03-03 15:33:33 +05:00
import {db, DDS} from '../../../App';
import {getElevation, ToastEvent} from '../../utils/utils';
2019-12-07 08:41:48 +05:00
2020-01-17 21:05:38 +05:00
import {updateEvent} from '../DialogManager';
2020-03-02 13:52:09 +05:00
import Share from 'react-native-share';
2020-03-10 23:19:16 +05:00
import {
eSendEvent,
eSubscribeEvent,
eUnSubscribeEvent,
} from '../../services/eventManager';
import {
eOnLoadNote,
eOpenVaultDialog,
eCloseVaultDialog,
} from '../../services/events';
2020-03-03 15:25:40 +05:00
import {openEditorAnimation} from '../../utils/animations';
2020-03-03 15:33:33 +05:00
import {ACTIONS} from '../../provider/actions';
2020-03-10 23:19:16 +05:00
2020-03-03 15:37:48 +05:00
const passInputRef = createRef();
2020-03-10 23:19:16 +05:00
const confirmPassRef = createRef();
export const openVault = (
item,
novault = false,
locked = false,
permanant = false,
editor = false,
share = false,
) => {
eSendEvent(eOpenVaultDialog, {
item,
novault,
locked,
permanant,
editor,
share,
});
};
2020-01-17 21:05:38 +05:00
export class VaultDialog extends Component {
constructor(props) {
super(props);
this.state = {
visible: false,
2020-03-10 23:19:16 +05:00
wrongPassword: false,
note: {},
vault: false,
locked: true,
permanant: false,
goToEditor: false,
share: false,
passwordsDontMatch: false,
2020-01-17 21:05:38 +05:00
};
this.password = null;
}
2020-01-17 00:23:16 +05:00
2020-03-10 23:19:16 +05:00
componentDidMount() {
eSubscribeEvent(eOpenVaultDialog, this.open);
eSubscribeEvent(eCloseVaultDialog, this.close);
}
componentWillUnmount() {
eUnSubscribeEvent(eOpenVaultDialog, this.open);
eUnSubscribeEvent(eCloseVaultDialog, this.close);
}
open = ({
item,
novault,
locked,
permanant = false,
goToEditor = false,
share = false,
}) => {
2020-01-17 21:05:38 +05:00
this.setState({
visible: true,
2020-03-10 23:19:16 +05:00
note: item,
novault: novault,
locked,
permanant,
goToEditor,
share,
2020-01-17 21:05:38 +05:00
});
};
2020-03-03 15:33:33 +05:00
2020-03-10 23:19:16 +05:00
close = () => {
2020-03-03 15:33:33 +05:00
updateEvent({type: ACTIONS.NOTES});
2020-03-02 13:52:09 +05:00
this.setState({
visible: false,
2020-03-10 23:19:16 +05:00
note: {},
locked: false,
permanant: false,
goToEditor: false,
share: false,
novault: false,
2020-03-02 13:52:09 +05:00
});
2020-01-17 21:05:38 +05:00
};
onPress = async () => {
2020-03-10 23:19:16 +05:00
if (!this.state.novault) {
if (this.password.length < 3) {
ToastAndroid.show('Password too short', 300);
return;
}
if (
this.password &&
this.password.trim() !== 0 &&
this.state.passwordsDontMatch
) {
ToastAndroid.show('Passwords do not match', 300);
return;
} else {
this._createVault();
}
} else if (this.state.locked) {
if (!this.password || this.password.trim() === 0) {
ToastAndroid.show('Please enter a valid password', 300);
2020-03-03 15:44:31 +05:00
return;
2020-03-10 23:19:16 +05:00
} else {
db.vault
.unlock(this.password)
.then(async () => {
if (this.state.note.locked) {
await this._unlockNote();
} else {
await this._lockNote();
}
})
.catch(e => {
this._takeErrorAction(e);
});
2020-01-17 21:05:38 +05:00
}
2020-03-10 23:19:16 +05:00
}
};
async _lockNote() {
if (!this.password || this.password.trim() === 0) {
ToastAndroid.show('Please enter a valid password', 300);
return;
} else {
db.vault.add(this.state.note.id).then(e => {
this.close();
});
}
}
2020-03-03 15:33:33 +05:00
2020-03-10 23:19:16 +05:00
async _unlockNote() {
if (!this.password || this.password.trim() === 0) {
ToastAndroid.show('Please enter a valid password', 300);
return;
} else {
if (this.state.permanant) {
this._permanantUnlock();
} else {
await this._openNote();
2020-01-17 21:05:38 +05:00
}
2020-03-10 23:19:16 +05:00
}
}
async _openNote() {
let note = await db.vault.open(this.state.note.id, this.password);
if (this.state.goToEditor) {
this._openInEditor(note);
} else if (this.state.share) {
this._shareNote(note);
}
}
async _createVault() {
await db.vault.create(this.password);
if (this.state.note && this.state.note.id && !this.state.note.locked) {
await db.vault.add(this.state.note.id);
this.close();
ToastEvent.show('Note added to vault', 'success');
}
}
_permanantUnlock() {
db.vault
.remove(this.state.note.id, this.password)
.then(() => {
this.close();
})
.catch(e => {
this._takeErrorAction(e);
});
}
_openInEditor(note) {
eSendEvent(eOnLoadNote, note);
if (!DDS.isTab) {
openEditorAnimation();
}
ToastEvent.show('Note unlocked', 'success');
this.close();
}
_shareNote(note) {
let m = `${note.title}\n \n ${note.content.text}`;
Share.open({
title: 'Share note to',
failOnCancel: false,
message: m,
});
this.close();
}
_takeErrorAction(e) {
if (e.message === db.vault.ERRORS.wrongPassword) {
ToastAndroid.show('Password is incorrect', 300);
this.setState({
wrongPassword: true,
});
return;
2020-01-17 21:05:38 +05:00
} else {
2020-03-10 23:19:16 +05:00
console.log('ERROR', e.message);
2020-01-17 21:05:38 +05:00
}
2020-03-10 23:19:16 +05:00
}
2020-01-17 21:05:38 +05:00
render() {
2020-03-10 23:19:16 +05:00
const {colors} = this.props;
const {
note,
visible,
wrongPassword,
passwordsDontMatch,
novault,
locked,
permanant,
goToEditor,
share,
} = this.state;
2020-01-17 21:05:38 +05:00
return (
2020-03-03 15:37:48 +05:00
<Modal
onShow={() => {
passInputRef.current?.focus();
}}
visible={visible}
transparent={true}
onRequestClose={this.close}>
2019-12-07 08:41:48 +05:00
<View
style={{
2020-01-17 21:05:38 +05:00
width: '100%',
height: '100%',
backgroundColor: colors.night
? 'rgba(255,255,255,0.3)'
: 'rgba(0,0,0,0.3)',
justifyContent: 'center',
alignItems: 'center',
2019-12-07 08:41:48 +05:00
}}>
<View
style={{
2020-01-17 21:05:38 +05:00
...getElevation(5),
width: '80%',
maxHeight: 350,
borderRadius: 5,
backgroundColor: colors.bg,
paddingHorizontal: ph,
paddingVertical: pv,
2019-12-07 08:41:48 +05:00
}}>
2020-01-17 21:05:38 +05:00
<View
2019-12-07 08:41:48 +05:00
style={{
2020-01-17 21:05:38 +05:00
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
2019-12-07 08:41:48 +05:00
}}>
2020-01-17 21:05:38 +05:00
<Icon name="shield" color={colors.accent} size={SIZE.lg} />
<Text
style={{
color: colors.accent,
fontFamily: WEIGHT.bold,
marginLeft: 5,
fontSize: SIZE.md,
}}>
2020-03-10 23:19:16 +05:00
{!novault
? 'Create vault'
: note.locked
? 'Unlock Note'
: 'Lock Note'}
2020-01-17 21:05:38 +05:00
</Text>
</View>
2019-12-07 08:41:48 +05:00
2020-01-17 21:05:38 +05:00
<Text
2020-01-05 18:03:40 +05:00
style={{
2020-01-17 21:05:38 +05:00
color: colors.icon,
2020-01-05 18:03:40 +05:00
fontFamily: WEIGHT.regular,
2020-01-17 21:05:38 +05:00
textAlign: 'center',
fontSize: SIZE.sm - 1,
2020-03-10 23:19:16 +05:00
flexWrap: 'wrap',
maxWidth: '90%',
alignSelf: 'center',
2020-01-17 21:05:38 +05:00
marginTop: 10,
}}>
2020-03-10 23:19:16 +05:00
{!novault
? 'Set a password to create vault'
: permanant
? 'Enter password to remove note from vault.'
2020-01-17 21:05:38 +05:00
: note.locked
? 'Enter vault password to unlock note.'
: 'Do you want to lock this note?'}
</Text>
2020-01-05 18:03:40 +05:00
2020-03-10 23:19:16 +05:00
{note.locked || locked || permanant ? (
2019-12-07 08:41:48 +05:00
<TextInput
2020-03-03 15:37:48 +05:00
ref={passInputRef}
2019-12-07 08:41:48 +05:00
style={{
padding: pv - 5,
borderWidth: 1.5,
2020-03-10 23:19:16 +05:00
borderColor: this.state.wrongPassword
? colors.errorText
: colors.nav,
2019-12-07 08:41:48 +05:00
paddingHorizontal: ph,
borderRadius: 5,
2020-01-17 21:05:38 +05:00
marginTop: 10,
2019-12-07 08:41:48 +05:00
fontSize: SIZE.sm,
fontFamily: WEIGHT.regular,
}}
2020-01-17 21:05:38 +05:00
onChangeText={value => {
2020-03-03 15:33:33 +05:00
this.password = value;
2020-01-17 21:05:38 +05:00
}}
secureTextEntry
2019-12-07 08:41:48 +05:00
placeholder="Password"
placeholderTextColor={colors.icon}
/>
2020-01-17 21:05:38 +05:00
) : null}
2019-12-07 08:41:48 +05:00
2020-03-10 23:19:16 +05:00
{!novault ? (
2020-01-17 21:05:38 +05:00
<View>
<TextInput
2020-03-10 23:19:16 +05:00
ref={passInputRef}
2020-01-17 21:05:38 +05:00
style={{
padding: pv - 5,
borderWidth: 1.5,
2020-03-10 23:19:16 +05:00
borderColor: passwordsDontMatch
? colors.errorText
: colors.nav,
2020-01-17 21:05:38 +05:00
paddingHorizontal: ph,
borderRadius: 5,
fontSize: SIZE.sm,
fontFamily: WEIGHT.regular,
}}
2020-03-10 23:19:16 +05:00
onChangeText={value => {
this.password = value;
}}
secureTextEntry
2020-01-17 21:05:38 +05:00
placeholder="Password"
placeholderTextColor={colors.icon}
/>
2019-12-07 08:41:48 +05:00
2020-01-17 21:05:38 +05:00
<TextInput
2020-03-10 23:19:16 +05:00
ref={confirmPassRef}
2020-01-17 21:05:38 +05:00
style={{
padding: pv - 5,
borderWidth: 1.5,
2020-03-10 23:19:16 +05:00
borderColor: passwordsDontMatch
? colors.errorText
: colors.nav,
2020-01-17 21:05:38 +05:00
paddingHorizontal: ph,
borderRadius: 5,
fontSize: SIZE.sm,
fontFamily: WEIGHT.regular,
marginTop: 10,
}}
2020-03-10 23:19:16 +05:00
secureTextEntry
onChangeText={value => {
if (value !== this.password) {
this.setState({
passwordsDontMatch: true,
});
} else {
this.setState({
passwordsDontMatch: false,
});
}
2020-01-17 21:05:38 +05:00
}}
2020-03-10 23:19:16 +05:00
placeholder="Confirm password"
2020-01-17 21:05:38 +05:00
placeholderTextColor={colors.icon}
/>
</View>
2020-03-10 23:19:16 +05:00
) : null}
2020-01-05 18:03:40 +05:00
2020-01-17 21:05:38 +05:00
<View
2019-12-07 08:41:48 +05:00
style={{
2020-01-17 21:05:38 +05:00
justifyContent: 'space-around',
2019-12-07 08:41:48 +05:00
alignItems: 'center',
2020-01-17 21:05:38 +05:00
flexDirection: 'row',
marginTop: 20,
2019-12-07 08:41:48 +05:00
}}>
2020-01-17 21:05:38 +05:00
<TouchableOpacity
activeOpacity={opacity}
onPress={this.onPress}
2020-03-10 23:19:16 +05:00
secureTextEntry
2019-12-07 08:41:48 +05:00
style={{
2020-01-17 21:05:38 +05:00
paddingVertical: pv,
paddingHorizontal: ph,
borderRadius: 5,
width: '45%',
justifyContent: 'center',
alignItems: 'center',
borderColor: colors.accent,
backgroundColor: colors.accent,
borderWidth: 1,
2019-12-07 08:41:48 +05:00
}}>
2020-01-17 21:05:38 +05:00
<Text
style={{
fontFamily: WEIGHT.medium,
color: 'white',
fontSize: SIZE.sm,
}}>
{note.locked ? 'Unlock' : 'Lock'}
</Text>
</TouchableOpacity>
2019-12-07 08:41:48 +05:00
2020-01-17 21:05:38 +05:00
<TouchableOpacity
activeOpacity={opacity}
onPress={this.close}
2019-12-07 08:41:48 +05:00
style={{
2020-01-17 21:05:38 +05:00
paddingVertical: pv,
paddingHorizontal: ph,
borderRadius: 5,
width: '45%',
justifyContent: 'center',
alignItems: 'center',
backgroundColor: colors.nav,
2019-12-07 08:41:48 +05:00
}}>
2020-01-17 21:05:38 +05:00
<Text
style={{
fontFamily: WEIGHT.medium,
color: colors.icon,
fontSize: SIZE.sm,
}}>
Cancel
</Text>
</TouchableOpacity>
</View>
2019-12-07 08:41:48 +05:00
</View>
</View>
2020-01-17 21:05:38 +05:00
</Modal>
);
}
}