diff --git a/src/components/hideableHeader.tsx b/src/components/hideableHeader.tsx
new file mode 100644
index 0000000..fe341f9
--- /dev/null
+++ b/src/components/hideableHeader.tsx
@@ -0,0 +1,63 @@
+import React, { useEffect, useRef } from 'react';
+import { Animated, StyleSheet } from 'react-native';
+import { useDimensions } from '../contexts';
+import styles from '../styles';
+import { useTheme } from 'react-native-paper';
+
+const hideableHeaderStyles = StyleSheet.create({
+ headerView: {
+ position: 'absolute',
+ top: 0,
+ left: 0,
+ right: 0,
+ zIndex: 100,
+ },
+});
+
+const HideableHeader = ({
+ visible = true,
+ children,
+}: {
+ visible?: boolean;
+ children: React.ReactNode;
+}) => {
+ const { colors } = useTheme();
+ const { orientation } = useDimensions();
+
+ const headerAnim = useRef(new Animated.Value(visible ? 1 : 0)).current;
+
+ useEffect(() => {
+ Animated.timing(headerAnim, {
+ toValue: visible ? 1 : 0,
+ duration: visible ? 200 : 150,
+ useNativeDriver: true,
+ }).start();
+ }, [headerAnim, visible]);
+
+ return (
+
+ {children}
+
+ );
+};
+
+export default HideableHeader;
diff --git a/src/components/index.ts b/src/components/index.ts
index 3d9cf86..455a959 100644
--- a/src/components/index.ts
+++ b/src/components/index.ts
@@ -1,5 +1,6 @@
export { default as FloatingActionButton } from './floatingActionButton';
export { default as HideableBottomNavigationBar } from './hideableBottomNavigationBar';
+export { default as HideableHeader } from './hideableHeader';
export { default as LoadingView } from './loadingView';
-export { default as TagChip } from './tagChip';
-export { default as TagPreview } from './tagPreview';
+export { default as TagChip } from './tags/tagChip';
+export { default as TagPreview } from './tags/tagPreview';
diff --git a/src/components/tagChip.tsx b/src/components/tags/tagChip.tsx
similarity index 86%
rename from src/components/tagChip.tsx
rename to src/components/tags/tagChip.tsx
index f3e6d36..dfb801a 100644
--- a/src/components/tagChip.tsx
+++ b/src/components/tags/tagChip.tsx
@@ -1,7 +1,7 @@
import React from 'react';
-import { getContrastColor } from '../utilities';
+import { getContrastColor } from '../../utilities';
import { Chip } from 'react-native-paper';
-import { Tag } from '../database';
+import { Tag } from '../../database';
import FontAwesome5 from 'react-native-vector-icons/FontAwesome5';
const TagChip = ({ tag }: { tag: Tag }) => {
diff --git a/src/components/tagPreview.tsx b/src/components/tags/tagPreview.tsx
similarity index 88%
rename from src/components/tagPreview.tsx
rename to src/components/tags/tagPreview.tsx
index 89bb11d..8e9e329 100644
--- a/src/components/tagPreview.tsx
+++ b/src/components/tags/tagPreview.tsx
@@ -2,9 +2,9 @@ import React from 'react';
import { StyleSheet, 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';
+import styles from '../../styles';
+import { useDimensions } from '../../contexts';
+import { getContrastColor } from '../../utilities';
const tagPreviewStyles = StyleSheet.create({
chip: {
diff --git a/src/screens/tags.tsx b/src/screens/tags.tsx
index 86e696e..af56bbc 100644
--- a/src/screens/tags.tsx
+++ b/src/screens/tags.tsx
@@ -1,11 +1,11 @@
-import React, { useEffect, useRef, useState } from 'react';
+import React, { useCallback, useRef, useState } from 'react';
import {
StyleSheet,
View,
Text,
NativeSyntheticEvent,
NativeScrollEvent,
- Animated,
+ BackHandler,
} from 'react-native';
import {
Button,
@@ -19,7 +19,12 @@ import {
import { useQuery } from '@realm/react';
import { useDispatch, useSelector } from 'react-redux';
import { FlashList } from '@shopify/flash-list';
-import { TagChip } from '../components';
+import {
+ NavigationProp,
+ useFocusEffect,
+ useNavigation,
+} from '@react-navigation/native';
+import { HideableHeader, TagChip } from '../components';
import { Tag } from '../database';
import styles from '../styles';
import {
@@ -37,17 +42,8 @@ import {
tagSortQuery,
} from '../types';
import { getSortIcon } from '../utilities';
-import { useDimensions } from '../contexts';
-import { NavigationProp, useNavigation } from '@react-navigation/native';
const tagsStyles = StyleSheet.create({
- headerView: {
- position: 'absolute',
- top: 0,
- left: 0,
- right: 0,
- zIndex: 100,
- },
headerButtonView: {
height: 50,
},
@@ -74,8 +70,7 @@ const tagsStyles = StyleSheet.create({
const Tags = () => {
const { colors } = useTheme();
- const { orientation } = useDimensions();
- const navigation = useNavigation>();
+ const { navigate } = useNavigation>();
const sort = useSelector((state: RootState) => state.tags.sort);
const sortDirection = useSelector(
(state: RootState) => state.tags.sortDirection,
@@ -101,16 +96,6 @@ const Tags = () => {
setSortMenuVisible(false);
};
- const sortMenuAnim = useRef(new Animated.Value(navVisisble ? 1 : 0)).current;
-
- useEffect(() => {
- Animated.timing(sortMenuAnim, {
- toValue: navVisisble ? 1 : 0,
- duration: navVisisble ? 200 : 150,
- useNativeDriver: true,
- }).start();
- }, [navVisisble, sortMenuAnim]);
-
const [search, setSearch] = useState('');
const tags = useQuery(
@@ -132,17 +117,33 @@ const Tags = () => {
if (currentOffset <= 150) {
dispatch(setNavVisible(true));
- setScrollOffset(0);
- return;
+ } else {
+ const diff = currentOffset - scrollOffset;
+ if (Math.abs(diff) > 50) dispatch(setNavVisible(diff < 0));
}
- const diff = currentOffset - scrollOffset;
- if (Math.abs(diff) < 50) return;
-
- dispatch(setNavVisible(diff < 0));
setScrollOffset(currentOffset);
};
+ const flashListRef = useRef>(null);
+
+ useFocusEffect(
+ useCallback(() => {
+ const handleBackPress = () => {
+ if (scrollOffset > 0) {
+ flashListRef.current?.scrollToOffset({ offset: 0, animated: true });
+ return true;
+ }
+ return false;
+ };
+
+ BackHandler.addEventListener('hardwareBackPress', handleBackPress);
+
+ return () =>
+ BackHandler.removeEventListener('hardwareBackPress', handleBackPress);
+ }, [flashListRef, scrollOffset]),
+ );
+
return (
{
styles.fullSize,
{ backgroundColor: colors.background },
]}>
-
+
{
-
+
(
- navigation.navigate(ROUTE.EDIT_TAG, { id: tag.id.toHexString() })
+ navigate(ROUTE.EDIT_TAG, { id: tag.id.toHexString() })
}>
diff --git a/src/styles.tsx b/src/styles.tsx
index 7f6deb0..82a33bc 100644
--- a/src/styles.tsx
+++ b/src/styles.tsx
@@ -14,16 +14,16 @@ const styles = StyleSheet.create({
paddingTop: '2%',
},
padding: {
- padding: '5%',
+ padding: '4%',
},
paddingHorizontal: {
- paddingHorizontal: '5%',
+ paddingHorizontal: '4%',
},
paddingVertical: {
- paddingVertical: '5%',
+ paddingVertical: '4%',
},
paddingTop: {
- paddingTop: '5%',
+ paddingTop: '4%',
},
centered: {
justifyContent: 'center',