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

292 lines
7.7 KiB
JavaScript
Raw Normal View History

2021-04-11 14:04:14 +05:00
import React, {useEffect, useRef, useState} from 'react';
2021-02-15 11:09:17 +05:00
import {RefreshControl, useWindowDimensions} from 'react-native';
import {DataProvider, LayoutProvider, RecyclerListView} from 'recyclerlistview';
import {useTracked} from '../../provider';
import {DDS} from '../../services/DeviceDetection';
import {eSendEvent} from '../../services/EventManager';
2021-06-03 12:01:40 +05:00
import SettingsService from '../../services/SettingsService';
2020-12-20 23:01:35 +05:00
import Sync from '../../services/Sync';
2021-06-02 17:34:39 +05:00
import {dHeight, dWidth} from '../../utils';
2021-04-11 10:34:01 +05:00
import {COLORS_NOTE} from '../../utils/Colors';
2021-02-15 11:09:17 +05:00
import {eScrollEvent} from '../../utils/Events';
2021-05-26 14:18:10 +05:00
import useAnnouncement from '../../utils/useAnnouncement';
2021-04-11 14:04:14 +05:00
import JumpToDialog from '../JumpToDialog';
2021-02-15 11:09:17 +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-04-11 10:34:01 +05:00
import {Announcement} from './announcement';
2021-02-15 11:09:17 +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
const header = {
2020-11-04 15:06:06 +05:00
type: 'MAIN_HEADER',
2020-09-18 20:47:52 +05:00
};
2020-05-10 22:19:23 +05:00
2021-04-11 14:04:14 +05:00
const empty = {
2021-06-03 12:01:40 +05:00
type: 'empty_loading',
};
const empty_not = {
type: 'empty_not_loading',
2021-04-11 14:04:14 +05:00
};
2020-03-09 20:06:55 +05:00
const SimpleList = ({
2021-02-15 11:09:17 +05:00
listData,
2020-11-04 15:06:06 +05:00
type,
customRefresh,
customRefreshing,
refreshCallback,
sortMenuButton,
2020-11-04 20:29:45 +05:00
jumpToDialog,
2020-11-10 17:18:19 +05:00
placeholderData,
2020-11-24 16:59:12 +05:00
loading,
2020-12-08 12:49:02 +05:00
headerProps = {
heading: 'Home',
},
2021-05-24 15:50:02 +05:00
screen,
2020-11-04 15:06:06 +05:00
}) => {
2021-01-11 19:40:57 +05:00
const [state] = useTracked();
const {colors, deviceMode, messageBoardState} = state;
2021-06-03 12:01:40 +05:00
const [_loading, _setLoading] = useState(false);
2020-11-04 15:06:06 +05:00
const [dataProvider, setDataProvider] = useState(
new DataProvider((r1, r2) => {
return r1 !== r2;
2021-06-03 12:01:40 +05:00
}),
2020-11-04 15:06:06 +05:00
);
2021-05-24 15:50:02 +05:00
const [width, setWidth] = useState(dWidth);
2021-04-11 14:04:14 +05:00
const scrollRef = useRef();
2021-04-19 11:01:07 +05:00
const {fontScale} = useWindowDimensions();
2021-01-12 21:43:34 +05:00
const refreshing = false;
2020-11-04 15:06:06 +05:00
const dataType = type;
2021-05-26 14:18:10 +05:00
const [announcement, remove] = useAnnouncement();
2021-01-12 21:43:34 +05:00
2020-11-04 15:06:06 +05:00
useEffect(() => {
2021-02-27 12:25:57 +05:00
if (!loading) {
2021-06-03 12:01:40 +05:00
if (!dataProvider.getDataForIndex(1) || dataProvider.getDataForIndex(1).type.includes("empty")) {
setDataProvider(
dataProvider.cloneWithRows(
!listData || listData.length === 0
? [header, empty_not]
: [header].concat(
listData.length > 1 && SettingsService.get().homepage !== screen
? listData.slice(0, 1)
: listData,
),
),
);
}
if (
!listData ||
listData.length === 0 ||
SettingsService.get().homepage === screen
)
return;
2021-04-11 14:04:14 +05:00
setTimeout(() => {
2021-06-03 12:01:40 +05:00
setDataProvider(dataProvider.cloneWithRows([header].concat(listData)));
}, 150);
2021-04-11 14:04:14 +05:00
} else {
setDataProvider(dataProvider.cloneWithRows([header, empty]));
2021-02-27 12:25:57 +05:00
}
2021-06-02 17:34:39 +05:00
}, [listData, loading, announcement]);
useEffect(() => {
setWidth(dWidth);
}, [deviceMode]);
2020-12-20 23:01:35 +05:00
const _onRefresh = async () => {
await Sync.run();
2020-12-20 23:01:35 +05:00
if (refreshCallback) {
refreshCallback();
2020-11-04 15:06:06 +05:00
}
2021-06-03 12:01:40 +05:00
}
2020-11-04 15:06:06 +05:00
2021-06-03 12:01:40 +05:00
const _onScroll = React.useCallback(
event => {
if (!event) return;
let y = event.nativeEvent.contentOffset.y;
eSendEvent(eScrollEvent, {
y,
screen,
});
},
[screen],
);
2021-01-12 21:43:34 +05:00
2020-11-04 15:06:06 +05:00
const _layoutProvider = new LayoutProvider(
2021-04-11 10:34:01 +05:00
index => {
2021-06-02 17:34:39 +05:00
return dataProvider.getDataForIndex(index)?.type || 'note';
2020-11-04 15:06:06 +05:00
},
(type, dim) => {
switch (type) {
case 'note':
dim.width = width;
dim.height = 100 * fontScale;
break;
case 'notebook':
dim.width = width;
dim.height = 110 * fontScale;
break;
case 'trash':
dim.width = width;
dim.height = 110 * fontScale;
break;
2020-11-24 16:59:12 +05:00
case 'empty':
dim.width = width;
2021-06-02 17:34:39 +05:00
dim.height = dHeight - 250 - 35;
2020-11-24 16:59:12 +05:00
break;
2020-11-04 15:06:06 +05:00
case 'topic':
dim.width = width;
dim.height = 80 * fontScale;
break;
case 'tag':
dim.width = width;
dim.height = 80 * fontScale;
break;
case 'header':
dim.width = width;
2020-12-16 20:02:24 +05:00
dim.height = 40 * fontScale;
2020-11-04 15:06:06 +05:00
break;
case 'MAIN_HEADER':
dim.width = width;
2020-11-20 01:23:05 +05:00
dim.height =
dataType === 'search'
? 0
2021-05-26 14:18:10 +05:00
: DDS.isLargeTablet() || announcement
? messageBoardState.visible && !announcement
? 50
: 0
: 195;
2020-11-04 15:06:06 +05:00
break;
default:
dim.width = width;
dim.height = 0;
}
},
);
2021-06-03 12:01:40 +05:00
_layoutProvider.shouldRefreshWithAnchoring = false;
2020-11-01 09:22:28 +05:00
2021-06-03 12:01:40 +05:00
const _renderRow = (type, data, index) => {
2021-06-02 17:34:39 +05:00
switch (type) {
case 'note':
return <NoteWrapper item={data} index={index} />;
case 'notebook':
case 'topic':
return <NotebookWrapper item={data} index={index} />;
case 'tag':
return <TagItem item={data} index={index} />;
case 'trash':
return data.itemType === 'note' ? (
<NoteWrapper item={data} index={index} />
) : (
<NotebookWrapper item={data} index={index} />
);
case 'MAIN_HEADER':
return (
<Header
title={headerProps.heading}
paragraph={headerProps.paragraph}
onPress={headerProps.onPress}
icon={headerProps.icon}
type={dataType}
announcement={announcement}
index={index}
screen={screen}
/>
);
case 'header':
return (
<SectionHeader
item={data}
index={index}
headerProps={headerProps}
jumpToDialog={jumpToDialog}
sortMenuButton={sortMenuButton}
/>
);
2021-06-03 12:01:40 +05:00
case 'empty_not_loading':
2021-06-02 17:34:39 +05:00
return (
<Empty
2021-06-03 12:01:40 +05:00
loading={false}
placeholderData={placeholderData}
headerProps={headerProps}
/>
);
case 'empty_loading':
return (
<Empty
loading={true}
2021-06-02 17:34:39 +05:00
placeholderData={placeholderData}
headerProps={headerProps}
/>
);
}
2021-06-03 12:01:40 +05:00
}
2020-09-27 10:15:19 +05:00
2021-01-12 21:39:49 +05:00
let scrollProps = React.useMemo(() => {
return {
refreshControl: (
<RefreshControl
style={{
opacity: 0,
elevation: 0,
}}
tintColor={colors.accent}
colors={[colors.accent]}
progressViewOffset={150}
onRefresh={customRefresh ? customRefresh : _onRefresh}
refreshing={customRefresh ? customRefreshing : refreshing}
/>
),
2021-02-15 11:09:17 +05:00
2021-01-12 21:39:49 +05:00
overScrollMode: 'always',
contentContainerStyle: {
width: '100%',
alignSelf: 'center',
minHeight: '100%',
},
testID: 'list-' + type,
};
}, [colors.accent, type, customRefresh]);
let styles = {
height: '100%',
backgroundColor: colors.bg,
width: '100%',
2021-05-24 15:50:02 +05:00
minHeight: 1,
minWidth: 1,
2021-01-12 21:39:49 +05:00
};
2021-06-02 17:34:39 +05:00
2021-06-03 12:01:40 +05:00
const renderFooter = () => (listData.length === 0 ? null : <Footer/>);
2020-11-24 16:59:12 +05:00
return (
2021-02-27 12:25:57 +05:00
<>
2021-04-11 14:04:14 +05:00
{!loading && (
<Announcement
2021-05-26 14:18:10 +05:00
announcement={announcement}
remove={remove}
2021-04-11 14:04:14 +05:00
color={
COLORS_NOTE[headerProps.heading?.toLowerCase()] || colors.accent
}
/>
2021-02-27 12:25:57 +05:00
)}
2021-04-11 14:04:14 +05:00
<RecyclerListView
ref={scrollRef}
layoutProvider={_layoutProvider}
dataProvider={dataProvider}
rowRenderer={_renderRow}
2021-06-02 17:34:39 +05:00
renderAheadOffset={0}
2021-04-11 14:04:14 +05:00
onScroll={_onScroll}
2021-06-03 12:01:40 +05:00
renderFooter={renderFooter}
2021-04-11 14:04:14 +05:00
scrollViewProps={scrollProps}
style={styles}
/>
<JumpToDialog scrollRef={scrollRef} />
2021-02-27 12:25:57 +05:00
</>
2020-11-04 15:06:06 +05:00
);
2020-03-09 20:06:55 +05:00
};
export default SimpleList;