From 622d88cf40b59ec60512715e74f229b992499ccc Mon Sep 17 00:00:00 2001 From: Nikolaos Karaolidis Date: Sat, 15 Jul 2023 19:37:15 +0300 Subject: [PATCH] Refactor tag screen to use FlashList Signed-off-by: Nikolaos Karaolidis --- src/components/rootScrollView.tsx | 7 ++- src/components/rootView.tsx | 5 +- src/components/tagChip.tsx | 8 +-- src/components/tagPreview.tsx | 8 +-- src/database/meme.ts | 2 +- src/database/tag.ts | 5 +- src/screens/addTag.tsx | 1 - src/screens/tags.tsx | 85 ++++++++++++++++++++----------- src/styles.tsx | 16 ++++++ src/types/sort.ts | 4 ++ src/utilities/icon.ts | 3 +- 11 files changed, 95 insertions(+), 49 deletions(-) diff --git a/src/components/rootScrollView.tsx b/src/components/rootScrollView.tsx index 21f9563..9b0372d 100644 --- a/src/components/rootScrollView.tsx +++ b/src/components/rootScrollView.tsx @@ -24,14 +24,17 @@ const RootScrollView = ({ padded && orientation == 'portrait' && [ styles.paddingHorizontal, - styles.paddingVertical, + styles.paddingTop, ], padded && orientation == 'landscape' && [ styles.paddingHorizontal, - styles.smallPaddingVertical, + styles.smallPaddingTop, ], centered && [styles.centered, styles.flex], + styles.fullSize, + centered && [styles.centered, styles.flex], + styles.fullSize, { backgroundColor: colors.background }, style, ]} diff --git a/src/components/rootView.tsx b/src/components/rootView.tsx index f630e31..f2a82ac 100644 --- a/src/components/rootView.tsx +++ b/src/components/rootView.tsx @@ -24,14 +24,15 @@ const RootView = ({ padded && orientation == 'portrait' && [ styles.paddingHorizontal, - styles.paddingVertical, + styles.paddingTop, ], padded && orientation == 'landscape' && [ styles.paddingHorizontal, - styles.smallPaddingVertical, + styles.smallPaddingTop, ], centered && [styles.centered, styles.flex], + styles.fullSize, { backgroundColor: colors.background }, style, ]}> diff --git a/src/components/tagChip.tsx b/src/components/tagChip.tsx index 40b607e..f3e6d36 100644 --- a/src/components/tagChip.tsx +++ b/src/components/tagChip.tsx @@ -4,8 +4,8 @@ import { Chip } from 'react-native-paper'; import { Tag } from '../database'; import FontAwesome5 from 'react-native-vector-icons/FontAwesome5'; -const TagChip = (properties: { tag: Tag }) => { - const contrastColor = getContrastColor(properties.tag.color); +const TagChip = ({ tag }: { tag: Tag }) => { + const contrastColor = getContrastColor(tag.color); return ( { compact style={[ { - backgroundColor: properties.tag.color, + backgroundColor: tag.color, }, ]} textStyle={{ color: contrastColor }}> - {'#' + properties.tag.name} + {'#' + tag.name} ); }; diff --git a/src/components/tagPreview.tsx b/src/components/tagPreview.tsx index ec17d3c..89bb11d 100644 --- a/src/components/tagPreview.tsx +++ b/src/components/tagPreview.tsx @@ -15,9 +15,9 @@ const tagPreviewStyles = StyleSheet.create({ }, }); -const TagPreview = (properties: { name: string; color: string }) => { +const TagPreview = ({ name, color }: { name: string; color: string }) => { const { responsive } = useDimensions(); - const contrastColor = getContrastColor(properties.color); + const contrastColor = getContrastColor(color); return ( { style={[ tagPreviewStyles.chip, { - backgroundColor: properties.color, + backgroundColor: color, }, ]} textStyle={[tagPreviewStyles.text, { color: contrastColor }]}> - {'#' + properties.name} + {'#' + name} ); diff --git a/src/database/meme.ts b/src/database/meme.ts index 44870cb..3785200 100644 --- a/src/database/meme.ts +++ b/src/database/meme.ts @@ -45,7 +45,7 @@ class Meme extends Realm.Object { title: 'string', description: 'string?', isFavorite: { type: 'bool', indexed: true, default: false }, - tags: 'Tag[]', + tags: { type: 'list', objectType: 'Tag', default: [] }, tagsLength: { type: 'int', default: 0 }, dateCreated: { type: 'date', default: new Date() }, dateModified: { type: 'date', default: new Date() }, diff --git a/src/database/tag.ts b/src/database/tag.ts index c3e7090..ab4da00 100644 --- a/src/database/tag.ts +++ b/src/database/tag.ts @@ -16,9 +16,9 @@ class Tag extends Realm.Object { primaryKey: 'id', properties: { id: 'uuid', - name: 'string', + name: { type: 'string', indexed: true }, color: 'string', - memes: 'Meme[]', + memes: { type: 'list', objectType: 'Meme', default: [] }, memesLength: { type: 'int', default: 0 }, dateCreated: { type: 'date', default: new Date() }, dateModified: { type: 'date', default: new Date() }, @@ -39,5 +39,4 @@ const deleteAllTags = (realm: Realm) => { }); }; - export { Tag, deleteTag, deleteAllTags }; diff --git a/src/screens/addTag.tsx b/src/screens/addTag.tsx index 0de061c..c9edb79 100644 --- a/src/screens/addTag.tsx +++ b/src/screens/addTag.tsx @@ -50,7 +50,6 @@ const AddTag = () => { id: new BSON.UUID(), name: tagName, color: tagColor, - memes: [], }); }); navigation.goBack(); diff --git a/src/screens/tags.tsx b/src/screens/tags.tsx index 3239fbc..8a9eff4 100644 --- a/src/screens/tags.tsx +++ b/src/screens/tags.tsx @@ -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 ( + deleteTag(realm, tag)}> + + + + + {tag.memesLength} + + + ); +}; + +const ListEmpty = () => { + return ( + + + No tags found + + + ); +}; + +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.schema.name) .filtered(`name CONTAINS[c] "${search}"`) - .sorted(tagSortQuery(sort), sortDirection === SORT_DIRECTION.ASCENDING); + .sorted(tagSortQuery(sort), sortDirection === SORT_DIRECTION.DESCENDING); return ( - + { + setSearch(value); + }} /> { - - {tags.map(tag => ( - deleteTag(realm, tag)}> - - - - {tag.memesLength} - - ))} - - {tags.length === 0 && ( - - - No tags found - - - )} - + } + ItemSeparatorComponent={() => } + ListEmptyComponent={() => } + /> + ); }; diff --git a/src/styles.tsx b/src/styles.tsx index ce39333..7f6deb0 100644 --- a/src/styles.tsx +++ b/src/styles.tsx @@ -10,6 +10,9 @@ const styles = StyleSheet.create({ smallPaddingVertical: { paddingVertical: '2%', }, + smallPaddingTop: { + paddingTop: '2%', + }, padding: { padding: '5%', }, @@ -19,6 +22,9 @@ const styles = StyleSheet.create({ paddingVertical: { paddingVertical: '5%', }, + paddingTop: { + paddingTop: '5%', + }, centered: { justifyContent: 'center', alignItems: 'center', @@ -61,6 +67,16 @@ const styles = StyleSheet.create({ justifyEnd: { justifyContent: 'flex-end', }, + fullWidth: { + width: '100%', + }, + fullHeight: { + height: '100%', + }, + fullSize: { + width: '100%', + height: '100%', + }, }); export default styles; diff --git a/src/types/sort.ts b/src/types/sort.ts index 0d67d00..886e9b0 100644 --- a/src/types/sort.ts +++ b/src/types/sort.ts @@ -32,6 +32,7 @@ const homeSortQuery = (sort: HOME_SORT) => { enum TAG_SORT { NAME = 'Name', + COLOR = 'Color', MEMES_LENGTH = 'Items', DATE_CREATED = 'Date Created', DATE_MODIFIED = 'Date Modified', @@ -43,6 +44,9 @@ const tagSortQuery = (sort: TAG_SORT) => { case TAG_SORT.NAME: { return 'name'; } + case TAG_SORT.COLOR: { + return 'color'; + } case TAG_SORT.MEMES_LENGTH: { return 'memesLength'; } diff --git a/src/utilities/icon.ts b/src/utilities/icon.ts index f2ad6ed..d0d0d2e 100644 --- a/src/utilities/icon.ts +++ b/src/utilities/icon.ts @@ -8,7 +8,8 @@ const getSortIcon = ( switch (sort) { case HOME_SORT.TITLE: - case TAG_SORT.NAME: { + case TAG_SORT.NAME: + case TAG_SORT.COLOR: { sortIcon = 'sort-alphabetical'; break; }