Refactor styles
Signed-off-by: Nikolaos Karaolidis <nick@karaolidis.com>
This commit is contained in:
11
src/app.tsx
11
src/app.tsx
@@ -1,5 +1,5 @@
|
|||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import { AppState, StatusBar, useColorScheme } from 'react-native';
|
import { AppState, StatusBar, useColorScheme, StyleSheet } from 'react-native';
|
||||||
import { PaperProvider } from 'react-native-paper';
|
import { PaperProvider } from 'react-native-paper';
|
||||||
import { SafeAreaProvider } from 'react-native-safe-area-context';
|
import { SafeAreaProvider } from 'react-native-safe-area-context';
|
||||||
import { RealmProvider } from '@realm/react';
|
import { RealmProvider } from '@realm/react';
|
||||||
@@ -13,7 +13,12 @@ import NavigationContainer from './navigation';
|
|||||||
import { store, persistor, validateSettings } from './state';
|
import { store, persistor, validateSettings } from './state';
|
||||||
import { LoadingView } from './components';
|
import { LoadingView } from './components';
|
||||||
import { Welcome } from './screens';
|
import { Welcome } from './screens';
|
||||||
import styles from './styles';
|
|
||||||
|
const appStyles = StyleSheet.create({
|
||||||
|
gestureHandler: {
|
||||||
|
flex: 1,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const App = () => {
|
const App = () => {
|
||||||
const [showWelcome, setShowWelcome] = useState(false);
|
const [showWelcome, setShowWelcome] = useState(false);
|
||||||
@@ -49,7 +54,7 @@ const App = () => {
|
|||||||
persistor={persistor}
|
persistor={persistor}
|
||||||
onBeforeLift={onBeforeLift}>
|
onBeforeLift={onBeforeLift}>
|
||||||
<RealmProvider schema={[Meme, Tag]}>
|
<RealmProvider schema={[Meme, Tag]}>
|
||||||
<GestureHandlerRootView style={styles.flex}>
|
<GestureHandlerRootView style={appStyles.gestureHandler}>
|
||||||
<SafeAreaProvider>
|
<SafeAreaProvider>
|
||||||
<StatusBar
|
<StatusBar
|
||||||
barStyle={isDarkMode ? 'light-content' : 'dark-content'}
|
barStyle={isDarkMode ? 'light-content' : 'dark-content'}
|
||||||
|
@@ -2,7 +2,6 @@ import React, { useEffect, useRef } from 'react';
|
|||||||
import { Animated, StyleSheet } from 'react-native';
|
import { Animated, StyleSheet } from 'react-native';
|
||||||
import { useTheme } from 'react-native-paper';
|
import { useTheme } from 'react-native-paper';
|
||||||
import { useDeviceOrientation } from '@react-native-community/hooks';
|
import { useDeviceOrientation } from '@react-native-community/hooks';
|
||||||
import styles from '../styles';
|
|
||||||
|
|
||||||
const hideableHeaderStyles = StyleSheet.create({
|
const hideableHeaderStyles = StyleSheet.create({
|
||||||
headerView: {
|
headerView: {
|
||||||
@@ -11,6 +10,13 @@ const hideableHeaderStyles = StyleSheet.create({
|
|||||||
left: 0,
|
left: 0,
|
||||||
right: 0,
|
right: 0,
|
||||||
zIndex: 1,
|
zIndex: 1,
|
||||||
|
paddingHorizontal: '4%',
|
||||||
|
},
|
||||||
|
headerViewPortrait: {
|
||||||
|
paddingTop: '4%',
|
||||||
|
},
|
||||||
|
headerViewLandscape: {
|
||||||
|
paddingTop: '2%',
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -38,8 +44,9 @@ const HideableHeader = ({
|
|||||||
<Animated.View
|
<Animated.View
|
||||||
style={[
|
style={[
|
||||||
hideableHeaderStyles.headerView,
|
hideableHeaderStyles.headerView,
|
||||||
orientation === 'portrait' ? styles.paddingTop : styles.smallPaddingTop,
|
orientation === 'portrait'
|
||||||
styles.paddingHorizontal,
|
? hideableHeaderStyles.headerViewPortrait
|
||||||
|
: hideableHeaderStyles.headerViewLandscape,
|
||||||
{
|
{
|
||||||
transform: [
|
transform: [
|
||||||
{
|
{
|
||||||
|
@@ -1,19 +1,23 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { ActivityIndicator, View } from 'react-native';
|
import { ActivityIndicator, StyleSheet, View } from 'react-native';
|
||||||
import { useTheme } from 'react-native-paper';
|
import { useTheme } from 'react-native-paper';
|
||||||
import styles from '../styles';
|
|
||||||
|
const loadingViewStyles = StyleSheet.create({
|
||||||
|
view: {
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
flex: 1,
|
||||||
|
width: '100%',
|
||||||
|
height: '100%',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const LoadingView = () => {
|
const LoadingView = () => {
|
||||||
const { colors } = useTheme();
|
const { colors } = useTheme();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View
|
<View
|
||||||
style={[
|
style={[loadingViewStyles.view, { backgroundColor: colors.background }]}>
|
||||||
styles.center,
|
|
||||||
styles.flex,
|
|
||||||
styles.fullSize,
|
|
||||||
{ backgroundColor: colors.background },
|
|
||||||
]}>
|
|
||||||
<ActivityIndicator size="large" color={colors.primary} />
|
<ActivityIndicator size="large" color={colors.primary} />
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
|
@@ -7,7 +7,6 @@ import { useSafeAreaFrame } from 'react-native-safe-area-context';
|
|||||||
import { TAG_SORT, tagSortQuery } from '../../types';
|
import { TAG_SORT, tagSortQuery } from '../../types';
|
||||||
import { TagChip } from '../tags';
|
import { TagChip } from '../tags';
|
||||||
import { Tag } from '../../database';
|
import { Tag } from '../../database';
|
||||||
import styles from '../../styles';
|
|
||||||
import { validateTagName } from '../../utilities';
|
import { validateTagName } from '../../utilities';
|
||||||
|
|
||||||
const memeTagSearchModalStyles = StyleSheet.create({
|
const memeTagSearchModalStyles = StyleSheet.create({
|
||||||
@@ -17,6 +16,7 @@ const memeTagSearchModalStyles = StyleSheet.create({
|
|||||||
padding: 10,
|
padding: 10,
|
||||||
borderTopLeftRadius: 20,
|
borderTopLeftRadius: 20,
|
||||||
borderTopRightRadius: 20,
|
borderTopRightRadius: 20,
|
||||||
|
width: '100%',
|
||||||
},
|
},
|
||||||
searchbar: {
|
searchbar: {
|
||||||
marginBottom: 12,
|
marginBottom: 12,
|
||||||
@@ -97,11 +97,10 @@ const MemeTagSearchModal = ({
|
|||||||
<Modal
|
<Modal
|
||||||
visible={visible}
|
visible={visible}
|
||||||
contentContainerStyle={[
|
contentContainerStyle={[
|
||||||
|
memeTagSearchModalStyles.modal,
|
||||||
{
|
{
|
||||||
backgroundColor: colors.surface,
|
backgroundColor: colors.surface,
|
||||||
},
|
},
|
||||||
styles.fullWidth,
|
|
||||||
memeTagSearchModalStyles.modal,
|
|
||||||
]}
|
]}
|
||||||
onDismiss={() => setVisible(false)}>
|
onDismiss={() => setVisible(false)}>
|
||||||
<Searchbar
|
<Searchbar
|
||||||
|
@@ -1,11 +1,17 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { ImageZoom } from '@likashefqet/react-native-image-zoom';
|
import { ImageZoom } from '@likashefqet/react-native-image-zoom';
|
||||||
import { Meme } from '../../database';
|
import { StyleSheet, View } from 'react-native';
|
||||||
import { View } from 'react-native';
|
|
||||||
import styles from '../../styles';
|
|
||||||
import LoadingView from '../loadingView';
|
|
||||||
import { useSafeAreaFrame } from 'react-native-safe-area-context';
|
import { useSafeAreaFrame } from 'react-native-safe-area-context';
|
||||||
import { useImageDimensions } from '@react-native-community/hooks';
|
import { useImageDimensions } from '@react-native-community/hooks';
|
||||||
|
import LoadingView from '../loadingView';
|
||||||
|
import { Meme } from '../../database';
|
||||||
|
|
||||||
|
const memeViewItemStyles = StyleSheet.create({
|
||||||
|
view: {
|
||||||
|
justifyContent: 'center',
|
||||||
|
alignItems: 'center',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const MemeViewItem = ({ meme }: { meme: Meme }) => {
|
const MemeViewItem = ({ meme }: { meme: Meme }) => {
|
||||||
const { height, width } = useSafeAreaFrame();
|
const { height, width } = useSafeAreaFrame();
|
||||||
@@ -15,7 +21,7 @@ const MemeViewItem = ({ meme }: { meme: Meme }) => {
|
|||||||
if (loading || error || !dimensions) return <LoadingView />;
|
if (loading || error || !dimensions) return <LoadingView />;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={[{ width, height }, styles.center]}>
|
<View style={[{ width, height }, memeViewItemStyles.view]}>
|
||||||
<ImageZoom
|
<ImageZoom
|
||||||
source={{ uri: meme.uri }}
|
source={{ uri: meme.uri }}
|
||||||
style={
|
style={
|
||||||
|
@@ -19,14 +19,23 @@ import {
|
|||||||
toggleMemesFavoritesOnly,
|
toggleMemesFavoritesOnly,
|
||||||
toggleMemesSortDirection,
|
toggleMemesSortDirection,
|
||||||
} from '../../state';
|
} from '../../state';
|
||||||
import styles from '../../styles';
|
|
||||||
import { MEME_SORT, SORT_DIRECTION } from '../../types';
|
import { MEME_SORT, SORT_DIRECTION } from '../../types';
|
||||||
import { getSortIcon, getViewIcon } from '../../utilities';
|
import { getSortIcon, getViewIcon } from '../../utilities';
|
||||||
|
|
||||||
const memesHeaderStyles = StyleSheet.create({
|
const memesHeaderStyles = StyleSheet.create({
|
||||||
buttonView: {
|
buttonView: {
|
||||||
|
flexDirection: 'row',
|
||||||
|
justifyContent: 'space-between',
|
||||||
|
alignItems: 'center',
|
||||||
height: 50,
|
height: 50,
|
||||||
},
|
},
|
||||||
|
buttonSection: {
|
||||||
|
flexDirection: 'row',
|
||||||
|
alignItems: 'center',
|
||||||
|
},
|
||||||
|
sortButton: {
|
||||||
|
flexDirection: 'row-reverse',
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const MemesHeader = ({
|
const MemesHeader = ({
|
||||||
@@ -78,13 +87,8 @@ const MemesHeader = ({
|
|||||||
value={search}
|
value={search}
|
||||||
onChangeText={setSearch}
|
onChangeText={setSearch}
|
||||||
/>
|
/>
|
||||||
<View
|
<View style={memesHeaderStyles.buttonView}>
|
||||||
style={[
|
<View style={memesHeaderStyles.buttonSection}>
|
||||||
styles.flexRowSpaceBetween,
|
|
||||||
styles.alignCenter,
|
|
||||||
memesHeaderStyles.buttonView,
|
|
||||||
]}>
|
|
||||||
<View style={[styles.flexRow, styles.alignCenter]}>
|
|
||||||
<Menu
|
<Menu
|
||||||
visible={sortMenuVisible}
|
visible={sortMenuVisible}
|
||||||
onDismiss={() => setSortMenuVisible(false)}
|
onDismiss={() => setSortMenuVisible(false)}
|
||||||
@@ -92,7 +96,7 @@ const MemesHeader = ({
|
|||||||
<Button
|
<Button
|
||||||
onPress={() => setSortMenuVisible(true)}
|
onPress={() => setSortMenuVisible(true)}
|
||||||
icon={getSortIcon(sort, sortDirection)}
|
icon={getSortIcon(sort, sortDirection)}
|
||||||
contentStyle={styles.flexRowReverse}
|
contentStyle={memesHeaderStyles.sortButton}
|
||||||
compact>
|
compact>
|
||||||
Sort By: {sort}
|
Sort By: {sort}
|
||||||
</Button>
|
</Button>
|
||||||
@@ -112,7 +116,7 @@ const MemesHeader = ({
|
|||||||
})}
|
})}
|
||||||
</Menu>
|
</Menu>
|
||||||
</View>
|
</View>
|
||||||
<View style={[styles.flexRow, styles.alignCenter]}>
|
<View style={memesHeaderStyles.buttonSection}>
|
||||||
<IconButton
|
<IconButton
|
||||||
icon={getViewIcon(view)}
|
icon={getViewIcon(view)}
|
||||||
iconColor={colors.primary}
|
iconColor={colors.primary}
|
||||||
|
@@ -12,7 +12,6 @@ import { Meme } from '../../../database';
|
|||||||
import { RootState } from '../../../state';
|
import { RootState } from '../../../state';
|
||||||
import { VIEW } from '../../../types';
|
import { VIEW } from '../../../types';
|
||||||
import { getFlashListItemHeight } from '../../../utilities';
|
import { getFlashListItemHeight } from '../../../utilities';
|
||||||
import styles from '../../../styles';
|
|
||||||
import MemesMasonryItem from './memesMasonryItem';
|
import MemesMasonryItem from './memesMasonryItem';
|
||||||
import MemesGridItem from './memesGridItem';
|
import MemesGridItem from './memesGridItem';
|
||||||
import MemesListItem from './memesListItem';
|
import MemesListItem from './memesListItem';
|
||||||
@@ -22,6 +21,7 @@ const sharedMemesListStyles = StyleSheet.create({
|
|||||||
paddingBottom: 100,
|
paddingBottom: 100,
|
||||||
},
|
},
|
||||||
helperText: {
|
helperText: {
|
||||||
|
textAlign: 'center',
|
||||||
marginVertical: 15,
|
marginVertical: 15,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@@ -89,9 +89,7 @@ const MemesList = ({
|
|||||||
...memesMasonryListStyles.flashList,
|
...memesMasonryListStyles.flashList,
|
||||||
}}
|
}}
|
||||||
ListEmptyComponent={() => (
|
ListEmptyComponent={() => (
|
||||||
<HelperText
|
<HelperText type={'info'} style={sharedMemesListStyles.helperText}>
|
||||||
type={'info'}
|
|
||||||
style={[sharedMemesListStyles.helperText, styles.centerText]}>
|
|
||||||
No memes found
|
No memes found
|
||||||
</HelperText>
|
</HelperText>
|
||||||
)}
|
)}
|
||||||
@@ -119,9 +117,7 @@ const MemesList = ({
|
|||||||
...memesGridListStyles.flashList,
|
...memesGridListStyles.flashList,
|
||||||
}}
|
}}
|
||||||
ListEmptyComponent={() => (
|
ListEmptyComponent={() => (
|
||||||
<HelperText
|
<HelperText type={'info'} style={sharedMemesListStyles.helperText}>
|
||||||
type={'info'}
|
|
||||||
style={[sharedMemesListStyles.helperText, styles.centerText]}>
|
|
||||||
No memes found
|
No memes found
|
||||||
</HelperText>
|
</HelperText>
|
||||||
)}
|
)}
|
||||||
@@ -149,9 +145,7 @@ const MemesList = ({
|
|||||||
...memesListListStyles.flashList,
|
...memesListListStyles.flashList,
|
||||||
}}
|
}}
|
||||||
ListEmptyComponent={() => (
|
ListEmptyComponent={() => (
|
||||||
<HelperText
|
<HelperText type={'info'} style={sharedMemesListStyles.helperText}>
|
||||||
type={'info'}
|
|
||||||
style={[sharedMemesListStyles.helperText, styles.centerText]}>
|
|
||||||
No memes found
|
No memes found
|
||||||
</HelperText>
|
</HelperText>
|
||||||
)}
|
)}
|
||||||
|
@@ -4,10 +4,10 @@ import { Text, TouchableRipple } from 'react-native-paper';
|
|||||||
import { useSafeAreaFrame } from 'react-native-safe-area-context';
|
import { useSafeAreaFrame } from 'react-native-safe-area-context';
|
||||||
import { useImageDimensions } from '@react-native-community/hooks';
|
import { useImageDimensions } from '@react-native-community/hooks';
|
||||||
import { Meme } from '../../../database';
|
import { Meme } from '../../../database';
|
||||||
import styles from '../../../styles';
|
|
||||||
|
|
||||||
const memesListItemStyles = StyleSheet.create({
|
const memesListItemStyles = StyleSheet.create({
|
||||||
view: {
|
view: {
|
||||||
|
flexDirection: 'row',
|
||||||
paddingVertical: 10,
|
paddingVertical: 10,
|
||||||
},
|
},
|
||||||
image: {
|
image: {
|
||||||
@@ -16,12 +16,17 @@ const memesListItemStyles = StyleSheet.create({
|
|||||||
borderRadius: 5,
|
borderRadius: 5,
|
||||||
},
|
},
|
||||||
detailsView: {
|
detailsView: {
|
||||||
|
flexDirection: 'column',
|
||||||
marginLeft: 10,
|
marginLeft: 10,
|
||||||
},
|
},
|
||||||
text: {
|
text: {
|
||||||
marginRight: 5,
|
marginRight: 5,
|
||||||
marginBottom: 5,
|
marginBottom: 5,
|
||||||
},
|
},
|
||||||
|
tagsView: {
|
||||||
|
flexDirection: 'row',
|
||||||
|
flexWrap: 'wrap',
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const MemesListItem = ({
|
const MemesListItem = ({
|
||||||
@@ -42,13 +47,12 @@ const MemesListItem = ({
|
|||||||
return (
|
return (
|
||||||
<TouchableRipple
|
<TouchableRipple
|
||||||
onPress={() => focusMeme(index)}
|
onPress={() => focusMeme(index)}
|
||||||
style={[memesListItemStyles.view, styles.flexRow]}>
|
style={memesListItemStyles.view}>
|
||||||
<>
|
<>
|
||||||
<Image source={{ uri: meme.uri }} style={memesListItemStyles.image} />
|
<Image source={{ uri: meme.uri }} style={memesListItemStyles.image} />
|
||||||
<View
|
<View
|
||||||
style={[
|
style={[
|
||||||
memesListItemStyles.detailsView,
|
memesListItemStyles.detailsView,
|
||||||
styles.flexColumn,
|
|
||||||
{
|
{
|
||||||
width: width * 0.92 - 75 - 10,
|
width: width * 0.92 - 75 - 10,
|
||||||
},
|
},
|
||||||
@@ -56,13 +60,11 @@ const MemesListItem = ({
|
|||||||
<Text variant="titleMedium" style={memesListItemStyles.text}>
|
<Text variant="titleMedium" style={memesListItemStyles.text}>
|
||||||
{meme.title}
|
{meme.title}
|
||||||
</Text>
|
</Text>
|
||||||
<View style={styles.flexRow}>
|
<Text variant="labelSmall" style={memesListItemStyles.text}>
|
||||||
<Text variant="labelSmall" style={memesListItemStyles.text}>
|
{meme.dateModified.toLocaleDateString()} • {meme.size / 1000}
|
||||||
{meme.dateModified.toLocaleDateString()} • {meme.size / 1000}
|
KB
|
||||||
KB
|
</Text>
|
||||||
</Text>
|
<View style={memesListItemStyles.tagsView}>
|
||||||
</View>
|
|
||||||
<View style={[styles.flexRow, styles.flexWrap]}>
|
|
||||||
{meme.tags.map(tag => (
|
{meme.tags.map(tag => (
|
||||||
<Text
|
<Text
|
||||||
variant="labelMedium"
|
variant="labelMedium"
|
||||||
|
@@ -2,11 +2,12 @@ import React, { useMemo } from 'react';
|
|||||||
import { StyleSheet, View } from 'react-native';
|
import { StyleSheet, View } from 'react-native';
|
||||||
import FontAwesome5 from 'react-native-vector-icons/FontAwesome5';
|
import FontAwesome5 from 'react-native-vector-icons/FontAwesome5';
|
||||||
import { Chip, useTheme } from 'react-native-paper';
|
import { Chip, useTheme } from 'react-native-paper';
|
||||||
import styles from '../../styles';
|
|
||||||
import { getContrastColor } from '../../utilities';
|
import { getContrastColor } from '../../utilities';
|
||||||
|
|
||||||
const tagPreviewStyles = StyleSheet.create({
|
const tagPreviewStyles = StyleSheet.create({
|
||||||
view: {
|
view: {
|
||||||
|
flexDirection: 'row',
|
||||||
|
justifyContent: 'center',
|
||||||
margin: '10%',
|
margin: '10%',
|
||||||
},
|
},
|
||||||
chip: {
|
chip: {
|
||||||
@@ -33,7 +34,7 @@ const TagPreview = ({ name, color }: { name: string; color: string }) => {
|
|||||||
const contrastColor = getContrastColor(color);
|
const contrastColor = getContrastColor(color);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={[styles.justifyCenter, styles.flexRow, tagPreviewStyles.view]}>
|
<View style={tagPreviewStyles.view}>
|
||||||
<Chip
|
<Chip
|
||||||
icon={() => {
|
icon={() => {
|
||||||
return <FontAwesome5 name="tag" size={14} color={contrastColor} />;
|
return <FontAwesome5 name="tag" size={14} color={contrastColor} />;
|
||||||
|
@@ -1,7 +1,6 @@
|
|||||||
import React, { ComponentProps, useState } from 'react';
|
import React, { ComponentProps, useState } from 'react';
|
||||||
import { StyleSheet, View } from 'react-native';
|
import { StyleSheet, View } from 'react-native';
|
||||||
import { Button, Divider, Menu, Searchbar } from 'react-native-paper';
|
import { Button, Divider, Menu, Searchbar } from 'react-native-paper';
|
||||||
import styles from '../../styles';
|
|
||||||
import { useDispatch, useSelector } from 'react-redux';
|
import { useDispatch, useSelector } from 'react-redux';
|
||||||
import {
|
import {
|
||||||
RootState,
|
RootState,
|
||||||
@@ -14,8 +13,13 @@ import { getSortIcon } from '../../utilities';
|
|||||||
|
|
||||||
const tagsHeaderStyles = StyleSheet.create({
|
const tagsHeaderStyles = StyleSheet.create({
|
||||||
buttonView: {
|
buttonView: {
|
||||||
|
alignItems: 'center',
|
||||||
|
flexDirection: 'row',
|
||||||
height: 50,
|
height: 50,
|
||||||
},
|
},
|
||||||
|
sortButton: {
|
||||||
|
flexDirection: 'row-reverse',
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const TagsHeader = ({
|
const TagsHeader = ({
|
||||||
@@ -57,12 +61,7 @@ const TagsHeader = ({
|
|||||||
setSearch(value);
|
setSearch(value);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<View
|
<View style={tagsHeaderStyles.buttonView}>
|
||||||
style={[
|
|
||||||
styles.flexRow,
|
|
||||||
styles.alignCenter,
|
|
||||||
tagsHeaderStyles.buttonView,
|
|
||||||
]}>
|
|
||||||
<Menu
|
<Menu
|
||||||
visible={sortMenuVisible}
|
visible={sortMenuVisible}
|
||||||
onDismiss={() => setSortMenuVisible(false)}
|
onDismiss={() => setSortMenuVisible(false)}
|
||||||
@@ -70,7 +69,7 @@ const TagsHeader = ({
|
|||||||
<Button
|
<Button
|
||||||
onPress={() => setSortMenuVisible(true)}
|
onPress={() => setSortMenuVisible(true)}
|
||||||
icon={getSortIcon(sort, sortDirection)}
|
icon={getSortIcon(sort, sortDirection)}
|
||||||
contentStyle={styles.flexRowReverse}
|
contentStyle={tagsHeaderStyles.sortButton}
|
||||||
compact>
|
compact>
|
||||||
Sort By: {sort}
|
Sort By: {sort}
|
||||||
</Button>
|
</Button>
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
import React, { useCallback, useRef, useState } from 'react';
|
import React, { useCallback, useRef, useState } from 'react';
|
||||||
import { Appbar, Button, useTheme } from 'react-native-paper';
|
import { Appbar, Button, useTheme } from 'react-native-paper';
|
||||||
import { useNavigation } from '@react-navigation/native';
|
import { useNavigation } from '@react-navigation/native';
|
||||||
import { ScrollView, StyleSheet, View } from 'react-native';
|
import { ScrollView, View } from 'react-native';
|
||||||
import { NativeStackScreenProps } from '@react-navigation/native-stack';
|
import { NativeStackScreenProps } from '@react-navigation/native-stack';
|
||||||
import { useRealm } from '@realm/react';
|
import { useRealm } from '@realm/react';
|
||||||
import { BSON } from 'realm';
|
import { BSON } from 'realm';
|
||||||
@@ -13,23 +13,16 @@ import {
|
|||||||
DocumentPickerResponse,
|
DocumentPickerResponse,
|
||||||
pickSingle,
|
pickSingle,
|
||||||
} from 'react-native-document-picker';
|
} from 'react-native-document-picker';
|
||||||
import styles from '../styles';
|
import { ROUTE, RootStackParamList } from '../../types';
|
||||||
import { ROUTE, RootStackParamList } from '../types';
|
import { Meme, Tag } from '../../database';
|
||||||
import { Meme, Tag } from '../database';
|
import { RootState } from '../../state';
|
||||||
import { RootState } from '../state';
|
import {
|
||||||
import { allowedMimeTypes, getMemeType, validateMemeTitle } from '../utilities';
|
allowedMimeTypes,
|
||||||
import { MemeEditor } from '../components';
|
getMemeType,
|
||||||
|
validateMemeTitle,
|
||||||
const addMemeStyles = StyleSheet.create({
|
} from '../../utilities';
|
||||||
saveAndAddButton: {
|
import { MemeEditor } from '../../components';
|
||||||
flex: 1,
|
import editorStyles from './editorStyles';
|
||||||
marginRight: 5,
|
|
||||||
},
|
|
||||||
saveButton: {
|
|
||||||
flex: 1,
|
|
||||||
marginLeft: 5,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const AddMeme = ({
|
const AddMeme = ({
|
||||||
route,
|
route,
|
||||||
@@ -104,15 +97,13 @@ const AddMeme = ({
|
|||||||
</Appbar.Header>
|
</Appbar.Header>
|
||||||
<ScrollView
|
<ScrollView
|
||||||
contentContainerStyle={[
|
contentContainerStyle={[
|
||||||
|
editorStyles.scrollView,
|
||||||
orientation === 'portrait'
|
orientation === 'portrait'
|
||||||
? styles.paddingVertical
|
? editorStyles.scrollViewPortrait
|
||||||
: styles.smallPaddingVertical,
|
: editorStyles.scrollViewLandscape,
|
||||||
styles.paddingHorizontal,
|
|
||||||
styles.flexGrow,
|
|
||||||
styles.flexColumnSpaceBetween,
|
|
||||||
{ backgroundColor: colors.background },
|
{ backgroundColor: colors.background },
|
||||||
]}>
|
]}>
|
||||||
<View style={[styles.flex, styles.justifyStart]}>
|
<View style={editorStyles.editorView}>
|
||||||
<MemeEditor
|
<MemeEditor
|
||||||
memeUri={memeUri}
|
memeUri={memeUri}
|
||||||
memeTitle={memeTitle}
|
memeTitle={memeTitle}
|
||||||
@@ -121,7 +112,7 @@ const AddMeme = ({
|
|||||||
setMemeTags={setMemeTags}
|
setMemeTags={setMemeTags}
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
<View style={[styles.flexRow, styles.fullWidth]}>
|
<View style={editorStyles.saveButtonView}>
|
||||||
<Button
|
<Button
|
||||||
mode="contained-tonal"
|
mode="contained-tonal"
|
||||||
icon="plus"
|
icon="plus"
|
||||||
@@ -139,7 +130,7 @@ const AddMeme = ({
|
|||||||
}}
|
}}
|
||||||
disabled={!memeTitle.valid || isSaving || isSavingAndAddingAnother}
|
disabled={!memeTitle.valid || isSaving || isSavingAndAddingAnother}
|
||||||
loading={isSavingAndAddingAnother}
|
loading={isSavingAndAddingAnother}
|
||||||
style={addMemeStyles.saveAndAddButton}>
|
style={editorStyles.saveAndAddButton}>
|
||||||
Save & Add
|
Save & Add
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
@@ -153,7 +144,7 @@ const AddMeme = ({
|
|||||||
}}
|
}}
|
||||||
disabled={!memeTitle.valid || isSaving || isSavingAndAddingAnother}
|
disabled={!memeTitle.valid || isSaving || isSavingAndAddingAnother}
|
||||||
loading={isSaving}
|
loading={isSaving}
|
||||||
style={addMemeStyles.saveButton}>
|
style={editorStyles.saveButton}>
|
||||||
Save
|
Save
|
||||||
</Button>
|
</Button>
|
||||||
</View>
|
</View>
|
@@ -1,28 +1,17 @@
|
|||||||
import React, { useCallback, useState } from 'react';
|
import React, { useCallback, useState } from 'react';
|
||||||
import { ScrollView, StyleSheet, View } from 'react-native';
|
import { ScrollView, View } from 'react-native';
|
||||||
import { Appbar, Button, useTheme } from 'react-native-paper';
|
import { Appbar, Button, useTheme } from 'react-native-paper';
|
||||||
import { useNavigation } from '@react-navigation/native';
|
import { useNavigation } from '@react-navigation/native';
|
||||||
import { useRealm } from '@realm/react';
|
import { useRealm } from '@realm/react';
|
||||||
import { useDeviceOrientation } from '@react-native-community/hooks';
|
import { useDeviceOrientation } from '@react-native-community/hooks';
|
||||||
import styles from '../styles';
|
|
||||||
import {
|
import {
|
||||||
generateRandomColor,
|
generateRandomColor,
|
||||||
validateColor,
|
validateColor,
|
||||||
validateTagName,
|
validateTagName,
|
||||||
} from '../utilities';
|
} from '../../utilities';
|
||||||
import { Tag } from '../database';
|
import { Tag } from '../../database';
|
||||||
import { TagEditor } from '../components';
|
import { TagEditor } from '../../components';
|
||||||
|
import editorStyles from './editorStyles';
|
||||||
const addTagStyles = StyleSheet.create({
|
|
||||||
saveAndAddButton: {
|
|
||||||
flex: 1,
|
|
||||||
marginRight: 5,
|
|
||||||
},
|
|
||||||
saveButton: {
|
|
||||||
flex: 1,
|
|
||||||
marginLeft: 5,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const AddTag = () => {
|
const AddTag = () => {
|
||||||
const { goBack } = useNavigation();
|
const { goBack } = useNavigation();
|
||||||
@@ -57,15 +46,13 @@ const AddTag = () => {
|
|||||||
</Appbar.Header>
|
</Appbar.Header>
|
||||||
<ScrollView
|
<ScrollView
|
||||||
contentContainerStyle={[
|
contentContainerStyle={[
|
||||||
|
editorStyles.scrollView,
|
||||||
orientation === 'portrait'
|
orientation === 'portrait'
|
||||||
? styles.paddingVertical
|
? editorStyles.scrollViewPortrait
|
||||||
: styles.smallPaddingVertical,
|
: editorStyles.scrollViewLandscape,
|
||||||
styles.paddingHorizontal,
|
|
||||||
styles.flexGrow,
|
|
||||||
styles.flexColumnSpaceBetween,
|
|
||||||
{ backgroundColor: colors.background },
|
{ backgroundColor: colors.background },
|
||||||
]}>
|
]}>
|
||||||
<View style={[styles.flex, styles.justifyStart]}>
|
<View style={editorStyles.editorView}>
|
||||||
<TagEditor
|
<TagEditor
|
||||||
tagName={tagName}
|
tagName={tagName}
|
||||||
setTagName={setTagName}
|
setTagName={setTagName}
|
||||||
@@ -73,7 +60,7 @@ const AddTag = () => {
|
|||||||
setTagColor={setTagColor}
|
setTagColor={setTagColor}
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
<View style={[styles.flexRow, styles.fullWidth]}>
|
<View style={editorStyles.saveButtonView}>
|
||||||
<Button
|
<Button
|
||||||
mode="contained-tonal"
|
mode="contained-tonal"
|
||||||
icon="plus"
|
icon="plus"
|
||||||
@@ -86,7 +73,7 @@ const AddTag = () => {
|
|||||||
}}
|
}}
|
||||||
disabled={!tagName.valid || isSavingAndAddingAnother}
|
disabled={!tagName.valid || isSavingAndAddingAnother}
|
||||||
loading={isSavingAndAddingAnother}
|
loading={isSavingAndAddingAnother}
|
||||||
style={addTagStyles.saveAndAddButton}>
|
style={editorStyles.saveAndAddButton}>
|
||||||
Save & Add
|
Save & Add
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
@@ -97,7 +84,7 @@ const AddTag = () => {
|
|||||||
goBack();
|
goBack();
|
||||||
}}
|
}}
|
||||||
disabled={!tagName.valid || isSavingAndAddingAnother}
|
disabled={!tagName.valid || isSavingAndAddingAnother}
|
||||||
style={addTagStyles.saveButton}>
|
style={editorStyles.saveButton}>
|
||||||
Save
|
Save
|
||||||
</Button>
|
</Button>
|
||||||
</View>
|
</View>
|
@@ -6,11 +6,11 @@ import { NativeStackScreenProps } from '@react-navigation/native-stack';
|
|||||||
import { useObject, useRealm } from '@realm/react';
|
import { useObject, useRealm } from '@realm/react';
|
||||||
import { useDeviceOrientation } from '@react-native-community/hooks';
|
import { useDeviceOrientation } from '@react-native-community/hooks';
|
||||||
import { BSON } from 'realm';
|
import { BSON } from 'realm';
|
||||||
import styles from '../styles';
|
import { RootStackParamList, ROUTE } from '../../types';
|
||||||
import { RootStackParamList, ROUTE } from '../types';
|
import { Tag, Meme } from '../../database';
|
||||||
import { Tag, Meme } from '../database';
|
import { deleteMeme, favoriteMeme, validateMemeTitle } from '../../utilities';
|
||||||
import { deleteMeme, favoriteMeme, validateMemeTitle } from '../utilities';
|
import { MemeEditor } from '../../components';
|
||||||
import { MemeEditor } from '../components';
|
import editorStyles from './editorStyles';
|
||||||
|
|
||||||
const EditMeme = ({
|
const EditMeme = ({
|
||||||
route,
|
route,
|
||||||
@@ -80,15 +80,13 @@ const EditMeme = ({
|
|||||||
</Appbar.Header>
|
</Appbar.Header>
|
||||||
<ScrollView
|
<ScrollView
|
||||||
contentContainerStyle={[
|
contentContainerStyle={[
|
||||||
|
editorStyles.scrollView,
|
||||||
orientation === 'portrait'
|
orientation === 'portrait'
|
||||||
? styles.paddingVertical
|
? editorStyles.scrollViewPortrait
|
||||||
: styles.smallPaddingVertical,
|
: editorStyles.scrollViewLandscape,
|
||||||
styles.paddingHorizontal,
|
|
||||||
styles.flexGrow,
|
|
||||||
styles.flexColumnSpaceBetween,
|
|
||||||
{ backgroundColor: colors.background },
|
{ backgroundColor: colors.background },
|
||||||
]}>
|
]}>
|
||||||
<View style={[styles.flex, styles.justifyStart]}>
|
<View style={editorStyles.editorView}>
|
||||||
<MemeEditor
|
<MemeEditor
|
||||||
memeUri={meme.uri}
|
memeUri={meme.uri}
|
||||||
memeTitle={memeTitle}
|
memeTitle={memeTitle}
|
||||||
@@ -97,7 +95,7 @@ const EditMeme = ({
|
|||||||
setMemeTags={setMemeTags}
|
setMemeTags={setMemeTags}
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
<View style={[styles.flex, styles.justifyEnd]}>
|
<View style={editorStyles.saveButtonView}>
|
||||||
<Button
|
<Button
|
||||||
mode="contained"
|
mode="contained"
|
||||||
icon="floppy"
|
icon="floppy"
|
@@ -6,11 +6,11 @@ import { NativeStackScreenProps } from '@react-navigation/native-stack';
|
|||||||
import { BSON } from 'realm';
|
import { BSON } from 'realm';
|
||||||
import { useObject, useRealm } from '@realm/react';
|
import { useObject, useRealm } from '@realm/react';
|
||||||
import { useDeviceOrientation } from '@react-native-community/hooks';
|
import { useDeviceOrientation } from '@react-native-community/hooks';
|
||||||
import { TagEditor } from '../components';
|
import { TagEditor } from '../../components';
|
||||||
import styles from '../styles';
|
import { ROUTE, RootStackParamList } from '../../types';
|
||||||
import { ROUTE, RootStackParamList } from '../types';
|
import { Tag } from '../../database';
|
||||||
import { Tag } from '../database';
|
import { deleteTag, validateColor, validateTagName } from '../../utilities';
|
||||||
import { deleteTag, validateColor, validateTagName } from '../utilities';
|
import editorStyles from './editorStyles';
|
||||||
|
|
||||||
const EditTag = ({
|
const EditTag = ({
|
||||||
route,
|
route,
|
||||||
@@ -52,16 +52,14 @@ const EditTag = ({
|
|||||||
</Appbar.Header>
|
</Appbar.Header>
|
||||||
<ScrollView
|
<ScrollView
|
||||||
contentContainerStyle={[
|
contentContainerStyle={[
|
||||||
|
editorStyles.scrollView,
|
||||||
orientation === 'portrait'
|
orientation === 'portrait'
|
||||||
? styles.paddingVertical
|
? editorStyles.scrollViewPortrait
|
||||||
: styles.smallPaddingVertical,
|
: editorStyles.scrollViewLandscape,
|
||||||
styles.paddingHorizontal,
|
|
||||||
styles.flexGrow,
|
|
||||||
styles.flexColumnSpaceBetween,
|
|
||||||
{ backgroundColor: colors.background },
|
{ backgroundColor: colors.background },
|
||||||
]}
|
]}
|
||||||
nestedScrollEnabled>
|
nestedScrollEnabled>
|
||||||
<View style={[styles.flex, styles.justifyStart]}>
|
<View style={editorStyles.editorView}>
|
||||||
<TagEditor
|
<TagEditor
|
||||||
tagName={tagName}
|
tagName={tagName}
|
||||||
setTagName={setTagName}
|
setTagName={setTagName}
|
||||||
@@ -69,7 +67,7 @@ const EditTag = ({
|
|||||||
setTagColor={setTagColor}
|
setTagColor={setTagColor}
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
<View style={[styles.flex, styles.justifyEnd]}>
|
<View style={editorStyles.saveButtonView}>
|
||||||
<Button
|
<Button
|
||||||
mode="contained"
|
mode="contained"
|
||||||
icon="floppy"
|
icon="floppy"
|
34
src/screens/editors/editorStyles.ts
Normal file
34
src/screens/editors/editorStyles.ts
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
import { StyleSheet } from 'react-native';
|
||||||
|
|
||||||
|
const editorStyles = StyleSheet.create({
|
||||||
|
scrollView: {
|
||||||
|
flexGrow: 1,
|
||||||
|
flexDirection: 'column',
|
||||||
|
justifyContent: 'space-between',
|
||||||
|
paddingHorizontal: '4%',
|
||||||
|
},
|
||||||
|
scrollViewPortrait: {
|
||||||
|
paddingVertical: '4%',
|
||||||
|
},
|
||||||
|
scrollViewLandscape: {
|
||||||
|
paddingVertical: '2%',
|
||||||
|
},
|
||||||
|
editorView: {
|
||||||
|
flex: 1,
|
||||||
|
justifyContent: 'flex-start',
|
||||||
|
},
|
||||||
|
saveButtonView: {
|
||||||
|
flexDirection: 'row',
|
||||||
|
width: '100%',
|
||||||
|
},
|
||||||
|
saveAndAddButton: {
|
||||||
|
flex: 1,
|
||||||
|
marginRight: 5,
|
||||||
|
},
|
||||||
|
saveButton: {
|
||||||
|
flex: 1,
|
||||||
|
marginLeft: 5,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default editorStyles;
|
@@ -1,7 +1,7 @@
|
|||||||
export { default as AddMeme } from './addMeme';
|
export { default as AddMeme } from './editors/addMeme';
|
||||||
export { default as AddTag } from './addTag';
|
export { default as AddTag } from './editors/addTag';
|
||||||
export { default as EditMeme } from './editMeme';
|
export { default as EditMeme } from './editors/editMeme';
|
||||||
export { default as EditTag } from './editTag';
|
export { default as EditTag } from './editors/editTag';
|
||||||
export { default as Memes } from './memes';
|
export { default as Memes } from './memes';
|
||||||
export { default as MemeView } from './memeView';
|
export { default as MemeView } from './memeView';
|
||||||
export { default as Settings } from './settings';
|
export { default as Settings } from './settings';
|
||||||
|
@@ -17,7 +17,6 @@ import {
|
|||||||
shareMeme,
|
shareMeme,
|
||||||
} from '../utilities';
|
} from '../utilities';
|
||||||
import { NavigationProp, useNavigation } from '@react-navigation/native';
|
import { NavigationProp, useNavigation } from '@react-navigation/native';
|
||||||
import styles from '../styles';
|
|
||||||
|
|
||||||
const memeViewStyles = StyleSheet.create({
|
const memeViewStyles = StyleSheet.create({
|
||||||
// eslint-disable-next-line react-native/no-color-literals
|
// eslint-disable-next-line react-native/no-color-literals
|
||||||
@@ -36,6 +35,8 @@ const memeViewStyles = StyleSheet.create({
|
|||||||
left: 0,
|
left: 0,
|
||||||
right: 0,
|
right: 0,
|
||||||
backgroundColor: 'transparent',
|
backgroundColor: 'transparent',
|
||||||
|
flexDirection: 'row',
|
||||||
|
justifyContent: 'space-evenly',
|
||||||
},
|
},
|
||||||
snackbar: {
|
snackbar: {
|
||||||
marginBottom: 64,
|
marginBottom: 64,
|
||||||
@@ -88,7 +89,7 @@ const MemeView = ({
|
|||||||
showsHorizontalScrollIndicator={false}
|
showsHorizontalScrollIndicator={false}
|
||||||
renderItem={({ item: meme }) => <MemeViewItem meme={meme} />}
|
renderItem={({ item: meme }) => <MemeViewItem meme={meme} />}
|
||||||
/>
|
/>
|
||||||
<Appbar style={[styles.flexRowSpaceEvenly, memeViewStyles.footer]}>
|
<Appbar style={memeViewStyles.footer}>
|
||||||
<Appbar.Action
|
<Appbar.Action
|
||||||
icon={memes[index].isFavorite ? 'heart' : 'heart-outline'}
|
icon={memes[index].isFavorite ? 'heart' : 'heart-outline'}
|
||||||
onPress={() => favoriteMeme(realm, memes[index])}
|
onPress={() => favoriteMeme(realm, memes[index])}
|
||||||
|
@@ -3,6 +3,7 @@ import {
|
|||||||
BackHandler,
|
BackHandler,
|
||||||
NativeScrollEvent,
|
NativeScrollEvent,
|
||||||
NativeSyntheticEvent,
|
NativeSyntheticEvent,
|
||||||
|
StyleSheet,
|
||||||
View,
|
View,
|
||||||
useWindowDimensions,
|
useWindowDimensions,
|
||||||
} from 'react-native';
|
} from 'react-native';
|
||||||
@@ -16,13 +17,20 @@ import {
|
|||||||
useNavigation,
|
useNavigation,
|
||||||
} from '@react-navigation/native';
|
} from '@react-navigation/native';
|
||||||
import { NativeStackNavigationProp } from '@react-navigation/native-stack';
|
import { NativeStackNavigationProp } from '@react-navigation/native-stack';
|
||||||
import styles from '../styles';
|
|
||||||
import { ROUTE, SORT_DIRECTION, memesSortQuery } from '../types';
|
import { ROUTE, SORT_DIRECTION, memesSortQuery } from '../types';
|
||||||
import { RootState, setNavVisible } from '../state';
|
import { RootState, setNavVisible } from '../state';
|
||||||
import { Meme } from '../database';
|
import { Meme } from '../database';
|
||||||
import { HideableHeader, MemesHeader, MemesList } from '../components';
|
import { HideableHeader, MemesHeader, MemesList } from '../components';
|
||||||
import { useDeviceOrientation } from '@react-native-community/hooks';
|
import { useDeviceOrientation } from '@react-native-community/hooks';
|
||||||
|
|
||||||
|
const memesStyles = StyleSheet.create({
|
||||||
|
listView: {
|
||||||
|
paddingHorizontal: '4%',
|
||||||
|
width: '100%',
|
||||||
|
height: '100%',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const Memes = () => {
|
const Memes = () => {
|
||||||
const { colors } = useTheme();
|
const { colors } = useTheme();
|
||||||
const { navigate } =
|
const { navigate } =
|
||||||
@@ -128,12 +136,7 @@ const Memes = () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View
|
<>
|
||||||
style={[
|
|
||||||
styles.paddingHorizontal,
|
|
||||||
styles.fullSize,
|
|
||||||
{ backgroundColor: colors.background },
|
|
||||||
]}>
|
|
||||||
<HideableHeader visible={navVisisble}>
|
<HideableHeader visible={navVisisble}>
|
||||||
<MemesHeader
|
<MemesHeader
|
||||||
search={search}
|
search={search}
|
||||||
@@ -146,19 +149,22 @@ const Memes = () => {
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</HideableHeader>
|
</HideableHeader>
|
||||||
<MemesList
|
<View
|
||||||
memes={memes}
|
style={[memesStyles.listView, { backgroundColor: colors.background }]}>
|
||||||
flashListRef={flashListRef}
|
<MemesList
|
||||||
flashListPadding={flashListPadding}
|
memes={memes}
|
||||||
handleScroll={handleScroll}
|
flashListRef={flashListRef}
|
||||||
focusMeme={(index: number) => {
|
flashListPadding={flashListPadding}
|
||||||
navigate(ROUTE.MEME_VIEW, {
|
handleScroll={handleScroll}
|
||||||
ids: memes.map(meme => meme.id.toHexString()),
|
focusMeme={(index: number) => {
|
||||||
index,
|
navigate(ROUTE.MEME_VIEW, {
|
||||||
});
|
ids: memes.map(meme => meme.id.toHexString()),
|
||||||
}}
|
index,
|
||||||
/>
|
});
|
||||||
</View>
|
}}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -13,8 +13,6 @@ import {
|
|||||||
import { openDocumentTree } from 'react-native-scoped-storage';
|
import { openDocumentTree } from 'react-native-scoped-storage';
|
||||||
import { useDispatch, useSelector } from 'react-redux';
|
import { useDispatch, useSelector } from 'react-redux';
|
||||||
import type {} from 'redux-thunk/extend-redux';
|
import type {} from 'redux-thunk/extend-redux';
|
||||||
import { useDeviceOrientation } from '@react-native-community/hooks';
|
|
||||||
import styles from '../styles';
|
|
||||||
import {
|
import {
|
||||||
RootState,
|
RootState,
|
||||||
setGridColumns,
|
setGridColumns,
|
||||||
@@ -24,17 +22,28 @@ import {
|
|||||||
} from '../state';
|
} from '../state';
|
||||||
|
|
||||||
const settingsStyles = StyleSheet.create({
|
const settingsStyles = StyleSheet.create({
|
||||||
|
scrollView: {
|
||||||
|
paddingHorizontal: '4%',
|
||||||
|
},
|
||||||
snackbar: {
|
snackbar: {
|
||||||
marginBottom: 90,
|
marginBottom: 90,
|
||||||
},
|
},
|
||||||
marginBottom: {
|
marginBottom: {
|
||||||
marginBottom: 15,
|
marginBottom: 15,
|
||||||
},
|
},
|
||||||
|
columnSegmentedButtons: {
|
||||||
|
marginBottom: 15,
|
||||||
|
paddingHorizontal: '2%',
|
||||||
|
},
|
||||||
|
hideMediaSwitch: {
|
||||||
|
flexDirection: 'row',
|
||||||
|
justifyContent: 'space-between',
|
||||||
|
paddingHorizontal: '2%',
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const Settings = () => {
|
const Settings = () => {
|
||||||
const { colors } = useTheme();
|
const { colors } = useTheme();
|
||||||
const orientation = useDeviceOrientation();
|
|
||||||
const noMedia = useSelector((state: RootState) => state.settings.noMedia);
|
const noMedia = useSelector((state: RootState) => state.settings.noMedia);
|
||||||
const masonryColumns = useSelector(
|
const masonryColumns = useSelector(
|
||||||
(state: RootState) => state.settings.masonryColumns,
|
(state: RootState) => state.settings.masonryColumns,
|
||||||
@@ -60,19 +69,12 @@ const Settings = () => {
|
|||||||
<>
|
<>
|
||||||
<ScrollView
|
<ScrollView
|
||||||
contentContainerStyle={[
|
contentContainerStyle={[
|
||||||
orientation === 'portrait'
|
settingsStyles.scrollView,
|
||||||
? styles.paddingTop
|
|
||||||
: styles.smallPaddingTop,
|
|
||||||
styles.paddingHorizontal,
|
|
||||||
{ backgroundColor: colors.background },
|
{ backgroundColor: colors.background },
|
||||||
]}>
|
]}>
|
||||||
<List.Section>
|
<List.Section>
|
||||||
<List.Subheader>Views</List.Subheader>
|
<List.Subheader>Views</List.Subheader>
|
||||||
<Text
|
<Text style={settingsStyles.columnSegmentedButtons}>
|
||||||
style={[
|
|
||||||
settingsStyles.marginBottom,
|
|
||||||
styles.smallPaddingHorizontal,
|
|
||||||
]}>
|
|
||||||
Masonry Columns
|
Masonry Columns
|
||||||
</Text>
|
</Text>
|
||||||
<SegmentedButtons
|
<SegmentedButtons
|
||||||
@@ -90,11 +92,7 @@ const Settings = () => {
|
|||||||
]}
|
]}
|
||||||
style={settingsStyles.marginBottom}
|
style={settingsStyles.marginBottom}
|
||||||
/>
|
/>
|
||||||
<Text
|
<Text style={settingsStyles.columnSegmentedButtons}>
|
||||||
style={[
|
|
||||||
settingsStyles.marginBottom,
|
|
||||||
styles.smallPaddingHorizontal,
|
|
||||||
]}>
|
|
||||||
Grid Columns
|
Grid Columns
|
||||||
</Text>
|
</Text>
|
||||||
<SegmentedButtons
|
<SegmentedButtons
|
||||||
@@ -123,8 +121,7 @@ const Settings = () => {
|
|||||||
}}>
|
}}>
|
||||||
Change External Storage Path
|
Change External Storage Path
|
||||||
</Button>
|
</Button>
|
||||||
<View
|
<View style={settingsStyles.hideMediaSwitch}>
|
||||||
style={[styles.flexRowSpaceBetween, styles.smallPaddingHorizontal]}>
|
|
||||||
<Text>Hide media from gallery</Text>
|
<Text>Hide media from gallery</Text>
|
||||||
<Switch
|
<Switch
|
||||||
value={noMedia}
|
value={noMedia}
|
||||||
|
@@ -15,16 +15,21 @@ import { useDeviceOrientation } from '@react-native-community/hooks';
|
|||||||
import { useSafeAreaFrame } from 'react-native-safe-area-context';
|
import { useSafeAreaFrame } from 'react-native-safe-area-context';
|
||||||
import { HideableHeader, TagRow, TagsHeader } from '../components';
|
import { HideableHeader, TagRow, TagsHeader } from '../components';
|
||||||
import { Tag } from '../database';
|
import { Tag } from '../database';
|
||||||
import styles from '../styles';
|
|
||||||
import { RootState, setNavVisible } from '../state';
|
import { RootState, setNavVisible } from '../state';
|
||||||
import { SORT_DIRECTION, tagSortQuery } from '../types';
|
import { SORT_DIRECTION, tagSortQuery } from '../types';
|
||||||
|
|
||||||
const tagsStyles = StyleSheet.create({
|
const tagsStyles = StyleSheet.create({
|
||||||
|
listView: {
|
||||||
|
paddingHorizontal: '4%',
|
||||||
|
width: '100%',
|
||||||
|
height: '100%',
|
||||||
|
},
|
||||||
flashList: {
|
flashList: {
|
||||||
paddingBottom: 100,
|
paddingBottom: 100,
|
||||||
},
|
},
|
||||||
helperText: {
|
helperText: {
|
||||||
marginVertical: 15,
|
marginVertical: 15,
|
||||||
|
textAlign: 'center',
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -104,12 +109,7 @@ const Tags = () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View
|
<>
|
||||||
style={[
|
|
||||||
styles.paddingHorizontal,
|
|
||||||
styles.fullSize,
|
|
||||||
{ backgroundColor: colors.background },
|
|
||||||
]}>
|
|
||||||
<HideableHeader visible={navVisisble}>
|
<HideableHeader visible={navVisisble}>
|
||||||
<TagsHeader
|
<TagsHeader
|
||||||
search={search}
|
search={search}
|
||||||
@@ -119,34 +119,35 @@ const Tags = () => {
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</HideableHeader>
|
</HideableHeader>
|
||||||
<FlashList
|
<View
|
||||||
ref={flashListRef}
|
style={[tagsStyles.listView, { backgroundColor: colors.background }]}>
|
||||||
data={tags}
|
<FlashList
|
||||||
estimatedItemSize={50}
|
ref={flashListRef}
|
||||||
estimatedListSize={{
|
data={tags}
|
||||||
height,
|
estimatedItemSize={50}
|
||||||
width: width * 0.92,
|
estimatedListSize={{
|
||||||
}}
|
height,
|
||||||
showsVerticalScrollIndicator={false}
|
width: width * 0.92,
|
||||||
renderItem={({ item: tag }) => <TagRow tag={tag} />}
|
}}
|
||||||
contentContainerStyle={{
|
showsVerticalScrollIndicator={false}
|
||||||
paddingTop:
|
renderItem={({ item: tag }) => <TagRow tag={tag} />}
|
||||||
flashListPadding +
|
contentContainerStyle={{
|
||||||
height * (orientation === 'portrait' ? 0.02 : 0.04),
|
paddingTop:
|
||||||
...tagsStyles.flashList,
|
flashListPadding +
|
||||||
}}
|
height * (orientation === 'portrait' ? 0.02 : 0.04),
|
||||||
ItemSeparatorComponent={() => <Divider />}
|
...tagsStyles.flashList,
|
||||||
ListEmptyComponent={() => (
|
}}
|
||||||
<HelperText
|
ItemSeparatorComponent={() => <Divider />}
|
||||||
type={'info'}
|
ListEmptyComponent={() => (
|
||||||
style={[tagsStyles.helperText, styles.centerText]}>
|
<HelperText type={'info'} style={tagsStyles.helperText}>
|
||||||
No tags found
|
No tags found
|
||||||
</HelperText>
|
</HelperText>
|
||||||
)}
|
)}
|
||||||
onScroll={handleScroll}
|
onScroll={handleScroll}
|
||||||
fadingEdgeLength={100}
|
fadingEdgeLength={100}
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -3,14 +3,19 @@ import { StyleSheet, View } from 'react-native';
|
|||||||
import { Button, Text, useTheme } from 'react-native-paper';
|
import { Button, Text, useTheme } from 'react-native-paper';
|
||||||
import { useDispatch } from 'react-redux';
|
import { useDispatch } from 'react-redux';
|
||||||
import { openDocumentTree } from 'react-native-scoped-storage';
|
import { openDocumentTree } from 'react-native-scoped-storage';
|
||||||
import { useDeviceOrientation } from '@react-native-community/hooks';
|
|
||||||
import styles from '../styles';
|
|
||||||
import { noOp } from '../utilities';
|
import { noOp } from '../utilities';
|
||||||
import { setStorageUri } from '../state';
|
import { setStorageUri } from '../state';
|
||||||
|
|
||||||
const welcomeStyles = StyleSheet.create({
|
const welcomeStyles = StyleSheet.create({
|
||||||
|
view: {
|
||||||
|
paddingHorizontal: '4%',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
flex: 1,
|
||||||
|
},
|
||||||
text: {
|
text: {
|
||||||
marginBottom: 30,
|
marginBottom: 30,
|
||||||
|
textAlign: 'center',
|
||||||
},
|
},
|
||||||
button: {
|
button: {
|
||||||
marginBottom: 100,
|
marginBottom: 100,
|
||||||
@@ -19,7 +24,6 @@ const welcomeStyles = StyleSheet.create({
|
|||||||
|
|
||||||
const Welcome = ({ onWelcomeComplete }: { onWelcomeComplete: () => void }) => {
|
const Welcome = ({ onWelcomeComplete }: { onWelcomeComplete: () => void }) => {
|
||||||
const { colors } = useTheme();
|
const { colors } = useTheme();
|
||||||
const orientation = useDeviceOrientation();
|
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
const selectStorageLocation = async () => {
|
const selectStorageLocation = async () => {
|
||||||
@@ -30,18 +34,8 @@ const Welcome = ({ onWelcomeComplete }: { onWelcomeComplete: () => void }) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View
|
<View style={[welcomeStyles.view, { backgroundColor: colors.background }]}>
|
||||||
style={[
|
<Text variant="displayMedium" style={welcomeStyles.text}>
|
||||||
orientation === 'portrait' ? styles.paddingTop : styles.smallPaddingTop,
|
|
||||||
styles.paddingHorizontal,
|
|
||||||
styles.center,
|
|
||||||
styles.flex,
|
|
||||||
styles.fullSize,
|
|
||||||
{ backgroundColor: colors.background },
|
|
||||||
]}>
|
|
||||||
<Text
|
|
||||||
variant="displayMedium"
|
|
||||||
style={[welcomeStyles.text, styles.centerText]}>
|
|
||||||
Welcome to Terminally Online!
|
Welcome to Terminally Online!
|
||||||
</Text>
|
</Text>
|
||||||
<Button
|
<Button
|
||||||
|
@@ -1,95 +0,0 @@
|
|||||||
import { StyleSheet } from 'react-native';
|
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
|
||||||
smallPadding: {
|
|
||||||
padding: '2%',
|
|
||||||
},
|
|
||||||
smallPaddingHorizontal: {
|
|
||||||
paddingHorizontal: '2%',
|
|
||||||
},
|
|
||||||
smallPaddingVertical: {
|
|
||||||
paddingVertical: '2%',
|
|
||||||
},
|
|
||||||
smallPaddingTop: {
|
|
||||||
paddingTop: '2%',
|
|
||||||
},
|
|
||||||
padding: {
|
|
||||||
padding: '4%',
|
|
||||||
},
|
|
||||||
paddingHorizontal: {
|
|
||||||
paddingHorizontal: '4%',
|
|
||||||
},
|
|
||||||
paddingVertical: {
|
|
||||||
paddingVertical: '4%',
|
|
||||||
},
|
|
||||||
paddingTop: {
|
|
||||||
paddingTop: '4%',
|
|
||||||
},
|
|
||||||
center: {
|
|
||||||
justifyContent: 'center',
|
|
||||||
alignItems: 'center',
|
|
||||||
},
|
|
||||||
alignCenter: {
|
|
||||||
alignItems: 'center',
|
|
||||||
},
|
|
||||||
justifyCenter: {
|
|
||||||
justifyContent: 'center',
|
|
||||||
},
|
|
||||||
centerText: {
|
|
||||||
textAlign: 'center',
|
|
||||||
},
|
|
||||||
centerSelf: {
|
|
||||||
alignSelf: 'center',
|
|
||||||
},
|
|
||||||
flex: {
|
|
||||||
flex: 1,
|
|
||||||
},
|
|
||||||
flexGrow: {
|
|
||||||
flexGrow: 1,
|
|
||||||
},
|
|
||||||
flexShrink: {
|
|
||||||
flexShrink: 1,
|
|
||||||
},
|
|
||||||
flexRow: {
|
|
||||||
flexDirection: 'row',
|
|
||||||
},
|
|
||||||
flexRowSpaceBetween: {
|
|
||||||
flexDirection: 'row',
|
|
||||||
justifyContent: 'space-between',
|
|
||||||
},
|
|
||||||
flexRowSpaceEvenly: {
|
|
||||||
flexDirection: 'row',
|
|
||||||
justifyContent: 'space-evenly',
|
|
||||||
},
|
|
||||||
flexColumn: {
|
|
||||||
flexDirection: 'column',
|
|
||||||
},
|
|
||||||
flexColumnSpaceBetween: {
|
|
||||||
flexDirection: 'column',
|
|
||||||
justifyContent: 'space-between',
|
|
||||||
},
|
|
||||||
flexRowReverse: {
|
|
||||||
flexDirection: 'row-reverse',
|
|
||||||
},
|
|
||||||
flexWrap: {
|
|
||||||
flexWrap: 'wrap',
|
|
||||||
},
|
|
||||||
justifyStart: {
|
|
||||||
justifyContent: 'flex-start',
|
|
||||||
},
|
|
||||||
justifyEnd: {
|
|
||||||
justifyContent: 'flex-end',
|
|
||||||
},
|
|
||||||
fullWidth: {
|
|
||||||
width: '100%',
|
|
||||||
},
|
|
||||||
fullHeight: {
|
|
||||||
height: '100%',
|
|
||||||
},
|
|
||||||
fullSize: {
|
|
||||||
width: '100%',
|
|
||||||
height: '100%',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
export default styles;
|
|
Reference in New Issue
Block a user