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

211 lines
5.0 KiB
JavaScript
Raw Normal View History

2021-12-17 10:30:07 +05:00
import React, {useEffect, useRef, useState} from 'react';
2022-01-04 10:11:29 +05:00
import {
FlatList,
RefreshControl,
RefreshControlComponent,
View
} from 'react-native';
2021-12-17 10:30:07 +05:00
import {notesnook} from '../../../e2e/test.ids';
import {useTracked} from '../../provider';
2022-01-04 10:11:29 +05:00
import {useUserStore} from '../../provider/stores';
2021-12-17 10:30:07 +05:00
import {eSendEvent} from '../../services/EventManager';
2020-12-20 23:01:35 +05:00
import Sync from '../../services/Sync';
2021-12-17 10:30:07 +05:00
import {db} from '../../utils/database';
import {eScrollEvent} from '../../utils/Events';
2021-12-23 12:40:20 +05:00
import {sleep} from '../../utils/TimeUtils';
2021-04-11 14:04:14 +05:00
import JumpToDialog from '../JumpToDialog';
2021-12-17 10:30:07 +05:00
import {NotebookWrapper} from '../NotebookItem/wrapper';
import {NoteWrapper} from '../NoteItem/wrapper';
2020-11-14 10:06:32 +05:00
import TagItem from '../TagItem';
2021-12-17 10:30:07 +05:00
import {Empty} from './empty';
import {Footer} from './footer';
import {Header} from './header';
import {SectionHeader} from './section-header';
2020-09-18 20:47:52 +05:00
2021-06-05 01:35:58 +05:00
let renderItems = {
2021-06-13 14:58:54 +05:00
note: NoteWrapper,
notebook: NotebookWrapper,
topic: NotebookWrapper,
tag: TagItem,
2021-12-05 00:05:27 +05:00
section: SectionHeader,
header: SectionHeader
2021-06-05 01:35:58 +05:00
};
const RenderItem = ({item, index, type, ...restArgs}) => {
2021-12-05 00:05:27 +05:00
if (!item) return <View />;
const Item = renderItems[item.itemType || item.type] || View;
const groupOptions = db.settings?.getGroupOptions(type);
const dateBy =
groupOptions.sortBy !== 'title' ? groupOptions.sortBy : 'dateEdited';
2021-08-17 09:33:49 +05:00
2021-12-05 00:05:27 +05:00
let tags =
2021-12-06 21:14:06 +05:00
item.tags
?.slice(0, 3)
?.map(item => {
let tag = db.tags.tag(item);
if (!tag) return null;
return {
title: tag.title,
id: tag.id,
alias: tag.alias
};
})
.filter(t => t !== null) || [];
return (
<Item
item={item}
tags={tags}
dateBy={dateBy}
index={index}
type={type}
{...restArgs}
/>
);
2021-12-06 21:14:06 +05:00
};
2021-06-13 14:58:54 +05:00
2021-06-05 01:35:58 +05:00
const SimpleList = ({
listData,
type,
refreshCallback,
placeholderData,
loading,
headerProps = {
2021-08-17 09:33:49 +05:00
heading: 'Home'
2021-06-05 01:35:58 +05:00
},
screen,
ListHeader
2021-06-05 01:35:58 +05:00
}) => {
const [state] = useTracked();
const {colors} = state;
const scrollRef = useRef();
2021-06-05 21:10:20 +05:00
const [_loading, _setLoading] = useState(true);
2021-12-23 12:40:20 +05:00
//const refreshing = false;
const [refreshing, setRefreshing] = useState(false);
2022-01-04 10:11:29 +05:00
const syncing = useUserStore(state => state.syncing);
2021-06-05 01:35:58 +05:00
useEffect(() => {
2021-11-11 13:06:27 +05:00
let timeout = null;
2021-06-05 01:35:58 +05:00
if (!loading) {
2021-11-11 13:06:27 +05:00
timeout = setTimeout(
2021-07-17 20:40:49 +05:00
() => {
_setLoading(false);
},
2021-08-17 09:33:49 +05:00
listData.length === 0 ? 0 : 300
2021-07-17 20:40:49 +05:00
);
2021-06-05 01:35:58 +05:00
} else {
2021-07-13 10:46:21 +05:00
_setLoading(true);
2021-06-05 01:35:58 +05:00
}
2021-11-11 13:06:27 +05:00
return () => {
clearTimeout(timeout);
};
2021-07-13 10:46:21 +05:00
}, [loading]);
2021-06-05 01:35:58 +05:00
const renderItem = React.useCallback(
2021-12-05 00:05:27 +05:00
({item, index}) => (
<RenderItem
item={item}
index={index}
color={headerProps.color}
title={headerProps.heading}
type={screen === 'Notes' ? 'home' : type}
2021-12-07 11:46:59 +05:00
screen={screen}
2021-12-05 00:05:27 +05:00
/>
),
2021-08-17 09:33:49 +05:00
[]
2021-06-05 01:35:58 +05:00
);
const _onRefresh = async () => {
2021-12-23 12:40:20 +05:00
setRefreshing(true);
2021-06-05 01:35:58 +05:00
await Sync.run();
2021-12-23 12:40:20 +05:00
setRefreshing(false);
2021-06-05 01:35:58 +05:00
if (refreshCallback) {
refreshCallback();
}
};
const _onScroll = React.useCallback(
event => {
if (!event) return;
let y = event.nativeEvent.contentOffset.y;
eSendEvent(eScrollEvent, {
y,
2021-08-17 09:33:49 +05:00
screen
2021-06-05 01:35:58 +05:00
});
},
2021-08-17 09:33:49 +05:00
[screen]
2021-06-05 01:35:58 +05:00
);
let styles = {
height: '100%',
width: '100%',
minHeight: 1,
minWidth: 1,
2021-12-05 00:05:27 +05:00
backgroundColor: colors.bg
2021-06-05 01:35:58 +05:00
};
const _keyExtractor = item => item.id || item.title;
return (
<>
<FlatList
style={styles}
keyExtractor={_keyExtractor}
ref={scrollRef}
testID={notesnook.list.id}
2021-07-17 20:40:49 +05:00
data={_loading ? listData.slice(0, 9) : listData}
2021-06-05 01:35:58 +05:00
renderItem={renderItem}
onScroll={_onScroll}
initialNumToRender={10}
maxToRenderPerBatch={10}
keyboardShouldPersistTaps="always"
keyboardDismissMode="interactive"
2021-06-05 01:35:58 +05:00
refreshControl={
<RefreshControl
tintColor={colors.accent}
colors={[colors.accent]}
progressBackgroundColor={colors.nav}
2021-12-23 12:40:20 +05:00
onRefresh={_onRefresh}
2022-01-04 10:11:29 +05:00
refreshing={refreshing || syncing}
2021-06-05 01:35:58 +05:00
/>
}
ListEmptyComponent={
<Empty
loading={loading || _loading}
placeholderData={placeholderData}
headerProps={headerProps}
2021-07-09 12:15:06 +05:00
type={type}
screen={screen}
2021-06-05 01:35:58 +05:00
/>
}
ListFooterComponent={<Footer />}
ListHeaderComponent={
2021-07-17 20:40:49 +05:00
<>
{ListHeader ? (
ListHeader
) : (
<Header
title={headerProps.heading}
paragraph={headerProps.paragraph}
onPress={headerProps.onPress}
icon={headerProps.icon}
color={headerProps.color}
type={type}
screen={screen}
/>
)}
2021-07-17 20:40:49 +05:00
</>
2021-06-05 01:35:58 +05:00
}
/>
2021-07-13 10:19:06 +05:00
<JumpToDialog
screen={screen}
2021-07-13 14:10:51 +05:00
data={listData}
2021-07-13 10:19:06 +05:00
type={screen === 'Notes' ? 'home' : type}
scrollRef={scrollRef}
/>
2021-06-05 01:35:58 +05:00
</>
);
};
2020-03-09 20:06:55 +05:00
export default SimpleList;