mirror of
https://github.com/streetwriters/notesnook.git
synced 2025-12-22 22:49:45 +01:00
refactor
This commit is contained in:
@@ -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,26 +75,13 @@ 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;
|
||||
}
|
||||
},
|
||||
startSyncer = async () => {
|
||||
};
|
||||
const startSyncer = async () => {
|
||||
try {
|
||||
let user = await db.user.get();
|
||||
if (user) {
|
||||
@@ -111,27 +98,40 @@ 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 () => {
|
||||
try {
|
||||
let user = await db.user.get();
|
||||
if (user) {
|
||||
dispatch({type: Actions.USER, user: user});
|
||||
@@ -143,38 +143,27 @@ const App = () => {
|
||||
} 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 (
|
||||
<>
|
||||
<SafeAreaProvider>
|
||||
<>{!init ? <></> : <RootView />}</>
|
||||
{intent && <AppRootView />}
|
||||
{init && !intent && <AppRootView />}
|
||||
</SafeAreaProvider>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
20
apps/mobile/initializer.intent.js
Normal file
20
apps/mobile/initializer.intent.js
Normal file
@@ -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 (
|
||||
<>
|
||||
<EditorWrapper dimensions={{width: '100%', height: '100%'}} />
|
||||
<Toast />
|
||||
<DummyText />
|
||||
<DialogManager colors={colors} />
|
||||
</>
|
||||
);
|
||||
};
|
||||
269
apps/mobile/initializer.root.js
Normal file
269
apps/mobile/initializer.root.js
Normal file
@@ -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 (
|
||||
<>
|
||||
<NavigationStack component={AppStack} />
|
||||
<Toast />
|
||||
<ContextMenu />
|
||||
<DummyText />
|
||||
<DialogManager colors={colors} />
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
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 (
|
||||
<View
|
||||
onLayout={_onLayout}
|
||||
style={{
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
backgroundColor: colors.bg,
|
||||
}}
|
||||
onStartShouldSetResponder={_responder}>
|
||||
{mode && (
|
||||
<ScrollableTabView
|
||||
ref={tabBarRef}
|
||||
style={{
|
||||
zIndex: 1,
|
||||
}}
|
||||
initialPage={0}
|
||||
prerenderingSiblingsNumber={Infinity}
|
||||
onChangeTab={onChangeTab}
|
||||
renderTabBar={() => <></>}>
|
||||
{mode !== 'tablet' && (
|
||||
<View
|
||||
style={{
|
||||
width: dimensions.width,
|
||||
height: '100%',
|
||||
borderRightColor: colors.nav,
|
||||
borderRightWidth: 1,
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'flex-start',
|
||||
}}>
|
||||
{mode === 'smallTablet' && (
|
||||
<View
|
||||
style={{
|
||||
height: '100%',
|
||||
width: dimensions.width * 0.35,
|
||||
}}>
|
||||
<Menu />
|
||||
</View>
|
||||
)}
|
||||
|
||||
<View
|
||||
style={{
|
||||
height: '100%',
|
||||
width:
|
||||
mode === 'mobile'
|
||||
? dimensions.width
|
||||
: dimensions.width * 0.65,
|
||||
}}>
|
||||
<NavigatorStack />
|
||||
</View>
|
||||
</View>
|
||||
)}
|
||||
|
||||
<View
|
||||
style={{
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
flexDirection: 'row',
|
||||
backgroundColor: colors.bg,
|
||||
}}>
|
||||
{mode === 'tablet' && (
|
||||
<View
|
||||
style={{
|
||||
width: dimensions.width * 0.45,
|
||||
height: '100%',
|
||||
borderRightColor: colors.nav,
|
||||
borderRightWidth: 1,
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
}}>
|
||||
<View
|
||||
style={{
|
||||
height: '100%',
|
||||
width: dimensions.width * 0.15,
|
||||
}}>
|
||||
<Menu />
|
||||
</View>
|
||||
|
||||
<View
|
||||
style={{
|
||||
height: '100%',
|
||||
width: dimensions.width * 0.3,
|
||||
}}>
|
||||
<NavigatorStack />
|
||||
</View>
|
||||
</View>
|
||||
)}
|
||||
<EditorWrapper dimensions={dimensions} />
|
||||
</View>
|
||||
</ScrollableTabView>
|
||||
)}
|
||||
</View>
|
||||
);
|
||||
},
|
||||
() => true,
|
||||
);
|
||||
Reference in New Issue
Block a user