Add meme-adding logic

Signed-off-by: Nikolaos Karaolidis <nick@karaolidis.com>
This commit is contained in:
2023-07-21 09:46:13 +03:00
parent 1b2ce96c5e
commit 4b601872bc
40 changed files with 1037 additions and 324 deletions

185
src/screens/memes.tsx Normal file
View File

@@ -0,0 +1,185 @@
import React, { useState } from 'react';
import { StyleSheet, View } from 'react-native';
import { useQuery } from '@realm/react';
import {
Button,
Menu,
IconButton,
Divider,
useTheme,
Searchbar,
HelperText,
} from 'react-native-paper';
import { useDispatch, useSelector } from 'react-redux';
import styles from '../styles';
import { MEME_SORT, SORT_DIRECTION } from '../types';
import { getSortIcon, getViewIcon } from '../utilities';
import {
RootState,
cycleMemesView,
toggleMemesSortDirection,
setMemesSortDirection,
toggleMemesFavoritesOnly,
setMemesSort,
setMemesFilter,
} from '../state';
import { MEME_TYPE, Meme, memeTypePlural } from '../database';
import { useDimensions } from '../contexts';
const memesStyles = StyleSheet.create({
headerButtonView: {
height: 50,
},
helperText: {
marginVertical: 10,
},
});
const Memes = () => {
const { colors } = useTheme();
const { orientation } = useDimensions();
const sort = useSelector((state: RootState) => state.memes.sort);
const sortDirection = useSelector(
(state: RootState) => state.memes.sortDirection,
);
const view = useSelector((state: RootState) => state.memes.view);
const favoritesOnly = useSelector(
(state: RootState) => state.memes.favoritesOnly,
);
const filter = useSelector((state: RootState) => state.memes.filter);
const dispatch = useDispatch();
const [sortMenuVisible, setSortMenuVisible] = useState(false);
const [filterMenuVisible, setFilterMenuVisible] = useState(false);
const handleSortModeChange = (newSort: MEME_SORT) => {
if (newSort === sort) {
dispatch(toggleMemesSortDirection());
} else {
dispatch(setMemesSort(newSort));
if (newSort === MEME_SORT.TITLE) {
dispatch(setMemesSortDirection(SORT_DIRECTION.ASCENDING));
} else {
dispatch(setMemesSortDirection(SORT_DIRECTION.DESCENDING));
}
}
setSortMenuVisible(false);
};
const handleFilterChange = (newFilter: MEME_TYPE | undefined) => {
dispatch(setMemesFilter(newFilter));
setFilterMenuVisible(false);
};
const [search, setSearch] = useState('');
const memes = useQuery<Meme>(Meme.schema.name);
return (
<View
style={[
orientation == 'portrait' && styles.paddingTop,
orientation == 'landscape' && styles.smallPaddingTop,
styles.paddingHorizontal,
styles.fullSize,
{ backgroundColor: colors.background },
]}>
<Searchbar
placeholder="Search Memes"
value={search}
onChangeText={setSearch}
/>
<View
style={[
styles.flexRowSpaceBetween,
styles.alignCenter,
memesStyles.headerButtonView,
]}>
<View style={[styles.flexRow, styles.alignCenter]}>
<Menu
visible={sortMenuVisible}
onDismiss={() => setSortMenuVisible(false)}
anchor={
<Button
onPress={() => setSortMenuVisible(true)}
icon={getSortIcon(sort, sortDirection)}
contentStyle={styles.flexRowReverse}
compact>
Sort By: {sort}
</Button>
}>
{Object.keys(MEME_SORT).map(key => {
return (
<Menu.Item
key={key}
onPress={() =>
handleSortModeChange(
MEME_SORT[key as keyof typeof MEME_SORT],
)
}
title={MEME_SORT[key as keyof typeof MEME_SORT]}
/>
);
})}
</Menu>
</View>
<View style={[styles.flexRow, styles.alignCenter]}>
<IconButton
icon={getViewIcon(view)}
iconColor={colors.primary}
size={16}
animated
onPress={() => dispatch(cycleMemesView())}
/>
<IconButton
icon={favoritesOnly ? 'heart' : 'heart-outline'}
iconColor={colors.primary}
size={16}
animated
onPress={() => dispatch(toggleMemesFavoritesOnly())}
/>
<Menu
visible={filterMenuVisible}
onDismiss={() => setFilterMenuVisible(false)}
anchor={
<IconButton
onPress={() => setFilterMenuVisible(true)}
icon={filter ? 'filter' : 'filter-outline'}
iconColor={colors.primary}
size={16}
/>
}>
<Menu.Item
// eslint-disable-next-line unicorn/no-useless-undefined
onPress={() => handleFilterChange(undefined)}
title="All"
/>
{Object.keys(MEME_TYPE).map(key => {
return (
<Menu.Item
key={key}
onPress={() =>
handleFilterChange(MEME_TYPE[key as keyof typeof MEME_TYPE])
}
title={
memeTypePlural[MEME_TYPE[key as keyof typeof MEME_TYPE]]
}
/>
);
})}
</Menu>
</View>
</View>
<Divider />
{/* TODO: Meme Views */}
{memes.length === 0 && (
<HelperText
type={'info'}
style={[memesStyles.helperText, styles.centerText]}>
No memes found
</HelperText>
)}
</View>
);
};
export default Memes;