diff --git a/apps/mobile/App.js b/apps/mobile/App.js
index 2837bfd7c..229110bc0 100644
--- a/apps/mobile/App.js
+++ b/apps/mobile/App.js
@@ -1,16 +1,11 @@
import * as NetInfo from '@react-native-community/netinfo';
-import * as Sentry from '@sentry/react-native';
import {EV} from 'notes-core/common';
import React, {useEffect, useState} from 'react';
import {Appearance, AppState, Platform, StatusBar} from 'react-native';
import {enabled} from 'react-native-privacy-snapshot';
import {SafeAreaProvider} from 'react-native-safe-area-context';
-import SplashScreen from 'react-native-splash-screen';
-import {RootView} from './RootView';
import {useTracked} from './src/provider';
import {Actions} from './src/provider/Actions';
-import Backup from './src/services/Backup';
-import {DDS} from './src/services/DeviceDetection';
import {
eSendEvent,
eSubscribeEvent,
@@ -19,27 +14,21 @@ import {
} from './src/services/EventManager';
import IntentService from './src/services/IntentService';
import {setLoginMessage} from './src/services/Message';
-import SettingsService from './src/services/SettingsService';
+import Navigation from './src/services/Navigation';
+import {editing} from './src/utils';
import {COLOR_SCHEME} from './src/utils/Colors';
import {db} from './src/utils/DB';
-import {
- eDispatchAction,
- eOnLoadNote,
- eResetApp,
- eStartSyncer,
-} from './src/utils/Events';
+import {eDispatchAction, eOnLoadNote, eStartSyncer} from './src/utils/Events';
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';
+import {getNote, setIntentNote} from './src/views/Editor/Functions';
-Sentry.init({
- dsn:
- 'https://317a5c31caf64d1e9b27abf15eb1a554@o477952.ingest.sentry.io/5519681',
-});
-let note = null;
+let AppRootView = require('./initializer.intent').IntentView;
+let SettingsService = null;
+let Sentry = null;
const onAppStateChanged = async (state) => {
+ console.log('app state', state);
if (state === 'active') {
StatusBar.setBarStyle(
COLOR_SCHEME.night ? 'light-content' : 'dark-content',
@@ -52,7 +41,18 @@ const onAppStateChanged = async (state) => {
if (SettingsService.get().privacyScreen) {
enabled(false);
}
+ MMKV.removeItem('appState');
} else {
+ if (editing.currentlyEditing) {
+ MMKV.setItem(
+ 'appState',
+ JSON.stringify({
+ editing: editing.currentlyEditing,
+ note: getNote(),
+ }),
+ );
+ }
+
if (SettingsService.get().privacyScreen) {
enabled(true);
}
@@ -75,35 +75,22 @@ const onNetworkStateChanged = (netInfo) => {
const App = () => {
const [, dispatch] = useTracked(),
- [init, setInit] = useState(false);
+ [init, setInit] = useState(false),
+ [intent, setIntent] = useState(false);
const syncChanges = async () => {
- dispatch({type: Actions.ALL});
- },
- resetApp = async () => {
- note = getNote();
- setInit(false);
- await SettingsService.init();
- setInit(true);
- await sleep(300);
- if (note && note.id) {
- eSendEvent(eOnLoadNote, note);
- if (!DDS.isLargeTablet()) {
- tabBarRef.current?.goToPage(1);
- }
- note = null;
+ dispatch({type: Actions.ALL});
+ };
+ const startSyncer = async () => {
+ try {
+ let user = await db.user.get();
+ if (user) {
+ EV.subscribe('db:refresh', syncChanges);
}
- },
- startSyncer = async () => {
- try {
- let user = await db.user.get();
- if (user) {
- EV.subscribe('db:refresh', syncChanges);
- }
- } catch (e) {
- console.log(e);
- }
- };
+ } catch (e) {
+ console.log(e);
+ }
+ };
const onSystemThemeChanged = async () => {
await SettingsService.setTheme();
@@ -111,70 +98,72 @@ const App = () => {
useEffect(() => {
eSubscribeEvent(eStartSyncer, startSyncer);
- eSubscribeEvent(eResetApp, resetApp);
eSubscribeEvent(eDispatchAction, (type) => {
dispatch(type);
});
AppState.addEventListener('change', onAppStateChanged);
+ eSubscribeEvent('nointent', loadMainApp);
Appearance.addChangeListener(onSystemThemeChanged);
let unsub = NetInfo.addEventListener(onNetworkStateChanged);
return () => {
EV.unsubscribe('db:refresh', syncChanges);
eUnSubscribeEvent(eStartSyncer, startSyncer);
- eUnSubscribeEvent(eResetApp, resetApp);
eUnSubscribeEvent(eDispatchAction, (type) => {
dispatch(type);
});
+ eUnSubscribeEvent('nointent', loadMainApp);
AppState.removeEventListener('change', onAppStateChanged);
Appearance.removeChangeListener(onSystemThemeChanged);
unsub();
};
}, []);
+ const loadMainApp = () => {
+ setIntent(false);
+ AppRootView = require('./initializer.root').RootView;
+ setInit(true);
+ backupData().then((r) => r);
+ Sentry = require('@sentry/react-native');
+ Sentry.init({
+ dsn:
+ 'https://317a5c31caf64d1e9b27abf15eb1a554@o477952.ingest.sentry.io/5519681',
+ });
+ };
+
const getUser = async () => {
- let user = await db.user.get();
- if (user) {
- dispatch({type: Actions.USER, user: user});
- dispatch({type: Actions.SYNCING, syncing: true});
- await db.sync();
- dispatch({type: Actions.SYNCING, syncing: false});
- dispatch({type: Actions.ALL});
- await startSyncer();
- } else {
- setLoginMessage(dispatch);
+ try {
+ let user = await db.user.get();
+ if (user) {
+ dispatch({type: Actions.USER, user: user});
+ dispatch({type: Actions.SYNCING, syncing: true});
+ await db.sync();
+ dispatch({type: Actions.SYNCING, syncing: false});
+ dispatch({type: Actions.ALL});
+ await startSyncer();
+ } else {
+ setLoginMessage(dispatch);
+ }
+ } catch (e) {
+ console.log(e);
}
};
useEffect(() => {
- SettingsService.init().then((r) => r);
- let error = null;
- (async () => {
- try {
- await db.init();
- } catch (e) {
- error = e;
- console.log(e, 'ERROR DB');
- } finally {
- dispatch({type: Actions.ALL});
- getUser().catch((e) => console.log);
- backupData().then((r) => r);
- }
- setInit(true);
- setTimeout(() => {
- if (error) {
- console.log(error);
- ToastEvent.show('Error initializing database.');
- }
- IntentService.check();
- SplashScreen.hide();
- }, 100);
- })();
+ SettingsService = require('./src/services/SettingsService').default;
+ SettingsService.init().finally(() => {
+ db.init().finally(runAfterInit);
+ });
}, []);
+ const runAfterInit = () => {
+ setIntent(true);
+ dispatch({type: Actions.ALL});
+ getUser().catch((e) => console.log);
+ };
+
async function backupData() {
- await sleep(1000);
- let settings = await MMKV.getStringAsync('settings');
- settings = JSON.parse(settings);
+ let settings = SettingsService.get();
+ let Backup = require('./src/services/Backup').default;
if (await Backup.checkBackupRequired(settings.reminder)) {
try {
await Backup.run();
@@ -185,11 +174,10 @@ const App = () => {
}
return (
- <>
-
- <>{!init ? <>> : }>
-
- >
+
+ {intent && }
+ {init && !intent && }
+
);
};
diff --git a/apps/mobile/initializer.intent.js b/apps/mobile/initializer.intent.js
new file mode 100644
index 000000000..cc8bc5873
--- /dev/null
+++ b/apps/mobile/initializer.intent.js
@@ -0,0 +1,20 @@
+import React from 'react';
+import { DialogManager } from './src/components/DialogManager';
+import { DummyText } from './src/components/DummyText';
+import { Toast } from './src/components/Toast';
+import { useTracked } from './src/provider';
+import { EditorWrapper } from './src/views/Editor/EditorWrapper';
+
+export const IntentView = () => {
+ const [state] = useTracked();
+ const {colors} = state;
+
+ return (
+ <>
+
+
+
+
+ >
+ );
+};
diff --git a/apps/mobile/initializer.root.js b/apps/mobile/initializer.root.js
new file mode 100644
index 000000000..24e15731a
--- /dev/null
+++ b/apps/mobile/initializer.root.js
@@ -0,0 +1,269 @@
+import React, {useEffect, useState} from 'react';
+import {Dimensions, View} from 'react-native';
+import ScrollableTabView from 'react-native-scrollable-tab-view';
+import SplashScreen from 'react-native-splash-screen';
+import ContextMenu from './src/components/ContextMenu';
+import {DialogManager} from './src/components/DialogManager';
+import {DummyText} from './src/components/DummyText';
+import {Menu} from './src/components/Menu';
+import {Toast} from './src/components/Toast';
+import {NavigationStack} from './src/navigation/Drawer';
+import {NavigatorStack} from './src/navigation/NavigatorStack';
+import {useTracked} from './src/provider';
+import {Actions} from './src/provider/Actions';
+import {DDS} from './src/services/DeviceDetection';
+import {
+ eSendEvent,
+ eSubscribeEvent,
+ eUnSubscribeEvent,
+} from './src/services/EventManager';
+import {editing, setWidthHeight} from './src/utils';
+import {
+ eCloseFullscreenEditor,
+ eCloseSideMenu,
+ eOnLoadNote,
+ eOpenFullscreenEditor,
+ eOpenSideMenu,
+} from './src/utils/Events';
+import {editorRef, tabBarRef} from './src/utils/Refs';
+import {sleep} from './src/utils/TimeUtils';
+import {EditorWrapper} from './src/views/Editor/EditorWrapper';
+import {getIntent, getNote, post} from './src/views/Editor/Functions';
+
+let {width, height} = Dimensions.get('window');
+let movedAway = true;
+let layoutTimer = null;
+
+const onChangeTab = async (obj) => {
+ if (obj.i === 1) {
+ eSendEvent(eCloseSideMenu);
+ if (getIntent()) return;
+ movedAway = false;
+ if (!editing.currentlyEditing || !getNote()) {
+ eSendEvent(eOnLoadNote, {type: 'new'});
+ editing.currentlyEditing = true;
+ }
+ } else {
+ if (obj.from === 1) {
+ movedAway = true;
+ post('blur');
+ }
+ eSendEvent(eOpenSideMenu);
+ }
+};
+
+export const RootView = () => {
+ const [state] = useTracked();
+ const {colors} = state;
+
+ return (
+ <>
+
+
+
+
+
+ >
+ );
+};
+
+const AppStack = React.memo(
+ () => {
+ const [state, dispatch] = useTracked();
+ const {colors} = state;
+ const [mode, setMode] = useState(null);
+ const [dimensions, setDimensions] = useState({width, height});
+
+ const showFullScreenEditor = () => {
+ dispatch({type: Actions.FULLSCREEN, state: true});
+ editorRef.current?.setNativeProps({
+ style: {
+ position: 'absolute',
+ width: dimensions.width,
+ zIndex: 999,
+ paddingHorizontal: dimensions.width * 0.15,
+ backgroundColor: colors.bg,
+ },
+ });
+ };
+
+ const closeFullScreenEditor = () => {
+ dispatch({type: Actions.FULLSCREEN, state: false});
+ editorRef.current?.setNativeProps({
+ style: {
+ position: 'relative',
+ width: dimensions.width * 0.55,
+ zIndex: null,
+ paddingHorizontal: 0,
+ },
+ });
+ };
+
+ useEffect(() => {
+ eSubscribeEvent(eOpenFullscreenEditor, showFullScreenEditor);
+ eSubscribeEvent(eCloseFullscreenEditor, closeFullScreenEditor);
+
+ return () => {
+ eUnSubscribeEvent(eOpenFullscreenEditor, showFullScreenEditor);
+ eUnSubscribeEvent(eCloseFullscreenEditor, closeFullScreenEditor);
+ };
+ }, []);
+
+ const _onLayout = async (event) => {
+ if (layoutTimer) {
+ clearTimeout(layoutTimer);
+ layoutTimer = null;
+ }
+ let size = event?.nativeEvent?.layout;
+ if (!size || (size.width === dimensions.width && mode !== null)) {
+ return;
+ }
+ layoutTimer = setTimeout(async () => {
+ checkDeviceType(size);
+ }, 500);
+ };
+
+ function checkDeviceType(size) {
+ setDimensions({
+ width: size.width,
+ height: size.height,
+ });
+ setWidthHeight(size);
+ DDS.setSize(size);
+ DDS.checkSmallTab(size.width > size.height ? 'LANDSCAPE' : 'PORTRAIT');
+ if (DDS.isLargeTablet()) {
+ setDeviceMode('tablet', size);
+ } else if (DDS.isSmallTab) {
+ setDeviceMode('smallTablet', size);
+ } else {
+ setDeviceMode('mobile', size);
+ }
+ }
+
+ function setDeviceMode(current, size) {
+ eSendEvent(current !== 'mobile' ? eCloseSideMenu : eOpenSideMenu);
+ setMode(current);
+ dispatch({type: Actions.DEVICE_MODE, state: current});
+ dispatch({type: Actions.FULLSCREEN, state: false});
+ editorRef.current?.setNativeProps({
+ style: {
+ position: 'relative',
+ width: current === 'tablet' ? size.width * 0.55 : size.width,
+ zIndex: null,
+ paddingHorizontal: 0,
+ },
+ });
+ if (!movedAway && current !== 'tablet') {
+ tabBarRef.current?.goToPage(1);
+ }
+ sleep(50).then(() => SplashScreen.hide());
+ }
+
+ const _responder = (e) => {
+ const swiperLeftAreaLocation = 60;
+ const swiperRightAreaLocation = dimensions.width - 100;
+ let pageX = e.nativeEvent.pageX;
+ if (pageX <= swiperLeftAreaLocation || pageX >= swiperRightAreaLocation) {
+ tabBarRef.current?.setScrollEnabled(true);
+ } else {
+ tabBarRef.current?.setScrollEnabled(false);
+ }
+ return false;
+ };
+
+ return (
+
+ {mode && (
+ <>>}>
+ {mode !== 'tablet' && (
+
+ {mode === 'smallTablet' && (
+
+
+
+ )}
+
+
+
+
+
+ )}
+
+
+ {mode === 'tablet' && (
+
+
+
+
+
+
+
+
+
+ )}
+
+
+
+ )}
+
+ );
+ },
+ () => true,
+);