mirror of
https://github.com/streetwriters/notesnook.git
synced 2025-12-16 19:57:52 +01:00
update dialog ui similar to desktop app
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import React, {createRef} from 'react';
|
||||
import {View} from 'react-native';
|
||||
import {Actions} from '../../provider/Actions';
|
||||
import {useMenuStore} from '../../provider/stores';
|
||||
import {
|
||||
@@ -119,25 +120,31 @@ export class AddTopicDialog extends React.Component {
|
||||
paragraph={
|
||||
this.toEdit
|
||||
? 'Edit title of the topic'
|
||||
: 'Add a new topic to ' + this.notebook.title
|
||||
: 'Create a new topic in ' + this.notebook.title
|
||||
}
|
||||
padding={12}
|
||||
/>
|
||||
<Seperator half />
|
||||
<Input
|
||||
fwdRef={this.titleRef}
|
||||
onChangeText={value => {
|
||||
this.title = value;
|
||||
}}
|
||||
blurOnSubmit={false}
|
||||
defaultValue={this.toEdit ? this.toEdit.title : null}
|
||||
placeholder="Enter title of topic"
|
||||
onSubmit={() => this.addNewTopic()}
|
||||
returnKeyLabel="Done"
|
||||
returnKeyType="done"
|
||||
/>
|
||||
<View
|
||||
style={{
|
||||
paddingHorizontal: 12
|
||||
}}>
|
||||
<Input
|
||||
fwdRef={this.titleRef}
|
||||
onChangeText={value => {
|
||||
this.title = value;
|
||||
}}
|
||||
blurOnSubmit={false}
|
||||
defaultValue={this.toEdit ? this.toEdit.title : null}
|
||||
placeholder="Enter title of topic"
|
||||
onSubmit={() => this.addNewTopic()}
|
||||
returnKeyLabel="Done"
|
||||
returnKeyType="done"
|
||||
/>
|
||||
</View>
|
||||
|
||||
<DialogButtons
|
||||
positiveTitle={this.toEdit ? 'Save' : 'Add'}
|
||||
positiveTitle={this.toEdit ? 'Save' : 'Create'}
|
||||
onPressNegative={() => this.close()}
|
||||
onPressPositive={() => this.addNewTopic()}
|
||||
loading={this.state.loading}
|
||||
|
||||
@@ -7,8 +7,9 @@ import {
|
||||
StyleSheet,
|
||||
TouchableOpacity
|
||||
} from 'react-native';
|
||||
import { useTracked } from '../../provider';
|
||||
import {useTracked} from '../../provider';
|
||||
import useIsFloatingKeyboard from '../../utils/use-is-floating-keyboard';
|
||||
import {BouncingView} from '../ActionSheetComponent/BouncingView';
|
||||
|
||||
const BaseDialog = ({
|
||||
visible,
|
||||
@@ -25,7 +26,7 @@ const BaseDialog = ({
|
||||
}) => {
|
||||
const [state, dispatch] = useTracked();
|
||||
const floating = useIsFloatingKeyboard();
|
||||
|
||||
|
||||
return (
|
||||
<Modal
|
||||
visible={visible}
|
||||
@@ -41,26 +42,36 @@ const BaseDialog = ({
|
||||
onRequestClose={onRequestClose}>
|
||||
<SafeAreaView
|
||||
style={{
|
||||
backgroundColor:background? background : transparent
|
||||
backgroundColor: background
|
||||
? background
|
||||
: transparent
|
||||
? 'transparent'
|
||||
: 'rgba(0,0,0,0.3)',
|
||||
: 'rgba(0,0,0,0.3)'
|
||||
}}>
|
||||
<KeyboardAvoidingView
|
||||
enabled={!floating && Platform.OS === 'ios'}
|
||||
behavior="padding"
|
||||
style={[
|
||||
styles.backdrop,
|
||||
{
|
||||
justifyContent: centered ? 'center' : bottom ? 'flex-end' : 'flex-start',
|
||||
},
|
||||
]}>
|
||||
<TouchableOpacity
|
||||
behavior="padding">
|
||||
|
||||
|
||||
<BouncingView
|
||||
duration={400}
|
||||
style={[
|
||||
styles.backdrop,
|
||||
{
|
||||
justifyContent: centered
|
||||
? 'center'
|
||||
: bottom
|
||||
? 'flex-end'
|
||||
: 'flex-start'
|
||||
}
|
||||
]}>
|
||||
<TouchableOpacity
|
||||
onPress={onRequestClose}
|
||||
style={styles.overlayButton}
|
||||
/>
|
||||
{premium}
|
||||
|
||||
{children}
|
||||
{children}
|
||||
</BouncingView>
|
||||
</KeyboardAvoidingView>
|
||||
</SafeAreaView>
|
||||
</Modal>
|
||||
@@ -72,13 +83,13 @@ const styles = StyleSheet.create({
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
alignItems: 'center'
|
||||
},
|
||||
overlayButton: {
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
position: 'absolute',
|
||||
},
|
||||
}
|
||||
});
|
||||
|
||||
export default BaseDialog;
|
||||
|
||||
@@ -20,7 +20,13 @@ const DialogButtons = ({
|
||||
const {colors} = state;
|
||||
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<View style={[styles.container,{
|
||||
backgroundColor:colors.nav,
|
||||
height:60,
|
||||
borderBottomRightRadius:10,
|
||||
borderBottomLeftRadius:10,
|
||||
paddingHorizontal:12
|
||||
}]}>
|
||||
{loading ? (
|
||||
<ActivityIndicator color={colors.accent} size={SIZE.lg} />
|
||||
) : doneText ? (
|
||||
@@ -50,6 +56,7 @@ const DialogButtons = ({
|
||||
fontSize={SIZE.md}
|
||||
testID={notesnook.ids.default.dialog.no}
|
||||
type="gray"
|
||||
bold
|
||||
title={negativeTitle}
|
||||
/>
|
||||
{onPressPositive ? (
|
||||
@@ -60,6 +67,7 @@ const DialogButtons = ({
|
||||
style={{
|
||||
marginLeft: 10,
|
||||
}}
|
||||
bold
|
||||
type={positiveType || "transparent"}
|
||||
title={positiveTitle}
|
||||
/>
|
||||
|
||||
@@ -15,10 +15,9 @@ const DialogContainer = ({width, height, ...restProps}) => {
|
||||
...getElevation(5),
|
||||
width: width || DDS.isTab ? 400 : '85%',
|
||||
maxHeight: height || 450,
|
||||
borderRadius: 5,
|
||||
borderRadius: 10,
|
||||
backgroundColor: colors.bg,
|
||||
paddingHorizontal: 12,
|
||||
paddingVertical: 15,
|
||||
paddingTop: 12,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -6,7 +6,7 @@ import {Button} from '../Button';
|
||||
import Heading from '../Typography/Heading';
|
||||
import Paragraph from '../Typography/Paragraph';
|
||||
|
||||
const DialogHeader = ({icon, title, paragraph, button, paragraphColor}) => {
|
||||
const DialogHeader = ({icon, title, paragraph, button, paragraphColor,padding}) => {
|
||||
const [state, dispatch] = useTracked();
|
||||
const colors = state.colors;
|
||||
|
||||
@@ -17,7 +17,8 @@ const DialogHeader = ({icon, title, paragraph, button, paragraphColor}) => {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'space-between',
|
||||
minHeight: 50
|
||||
minHeight: 50,
|
||||
paddingHorizontal:padding
|
||||
}}>
|
||||
<View
|
||||
style={{
|
||||
|
||||
@@ -116,7 +116,7 @@ const JumpToDialog = ({scrollRef, data, type, screen}) => {
|
||||
zIndex: 100,
|
||||
bottom: 20,
|
||||
maxHeight: '65%',
|
||||
borderRadius: 5,
|
||||
borderRadius: 10,
|
||||
alignSelf: 'center',
|
||||
padding: 10,
|
||||
}}>
|
||||
|
||||
@@ -450,7 +450,9 @@ const LoginDialog = () => {
|
||||
title="Logout"
|
||||
paragraph="All user data on this device will be cleared including any unsynced changes. Do you want to proceed?"
|
||||
paragraphColor="red"
|
||||
padding={12}
|
||||
/>
|
||||
<Seperator/>
|
||||
<DialogButtons
|
||||
negativeTitle="Cancel"
|
||||
onPressNegative={() => {
|
||||
@@ -482,7 +484,7 @@ const LoginDialog = () => {
|
||||
<BaseDialog
|
||||
visible={true}
|
||||
transparent={current.showLoader}
|
||||
animation="slide"
|
||||
animation="fade"
|
||||
onRequestClose={() => {
|
||||
if (!current.showLoader) {
|
||||
setStatus(null);
|
||||
|
||||
@@ -36,6 +36,7 @@ import BaseDialog from '../Dialog/base-dialog';
|
||||
import DialogButtons from '../Dialog/dialog-buttons';
|
||||
import DialogContainer from '../Dialog/dialog-container';
|
||||
import DialogHeader from '../Dialog/dialog-header';
|
||||
import Seperator from '../Seperator';
|
||||
import Paragraph from '../Typography/Paragraph';
|
||||
|
||||
const primaryWebView = createRef();
|
||||
@@ -272,7 +273,9 @@ const MergeEditor = () => {
|
||||
<DialogHeader
|
||||
title="Apply Changes"
|
||||
paragraph="Apply selected changes to note?"
|
||||
padding={12}
|
||||
/>
|
||||
<Seperator/>
|
||||
<DialogButtons
|
||||
positiveTitle="Apply"
|
||||
negativeTitle="Cancel"
|
||||
|
||||
@@ -26,7 +26,7 @@ import {useUserStore} from '../../provider/stores';
|
||||
|
||||
const features = [
|
||||
{
|
||||
title: 'Unlimited attachments'
|
||||
title: 'Unlimited file & image attachments'
|
||||
},
|
||||
{
|
||||
title: 'Unlimited storage'
|
||||
|
||||
@@ -76,13 +76,7 @@ class RecoveryKeyDialog extends React.Component {
|
||||
if (this.signup) {
|
||||
this.signup = false;
|
||||
setTimeout(() => {
|
||||
eSendEvent(eOpenResultDialog, {
|
||||
title: 'Welcome to your private\nnote taking haven',
|
||||
paragraph:
|
||||
'Please confirm your email to encrypt and sync all your notes.',
|
||||
icon: 'check',
|
||||
button: 'Start taking notes'
|
||||
});
|
||||
eSendEvent(eOpenResultDialog);
|
||||
}, 500);
|
||||
}
|
||||
};
|
||||
|
||||
56
apps/mobile/src/components/ResultDialog/ProFeatures.js
Normal file
56
apps/mobile/src/components/ResultDialog/ProFeatures.js
Normal file
@@ -0,0 +1,56 @@
|
||||
import React from 'react';
|
||||
import {View} from 'react-native';
|
||||
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
|
||||
import {useTracked} from '../../provider';
|
||||
import {SIZE} from '../../utils/SizeUtils';
|
||||
import Paragraph from '../Typography/Paragraph';
|
||||
export const ProFeatures = () => {
|
||||
const [state, dispatch] = useTracked();
|
||||
const {colors} = state;
|
||||
|
||||
return (
|
||||
<>
|
||||
{[
|
||||
{
|
||||
title: 'Unlimited notes & notebooks',
|
||||
icon: 'notebook'
|
||||
},
|
||||
{
|
||||
title: 'Unlimited file & image attachments',
|
||||
icon: 'attachment'
|
||||
},
|
||||
{
|
||||
title: 'Lock any note with password',
|
||||
icon: 'shield-outline'
|
||||
},
|
||||
{
|
||||
title: 'Rich text editing with markdown',
|
||||
icon: 'pencil'
|
||||
}
|
||||
].map(item => (
|
||||
<View
|
||||
style={{
|
||||
flexDirection: 'row',
|
||||
width: '100%',
|
||||
height: 40,
|
||||
paddingHorizontal: 12,
|
||||
marginBottom: 10,
|
||||
alignItems: 'center',
|
||||
borderRadius: 5
|
||||
}}>
|
||||
<Icon size={SIZE.md} color={colors.accent} name={item.icon} />
|
||||
<Paragraph style={{marginLeft: 5}}>{item.title}</Paragraph>
|
||||
</View>
|
||||
))}
|
||||
<Paragraph
|
||||
onPress={() => {}}
|
||||
size={SIZE.xs + 2}
|
||||
style={{
|
||||
textDecorationLine: 'underline',
|
||||
color: colors.icon
|
||||
}}>
|
||||
See all features included in Notesnook Pro
|
||||
</Paragraph>
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -1,6 +1,5 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { View } from 'react-native';
|
||||
import { WELCOME_SVG } from '../../assets/images/assets';
|
||||
import { useTracked } from '../../provider';
|
||||
import { DDS } from '../../services/DeviceDetection';
|
||||
import { eSubscribeEvent, eUnSubscribeEvent } from '../../services/EventManager';
|
||||
@@ -9,15 +8,15 @@ import { eCloseResultDialog, eOpenResultDialog } from '../../utils/Events';
|
||||
import { ph, SIZE } from '../../utils/SizeUtils';
|
||||
import { Button } from '../Button';
|
||||
import BaseDialog from '../Dialog/base-dialog';
|
||||
import { SvgToPngView } from '../ListPlaceholders';
|
||||
import Seperator from '../Seperator';
|
||||
import Heading from '../Typography/Heading';
|
||||
import Paragraph from '../Typography/Paragraph';
|
||||
import { ProFeatures } from './pro-features';
|
||||
|
||||
const ResultDialog = () => {
|
||||
const [state, dispatch] = useTracked();
|
||||
const {colors} = state;
|
||||
const [visible, setVisible] = useState(false);
|
||||
const [visible, setVisible] = useState(true);
|
||||
const [dialogData, setDialogData] = useState({
|
||||
title: 'Thank you for signing up!',
|
||||
paragraph:
|
||||
@@ -49,20 +48,13 @@ const ResultDialog = () => {
|
||||
...getElevation(5),
|
||||
width: DDS.isTab ? 350 : '85%',
|
||||
maxHeight: 500,
|
||||
borderRadius: 5,
|
||||
borderRadius: 10,
|
||||
backgroundColor: colors.bg,
|
||||
paddingHorizontal: ph,
|
||||
paddingVertical: 20,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center'
|
||||
}}>
|
||||
<SvgToPngView
|
||||
src={WELCOME_SVG(colors.accent)}
|
||||
color={colors.accent}
|
||||
width={240}
|
||||
height={240}
|
||||
/>
|
||||
|
||||
<Heading
|
||||
size={SIZE.lg}
|
||||
textBreakStrategy="balanced"
|
||||
@@ -75,6 +67,7 @@ const ResultDialog = () => {
|
||||
}}>
|
||||
{dialogData.title}
|
||||
</Heading>
|
||||
|
||||
<Paragraph
|
||||
color={colors.icon}
|
||||
size={SIZE.md}
|
||||
@@ -86,6 +79,11 @@ const ResultDialog = () => {
|
||||
}}>
|
||||
{dialogData.paragraph}
|
||||
</Paragraph>
|
||||
|
||||
<Seperator />
|
||||
|
||||
<ProFeatures />
|
||||
|
||||
<Seperator />
|
||||
<Button
|
||||
title={dialogData.button}
|
||||
|
||||
@@ -52,7 +52,7 @@ export const Card = ({color}) => {
|
||||
<View
|
||||
style={{
|
||||
marginLeft: 10,
|
||||
maxWidth: '75%'
|
||||
maxWidth: '70%'
|
||||
}}>
|
||||
<Paragraph color={colors.icon} size={SIZE.xs + 1}>
|
||||
{messageBoardState.message}
|
||||
|
||||
@@ -1,11 +1,7 @@
|
||||
import React, {Component, createRef} from 'react';
|
||||
import {Platform} from 'react-native';
|
||||
import {
|
||||
InteractionManager,
|
||||
TouchableOpacity,
|
||||
View,
|
||||
} from 'react-native';
|
||||
import Clipboard from "@react-native-clipboard/clipboard"
|
||||
import {InteractionManager, TouchableOpacity, View} from 'react-native';
|
||||
import Clipboard from '@react-native-clipboard/clipboard';
|
||||
import Share from 'react-native-share';
|
||||
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
|
||||
import {notesnook} from '../../../e2e/test.ids';
|
||||
@@ -16,7 +12,7 @@ import {
|
||||
eSubscribeEvent,
|
||||
eUnSubscribeEvent,
|
||||
sendNoteEditedEvent,
|
||||
ToastEvent,
|
||||
ToastEvent
|
||||
} from '../../services/EventManager';
|
||||
import Navigation from '../../services/Navigation';
|
||||
import {getElevation, toTXT} from '../../utils';
|
||||
@@ -26,7 +22,7 @@ import {
|
||||
eCloseActionSheet,
|
||||
eCloseVaultDialog,
|
||||
eOnLoadNote,
|
||||
eOpenVaultDialog,
|
||||
eOpenVaultDialog
|
||||
} from '../../utils/Events';
|
||||
import {deleteItems} from '../../utils/functions';
|
||||
import {tabBarRef} from '../../utils/Refs';
|
||||
@@ -73,7 +69,7 @@ export class VaultDialog extends Component {
|
||||
description: null,
|
||||
clearVault: false,
|
||||
deleteVault: false,
|
||||
deleteAll: false,
|
||||
deleteAll: false
|
||||
};
|
||||
this.password = null;
|
||||
this.confirmPassword = null;
|
||||
@@ -164,7 +160,7 @@ export class VaultDialog extends Component {
|
||||
title: data.title,
|
||||
description: data.description,
|
||||
clearVault: data.clearVault,
|
||||
deleteVault: data.deleteVault,
|
||||
deleteVault: data.deleteVault
|
||||
});
|
||||
|
||||
if (
|
||||
@@ -179,7 +175,7 @@ export class VaultDialog extends Component {
|
||||
await this._onPressFingerprintAuth(data.title, data.description);
|
||||
} else {
|
||||
this.setState({
|
||||
visible: true,
|
||||
visible: true
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -190,20 +186,20 @@ export class VaultDialog extends Component {
|
||||
heading: this.state.title,
|
||||
message: 'Please wait and do not close the app.',
|
||||
type: 'success',
|
||||
context: 'local',
|
||||
context: 'local'
|
||||
});
|
||||
return;
|
||||
}
|
||||
Navigation.setRoutesToUpdate([
|
||||
Navigation.routeNames.NotesPage,
|
||||
Navigation.routeNames.Favorites,
|
||||
Navigation.routeNames.Notes,
|
||||
Navigation.routeNames.Notes
|
||||
]);
|
||||
Navigation.setRoutesToUpdate([
|
||||
Navigation.routeNames.Notes,
|
||||
Navigation.routeNames.Favorites,
|
||||
Navigation.routeNames.NotesPage,
|
||||
Navigation.routeNames.Notebook,
|
||||
Navigation.routeNames.Notebook
|
||||
]);
|
||||
this.password = null;
|
||||
this.confirmPassword = null;
|
||||
@@ -216,7 +212,7 @@ export class VaultDialog extends Component {
|
||||
share: false,
|
||||
novault: false,
|
||||
deleteNote: false,
|
||||
passwordsDontMatch: false,
|
||||
passwordsDontMatch: false
|
||||
});
|
||||
};
|
||||
|
||||
@@ -234,7 +230,7 @@ export class VaultDialog extends Component {
|
||||
heading: 'Password not entered',
|
||||
message: 'Enter a password for the vault and try again.',
|
||||
type: 'error',
|
||||
context: 'local',
|
||||
context: 'local'
|
||||
});
|
||||
return;
|
||||
}
|
||||
@@ -243,7 +239,7 @@ export class VaultDialog extends Component {
|
||||
heading: 'Password too short',
|
||||
message: 'Password must be longer than 3 characters.',
|
||||
type: 'error',
|
||||
context: 'local',
|
||||
context: 'local'
|
||||
});
|
||||
|
||||
return;
|
||||
@@ -254,10 +250,10 @@ export class VaultDialog extends Component {
|
||||
ToastEvent.show({
|
||||
heading: 'Passwords do not match',
|
||||
type: 'error',
|
||||
context: 'local',
|
||||
context: 'local'
|
||||
});
|
||||
this.setState({
|
||||
passwordsDontMatch: true,
|
||||
passwordsDontMatch: true
|
||||
});
|
||||
return;
|
||||
}
|
||||
@@ -265,14 +261,14 @@ export class VaultDialog extends Component {
|
||||
this._createVault();
|
||||
} else if (this.state.changePassword) {
|
||||
this.setState({
|
||||
loading: true,
|
||||
loading: true
|
||||
});
|
||||
|
||||
db.vault
|
||||
.changePassword(this.password, this.newPassword)
|
||||
.then(result => {
|
||||
this.setState({
|
||||
loading: false,
|
||||
loading: false
|
||||
});
|
||||
if (this.state.biometricUnlock) {
|
||||
this._enrollFingerprint(this.newPassword);
|
||||
@@ -280,20 +276,20 @@ export class VaultDialog extends Component {
|
||||
ToastEvent.show({
|
||||
heading: 'Vault password updated successfully',
|
||||
type: 'success',
|
||||
context: 'global',
|
||||
context: 'global'
|
||||
});
|
||||
this.close();
|
||||
})
|
||||
.catch(e => {
|
||||
this.setState({
|
||||
loading: false,
|
||||
loading: false
|
||||
});
|
||||
if (e.message === db.vault.ERRORS.wrongPassword) {
|
||||
ToastEvent.show({
|
||||
heading: 'Incorrect password',
|
||||
message: 'Please enter the correct password and try again',
|
||||
type: 'error',
|
||||
context: 'local',
|
||||
context: 'local'
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -303,10 +299,10 @@ export class VaultDialog extends Component {
|
||||
heading: 'Incorrect password',
|
||||
message: 'Please enter the correct password and try again',
|
||||
type: 'error',
|
||||
context: 'local',
|
||||
context: 'local'
|
||||
});
|
||||
this.setState({
|
||||
wrongPassword: true,
|
||||
wrongPassword: true
|
||||
});
|
||||
return;
|
||||
}
|
||||
@@ -314,7 +310,7 @@ export class VaultDialog extends Component {
|
||||
.unlock(this.password)
|
||||
.then(async () => {
|
||||
this.setState({
|
||||
wrongPassword: false,
|
||||
wrongPassword: false
|
||||
});
|
||||
if (this.state.note.locked) {
|
||||
await this._unlockNote();
|
||||
@@ -336,7 +332,7 @@ export class VaultDialog extends Component {
|
||||
|
||||
deleteVault = async () => {
|
||||
this.setState({
|
||||
loading: true,
|
||||
loading: true
|
||||
});
|
||||
try {
|
||||
let verified = await db.user.verifyPassword(this.password);
|
||||
@@ -344,7 +340,7 @@ export class VaultDialog extends Component {
|
||||
await db.vault.delete(this.state.deleteAll);
|
||||
eSendEvent('vaultUpdated');
|
||||
this.setState({
|
||||
loading: false,
|
||||
loading: false
|
||||
});
|
||||
this.close();
|
||||
} else {
|
||||
@@ -352,23 +348,23 @@ export class VaultDialog extends Component {
|
||||
heading: 'Account password incorrect',
|
||||
message: 'Please enter correct password for your account.',
|
||||
type: 'error',
|
||||
context: 'local',
|
||||
context: 'local'
|
||||
});
|
||||
}
|
||||
} catch (e) {}
|
||||
this.setState({
|
||||
loading: false,
|
||||
loading: false
|
||||
});
|
||||
};
|
||||
|
||||
clearVault = async () => {
|
||||
this.setState({
|
||||
loading: true,
|
||||
loading: true
|
||||
});
|
||||
try {
|
||||
await db.vault.clear(this.password);
|
||||
this.setState({
|
||||
loading: false,
|
||||
loading: false
|
||||
});
|
||||
this.close();
|
||||
eSendEvent('vaultUpdated');
|
||||
@@ -377,11 +373,11 @@ export class VaultDialog extends Component {
|
||||
heading: 'Vault password incorrect',
|
||||
message: 'Please enter correct password to clear vault.',
|
||||
type: 'error',
|
||||
context: 'local',
|
||||
context: 'local'
|
||||
});
|
||||
}
|
||||
this.setState({
|
||||
loading: false,
|
||||
loading: false
|
||||
});
|
||||
};
|
||||
|
||||
@@ -391,7 +387,7 @@ export class VaultDialog extends Component {
|
||||
message: 'Incorrect password',
|
||||
message: 'Please enter the correct password and try again',
|
||||
type: 'error',
|
||||
context: 'local',
|
||||
context: 'local'
|
||||
});
|
||||
console.log('returning from here');
|
||||
return;
|
||||
@@ -404,10 +400,10 @@ export class VaultDialog extends Component {
|
||||
ToastEvent.show({
|
||||
message: 'Note locked successfully',
|
||||
type: 'error',
|
||||
context: 'local',
|
||||
context: 'local'
|
||||
});
|
||||
this.setState({
|
||||
loading: false,
|
||||
loading: false
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -418,7 +414,7 @@ export class VaultDialog extends Component {
|
||||
heading: 'Incorrect password',
|
||||
message: 'Please enter the correct password and try again',
|
||||
type: 'error',
|
||||
context: 'local',
|
||||
context: 'local'
|
||||
});
|
||||
return;
|
||||
}
|
||||
@@ -462,21 +458,21 @@ export class VaultDialog extends Component {
|
||||
try {
|
||||
this.setState(
|
||||
{
|
||||
loading: true,
|
||||
loading: true
|
||||
},
|
||||
async () => {
|
||||
try {
|
||||
await db.vault.unlock(password);
|
||||
await BiometricService.storeCredentials(password);
|
||||
this.setState({
|
||||
loading: false,
|
||||
loading: false
|
||||
});
|
||||
eSendEvent('vaultUpdated');
|
||||
ToastEvent.show({
|
||||
heading: 'Biometric unlocking enabled!',
|
||||
message: 'Now you can unlock notes in vault with biometrics.',
|
||||
type: 'success',
|
||||
context: 'global',
|
||||
context: 'global'
|
||||
});
|
||||
this.close();
|
||||
} catch (e) {
|
||||
@@ -485,14 +481,14 @@ export class VaultDialog extends Component {
|
||||
message:
|
||||
'Please enter the correct vault password to enable biometrics.',
|
||||
type: 'error',
|
||||
context: 'local',
|
||||
context: 'local'
|
||||
});
|
||||
this.setState({
|
||||
loading: false,
|
||||
loading: false
|
||||
});
|
||||
return;
|
||||
}
|
||||
},
|
||||
}
|
||||
);
|
||||
} catch (e) {
|
||||
this._takeErrorAction(e);
|
||||
@@ -511,12 +507,12 @@ export class VaultDialog extends Component {
|
||||
eSendEvent(eClearEditor);
|
||||
}
|
||||
this.setState({
|
||||
loading: false,
|
||||
loading: false
|
||||
});
|
||||
ToastEvent.show({
|
||||
heading: 'Note added to vault',
|
||||
type: 'success',
|
||||
context: 'global',
|
||||
context: 'global'
|
||||
});
|
||||
this.close();
|
||||
} else {
|
||||
@@ -524,7 +520,7 @@ export class VaultDialog extends Component {
|
||||
ToastEvent.show({
|
||||
heading: 'Vault created successfully',
|
||||
type: 'success',
|
||||
context: 'global',
|
||||
context: 'global'
|
||||
});
|
||||
this.close();
|
||||
}
|
||||
@@ -537,7 +533,7 @@ export class VaultDialog extends Component {
|
||||
ToastEvent.show({
|
||||
heading: 'Note permanantly unlocked.',
|
||||
type: 'success',
|
||||
context: 'global',
|
||||
context: 'global'
|
||||
});
|
||||
this.close();
|
||||
})
|
||||
@@ -565,7 +561,7 @@ export class VaultDialog extends Component {
|
||||
heading: 'Note copied',
|
||||
type: 'success',
|
||||
message: 'Note has been copied to clipboard!',
|
||||
context: 'global',
|
||||
context: 'global'
|
||||
});
|
||||
this.close();
|
||||
}
|
||||
@@ -578,7 +574,7 @@ export class VaultDialog extends Component {
|
||||
await Share.open({
|
||||
heading: 'Share note',
|
||||
failOnCancel: false,
|
||||
message: text,
|
||||
message: text
|
||||
});
|
||||
} catch (e) {}
|
||||
}
|
||||
@@ -587,13 +583,13 @@ export class VaultDialog extends Component {
|
||||
if (e.message === db.vault.ERRORS.wrongPassword) {
|
||||
this.setState({
|
||||
wrongPassword: true,
|
||||
visible: true,
|
||||
visible: true
|
||||
});
|
||||
setTimeout(() => {
|
||||
ToastEvent.show({
|
||||
heading: 'Incorrect password',
|
||||
type: 'error',
|
||||
context: 'local',
|
||||
context: 'local'
|
||||
});
|
||||
}, 500);
|
||||
|
||||
@@ -608,14 +604,14 @@ export class VaultDialog extends Component {
|
||||
ToastEvent.show({
|
||||
heading: 'Biometric unlocking disabled!',
|
||||
type: 'success',
|
||||
context: 'global',
|
||||
context: 'global'
|
||||
});
|
||||
} catch (e) {
|
||||
ToastEvent.show({
|
||||
heading: 'Failed to disable Biometric unlocking.',
|
||||
message: e.message,
|
||||
type: 'success',
|
||||
context: 'global',
|
||||
context: 'global'
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -624,7 +620,7 @@ export class VaultDialog extends Component {
|
||||
try {
|
||||
let credentials = await BiometricService.getCredentials(
|
||||
title || this.state.title,
|
||||
description || this.state.description,
|
||||
description || this.state.description
|
||||
);
|
||||
|
||||
if (credentials?.password) {
|
||||
@@ -634,7 +630,7 @@ export class VaultDialog extends Component {
|
||||
eSendEvent(eCloseActionSheet);
|
||||
await sleep(300);
|
||||
this.setState({
|
||||
visible: true,
|
||||
visible: true
|
||||
});
|
||||
}
|
||||
} catch (e) {}
|
||||
@@ -659,7 +655,7 @@ export class VaultDialog extends Component {
|
||||
copyNote,
|
||||
loading,
|
||||
deleteVault,
|
||||
clearVault,
|
||||
clearVault
|
||||
} = this.state;
|
||||
|
||||
if (!visible) return null;
|
||||
@@ -676,162 +672,166 @@ export class VaultDialog extends Component {
|
||||
style={{
|
||||
...getElevation(5),
|
||||
width: DDS.isTab ? 350 : '85%',
|
||||
borderRadius: 5,
|
||||
borderRadius: 10,
|
||||
backgroundColor: colors.bg,
|
||||
paddingHorizontal: ph,
|
||||
paddingVertical: 15,
|
||||
paddingTop: 12
|
||||
}}>
|
||||
<DialogHeader
|
||||
title={this.state.title}
|
||||
paragraph={this.state.description}
|
||||
icon="shield"
|
||||
padding={12}
|
||||
/>
|
||||
<Seperator half />
|
||||
|
||||
{(novault ||
|
||||
changePassword ||
|
||||
this.state.clearVault ||
|
||||
this.state.deleteVault) &&
|
||||
!this.state.revokeFingerprintAccess ? (
|
||||
<>
|
||||
<Input
|
||||
fwdRef={passInputRef}
|
||||
editable={!loading}
|
||||
autoCapitalize="none"
|
||||
testID={notesnook.ids.dialogs.vault.pwd}
|
||||
onChangeText={value => {
|
||||
this.password = value;
|
||||
}}
|
||||
marginBottom={
|
||||
!this.state.biometricUnlock ||
|
||||
!this.state.isBiometryEnrolled ||
|
||||
!novault ||
|
||||
changePassword
|
||||
? 0
|
||||
: 10
|
||||
}
|
||||
onSubmit={() => {
|
||||
changePassword
|
||||
? changePassInputRef.current?.focus()
|
||||
: this.onPress;
|
||||
}}
|
||||
autoCompleteType="password"
|
||||
returnKeyLabel={changePassword ? 'Next' : this.state.title}
|
||||
returnKeyType={changePassword ? 'next' : 'done'}
|
||||
secureTextEntry
|
||||
placeholder={changePassword ? 'Current password' : 'Password'}
|
||||
/>
|
||||
|
||||
{!this.state.biometricUnlock ||
|
||||
!this.state.isBiometryEnrolled ||
|
||||
!novault ||
|
||||
changePassword ? null : (
|
||||
<Button
|
||||
onPress={() =>
|
||||
this._onPressFingerprintAuth('Unlock note', '')
|
||||
<View
|
||||
style={{
|
||||
paddingHorizontal: 12
|
||||
}}>
|
||||
{(novault ||
|
||||
changePassword ||
|
||||
this.state.clearVault ||
|
||||
this.state.deleteVault) &&
|
||||
!this.state.revokeFingerprintAccess ? (
|
||||
<>
|
||||
<Input
|
||||
fwdRef={passInputRef}
|
||||
editable={!loading}
|
||||
autoCapitalize="none"
|
||||
testID={notesnook.ids.dialogs.vault.pwd}
|
||||
onChangeText={value => {
|
||||
this.password = value;
|
||||
}}
|
||||
marginBottom={
|
||||
!this.state.biometricUnlock ||
|
||||
!this.state.isBiometryEnrolled ||
|
||||
!novault ||
|
||||
changePassword
|
||||
? 0
|
||||
: 10
|
||||
}
|
||||
icon="fingerprint"
|
||||
width="100%"
|
||||
title={'Biometric unlock'}
|
||||
type="shade"
|
||||
onSubmit={() => {
|
||||
changePassword
|
||||
? changePassInputRef.current?.focus()
|
||||
: this.onPress;
|
||||
}}
|
||||
autoCompleteType="password"
|
||||
returnKeyLabel={changePassword ? 'Next' : this.state.title}
|
||||
returnKeyType={changePassword ? 'next' : 'done'}
|
||||
secureTextEntry
|
||||
placeholder={changePassword ? 'Current password' : 'Password'}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
) : null}
|
||||
|
||||
{this.state.deleteVault && (
|
||||
<Button
|
||||
onPress={() =>
|
||||
this.setState({
|
||||
deleteAll: !this.state.deleteAll,
|
||||
})
|
||||
}
|
||||
icon={
|
||||
this.state.deleteAll
|
||||
? 'check-circle-outline'
|
||||
: 'checkbox-blank-circle-outline'
|
||||
}
|
||||
style={{
|
||||
marginTop:10
|
||||
}}
|
||||
width="100%"
|
||||
title={'Delete all notes'}
|
||||
type="errorShade"
|
||||
/>
|
||||
)}
|
||||
{!this.state.biometricUnlock ||
|
||||
!this.state.isBiometryEnrolled ||
|
||||
!novault ||
|
||||
changePassword ? null : (
|
||||
<Button
|
||||
onPress={() =>
|
||||
this._onPressFingerprintAuth('Unlock note', '')
|
||||
}
|
||||
icon="fingerprint"
|
||||
width="100%"
|
||||
title={'Biometric unlock'}
|
||||
type="transparent"
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
) : null}
|
||||
|
||||
{changePassword ? (
|
||||
<>
|
||||
<Seperator half/>
|
||||
<Input
|
||||
ref={changePassInputRef}
|
||||
editable={!loading}
|
||||
testID={notesnook.ids.dialogs.vault.changePwd}
|
||||
autoCapitalize="none"
|
||||
onChangeText={value => {
|
||||
this.newPassword = value;
|
||||
{this.state.deleteVault && (
|
||||
<Button
|
||||
onPress={() =>
|
||||
this.setState({
|
||||
deleteAll: !this.state.deleteAll
|
||||
})
|
||||
}
|
||||
icon={
|
||||
this.state.deleteAll
|
||||
? 'check-circle-outline'
|
||||
: 'checkbox-blank-circle-outline'
|
||||
}
|
||||
style={{
|
||||
marginTop: 10
|
||||
}}
|
||||
autoCompleteType="password"
|
||||
onSubmit={this.onPress}
|
||||
returnKeyLabel="Change"
|
||||
returnKeyType="done"
|
||||
secureTextEntry
|
||||
placeholder={'New password'}
|
||||
width="100%"
|
||||
title={'Delete all notes'}
|
||||
type="errorShade"
|
||||
/>
|
||||
</>
|
||||
) : null}
|
||||
)}
|
||||
|
||||
{!novault ? (
|
||||
<View>
|
||||
<Input
|
||||
fwdRef={passInputRef}
|
||||
autoCapitalize="none"
|
||||
testID={notesnook.ids.dialogs.vault.pwd}
|
||||
onChangeText={value => {
|
||||
this.password = value;
|
||||
}}
|
||||
autoCompleteType="password"
|
||||
returnKeyLabel="Next"
|
||||
returnKeyType="next"
|
||||
secureTextEntry
|
||||
onSubmit={() => {
|
||||
confirmPassRef.current?.focus();
|
||||
}}
|
||||
placeholder="Password"
|
||||
/>
|
||||
{changePassword ? (
|
||||
<>
|
||||
<Seperator half />
|
||||
<Input
|
||||
ref={changePassInputRef}
|
||||
editable={!loading}
|
||||
testID={notesnook.ids.dialogs.vault.changePwd}
|
||||
autoCapitalize="none"
|
||||
onChangeText={value => {
|
||||
this.newPassword = value;
|
||||
}}
|
||||
autoCompleteType="password"
|
||||
onSubmit={this.onPress}
|
||||
returnKeyLabel="Change"
|
||||
returnKeyType="done"
|
||||
secureTextEntry
|
||||
placeholder={'New password'}
|
||||
/>
|
||||
</>
|
||||
) : null}
|
||||
|
||||
<Input
|
||||
fwdRef={confirmPassRef}
|
||||
autoCapitalize="none"
|
||||
testID={notesnook.ids.dialogs.vault.pwdAlt}
|
||||
secureTextEntry
|
||||
validationType="confirmPassword"
|
||||
customValidator={() => this.password}
|
||||
errorMessage="Passwords do not match."
|
||||
onErrorCheck={e => null}
|
||||
marginBottom={0}
|
||||
autoCompleteType="password"
|
||||
returnKeyLabel="Create"
|
||||
returnKeyType="done"
|
||||
onChangeText={value => {
|
||||
this.confirmPassword = value;
|
||||
if (value !== this.password) {
|
||||
this.setState({
|
||||
passwordsDontMatch: true,
|
||||
});
|
||||
} else {
|
||||
this.setState({
|
||||
passwordsDontMatch: false,
|
||||
});
|
||||
}
|
||||
}}
|
||||
onSubmit={this.onPress}
|
||||
placeholder="Confirm password"
|
||||
/>
|
||||
</View>
|
||||
) : null}
|
||||
{!novault ? (
|
||||
<View>
|
||||
<Input
|
||||
fwdRef={passInputRef}
|
||||
autoCapitalize="none"
|
||||
testID={notesnook.ids.dialogs.vault.pwd}
|
||||
onChangeText={value => {
|
||||
this.password = value;
|
||||
}}
|
||||
autoCompleteType="password"
|
||||
returnKeyLabel="Next"
|
||||
returnKeyType="next"
|
||||
secureTextEntry
|
||||
onSubmit={() => {
|
||||
confirmPassRef.current?.focus();
|
||||
}}
|
||||
placeholder="Password"
|
||||
/>
|
||||
|
||||
{this.state.biometricUnlock &&
|
||||
<Input
|
||||
fwdRef={confirmPassRef}
|
||||
autoCapitalize="none"
|
||||
testID={notesnook.ids.dialogs.vault.pwdAlt}
|
||||
secureTextEntry
|
||||
validationType="confirmPassword"
|
||||
customValidator={() => this.password}
|
||||
errorMessage="Passwords do not match."
|
||||
onErrorCheck={e => null}
|
||||
marginBottom={0}
|
||||
autoCompleteType="password"
|
||||
returnKeyLabel="Create"
|
||||
returnKeyType="done"
|
||||
onChangeText={value => {
|
||||
this.confirmPassword = value;
|
||||
if (value !== this.password) {
|
||||
this.setState({
|
||||
passwordsDontMatch: true
|
||||
});
|
||||
} else {
|
||||
this.setState({
|
||||
passwordsDontMatch: false
|
||||
});
|
||||
}
|
||||
}}
|
||||
onSubmit={this.onPress}
|
||||
placeholder="Confirm password"
|
||||
/>
|
||||
</View>
|
||||
) : null}
|
||||
|
||||
{this.state.biometricUnlock &&
|
||||
!this.state.isBiometryEnrolled &&
|
||||
novault ? (
|
||||
<Paragraph>
|
||||
@@ -839,27 +839,28 @@ export class VaultDialog extends Component {
|
||||
</Paragraph>
|
||||
) : null}
|
||||
|
||||
{this.state.isBiometryAvailable &&
|
||||
!this.state.fingerprintAccess &&
|
||||
!this.state.clearVault &&
|
||||
!this.state.deleteVault &&
|
||||
((!this.state.biometricUnlock && !changePassword) || !novault) ? (
|
||||
<Button
|
||||
onPress={() => {
|
||||
console.log(this.state.biometricUnlock)
|
||||
this.setState({
|
||||
biometricUnlock: !this.state.biometricUnlock,
|
||||
});
|
||||
}}
|
||||
style={{
|
||||
marginTop: 10,
|
||||
}}
|
||||
icon="fingerprint"
|
||||
width="100%"
|
||||
title="Biometric unlocking"
|
||||
type={this.state.biometricUnlock ? "shade" : 'grayBg'}
|
||||
/>
|
||||
) : null}
|
||||
{this.state.isBiometryAvailable &&
|
||||
!this.state.fingerprintAccess &&
|
||||
!this.state.clearVault &&
|
||||
!this.state.deleteVault &&
|
||||
((!this.state.biometricUnlock && !changePassword) || !novault) ? (
|
||||
<Button
|
||||
onPress={() => {
|
||||
console.log(this.state.biometricUnlock);
|
||||
this.setState({
|
||||
biometricUnlock: !this.state.biometricUnlock
|
||||
});
|
||||
}}
|
||||
style={{
|
||||
marginTop: 10
|
||||
}}
|
||||
icon="fingerprint"
|
||||
width="100%"
|
||||
title="Biometric unlocking"
|
||||
type={this.state.biometricUnlock ? 'transparent' : 'gray'}
|
||||
/>
|
||||
) : null}
|
||||
</View>
|
||||
|
||||
<DialogButtons
|
||||
onPressNegative={this.close}
|
||||
|
||||
@@ -391,8 +391,8 @@ const SectionHeader = ({title, collapsed, setCollapsed}) => {
|
||||
alignSelf: 'center',
|
||||
marginBottom: 5,
|
||||
marginTop: 5,
|
||||
borderBottomWidth:1,
|
||||
borderBottomColor:colors.nav
|
||||
borderBottomWidth: 1,
|
||||
borderBottomColor: colors.nav
|
||||
}}>
|
||||
{collapsed ? (
|
||||
<Paragraph
|
||||
@@ -437,9 +437,12 @@ const AccoutLogoutSection = () => {
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center'
|
||||
}}>
|
||||
<Heading color={colors.pri} size={SIZE.md}>
|
||||
<Heading color={colors.pri} size={SIZE.lg}>
|
||||
Logging out
|
||||
</Heading>
|
||||
<Paragraph color={colors.icon}>
|
||||
Please wait while log out and clear app data.
|
||||
</Paragraph>
|
||||
<View
|
||||
style={{
|
||||
flexDirection: 'row',
|
||||
@@ -459,7 +462,9 @@ const AccoutLogoutSection = () => {
|
||||
<DialogHeader
|
||||
title="Logout"
|
||||
paragraph="Clear all your data and reset the app."
|
||||
padding={12}
|
||||
/>
|
||||
<Seperator />
|
||||
<DialogButtons
|
||||
positiveTitle="Logout"
|
||||
negativeTitle="Cancel"
|
||||
@@ -493,65 +498,57 @@ const AccoutLogoutSection = () => {
|
||||
<DialogContainer>
|
||||
<DialogHeader
|
||||
title="Delete account"
|
||||
paragraph="Your account will be deleted and all your data will be removed
|
||||
paragraph="All your data will be removed
|
||||
permanantly. Make sure you have saved backup of your notes. This action is IRREVERSIBLE."
|
||||
paragraphColor={colors.red}
|
||||
padding={12}
|
||||
/>
|
||||
|
||||
<Input
|
||||
placeholder="Enter account password"
|
||||
fwdRef={pwdInput}
|
||||
onChangeText={v => {
|
||||
passwordValue = v;
|
||||
}}
|
||||
secureTextEntry={true}
|
||||
/>
|
||||
<Seperator half />
|
||||
|
||||
<View
|
||||
style={{
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
alignSelf: 'flex-end'
|
||||
paddingHorizontal: 12
|
||||
}}>
|
||||
<Button
|
||||
onPress={() => {
|
||||
setDeleteAccount(false);
|
||||
passwordValue = null;
|
||||
<Input
|
||||
placeholder="Enter account password"
|
||||
fwdRef={pwdInput}
|
||||
onChangeText={v => {
|
||||
passwordValue = v;
|
||||
}}
|
||||
fontSize={SIZE.md}
|
||||
type="gray"
|
||||
title="Cancel"
|
||||
/>
|
||||
<Button
|
||||
onPress={async () => {
|
||||
if (!passwordValue) {
|
||||
ToastEvent.show({
|
||||
heading: 'Account Password is required',
|
||||
type: 'error',
|
||||
context: 'local'
|
||||
});
|
||||
return;
|
||||
}
|
||||
try {
|
||||
await db.user.deleteUser(passwordValue);
|
||||
} catch (e) {
|
||||
ToastEvent.show({
|
||||
heading: 'Failed to delete account',
|
||||
message: e.message,
|
||||
type: 'error',
|
||||
context: 'local'
|
||||
});
|
||||
}
|
||||
close();
|
||||
}}
|
||||
fontSize={SIZE.md}
|
||||
style={{
|
||||
marginLeft: 10
|
||||
}}
|
||||
type="error"
|
||||
title="Delete"
|
||||
secureTextEntry={true}
|
||||
/>
|
||||
</View>
|
||||
|
||||
<DialogButtons
|
||||
positiveTitle="Delete"
|
||||
positiveType="errorShade"
|
||||
onPressPositive={async () => {
|
||||
if (!passwordValue) {
|
||||
ToastEvent.show({
|
||||
heading: 'Account Password is required',
|
||||
type: 'error',
|
||||
context: 'local'
|
||||
});
|
||||
return;
|
||||
}
|
||||
try {
|
||||
await db.user.deleteUser(passwordValue);
|
||||
} catch (e) {
|
||||
ToastEvent.show({
|
||||
heading: 'Failed to delete account',
|
||||
message: e.message,
|
||||
type: 'error',
|
||||
context: 'local'
|
||||
});
|
||||
}
|
||||
close();
|
||||
}}
|
||||
onPressNegative={() => {
|
||||
setDeleteAccount(false);
|
||||
passwordValue = null;
|
||||
}}
|
||||
/>
|
||||
</DialogContainer>
|
||||
<Toast context="local" />
|
||||
</BaseDialog>
|
||||
@@ -735,6 +732,10 @@ const SettingsUserSection = () => {
|
||||
};
|
||||
|
||||
const manageSubscription = () => {
|
||||
if (!user.isEmailConfirmed) {
|
||||
PremiumService.showVerifyEmailDialog();
|
||||
return;
|
||||
}
|
||||
if (
|
||||
user.subscription?.type === SUBSCRIPTION_STATUS.PREMIUM_CANCELLED &&
|
||||
Platform.OS === 'android'
|
||||
@@ -784,7 +785,7 @@ const SettingsUserSection = () => {
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
flexDirection: 'row',
|
||||
paddingBottom: 2.5,
|
||||
paddingBottom: 4,
|
||||
borderBottomWidth: 1,
|
||||
borderColor: colors.accent
|
||||
}}>
|
||||
@@ -850,7 +851,7 @@ const SettingsUserSection = () => {
|
||||
{isExpired
|
||||
? 'Your subscription has ended.'
|
||||
: user.subscription?.type === 1
|
||||
? `Your trial has started`
|
||||
? `Your free trial has started`
|
||||
: `Subscribed to Notesnook Pro`}
|
||||
</Paragraph>
|
||||
<Paragraph
|
||||
@@ -861,7 +862,7 @@ const SettingsUserSection = () => {
|
||||
{user.subscription?.type === 2
|
||||
? 'You signed up on ' + startDate
|
||||
: user.subscription?.type === 1
|
||||
? 'Your trial will end on ' + expiryDate
|
||||
? 'Your free trial will end on ' + expiryDate
|
||||
: user.subscription?.type === 6
|
||||
? subscriptionDaysLeft.time < -3
|
||||
? 'Your subscription has ended'
|
||||
@@ -875,8 +876,7 @@ const SettingsUserSection = () => {
|
||||
</View>
|
||||
) : null}
|
||||
|
||||
{user.isEmailConfirmed &&
|
||||
user.subscription?.type !== SUBSCRIPTION_STATUS.PREMIUM &&
|
||||
{user.subscription?.type !== SUBSCRIPTION_STATUS.PREMIUM &&
|
||||
user.subscription?.type !== SUBSCRIPTION_STATUS.BETA && (
|
||||
<>
|
||||
<Seperator />
|
||||
@@ -888,9 +888,11 @@ const SettingsUserSection = () => {
|
||||
}}
|
||||
fontSize={SIZE.md}
|
||||
title={
|
||||
user.subscription?.provider === 3 &&
|
||||
user.subscription?.type ===
|
||||
SUBSCRIPTION_STATUS.PREMIUM_CANCELLED
|
||||
!user.isEmailConfirmed
|
||||
? 'Confirm your email to get 7 days more'
|
||||
: user.subscription?.provider === 3 &&
|
||||
user.subscription?.type ===
|
||||
SUBSCRIPTION_STATUS.PREMIUM_CANCELLED
|
||||
? 'Manage subscription from desktop app'
|
||||
: user.subscription?.type ===
|
||||
SUBSCRIPTION_STATUS.PREMIUM_CANCELLED &&
|
||||
@@ -965,43 +967,32 @@ const SettingsUserSection = () => {
|
||||
<DialogHeader
|
||||
title="Verify it's you"
|
||||
paragraph="Enter your account password to save your data recovery key."
|
||||
padding={12}
|
||||
/>
|
||||
<Seperator half />
|
||||
<Input
|
||||
fwdRef={input}
|
||||
placeholder="Enter account password"
|
||||
onChangeText={v => {
|
||||
passwordVerifyValue = v;
|
||||
}}
|
||||
onSubmit={tryVerification}
|
||||
secureTextEntry={true}
|
||||
/>
|
||||
|
||||
<View
|
||||
style={{
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
alignSelf: 'flex-end'
|
||||
paddingHorizontal: 12
|
||||
}}>
|
||||
<Button
|
||||
onPress={() => {
|
||||
setVerifyUser(false);
|
||||
passwordVerifyValue = null;
|
||||
<Input
|
||||
fwdRef={input}
|
||||
placeholder="Enter account password"
|
||||
onChangeText={v => {
|
||||
passwordVerifyValue = v;
|
||||
}}
|
||||
fontSize={SIZE.md}
|
||||
type="gray"
|
||||
title="Cancel"
|
||||
/>
|
||||
<Button
|
||||
onPress={tryVerification}
|
||||
fontSize={SIZE.md}
|
||||
style={{
|
||||
marginLeft: 10
|
||||
}}
|
||||
type="transparent"
|
||||
title="Verify"
|
||||
onSubmit={tryVerification}
|
||||
secureTextEntry={true}
|
||||
/>
|
||||
</View>
|
||||
|
||||
<DialogButtons
|
||||
positiveTitle="Verify"
|
||||
onPressPositive={tryVerification}
|
||||
onPressNegative={() => {
|
||||
setVerifyUser(false);
|
||||
passwordVerifyValue = null;
|
||||
}}
|
||||
/>
|
||||
</DialogContainer>
|
||||
<Toast context="local" />
|
||||
</BaseDialog>
|
||||
@@ -1015,7 +1006,7 @@ const SettingsUserSection = () => {
|
||||
},
|
||||
desc: 'Recover your data using the recovery key if your password is lost.'
|
||||
},
|
||||
/* {
|
||||
/* {
|
||||
name: 'Change password',
|
||||
func: async () => {
|
||||
eSendEvent(eOpenLoginDialog, 3);
|
||||
@@ -1335,7 +1326,7 @@ const SettingsAppearanceSection = () => {
|
||||
style={{
|
||||
backgroundColor:
|
||||
settings.homepage === item.name
|
||||
? colors.shade
|
||||
? colors.nav
|
||||
: 'transparent'
|
||||
}}
|
||||
textStyle={{
|
||||
@@ -1398,17 +1389,17 @@ const SettingsPrivacyAndSecurity = () => {
|
||||
{
|
||||
title: 'None',
|
||||
value: 'none',
|
||||
desc: 'Disable app lock. Notes will be accessible to anyone who opens the app'
|
||||
desc: 'Disable app lock. Notes can be accessed by anyone who opens the app'
|
||||
},
|
||||
{
|
||||
title: 'Secure Mode',
|
||||
value: 'launch',
|
||||
desc: 'Lock app on launch and keep it unlocked when you switch to other apps.'
|
||||
desc: 'Locks app on launch and keeps it unlocked when you switch to other apps.'
|
||||
},
|
||||
{
|
||||
title: 'Strict Mode',
|
||||
value: 'background',
|
||||
desc: 'Lock app on launch and also when you switch from other apps or background.'
|
||||
desc: 'Locks app on launch and also when you switch from other apps or background.'
|
||||
}
|
||||
];
|
||||
|
||||
@@ -1423,7 +1414,7 @@ const SettingsPrivacyAndSecurity = () => {
|
||||
: 'Enable biometery unlock',
|
||||
description: vaultStatus.biometryEnrolled
|
||||
? 'Disable biometric unlocking for notes in vault'
|
||||
: 'Disable biometric unlocking for notes in vault'
|
||||
: 'Enable biometric unlocking for notes in vault'
|
||||
});
|
||||
};
|
||||
|
||||
@@ -1439,48 +1430,60 @@ const SettingsPrivacyAndSecurity = () => {
|
||||
<DialogHeader
|
||||
title="App lock mode"
|
||||
paragraph="Select the level of security you want to enable."
|
||||
padding={12}
|
||||
/>
|
||||
<Seperator />
|
||||
{modes.map(item => (
|
||||
<PressableButton
|
||||
type={
|
||||
settings.appLockMode === item.value ? 'accent' : 'transparent'
|
||||
}
|
||||
onPress={() => {
|
||||
SettingsService.set('appLockMode', item.value);
|
||||
}}
|
||||
customStyle={{
|
||||
justifyContent: 'flex-start',
|
||||
alignItems: 'flex-start',
|
||||
paddingHorizontal: 6,
|
||||
paddingVertical: 6,
|
||||
marginTop: 3,
|
||||
marginBottom: 3
|
||||
}}
|
||||
style={{
|
||||
marginBottom: 10
|
||||
}}>
|
||||
<Heading
|
||||
color={
|
||||
settings.appLockMode === item.value ? 'white' : colors.pri
|
||||
<View
|
||||
style={{
|
||||
paddingHorizontal: 12
|
||||
}}>
|
||||
{modes.map(item => (
|
||||
<PressableButton
|
||||
type={
|
||||
settings.appLockMode === item.value
|
||||
? 'grayBg'
|
||||
: 'transparent'
|
||||
}
|
||||
style={{maxWidth: '95%'}}
|
||||
size={SIZE.md}>
|
||||
{item.title}
|
||||
</Heading>
|
||||
<Paragraph
|
||||
color={
|
||||
settings.appLockMode === item.value ? 'white' : colors.icon
|
||||
}
|
||||
style={{maxWidth: '95%'}}
|
||||
size={SIZE.sm}>
|
||||
{item.desc}
|
||||
</Paragraph>
|
||||
</PressableButton>
|
||||
))}
|
||||
onPress={() => {
|
||||
SettingsService.set('appLockMode', item.value);
|
||||
}}
|
||||
customStyle={{
|
||||
justifyContent: 'flex-start',
|
||||
alignItems: 'flex-start',
|
||||
paddingHorizontal: 6,
|
||||
paddingVertical: 6,
|
||||
marginTop: 3,
|
||||
marginBottom: 3
|
||||
}}
|
||||
style={{
|
||||
marginBottom: 10
|
||||
}}>
|
||||
<Heading
|
||||
color={
|
||||
settings.appLockMode === item.value
|
||||
? colors.accent
|
||||
: colors.pri
|
||||
}
|
||||
style={{maxWidth: '95%'}}
|
||||
size={SIZE.md}>
|
||||
{item.title}
|
||||
</Heading>
|
||||
<Paragraph
|
||||
color={
|
||||
settings.appLockMode === item.value
|
||||
? colors.accent
|
||||
: colors.icon
|
||||
}
|
||||
style={{maxWidth: '95%'}}
|
||||
size={SIZE.sm}>
|
||||
{item.desc}
|
||||
</Paragraph>
|
||||
</PressableButton>
|
||||
))}
|
||||
</View>
|
||||
|
||||
<DialogButtons
|
||||
negativeTitle="Close"
|
||||
negativeTitle="Done"
|
||||
onPressNegative={() => {
|
||||
setAppLockVisible(false);
|
||||
}}
|
||||
@@ -1780,11 +1783,11 @@ export const SettingsBackupAndRestore = ({isSheet}) => {
|
||||
func: async () => {
|
||||
if (!user || !user?.email) {
|
||||
ToastEvent.show({
|
||||
heading:"Login required",
|
||||
message:"Please login to your account to restore backup",
|
||||
type:"error",
|
||||
context:'global'
|
||||
})
|
||||
heading: 'Login required',
|
||||
message: 'Please login to your account to restore backup',
|
||||
type: 'error',
|
||||
context: 'global'
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (isSheet) {
|
||||
|
||||
Reference in New Issue
Block a user