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

406 lines
11 KiB
JavaScript
Raw Normal View History

2020-09-09 11:10:35 +05:00
import React, {Component, createRef} from 'react';
import {Modal, Text, View} from 'react-native';
import {TextInput} from 'react-native-gesture-handler';
2020-03-02 13:52:09 +05:00
import Share from 'react-native-share';
2020-03-21 10:03:11 +05:00
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
2020-10-13 17:02:14 +05:00
import {Actions} from '../../provider/Actions';
2020-03-10 23:19:16 +05:00
import {
2020-10-13 17:02:14 +05:00
eSendEvent,
eSubscribeEvent,
eUnSubscribeEvent, ToastEvent,
} from '../../services/EventManager';
2020-03-10 23:19:16 +05:00
import {
2020-03-21 10:03:11 +05:00
eCloseVaultDialog,
2020-03-10 23:19:16 +05:00
eOnLoadNote,
eOpenVaultDialog,
2020-03-14 12:13:00 +05:00
refreshNotesPage,
2020-10-13 17:02:14 +05:00
} from '../../utils/Events';
import {openEditorAnimation} from '../../utils/Animations';
import {getElevation} from '../../utils';
2020-09-09 11:10:35 +05:00
import {Button} from '../Button/index';
2020-09-27 13:05:26 +05:00
import BaseDialog from '../Dialog/base-dialog';
import DialogButtons from '../Dialog/dialog-buttons';
import DialogHeader from '../Dialog/dialog-header';
2020-09-09 11:10:35 +05:00
import {updateEvent} from '../DialogManager/recievers';
import {Toast} from '../Toast';
2020-10-13 17:02:14 +05:00
import {ph, pv, SIZE, WEIGHT} from "../../utils/SizeUtils";
import {db} from "../../utils/DB";
import {DDS} from "../../services/DeviceDetection";
2020-03-03 15:37:48 +05:00
const passInputRef = createRef();
2020-03-10 23:19:16 +05:00
const confirmPassRef = createRef();
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-03-14 12:13:00 +05:00
deleteNote: false,
2020-01-17 21:05:38 +05:00
};
this.password = null;
2020-03-17 15:09:15 +05:00
this.confirmPassword = null;
2020-01-17 21:05:38 +05:00
}
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-03-14 12:13:00 +05:00
deleteNote = false,
2020-03-10 23:19:16 +05:00
}) => {
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-03-14 12:13:00 +05:00
deleteNote,
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-10-13 17:02:14 +05:00
updateEvent({type: Actions.NOTES});
2020-03-03 15:33:33 +05:00
2020-03-19 11:05:52 +05:00
this.password = null;
this.confirmPassword = null;
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-14 12:13:00 +05:00
deleteNote: false,
2020-03-19 11:05:52 +05:00
passwordsDontMatch: 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) {
2020-03-14 12:59:52 +05:00
ToastEvent.show('Password too short', 'error', 'local');
2020-03-10 23:19:16 +05:00
return;
}
2020-03-17 15:09:15 +05:00
if (this.password !== this.confirmPassword) {
2020-03-14 12:59:52 +05:00
ToastEvent.show('Passwords do not match', 'error', 'local');
2020-03-17 15:09:15 +05:00
this.setState({
passwordsDontMatch: true,
});
2020-03-10 23:19:16 +05:00
return;
}
2020-03-17 15:09:15 +05:00
this._createVault();
2020-03-10 23:19:16 +05:00
} else if (this.state.locked) {
if (!this.password || this.password.trim() === 0) {
2020-03-14 12:59:52 +05:00
ToastEvent.show('Password is invalid', 'error', 'local');
2020-03-14 12:13:00 +05:00
this.setState({
wrongPassword: true,
});
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 () => {
2020-03-14 12:13:00 +05:00
this.setState({
wrongPassword: false,
});
2020-03-10 23:19:16 +05:00
if (this.state.note.locked) {
await this._unlockNote();
} else {
await this._lockNote();
}
})
2020-09-09 11:10:35 +05:00
.catch((e) => {
2020-03-10 23:19:16 +05:00
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) {
2020-03-14 12:59:52 +05:00
ToastEvent.show('Password is invalid', 'error', 'local');
2020-03-10 23:19:16 +05:00
return;
} else {
2020-09-09 11:10:35 +05:00
db.vault.add(this.state.note.id).then((e) => {
2020-03-10 23:19:16 +05:00
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) {
2020-03-14 12:59:52 +05:00
ToastEvent.show('Password is invalid', 'error', 'local');
2020-03-10 23:19:16 +05:00
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() {
2020-03-14 12:13:00 +05:00
db.vault
.open(this.state.note.id, this.password)
2020-04-15 17:41:28 +05:00
.then(async (note) => {
2020-03-14 12:13:00 +05:00
if (this.state.goToEditor) {
this._openInEditor(note);
} else if (this.state.share) {
this._shareNote(note);
} else if (this.state.deleteNote) {
await this._deleteNote();
}
})
2020-09-09 11:10:35 +05:00
.catch((e) => {
2020-03-14 12:13:00 +05:00
this._takeErrorAction(e);
});
}
async _deleteNote() {
await db.notes.delete(this.state.note.id);
2020-10-13 17:02:14 +05:00
updateEvent({type: Actions.NOTES});
updateEvent({type: Actions.FAVORITES});
2020-03-14 12:13:00 +05:00
eSendEvent(refreshNotesPage);
this.close();
2020-03-14 12:59:52 +05:00
ToastEvent.show('Note deleted', 'success', 'local');
2020-03-10 23:19:16 +05:00
}
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();
2020-03-14 12:59:52 +05:00
ToastEvent.show('Note added to vault', 'success', 'local');
2020-03-10 23:19:16 +05:00
}
}
_permanantUnlock() {
db.vault
.remove(this.state.note.id, this.password)
.then(() => {
this.close();
})
2020-09-09 11:10:35 +05:00
.catch((e) => {
2020-03-10 23:19:16 +05:00
this._takeErrorAction(e);
});
}
_openInEditor(note) {
eSendEvent(eOnLoadNote, note);
2020-04-15 17:41:28 +05:00
2020-03-10 23:19:16 +05:00
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) {
2020-03-14 12:59:52 +05:00
ToastEvent.show('Password is incorrect', 'error', 'local');
2020-03-10 23:19:16 +05:00
this.setState({
wrongPassword: true,
});
return;
2020-01-17 21:05:38 +05:00
} else {
}
2020-03-10 23:19:16 +05:00
}
2020-01-17 21:05:38 +05:00
render() {
2020-09-09 11:10:35 +05:00
const {colors} = this.props;
2020-03-10 23:19:16 +05:00
const {
note,
visible,
wrongPassword,
passwordsDontMatch,
novault,
locked,
permanant,
goToEditor,
share,
} = this.state;
2020-01-17 21:05:38 +05:00
return (
2020-09-27 13:05:26 +05:00
<BaseDialog
2020-03-03 15:37:48 +05:00
onShow={() => {
passInputRef.current?.focus();
}}
2020-09-27 13:05:26 +05:00
onRequestClose={this.close}
visible={visible}>
2019-12-07 08:41:48 +05:00
<View
style={{
2020-09-27 13:05:26 +05:00
...getElevation(5),
2020-10-04 09:46:50 +05:00
width: DDS.isTab ? 350 : '80%',
2020-09-27 13:05:26 +05:00
maxHeight: 350,
borderRadius: 5,
backgroundColor: colors.bg,
paddingHorizontal: ph,
paddingVertical: pv,
2019-12-07 08:41:48 +05:00
}}>
2020-09-27 13:05:26 +05:00
<DialogHeader
title={
!novault
? 'Create vault'
: note.locked
? this.state.deleteNote
? 'Delete note'
: this.state.share
? 'Share note'
: this.state.goToEditor
? 'Unlock note'
: 'Unlock note'
: 'Lock note'
}
2020-09-27 13:14:24 +05:00
paragraph={
!novault
? 'Set a password to create vault'
: permanant
? 'Enter password to remove note from vault.'
: note.locked
? this.state.deleteNote
? 'Unlock note to delete it.'
: this.state.share
? 'Unlock note to share it.'
: this.state.goToEditor
? 'Unlock note to open it in editor'
: 'Enter vault password to unlock note.'
: 'Enter vault password to lock note.'
}
2020-09-27 13:05:26 +05:00
icon="shield"
/>
{note.locked || locked || permanant ? (
<TextInput
ref={passInputRef}
2020-01-05 18:03:40 +05:00
style={{
2020-09-27 13:05:26 +05:00
padding: pv - 5,
borderWidth: 1.5,
borderColor: wrongPassword ? colors.errorText : colors.nav,
paddingHorizontal: ph,
borderRadius: 5,
2020-01-17 21:05:38 +05:00
marginTop: 10,
2020-09-27 13:05:26 +05:00
fontSize: SIZE.sm,
fontFamily: WEIGHT.regular,
}}
onChangeText={(value) => {
this.password = value;
}}
secureTextEntry
placeholder="Password"
placeholderTextColor={colors.icon}
/>
) : null}
2020-01-05 18:03:40 +05:00
2020-09-27 13:05:26 +05:00
{!novault ? (
<View>
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-09-27 13:05:26 +05:00
borderColor: passwordsDontMatch
? colors.errorText
: colors.nav,
2019-12-07 08:41:48 +05:00
paddingHorizontal: ph,
borderRadius: 5,
fontSize: SIZE.sm,
fontFamily: WEIGHT.regular,
}}
2020-09-09 11:10:35 +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-09-09 11:10:35 +05:00
2020-09-27 13:05:26 +05:00
<TextInput
ref={confirmPassRef}
style={{
padding: pv - 5,
borderWidth: 1.5,
borderColor: passwordsDontMatch
? colors.errorText
: colors.nav,
paddingHorizontal: ph,
borderRadius: 5,
fontSize: SIZE.sm,
fontFamily: WEIGHT.regular,
marginTop: 10,
}}
secureTextEntry
onChangeText={(value) => {
this.confirmPassword = value;
if (value !== this.password) {
this.setState({
passwordsDontMatch: true,
});
} else {
this.setState({
passwordsDontMatch: false,
});
}
}}
placeholder="Confirm password"
placeholderTextColor={colors.icon}
2020-09-09 11:10:35 +05:00
/>
2020-01-17 21:05:38 +05:00
</View>
2020-09-27 13:05:26 +05:00
) : null}
<DialogButtons
onPressNegative={this.close}
onPressPositive={this.onPress}
positiveTitle={
note.locked
? this.state.deleteNote
? 'Delete'
: this.state.share
? 'Share '
: this.state.goToEditor
? 'Open'
: 'Unlock'
: 'Lock'
}
/>
2019-12-07 08:41:48 +05:00
</View>
2020-03-14 12:59:52 +05:00
<Toast context="local" />
2020-09-27 13:05:26 +05:00
</BaseDialog>
2020-01-17 21:05:38 +05:00
);
}
}