Refactor tag screen to use FlashList

Signed-off-by: Nikolaos Karaolidis <nick@karaolidis.com>
This commit is contained in:
2023-07-15 19:37:15 +03:00
parent bd1dcd6809
commit 622d88cf40
11 changed files with 95 additions and 49 deletions

View File

@@ -50,7 +50,6 @@ const AddTag = () => {
id: new BSON.UUID(),
name: tagName,
color: tagColor,
memes: [],
});
});
navigation.goBack();

View File

@@ -1,16 +1,17 @@
import React, { useState } from 'react';
import { StyleSheet, View } from 'react-native';
import { StyleSheet, View, Text } from 'react-native';
import {
Button,
DataTable,
Divider,
HelperText,
Menu,
Searchbar,
TouchableRipple,
} from 'react-native-paper';
import { useQuery, useRealm } from '@realm/react';
import { useDispatch, useSelector } from 'react-redux';
import { RootScrollView, TagChip } from '../components';
import { FlashList } from '@shopify/flash-list';
import { RootView, TagChip } from '../components';
import { Tag, deleteTag } from '../database';
import styles from '../styles';
import {
@@ -26,17 +27,48 @@ const tagStyles = StyleSheet.create({
headerButtonView: {
height: 50,
},
tagRow: {
flexWrap: 'wrap',
justifyContent: 'space-between',
flexDirection: 'row',
alignItems: 'center',
padding: 10,
},
tagView: {
flexShrink: 1,
maxWidth: '80%',
},
helperText: {
marginVertical: 10,
},
tagView: {
justifyContent: 'center',
maxWidth: '75%',
},
});
const Tags = () => {
const TagRow = ({ tag }: { tag: Tag }) => {
const realm = useRealm();
return (
<TouchableRipple onPress={() => deleteTag(realm, tag)}>
<View style={tagStyles.tagRow}>
<View style={tagStyles.tagView}>
<TagChip tag={tag} />
</View>
<Text>{tag.memesLength}</Text>
</View>
</TouchableRipple>
);
};
const ListEmpty = () => {
return (
<View style={styles.alignCenter}>
<HelperText type={'info'} style={tagStyles.helperText}>
No tags found
</HelperText>
</View>
);
};
const Tags = () => {
const sort = useSelector((state: RootState) => state.tags.sort);
const sortDirection = useSelector(
(state: RootState) => state.tags.sortDirection,
@@ -60,16 +92,19 @@ const Tags = () => {
};
const [search, setSearch] = useState('');
const tags = useQuery<Tag>(Tag.schema.name)
.filtered(`name CONTAINS[c] "${search}"`)
.sorted(tagSortQuery(sort), sortDirection === SORT_DIRECTION.ASCENDING);
.sorted(tagSortQuery(sort), sortDirection === SORT_DIRECTION.DESCENDING);
return (
<RootScrollView padded>
<RootView padded>
<Searchbar
placeholder="Search Tags"
value={search}
onChangeText={setSearch}
onChangeText={(value: string) => {
setSearch(value);
}}
/>
<View
style={[
@@ -103,26 +138,14 @@ const Tags = () => {
</Menu>
</View>
<Divider />
<DataTable>
{tags.map(tag => (
<DataTable.Row
key={tag.id.toHexString()}
onPress={() => deleteTag(realm, tag)}>
<View style={tagStyles.tagView}>
<TagChip tag={tag} />
</View>
<DataTable.Cell numeric>{tag.memesLength}</DataTable.Cell>
</DataTable.Row>
))}
</DataTable>
{tags.length === 0 && (
<View style={styles.alignCenter}>
<HelperText type={'info'} style={tagStyles.helperText}>
No tags found
</HelperText>
</View>
)}
</RootScrollView>
<FlashList
data={tags}
estimatedItemSize={52}
renderItem={({ item }) => <TagRow tag={item} />}
ItemSeparatorComponent={() => <Divider />}
ListEmptyComponent={() => <ListEmpty />}
/>
</RootView>
);
};