Files
notesnook/apps/mobile/initializer.root.js

641 lines
18 KiB
JavaScript
Raw Normal View History

2021-01-08 12:30:05 +05:00
import {
activateKeepAwake,
2021-06-05 21:10:20 +05:00
deactivateKeepAwake
2021-01-08 12:30:05 +05:00
} from '@sayem314/react-native-keep-awake';
2021-06-05 21:10:20 +05:00
import React, { Component, createRef, useEffect, useRef, useState } from 'react';
import { Dimensions, FlatList, TextInput, View } from 'react-native';
import Animated, { useValue } from 'react-native-reanimated';
import { notesnook } from './e2e/test.ids';
2020-11-23 11:30:55 +05:00
import ContextMenu from './src/components/ContextMenu';
2021-06-05 21:10:20 +05:00
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 { NavigatorStack } from './src/navigation/NavigatorStack';
import { useTracked } from './src/provider';
import { useSettingStore } from './src/provider/stores';
import { DDS } from './src/services/DeviceDetection';
2020-11-23 11:30:55 +05:00
import {
eSendEvent,
eSubscribeEvent,
2021-06-05 21:10:20 +05:00
eUnSubscribeEvent
2020-11-23 11:30:55 +05:00
} from './src/services/EventManager';
2021-06-05 21:10:20 +05:00
import { editing, setWidthHeight } from './src/utils';
import { updateStatusBarColor } from './src/utils/Colors';
2020-11-23 11:30:55 +05:00
import {
eClearEditor,
2020-11-23 11:30:55 +05:00
eCloseFullscreenEditor,
eCloseSideMenu,
eOnLoadNote,
eOpenFullscreenEditor,
2021-06-05 21:10:20 +05:00
eOpenSideMenu
2020-11-23 11:30:55 +05:00
} from './src/utils/Events';
2021-06-05 21:10:20 +05:00
import { editorRef, tabBarRef } from './src/utils/Refs';
import { sleep } from './src/utils/TimeUtils';
import { EditorWrapper } from './src/views/Editor/EditorWrapper';
import { EditorWebView, getNote } from './src/views/Editor/Functions';
2021-02-04 14:39:02 +05:00
import tiny from './src/views/Editor/tiny/tiny';
2020-11-23 11:30:55 +05:00
let {width, height} = Dimensions.get('window');
let layoutTimer = null;
2020-12-01 17:32:01 +05:00
let currentTab = 0;
2021-01-08 12:30:05 +05:00
2021-06-03 18:48:44 +05:00
const onChangeTab = async obj => {
2021-06-05 01:35:58 +05:00
console.log(obj.i);
2020-11-23 11:30:55 +05:00
if (obj.i === 1) {
2021-06-05 01:35:58 +05:00
console.log('making note');
2020-11-23 11:30:55 +05:00
eSendEvent(eCloseSideMenu);
editing.movedAway = false;
2020-12-01 17:32:01 +05:00
currentTab = 1;
2021-01-03 12:39:22 +05:00
activateKeepAwake();
eSendEvent('navigate');
eSendEvent(eClearEditor, 'addHandler');
2021-06-03 18:48:44 +05:00
if (
!editing.isRestoringState &&
(!editing.currentlyEditing || !getNote())
) {
2021-06-05 01:35:58 +05:00
console.log('new note');
2020-11-23 11:30:55 +05:00
eSendEvent(eOnLoadNote, {type: 'new'});
editing.currentlyEditing = true;
}
2021-02-22 13:06:19 +05:00
sleep(1000).then(() => {
updateStatusBarColor();
});
2020-11-23 11:30:55 +05:00
} else {
if (obj.from === 1) {
2021-02-22 13:06:19 +05:00
updateStatusBarColor();
2021-01-03 12:39:22 +05:00
deactivateKeepAwake();
eSendEvent(eClearEditor, 'removeHandler');
if (getNote()?.locked) {
eSendEvent(eClearEditor);
}
2021-02-22 13:06:19 +05:00
eSendEvent('showTooltip');
editing.movedAway = true;
2021-02-04 14:39:02 +05:00
tiny.call(EditorWebView, tiny.blur);
2020-11-23 11:30:55 +05:00
}
2021-01-14 14:25:36 +05:00
editing.isFocused = false;
2020-12-01 17:32:01 +05:00
currentTab = 0;
2020-11-23 11:30:55 +05:00
eSendEvent(eOpenSideMenu);
}
};
2021-01-08 12:30:05 +05:00
export const RootView = React.memo(
() => {
return (
<>
2021-06-03 18:48:44 +05:00
<AppStack />
2021-01-08 12:30:05 +05:00
<Toast />
<ContextMenu />
<DummyText />
<DialogManager />
</>
);
},
() => true,
);
2020-11-23 11:30:55 +05:00
2020-12-01 17:32:01 +05:00
let updatedDimensions = {
width: width,
height: height,
};
2020-12-05 11:57:55 +05:00
let currentScroll = 0;
let startLocation = 0;
2020-12-06 11:49:40 +05:00
let startLocationX = 0;
2021-06-03 18:48:44 +05:00
const _responder = e => {
2020-12-06 09:52:52 +05:00
startLocation = e.nativeEvent.pageY;
2020-12-07 10:13:30 +05:00
startLocationX = e.nativeEvent.pageX;
2020-12-06 09:52:52 +05:00
_handleTouch();
return false;
};
2021-06-03 18:48:44 +05:00
const _moveResponder = e => {
2020-12-06 09:52:52 +05:00
_handleTouch();
return false;
};
2020-12-12 11:37:53 +05:00
let touchEndTimer = null;
2020-12-06 09:52:52 +05:00
const _handleTouch = () => {
{
2021-02-04 14:39:02 +05:00
let heightCheck = !editing.tooltip
? updatedDimensions.height - 70
: updatedDimensions.height - 140;
2020-12-12 11:37:53 +05:00
if (
2021-02-04 14:39:02 +05:00
(currentTab === 1 && startLocation > heightCheck) ||
(currentTab === 1 && startLocationX > 50) ||
2020-12-12 11:37:53 +05:00
(currentTab === 0 && startLocationX < 150)
) {
2020-12-06 09:52:52 +05:00
if (currentScroll === 0 || currentScroll === 1) {
tabBarRef.current?.setScrollEnabled(false);
}
2020-12-08 10:42:26 +05:00
} else {
2020-12-06 09:52:52 +05:00
tabBarRef.current?.setScrollEnabled(true);
}
}
};
2021-06-03 18:48:44 +05:00
const _onTouchEnd = e => {
2020-12-06 09:52:52 +05:00
startLocation = 0;
2020-12-12 11:37:53 +05:00
clearTimeout(touchEndTimer);
touchEndTimer = null;
touchEndTimer = setTimeout(() => {
tabBarRef.current?.setScrollEnabled(true);
}, 200);
2020-12-06 09:52:52 +05:00
};
2020-11-23 11:30:55 +05:00
const AppStack = React.memo(
() => {
const [state, dispatch] = useTracked();
2021-06-05 21:10:20 +05:00
const {colors} = state;
const deviceMode = useSettingStore(state => state.deviceMode);
const setFullscreen = useSettingStore(state => state.setFullscreen);
const setDeviceModeState = useSettingStore(state => state.setDeviceMode);
2020-11-23 11:30:55 +05:00
const [dimensions, setDimensions] = useState({width, height});
2021-06-03 18:48:44 +05:00
const animatedOpacity = useValue(0);
2021-06-05 01:35:58 +05:00
const overlayRef = useRef();
2021-06-05 21:10:20 +05:00
2020-11-23 11:30:55 +05:00
const showFullScreenEditor = () => {
2021-06-05 21:10:20 +05:00
setFullscreen(true);
2020-11-23 11:30:55 +05:00
editorRef.current?.setNativeProps({
style: {
position: 'absolute',
width: dimensions.width,
zIndex: 999,
paddingHorizontal: dimensions.width * 0.15,
backgroundColor: colors.bg,
},
});
};
const closeFullScreenEditor = () => {
2021-06-05 21:10:20 +05:00
setFullscreen(false);
2020-11-23 11:30:55 +05:00
editorRef.current?.setNativeProps({
style: {
position: 'relative',
width: dimensions.width * 0.55,
zIndex: null,
paddingHorizontal: 0,
},
});
};
useEffect(() => {
2021-06-05 01:35:58 +05:00
toggleView(false);
2020-11-23 11:30:55 +05:00
eSubscribeEvent(eOpenFullscreenEditor, showFullScreenEditor);
eSubscribeEvent(eCloseFullscreenEditor, closeFullScreenEditor);
return () => {
eUnSubscribeEvent(eOpenFullscreenEditor, showFullScreenEditor);
eUnSubscribeEvent(eCloseFullscreenEditor, closeFullScreenEditor);
};
}, []);
2021-06-03 18:48:44 +05:00
const _onLayout = async event => {
2020-11-23 11:30:55 +05:00
if (layoutTimer) {
clearTimeout(layoutTimer);
layoutTimer = null;
}
2020-12-01 17:32:01 +05:00
2020-11-23 11:30:55 +05:00
let size = event?.nativeEvent?.layout;
2020-12-01 17:32:01 +05:00
updatedDimensions = size;
2021-02-06 13:28:27 +05:00
if (!size || (size.width === dimensions.width && deviceMode !== null)) {
2020-12-19 13:15:34 +05:00
DDS.setSize(size);
2021-02-15 11:06:12 +05:00
//console.log(deviceMode, 'MODE__');
2021-06-05 21:10:20 +05:00
setDeviceModeState(deviceMode)
2020-11-23 11:30:55 +05:00
return;
}
2021-02-06 13:28:27 +05:00
2020-11-23 11:30:55 +05:00
layoutTimer = setTimeout(async () => {
checkDeviceType(size);
}, 500);
};
function checkDeviceType(size) {
setDimensions({
width: size.width,
height: size.height,
});
2020-12-01 17:32:01 +05:00
2020-11-23 11:30:55 +05:00
setWidthHeight(size);
DDS.setSize(size);
2021-02-15 11:06:12 +05:00
//console.log(DDS.isLargeTablet(), size, DDS.isSmallTab);
2020-11-23 11:30:55 +05:00
if (DDS.isLargeTablet()) {
2021-02-15 11:06:12 +05:00
//console.log('setting large tab');
2020-11-23 11:30:55 +05:00
setDeviceMode('tablet', size);
2021-06-05 01:35:58 +05:00
tabBarRef.current?.goToIndex(0)
2021-06-03 18:48:44 +05:00
sleep(300).then(r => eSendEvent(eOpenSideMenu));
2020-11-23 11:30:55 +05:00
} else if (DDS.isSmallTab) {
2021-02-15 11:06:12 +05:00
//console.log('setting small tab');
2020-11-23 11:30:55 +05:00
setDeviceMode('smallTablet', size);
2021-06-05 01:35:58 +05:00
tabBarRef.current?.goToIndex(0)
2021-06-03 18:48:44 +05:00
sleep(300).then(r => eSendEvent(eOpenSideMenu));
2020-11-23 11:30:55 +05:00
} else {
setDeviceMode('mobile', size);
2021-06-05 01:35:58 +05:00
tabBarRef.current?.goToIndex(1)
2021-06-03 18:48:44 +05:00
sleep(300).then(r => eSendEvent(eOpenSideMenu));
2020-11-23 11:30:55 +05:00
}
}
function setDeviceMode(current, size) {
eSendEvent(current !== 'mobile' ? eCloseSideMenu : eOpenSideMenu);
2021-06-05 21:10:20 +05:00
setDeviceModeState(current);
setFullscreen(false);
2020-12-29 17:21:45 +05:00
2020-11-23 11:30:55 +05:00
editorRef.current?.setNativeProps({
style: {
position: 'relative',
width: current === 'tablet' ? size.width * 0.55 : size.width,
zIndex: null,
paddingHorizontal: 0,
},
});
if (!editing.movedAway && current !== 'tablet') {
2020-11-23 11:30:55 +05:00
tabBarRef.current?.goToPage(1);
}
}
2021-06-05 01:35:58 +05:00
const onScroll = scrollOffset => {
if (scrollOffset > 299) {
animatedOpacity.setValue(0);
toggleView(false);
} else {
2021-06-05 01:35:58 +05:00
let o = scrollOffset / 300;
let op = 0;
if (o < 0) {
op = 1;
} else {
op = 1 - o;
}
animatedOpacity.setValue(op);
toggleView(true);
}
};
2021-06-03 18:48:44 +05:00
const toggleView = show => {
2021-06-05 01:35:58 +05:00
overlayRef.current?.setNativeProps({
style: {
display: show ? 'flex' : 'none',
zIndex: show ? 999 : -10,
},
});
2021-06-03 18:48:44 +05:00
};
2020-11-23 11:30:55 +05:00
return (
<View
onLayout={_onLayout}
2020-11-30 16:16:03 +05:00
testID={notesnook.ids.default.root}
2020-11-23 11:30:55 +05:00
style={{
width: '100%',
height: '100%',
backgroundColor: colors.bg,
2021-06-05 01:35:58 +05:00
}}>
2021-02-06 13:28:27 +05:00
{deviceMode && (
2021-06-03 18:48:44 +05:00
<CustomTabs
2020-11-23 11:30:55 +05:00
ref={tabBarRef}
style={{
zIndex: 1,
}}
2021-06-03 18:48:44 +05:00
onDrawerStateChange={state => {
2021-06-05 01:35:58 +05:00
//console.log(state);
2021-06-03 18:48:44 +05:00
}}
2021-06-05 01:35:58 +05:00
initialIndex={deviceMode === 'smallTablet' ? 0 : 1}
2021-06-03 18:48:44 +05:00
offsets={{
2021-06-05 01:35:58 +05:00
a: deviceMode === 'smallTablet' ? dimensions.width : 300,
b:
deviceMode === 'smallTablet'
? dimensions.width
: dimensions.width + 300,
c:
deviceMode === 'smallTablet'
? dimensions.width * 2
: dimensions.width * 2 + 300,
2021-06-03 18:48:44 +05:00
}}
items={[
<View
style={{
height: '100%',
2021-06-05 01:35:58 +05:00
width:
deviceMode === 'smallTablet'
? dimensions.width * 0.35
: 300,
2021-06-03 18:48:44 +05:00
}}>
<Menu />
</View>,
<View
style={{
height: '100%',
2021-06-05 01:35:58 +05:00
width:
deviceMode === 'mobile'
? dimensions.width
: dimensions.width * 0.65,
2021-06-03 18:48:44 +05:00
}}>
2021-06-05 01:35:58 +05:00
{deviceMode === 'mobile' && (
<View
style={{
position: 'absolute',
width: '100%',
height: '100%',
display: 'none',
zIndex: -10,
}}
ref={overlayRef}>
<Animated.View
onTouchEnd={() => {
tabBarRef.current?.goToIndex(1)
}}
style={{
backgroundColor: 'rgba(0,0,0,0.2)',
opacity: animatedOpacity,
width: '100%',
height: '100%',
}}
/>
</View>
)}
2021-06-03 18:48:44 +05:00
<NavigatorStack />
</View>,
<EditorWrapper dimensions={dimensions} />,
]}
2021-06-05 01:35:58 +05:00
onScroll={onScroll}
2020-11-23 11:30:55 +05:00
onChangeTab={onChangeTab}
2021-06-03 18:48:44 +05:00
/>
)}
{/* {deviceMode !== 'tablet' && (
2020-11-23 11:30:55 +05:00
<View
style={{
width: dimensions.width,
height: '100%',
borderRightColor: colors.nav,
borderRightWidth: 1,
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'flex-start',
}}>
2021-02-06 13:28:27 +05:00
{deviceMode === 'smallTablet' && (
2020-11-23 11:30:55 +05:00
<View
style={{
height: '100%',
width: dimensions.width * 0.35,
}}>
<Menu />
</View>
)}
<View
style={{
height: '100%',
width:
2021-02-06 13:28:27 +05:00
deviceMode === 'mobile'
2020-11-23 11:30:55 +05:00
? dimensions.width
: dimensions.width * 0.65,
}}>
<NavigatorStack />
</View>
</View>
)}
<View
style={{
width: '100%',
height: '100%',
flexDirection: 'row',
backgroundColor: colors.bg,
}}>
2021-02-06 13:28:27 +05:00
{deviceMode === 'tablet' && (
2020-11-23 11:30:55 +05:00
<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} />
2021-06-03 18:48:44 +05:00
</View> */}
2020-11-23 11:30:55 +05:00
</View>
);
},
() => true,
);
2021-06-03 18:48:44 +05:00
class CustomTabs extends Component {
constructor(props) {
super(props);
this.listRef = createRef();
2021-06-05 01:35:58 +05:00
this.scrollOffset = props.initialIndex === 0 ? 0 : 300;
2021-06-03 18:48:44 +05:00
this.page = 0;
2021-06-05 01:35:58 +05:00
this.currentDrawerState = false;
this.inputElement = createRef();
this.keyboardState = false;
this.scrollTimeout = null;
this.scrollEnabled = true;
this.responderAllowedScroll = false;
2021-06-03 18:48:44 +05:00
}
2021-06-05 01:35:58 +05:00
2021-06-03 18:48:44 +05:00
renderItem = ({item, index}) => this.props.items[index];
onMoveShouldSetResponder = event => {
2021-06-05 01:35:58 +05:00
// console.log(this.responderAllowedScroll,'allowed scrolling')
if (this.responderAllowedScroll) return;
let x = event.nativeEvent.pageX;
let y = event.nativeEvent.pageY;
this.hideKeyboardIfVisible();
let cOffset = this.scrollOffset.toFixed(0);
let pOffset = this.props.offsets.b.toFixed(0);
let heightCheck = !editing.tooltip
? updatedDimensions.height - 70
: updatedDimensions.height - 140;
if (cOffset > pOffset - 50) {
if (x > 50 || y > heightCheck) {
this.responderAllowedScroll = false;
this.setScrollEnabled(false);
return;
2021-06-03 18:48:44 +05:00
} else {
2021-06-05 01:35:58 +05:00
this.responderAllowedScroll = true;
this.setScrollEnabled(true);
return;
2021-06-03 18:48:44 +05:00
}
}
2021-06-05 01:35:58 +05:00
this.responderAllowedScroll = true;
2021-06-03 18:48:44 +05:00
};
openDrawer = () => {
console.log('open');
if (this.page === 0) {
2021-06-05 01:35:58 +05:00
this.goToIndex(0);
2021-06-03 18:48:44 +05:00
}
};
closeDrawer = () => {
console.log('close');
if (this.page === 0) {
2021-06-05 01:35:58 +05:00
this.goToIndex(1);
2021-06-03 18:48:44 +05:00
}
};
2021-06-05 01:35:58 +05:00
hideKeyboardIfVisible() {
if ((editing.keyboardState || editing.isFocused) && this.scrollOffset < this.props.offsets.b - 50) {
editing.isFocused = false;
editing.keyboardState = false;
this.inputElement.current?.focus();
this.inputElement.current?.blur();
}
}
goToIndex(index, animated = true) {
// console.log('called me', index);
this.listRef.current?.scrollToIndex({
animated: animated,
index: index,
viewOffset: 0,
viewPosition: 0,
});
}
setScrollEnabled = enabled => {
this.scrollEnabled = enabled;
this.listRef.current?.getNativeScrollRef().setNativeProps({
scrollEnabled: enabled,
});
};
2021-06-03 18:48:44 +05:00
onTouchEnd = () => {
2021-06-05 01:35:58 +05:00
//console.log('touch has ended');
this.responderAllowedScroll = false;
2021-06-03 18:48:44 +05:00
this.listRef.current?.getNativeScrollRef().setNativeProps({
scrollEnabled: true,
});
};
onScroll = event => {
this.scrollOffset = event.nativeEvent.contentOffset.x;
2021-06-05 01:35:58 +05:00
if (this.page === 1) {
this.hideKeyboardIfVisible();
}
2021-06-03 18:48:44 +05:00
this.props.onScroll(this.scrollOffset);
2021-06-05 01:35:58 +05:00
if (this.scrollTimeout) {
clearTimeout(this.scrollTimeout);
this.scrollTimeout = null;
}
this.scrollTimeout = setTimeout(() => {
if (
this.scrollOffset !== this.props.offsets.a &&
this.page === 1 &&
!this.scrollEnabled
) {
this.goToIndex(2, false);
}
}, 300);
2021-06-03 18:48:44 +05:00
};
goToPage = page => {
if (page === 0) {
2021-06-05 01:35:58 +05:00
this.scrollOffset = this.props.offsets.a;
this.hideKeyboardIfVisible();
this.goToIndex(1);
2021-06-03 18:48:44 +05:00
} else if (page === 1) {
2021-06-05 01:35:58 +05:00
this.goToIndex(2);
}
if (this.page !== page) {
this.props.onChangeTab({i: page, from: this.page});
this.page = page;
2021-06-03 18:48:44 +05:00
}
};
keyExtractor = (item, index) => item;
onScrollEnd = event => {
2021-06-05 01:35:58 +05:00
//console.log('scroll end');
this.responderAllowedScroll = false;
let page = 0;
if (this.scrollOffset > this.props.offsets.b - 50) {
page = 1;
} else {
this.hideKeyboardIfVisible();
}
let drawerState = page === 0 && this.scrollOffset < 10;
if (drawerState !== this.currentDrawerState) {
this.currentDrawerState = drawerState;
this.props.onDrawerStateChange(this.currentDrawerState);
}
if (this.page !== page) {
console.log(page);
this.props.onChangeTab({i: page, from: this.page});
this.page = page;
2021-06-03 18:48:44 +05:00
}
};
render() {
return (
<View
onTouchEnd={this.onTouchEnd}
2021-06-05 01:35:58 +05:00
onMoveShouldSetResponderCapture={this.onMoveShouldSetResponder}
onStartShouldSetResponderCapture={this.onMoveShouldSetResponder}
2021-06-03 18:48:44 +05:00
style={{
flex: 1,
}}>
2021-06-05 01:35:58 +05:00
<TextInput
ref={this.inputElement}
style={{height: 1, padding: 0, width: 1, position: 'absolute'}}
blurOnSubmit={false}
/>
2021-06-03 18:48:44 +05:00
<FlatList
ref={this.listRef}
horizontal
onMomentumScrollEnd={this.onScrollEnd}
onScrollAnimationEnd={this.onScrollEnd}
keyExtractor={this.keyExtractor}
onScroll={this.onScroll}
bounces={false}
bouncesZoom={false}
initialNumToRender={100}
alwaysBounceHorizontal={false}
scrollToOverflowEnabled={false}
2021-06-05 01:35:58 +05:00
scrollsToTop={false}
scrollEventThrottle={1}
directionalLockEnabled
maintainVisibleContentPosition={true}
2021-06-03 18:48:44 +05:00
overScrollMode="never"
maxToRenderPerBatch={100}
removeClippedSubviews={false}
2021-06-05 01:35:58 +05:00
keyboardDismissMode="none"
2021-06-03 18:48:44 +05:00
keyboardShouldPersistTaps="always"
showsHorizontalScrollIndicator={false}
disableIntervalMomentum={true}
snapToOffsets={[
this.props.offsets.a,
this.props.offsets.b,
this.props.offsets.c,
]}
2021-06-05 01:35:58 +05:00
initialScrollIndex={this.props.initialIndex}
2021-06-03 18:48:44 +05:00
data={['drawer', 'navigation', 'editor']}
renderItem={this.renderItem}
/>
</View>
);
}
}