From 880c20661e6e08a216db8518f50c0629d89dfe71 Mon Sep 17 00:00:00 2001 From: Nikolaos Karaolidis Date: Mon, 31 Jul 2023 10:03:16 +0300 Subject: [PATCH] Fix crash when deleting memes Again. Signed-off-by: Nikolaos Karaolidis --- src/components/loadingView.tsx | 11 +++-- src/components/memes/memeViewItem.tsx | 6 +-- src/database/meme.ts | 1 - src/database/tag.ts | 1 - src/screens/editors/addMeme.tsx | 60 ++++++++++++--------------- src/screens/memeView.tsx | 53 +++++++++++++++-------- src/state/settings.ts | 3 +- src/utilities/constants.ts | 3 +- src/utilities/index.ts | 2 +- 9 files changed, 74 insertions(+), 66 deletions(-) diff --git a/src/components/loadingView.tsx b/src/components/loadingView.tsx index 3d3a111..8ba41fc 100644 --- a/src/components/loadingView.tsx +++ b/src/components/loadingView.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { ComponentProps } from 'react'; import { ActivityIndicator, StyleSheet, View } from 'react-native'; import { useTheme } from 'react-native-paper'; @@ -10,12 +10,17 @@ const loadingViewStyles = StyleSheet.create({ }, }); -const LoadingView = () => { +const LoadingView = ({ ...props }: ComponentProps) => { const { colors } = useTheme(); return ( + {...props} + style={[ + props.style, + loadingViewStyles.view, + { backgroundColor: colors.background }, + ]}> ); diff --git a/src/components/memes/memeViewItem.tsx b/src/components/memes/memeViewItem.tsx index 05a314e..0c9eb16 100644 --- a/src/components/memes/memeViewItem.tsx +++ b/src/components/memes/memeViewItem.tsx @@ -27,11 +27,7 @@ const MemeViewItem = ({ meme }: { meme: Meme }) => { const { dimensions, loading, error } = useImageDimensions({ uri }); if (!error && (loading || !dimensions)) { - return ( - - - - ); + return ; } return ( diff --git a/src/database/meme.ts b/src/database/meme.ts index 0c2f401..ccf55b2 100644 --- a/src/database/meme.ts +++ b/src/database/meme.ts @@ -17,7 +17,6 @@ const memeTypePlural = { [MEME_TYPE.TEXT]: 'Text', }; -// eslint-disable-next-line @typescript-eslint/naming-convention class Meme extends Object { id!: BSON.UUID; memeType!: MEME_TYPE; diff --git a/src/database/tag.ts b/src/database/tag.ts index f311326..64f90ac 100644 --- a/src/database/tag.ts +++ b/src/database/tag.ts @@ -2,7 +2,6 @@ import { BSON, Object, ObjectSchema } from 'realm'; import { Meme } from './meme'; import { generateRandomColor } from '../utilities'; -// eslint-disable-next-line @typescript-eslint/naming-convention class Tag extends Object { id!: BSON.UUID; name!: string; diff --git a/src/screens/editors/addMeme.tsx b/src/screens/editors/addMeme.tsx index c5201ff..6b15e56 100644 --- a/src/screens/editors/addMeme.tsx +++ b/src/screens/editors/addMeme.tsx @@ -56,23 +56,33 @@ const AddMeme = ({ const [memeIsFavorite, setMemeIsFavorite] = useState(false); const [memeTags, setMemeTags] = useState(new Map()); - useEffect(() => { - const loadMeme = async () => { - const mimeType = await guessMimeType(file.current.uri); - if (!mimeType) { - setMemeError( - new Error('Could not determine MIME type or file is not supported.'), - ); - return; - } - - setMemeMimeType(mimeType); - }; - + const resetState = useCallback(async (newIndex = 0) => { setMemeLoading(true); - void loadMeme(); + // eslint-disable-next-line unicorn/no-useless-undefined + setMemeError(undefined); + + setIndex(newIndex); + file.current = files.current[newIndex]; + + setMemeUri(file.current.uri); + setMemeFilename(file.current.filename); + setMemeTitle(validateMemeTitle('New Meme')); + setMemeIsFavorite(false); + setMemeTags(new Map()); + + const mimeType = await guessMimeType(file.current.uri); + if (!mimeType) { + setMemeError( + new Error('Could not determine MIME type or file is not supported.'), + ); + return; + } + setMemeMimeType(mimeType); + setMemeLoading(false); - }, [file]); + }, []); + + useEffect(() => void resetState(), [resetState]); const saveMeme = useCallback(async () => { if (!memeMimeType) return; @@ -126,40 +136,24 @@ const AddMeme = ({ goBack(); }, [goBack, saveMeme]); - const resetState = useCallback(() => { - setMemeUri(file.current.uri); - setMemeFilename(file.current.filename); - setMemeTitle(validateMemeTitle('New Meme')); - setMemeIsFavorite(false); - setMemeTags(new Map()); - }, []); - const handleSaveAndNext = useCallback(async () => { setIsSaving(true); await saveMeme(); setIsSaving(false); - - setIndex(index + 1); - file.current = files.current[index + 1]; - - resetState(); + await resetState(index + 1); }, [index, resetState, saveMeme]); const handleSaveAndAddMore = useCallback(async () => { setIsSavingAndAddingMore(true); await saveMeme(); setIsSavingAndAddingMore(false); - - setIndex(0); const response = await pick({ type: allowedMimeTypes, allowMultiSelection: true, }).catch(goBack); if (!response) return; files.current = documentPickerResponseToAddMemeFile(response); - file.current = files.current[0]; - - resetState(); + await resetState(0); }, [goBack, resetState, saveMeme]); return ( diff --git a/src/screens/memeView.tsx b/src/screens/memeView.tsx index 440a273..812f1d4 100644 --- a/src/screens/memeView.tsx +++ b/src/screens/memeView.tsx @@ -1,4 +1,4 @@ -import React, { useRef, useState } from 'react'; +import React, { useEffect, useRef, useState } from 'react'; import { NativeStackScreenProps } from '@react-navigation/native-stack'; import { StyleSheet } from 'react-native'; import { useQuery, useRealm } from '@realm/react'; @@ -8,7 +8,7 @@ import { useSafeAreaFrame } from 'react-native-safe-area-context'; import { NavigationProp, useNavigation } from '@react-navigation/native'; import { RootStackParamList, ROUTE } from '../types'; import { Meme } from '../database'; -import { MemeViewItem } from '../components'; +import { LoadingView, MemeViewItem } from '../components'; import { copyMeme, deleteMeme, @@ -56,22 +56,30 @@ const MemeView = ({ )!; const realm = useRealm(); - const { ids } = route.params; - const [index, setIndex] = useState(route.params.index); - + const [isBlocked, setIsBlocked] = useState(false); const [snackbarMessage, setSnackbarMessage] = useState(); const flashListRef = useRef>(null); + const [index, setIndex] = useState(route.params.index); const memes = useQuery(Meme.schema.name, collectionIn => { - return collectionIn.filtered(multipleIdQuery(ids)); + return collectionIn.filtered(multipleIdQuery(route.params.ids)); }); + useEffect(() => { + if (memes.length === 0) navigation.goBack(); + if (index >= memes.length) { + setIndex(memes.length - 1); + flashListRef.current?.scrollToIndex({ index: memes.length - 1 }); + } + }, [index, memes.length, navigation]); + return ( <> navigation.goBack()} /> - + {/* eslint-disable-next-line @typescript-eslint/no-unnecessary-condition */} + } + renderItem={({ item }) => + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition + item ? ( + + ) : ( + + ) + } + scrollEnabled={!isBlocked} /> favoriteMeme(realm, memes[index])} + disabled={isBlocked} /> setSnackbarMessage('Meme copied!')) .catch(() => setSnackbarMessage('Failed to copy meme!')); }} + disabled={isBlocked} /> { editMeme(navigation, memes[index]); }} + disabled={isBlocked} /> { - void deleteMeme(realm, storageUri, memes[index]); - if (index === memes.length - 1) { - setIndex(index - 1); - flashListRef.current?.scrollToIndex({ - index: index - 1, - }); - } - if (memes.length === 1) navigation.goBack(); + onPress={async () => { + setIsBlocked(true); + await deleteMeme(realm, storageUri, memes[index]); + setIsBlocked(false); }} + disabled={isBlocked} /> diff --git a/src/state/settings.ts b/src/state/settings.ts index 687cf6a..fe1bd61 100644 --- a/src/state/settings.ts +++ b/src/state/settings.ts @@ -91,8 +91,7 @@ const updateNoMedia = createAsyncThunk( const validateSettings = createAsyncThunk( 'settings/validateSettings', - // eslint-disable-next-line @typescript-eslint/naming-convention - async (_, { dispatch, getState }) => { + async (ignored, { dispatch, getState }) => { const state = getState() as RootState; const { storageUri, noMedia } = state.settings; diff --git a/src/utilities/constants.ts b/src/utilities/constants.ts index c74120c..629461f 100644 --- a/src/utilities/constants.ts +++ b/src/utilities/constants.ts @@ -1,8 +1,7 @@ const packageName = 'com.karaolidis.terminallyonline'; const appName = 'Terminally Online'; -const fileProvider = 'com.karaolidis.terminallyonline.rnshare.fileprovider'; // eslint-disable-next-line @typescript-eslint/no-empty-function const noOp = () => {}; -export { packageName, appName, fileProvider, noOp }; +export { packageName, appName, noOp }; diff --git a/src/utilities/index.ts b/src/utilities/index.ts index 26ad6a2..5cd1444 100644 --- a/src/utilities/index.ts +++ b/src/utilities/index.ts @@ -7,7 +7,7 @@ export { rgbToRgba, generateRandomColor, } from './color'; -export { packageName, appName, fileProvider, noOp } from './constants'; +export { packageName, appName, noOp } from './constants'; export { multipleIdQuery } from './database'; export { getFlashListItemHeight, getFontAwesome5IconSize } from './dimensions'; export {