Fix layout bugs
Signed-off-by: Nikolaos Karaolidis <nick@karaolidis.com>
This commit is contained in:
@@ -1,35 +1,24 @@
|
||||
import React, { useState } from 'react';
|
||||
import { StyleSheet, View } from 'react-native';
|
||||
import React, { useCallback, useRef, useState } from 'react';
|
||||
import {
|
||||
BackHandler,
|
||||
NativeScrollEvent,
|
||||
NativeSyntheticEvent,
|
||||
StyleSheet,
|
||||
View,
|
||||
} from 'react-native';
|
||||
import { useQuery } from '@realm/react';
|
||||
import {
|
||||
Button,
|
||||
Menu,
|
||||
IconButton,
|
||||
Divider,
|
||||
useTheme,
|
||||
Searchbar,
|
||||
HelperText,
|
||||
} from 'react-native-paper';
|
||||
import { useTheme, HelperText } from 'react-native-paper';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import { FlashList } from '@shopify/flash-list';
|
||||
import { useFocusEffect } from '@react-navigation/native';
|
||||
import styles from '../styles';
|
||||
import { MEME_SORT, SORT_DIRECTION, memesSortQuery } from '../types';
|
||||
import { getSortIcon, getViewIcon } from '../utilities';
|
||||
import {
|
||||
RootState,
|
||||
cycleMemesView,
|
||||
toggleMemesSortDirection,
|
||||
setMemesSortDirection,
|
||||
toggleMemesFavoritesOnly,
|
||||
setMemesSort,
|
||||
setMemesFilter,
|
||||
} from '../state';
|
||||
import { MEME_TYPE, Meme, memeTypePlural } from '../database';
|
||||
import { SORT_DIRECTION, memesSortQuery } from '../types';
|
||||
import { RootState, setNavVisible } from '../state';
|
||||
import { Meme, Tag } from '../database';
|
||||
import { useDimensions } from '../contexts';
|
||||
import { HideableHeader, MemesHeader } from '../components';
|
||||
|
||||
const memesStyles = StyleSheet.create({
|
||||
headerButtonView: {
|
||||
height: 50,
|
||||
},
|
||||
helperText: {
|
||||
marginVertical: 10,
|
||||
},
|
||||
@@ -47,30 +36,12 @@ const Memes = () => {
|
||||
(state: RootState) => state.memes.favoritesOnly,
|
||||
);
|
||||
const filter = useSelector((state: RootState) => state.memes.filter);
|
||||
const navVisisble = useSelector(
|
||||
(state: RootState) => state.navigation.navVisible,
|
||||
);
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const [sortMenuVisible, setSortMenuVisible] = useState(false);
|
||||
const [filterMenuVisible, setFilterMenuVisible] = useState(false);
|
||||
|
||||
const handleSortModeChange = (newSort: MEME_SORT) => {
|
||||
if (newSort === sort) {
|
||||
dispatch(toggleMemesSortDirection());
|
||||
} else {
|
||||
dispatch(setMemesSort(newSort));
|
||||
if (newSort === MEME_SORT.TITLE) {
|
||||
dispatch(setMemesSortDirection(SORT_DIRECTION.ASCENDING));
|
||||
} else {
|
||||
dispatch(setMemesSortDirection(SORT_DIRECTION.DESCENDING));
|
||||
}
|
||||
}
|
||||
setSortMenuVisible(false);
|
||||
};
|
||||
|
||||
const handleFilterChange = (newFilter: MEME_TYPE | undefined) => {
|
||||
dispatch(setMemesFilter(newFilter));
|
||||
setFilterMenuVisible(false);
|
||||
};
|
||||
|
||||
const [flashListPadding, setFlashListPadding] = useState(0);
|
||||
const [search, setSearch] = useState('');
|
||||
|
||||
const memes = useQuery<Meme>(
|
||||
@@ -94,110 +65,56 @@ const Memes = () => {
|
||||
[sort, sortDirection, favoritesOnly, filter, search],
|
||||
);
|
||||
|
||||
const [scrollOffset, setScrollOffset] = useState(0);
|
||||
|
||||
const handleScroll = (event: NativeSyntheticEvent<NativeScrollEvent>) => {
|
||||
const currentOffset = event.nativeEvent.contentOffset.y;
|
||||
|
||||
if (currentOffset <= 150) {
|
||||
dispatch(setNavVisible(true));
|
||||
} else {
|
||||
const diff = currentOffset - scrollOffset;
|
||||
if (Math.abs(diff) > 50) dispatch(setNavVisible(diff < 0));
|
||||
}
|
||||
|
||||
setScrollOffset(currentOffset);
|
||||
};
|
||||
|
||||
const flashListRef = useRef<FlashList<Tag>>(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 (
|
||||
<View
|
||||
style={[
|
||||
orientation == 'portrait' && styles.paddingTop,
|
||||
orientation == 'landscape' && styles.smallPaddingTop,
|
||||
styles.paddingHorizontal,
|
||||
styles.fullSize,
|
||||
{ backgroundColor: colors.background },
|
||||
]}>
|
||||
<Searchbar
|
||||
placeholder="Search Memes"
|
||||
value={search}
|
||||
onChangeText={setSearch}
|
||||
/>
|
||||
<View
|
||||
style={[
|
||||
styles.flexRowSpaceBetween,
|
||||
styles.alignCenter,
|
||||
memesStyles.headerButtonView,
|
||||
]}>
|
||||
<View style={[styles.flexRow, styles.alignCenter]}>
|
||||
<Menu
|
||||
visible={sortMenuVisible}
|
||||
onDismiss={() => setSortMenuVisible(false)}
|
||||
anchor={
|
||||
<Button
|
||||
onPress={() => setSortMenuVisible(true)}
|
||||
icon={getSortIcon(sort, sortDirection)}
|
||||
contentStyle={styles.flexRowReverse}
|
||||
compact>
|
||||
Sort By: {sort}
|
||||
</Button>
|
||||
}>
|
||||
{Object.keys(MEME_SORT).map(key => {
|
||||
return (
|
||||
<Menu.Item
|
||||
key={key}
|
||||
onPress={() =>
|
||||
handleSortModeChange(
|
||||
MEME_SORT[key as keyof typeof MEME_SORT],
|
||||
)
|
||||
}
|
||||
title={MEME_SORT[key as keyof typeof MEME_SORT]}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</Menu>
|
||||
</View>
|
||||
<View style={[styles.flexRow, styles.alignCenter]}>
|
||||
<IconButton
|
||||
icon={getViewIcon(view)}
|
||||
iconColor={colors.primary}
|
||||
size={16}
|
||||
animated
|
||||
onPress={() => dispatch(cycleMemesView())}
|
||||
/>
|
||||
<IconButton
|
||||
icon={favoritesOnly ? 'heart' : 'heart-outline'}
|
||||
iconColor={colors.primary}
|
||||
size={16}
|
||||
animated
|
||||
onPress={() => dispatch(toggleMemesFavoritesOnly())}
|
||||
/>
|
||||
<Menu
|
||||
visible={filterMenuVisible}
|
||||
onDismiss={() => setFilterMenuVisible(false)}
|
||||
anchor={
|
||||
<IconButton
|
||||
onPress={() => setFilterMenuVisible(true)}
|
||||
icon={filter ? 'filter' : 'filter-outline'}
|
||||
iconColor={colors.primary}
|
||||
size={16}
|
||||
/>
|
||||
}>
|
||||
<Menu.Item
|
||||
// eslint-disable-next-line unicorn/no-useless-undefined
|
||||
onPress={() => handleFilterChange(undefined)}
|
||||
title="All"
|
||||
/>
|
||||
{Object.keys(MEME_TYPE).map(key => {
|
||||
return (
|
||||
<Menu.Item
|
||||
key={key}
|
||||
onPress={() =>
|
||||
handleFilterChange(MEME_TYPE[key as keyof typeof MEME_TYPE])
|
||||
}
|
||||
title={
|
||||
memeTypePlural[MEME_TYPE[key as keyof typeof MEME_TYPE]]
|
||||
}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</Menu>
|
||||
</View>
|
||||
</View>
|
||||
<Divider />
|
||||
{/* TODO: Meme Views */}
|
||||
{memes.length === 0 && (
|
||||
<HelperText
|
||||
type={'info'}
|
||||
style={[memesStyles.helperText, styles.centerText]}>
|
||||
No memes found
|
||||
</HelperText>
|
||||
)}
|
||||
<HideableHeader visible={navVisisble}>
|
||||
<MemesHeader
|
||||
search={search}
|
||||
setSearch={setSearch}
|
||||
onLayout={event => {
|
||||
setFlashListPadding(event.nativeEvent.layout.height);
|
||||
}}
|
||||
/>
|
||||
</HideableHeader>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
Reference in New Issue
Block a user