Files
notesnook/apps/mobile/src/components/SimpleList/index.js

344 lines
9.0 KiB
JavaScript
Raw Normal View History

2020-04-26 16:15:59 +05:00
import React, {createRef, useState} from 'react';
2020-04-20 10:54:58 +05:00
import {
FlatList,
Platform,
RefreshControl,
2020-04-26 16:36:51 +05:00
SectionList,
2020-04-20 10:54:58 +05:00
Text,
View,
} from 'react-native';
2020-09-09 14:55:59 +05:00
import * as Animatable from 'react-native-animatable';
2020-04-26 16:36:51 +05:00
import {useSafeArea} from 'react-native-safe-area-context';
2020-09-09 14:55:59 +05:00
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
import {SIZE, WEIGHT} from '../../common/common';
2020-04-20 09:16:01 +05:00
import {useTracked} from '../../provider';
import {ACTIONS} from '../../provider/actions';
import {eSendEvent} from '../../services/eventManager';
2020-08-16 18:59:07 +05:00
import {
eClearSearch,
eOpenLoginDialog,
2020-09-09 14:55:59 +05:00
eScrollEvent,
2020-08-16 18:59:07 +05:00
} from '../../services/events';
2020-05-14 14:52:56 +05:00
import NavigationService from '../../services/NavigationService';
2020-09-09 14:55:59 +05:00
import {db, DDS, ToastEvent} from '../../utils/utils';
import {PressableButton} from '../PressableButton';
import {PinnedItemList} from './PinnedItemList';
2020-04-20 10:54:58 +05:00
const sectionListRef = createRef();
2020-05-10 22:19:23 +05:00
const AnimatedFlatlist = Animatable.createAnimatableComponent(FlatList);
const AnimatedSectionList = Animatable.createAnimatableComponent(SectionList);
2020-03-09 20:06:55 +05:00
const SimpleList = ({
data,
type,
placeholder,
2020-05-10 22:19:23 +05:00
RenderItem,
2020-03-09 20:06:55 +05:00
focused,
placeholderText,
2020-03-09 20:15:00 +05:00
pinned = null,
2020-04-26 16:36:51 +05:00
customRefresh,
customRefreshing,
2020-03-17 10:02:34 +05:00
isMove,
hideMore,
noteToMove,
2020-04-20 10:54:58 +05:00
isHome = false,
2020-03-09 20:06:55 +05:00
}) => {
const [state, dispatch] = useTracked();
2020-05-14 14:52:56 +05:00
const {colors, selectionMode, user} = state;
2020-04-20 09:16:01 +05:00
const searchResults = {...state.searchResults};
2020-04-26 16:15:59 +05:00
const [refreshing, setRefreshing] = useState(false);
2020-04-16 13:57:51 +05:00
const insets = useSafeArea();
2020-09-07 19:19:54 +05:00
const _onScroll = (event) => {
2020-03-09 20:06:55 +05:00
if (!event) return;
let y = event.nativeEvent.contentOffset.y;
eSendEvent(eScrollEvent, y);
};
const _ListFooterComponent = data[0] ? (
<View
style={{
height: 150,
alignItems: 'center',
justifyContent: 'center',
}}>
<Text
style={{
2020-09-07 21:23:38 +05:00
color: colors.nav,
2020-03-09 20:06:55 +05:00
fontSize: SIZE.sm,
fontFamily: WEIGHT.regular,
}}>
- End -
</Text>
</View>
) : null;
2020-04-20 10:54:58 +05:00
const _renderSectionHeader = ({section: {title}}) => (
<Text
style={{
fontFamily: WEIGHT.bold,
fontSize: SIZE.xs + 1,
color: colors.accent,
paddingHorizontal: 12,
width: '100%',
alignSelf: 'center',
marginTop: 15,
paddingBottom: 5,
}}>
{title}
</Text>
);
2020-04-26 16:15:59 +05:00
const _onRefresh = async () => {
if (Platform.OS === 'ios') {
dispatch({
type: ACTIONS.SYNCING,
syncing: true,
});
} else {
setRefreshing(true);
}
try {
let user = await db.user.get();
dispatch({type: ACTIONS.USER, user: user});
await db.sync();
if (Platform.OS === 'ios') {
dispatch({
type: ACTIONS.SYNCING,
syncing: false,
});
} else {
setRefreshing(false);
}
ToastEvent.show('Sync Complete', 'success');
} catch (e) {
if (Platform.OS === 'ios') {
dispatch({
type: ACTIONS.SYNCING,
syncing: false,
});
} else {
setRefreshing(false);
}
2020-09-14 09:42:46 +05:00
ToastEvent.show(
e.message,
'error',
'global',
5000,
() => {
NavigationService.navigate('Login', {
root: true,
});
},
'Login',
);
2020-04-26 16:15:59 +05:00
}
dispatch({type: ACTIONS.ALL});
};
2020-03-09 20:06:55 +05:00
const _ListHeaderComponent_S =
searchResults.type === type && searchResults.results.length > 0 ? (
<View
style={{
marginTop:
Platform.OS == 'ios'
? data[0] && !selectionMode
2020-04-26 16:08:50 +05:00
? 115
: 115 - 60
2020-03-09 20:06:55 +05:00
: data[0] && !selectionMode
2020-04-20 10:54:58 +05:00
? 155 - insets.top
: 155 - insets.top - 60,
2020-03-09 20:06:55 +05:00
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
paddingHorizontal: 12,
}}>
<Text
style={{
fontFamily: WEIGHT.bold,
color: colors.accent,
fontSize: SIZE.xs,
}}>
2020-04-25 11:28:20 +05:00
Showing Results for {searchResults.keyword}
2020-03-09 20:06:55 +05:00
</Text>
<Text
onPress={() => {
eSendEvent(eClearSearch);
2020-03-09 20:06:55 +05:00
}}
style={{
fontFamily: WEIGHT.regular,
color: colors.errorText,
fontSize: SIZE.xs,
}}>
Clear
</Text>
</View>
) : (
2020-04-20 09:16:01 +05:00
<View
style={{
marginTop:
Platform.OS == 'ios'
? data[0] && !selectionMode
2020-04-28 18:12:46 +05:00
? 135
: 135 - 60
2020-04-20 09:16:01 +05:00
: data[0] && !selectionMode
2020-04-20 10:54:58 +05:00
? 155 - insets.top
: 155 - 60 - insets.top,
2020-04-20 09:16:01 +05:00
}}>
2020-08-16 18:59:07 +05:00
{user || !data[0] || selectionMode ? null : (
2020-09-08 22:23:44 +05:00
<PressableButton
2020-05-14 14:52:56 +05:00
onPress={() => {
DDS.isTab
? eSendEvent(eOpenLoginDialog)
: NavigationService.navigate('Login', {
root: true,
});
}}
2020-09-08 22:23:44 +05:00
color={colors.shade}
selectedColor={colors.accent}
alpha={!colors.night ? -0.02 : 0.1}
opacity={0.12}
customStyle={{
2020-08-16 18:59:07 +05:00
paddingVertical: 6,
2020-05-14 14:52:56 +05:00
width: '100%',
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'flex-start',
paddingHorizontal: 12,
2020-08-16 18:59:07 +05:00
alignSelf: 'center',
2020-05-14 14:52:56 +05:00
}}>
<View
style={{
width: 25,
backgroundColor: colors.accent,
height: 25,
borderRadius: 100,
alignItems: 'center',
justifyContent: 'center',
}}>
<Icon
style={{
textAlign: 'center',
textAlignVertical: 'center',
}}
name="account-outline"
color="white"
size={SIZE.xs}
/>
</View>
<View
style={{
marginLeft: 10,
}}>
<Text
style={{
fontFamily: WEIGHT.regular,
color: colors.icon,
fontSize: SIZE.xxs - 1,
}}>
You are not logged in
</Text>
<Text
style={{
color: colors.accent,
fontSize: SIZE.xxs,
}}>
Login to sync your {type}.
</Text>
</View>
2020-09-08 22:23:44 +05:00
</PressableButton>
2020-05-14 14:52:56 +05:00
)}
{pinned ? <PinnedItemList type={type} /> : null}
2020-04-20 09:16:01 +05:00
</View>
);
2020-03-09 20:06:55 +05:00
const _ListEmptyComponent = (
<View
style={{
height: '80%',
width: '100%',
alignItems: 'center',
alignSelf: 'center',
justifyContent: 'center',
2020-03-19 11:04:47 +05:00
opacity: 1,
2020-03-09 20:06:55 +05:00
}}>
2020-08-16 18:59:07 +05:00
<>{placeholder}</>
2020-03-09 20:06:55 +05:00
</View>
);
const _listKeyExtractor = (item, index) =>
2020-03-22 12:39:35 +05:00
item.id.toString() + index.toString();
2020-03-09 20:06:55 +05:00
2020-04-20 10:54:58 +05:00
return isHome && searchResults.type !== 'notes' ? (
2020-05-10 22:19:23 +05:00
<AnimatedSectionList
transition="backgroundColor"
duration={300}
2020-04-20 10:54:58 +05:00
ref={sectionListRef}
sections={data}
refreshControl={
<RefreshControl
tintColor={colors.accent}
colors={[colors.accent]}
2020-04-26 16:08:50 +05:00
progressViewOffset={150}
2020-04-26 16:15:59 +05:00
onRefresh={_onRefresh}
2020-04-26 16:27:54 +05:00
refreshing={refreshing}
2020-04-20 10:54:58 +05:00
/>
}
keyExtractor={_listKeyExtractor}
renderSectionHeader={_renderSectionHeader}
onScroll={_onScroll}
2020-04-26 16:08:50 +05:00
stickySectionHeadersEnabled={false}
2020-04-20 10:54:58 +05:00
ListEmptyComponent={_ListEmptyComponent}
ListHeaderComponent={_ListHeaderComponent_S}
contentContainerStyle={{
width: '100%',
alignSelf: 'center',
minHeight: '100%',
}}
style={{
height: '100%',
2020-05-10 22:19:23 +05:00
backgroundColor: colors.bg,
2020-04-20 10:54:58 +05:00
}}
removeClippedSubviews={true}
ListFooterComponent={_ListFooterComponent}
2020-05-10 22:19:23 +05:00
renderItem={({item, index}) => <RenderItem item={item} index={index} />}
2020-04-20 10:54:58 +05:00
/>
) : (
2020-05-10 22:19:23 +05:00
<AnimatedFlatlist
transition="backgroundColor"
duration={300}
2020-03-09 20:06:55 +05:00
data={
searchResults.type === type &&
2020-04-20 09:16:01 +05:00
focused &&
searchResults.results.length > 0
2020-03-09 20:06:55 +05:00
? searchResults.results
: data
}
refreshControl={
<RefreshControl
tintColor={colors.accent}
colors={[colors.accent]}
2020-04-26 16:36:51 +05:00
progressViewOffset={150}
onRefresh={customRefresh ? customRefresh : _onRefresh}
refreshing={customRefresh ? customRefreshing : refreshing}
2020-03-09 20:06:55 +05:00
/>
}
keyExtractor={_listKeyExtractor}
ListFooterComponent={_ListFooterComponent}
onScroll={_onScroll}
ListHeaderComponent={_ListHeaderComponent_S}
ListEmptyComponent={_ListEmptyComponent}
contentContainerStyle={{
width: '100%',
alignSelf: 'center',
minHeight: '100%',
}}
style={{
height: '100%',
2020-05-10 22:19:23 +05:00
backgroundColor: colors.bg,
2020-03-09 20:06:55 +05:00
}}
2020-05-10 22:19:23 +05:00
renderItem={({item, index}) => <RenderItem item={item} index={index} />}
2020-03-09 20:06:55 +05:00
/>
);
};
export default SimpleList;