This repository has been archived on 2025-07-31. You can view files and clone it, but cannot push or open issues or pull requests.
Files
terminally-online/src/screens/memes/memesList/memesList.tsx
Nikolaos Karaolidis 1b09b058e4 Improve performance
Signed-off-by: Nikolaos Karaolidis <nick@karaolidis.com>
2023-08-04 13:39:55 +03:00

185 lines
5.5 KiB
TypeScript

import React, { RefObject } from 'react';
import { FlashList, MasonryFlashList } from '@shopify/flash-list';
import {
NativeSyntheticEvent,
NativeScrollEvent,
StyleSheet,
} from 'react-native';
import { useSelector } from 'react-redux';
import { Divider, HelperText } from 'react-native-paper';
import { useSafeAreaFrame } from 'react-native-safe-area-context';
import { Meme } from '../../../database';
import { RootState } from '../../../state';
import { VIEW } from '../../../types';
import { getFlashListItemHeight } from '../../../utilities';
import MemesMasonryItem from './memesMasonryItem';
import MemesGridItem from './memesGridItem';
import MemesListItem from './memesListItem';
import { AndroidScoped } from 'react-native-file-access';
const sharedMemesListStyles = StyleSheet.create({
flashList: {
paddingBottom: 100,
},
helperText: {
textAlign: 'center',
marginVertical: 15,
},
});
const memesMasonryListStyles = StyleSheet.create({
flashList: {
// Needed to prevent fucky MasonryFlashList, see https://github.com/Shopify/flash-list/issues/876
paddingHorizontal: 0.1,
},
});
const memesGridListStyles = StyleSheet.create({
flashList: {
paddingHorizontal: 2.5,
},
});
const memesListListStyles = StyleSheet.create({
flashList: {
paddingHorizontal: 5,
},
});
const MemesList = ({
memes,
flashListRef,
flashListPadding,
handleScroll,
focusMeme,
}: {
memes: Realm.Results<Meme & Realm.Object<Meme>>;
flashListRef: RefObject<FlashList<Meme>>;
flashListPadding: number;
handleScroll: (event: NativeSyntheticEvent<NativeScrollEvent>) => void;
focusMeme: (index: number) => void;
}) => {
const { height, width } = useSafeAreaFrame();
const view = useSelector((state: RootState) => state.memes.view);
const masonryColumns = useSelector(
(state: RootState) => state.settings.masonryColumns,
);
const gridColumns = useSelector(
(state: RootState) => state.settings.gridColumns,
);
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const storageUri = useSelector(
(state: RootState) => state.settings.storageUri,
)!;
return (
<>
{view === VIEW.MASONRY && (
<MasonryFlashList
ref={flashListRef}
data={memes}
key={masonryColumns}
estimatedItemSize={getFlashListItemHeight(masonryColumns)}
estimatedListSize={{
height,
width: width * 0.92,
}}
numColumns={masonryColumns}
showsVerticalScrollIndicator={false}
renderItem={({ item: meme, index }) => (
<MemesMasonryItem
meme={meme}
focusMeme={() => focusMeme(index)}
uri={AndroidScoped.appendPath(storageUri, meme.filename)}
columns={masonryColumns}
/>
)}
contentContainerStyle={{
paddingTop: flashListPadding,
...sharedMemesListStyles.flashList,
...memesMasonryListStyles.flashList,
}}
ListEmptyComponent={() => (
<HelperText type={'info'} style={sharedMemesListStyles.helperText}>
No memes found
</HelperText>
)}
onScroll={handleScroll}
fadingEdgeLength={100}
overScrollMode="never"
/>
)}
{view === VIEW.GRID && (
<FlashList
ref={flashListRef}
data={memes}
key={gridColumns}
estimatedItemSize={getFlashListItemHeight(gridColumns)}
estimatedListSize={{
height: height,
width: width * 0.92,
}}
numColumns={gridColumns}
showsVerticalScrollIndicator={false}
renderItem={({ item: meme, index }) => (
<MemesGridItem
meme={meme}
focusMeme={() => focusMeme(index)}
uri={AndroidScoped.appendPath(storageUri, meme.filename)}
columns={gridColumns}
/>
)}
contentContainerStyle={{
paddingTop: flashListPadding,
...sharedMemesListStyles.flashList,
...memesGridListStyles.flashList,
}}
ListEmptyComponent={() => (
<HelperText type={'info'} style={sharedMemesListStyles.helperText}>
No memes found
</HelperText>
)}
onScroll={handleScroll}
fadingEdgeLength={100}
overScrollMode="never"
/>
)}
{view === VIEW.LIST && (
<FlashList
ref={flashListRef}
data={memes}
estimatedItemSize={90}
estimatedListSize={{
height: height,
width: width * 0.92,
}}
showsVerticalScrollIndicator={false}
renderItem={({ item: meme, index }) => (
<MemesListItem
meme={meme}
focusMeme={() => focusMeme(index)}
uri={AndroidScoped.appendPath(storageUri, meme.filename)}
/>
)}
ItemSeparatorComponent={() => <Divider />}
contentContainerStyle={{
paddingTop: flashListPadding,
...sharedMemesListStyles.flashList,
...memesListListStyles.flashList,
}}
ListEmptyComponent={() => (
<HelperText type={'info'} style={sharedMemesListStyles.helperText}>
No memes found
</HelperText>
)}
onScroll={handleScroll}
fadingEdgeLength={100}
overScrollMode="never"
/>
)}
</>
);
};
export default MemesList;