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

231 lines
5.8 KiB
JavaScript
Raw Normal View History

2022-01-22 12:57:05 +05:00
import React, { useEffect, useRef, useState } from 'react';
import { RefreshControl, View } from 'react-native';
2022-06-13 10:55:42 +05:00
import { FastList } from 'superlist';
2022-01-22 12:57:05 +05:00
import { notesnook } from '../../../e2e/test.ids';
2022-02-28 23:25:18 +05:00
import { eSendEvent } from '../../services/event-manager';
import Sync from '../../services/sync';
2022-06-13 10:55:42 +05:00
import { useSettingStore } from '../../stores/use-setting-store';
2022-04-24 05:59:14 +05:00
import { useThemeStore } from '../../stores/use-theme-store';
2022-01-22 12:57:05 +05:00
import { db } from '../../utils/database';
2022-02-28 13:48:59 +05:00
import { eScrollEvent } from '../../utils/events';
2022-04-20 17:55:47 +05:00
import { tabBarRef } from '../../utils/global-refs';
2022-02-28 15:32:55 +05:00
import JumpToSectionDialog from '../dialogs/jump-to-section';
2022-02-28 13:48:59 +05:00
import { Footer } from '../list-items/footer';
import { Header } from '../list-items/headers/header';
2022-02-28 15:05:40 +05:00
import { SectionHeader } from '../list-items/headers/section-header';
2022-04-20 17:55:47 +05:00
import { NoteWrapper } from '../list-items/note/wrapper';
import { NotebookWrapper } from '../list-items/notebook/wrapper';
import TagItem from '../list-items/tag';
import { Empty } from './empty';
2020-09-18 20:47:52 +05:00
2022-02-28 15:05:40 +05:00
const 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
};
2022-06-13 10:55:42 +05:00
const itemHeights = {
notes: 70,
notebooks: 100,
topics: 80,
tags: 80,
sections: 40,
headers: 40
};
2022-01-22 12:57:05 +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);
2022-01-22 12:57:05 +05:00
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) || [];
2022-01-22 12:57:05 +05:00
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
2022-02-28 13:48:59 +05:00
const List = ({
2021-06-05 01:35:58 +05:00
listData,
type,
refreshCallback,
placeholderData,
loading,
headerProps = {
2022-04-24 05:59:14 +05:00
heading: 'Home',
color: null
2021-06-05 01:35:58 +05:00
},
screen,
ListHeader,
warning
2021-06-05 01:35:58 +05:00
}) => {
2022-02-28 23:25:18 +05:00
const colors = useThemeStore(state => state.colors);
2021-06-05 01:35:58 +05:00
const scrollRef = useRef();
2022-06-13 10:55:42 +05:00
const [_loading, _setLoading] = useState(false);
const compactMode =
type !== 'notes' && type !== 'notebooks'
? null
: useSettingStore(
state => state.settings[type === 'notes' ? 'notesListMode' : 'notebooksListMode']
);
const heights = listData.map(item => {
let height = itemHeights[item.type + 's'];
return item.type !== 'header' ? (compactMode === 'compact' ? 50 : height) : height;
});
// useEffect(() => {
// let timeout = null;
// if (!loading) {
// timeout = setTimeout(
// () => {
// _setLoading(false);
// },
// listData.length === 0 ? 0 : 300
// );
// } else {
// _setLoading(true);
// }
// return () => {
// // clearTimeout(timeout);
// };
// }, [loading]);
const renderRow = React.useCallback(
(section, row) => {
return (
<RenderItem
item={listData[row]}
index={row}
color={headerProps.color}
title={headerProps.heading}
type={screen === 'Notes' ? 'home' : type}
screen={screen}
/>
2021-07-17 20:40:49 +05:00
);
2022-06-13 10:55:42 +05:00
},
[headerProps.color, headerProps.heading, listData]
2021-06-05 01:35:58 +05:00
);
const _onRefresh = async () => {
await Sync.run();
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 = {
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
};
2022-06-13 10:55:42 +05:00
//const _keyExtractor = item => item.id || item.title;
const renderEmpty = React.useCallback(() => {
return (
<Empty
loading={loading || _loading}
placeholderData={placeholderData}
headerProps={headerProps}
type={type}
screen={screen}
/>
);
}, [loading, _loading]);
const renderFooter = React.useCallback(() => {
return <Footer />;
}, []);
const renderHeader = React.useCallback(() => {
return (
<>
{ListHeader ? (
ListHeader
) : (
<Header
title={headerProps.heading}
color={headerProps.color}
type={type}
screen={screen}
warning={warning}
/>
)}
</>
);
}, [headerProps.heading, headerProps.color]);
const rowHeight = React.useCallback((section, row) => heights[row], [listData.length]);
2021-06-05 01:35:58 +05:00
return (
<>
2022-06-13 10:55:42 +05:00
<FastList
2021-06-05 01:35:58 +05:00
style={styles}
ref={scrollRef}
testID={notesnook.list.id}
2022-06-13 10:55:42 +05:00
sections={[listData.length]}
batchSize={height => height / 2.2}
renderAheadMultiplier={2}
renderBehindMultiplier={1}
rowHeight={rowHeight}
renderRow={renderRow}
2021-06-05 01:35:58 +05:00
onScroll={_onScroll}
2022-04-13 13:54:06 +05:00
onMomentumScrollEnd={() => {
tabBarRef.current?.unlock();
}}
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-04-24 05:59:14 +05:00
refreshing={false}
2021-06-05 01:35:58 +05:00
/>
}
2022-06-13 10:55:42 +05:00
renderEmpty={renderEmpty}
renderFooter={renderFooter}
renderHeader={renderHeader}
2021-06-05 01:35:58 +05:00
/>
2022-02-28 15:32:55 +05:00
<JumpToSectionDialog
2021-07-13 10:19:06 +05:00
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
</>
);
};
2022-02-28 13:48:59 +05:00
export default List;