mirror of
https://github.com/streetwriters/notesnook.git
synced 2025-12-23 23:19:40 +01:00
improve navigation performance
This commit is contained in:
9
apps/mobile/android/app/proguard-rules.pro
vendored
9
apps/mobile/android/app/proguard-rules.pro
vendored
@@ -29,3 +29,12 @@
|
||||
|
||||
-keep class com.samsung.android.sdk.** { *; }
|
||||
-dontwarn com.samsung.android.sdk.**
|
||||
|
||||
-keep public class com.dylanvann.fastimage.* {*;}
|
||||
-keep public class com.dylanvann.fastimage.** {*;}
|
||||
-keep public class * implements com.bumptech.glide.module.GlideModule
|
||||
-keep public class * extends com.bumptech.glide.module.AppGlideModule
|
||||
-keep public enum com.bumptech.glide.load.ImageHeaderParser$** {
|
||||
**[] $VALUES;
|
||||
public *;
|
||||
}
|
||||
@@ -2,7 +2,8 @@ import 'react-native-gesture-handler';
|
||||
import React from 'react';
|
||||
import {AppRegistry} from 'react-native';
|
||||
import {name as appName} from './app.json';
|
||||
|
||||
import { enableScreens } from 'react-native-screens';
|
||||
enableScreens(true);
|
||||
let Provider;
|
||||
let App;
|
||||
let NotesnookShare;
|
||||
|
||||
@@ -1147,8 +1147,8 @@
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = Notesnook/Notesnook.entitlements;
|
||||
CODE_SIGN_IDENTITY = "iPhone Distribution";
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 1340;
|
||||
DEVELOPMENT_TEAM = 53CWBG3QUC;
|
||||
GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
|
||||
@@ -1228,7 +1228,7 @@
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.streetwriters.notesnook;
|
||||
PRODUCT_NAME = Notesnook;
|
||||
PROVISIONING_PROFILE_SPECIFIER = "Notesnook iOS Distribution";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "Notesnook-Bridging-Header.h";
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
@@ -1476,8 +1476,8 @@
|
||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||
CODE_SIGN_ENTITLEMENTS = "Make Note/Make Note.entitlements";
|
||||
CODE_SIGN_IDENTITY = "iPhone Distribution";
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 1340;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
@@ -1556,7 +1556,7 @@
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.streetwriters.notesnook.share;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "Notesnook Extension iOS Distribution 2";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "Make Note/Make Note-Bridging-Header.h";
|
||||
SWIFT_VERSION = 5.0;
|
||||
|
||||
@@ -3,7 +3,7 @@ import { View } from 'react-native';
|
||||
import { useTracked } from '../../provider';
|
||||
import { Header } from '../Header';
|
||||
|
||||
export const ContainerTopSection = ({root}) => {
|
||||
export const ContainerTopSection = ({children}) => {
|
||||
const [state] = useTracked();
|
||||
const {colors, selectionMode} = state;
|
||||
|
||||
@@ -20,7 +20,7 @@ export const ContainerTopSection = ({root}) => {
|
||||
},
|
||||
],
|
||||
}}>
|
||||
<Header root={root} />
|
||||
{children}
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -2,7 +2,6 @@ import React from 'react';
|
||||
import { KeyboardAvoidingView, Platform, SafeAreaView } from 'react-native';
|
||||
import Animated from 'react-native-reanimated';
|
||||
import { useTracked } from '../../provider';
|
||||
import { getElevation } from '../../utils';
|
||||
import { ContainerScale } from '../../utils/Animations';
|
||||
import SelectionHeader from '../SelectionHeader';
|
||||
import { ContainerTopSection } from './ContainerTopSection';
|
||||
@@ -30,8 +29,7 @@ export const Container = ({children, root}) => {
|
||||
}
|
||||
]
|
||||
}}>
|
||||
<SelectionHeader />
|
||||
<ContainerTopSection root={root} />
|
||||
|
||||
{children}
|
||||
</AnimatedView>
|
||||
</KeyboardAvoidingView>
|
||||
|
||||
@@ -379,7 +379,7 @@ export class DialogManager extends Component {
|
||||
<VaultDialog colors={colors} />
|
||||
<MoveNoteDialog colors={colors} />
|
||||
<SortDialog colors={colors} />
|
||||
<JumpToDialog />
|
||||
|
||||
<UpdateDialog />
|
||||
<RateDialog/>
|
||||
</>
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import React from 'react';
|
||||
import { notesnook } from '../../../e2e/test.ids';
|
||||
import { useTracked } from '../../provider';
|
||||
import { DDS } from '../../services/DeviceDetection';
|
||||
import { eSubscribeEvent, eUnSubscribeEvent } from '../../services/EventManager';
|
||||
import Navigation from '../../services/Navigation';
|
||||
import { SIZE } from '../../utils/SizeUtils';
|
||||
import { ActionIcon } from '../ActionIcon';
|
||||
|
||||
@@ -1,18 +1,16 @@
|
||||
import React, {useEffect, useState} from 'react';
|
||||
import React from 'react';
|
||||
import { ActivityIndicator, StyleSheet, View } from 'react-native';
|
||||
import { notesnook } from '../../../e2e/test.ids';
|
||||
import { useTracked } from '../../provider';
|
||||
import { DDS } from '../../services/DeviceDetection';
|
||||
import {eSubscribeEvent, eUnSubscribeEvent} from '../../services/EventManager';
|
||||
import Navigation from '../../services/Navigation';
|
||||
import {dWidth} from '../../utils';
|
||||
import { SIZE } from '../../utils/SizeUtils';
|
||||
import { ActionIcon } from '../ActionIcon';
|
||||
import { Button } from '../Button';
|
||||
|
||||
export const HeaderRightMenu = ({currentScreen}) => {
|
||||
const [state] = useTracked();
|
||||
const {colors, containerBottomButton, syncing} = state;
|
||||
const {colors, syncing} = state;
|
||||
|
||||
return (
|
||||
<View style={styles.rightBtnContainer}>
|
||||
@@ -33,11 +31,9 @@ export const HeaderRightMenu = ({currentScreen}) => {
|
||||
/>
|
||||
)}
|
||||
|
||||
{DDS.isLargeTablet() && containerBottomButton.onPress ? (
|
||||
{DDS.isLargeTablet() ? (
|
||||
<Button
|
||||
onPress={() => {
|
||||
containerBottomButton.onPress();
|
||||
}}
|
||||
onPress={action}
|
||||
testID={notesnook.ids.default.addBtn}
|
||||
icon={currentScreen === 'Trash' ? 'delete' : 'plus'}
|
||||
iconSize={SIZE.xl}
|
||||
|
||||
@@ -1,50 +1,27 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import Animated from 'react-native-reanimated';
|
||||
import React, { useEffect } from 'react';
|
||||
import Animated, { useValue } from 'react-native-reanimated';
|
||||
import { useTracked } from '../../provider';
|
||||
import { DDS } from '../../services/DeviceDetection';
|
||||
import { eSubscribeEvent, eUnSubscribeEvent } from '../../services/EventManager';
|
||||
import Navigation from '../../services/Navigation';
|
||||
import { eScrollEvent } from '../../utils/Events';
|
||||
import Heading from '../Typography/Heading';
|
||||
|
||||
const opacity = new Animated.Value(DDS.isLargeTablet() ? 1 : 0);
|
||||
|
||||
let scrollPostions = {};
|
||||
|
||||
export const HeaderTitle = ({heading,headerColor}) => {
|
||||
export const HeaderTitle = ({heading,headerColor,screen}) => {
|
||||
const [state] = useTracked();
|
||||
const {colors} = state;
|
||||
const opacity = useValue(DDS.isLargeTablet() ? 1 : 0)
|
||||
|
||||
|
||||
const onScroll = async (y) => {
|
||||
const onScroll = async (data) => {
|
||||
if (data.screen !== screen) return;
|
||||
if (DDS.isTab) return;
|
||||
if (typeof y !== 'number') {
|
||||
if (y.type === 'back') {
|
||||
scrollPostions[y.name] = null;
|
||||
return;
|
||||
}
|
||||
if (scrollPostions[y.name]) {
|
||||
if (scrollPostions[y.name] > 200) {
|
||||
opacity.setValue(1);
|
||||
} else {
|
||||
scrollPostions[y.name] = 0;
|
||||
opacity.setValue(0);
|
||||
}
|
||||
} else {
|
||||
scrollPostions[y.name] = 0;
|
||||
opacity.setValue(0);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (y > 75) {
|
||||
let yVal = y - 75;
|
||||
if (data.y > 75) {
|
||||
let yVal = data.y - 75;
|
||||
o = yVal / 75;
|
||||
opacity.setValue(o);
|
||||
} else {
|
||||
opacity.setValue(0);
|
||||
}
|
||||
scrollPostions[heading] = y;
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
@@ -3,7 +3,6 @@ import {Platform, StyleSheet, View} from 'react-native';
|
||||
import {useSafeAreaInsets} from 'react-native-safe-area-context';
|
||||
import {useTracked} from '../../provider';
|
||||
import {eSubscribeEvent, eUnSubscribeEvent} from '../../services/EventManager';
|
||||
import Navigation from '../../services/Navigation';
|
||||
import SearchService from '../../services/SearchService';
|
||||
import {dWidth} from '../../utils';
|
||||
import {eScrollEvent} from '../../utils/Events';
|
||||
@@ -14,30 +13,16 @@ import {HeaderLeftMenu} from './HeaderLeftMenu';
|
||||
import {HeaderRightMenu} from './HeaderRightMenu';
|
||||
import {HeaderTitle} from './HeaderTitle';
|
||||
|
||||
export const Header = ({root}) => {
|
||||
export const Header = React.memo(
|
||||
({root, title, screen, isBack, color, action}) => {
|
||||
const [state] = useTracked();
|
||||
const {colors} = state;
|
||||
const insets = useSafeAreaInsets();
|
||||
const [hide, setHide] = useState(true);
|
||||
const [headerTextState, setHeaderTextState] = useState(
|
||||
Navigation.getHeaderState(),
|
||||
);
|
||||
const currentScreen = headerTextState.currentScreen;
|
||||
|
||||
const onHeaderStateChange = event => {
|
||||
if (!event) return;
|
||||
setHeaderTextState(event);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
eSubscribeEvent('onHeaderStateChange', onHeaderStateChange);
|
||||
return () => {
|
||||
eUnSubscribeEvent('onHeaderStateChange', onHeaderStateChange);
|
||||
};
|
||||
}, []);
|
||||
|
||||
const onScroll = y => {
|
||||
if (y > 150) {
|
||||
const onScroll = data => {
|
||||
if (data.screen !== screen) return;
|
||||
if (data.y > 150) {
|
||||
setHide(false);
|
||||
} else {
|
||||
setHide(true);
|
||||
@@ -65,33 +50,28 @@ export const Header = ({root}) => {
|
||||
},
|
||||
]}>
|
||||
<View style={styles.leftBtnContainer}>
|
||||
<HeaderLeftMenu
|
||||
headerMenuState={headerTextState.verticalMenu}
|
||||
currentScreen={currentScreen}
|
||||
/>
|
||||
<HeaderLeftMenu headerMenuState={!isBack} currentScreen={screen} />
|
||||
|
||||
{(Platform.OS === 'android' || Platform.isPad) &&
|
||||
currentScreen !== 'Search' ? (
|
||||
screen !== 'Search' ? (
|
||||
<HeaderTitle
|
||||
headerColor={headerTextState.color}
|
||||
heading={headerTextState.heading}
|
||||
currentScreen={currentScreen}
|
||||
headerColor={color}
|
||||
heading={title}
|
||||
screen={screen}
|
||||
root={root}
|
||||
/>
|
||||
) : null}
|
||||
</View>
|
||||
{Platform.OS !== 'android' &&
|
||||
!Platform.isPad &&
|
||||
currentScreen !== 'Search' ? (
|
||||
{Platform.OS !== 'android' && !Platform.isPad && screen !== 'Search' ? (
|
||||
<HeaderTitle
|
||||
headerColor={headerTextState.color}
|
||||
heading={headerTextState.heading}
|
||||
currentScreen={currentScreen}
|
||||
headerColor={color}
|
||||
heading={title}
|
||||
screen={screen}
|
||||
root={root}
|
||||
/>
|
||||
) : null}
|
||||
|
||||
{currentScreen === 'Search' ? (
|
||||
{screen === 'Search' ? (
|
||||
<>
|
||||
<View
|
||||
style={{
|
||||
@@ -112,11 +92,13 @@ export const Header = ({root}) => {
|
||||
</View>
|
||||
</>
|
||||
) : (
|
||||
<HeaderRightMenu currentScreen={currentScreen} />
|
||||
<HeaderRightMenu action={action} currentScreen={screen} />
|
||||
)}
|
||||
</View>
|
||||
);
|
||||
};
|
||||
},
|
||||
(prev, next) => prev.title === next.title,
|
||||
);
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
|
||||
@@ -6,7 +6,7 @@ import Seperator from '../../components/Seperator';
|
||||
import {useTracked} from '../../provider';
|
||||
import {DDS} from '../../services/DeviceDetection';
|
||||
import {eSubscribeEvent, eUnSubscribeEvent} from '../../services/EventManager';
|
||||
import {getElevation, scrollRef} from '../../utils';
|
||||
import {getElevation, } from '../../utils';
|
||||
import {
|
||||
eCloseJumpToDialog,
|
||||
eOpenJumpToDialog,
|
||||
@@ -17,7 +17,7 @@ import Heading from '../Typography/Heading';
|
||||
|
||||
const offsets = [];
|
||||
let timeout = null;
|
||||
const JumpToDialog = () => {
|
||||
const JumpToDialog = ({scrollRef}) => {
|
||||
const [state] = useTracked();
|
||||
const {notes, colors, settings} = state;
|
||||
const [visible, setVisible] = useState(false);
|
||||
|
||||
@@ -14,7 +14,7 @@ import {
|
||||
TRASH_SVG,
|
||||
} from '../../assets/images/assets';
|
||||
import {useTracked} from '../../provider';
|
||||
|
||||
import FastImage from 'react-native-fast-image'
|
||||
export const Placeholder = ({type, w, h, color}) => {
|
||||
const [state, dispatch] = useTracked();
|
||||
const {colors} = state;
|
||||
@@ -66,7 +66,7 @@ export const SvgToPngView = ({width, height, src, color, img}) => {
|
||||
{error ? (
|
||||
<SvgXml xml={src} width="100%" height="100%" />
|
||||
) : (
|
||||
<Image
|
||||
<FastImage
|
||||
style={{
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
@@ -74,11 +74,12 @@ export const SvgToPngView = ({width, height, src, color, img}) => {
|
||||
onError={() => {
|
||||
setError(true);
|
||||
}}
|
||||
|
||||
source={{
|
||||
uri: `https://github.com/ammarahm-ed/notesnook/raw/main/assets/${img}-${color.replace(
|
||||
'#',
|
||||
'%23',
|
||||
)}.png`,
|
||||
)}.png`, cache:"immutable",priority:"high"
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
||||
@@ -1,15 +1,9 @@
|
||||
import React, {useEffect, useState} from 'react';
|
||||
import React from 'react';
|
||||
import {View} from 'react-native';
|
||||
import Animated, {Easing, useValue} from 'react-native-reanimated';
|
||||
import {useSafeAreaInsets} from 'react-native-safe-area-context';
|
||||
import {useTracked} from '../../provider';
|
||||
import {Actions} from '../../provider/Actions';
|
||||
import {
|
||||
eSendEvent,
|
||||
eSubscribeEvent,
|
||||
eUnSubscribeEvent,
|
||||
ToastEvent,
|
||||
} from '../../services/EventManager';
|
||||
import {eSendEvent, ToastEvent} from '../../services/EventManager';
|
||||
import Navigation from '../../services/Navigation';
|
||||
import {db} from '../../utils/DB';
|
||||
import {eOpenMoveNoteDialog, eOpenSimpleDialog} from '../../utils/Events';
|
||||
@@ -19,43 +13,14 @@ import {ActionIcon} from '../ActionIcon';
|
||||
import {TEMPLATE_DELETE} from '../DialogManager/Templates';
|
||||
import Heading from '../Typography/Heading';
|
||||
|
||||
export const SelectionHeader = () => {
|
||||
// State
|
||||
export const SelectionHeader = ({screen}) => {
|
||||
const [state, dispatch] = useTracked();
|
||||
const {colors, selectionMode, selectedItemsList} = state;
|
||||
const insets = useSafeAreaInsets();
|
||||
const translateY = useValue(-150);
|
||||
const opacity = useValue(0);
|
||||
|
||||
const [headerTextState, setHeaderTextState] = useState(
|
||||
Navigation.getHeaderState(),
|
||||
);
|
||||
const currentScreen = headerTextState.currentScreen;
|
||||
|
||||
const onHeaderStateChange = (event) => {
|
||||
if (!event) return;
|
||||
setHeaderTextState(event);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
eSubscribeEvent('onHeaderStateChange', onHeaderStateChange);
|
||||
return () => {
|
||||
eUnSubscribeEvent('onHeaderStateChange', onHeaderStateChange);
|
||||
};
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
translateY.setValue(selectionMode ? 0 : -150);
|
||||
Animated.timing(opacity, {
|
||||
duration: 200,
|
||||
toValue: selectionMode ? 1 : 0,
|
||||
easing: Easing.in(Easing.ease),
|
||||
}).start();
|
||||
}, [selectionMode]);
|
||||
|
||||
const addToFavorite = async () => {
|
||||
if (selectedItemsList.length > 0) {
|
||||
selectedItemsList.forEach((item) => {
|
||||
selectedItemsList.forEach(item => {
|
||||
db.notes.note(item.id).favorite();
|
||||
});
|
||||
Navigation.setRoutesToUpdate([
|
||||
@@ -71,7 +36,7 @@ export const SelectionHeader = () => {
|
||||
const restoreItem = async () => {
|
||||
if (selectedItemsList.length > 0) {
|
||||
let noteIds = [];
|
||||
selectedItemsList.forEach((item) => {
|
||||
selectedItemsList.forEach(item => {
|
||||
noteIds.push(item.id);
|
||||
});
|
||||
await db.trash.restore(...noteIds);
|
||||
@@ -92,8 +57,8 @@ export const SelectionHeader = () => {
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Animated.View
|
||||
return !selectionMode ? null : (
|
||||
<View
|
||||
style={{
|
||||
width: '100%',
|
||||
position: 'absolute',
|
||||
@@ -104,13 +69,7 @@ export const SelectionHeader = () => {
|
||||
alignItems: 'center',
|
||||
flexDirection: 'row',
|
||||
zIndex: 999,
|
||||
opacity: opacity,
|
||||
paddingHorizontal: 12,
|
||||
transform: [
|
||||
{
|
||||
translateY: translateY,
|
||||
},
|
||||
],
|
||||
}}>
|
||||
<View
|
||||
style={{
|
||||
@@ -162,9 +121,9 @@ export const SelectionHeader = () => {
|
||||
right: 12,
|
||||
paddingTop: insets.top,
|
||||
}}>
|
||||
{currentScreen === 'Trash' ||
|
||||
currentScreen === 'Notebooks' ||
|
||||
currentScreen === 'Notebook' ? null : (
|
||||
{screen === 'Trash' ||
|
||||
screen === 'Notebooks' ||
|
||||
screen === 'Notebook' ? null : (
|
||||
<ActionIcon
|
||||
onPress={async () => {
|
||||
//dispatch({type: Actions.SELECTION_MODE, enabled: false});
|
||||
@@ -180,7 +139,7 @@ export const SelectionHeader = () => {
|
||||
/>
|
||||
)}
|
||||
|
||||
{currentScreen === 'Favorites' ? (
|
||||
{screen === 'Favorites' ? (
|
||||
<ActionIcon
|
||||
onPress={addToFavorite}
|
||||
customStyle={{
|
||||
@@ -192,7 +151,7 @@ export const SelectionHeader = () => {
|
||||
/>
|
||||
) : null}
|
||||
|
||||
{currentScreen === 'Trash' ? null : (
|
||||
{screen === 'Trash' ? null : (
|
||||
<ActionIcon
|
||||
customStyle={{
|
||||
marginLeft: 10,
|
||||
@@ -207,7 +166,7 @@ export const SelectionHeader = () => {
|
||||
/>
|
||||
)}
|
||||
|
||||
{currentScreen === 'Trash' ? (
|
||||
{screen === 'Trash' ? (
|
||||
<ActionIcon
|
||||
customStyle={{
|
||||
marginLeft: 10,
|
||||
@@ -219,7 +178,7 @@ export const SelectionHeader = () => {
|
||||
/>
|
||||
) : null}
|
||||
</View>
|
||||
</Animated.View>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
import React, {useEffect, useState} from 'react';
|
||||
import React from 'react';
|
||||
import { ActivityIndicator, useWindowDimensions, View } from 'react-native';
|
||||
|
||||
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
||||
import { useTracked } from '../../provider';
|
||||
import {eSubscribeEvent, eUnSubscribeEvent} from '../../services/EventManager';
|
||||
import Navigation from '../../services/Navigation';
|
||||
import { COLORS_NOTE } from '../../utils/Colors';
|
||||
import { SIZE } from '../../utils/SizeUtils';
|
||||
import { Button } from '../Button';
|
||||
@@ -12,34 +9,26 @@ import Seperator from '../Seperator';
|
||||
import Heading from '../Typography/Heading';
|
||||
import Paragraph from '../Typography/Paragraph';
|
||||
|
||||
export const Empty = ({loading = true, placeholderData,absolute}) => {
|
||||
|
||||
export const Empty = ({
|
||||
loading = true,
|
||||
placeholderData,
|
||||
absolute,
|
||||
headerProps,
|
||||
}) => {
|
||||
const [state] = useTracked();
|
||||
const {colors} = state;
|
||||
const [headerTextState, setHeaderTextState] = useState(
|
||||
Navigation.getHeaderState(),
|
||||
);
|
||||
const insets = useSafeAreaInsets();
|
||||
const {height} = useWindowDimensions();
|
||||
|
||||
const onHeaderStateChange = (event) => {
|
||||
if (!event) return;
|
||||
setHeaderTextState(event);
|
||||
};
|
||||
useEffect(() => {
|
||||
eSubscribeEvent('onHeaderStateChange', onHeaderStateChange);
|
||||
return () => {
|
||||
eUnSubscribeEvent('onHeaderStateChange', onHeaderStateChange);
|
||||
};
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<View
|
||||
style={[
|
||||
{
|
||||
backgroundColor: colors.bg,
|
||||
position: absolute? "absolute" : 'relative',
|
||||
position: absolute ? 'absolute' : 'relative',
|
||||
zIndex: absolute ? 10 : null,
|
||||
height: (height - 250) - insets.top,
|
||||
height: height - 250 - insets.top,
|
||||
width: '100%',
|
||||
},
|
||||
]}>
|
||||
@@ -69,16 +58,16 @@ export const Empty = ({loading = true, placeholderData,absolute}) => {
|
||||
fontSize={SIZE.md}
|
||||
accentColor="bg"
|
||||
accentText={
|
||||
COLORS_NOTE[headerTextState?.heading?.toLowerCase()]
|
||||
? headerTextState.heading?.toLowerCase()
|
||||
COLORS_NOTE[headerProps?.heading?.toLowerCase()]
|
||||
? headerProps.heading?.toLowerCase()
|
||||
: 'accent'
|
||||
}
|
||||
/>
|
||||
) : loading ? (
|
||||
<ActivityIndicator
|
||||
color={
|
||||
COLORS_NOTE[headerTextState?.heading?.toLowerCase()]
|
||||
? COLORS_NOTE[headerTextState?.heading?.toLowerCase()]
|
||||
COLORS_NOTE[headerProps?.heading?.toLowerCase()]
|
||||
? COLORS_NOTE[headerProps?.heading?.toLowerCase()]
|
||||
: colors.accent
|
||||
}
|
||||
/>
|
||||
|
||||
@@ -1,18 +1,15 @@
|
||||
import React, {useEffect, useState} from 'react';
|
||||
import {View} from 'react-native';
|
||||
import React, {useEffect, useRef, useState} from 'react';
|
||||
import {RefreshControl, useWindowDimensions} from 'react-native';
|
||||
import {useSafeAreaInsets} from 'react-native-safe-area-context';
|
||||
import {DataProvider, LayoutProvider, RecyclerListView} from 'recyclerlistview';
|
||||
import {useTracked} from '../../provider';
|
||||
import {DDS} from '../../services/DeviceDetection';
|
||||
import {eSendEvent} from '../../services/EventManager';
|
||||
import Navigation from '../../services/Navigation';
|
||||
import SettingsService from '../../services/SettingsService';
|
||||
import Sync from '../../services/Sync';
|
||||
import {dHeight} from '../../utils';
|
||||
import {COLORS_NOTE} from '../../utils/Colors';
|
||||
import {eScrollEvent} from '../../utils/Events';
|
||||
import {sleep} from '../../utils/TimeUtils';
|
||||
import JumpToDialog from '../JumpToDialog';
|
||||
import {NotebookWrapper} from '../NotebookItem/wrapper';
|
||||
import {NoteWrapper} from '../NoteItem/wrapper';
|
||||
import TagItem from '../TagItem';
|
||||
@@ -26,6 +23,10 @@ const header = {
|
||||
type: 'MAIN_HEADER',
|
||||
};
|
||||
|
||||
const empty = {
|
||||
type: 'empty',
|
||||
};
|
||||
|
||||
const SimpleList = ({
|
||||
listData,
|
||||
type,
|
||||
@@ -33,23 +34,23 @@ const SimpleList = ({
|
||||
customRefreshing,
|
||||
refreshCallback,
|
||||
sortMenuButton,
|
||||
scrollRef,
|
||||
jumpToDialog,
|
||||
placeholderData,
|
||||
loading,
|
||||
headerProps = {
|
||||
heading: 'Home',
|
||||
},
|
||||
screen
|
||||
}) => {
|
||||
const [state] = useTracked();
|
||||
const {colors, deviceMode, messageBoardState} = state;
|
||||
const [_loading, setLoading] = useState(true);
|
||||
const [loaded, setLoaded] = useState(false);
|
||||
const [_loading, _setLoading] = useState(true);
|
||||
const [dataProvider, setDataProvider] = useState(
|
||||
new DataProvider((r1, r2) => {
|
||||
return r1 !== r2;
|
||||
}),
|
||||
}).cloneWithRows([header, empty]),
|
||||
);
|
||||
const scrollRef = useRef();
|
||||
|
||||
const insets = useSafeAreaInsets();
|
||||
const {width, fontScale} = useWindowDimensions();
|
||||
@@ -57,28 +58,20 @@ const SimpleList = ({
|
||||
const dataType = type;
|
||||
|
||||
useEffect(() => {
|
||||
if (loading) {
|
||||
setDataProvider(dataProvider.cloneWithRows([header, {type: 'empty'}]));
|
||||
setLoaded(false);
|
||||
}
|
||||
|
||||
if (!loading) {
|
||||
setDataProvider(
|
||||
dataProvider.cloneWithRows(
|
||||
!listData || listData.length === 0
|
||||
? [header, {type: 'empty'}]
|
||||
? [header, empty]
|
||||
: [header].concat(listData),
|
||||
),
|
||||
);
|
||||
setLoading(false);
|
||||
setTimeout(
|
||||
() => {
|
||||
setLoaded(true);
|
||||
},
|
||||
Navigation.getCurrentScreen() === SettingsService.get().homepage
|
||||
? 1000
|
||||
: 150,
|
||||
);
|
||||
setTimeout(() => {
|
||||
_setLoading(false);
|
||||
}, 500);
|
||||
} else {
|
||||
_setLoading(true);
|
||||
setDataProvider(dataProvider.cloneWithRows([header, empty]));
|
||||
}
|
||||
}, [listData, deviceMode, loading]);
|
||||
|
||||
@@ -92,7 +85,10 @@ const SimpleList = ({
|
||||
const _onScroll = event => {
|
||||
if (!event) return;
|
||||
let y = event.nativeEvent.contentOffset.y;
|
||||
eSendEvent(eScrollEvent, y);
|
||||
eSendEvent(eScrollEvent, {
|
||||
y,
|
||||
screen
|
||||
});
|
||||
};
|
||||
|
||||
const _layoutProvider = new LayoutProvider(
|
||||
@@ -199,6 +195,7 @@ const SimpleList = ({
|
||||
<Empty
|
||||
loading={loading || _loading}
|
||||
placeholderData={placeholderData}
|
||||
headerProps={headerProps}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -237,36 +234,13 @@ const SimpleList = ({
|
||||
};
|
||||
return (
|
||||
<>
|
||||
{loaded && !loading ? null : (
|
||||
<>
|
||||
<View
|
||||
style={{
|
||||
position: 'absolute',
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
backgroundColor: colors.bg,
|
||||
zIndex: 999,
|
||||
}}>
|
||||
<Header
|
||||
title={headerProps.heading}
|
||||
paragraph={headerProps.paragraph}
|
||||
onPress={headerProps.onPress}
|
||||
icon={headerProps.icon}
|
||||
type={dataType}
|
||||
index={0}
|
||||
/>
|
||||
<Empty loading={true} placeholderData={placeholderData} />
|
||||
</View>
|
||||
</>
|
||||
)}
|
||||
|
||||
{_loading ? null : (
|
||||
<>
|
||||
{!loading && (
|
||||
<Announcement
|
||||
color={
|
||||
COLORS_NOTE[headerProps.heading?.toLowerCase()] || colors.accent
|
||||
}
|
||||
/>
|
||||
)}
|
||||
<RecyclerListView
|
||||
ref={scrollRef}
|
||||
layoutProvider={_layoutProvider}
|
||||
@@ -278,8 +252,7 @@ const SimpleList = ({
|
||||
scrollViewProps={scrollProps}
|
||||
style={styles}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
<JumpToDialog scrollRef={scrollRef} />
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -81,7 +81,7 @@ const SplashScreen = () => {
|
||||
useEffect(() => {
|
||||
Storage.read('introCompleted').then(async r => {
|
||||
requestAnimationFrame(() => {
|
||||
if (r) {
|
||||
if (!r) {
|
||||
setVisible(true);
|
||||
timing(opacity, {
|
||||
toValue: 1,
|
||||
|
||||
@@ -14,6 +14,7 @@ import {
|
||||
} from '../services/EventManager';
|
||||
import Navigation from '../services/Navigation';
|
||||
import SettingsService from '../services/SettingsService';
|
||||
import {editing, history} from '../utils';
|
||||
import {eOpenSideMenu} from '../utils/Events';
|
||||
import {rootNavigatorRef} from '../utils/Refs';
|
||||
import {sleep} from '../utils/TimeUtils';
|
||||
@@ -74,8 +75,8 @@ const forSlide = ({current, next, inverted, layouts: {screen}}) => {
|
||||
};
|
||||
|
||||
const screenOptionsForAnimation = {
|
||||
animationEnabled: false,
|
||||
cardStyleInterpolator: forSlide,
|
||||
animationEnabled: true,
|
||||
cardStyleInterpolator: forFade,
|
||||
gestureEnabled: true,
|
||||
};
|
||||
|
||||
@@ -84,8 +85,10 @@ export const NavigatorStack = React.memo(
|
||||
const [, dispatch] = useTracked();
|
||||
const [render, setRender] = React.useState(false);
|
||||
const onStateChange = React.useCallback(() => {
|
||||
if (history.selectionMode) {
|
||||
dispatch({type: Actions.SELECTION_MODE, enabled: false});
|
||||
dispatch({type: Actions.CLEAR_SELECTION});
|
||||
}
|
||||
eSendEvent('navigate');
|
||||
});
|
||||
|
||||
@@ -102,7 +105,6 @@ export const NavigatorStack = React.memo(
|
||||
id: SettingsService.get().homepage.toLowerCase() + '_navigation',
|
||||
},
|
||||
);
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
@@ -126,6 +128,7 @@ export const NavigatorStack = React.memo(
|
||||
headerShown: false,
|
||||
animationEnabled: false,
|
||||
gestureEnabled: false,
|
||||
|
||||
}}>
|
||||
<Stack.Screen name="Notes" component={Home} />
|
||||
<Stack.Screen name="Notebooks" component={Folders} />
|
||||
|
||||
@@ -8,14 +8,10 @@ import {defaultState} from './DefaultState';
|
||||
|
||||
export const reducer = (state, action) => {
|
||||
switch (action.type) {
|
||||
|
||||
case Actions.ALL: {
|
||||
return {
|
||||
...state,
|
||||
notes: db.notes.group(
|
||||
SORT[sortSettings.sort],
|
||||
sortSettings.sortOrder,
|
||||
),
|
||||
notes: db.notes.group(SORT[sortSettings.sort], sortSettings.sortOrder),
|
||||
notebooks: db.notebooks.all,
|
||||
trash: db.trash.all,
|
||||
tags: db.tags.all,
|
||||
@@ -56,10 +52,7 @@ export const reducer = (state, action) => {
|
||||
case Actions.NOTES:
|
||||
return {
|
||||
...state,
|
||||
notes: db.notes.group(
|
||||
SORT[sortSettings.sort],
|
||||
sortSettings.sortOrder,
|
||||
)
|
||||
notes: db.notes.group(SORT[sortSettings.sort], sortSettings.sortOrder),
|
||||
};
|
||||
case Actions.THEME: {
|
||||
return {
|
||||
@@ -134,7 +127,7 @@ export const reducer = (state, action) => {
|
||||
} else {
|
||||
eSendEvent(eOpenSideMenu);
|
||||
}
|
||||
|
||||
history.selectionMode = action.enabled;
|
||||
return {
|
||||
...state,
|
||||
selectionMode: action.enabled,
|
||||
@@ -157,15 +150,18 @@ export const reducer = (state, action) => {
|
||||
if (selectedItems.length === 0) {
|
||||
eSendEvent(eOpenSideMenu);
|
||||
}
|
||||
history.selectionMode =
|
||||
selectedItems.length > 0 ? state.selectionMode : false;
|
||||
return {
|
||||
...state,
|
||||
selectedItemsList: selectedItems,
|
||||
selectionMode: selectedItems.length > 0 ? state.selectionMode : false,
|
||||
selectionMode: history.selectionMode,
|
||||
};
|
||||
}
|
||||
case Actions.CLEAR_SELECTION: {
|
||||
history.selectedItemsList = [];
|
||||
eSendEvent(eOpenSideMenu);
|
||||
history.selectionMode = false;
|
||||
return {
|
||||
...state,
|
||||
selectedItemsList: [],
|
||||
@@ -280,7 +276,7 @@ export const reducer = (state, action) => {
|
||||
return {
|
||||
...state,
|
||||
searching: action.searching.isSearching,
|
||||
searchStatus:action.searching.status
|
||||
searchStatus: action.searching.status,
|
||||
};
|
||||
}
|
||||
case Actions.PREMIUM: {
|
||||
|
||||
@@ -9,7 +9,6 @@ import SettingsService from './SettingsService';
|
||||
let currentScreen = 'Notes';
|
||||
let homeLoaded = false;
|
||||
|
||||
|
||||
function getHomeLoaded() {
|
||||
return homeLoaded;
|
||||
}
|
||||
@@ -47,7 +46,7 @@ function getHeaderState() {
|
||||
|
||||
function clearRouteFromUpdates(routeName) {
|
||||
if (routesToUpdate.indexOf(routeName) !== -1) {
|
||||
routesToUpdate = [...new Set(routesToUpdate)]
|
||||
routesToUpdate = [...new Set(routesToUpdate)];
|
||||
routesToUpdate.splice(routesToUpdate.indexOf(routeName), 1);
|
||||
}
|
||||
}
|
||||
@@ -64,15 +63,14 @@ function routeNeedsUpdate(routeName, callback) {
|
||||
* @param {array} routes
|
||||
*/
|
||||
function setRoutesToUpdate(routes) {
|
||||
|
||||
console.log(currentScreen, "current");
|
||||
console.log(currentScreen, 'current');
|
||||
if (routes.indexOf(currentScreen) > -1) {
|
||||
console.log('updating screen', currentScreen);
|
||||
if (
|
||||
currentScreen === routeNames.NotesPage ||
|
||||
currentScreen === routeNames.Notebook
|
||||
) {
|
||||
console.log(currentScreen ,"CURRENT");
|
||||
console.log(currentScreen, 'CURRENT');
|
||||
eSendEvent(
|
||||
currentScreen === routeNames.NotesPage
|
||||
? refreshNotesPage
|
||||
@@ -124,7 +122,7 @@ function setHeaderState(name, params, item) {
|
||||
headerState.currentScreen = name;
|
||||
headerState.verticalMenu = params.menu;
|
||||
if (headerState) {
|
||||
eSendEvent('onHeaderStateChange', {...headerState});
|
||||
eSendEvent('onHeaderStateChange', {id: headerState.id});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -133,13 +131,11 @@ function goBack() {
|
||||
}
|
||||
|
||||
function push(name, params, item) {
|
||||
currentScreen = name;
|
||||
setHeaderState(name, params, item);
|
||||
rootNavigatorRef.current?.dispatch(StackActions.push(name, params));
|
||||
}
|
||||
|
||||
function replace(name, params, item) {
|
||||
currentScreen = name;
|
||||
setHeaderState(name, params, item);
|
||||
rootNavigatorRef.current?.dispatch(StackActions.replace(name, params));
|
||||
}
|
||||
@@ -181,5 +177,5 @@ export default {
|
||||
routeNeedsUpdate,
|
||||
routeNames,
|
||||
getHomeLoaded,
|
||||
setHomeLoaded
|
||||
setHomeLoaded,
|
||||
};
|
||||
|
||||
@@ -19,7 +19,6 @@ const run = async (context = 'global') => {
|
||||
context: context,
|
||||
});
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
if (e.message === 'You need to login to sync.') {
|
||||
ToastEvent.show({
|
||||
heading:"Enable sync",
|
||||
|
||||
@@ -16,9 +16,9 @@ export const db = new Database(
|
||||
*/
|
||||
|
||||
db.host( __DEV__ ? {
|
||||
API_HOST: 'https://api.notesnook.com',
|
||||
AUTH_HOST: 'https://auth.streetwriters.co',
|
||||
SSE_HOST: 'https://events.streetwriters.co',
|
||||
API_HOST: 'http://192.168.10.3:5264',
|
||||
AUTH_HOST: 'http://192.168.10.3:8264',
|
||||
SSE_HOST: 'http://192.168.10.3:7264',
|
||||
} : {
|
||||
API_HOST: 'https://api.notesnook.com',
|
||||
AUTH_HOST: 'https://auth.streetwriters.co',
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
import {createRef} from 'react';
|
||||
import {Dimensions, NativeModules, Platform} from 'react-native';
|
||||
import {
|
||||
Dimensions,
|
||||
NativeModules,
|
||||
Platform,
|
||||
} from 'react-native';
|
||||
import RNTooltips from 'react-native-tooltips';
|
||||
import {updateEvent} from '../components/DialogManager/recievers';
|
||||
import {dummyRef} from '../components/DummyText';
|
||||
@@ -11,7 +15,7 @@ import {tabBarRef} from './Refs';
|
||||
import {SIZE} from './SizeUtils';
|
||||
|
||||
export const InteractionManager = {
|
||||
runAfterInteractions: (func, time = 150) => setTimeout(func, time),
|
||||
runAfterInteractions: (func, time = 400) => setTimeout(func, time),
|
||||
};
|
||||
|
||||
export const APP_VERSION = 1350;
|
||||
@@ -68,6 +72,7 @@ export const selection = {
|
||||
|
||||
export const history = {
|
||||
selectedItemsList: [],
|
||||
selectionMode: false,
|
||||
};
|
||||
|
||||
export async function showContext(event, title) {
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
import React, {useCallback, useEffect} from 'react';
|
||||
import {ContainerTopSection} from '../../components/Container/ContainerTopSection';
|
||||
import {Header} from '../../components/Header';
|
||||
import {Placeholder} from '../../components/ListPlaceholders';
|
||||
import SelectionHeader from '../../components/SelectionHeader';
|
||||
import SimpleList from '../../components/SimpleList';
|
||||
import {useTracked} from '../../provider';
|
||||
import {Actions} from '../../provider/Actions';
|
||||
@@ -25,8 +28,8 @@ export const Favorites = ({route, navigation}) => {
|
||||
}
|
||||
|
||||
Navigation.routeNeedsUpdate('Favorites', () => {
|
||||
dispatch({type:Actions.FAVORITES})
|
||||
})
|
||||
dispatch({type: Actions.FAVORITES});
|
||||
});
|
||||
|
||||
eSendEvent(eScrollEvent, {name: 'Favorites', type: 'in'});
|
||||
updateSearch();
|
||||
@@ -94,12 +97,18 @@ export const Favorites = ({route, navigation}) => {
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<ContainerTopSection>
|
||||
<SelectionHeader screen="Favorites" />
|
||||
<Header title="Favorites" isBack={false} screen="Favorites" />
|
||||
</ContainerTopSection>
|
||||
<SimpleList
|
||||
listData={favorites}
|
||||
type="notes"
|
||||
refreshCallback={() => {
|
||||
dispatch({type: Actions.FAVORITES});
|
||||
}}
|
||||
screen="Favorites"
|
||||
loading={loading || localLoad}
|
||||
placeholderData={{
|
||||
heading: 'Your favorites',
|
||||
@@ -114,6 +123,7 @@ export const Favorites = ({route, navigation}) => {
|
||||
placeholder={<Placeholder type="favorites" />}
|
||||
placeholderText="Notes you favorite appear here"
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -11,6 +11,9 @@ import {eScrollEvent} from '../../utils/Events';
|
||||
import Navigation from '../../services/Navigation';
|
||||
import {DDS} from '../../services/DeviceDetection';
|
||||
import {InteractionManager} from '../../utils';
|
||||
import { ContainerTopSection } from '../../components/Container/ContainerTopSection';
|
||||
import { Header } from '../../components/Header';
|
||||
import SelectionHeader from '../../components/SelectionHeader';
|
||||
|
||||
export const Folders = ({route, navigation}) => {
|
||||
const [state, dispatch] = useTracked();
|
||||
@@ -97,9 +100,19 @@ export const Folders = ({route, navigation}) => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<ContainerTopSection>
|
||||
<SelectionHeader screen="Notebooks" />
|
||||
<Header
|
||||
title="Notebooks"
|
||||
isBack={false}
|
||||
screen="Notesbooks"
|
||||
action={_onPressBottomButton}
|
||||
/>
|
||||
</ContainerTopSection>
|
||||
<SimpleList
|
||||
listData={notebooks}
|
||||
type="notebooks"
|
||||
screen="Notebooks"
|
||||
focused={() => navigation.isFocused()}
|
||||
loading={loading}
|
||||
placeholderData={{
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import React, {useCallback, useEffect, useState} from 'react';
|
||||
import {ContainerBottomButton} from '../../components/Container/ContainerBottomButton';
|
||||
import {ContainerTopSection} from '../../components/Container/ContainerTopSection';
|
||||
import SimpleList from '../../components/SimpleList';
|
||||
import {useTracked} from '../../provider';
|
||||
import {Actions} from '../../provider/Actions';
|
||||
@@ -11,6 +12,8 @@ import { InteractionManager, scrollRef } from '../../utils';
|
||||
import {db} from '../../utils/DB';
|
||||
import {eOnLoadNote, eScrollEvent} from '../../utils/Events';
|
||||
import {tabBarRef} from '../../utils/Refs';
|
||||
import {Header} from '../../components/Header/index';
|
||||
import SelectionHeader from '../../components/SelectionHeader';
|
||||
export const Home = ({route, navigation}) => {
|
||||
const [state, dispatch] = useTracked();
|
||||
const {loading} = state;
|
||||
@@ -93,8 +96,6 @@ export const Home = ({route, navigation}) => {
|
||||
}, [notes]);
|
||||
|
||||
const updateSearch = () => {
|
||||
|
||||
|
||||
SearchService.update({
|
||||
placeholder: 'Type a keyword to search in notes',
|
||||
data: db?.notes?.all,
|
||||
@@ -104,7 +105,6 @@ export const Home = ({route, navigation}) => {
|
||||
};
|
||||
|
||||
const _onPressBottomButton = async () => {
|
||||
|
||||
if (!DDS.isLargeTablet()) {
|
||||
tabBarRef.current?.goToPage(1);
|
||||
} else {
|
||||
@@ -114,12 +114,23 @@ export const Home = ({route, navigation}) => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<ContainerTopSection>
|
||||
<SelectionHeader screen="Notes" />
|
||||
<Header
|
||||
title="Notes"
|
||||
isBack={false}
|
||||
screen="Notes"
|
||||
action={_onPressBottomButton}
|
||||
/>
|
||||
</ContainerTopSection>
|
||||
|
||||
<SimpleList
|
||||
listData={notes}
|
||||
scrollRef={scrollRef}
|
||||
type="notes"
|
||||
isHome={true}
|
||||
pinned={true}
|
||||
screen="Notes"
|
||||
loading={loading || localLoad}
|
||||
sortMenuButton={true}
|
||||
headerProps={{
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { ContainerBottomButton } from '../../components/Container/ContainerBottomButton';
|
||||
import { ContainerTopSection } from '../../components/Container/ContainerTopSection';
|
||||
import { Header } from '../../components/Header';
|
||||
import SelectionHeader from '../../components/SelectionHeader';
|
||||
import SimpleList from '../../components/SimpleList';
|
||||
import {
|
||||
eSendEvent,
|
||||
eSubscribeEvent,
|
||||
eUnSubscribeEvent,
|
||||
eUnSubscribeEvent
|
||||
} from '../../services/EventManager';
|
||||
import Navigation from '../../services/Navigation';
|
||||
import SearchService from '../../services/SearchService';
|
||||
@@ -14,19 +17,17 @@ import {
|
||||
eOnNewTopicAdded,
|
||||
eOpenAddNotebookDialog,
|
||||
eOpenAddTopicDialog,
|
||||
eScrollEvent,
|
||||
eScrollEvent
|
||||
} from '../../utils/Events';
|
||||
import {sleep} from '../../utils/TimeUtils';
|
||||
|
||||
export const Notebook = ({route, navigation}) => {
|
||||
const [topics, setTopics] = useState(route.params.notebook.topics);
|
||||
const [loading, setLoading] = useState(true);
|
||||
let params = route.params;
|
||||
let pageIsLoaded = false;
|
||||
|
||||
let ranAfterInteractions = false;
|
||||
|
||||
const runAfterInteractions = (time = 150) => {
|
||||
const runAfterInteractions = (time = 400) => {
|
||||
InteractionManager.runAfterInteractions(() => {
|
||||
let notebook = db.notebooks.notebook(params.notebook?.id).data;
|
||||
params.notebook = notebook;
|
||||
@@ -36,14 +37,14 @@ export const Notebook = ({route, navigation}) => {
|
||||
if (loading) {
|
||||
setLoading(false);
|
||||
}
|
||||
},10)
|
||||
}, 10);
|
||||
Navigation.routeNeedsUpdate('Notebook', () => {
|
||||
onLoad();
|
||||
});
|
||||
eSendEvent(eScrollEvent, {name: params.title, type: 'in'});
|
||||
if (params.menu) {
|
||||
navigation.setOptions({
|
||||
animationEnabled: false,
|
||||
animationEnabled: true,
|
||||
gestureEnabled: false,
|
||||
});
|
||||
} else {
|
||||
@@ -56,13 +57,13 @@ export const Notebook = ({route, navigation}) => {
|
||||
ranAfterInteractions = false;
|
||||
}, time);
|
||||
};
|
||||
const onLoad = (data) => {
|
||||
const onLoad = data => {
|
||||
if (data) {
|
||||
setLoading(true);
|
||||
params = data;
|
||||
}
|
||||
|
||||
runAfterInteractions(data ? 150 : 1);
|
||||
runAfterInteractions(data ? 400 : 1);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
@@ -125,12 +126,22 @@ export const Notebook = ({route, navigation}) => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<ContainerTopSection>
|
||||
<SelectionHeader screen="Notebook" />
|
||||
<Header
|
||||
title={params.title}
|
||||
isBack={!params.menu}
|
||||
screen="Notebook"
|
||||
action={_onPressBottomButton}
|
||||
/>
|
||||
</ContainerTopSection>
|
||||
<SimpleList
|
||||
listData={topics}
|
||||
type="topics"
|
||||
refreshCallback={() => {
|
||||
onLoad();
|
||||
}}
|
||||
screen="Notebook"
|
||||
headerProps={{
|
||||
heading: params.title,
|
||||
paragraph: 'Edit notebook',
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
import React, {useCallback, useEffect, useState} from 'react';
|
||||
import {Platform} from 'react-native';
|
||||
import {ContainerBottomButton} from '../../components/Container/ContainerBottomButton';
|
||||
import {ContainerTopSection} from '../../components/Container/ContainerTopSection';
|
||||
import {Header} from '../../components/Header';
|
||||
import SelectionHeader from '../../components/SelectionHeader';
|
||||
import SimpleList from '../../components/SimpleList';
|
||||
import {useTracked} from '../../provider';
|
||||
import {Actions} from '../../provider/Actions';
|
||||
@@ -32,7 +35,7 @@ export const Notes = ({route, navigation}) => {
|
||||
let pageIsLoaded = false;
|
||||
let ranAfterInteractions = false;
|
||||
|
||||
const runAfterInteractions = (time = 150) => {
|
||||
const runAfterInteractions = (time = 400) => {
|
||||
InteractionManager.runAfterInteractions(() => {
|
||||
Navigation.routeNeedsUpdate('NotesPage', () => {
|
||||
init();
|
||||
@@ -61,7 +64,7 @@ export const Notes = ({route, navigation}) => {
|
||||
}
|
||||
if (params.menu) {
|
||||
navigation.setOptions({
|
||||
animationEnabled: false,
|
||||
animationEnabled: true,
|
||||
gestureEnabled: false,
|
||||
});
|
||||
} else {
|
||||
@@ -128,7 +131,7 @@ export const Notes = ({route, navigation}) => {
|
||||
setActionAfterFirstSave();
|
||||
if (!ranAfterInteractions) {
|
||||
ranAfterInteractions = true;
|
||||
runAfterInteractions(data ? 150 : 1);
|
||||
runAfterInteractions(data ? 400 : 1);
|
||||
}
|
||||
|
||||
if (!pageIsLoaded) {
|
||||
@@ -257,9 +260,19 @@ export const Notes = ({route, navigation}) => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<ContainerTopSection>
|
||||
<SelectionHeader screen="NotesPage" />
|
||||
<Header
|
||||
title={headerProps.heading}
|
||||
isBack={!params.menu}
|
||||
screen="NotesPage"
|
||||
action={_onPressBottomButton}
|
||||
/>
|
||||
</ContainerTopSection>
|
||||
<SimpleList
|
||||
listData={notes}
|
||||
type="notes"
|
||||
screen="NotesPage"
|
||||
refreshCallback={_refreshCallback}
|
||||
headerProps={headerProps}
|
||||
loading={loading || localLoad}
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
import React, {useCallback, useEffect} from 'react';
|
||||
import {ContainerTopSection} from '../../components/Container/ContainerTopSection';
|
||||
import {Header} from '../../components/Header';
|
||||
import SelectionHeader from '../../components/SelectionHeader';
|
||||
import SimpleList from '../../components/SimpleList';
|
||||
import {useTracked} from '../../provider';
|
||||
import {Actions} from '../../provider/Actions';
|
||||
@@ -48,13 +51,16 @@ export const Search = ({route, navigation}) => {
|
||||
};
|
||||
}, []);
|
||||
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
<ContainerTopSection>
|
||||
<SelectionHeader screen="Search" />
|
||||
<Header title="Search" isBack={true} screen="Search" />
|
||||
</ContainerTopSection>
|
||||
<SimpleList
|
||||
listData={searchResults}
|
||||
type="search"
|
||||
screen="Search"
|
||||
focused={() => navigation.isFocused()}
|
||||
placeholderText={`Notes you write appear here`}
|
||||
jumpToDialog={true}
|
||||
@@ -68,7 +74,7 @@ export const Search = ({route, navigation}) => {
|
||||
SearchService.getSearchInformation().title
|
||||
}`,
|
||||
button: null,
|
||||
loading:"Searching..."
|
||||
loading: 'Searching...',
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import React, {createRef, useCallback, useEffect, useState} from 'react';
|
||||
import {Linking} from 'react-native';
|
||||
import {
|
||||
Appearance,
|
||||
InteractionManager,
|
||||
Linking,
|
||||
Platform,
|
||||
ScrollView,
|
||||
TouchableOpacity,
|
||||
@@ -13,10 +12,12 @@ import Menu, {MenuItem} from 'react-native-reanimated-material-menu';
|
||||
import AnimatedProgress from 'react-native-reanimated-progress-bar';
|
||||
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
|
||||
import {Button} from '../../components/Button';
|
||||
import {ContainerTopSection} from '../../components/Container/ContainerTopSection';
|
||||
import BaseDialog from '../../components/Dialog/base-dialog';
|
||||
import DialogButtons from '../../components/Dialog/dialog-buttons';
|
||||
import DialogContainer from '../../components/Dialog/dialog-container';
|
||||
import DialogHeader from '../../components/Dialog/dialog-header';
|
||||
import {Header as TopHeader} from '../../components/Header/index';
|
||||
import Input from '../../components/Input';
|
||||
import {PressableButton} from '../../components/PressableButton';
|
||||
import Seperator from '../../components/Seperator';
|
||||
@@ -42,10 +43,8 @@ import SettingsService from '../../services/SettingsService';
|
||||
import {
|
||||
AndroidModule,
|
||||
APP_VERSION,
|
||||
dWidth,
|
||||
getElevation,
|
||||
InteractionManager,
|
||||
MenuItemsList,
|
||||
setSetting,
|
||||
SUBSCRIPTION_PROVIDER,
|
||||
SUBSCRIPTION_STATUS_STRINGS,
|
||||
} from '../../utils';
|
||||
@@ -75,7 +74,7 @@ import {sleep, timeConverter} from '../../utils/TimeUtils';
|
||||
|
||||
let menuRef = createRef();
|
||||
|
||||
const format = (ver) => {
|
||||
const format = ver => {
|
||||
let parts = ver.toString().split('');
|
||||
return `v${parts[0]}.${parts[1]}.${parts[2]}${
|
||||
parts[3] === '0' ? '' : parts[3]
|
||||
@@ -86,20 +85,11 @@ export const Settings = ({navigation}) => {
|
||||
const [state, dispatch] = useTracked();
|
||||
const {colors} = state;
|
||||
const [version, setVersion] = useState(null);
|
||||
|
||||
const [loading, setLoading] = useState(true);
|
||||
let pageIsLoaded = false;
|
||||
|
||||
const onFocus = useCallback(() => {
|
||||
eSendEvent(eScrollEvent, {name: 'Settings', type: 'in'});
|
||||
if (DDS.isLargeTablet()) {
|
||||
dispatch({
|
||||
type: Actions.CONTAINER_BOTTOM_BUTTON,
|
||||
state: {
|
||||
onPress: null,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
eSendEvent(eUpdateSearchState, {
|
||||
placeholder: '',
|
||||
data: [],
|
||||
@@ -125,13 +115,16 @@ export const Settings = ({navigation}) => {
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
InteractionManager.runAfterInteractions(() => {
|
||||
setLoading(false);
|
||||
navigation.addListener('focus', onFocus);
|
||||
db.version()
|
||||
.then((ver) => {
|
||||
.then(ver => {
|
||||
console.log(ver, 'VERSION');
|
||||
setVersion(ver);
|
||||
})
|
||||
.catch((e) => console.log(e, 'VER'));
|
||||
.catch(e => console.log(e, 'VER'));
|
||||
});
|
||||
|
||||
return () => {
|
||||
pageIsLoaded = false;
|
||||
@@ -243,14 +236,21 @@ export const Settings = ({navigation}) => {
|
||||
];
|
||||
|
||||
return (
|
||||
<>
|
||||
<ContainerTopSection>
|
||||
<TopHeader title="Settings" isBack={false} screen="Settings" />
|
||||
</ContainerTopSection>
|
||||
<View
|
||||
style={{
|
||||
height: '100%',
|
||||
backgroundColor: colors.bg,
|
||||
}}>
|
||||
<ScrollView
|
||||
onScroll={(e) =>
|
||||
eSendEvent(eScrollEvent, e.nativeEvent.contentOffset.y)
|
||||
onScroll={e =>
|
||||
eSendEvent(eScrollEvent, {
|
||||
y:e.nativeEvent.contentOffset.y,
|
||||
screen:"Settings"
|
||||
})
|
||||
}
|
||||
scrollEventThrottle={1}
|
||||
style={{
|
||||
@@ -259,14 +259,20 @@ export const Settings = ({navigation}) => {
|
||||
{!DDS.isLargeTablet() && (
|
||||
<Header title="Settings" type="settings" messageCard={false} />
|
||||
)}
|
||||
|
||||
<SettingsUserSection />
|
||||
<SettingsAppearanceSection />
|
||||
|
||||
{!loading && (
|
||||
<>
|
||||
<SettingsPrivacyAndSecurity />
|
||||
<SettingsBackupAndRestore />
|
||||
</>
|
||||
)}
|
||||
|
||||
<SectionHeader title="Other" />
|
||||
|
||||
{otherItems.map((item) => (
|
||||
{otherItems.map(item => (
|
||||
<CustomButton
|
||||
key={item.name}
|
||||
title={item.name}
|
||||
@@ -284,6 +290,7 @@ export const Settings = ({navigation}) => {
|
||||
/>
|
||||
</ScrollView>
|
||||
</View>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -386,7 +393,7 @@ const AccoutLogoutSection = () => {
|
||||
|
||||
<Input
|
||||
placeholder="Enter account password"
|
||||
onChangeText={(v) => {
|
||||
onChangeText={v => {
|
||||
passwordValue = v;
|
||||
}}
|
||||
secureTextEntry={true}
|
||||
@@ -543,7 +550,7 @@ const SettingsUserSection = () => {
|
||||
type: 5,
|
||||
},
|
||||
}; */
|
||||
const getTimeLeft = (t2) => {
|
||||
const getTimeLeft = t2 => {
|
||||
let d1 = new Date(Date.now());
|
||||
let d2 = new Date(t2);
|
||||
let diff = d2.getTime() - d1.getTime();
|
||||
@@ -816,7 +823,7 @@ const SettingsUserSection = () => {
|
||||
},
|
||||
desc: 'Setup a new password for your account.',
|
||||
},
|
||||
].map((item) => (
|
||||
].map(item => (
|
||||
<CustomButton
|
||||
key={item.name}
|
||||
title={item.name}
|
||||
@@ -920,7 +927,7 @@ const SettingsAppearanceSection = () => {
|
||||
'#FF1744',
|
||||
'#B71C1C',
|
||||
'#ffadad',
|
||||
].map((item) => (
|
||||
].map(item => (
|
||||
<PressableButton
|
||||
key={item}
|
||||
customColor={
|
||||
@@ -1078,7 +1085,7 @@ const SettingsPrivacyAndSecurity = () => {
|
||||
|
||||
const checkVaultStatus = useCallback(() => {
|
||||
InteractionManager.runAfterInteractions(() => {
|
||||
db.vault.exists().then(async (r) => {
|
||||
db.vault.exists().then(async r => {
|
||||
let available = await BiometricService.isBiometryAvailable();
|
||||
let fingerprint = await BiometricService.hasInternetCredentials();
|
||||
|
||||
@@ -1134,7 +1141,7 @@ const SettingsPrivacyAndSecurity = () => {
|
||||
paragraph="Select the level of security you want to enable."
|
||||
/>
|
||||
<Seperator />
|
||||
{modes.map((item) => (
|
||||
{modes.map(item => (
|
||||
<PressableButton
|
||||
type={
|
||||
settings.appLockMode === item.value ? 'accent' : 'transparent'
|
||||
@@ -1316,7 +1323,7 @@ const SettingsBackupAndRestore = () => {
|
||||
<>
|
||||
<SectionHeader title="Backup & restore" />
|
||||
|
||||
{backupItemsList.map((item) => (
|
||||
{backupItemsList.map(item => (
|
||||
<CustomButton
|
||||
key={item.name}
|
||||
title={item.name}
|
||||
@@ -1373,7 +1380,7 @@ const SettingsBackupAndRestore = () => {
|
||||
title: 'Weekly',
|
||||
value: 'weekly',
|
||||
},
|
||||
].map((item) => (
|
||||
].map(item => (
|
||||
<TouchableOpacity
|
||||
activeOpacity={1}
|
||||
onPress={async () => {
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
import React, {useCallback, useEffect, useState} from 'react';
|
||||
import {ContainerTopSection} from '../../components/Container/ContainerTopSection';
|
||||
import {Header} from '../../components/Header';
|
||||
import {Placeholder} from '../../components/ListPlaceholders';
|
||||
import SelectionHeader from '../../components/SelectionHeader';
|
||||
import SimpleList from '../../components/SimpleList';
|
||||
import {useTracked} from '../../provider';
|
||||
import {Actions} from '../../provider/Actions';
|
||||
@@ -18,7 +21,6 @@ export const Tags = ({route, navigation}) => {
|
||||
|
||||
let ranAfterInteractions = false;
|
||||
|
||||
|
||||
const runAfterInteractions = () => {
|
||||
InteractionManager.runAfterInteractions(() => {
|
||||
if (loading) {
|
||||
@@ -26,28 +28,18 @@ export const Tags = ({route, navigation}) => {
|
||||
}
|
||||
|
||||
Navigation.routeNeedsUpdate('Tags', () => {
|
||||
dispatch({type:Actions.TAGS})
|
||||
})
|
||||
dispatch({type: Actions.TAGS});
|
||||
});
|
||||
|
||||
eSendEvent(eScrollEvent, {name: 'Tags', type: 'in'});
|
||||
if (DDS.isLargeTablet()) {
|
||||
dispatch({
|
||||
type: Actions.CONTAINER_BOTTOM_BUTTON,
|
||||
state: {
|
||||
onPress: null,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
updateSearch();
|
||||
ranAfterInteractions = false;
|
||||
});
|
||||
|
||||
|
||||
};
|
||||
|
||||
const onFocus = useCallback(() => {
|
||||
if (!ranAfterInteractions) {
|
||||
|
||||
ranAfterInteractions = true;
|
||||
runAfterInteractions();
|
||||
}
|
||||
@@ -93,17 +85,23 @@ export const Tags = ({route, navigation}) => {
|
||||
placeholder: 'Search in tags',
|
||||
data: tags,
|
||||
type: 'tags',
|
||||
title:"Tags"
|
||||
title: 'Tags',
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<ContainerTopSection>
|
||||
<SelectionHeader screen="Tags" />
|
||||
<Header title="Tags" isBack={false} screen="Tags" />
|
||||
</ContainerTopSection>
|
||||
<SimpleList
|
||||
listData={tags}
|
||||
type="tags"
|
||||
headerProps={{
|
||||
heading: 'Tags',
|
||||
}}
|
||||
screen="Tags"
|
||||
loading={loading}
|
||||
focused={() => navigation.isFocused()}
|
||||
placeholderData={{
|
||||
@@ -115,6 +113,7 @@ export const Tags = ({route, navigation}) => {
|
||||
placeholder={<Placeholder type="tags" />}
|
||||
placeholderText="Tags added to notes appear here"
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
import React, {useCallback, useEffect, useState} from 'react';
|
||||
|
||||
import {ContainerBottomButton} from '../../components/Container/ContainerBottomButton';
|
||||
import {ContainerTopSection} from '../../components/Container/ContainerTopSection';
|
||||
import {simpleDialogEvent} from '../../components/DialogManager/recievers';
|
||||
import {TEMPLATE_EMPTY_TRASH} from '../../components/DialogManager/Templates';
|
||||
import {Header} from '../../components/Header';
|
||||
import {Placeholder} from '../../components/ListPlaceholders';
|
||||
import SelectionHeader from '../../components/SelectionHeader';
|
||||
import SimpleList from '../../components/SimpleList';
|
||||
import {useTracked} from '../../provider';
|
||||
import {Actions} from '../../provider/Actions';
|
||||
@@ -33,14 +36,7 @@ export const Trash = ({route, navigation}) => {
|
||||
});
|
||||
|
||||
eSendEvent(eScrollEvent, {name: 'Trash', type: 'in'});
|
||||
if (DDS.isLargeTablet()) {
|
||||
dispatch({
|
||||
type: Actions.CONTAINER_BOTTOM_BUTTON,
|
||||
state: {
|
||||
onPress: null,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
updateSearch();
|
||||
ranAfterInteractions = false;
|
||||
});
|
||||
@@ -101,9 +97,19 @@ export const Trash = ({route, navigation}) => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<ContainerTopSection>
|
||||
<SelectionHeader screen="Trash" />
|
||||
<Header
|
||||
title="Trash"
|
||||
isBack={false}
|
||||
screen="Trash"
|
||||
action={_onPressBottomButton}
|
||||
/>
|
||||
</ContainerTopSection>
|
||||
<SimpleList
|
||||
listData={trash}
|
||||
type="trash"
|
||||
screen="Trash"
|
||||
focused={() => navigation.isFocused()}
|
||||
loading={loading}
|
||||
placeholderData={{
|
||||
|
||||
Reference in New Issue
Block a user