Refactor dimension handling

Signed-off-by: Nikolaos Karaolidis <nick@karaolidis.com>
This commit is contained in:
2023-07-13 19:03:53 +03:00
parent 703155232d
commit 4128b0df20
17 changed files with 406 additions and 250 deletions

View File

@@ -1,24 +1,22 @@
import * as React from 'react';
import React, { useEffect, useState } from 'react';
import { StyleSheet, Keyboard } from 'react-native';
import { FAB, Portal } from 'react-native-paper';
import { horizontalScale, verticalScale } from '../styles';
import { FAB } from 'react-native-paper';
import { ParamListBase, useNavigation } from '@react-navigation/native';
import { NativeStackNavigationProp } from '@react-navigation/native-stack';
import { useEffect, useState } from 'react';
import { useDimensions } from '../contexts';
const styles = StyleSheet.create({
fab: {
position: 'absolute',
right: horizontalScale(10),
bottom: verticalScale(75),
},
});
const FloatingActionButton = ({ visible = true }: { visible?: boolean }) => {
const [state, setState] = useState(false);
const { navigate } =
useNavigation<NativeStackNavigationProp<ParamListBase>>();
const dimensions = useDimensions();
const [state, setState] = useState(false);
const [keyboardOpen, setKeyboardOpen] = useState(false);
useEffect(() => {
const keyboardDidShowListener = Keyboard.addListener(
@@ -37,35 +35,39 @@ const FloatingActionButton = ({ visible = true }: { visible?: boolean }) => {
}, []);
return (
<Portal>
<FAB.Group
open={state}
visible={visible && !keyboardOpen}
icon={state ? 'image' : 'plus'}
actions={[
{
icon: 'tag',
label: 'Tag',
onPress: () => navigate('Add Tag'),
},
{
icon: 'note-text',
label: 'Text',
onPress: () => navigate('Add Meme'),
},
{
icon: 'image-album',
label: 'Album',
onPress: () => navigate('Add Meme'),
},
]}
onStateChange={({ open }) => setState(open)}
onPress={() => {
if (state) navigate('Add Meme');
}}
style={styles.fab}
/>
</Portal>
<FAB.Group
open={state}
visible={visible && !keyboardOpen}
icon={state ? 'image' : 'plus'}
actions={[
{
icon: 'tag',
label: 'Tag',
onPress: () => navigate('Add Tag'),
},
{
icon: 'note-text',
label: 'Text',
onPress: () => navigate('Add Meme'),
},
{
icon: 'image-album',
label: 'Album',
onPress: () => navigate('Add Meme'),
},
]}
onStateChange={({ open }) => setState(open)}
onPress={() => {
if (state) navigate('Add Meme');
}}
style={[
styles.fab,
{
paddingRight: dimensions.responsive.horizontalScale(10),
paddingBottom: dimensions.responsive.verticalScale(75),
},
]}
/>
);
};

View File

@@ -1,3 +1,5 @@
export { default as FloatingActionButton } from './floatingActionButton';
export { default as LoadingView } from './loadingView';
export { default as PaddedView } from './paddedView';
export { default as RootScrollView } from './rootScrollView';
export { default as RootView } from './rootView';
export { default as TagPreview } from './tagPreview';

View File

@@ -1,15 +1,15 @@
import React from 'react';
import { ActivityIndicator } from 'react-native';
import { useTheme } from 'react-native-paper';
import PaddedView from './paddedView';
import { RootView } from '.';
const LoadingView = () => {
const { colors } = useTheme();
return (
<PaddedView centered>
<RootView centered>
<ActivityIndicator size="large" color={colors.primary} />
</PaddedView>
</RootView>
);
};

View File

@@ -0,0 +1,37 @@
import React, { ReactNode } from 'react';
import {
StyleProp,
ScrollView,
ViewStyle,
} from 'react-native';
import { useTheme } from 'react-native-paper';
import styles from '../styles';
const RootScrollView = ({
children,
style,
centered,
padded,
}: {
children: ReactNode;
style?: StyleProp<ViewStyle>;
centered?: boolean;
padded?: boolean;
}) => {
const { colors } = useTheme();
return (
<ScrollView
contentContainerStyle={[
padded && styles.padding,
centered && [styles.centered, styles.flex],
{ backgroundColor: colors.background },
style,
]}
nestedScrollEnabled>
{children}
</ScrollView>
);
};
export default RootScrollView;

View File

@@ -3,22 +3,24 @@ import { StyleProp, View, ViewStyle } from 'react-native';
import { useTheme } from 'react-native-paper';
import styles from '../styles';
const PaddedView = ({
const RootView = ({
children,
style,
centered,
padded,
}: {
children: ReactNode;
style?: StyleProp<ViewStyle>;
centered?: boolean;
padded?: boolean;
}) => {
const { colors } = useTheme();
return (
<View
style={[
styles.padding,
centered && styles.centered,
padded && styles.padding,
centered && [styles.centered, styles.flex],
{ backgroundColor: colors.background },
style,
]}>
@@ -27,4 +29,4 @@ const PaddedView = ({
);
};
export default PaddedView;
export default RootView;

View File

@@ -0,0 +1,48 @@
import React from 'react';
import { View } from 'react-native';
import FontAwesome5 from 'react-native-vector-icons/FontAwesome5';
import { Chip } from 'react-native-paper';
import styles from '../styles';
import { useDimensions } from '../contexts';
import { getContrastColor } from '../utilities';
const TagPreview = (properties: { name: string; color: string }) => {
const dimensions = useDimensions();
return (
<View
style={[
styles.centeredHorizontal,
styles.flexRow,
{
margin: dimensions.responsive.verticalScale(50),
},
]}>
<Chip
icon={() => {
return (
<FontAwesome5
name="tag"
size={dimensions.static.horizontalScale(12)}
color={getContrastColor(properties.color)}
/>
);
}}
elevated
style={[
{
backgroundColor: properties.color,
padding: dimensions.static.verticalScale(5),
},
]}
textStyle={[
{ fontSize: dimensions.static.horizontalScale(15) },
{ color: getContrastColor(properties.color) },
]}>
{'#' + properties.name}
</Chip>
</View>
);
};
export default TagPreview;