Files
notesnook/apps/mobile/App.js

442 lines
12 KiB
JavaScript
Raw Normal View History

2020-11-16 12:36:41 +05:00
import * as NetInfo from '@react-native-community/netinfo';
2020-12-10 13:06:59 +05:00
import {CHECK_IDS, EV} from 'notes-core/common';
import React, {useEffect, useState} from 'react';
2020-11-24 16:59:12 +05:00
import {
Appearance,
AppState,
Linking,
NativeModules,
Platform,
2020-12-10 13:06:59 +05:00
StatusBar,
2020-11-24 16:59:12 +05:00
} from 'react-native';
2020-12-09 22:16:22 +05:00
import * as RNIap from 'react-native-iap';
2020-12-10 13:06:59 +05:00
import {enabled} from 'react-native-privacy-snapshot';
import {SafeAreaProvider} from 'react-native-safe-area-context';
2020-12-10 09:54:48 +05:00
import SplashScreen from 'react-native-splash-screen';
2020-12-10 13:06:59 +05:00
import {useTracked} from './src/provider';
import {Actions} from './src/provider/Actions';
2020-12-10 15:26:02 +05:00
import {DDS} from './src/services/DeviceDetection';
2020-10-24 13:47:31 +05:00
import {
2020-11-24 16:59:12 +05:00
eSendEvent,
2020-10-24 13:47:31 +05:00
eSubscribeEvent,
eUnSubscribeEvent,
2020-12-10 13:06:59 +05:00
ToastEvent,
2020-10-24 13:47:31 +05:00
} from './src/services/EventManager';
2020-12-10 09:54:48 +05:00
import IntentService from './src/services/IntentService';
2020-12-10 13:06:59 +05:00
import {clearMessage, setLoginMessage} from './src/services/Message';
2020-12-10 09:54:48 +05:00
import Navigation from './src/services/Navigation';
import PremiumService from './src/services/PremiumService';
2020-12-10 13:06:59 +05:00
import {editing} from './src/utils';
import {COLOR_SCHEME} from './src/utils/Colors';
import {db} from './src/utils/DB';
2020-12-06 09:53:17 +05:00
import {
2020-12-09 22:16:22 +05:00
eClosePremiumDialog,
2020-12-06 09:53:17 +05:00
eDispatchAction,
eOnLoadNote,
2020-12-09 22:16:22 +05:00
eOpenPendingDialog,
2020-12-06 09:53:17 +05:00
eOpenPremiumDialog,
eShowGetPremium,
2020-12-10 13:06:59 +05:00
eStartSyncer,
2020-12-06 09:53:17 +05:00
} from './src/utils/Events';
2020-12-10 13:06:59 +05:00
import {MMKV} from './src/utils/mmkv';
import {tabBarRef} from './src/utils/Refs';
import {sleep} from './src/utils/TimeUtils';
import {getNote} from './src/views/Editor/Functions';
2020-11-24 16:59:12 +05:00
const {ReceiveSharingIntent} = NativeModules;
2020-11-17 16:18:43 +05:00
2020-11-24 16:59:12 +05:00
let AppRootView = require('./initializer.root').RootView;
2020-11-23 11:30:55 +05:00
let SettingsService = null;
let Sentry = null;
2020-11-23 15:57:31 +05:00
let appInit = false;
let intentInit = false;
2020-12-09 22:16:22 +05:00
let hasPurchased = false;
const onAppStateChanged = async (state) => {
2020-11-23 11:30:55 +05:00
console.log('app state', state);
if (state === 'active') {
StatusBar.setBarStyle(
2020-11-20 01:11:58 +05:00
COLOR_SCHEME.night ? 'light-content' : 'dark-content',
true,
);
if (Platform.OS === 'android') {
2020-11-20 01:11:58 +05:00
StatusBar.setBackgroundColor('transparent', true);
StatusBar.setTranslucent(true, true);
}
if (SettingsService.get().privacyScreen) {
enabled(false);
}
2020-11-23 15:57:31 +05:00
console.log('clearing state', await MMKV.getItem('appState'));
if (appInit) {
await MMKV.removeItem('appState');
}
2020-12-06 09:53:17 +05:00
try {
if (intentInit) {
if (Platform.OS === 'android') {
_data = await ReceiveSharingIntent.getFileNames();
if (_data) {
IntentService.setIntent(_data);
IntentService.check((event) => {
console.log(event);
if (event) {
eSendEvent(eOnLoadNote, event);
tabBarRef.current?.goToPage(1);
Navigation.closeDrawer();
} else {
eSendEvent('nointent');
SplashScreen.hide();
}
});
}
2020-11-24 16:59:12 +05:00
}
}
2020-12-06 09:53:17 +05:00
} catch (e) {
console.log(e);
2020-11-23 15:57:31 +05:00
}
} else {
if (editing.currentlyEditing && appInit) {
2020-11-23 15:57:31 +05:00
let state = JSON.stringify({
editing: editing.currentlyEditing,
note: getNote(),
});
console.log('putting items in state', state);
await MMKV.setItem('appState', state);
2020-11-23 11:30:55 +05:00
}
if (SettingsService.get().privacyScreen) {
enabled(true);
}
2020-11-16 12:18:59 +05:00
}
2020-11-16 12:13:02 +05:00
};
2020-11-16 12:36:41 +05:00
const onNetworkStateChanged = (netInfo) => {
let message = 'Internet connection restored';
let type = 'success';
if (!netInfo.isConnected || !netInfo.isInternetReachable) {
message = 'No internet connection';
type = 'error';
}
db.user?.get().then((user) => {
if (user && intentInit) {
2020-11-16 12:36:41 +05:00
ToastEvent.show(message, type);
}
});
};
2019-11-15 01:17:59 +05:00
const App = () => {
2020-10-24 13:47:31 +05:00
const [, dispatch] = useTracked(),
2020-11-24 16:59:12 +05:00
[init, setInit] = useState(true),
2020-11-23 11:30:55 +05:00
[intent, setIntent] = useState(false);
2020-11-16 12:36:41 +05:00
2020-10-24 13:47:31 +05:00
const syncChanges = async () => {
2020-12-10 15:26:02 +05:00
console.log('dispatching sync changes')
2020-11-23 11:30:55 +05:00
dispatch({type: Actions.ALL});
};
const startSyncer = async () => {
try {
let user = await db.user.get();
if (user) {
EV.subscribe('db:refresh', syncChanges);
2020-10-24 13:47:31 +05:00
}
2020-11-23 11:30:55 +05:00
} catch (e) {
2020-12-07 14:34:14 +05:00
console.log(e, 'SYNC ERROR');
2020-11-23 11:30:55 +05:00
}
};
2020-10-12 11:24:56 +05:00
2020-11-16 12:36:41 +05:00
const onSystemThemeChanged = async () => {
2020-11-16 13:02:02 +05:00
await SettingsService.setTheme();
2020-11-16 12:36:41 +05:00
};
2020-11-24 16:59:12 +05:00
const _handleIntent = async (res) => {
2020-12-06 09:53:17 +05:00
if (intentInit) {
let url = res ? res.url : '';
2020-12-07 12:14:00 +05:00
2020-12-06 09:53:17 +05:00
try {
2020-12-07 12:14:00 +05:00
if (url.startsWith('ShareMedia://dataUrl')) {
2020-12-07 14:34:14 +05:00
console.log(url);
2020-12-06 09:53:17 +05:00
_data = await ReceiveSharingIntent.getFileNames(url);
2020-12-07 14:34:14 +05:00
_data = IntentService.iosSortedData(_data);
2020-12-06 09:53:17 +05:00
}
if (_data) {
IntentService.setIntent(_data);
IntentService.check((event) => {
eSendEvent(eOnLoadNote, event);
tabBarRef.current?.goToPage(1);
Navigation.closeDrawer();
});
}
2020-12-07 12:14:00 +05:00
} catch (e) {
2020-12-07 14:34:14 +05:00
console.log(e, 'ERROR HERE');
2020-12-07 12:14:00 +05:00
}
2020-12-06 09:53:17 +05:00
}
};
const handlePremiumAccess = async (type) => {
let status = PremiumService.get();
let message = null;
2020-12-08 15:39:29 +05:00
2020-12-06 09:53:17 +05:00
if (!status) {
switch (type) {
case CHECK_IDS.noteColor:
message = {
context: 'sheet',
title: 'Get Notesnook Pro',
desc: 'To assign colors to a note get Notesnook Pro today.',
};
break;
case CHECK_IDS.noteExport:
message = {
context: 'export',
title: 'Export in PDF, MD & HTML',
desc:
'Get Notesnook Pro to export your notes in PDF, Markdown and HTML formats!',
};
break;
case CHECK_IDS.noteTag:
message = {
context: 'sheet',
title: 'Get Notesnook Pro',
desc: 'To create more tags for your notes become a Pro user today.',
};
break;
case CHECK_IDS.notebookAdd:
eSendEvent(eOpenPremiumDialog);
break;
case CHECK_IDS.vaultAdd:
message = {
context: 'sheet',
title: 'Add Notes to Vault',
desc:
'With Notesnook Pro you can add notes to your vault and do so much more! Get it now.',
};
break;
2020-11-24 16:59:12 +05:00
}
2020-12-06 09:53:17 +05:00
if (message) {
eSendEvent(eShowGetPremium, message);
2020-11-24 16:59:12 +05:00
}
2020-12-06 09:53:17 +05:00
}
return {type, result: status};
2020-11-24 16:59:12 +05:00
};
2020-12-09 22:16:22 +05:00
let subsriptionSuccessListerner;
let subsriptionErrorListener;
const attachIAPListeners = () => {
if (Platform.OS === 'ios') {
RNIap.getReceiptIOS()
.then((r) => {
hasPurchased = true;
processReceipt(r);
})
.catch(console.log)
.finally(() => {
subsriptionSuccessListerner = RNIap.purchaseUpdatedListener(
onSuccessfulSubscription,
);
subsriptionErrorListener = RNIap.purchaseErrorListener(
onSubscriptionError,
);
});
} else {
subsriptionSuccessListerner = RNIap.purchaseUpdatedListener(
onSuccessfulSubscription,
);
subsriptionErrorListener = RNIap.purchaseErrorListener(
onSubscriptionError,
);
}
};
2020-12-10 15:26:02 +05:00
const dbSync = async () => {
try {
dispatch({type: Actions.SYNCING, syncing: true});
await db.sync(false);
} catch (e) {
} finally {
dispatch({type: Actions.SYNCING, syncing: false});
}
};
2020-10-24 13:47:31 +05:00
useEffect(() => {
eSubscribeEvent(eStartSyncer, startSyncer);
eSubscribeEvent(eDispatchAction, (type) => {
dispatch(type);
});
2020-12-09 22:16:22 +05:00
attachIAPListeners();
AppState.addEventListener('change', onAppStateChanged);
2020-11-23 11:30:55 +05:00
eSubscribeEvent('nointent', loadMainApp);
2020-11-16 12:36:41 +05:00
Appearance.addChangeListener(onSystemThemeChanged);
let unsub = NetInfo.addEventListener(onNetworkStateChanged);
2020-11-24 16:59:12 +05:00
if (Platform.OS === 'ios') {
Linking.addEventListener('url', _handleIntent);
}
2020-12-10 15:26:02 +05:00
EV.subscribe('db:sync', dbSync);
2020-12-06 09:53:17 +05:00
EV.subscribe('user:checkStatus', handlePremiumAccess);
2020-10-24 13:47:31 +05:00
return () => {
2020-12-10 15:26:02 +05:00
2020-11-16 09:43:53 +05:00
EV.unsubscribe('db:refresh', syncChanges);
2020-12-10 15:26:02 +05:00
EV.unsubscribe('db:sync', dbSync);
2020-10-24 13:47:31 +05:00
eUnSubscribeEvent(eStartSyncer, startSyncer);
eUnSubscribeEvent(eDispatchAction, (type) => {
dispatch(type);
});
2020-11-23 11:30:55 +05:00
eUnSubscribeEvent('nointent', loadMainApp);
AppState.removeEventListener('change', onAppStateChanged);
2020-11-16 12:36:41 +05:00
Appearance.removeChangeListener(onSystemThemeChanged);
2020-11-24 16:59:12 +05:00
if (Platform.OS === 'ios') {
Linking.removeEventListener('url', _handleIntent);
}
2020-11-16 12:36:41 +05:00
unsub();
2020-12-09 22:16:22 +05:00
unsubIAP();
2020-10-24 13:47:31 +05:00
};
}, []);
2020-12-09 22:16:22 +05:00
unsubIAP = () => {
if (subsriptionSuccessListerner) {
subsriptionSuccessListerner?.remove();
subsriptionSuccessListerner = null;
}
if (subsriptionErrorListener) {
subsriptionErrorListener?.remove();
subsriptionErrorListener = null;
}
};
2020-12-09 13:09:55 +05:00
2020-12-09 22:16:22 +05:00
const loadMainApp = () => {
2020-11-24 16:59:12 +05:00
dispatch({type: Actions.ALL});
2020-11-23 11:30:55 +05:00
AppRootView = require('./initializer.root').RootView;
2020-11-24 16:59:12 +05:00
getUser().then(console.log).catch(console.log);
2020-11-23 11:30:55 +05:00
backupData().then((r) => r);
sleep(500).then(() => (appInit = true));
2020-11-24 16:59:12 +05:00
db.notes.init().then(() => {
dispatch({type: Actions.NOTES});
dispatch({type: Actions.LOADING, loading: false});
SettingsService.setAppLoaded();
2020-11-24 16:59:12 +05:00
});
2020-12-09 22:16:22 +05:00
SplashScreen.hide();
//Sentry = require('@sentry/react-native');
2020-11-24 16:59:12 +05:00
// Sentry.init({
// dsn:
// 'https://317a5c31caf64d1e9b27abf15eb1a554@o477952.ingest.sentry.io/5519681',
// });
2020-11-23 11:30:55 +05:00
};
2020-11-15 12:16:22 +05:00
const getUser = async () => {
2020-11-23 11:30:55 +05:00
try {
let user = await db.user.get();
if (user) {
dispatch({type: Actions.SYNCING, syncing: true});
2020-12-07 14:34:14 +05:00
dispatch({type: Actions.USER, user: user});
2020-11-23 11:30:55 +05:00
await db.sync();
dispatch({type: Actions.ALL});
await startSyncer();
2020-12-10 13:06:59 +05:00
clearMessage(dispatch);
2020-11-23 11:30:55 +05:00
} else {
setLoginMessage(dispatch);
}
} catch (e) {
2020-12-07 14:34:14 +05:00
console.log(e, 'SYNC ERROR');
2020-11-15 12:16:22 +05:00
}
2020-12-07 14:34:14 +05:00
dispatch({type: Actions.SYNCING, syncing: false});
2020-11-15 12:16:22 +05:00
};
2020-10-24 13:47:31 +05:00
useEffect(() => {
2020-11-23 11:30:55 +05:00
SettingsService = require('./src/services/SettingsService').default;
SettingsService.init();
2020-12-10 13:06:59 +05:00
dispatch({
type: Actions.DEVICE_MODE,
state: DDS.isLargeTablet()
? 'tablet'
: DDS.isSmallTab
? 'smallTablet'
: 'mobile',
});
db.init().finally(runAfterInit);
2020-10-24 13:47:31 +05:00
}, []);
2020-11-23 11:30:55 +05:00
const runAfterInit = () => {
2020-12-07 16:04:22 +05:00
let isIntent = false;
2020-11-24 16:59:12 +05:00
IntentService.getIntent()
.then(() => {
AppRootView = require('./initializer.intent').IntentView;
setInit(false);
intentInit = true;
2020-11-24 16:59:12 +05:00
dispatch({type: Actions.ALL});
setIntent(true);
2020-12-07 16:04:22 +05:00
isIntent = true;
2020-11-24 16:59:12 +05:00
ReceiveSharingIntent.clearFileNames();
})
2020-12-07 16:04:22 +05:00
.catch((e) => console.log)
.finally(() => {
if (!isIntent) {
ReceiveSharingIntent.clearFileNames();
intentInit = true;
loadMainApp();
}
2020-11-24 16:59:12 +05:00
});
2020-11-23 11:30:55 +05:00
};
2020-10-27 23:05:35 +05:00
async function backupData() {
2020-11-23 11:30:55 +05:00
let settings = SettingsService.get();
let Backup = require('./src/services/Backup').default;
2020-10-28 15:15:35 +05:00
if (await Backup.checkBackupRequired(settings.reminder)) {
try {
await Backup.run();
} catch (e) {
console.log(e);
2020-10-27 23:05:35 +05:00
}
2020-10-28 15:15:35 +05:00
}
2020-10-27 23:05:35 +05:00
}
2020-12-09 22:16:22 +05:00
const onSuccessfulSubscription = (subscription) => {
if (hasPurchased) {
return;
}
const receipt = subscription.transactionReceipt;
processReceipt(receipt);
setTimeout(() => {
eSendEvent(eClosePremiumDialog);
eSendEvent(eOpenPendingDialog);
}, 500);
};
2020-12-10 13:06:59 +05:00
const onSubscriptionError = (error) => {
console.log(error.message, 'Error');
//ToastEvent.show(error.message);
};
2020-12-09 22:16:22 +05:00
2020-12-10 13:06:59 +05:00
const processReceipt = (receipt) => {
2020-12-10 15:26:02 +05:00
return;
2020-12-10 13:06:59 +05:00
if (receipt) {
if (Platform.OS === 'ios') {
fetch('http://192.168.10.5:8100/webhooks/assn', {
method: 'POST',
body: JSON.stringify({
2020-12-10 15:26:02 +05:00
receipt_data: receipt,
2020-12-10 13:06:59 +05:00
}),
headers: {
'Content-Type': 'application/json',
},
2020-12-09 22:16:22 +05:00
})
2020-12-10 13:06:59 +05:00
.then((r) => {
console.log(r.status, 'STATUS');
})
.catch((e) => {
console.log(e, 'ERROR');
});
}
2020-12-09 22:16:22 +05:00
}
2020-12-10 13:06:59 +05:00
};
2020-12-09 22:16:22 +05:00
2020-10-24 13:47:31 +05:00
return (
2020-11-23 11:30:55 +05:00
<SafeAreaProvider>
{intent ? <AppRootView /> : null}
2020-12-09 22:16:22 +05:00
{init && !intent ? <AppRootView /> : null}
2020-11-23 11:30:55 +05:00
</SafeAreaProvider>
2020-10-24 13:47:31 +05:00
);
2019-11-15 01:17:59 +05:00
};
export default App;