Refactor validation
Signed-off-by: Nikolaos Karaolidis <nick@karaolidis.com>
This commit is contained in:
@@ -13,7 +13,11 @@ import styles from '../styles';
|
||||
import { ROUTE, RootStackParamList } from '../types';
|
||||
import { MEME_TYPE, Meme, Tag } from '../database';
|
||||
import { RootState } from '../state';
|
||||
import { getMemeType } from '../utilities';
|
||||
import {
|
||||
getMemeType,
|
||||
validateMemeDescription,
|
||||
validateMemeTitle,
|
||||
} from '../utilities';
|
||||
import { MemeEditor } from '../components';
|
||||
|
||||
const AddMeme = ({
|
||||
@@ -34,13 +38,13 @@ const AddMeme = ({
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
uri.length > 1 ? MEME_TYPE.ALBUM : getMemeType(uri[0].type!);
|
||||
|
||||
const [memeTitle, setMemeTitle] = useState('New Meme');
|
||||
const [memeDescription, setMemeDescription] = useState('');
|
||||
const [memeTitle, setMemeTitle] = useState(validateMemeTitle('New Meme'));
|
||||
const [memeDescription, setMemeDescription] = useState(
|
||||
validateMemeDescription(''),
|
||||
);
|
||||
const [memeIsFavorite, setMemeIsFavorite] = useState(false);
|
||||
const [memeTags, setMemeTags] = useState(new Map<string, Tag>());
|
||||
|
||||
const [memeTitleError, setMemeTitleError] = useState<string | undefined>();
|
||||
|
||||
const [isSaving, setIsSaving] = useState(false);
|
||||
|
||||
const handleSave = async () => {
|
||||
@@ -72,8 +76,8 @@ const AddMeme = ({
|
||||
uri: savedUri,
|
||||
size,
|
||||
hash,
|
||||
title: memeTitle,
|
||||
description: memeDescription,
|
||||
title: memeTitle.parsed,
|
||||
description: memeDescription.parsed,
|
||||
isFavorite: memeIsFavorite,
|
||||
tags: [...memeTags.values()],
|
||||
tagsLength: memeTags.size,
|
||||
@@ -119,8 +123,6 @@ const AddMeme = ({
|
||||
setMemeDescription={setMemeDescription}
|
||||
memeTags={memeTags}
|
||||
setMemeTags={setMemeTags}
|
||||
memeTitleError={memeTitleError}
|
||||
setMemeTitleError={setMemeTitleError}
|
||||
/>
|
||||
</View>
|
||||
<View style={[styles.flex, styles.justifyEnd]}>
|
||||
@@ -128,7 +130,7 @@ const AddMeme = ({
|
||||
mode="contained"
|
||||
icon="floppy"
|
||||
onPress={handleSave}
|
||||
disabled={!!memeTitleError || isSaving}
|
||||
disabled={!memeTitle.valid || !memeDescription.valid || isSaving}
|
||||
loading={isSaving}>
|
||||
Save
|
||||
</Button>
|
||||
|
@@ -4,7 +4,11 @@ import { Appbar, Button, useTheme } from 'react-native-paper';
|
||||
import { useNavigation } from '@react-navigation/native';
|
||||
import { useRealm } from '@realm/react';
|
||||
import styles from '../styles';
|
||||
import { generateRandomColor } from '../utilities';
|
||||
import {
|
||||
generateRandomColor,
|
||||
validateColor,
|
||||
validateTagName,
|
||||
} from '../utilities';
|
||||
import { useDimensions } from '../contexts';
|
||||
import { Tag } from '../database';
|
||||
import { TagEditor } from '../components';
|
||||
@@ -15,18 +19,16 @@ const AddTag = () => {
|
||||
const { orientation } = useDimensions();
|
||||
const realm = useRealm();
|
||||
|
||||
const [tagName, setTagName] = useState('newTag');
|
||||
const [tagColor, setTagColor] = useState(generateRandomColor());
|
||||
const [validatedTagColor, setValidatedTagColor] = useState(tagColor);
|
||||
|
||||
const [tagNameError, setTagNameError] = useState<string | undefined>();
|
||||
const [tagColorError, setTagColorError] = useState<string | undefined>();
|
||||
const [tagName, setTagName] = useState(validateTagName('newTag'));
|
||||
const [tagColor, setTagColor] = useState(
|
||||
validateColor(generateRandomColor()),
|
||||
);
|
||||
|
||||
const handleSave = () => {
|
||||
realm.write(() => {
|
||||
realm.create(Tag.schema.name, {
|
||||
name: tagName,
|
||||
color: tagColor,
|
||||
name: tagName.parsed,
|
||||
color: tagColor.parsed,
|
||||
});
|
||||
});
|
||||
|
||||
@@ -54,12 +56,6 @@ const AddTag = () => {
|
||||
setTagName={setTagName}
|
||||
tagColor={tagColor}
|
||||
setTagColor={setTagColor}
|
||||
validatedTagColor={validatedTagColor}
|
||||
setValidatedTagColor={setValidatedTagColor}
|
||||
tagNameError={tagNameError}
|
||||
setTagNameError={setTagNameError}
|
||||
tagColorError={tagColorError}
|
||||
setTagColorError={setTagColorError}
|
||||
/>
|
||||
</View>
|
||||
<View style={[styles.flex, styles.justifyEnd]}>
|
||||
@@ -67,7 +63,7 @@ const AddTag = () => {
|
||||
mode="contained"
|
||||
icon="floppy"
|
||||
onPress={handleSave}
|
||||
disabled={!!tagNameError || !!tagColorError}>
|
||||
disabled={!tagName.valid || !tagColor.valid}>
|
||||
Save
|
||||
</Button>
|
||||
</View>
|
||||
|
@@ -10,6 +10,7 @@ import styles from '../styles';
|
||||
import { useDimensions } from '../contexts';
|
||||
import { ROUTE, RootStackParamList } from '../types';
|
||||
import { Tag } from '../database';
|
||||
import { validateColor, validateTagName } from '../utilities';
|
||||
|
||||
const EditTag = ({
|
||||
route,
|
||||
@@ -25,17 +26,13 @@ const EditTag = ({
|
||||
BSON.UUID.createFromHexString(route.params.id),
|
||||
)!;
|
||||
|
||||
const [tagName, setTagName] = useState(tag.name);
|
||||
const [tagColor, setTagColor] = useState(tag.color);
|
||||
const [validatedTagColor, setValidatedTagColor] = useState(tagColor);
|
||||
|
||||
const [tagNameError, setTagNameError] = useState<string | undefined>();
|
||||
const [tagColorError, setTagColorError] = useState<string | undefined>();
|
||||
const [tagName, setTagName] = useState(validateTagName(tag.name));
|
||||
const [tagColor, setTagColor] = useState(validateColor(tag.color));
|
||||
|
||||
const handleSave = () => {
|
||||
realm.write(() => {
|
||||
tag.name = tagName;
|
||||
tag.color = tagColor;
|
||||
tag.name = tagName.parsed;
|
||||
tag.color = tagColor.parsed;
|
||||
tag.dateModified = new Date();
|
||||
});
|
||||
|
||||
@@ -80,12 +77,6 @@ const EditTag = ({
|
||||
setTagName={setTagName}
|
||||
tagColor={tagColor}
|
||||
setTagColor={setTagColor}
|
||||
validatedTagColor={validatedTagColor}
|
||||
setValidatedTagColor={setValidatedTagColor}
|
||||
tagNameError={tagNameError}
|
||||
setTagNameError={setTagNameError}
|
||||
tagColorError={tagColorError}
|
||||
setTagColorError={setTagColorError}
|
||||
/>
|
||||
</View>
|
||||
<View style={[styles.flex, styles.justifyEnd]}>
|
||||
@@ -93,7 +84,7 @@ const EditTag = ({
|
||||
mode="contained"
|
||||
icon="floppy"
|
||||
onPress={handleSave}
|
||||
disabled={!!tagNameError || !!tagColorError}>
|
||||
disabled={!tagName.valid || !tagColor.valid}>
|
||||
Save
|
||||
</Button>
|
||||
</View>
|
||||
|
@@ -12,7 +12,7 @@ import {
|
||||
} from 'react-native-paper';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import styles from '../styles';
|
||||
import { MEME_SORT, SORT_DIRECTION } from '../types';
|
||||
import { MEME_SORT, SORT_DIRECTION, memesSortQuery } from '../types';
|
||||
import { getSortIcon, getViewIcon } from '../utilities';
|
||||
import {
|
||||
RootState,
|
||||
@@ -72,7 +72,27 @@ const Memes = () => {
|
||||
};
|
||||
|
||||
const [search, setSearch] = useState('');
|
||||
const memes = useQuery<Meme>(Meme.schema.name);
|
||||
|
||||
const memes = useQuery<Meme>(
|
||||
Meme.schema.name,
|
||||
collectionIn => {
|
||||
let collection = collectionIn;
|
||||
|
||||
if (favoritesOnly) collection = collection.filtered('isFavorite == true');
|
||||
if (filter) collection = collection.filtered('type == $0', filter);
|
||||
if (search) {
|
||||
collection = collection.filtered('title CONTAINS[c] $0', search);
|
||||
}
|
||||
|
||||
collection = collection.sorted(
|
||||
memesSortQuery(sort),
|
||||
sortDirection === SORT_DIRECTION.DESCENDING,
|
||||
);
|
||||
|
||||
return collection;
|
||||
},
|
||||
[sort, sortDirection, favoritesOnly, filter, search],
|
||||
);
|
||||
|
||||
return (
|
||||
<View
|
||||
|
@@ -13,7 +13,11 @@ import { openDocumentTree } from 'react-native-scoped-storage';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import type {} from 'redux-thunk/extend-redux';
|
||||
import styles from '../styles';
|
||||
import { RootState, updateNoMedia, updateStorageUri } from '../state';
|
||||
import {
|
||||
RootState,
|
||||
setNoMedia,
|
||||
setStorageUri,
|
||||
} from '../state';
|
||||
import { useDimensions } from '../contexts';
|
||||
|
||||
const settingsScreenStyles = StyleSheet.create({
|
||||
@@ -68,7 +72,7 @@ const SettingsScreen = () => {
|
||||
}}
|
||||
onPress={async () => {
|
||||
const { uri } = await openDocumentTree(true);
|
||||
void dispatch(updateStorageUri(uri));
|
||||
void dispatch(setStorageUri(uri));
|
||||
}}>
|
||||
Change External Storage Path
|
||||
</Button>
|
||||
@@ -84,7 +88,7 @@ const SettingsScreen = () => {
|
||||
<Switch
|
||||
value={noMedia}
|
||||
onValueChange={value => {
|
||||
void dispatch(updateNoMedia(value));
|
||||
void dispatch(setNoMedia(value));
|
||||
}}
|
||||
/>
|
||||
</View>
|
||||
|
@@ -99,13 +99,20 @@ const Tags = () => {
|
||||
|
||||
const tags = useQuery<Tag>(
|
||||
Tag.schema.name,
|
||||
collection =>
|
||||
collection
|
||||
.filtered(`name CONTAINS[c] "${search}"`)
|
||||
.sorted(
|
||||
tagSortQuery(sort),
|
||||
sortDirection === SORT_DIRECTION.DESCENDING,
|
||||
),
|
||||
collectionIn => {
|
||||
let collection = collectionIn;
|
||||
|
||||
if (search) {
|
||||
collection = collection.filtered('name CONTAINS[c] $0', search);
|
||||
}
|
||||
|
||||
collection = collection.sorted(
|
||||
tagSortQuery(sort),
|
||||
sortDirection === SORT_DIRECTION.DESCENDING,
|
||||
);
|
||||
|
||||
return collection;
|
||||
},
|
||||
[search, sort, sortDirection],
|
||||
);
|
||||
|
||||
|
@@ -5,7 +5,7 @@ import { useDispatch } from 'react-redux';
|
||||
import { openDocumentTree } from 'react-native-scoped-storage';
|
||||
import styles from '../styles';
|
||||
import { noOp } from '../utilities';
|
||||
import { updateStorageUri } from '../state';
|
||||
import { setStorageUri } from '../state';
|
||||
import { useDimensions } from '../contexts';
|
||||
|
||||
const Welcome = ({ onWelcomeComplete }: { onWelcomeComplete: () => void }) => {
|
||||
@@ -16,7 +16,7 @@ const Welcome = ({ onWelcomeComplete }: { onWelcomeComplete: () => void }) => {
|
||||
const selectStorageLocation = async () => {
|
||||
const uri = await openDocumentTree(true).catch(noOp);
|
||||
if (!uri) return;
|
||||
await dispatch(updateStorageUri(uri.uri));
|
||||
await dispatch(setStorageUri(uri.uri));
|
||||
onWelcomeComplete();
|
||||
};
|
||||
|
||||
|
Reference in New Issue
Block a user