Refactor editor architecture

Signed-off-by: Nikolaos Karaolidis <nick@karaolidis.com>
This commit is contained in:
2023-08-01 08:58:35 +03:00
parent 880c20661e
commit f1f969c8ea
10 changed files with 265 additions and 224 deletions

View File

@@ -1,11 +1,10 @@
import React, { useState } from 'react';
import { HelperText, Text, TextInput, useTheme } from 'react-native-paper';
import { Image } from 'react-native';
import { Image, LayoutAnimation } from 'react-native';
import { useSafeAreaFrame } from 'react-native-safe-area-context';
import { MemeFail, MemeTagSelector } from '..';
import { Tag } from '../../database';
import { StringValidationResult, validateMemeTitle } from '../../utilities';
import { Dimensions } from '../../types';
import { LoadingView, MemeFail, MemeTagSelector } from '..';
import { getFilenameFromUri, validateMemeTitle } from '../../utilities';
import { Dimensions, StagingMeme } from '../../types';
const memeEditorStyles = {
image: {
@@ -25,43 +24,46 @@ const memeEditorStyles = {
};
const MemeEditor = ({
memeUri,
memeFilename,
memeError,
setMemeError,
memeTitle,
setMemeTitle,
memeTags,
setMemeTags,
uri,
mimeType,
setLoading,
error,
setError,
staging,
setStaging,
}: {
memeUri: string;
memeFilename?: string;
memeError: Error | undefined;
setMemeError: (error: Error | undefined) => void;
memeTitle: StringValidationResult;
setMemeTitle: (name: StringValidationResult) => void;
memeTags: Map<string, Tag>;
setMemeTags: (tags: Map<string, Tag>) => void;
uri?: string;
mimeType?: string;
loading: boolean;
setLoading: (loading: boolean) => void;
error: Error | undefined;
setError: (error: Error | undefined) => void;
staging?: StagingMeme;
setStaging: (staging: StagingMeme) => void;
}) => {
const { width } = useSafeAreaFrame();
const { colors } = useTheme();
const [dimensions, setDimensions] = useState<Dimensions>();
if (!uri || !mimeType || !staging) return <LoadingView />;
return (
<>
<TextInput
mode="outlined"
label="Title"
value={memeTitle.raw}
onChangeText={title => setMemeTitle(validateMemeTitle(title))}
error={!memeTitle.valid}
value={staging.title.raw}
onChangeText={title =>
setStaging({ ...staging, title: validateMemeTitle(title) })
}
error={!staging.title.valid}
selectTextOnFocus
/>
<HelperText type="error" visible={!memeTitle.valid}>
{memeTitle.error}
<HelperText type="error" visible={!staging.title.valid}>
{staging.title.error}
</HelperText>
{memeError ? (
{error ? (
<MemeFail
style={[
{
@@ -74,7 +76,7 @@ const MemeEditor = ({
/>
) : (
<Image
source={{ uri: memeUri }}
source={{ uri }}
style={[
dimensions
? {
@@ -87,9 +89,10 @@ const MemeEditor = ({
100,
),
}
: {
: // eslint-disable-next-line react-native/no-inline-styles
{
width: width * 0.92,
height: width * 0.92,
height: 1,
},
memeEditorStyles.image,
]}
@@ -99,19 +102,29 @@ const MemeEditor = ({
width: event.nativeEvent.source.width,
height: event.nativeEvent.source.height,
});
setLoading(false);
LayoutAnimation.configureNext(
LayoutAnimation.Presets.easeInEaseOut,
);
}}
onError={event => setMemeError(event.nativeEvent.error as Error)}
onError={() =>
setError(
new Error(
'The URI for this meme appears to be broken. This may have been caused by the file being moved or deleted.',
),
)
}
/>
)}
<Text
variant="bodySmall"
style={[memeEditorStyles.uri, { color: colors.onSurfaceDisabled }]}
numberOfLines={1}>
{memeFilename}
{getFilenameFromUri(uri)}
</Text>
<MemeTagSelector
memeTags={memeTags}
setMemeTags={setMemeTags}
memeTags={staging.tags}
setMemeTags={tags => setStaging({ ...staging, tags })}
style={memeEditorStyles.memeTagSelector}
/>
</>