2020-04-18 13:39:45 +05:00
|
|
|
import React, {useEffect, useState} from 'react';
|
2020-01-13 14:44:42 +05:00
|
|
|
import {
|
2020-01-18 01:04:33 +05:00
|
|
|
Keyboard,
|
|
|
|
|
KeyboardAvoidingView,
|
|
|
|
|
Platform,
|
2020-01-13 14:44:42 +05:00
|
|
|
SafeAreaView,
|
2020-01-18 01:04:33 +05:00
|
|
|
Text,
|
2020-01-13 14:44:42 +05:00
|
|
|
TouchableOpacity,
|
|
|
|
|
View,
|
|
|
|
|
} from 'react-native';
|
|
|
|
|
import * as Animatable from 'react-native-animatable';
|
2020-02-11 20:07:36 +05:00
|
|
|
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
|
2020-04-18 13:39:45 +05:00
|
|
|
import {br, opacity, pv, SIZE, WEIGHT} from '../../common/common';
|
|
|
|
|
import {useTracked} from '../../provider';
|
|
|
|
|
import {ACTIONS} from '../../provider/actions';
|
|
|
|
|
import {eSubscribeEvent, eUnSubscribeEvent} from '../../services/eventManager';
|
|
|
|
|
import {eScrollEvent, eClearSearch} from '../../services/events';
|
|
|
|
|
import {db, getElevation, ToastEvent, DDS, selection} from '../../utils/utils';
|
|
|
|
|
import {Header} from '../header';
|
|
|
|
|
import {Search} from '../SearchInput';
|
2020-01-25 23:47:17 +05:00
|
|
|
import SelectionHeader from '../SelectionHeader';
|
2020-04-18 13:39:45 +05:00
|
|
|
import {inputRef} from '../../utils/refs';
|
|
|
|
|
import {useSafeArea} from 'react-native-safe-area-context';
|
2020-03-14 13:54:16 +05:00
|
|
|
|
2020-04-18 13:39:45 +05:00
|
|
|
const AnimatedKeyboardAvoidingView = Animatable.createAnimatableComponent(
|
|
|
|
|
KeyboardAvoidingView,
|
|
|
|
|
);
|
2020-01-13 14:44:42 +05:00
|
|
|
|
2020-01-20 16:24:01 +05:00
|
|
|
const AnimatedTouchableOpacity = Animatable.createAnimatableComponent(
|
|
|
|
|
TouchableOpacity,
|
|
|
|
|
);
|
|
|
|
|
|
2020-01-13 14:44:42 +05:00
|
|
|
export const Container = ({
|
|
|
|
|
children,
|
|
|
|
|
bottomButtonOnPress,
|
|
|
|
|
bottomButtonText,
|
2020-01-13 17:34:29 +05:00
|
|
|
noBottomButton = false,
|
2020-01-25 23:47:17 +05:00
|
|
|
data = [],
|
2020-01-27 00:25:19 +05:00
|
|
|
heading,
|
|
|
|
|
canGoBack = true,
|
|
|
|
|
menu,
|
|
|
|
|
customIcon,
|
|
|
|
|
verticalMenu = false,
|
|
|
|
|
preventDefaultMargins,
|
|
|
|
|
navigation = null,
|
|
|
|
|
isLoginNavigator,
|
|
|
|
|
placeholder = '',
|
2020-01-27 13:04:25 +05:00
|
|
|
noSearch = false,
|
|
|
|
|
noSelectionHeader = false,
|
2020-02-07 00:26:44 +05:00
|
|
|
headerColor = null,
|
2020-02-07 00:53:59 +05:00
|
|
|
type = null,
|
2020-01-13 14:44:42 +05:00
|
|
|
}) => {
|
|
|
|
|
// State
|
2020-01-17 21:26:01 +05:00
|
|
|
const [state, dispatch] = useTracked();
|
2020-04-18 13:39:45 +05:00
|
|
|
const {colors, selectionMode, searchResults, loading} = state;
|
2020-01-25 23:47:17 +05:00
|
|
|
const [text, setText] = useState('');
|
|
|
|
|
const [hideHeader, setHideHeader] = useState(false);
|
2020-01-13 14:44:42 +05:00
|
|
|
const [buttonHide, setButtonHide] = useState(false);
|
2020-04-16 13:57:51 +05:00
|
|
|
const insets = useSafeArea();
|
|
|
|
|
|
2020-01-25 23:47:17 +05:00
|
|
|
let offsetY = 0;
|
|
|
|
|
let countUp = 1;
|
|
|
|
|
let countDown = 0;
|
|
|
|
|
let searchResult = [];
|
|
|
|
|
|
|
|
|
|
const onScroll = y => {
|
|
|
|
|
if (searchResults.length > 0) return;
|
2020-01-27 13:04:25 +05:00
|
|
|
if (y < 30) {
|
|
|
|
|
countUp = 1;
|
|
|
|
|
countDown = 0;
|
|
|
|
|
setHideHeader(false);
|
|
|
|
|
}
|
|
|
|
|
|
2020-01-25 23:47:17 +05:00
|
|
|
if (y > offsetY) {
|
|
|
|
|
if (y - offsetY < 150 || countDown > 0) return;
|
|
|
|
|
countDown = 1;
|
|
|
|
|
countUp = 0;
|
|
|
|
|
setHideHeader(true);
|
|
|
|
|
} else {
|
2020-01-27 13:04:25 +05:00
|
|
|
if (offsetY - y < 50 || countUp > 0) return;
|
2020-01-25 23:47:17 +05:00
|
|
|
countDown = 0;
|
|
|
|
|
countUp = 1;
|
|
|
|
|
setHideHeader(false);
|
|
|
|
|
}
|
|
|
|
|
offsetY = y;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const onChangeText = value => {
|
2020-02-07 00:53:59 +05:00
|
|
|
setText(value);
|
2020-01-25 23:47:17 +05:00
|
|
|
};
|
|
|
|
|
const onSubmitEditing = async () => {
|
|
|
|
|
if (!text || text.length < 1) {
|
2020-03-03 11:26:12 +05:00
|
|
|
ToastEvent.show('Please enter a search keyword');
|
2020-01-25 23:47:17 +05:00
|
|
|
clearSearch();
|
2020-03-09 15:30:40 +05:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (!type) return;
|
|
|
|
|
|
|
|
|
|
searchResult = await db.lookup[type](
|
|
|
|
|
data[0].data ? db.notes.all : data,
|
|
|
|
|
text,
|
|
|
|
|
);
|
2020-03-09 18:33:40 +05:00
|
|
|
if (!searchResult || searchResult.length === 0) {
|
|
|
|
|
ToastEvent.show('No search results found for ' + text, 'error');
|
2020-03-09 15:30:40 +05:00
|
|
|
return;
|
2020-03-09 18:33:40 +05:00
|
|
|
} else {
|
|
|
|
|
dispatch({
|
|
|
|
|
type: ACTIONS.SEARCH_RESULTS,
|
|
|
|
|
results: {
|
|
|
|
|
type,
|
|
|
|
|
results: searchResult,
|
|
|
|
|
keyword: text,
|
|
|
|
|
},
|
|
|
|
|
});
|
2020-01-25 23:47:17 +05:00
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const onBlur = () => {
|
|
|
|
|
if (text && text.length < 1) {
|
|
|
|
|
clearSearch();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const onFocus = () => {
|
|
|
|
|
//setSearch(false);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const clearSearch = () => {
|
|
|
|
|
searchResult = null;
|
2020-03-17 10:18:10 +05:00
|
|
|
setText(null);
|
|
|
|
|
inputRef.current?.setNativeProps({
|
|
|
|
|
text: '',
|
|
|
|
|
});
|
2020-03-09 15:30:40 +05:00
|
|
|
dispatch({
|
|
|
|
|
type: ACTIONS.SEARCH_RESULTS,
|
|
|
|
|
results: {
|
|
|
|
|
results: [],
|
|
|
|
|
type: null,
|
|
|
|
|
keyword: null,
|
|
|
|
|
},
|
|
|
|
|
});
|
2020-01-25 23:47:17 +05:00
|
|
|
};
|
|
|
|
|
|
2020-01-13 14:44:42 +05:00
|
|
|
useEffect(() => {
|
2020-03-17 10:18:10 +05:00
|
|
|
eSubscribeEvent(eClearSearch, clearSearch);
|
2020-01-13 14:44:42 +05:00
|
|
|
Keyboard.addListener('keyboardDidShow', () => {
|
2020-01-20 16:24:01 +05:00
|
|
|
setTimeout(() => {
|
2020-03-15 09:39:14 +05:00
|
|
|
if (DDS.isTab) return;
|
2020-01-20 16:24:01 +05:00
|
|
|
setButtonHide(true);
|
|
|
|
|
}, 300);
|
2020-01-13 14:44:42 +05:00
|
|
|
});
|
|
|
|
|
Keyboard.addListener('keyboardDidHide', () => {
|
|
|
|
|
setTimeout(() => {
|
2020-03-15 09:39:14 +05:00
|
|
|
if (DDS.isTab) return;
|
2020-01-13 14:44:42 +05:00
|
|
|
setButtonHide(false);
|
2020-03-15 09:38:23 +05:00
|
|
|
}, 0);
|
2020-01-13 14:44:42 +05:00
|
|
|
});
|
|
|
|
|
return () => {
|
2020-03-17 10:18:10 +05:00
|
|
|
eUnSubscribeEvent(eClearSearch, clearSearch);
|
2020-01-13 14:44:42 +05:00
|
|
|
Keyboard.removeListener('keyboardDidShow', () => {
|
2020-01-20 16:24:01 +05:00
|
|
|
setTimeout(() => {
|
2020-03-15 09:39:14 +05:00
|
|
|
if (DDS.isTab) return;
|
2020-01-20 16:24:01 +05:00
|
|
|
setButtonHide(true);
|
|
|
|
|
}, 300);
|
2020-01-13 14:44:42 +05:00
|
|
|
});
|
|
|
|
|
Keyboard.removeListener('keyboardDidHide', () => {
|
|
|
|
|
setTimeout(() => {
|
2020-03-15 09:39:14 +05:00
|
|
|
if (DDS.isTab) return;
|
2020-01-13 14:44:42 +05:00
|
|
|
setButtonHide(false);
|
2020-03-15 09:38:23 +05:00
|
|
|
}, 0);
|
2020-01-13 14:44:42 +05:00
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
}, []);
|
2020-01-25 23:47:17 +05:00
|
|
|
|
|
|
|
|
useEffect(() => {
|
2020-03-18 11:58:56 +05:00
|
|
|
selection.data = data;
|
|
|
|
|
selection.type = type;
|
2020-01-25 23:47:17 +05:00
|
|
|
eSubscribeEvent(eScrollEvent, onScroll);
|
|
|
|
|
|
|
|
|
|
return () => {
|
|
|
|
|
eUnSubscribeEvent(eScrollEvent, onScroll);
|
|
|
|
|
};
|
|
|
|
|
});
|
|
|
|
|
|
2020-01-13 14:44:42 +05:00
|
|
|
// Render
|
|
|
|
|
|
|
|
|
|
return (
|
2020-04-16 13:57:51 +05:00
|
|
|
<AnimatedKeyboardAvoidingView
|
2020-01-13 14:44:42 +05:00
|
|
|
transition="backgroundColor"
|
|
|
|
|
duration={300}
|
|
|
|
|
style={{
|
|
|
|
|
height: '100%',
|
2020-01-24 22:52:34 +05:00
|
|
|
backgroundColor: colors.bg,
|
2020-04-18 13:39:45 +05:00
|
|
|
paddingTop: insets.top,
|
2020-04-16 13:57:51 +05:00
|
|
|
}}
|
|
|
|
|
behavior="padding"
|
2020-04-18 13:39:45 +05:00
|
|
|
enabled={Platform.OS === 'ios' ? true : false}>
|
2020-04-16 13:57:51 +05:00
|
|
|
{noSelectionHeader ? null : <SelectionHeader items={data} />}
|
|
|
|
|
|
|
|
|
|
<View
|
2020-01-13 14:44:42 +05:00
|
|
|
style={{
|
2020-04-16 13:57:51 +05:00
|
|
|
position: selectionMode ? 'relative' : 'absolute',
|
|
|
|
|
backgroundColor: colors.bg,
|
|
|
|
|
zIndex: 999,
|
|
|
|
|
display: selectionMode ? 'none' : 'flex',
|
|
|
|
|
width: '100%',
|
2020-01-13 14:44:42 +05:00
|
|
|
}}>
|
2020-04-16 13:57:51 +05:00
|
|
|
<Header
|
|
|
|
|
menu={menu}
|
|
|
|
|
hide={hideHeader}
|
|
|
|
|
verticalMenu={verticalMenu}
|
|
|
|
|
showSearch={() => {
|
|
|
|
|
setHideHeader(false);
|
|
|
|
|
countUp = 0;
|
|
|
|
|
countDown = 0;
|
|
|
|
|
}}
|
|
|
|
|
headerColor={headerColor}
|
|
|
|
|
navigation={navigation}
|
|
|
|
|
colors={colors}
|
|
|
|
|
isLoginNavigator={isLoginNavigator}
|
|
|
|
|
preventDefaultMargins={preventDefaultMargins}
|
|
|
|
|
heading={heading}
|
|
|
|
|
canGoBack={canGoBack}
|
|
|
|
|
customIcon={customIcon}
|
|
|
|
|
/>
|
2020-01-25 23:47:17 +05:00
|
|
|
|
2020-04-16 13:57:51 +05:00
|
|
|
{data[0] && !noSearch ? (
|
|
|
|
|
<Search
|
|
|
|
|
clear={() => setText('')}
|
2020-01-26 22:15:08 +05:00
|
|
|
hide={hideHeader}
|
2020-04-16 13:57:51 +05:00
|
|
|
onChangeText={onChangeText}
|
2020-02-07 00:26:44 +05:00
|
|
|
headerColor={headerColor}
|
2020-04-16 13:57:51 +05:00
|
|
|
onSubmitEditing={onSubmitEditing}
|
|
|
|
|
placeholder={placeholder}
|
|
|
|
|
onBlur={onBlur}
|
|
|
|
|
onFocus={onFocus}
|
|
|
|
|
clearSearch={clearSearch}
|
|
|
|
|
value={text}
|
2020-01-26 22:15:08 +05:00
|
|
|
/>
|
2020-04-16 13:57:51 +05:00
|
|
|
) : null}
|
|
|
|
|
</View>
|
2020-01-26 22:15:08 +05:00
|
|
|
|
2020-04-16 13:57:51 +05:00
|
|
|
{children}
|
2020-01-25 23:47:17 +05:00
|
|
|
|
2020-04-16 13:57:51 +05:00
|
|
|
{noBottomButton ? null : (
|
|
|
|
|
<Animatable.View
|
|
|
|
|
transition={['translateY', 'opacity']}
|
|
|
|
|
useNativeDriver={true}
|
|
|
|
|
duration={300}
|
|
|
|
|
style={{
|
|
|
|
|
width: '100%',
|
|
|
|
|
opacity: buttonHide ? 0 : 1,
|
|
|
|
|
position: 'absolute',
|
|
|
|
|
paddingHorizontal: 12,
|
|
|
|
|
zIndex: 10,
|
2020-04-18 13:39:45 +05:00
|
|
|
bottom: Platform.OS === 'ios' ? insets.bottom : 15,
|
2020-04-16 13:57:51 +05:00
|
|
|
transform: [
|
|
|
|
|
{
|
|
|
|
|
translateY: buttonHide ? 200 : 0,
|
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
}}>
|
|
|
|
|
<AnimatedTouchableOpacity
|
|
|
|
|
onPress={bottomButtonOnPress}
|
|
|
|
|
activeOpacity={opacity}
|
2020-01-13 14:44:42 +05:00
|
|
|
style={{
|
2020-04-16 13:57:51 +05:00
|
|
|
...getElevation(5),
|
2020-01-22 02:50:25 +05:00
|
|
|
width: '100%',
|
2020-04-16 13:57:51 +05:00
|
|
|
|
|
|
|
|
alignSelf: 'center',
|
|
|
|
|
borderRadius: br,
|
|
|
|
|
backgroundColor: headerColor ? headerColor : colors.accent,
|
|
|
|
|
justifyContent: 'center',
|
|
|
|
|
alignItems: 'center',
|
|
|
|
|
marginBottom: 0,
|
2020-01-13 14:44:42 +05:00
|
|
|
}}>
|
2020-04-16 13:57:51 +05:00
|
|
|
<View
|
2020-01-13 14:44:42 +05:00
|
|
|
style={{
|
2020-04-16 13:57:51 +05:00
|
|
|
justifyContent: 'flex-start',
|
2020-01-22 02:50:25 +05:00
|
|
|
alignItems: 'center',
|
2020-04-16 13:57:51 +05:00
|
|
|
flexDirection: 'row',
|
|
|
|
|
width: '100%',
|
|
|
|
|
padding: pv,
|
|
|
|
|
paddingVertical: pv + 5,
|
2020-01-13 14:44:42 +05:00
|
|
|
}}>
|
2020-04-16 13:57:51 +05:00
|
|
|
<Icon name="plus" color="white" size={SIZE.xl} />
|
|
|
|
|
<Text
|
2020-01-13 14:44:42 +05:00
|
|
|
style={{
|
2020-04-16 13:57:51 +05:00
|
|
|
fontSize: SIZE.md,
|
|
|
|
|
color: 'white',
|
|
|
|
|
fontFamily: WEIGHT.regular,
|
|
|
|
|
textAlignVertical: 'center',
|
2020-01-13 14:44:42 +05:00
|
|
|
}}>
|
2020-04-16 13:57:51 +05:00
|
|
|
{' ' + bottomButtonText}
|
|
|
|
|
</Text>
|
|
|
|
|
</View>
|
|
|
|
|
</AnimatedTouchableOpacity>
|
|
|
|
|
</Animatable.View>
|
|
|
|
|
)}
|
|
|
|
|
</AnimatedKeyboardAvoidingView>
|
2020-01-13 14:44:42 +05:00
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export default Container;
|