Add meme view & sharing

Signed-off-by: Nikolaos Karaolidis <nick@karaolidis.com>
This commit is contained in:
2023-07-24 21:55:36 +03:00
parent 04661ca356
commit e479e3c0ad
33 changed files with 724 additions and 482 deletions

136
src/screens/memeView.tsx Normal file
View File

@@ -0,0 +1,136 @@
import React, { useRef, useState } from 'react';
import { NativeStackScreenProps } from '@react-navigation/native-stack';
import { StyleSheet, View } from 'react-native';
import { useQuery, useRealm } from '@realm/react';
import { FlashList } from '@shopify/flash-list';
import { Appbar, Portal, Snackbar } from 'react-native-paper';
import { RootStackParamList, ROUTE } from '../types';
import { Meme } from '../database';
import { useDimensions } from '../contexts';
import { MemeViewItem } from '../components';
import {
copyMeme,
deleteMeme,
editMeme,
favoriteMeme,
multipleIdQuery,
shareMeme,
} from '../utilities';
import { NavigationProp, useNavigation } from '@react-navigation/native';
import styles from '../styles';
const memeViewStyles = StyleSheet.create({
footer: {
position: 'absolute',
bottom: 0,
left: 0,
right: 0,
height: 80,
},
snackbar: {
marginBottom: 90,
},
});
const MemeView = ({
route,
}: NativeStackScreenProps<RootStackParamList, ROUTE.MEME_VIEW>) => {
const { orientation, dimensions } = useDimensions();
const navigation = useNavigation<NavigationProp<RootStackParamList>>();
const realm = useRealm();
const { ids } = route.params;
const [index, setIndex] = useState(route.params.index);
const [snackbarVisible, setSnackbarVisible] = useState(false);
const [snackbarMessage, setSnackbarMessage] = useState('');
const flashListRef = useRef<FlashList<Meme>>(null);
const memes = useQuery<Meme>(Meme.schema.name, collectionIn => {
return collectionIn.filtered(multipleIdQuery(ids));
});
if (memes.length === 0) return <></>;
return (
<>
<Appbar.Header>
<Appbar.BackAction onPress={() => navigation.goBack()} />
<Appbar.Content title={memes[index].title} />
</Appbar.Header>
<View>
<FlashList
ref={flashListRef}
key={orientation}
data={memes}
initialScrollIndex={index}
onScroll={event => {
const newIndex = Math.round(
event.nativeEvent.contentOffset.x /
event.nativeEvent.layoutMeasurement.width,
);
if (newIndex !== index) setIndex(newIndex);
}}
estimatedItemSize={dimensions.width}
pagingEnabled
horizontal
showsHorizontalScrollIndicator={false}
estimatedListSize={{
height: dimensions.height - 160,
width: dimensions.width,
}}
renderItem={({ item: meme }) => <MemeViewItem meme={meme} />}
/>
</View>
<Appbar style={[memeViewStyles.footer, styles.flexRowSpaceEvenly]}>
<Appbar.Action
icon={memes[index].isFavorite ? 'heart' : 'heart-outline'}
onPress={() => favoriteMeme(realm, memes[index])}
/>
<Appbar.Action icon="share" onPress={() => shareMeme(memes[index])} />
<Appbar.Action
icon="content-copy"
onPress={() => {
copyMeme(memes[index]);
setSnackbarMessage('Meme copied!');
setSnackbarVisible(true);
}}
/>
<Appbar.Action
icon="pencil"
onPress={() => {
editMeme(navigation, memes[index]);
}}
/>
<Appbar.Action
icon="delete"
onPress={() => {
if (index === memes.length - 1) {
setIndex(index - 1);
flashListRef.current?.scrollToIndex({
index: index - 1,
});
}
void deleteMeme(realm, memes[index]);
if (memes.length === 1) navigation.goBack();
}}
/>
</Appbar>
<Portal>
<Snackbar
visible={snackbarVisible}
onDismiss={() => setSnackbarVisible(false)}
style={memeViewStyles.snackbar}
action={{
label: 'Dismiss',
onPress: () => setSnackbarVisible(false),
}}>
{snackbarMessage}
</Snackbar>
</Portal>
</>
);
};
export default MemeView;