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

359 lines
11 KiB
JavaScript
Raw Normal View History

2022-07-09 18:42:02 +05:00
import React, { useEffect, useRef } from 'react';
2022-07-20 11:11:12 +05:00
import { Platform, View } from 'react-native';
2022-01-25 10:25:23 +05:00
import RNBootSplash from 'react-native-bootsplash';
import { checkVersion } from 'react-native-check-version';
import { editorState } from '../../screens/editor/tiptap/utils';
import BackupService from '../../services/backup';
2022-03-03 18:03:03 +05:00
import BiometricService from '../../services/biometrics';
import { DDS } from '../../services/device-detection';
import { eSendEvent, presentSheet, ToastEvent } from '../../services/event-manager';
import { setRateAppMessage } from '../../services/message';
import PremiumService from '../../services/premium';
import SettingsService from '../../services/settings';
2022-04-24 05:59:14 +05:00
import { initialize } from '../../stores';
import { useMessageStore } from '../../stores/use-message-store';
2022-04-24 05:59:14 +05:00
import { useNoteStore } from '../../stores/use-notes-store';
import { useSettingStore } from '../../stores/use-setting-store';
2022-04-24 05:59:14 +05:00
import { useThemeStore } from '../../stores/use-theme-store';
import { useUserStore } from '../../stores/use-user-store';
2022-07-19 13:36:45 +05:00
import { DatabaseLogger, db, loadDatabase } from '../../utils/database';
2022-02-28 13:48:59 +05:00
import { MMKV } from '../../utils/database/mmkv';
2022-07-20 11:11:12 +05:00
import { eOpenAnnouncementDialog } from '../../utils/events';
2022-02-28 13:48:59 +05:00
import { tabBarRef } from '../../utils/global-refs';
import { SIZE } from '../../utils/size';
import { sleep } from '../../utils/time';
2022-03-03 18:03:03 +05:00
import { SVG } from '../auth/background';
2022-07-20 11:11:12 +05:00
import Migrate from '../sheets/migrate';
import NewFeature from '../sheets/new-feature/index';
2022-03-03 18:03:03 +05:00
import { Update } from '../sheets/update';
2022-02-28 13:48:59 +05:00
import { Button } from '../ui/button';
2022-03-03 18:03:03 +05:00
import { IconButton } from '../ui/icon-button';
2022-02-28 13:48:59 +05:00
import Input from '../ui/input';
import Seperator from '../ui/seperator';
2022-03-03 18:03:03 +05:00
import { SvgView } from '../ui/svg';
2022-02-28 13:48:59 +05:00
import Heading from '../ui/typography/heading';
import Paragraph from '../ui/typography/paragraph';
import { Walkthrough } from '../walkthroughs';
2022-01-25 10:25:23 +05:00
const Launcher = React.memo(
() => {
const colors = useThemeStore(state => state.colors);
const setLoading = useNoteStore(state => state.setLoading);
const loading = useNoteStore(state => state.loading);
const user = useUserStore(state => state.user);
const verifyUser = useUserStore(state => state.verifyUser);
const setVerifyUser = useUserStore(state => state.setVerifyUser);
const deviceMode = useSettingStore(state => state.deviceMode);
const passwordInputRef = useRef();
const password = useRef();
2022-07-09 18:42:02 +05:00
const introCompleted = useSettingStore(state => state.settings.introCompleted);
const dbInitCompleted = useRef(false);
const loadNotes = async () => {
if (verifyUser) {
return;
2022-02-14 14:54:15 +05:00
}
await restoreEditorState();
2022-04-24 05:59:14 +05:00
setImmediate(() => {
db.notes.init().then(() => {
Walkthrough.init();
2022-07-01 11:53:48 +05:00
initialize();
2022-07-05 14:33:48 +05:00
setImmediate(() => {
setLoading(false);
setImmediate(() => doAppLoadActions());
});
2022-04-24 05:59:14 +05:00
});
});
};
2022-01-25 10:25:23 +05:00
const init = async () => {
if (!dbInitCompleted.current) {
2022-07-15 19:14:40 +05:00
await RNBootSplash.hide({ fade: true });
2022-07-06 12:17:08 +05:00
await loadDatabase();
2022-07-19 13:36:45 +05:00
DatabaseLogger.info('Initializing database');
await db.init();
dbInitCompleted.current = true;
}
2021-12-02 21:21:00 +05:00
2022-07-20 11:11:12 +05:00
if (db.migrations.required() && !verifyUser) {
presentSheet({
component: <Migrate />,
onClose: () => {
loadNotes();
},
disableClosing: true
});
return;
}
if (!verifyUser) {
loadNotes();
2022-07-20 11:11:12 +05:00
} else {
useUserStore.getState().setUser(await db.user?.getUser());
}
2022-03-07 15:19:07 +05:00
};
2022-03-03 18:03:03 +05:00
2022-07-05 14:33:48 +05:00
// useEffect(() => {
// hideSplashScreen();
// }, [verifyUser]);
2022-01-04 13:08:02 +05:00
useEffect(() => {
if (!loading) {
doAppLoadActions();
}
return () => {
dbInitCompleted.current = false;
};
}, [loading]);
2022-01-04 13:08:02 +05:00
const doAppLoadActions = async () => {
await sleep(500);
if (SettingsService.get().sessionExpired) {
eSendEvent('session_expired');
return;
}
2022-07-08 18:25:04 +05:00
await useMessageStore.getState().setAnnouncement();
if (NewFeature.present()) return;
if (await checkAppUpdateAvailable()) return;
if (await checkForRateAppRequest()) return;
if (await checkNeedsBackup()) return;
if (await PremiumService.getRemainingTrialDaysStatus()) return;
2022-04-14 01:25:03 +05:00
if (PremiumService.get() && user) {
if (SettingsService.get().reminder === 'off') {
SettingsService.set({ reminder: 'daily' });
}
if (BackupService.checkBackupRequired()) {
sleep(2000).then(() => BackupService.checkAndRun());
}
}
2022-07-05 14:33:48 +05:00
if (introCompleted) {
useMessageStore.subscribe(state => {
let dialogs = state.dialogs;
if (dialogs.length > 0) {
eSendEvent(eOpenAnnouncementDialog, dialogs[0]);
}
});
}
};
2021-10-05 12:53:08 +05:00
const checkAppUpdateAvailable = async () => {
2022-07-19 13:36:45 +05:00
if (__DEV__) return;
2022-07-06 12:17:08 +05:00
try {
const version = await checkVersion();
if (!version.needsUpdate) return false;
presentSheet({
component: ref => <Update version={version} fwdRef={ref} />
});
return true;
} catch (e) {
return false;
}
};
2021-02-25 12:16:38 +05:00
const restoreEditorState = async () => {
2022-04-13 03:00:04 +05:00
let appState = MMKV.getString('appState');
if (appState) {
appState = JSON.parse(appState);
if (
appState.note &&
!appState.note.locked &&
!appState.movedAway &&
Date.now() < appState.timestamp + 3600000
) {
2022-03-26 16:05:58 +05:00
editorState().currentlyEditing = true;
editorState().isRestoringState = true;
editorState().movedAway = false;
if (!DDS.isTab) {
tabBarRef.current?.goToPage(1);
}
eSendEvent('loadingNote', appState.note);
}
}
};
const checkForRateAppRequest = async () => {
let rateApp = SettingsService.get().rateApp;
2022-03-18 14:40:15 +05:00
if (rateApp && rateApp < Date.now() && !useMessageStore.getState().message?.visible) {
setRateAppMessage();
return true;
}
return false;
};
2021-06-11 09:16:04 +05:00
const checkNeedsBackup = async () => {
return false;
2022-06-15 19:07:49 +05:00
// let { nextBackupRequestTime, reminder } = SettingsService.get();
// if (reminder === 'off' || !reminder) {
// if (nextBackupRequestTime < Date.now()) {
// presentSheet({
// title: 'Backup & restore',
// paragraph: 'Please enable automatic backups to keep your data safe',
// component: <SettingsBackupAndRestore isSheet={true} />
// });
// return true;
// }
// }
// return false;
};
const onUnlockBiometrics = async () => {
if (!(await BiometricService.isBiometryAvailable())) {
ToastEvent.show({
heading: 'Biometrics unavailable',
message: 'Try unlocking the app with your account password'
});
return;
}
let verified = await BiometricService.validateUser('Unlock to access your notes', '');
2021-06-11 09:16:04 +05:00
if (verified) {
setVerifyUser(false);
2022-03-03 18:03:03 +05:00
password.current = null;
2021-06-11 09:16:04 +05:00
}
};
2022-03-03 18:03:03 +05:00
useEffect(() => {
if (verifyUser) {
onUnlockBiometrics();
}
init();
}, [verifyUser]);
2022-02-11 10:38:14 +05:00
const onSubmit = async () => {
if (!password.current) return;
try {
let verified = await db.user.verifyPassword(password.current);
if (verified) {
setVerifyUser(false);
password.current = null;
}
} catch (e) {}
};
return verifyUser ? (
2022-02-11 10:38:14 +05:00
<View
2021-02-25 12:16:38 +05:00
style={{
backgroundColor: colors.bg,
width: '100%',
height: '100%',
position: 'absolute',
zIndex: 999
2022-01-22 12:57:05 +05:00
}}
>
<View
2022-01-25 10:25:23 +05:00
style={{
height: 250,
overflow: 'hidden'
2022-01-25 10:25:23 +05:00
}}
>
<SvgView src={SVG(colors.night ? 'white' : 'black')} height={700} />
</View>
2021-11-18 14:52:07 +05:00
2022-02-11 10:38:14 +05:00
<View
style={{
flex: 1,
justifyContent: 'center',
width: deviceMode !== 'mobile' ? '50%' : Platform.OS == 'ios' ? '95%' : '100%',
paddingHorizontal: 12,
marginBottom: 30,
marginTop: 15
2022-02-11 10:38:14 +05:00
}}
>
<IconButton
name="fingerprint"
size={100}
customStyle={{
width: 100,
height: 100,
marginBottom: 20,
marginTop: user ? 0 : 50
}}
onPress={onUnlockBiometrics}
color={colors.border}
/>
<Heading
color={colors.heading}
style={{
alignSelf: 'center',
textAlign: 'center'
}}
>
Unlock to access your notes
</Heading>
2022-02-11 10:38:14 +05:00
<Paragraph
style={{
alignSelf: 'center',
textAlign: 'center',
fontSize: SIZE.md,
maxWidth: '90%'
}}
>
Please verify it's you
</Paragraph>
<Seperator />
2022-02-11 10:38:14 +05:00
<View
style={{
width: '100%',
padding: 12,
backgroundColor: colors.bg,
flexGrow: 1
2022-02-11 10:38:14 +05:00
}}
>
{user ? (
<>
<Input
fwdRef={passwordInputRef}
secureTextEntry
placeholder="Enter account password"
onChangeText={v => (password.current = v)}
onSubmit={onSubmit}
2022-02-11 10:38:14 +05:00
/>
</>
) : null}
2021-06-11 09:16:04 +05:00
<View
2022-02-11 10:38:14 +05:00
style={{
marginTop: user ? 50 : 25
2022-02-11 10:38:14 +05:00
}}
>
{user ? (
<>
<Button
title="Continue"
type="accent"
onPress={onSubmit}
width={250}
height={45}
style={{
borderRadius: 150,
marginBottom: 10
}}
fontSize={SIZE.md}
/>
</>
) : null}
<Button
title="Unlock with Biometrics"
width={250}
height={45}
style={{
borderRadius: 100
}}
onPress={onUnlockBiometrics}
icon={'fingerprint'}
type={user ? 'grayAccent' : 'accent'}
fontSize={SIZE.md}
/>
</View>
2022-02-11 10:38:14 +05:00
</View>
</View>
</View>
) : null;
},
() => true
);
2021-02-25 12:16:38 +05:00
2022-02-28 13:48:59 +05:00
export default Launcher;