Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nt/feed filters #2921

Merged
merged 8 commits into from
Sep 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1145,6 +1145,10 @@ PODS:
- React-Core
- react-native-orientation-locker (1.6.0):
- React-Core
- react-native-pager-view (6.4.1):
- glog
- RCT-Folly (= 2022.05.16.00)
- React-Core
- react-native-randombytes (3.6.1):
- React-Core
- react-native-receive-sharing-intent (2.0.0):
Expand Down Expand Up @@ -1510,6 +1514,7 @@ DEPENDENCIES:
- react-native-heic-converter (from `../node_modules/react-native-heic-converter`)
- "react-native-netinfo (from `../node_modules/@react-native-community/netinfo`)"
- react-native-orientation-locker (from `../node_modules/react-native-orientation-locker`)
- react-native-pager-view (from `../node_modules/react-native-pager-view`)
- react-native-randombytes (from `../node_modules/react-native-randombytes`)
- react-native-receive-sharing-intent (from `../node_modules/react-native-receive-sharing-intent`)
- react-native-render-html (from `../node_modules/react-native-render-html`)
Expand Down Expand Up @@ -1711,6 +1716,8 @@ EXTERNAL SOURCES:
:path: "../node_modules/@react-native-community/netinfo"
react-native-orientation-locker:
:path: "../node_modules/react-native-orientation-locker"
react-native-pager-view:
:path: "../node_modules/react-native-pager-view"
react-native-randombytes:
:path: "../node_modules/react-native-randombytes"
react-native-receive-sharing-intent:
Expand Down Expand Up @@ -1905,6 +1912,7 @@ SPEC CHECKSUMS:
react-native-heic-converter: 8f7cd7a143ef013a54540ef7ebbc232cecb4fa87
react-native-netinfo: 8a7fd3f7130ef4ad2fb4276d5c9f8d3f28d2df3d
react-native-orientation-locker: 4409c5b12b65f942e75449872b4f078b6f27af81
react-native-pager-view: 4e062b5bf27b7070d470c60fd2e091ee641ba852
react-native-randombytes: 421f1c7d48c0af8dbcd471b0324393ebf8fe7846
react-native-receive-sharing-intent: 62ab28c50e6ae56d32b9e841d7452091312a0bc7
react-native-render-html: 984dfe2294163d04bf5fe25d7c9f122e60e05ebe
Expand Down
6 changes: 5 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
"@tanstack/react-query": "^4.3.9",
"@tanstack/react-query-persist-client": "^4.3.9",
"@tradle/react-native-http": "^2.0.0",
"add": "^2.0.6",
"appcenter": "5.0.0",
"appcenter-analytics": "5.0.0",
"appcenter-crashes": "5.0.0",
Expand Down Expand Up @@ -137,6 +138,7 @@
"react-native-navigation-bar-color": "^2.0.2",
"react-native-orientation-locker": "^1.6.0",
"react-native-os": "^1.2.6",
"react-native-pager-view": "^6.4.1",
"react-native-permissions": "^3.3.0",
"react-native-portalize": "^1.0.7",
"react-native-progress": "^5.0.0",
Expand All @@ -154,6 +156,7 @@
"react-native-snap-carousel": "^3.8.0",
"react-native-svg": "^12.1.1",
"react-native-swiper": "^1.6.0-rc.3",
"react-native-tab-view": "^3.5.2",
"react-native-tcp": "^4.0.0",
"react-native-tus-client": "^1.1.0",
"react-native-udp": "^4.1.4",
Expand Down Expand Up @@ -187,7 +190,8 @@
"tty-browserify": "0.0.0",
"url": "~0.10.1",
"util": "~0.10.3",
"vm-browserify": "0.0.4"
"vm-browserify": "0.0.4",
"yarn": "^1.22.22"
},
"devDependencies": {
"@babel/core": "^7.20.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ const CustomiseFiltersModal = ({ pageType }: Props, ref: Ref<CustomiseFiltersMod

// save snippet based on editor pageType
const _onApply = () => {
if (selectedFilters.size !== 3) {
if (selectedFilters.size < 3) {
alert(intl.formatMessage({ id: 'alert.wrong_filter_count' }));
return;
}
Expand Down
65 changes: 32 additions & 33 deletions src/components/tabbedPosts/container/tabbedPosts.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import React, { useState } from 'react';
import ScrollableTabView from 'react-native-scrollable-tab-view';
import { TabView, TabBarProps } from 'react-native-tab-view';
import { useWindowDimensions, View } from 'react-native';
import { TabbedPostsProps } from '../types/tabbedPosts.types';
import { StackedTabBar, TabItem } from '../view/stackedTabBar';
import { FeedTabBar, TabItem } from '../view/feedTabBar';
import PostsTabContent from '../view/postsTabContent';

export const TabbedPosts = ({
Expand All @@ -14,15 +15,16 @@ export const TabbedPosts = ({
feedUsername,
pageType,
tabContentOverrides,
imagesToggleEnabled,
stackedTabs,
onTabChange,
...props
}: TabbedPostsProps) => {
const layout = useWindowDimensions();

// initialize state
const [initialTabIndex] = useState(
selectedOptionIndex == 0 && stackedTabs ? filterOptions.length : selectedOptionIndex,
);
const [index, setIndex] = useState(initialTabIndex);

const mainFilters = filterOptions.map(
(label, index) =>
Expand All @@ -43,6 +45,9 @@ export const TabbedPosts = ({
: [];

const combinedFilters = [...mainFilters, ...subFilters];
const [routes] = useState(
combinedFilters.map((filter) => ({ key: filter.filterKey, title: filter.label })),
);

const [selectedFilter, setSelectedFilter] = useState(combinedFilters[initialTabIndex].filterKey);
const [filterScrollRequest, createFilterScrollRequest] = useState<string | null>(null);
Expand All @@ -60,16 +65,22 @@ export const TabbedPosts = ({
createFilterScrollRequest(null);
};

// initialize first set of pages
const pages = combinedFilters.map((filter, index) => {
// render tab bar
const _renderTabBar = (props: TabBarProps<any>) => {
return (
<FeedTabBar {...props} routes={routes} onFilterSelect={_onFilterSelect} pageType={pageType} />
);
};

// Dynamically create scenes for each tab
const renderScene = ({ route }) => {
if (tabContentOverrides && tabContentOverrides.has(index)) {
return tabContentOverrides.get(index);
}

return (
<PostsTabContent
key={filter.filterKey}
filterKey={filter.filterKey}
key={route.key}
filterKey={route.key}
isFeedScreen={isFeedScreen}
isInitialTab={initialTabIndex == index}
feedUsername={feedUsername}
Expand All @@ -79,32 +90,20 @@ export const TabbedPosts = ({
{...props}
/>
);
});

// render tab bar
const _renderTabBar = (props) => {
return (
<StackedTabBar
{...props}
firstStack={mainFilters}
secondStack={subFilters}
initialFirstStackIndex={selectedOptionIndex}
onFilterSelect={_onFilterSelect}
toggleHideImagesFlag={imagesToggleEnabled}
pageType={pageType}
/>
);
};

return (
<ScrollableTabView
scrollWithoutAnimation={true}
locked={true}
initialPage={initialTabIndex}
renderTabBar={_renderTabBar}
onTabChange={onTabChange}
>
{pages}
</ScrollableTabView>
<View style={{ flex: 1, width: layout.width }}>
<TabView
animationEnabled={false}
lazy={true}
swipeEnabled={false}
renderTabBar={_renderTabBar}
navigationState={{ index, routes }}
renderScene={renderScene}
onIndexChange={setIndex}
initialLayout={{ width: layout.width }}
/>
</View>
);
};
59 changes: 59 additions & 0 deletions src/components/tabbedPosts/styles/feedTabBar.styles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import EStyleSheet from 'react-native-extended-stylesheet';
import getWindowDimensions from '../../../utils/getWindowDimensions';

const deviceWidth = getWindowDimensions().width;

export default EStyleSheet.create({
container: {
justifyContent: 'center',
backgroundColor: '$primaryLightBackground',
shadowOpacity: 0.3,
shadowColor: '$shadowColor',
elevation: 0.1,
shadowOffset: {
height: 1,
},
zIndex: 99,
},

indicatorStyle: {
backgroundColor: 'transparent',
},
tabStyle: {
width: 'auto',
minWidth: deviceWidth / 3 - 12,
height: 38,
paddingTop: 0,
},
tabBarStyle: {
flex: 1,
backgroundColor: EStyleSheet.value('$primaryLightBackground'), // Background color for the TabBar
},

dropdownWrapper: {
flexDirection: 'row',
justifyContent: 'space-around',
alignItems: 'center',
marginRight: 8,
flex: 1,
},
filterBarWrapper: {
flex: 1,
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
},
rightIconWrapper: {
paddingRight: 12,
paddingLeft: 4,
width: 40,
alignSelf: 'center',
},
rightIcon: {
color: '$darkIconColor',
textAlign: 'center',
},
rightIconPlaceholder: {
marginRight: 8,
},
});
2 changes: 0 additions & 2 deletions src/components/tabbedPosts/types/tabbedPosts.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,8 @@ export interface TabbedPostsProps {
tag: string;
forceLoadPosts: boolean;
tabContentOverrides: Map<number, any>;
imagesToggleEnabled?: boolean;
stackedTabs: boolean;
pinnedPermlink?: string;
onTabChange: (index: number) => void;
handleOnScroll: () => void;
}

Expand Down
77 changes: 77 additions & 0 deletions src/components/tabbedPosts/view/feedTabBar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import React, { useRef } from 'react';
import { useIntl } from 'react-intl';
import { TabBar, TabBarProps } from 'react-native-tab-view';
import EStyleSheet from 'react-native-extended-stylesheet';
import { useWindowDimensions, View } from 'react-native';
import { CustomiseFiltersModal, IconButton, Tag } from '../..';
import { CustomiseFiltersModalRef } from '../../customiseFiltersModal/customiseFiltersModal';
import styles from '../styles/feedTabBar.styles';

export interface TabItem {
filterKey: string;
label: string;
}

interface FeedTabBarProps extends TabBarProps<any> {
pageType?: 'main' | 'community' | 'profile' | 'ownProfile';
routes: {
key: string;
title: string;
}[];
onFilterSelect: (filterKey: string) => void;
}

export const FeedTabBar = ({ routes, onFilterSelect, pageType, ...props }: FeedTabBarProps) => {
const intl = useIntl();
const layout = useWindowDimensions();

const customiseModalRef = useRef<CustomiseFiltersModalRef>();

const enableCustomTabs = pageType !== undefined;

const _onCustomisePress = () => {
if (customiseModalRef.current) {
customiseModalRef.current.show();
}
};

return (
<View
style={{
flexDirection: 'row',
alignItems: 'center',
backgroundColor: EStyleSheet.value('$primaryLightBackground'),
}}
>
<TabBar
renderLabel={({ route, focused }) => (
<Tag
key={route.key}
value={intl.formatMessage({ id: route.title.toLowerCase() }).toUpperCase()}
isFilter
isPin={focused}
/>
)}
style={styles.tabBarStyle}
indicatorStyle={styles.indicatorStyle}
tabStyle={{ ...styles.tabStyle, minWidth: layout.width / 3 - (enableCustomTabs ? 14 : 0) }}
scrollEnabled={routes.length > 3}
onTabPress={({ route }) => {
onFilterSelect(route.key);
}}
{...props}
/>
{enableCustomTabs && (
<IconButton
iconStyle={styles.rightIcon}
style={styles.rightIconWrapper}
iconType="MaterialIcon"
size={28}
name="add"
onPress={_onCustomisePress}
/>
)}
{enableCustomTabs && <CustomiseFiltersModal pageType={pageType} ref={customiseModalRef} />}
</View>
);
};
2 changes: 1 addition & 1 deletion src/components/tabbedPosts/view/listEmptyView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { useNavigation } from '@react-navigation/native';
import { NoPost, PostCardPlaceHolder, UserListItem } from '../..';
import globalStyles from '../../../globalStyles';
import { CommunityListItem, EmptyScreen } from '../../basicUIElements';
import styles from './tabbedPostsStyles';
import styles from '../styles/tabbedPosts.styles';
import { default as ROUTES } from '../../../constants/routeNames';
import {
fetchCommunities,
Expand Down
2 changes: 1 addition & 1 deletion src/components/tabbedPosts/view/scrollTopPopup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { Image as ExpoImage } from 'expo-image';
import Animated, { ZoomIn, ZoomOut } from 'react-native-reanimated';
import EStyleSheet from 'react-native-extended-stylesheet';
import { IconButton } from '../..';
import styles from './tabbedPostsStyles';
import styles from '../styles/tabbedPosts.styles';

interface ScrollTopPopupProps {
onPress: () => void;
Expand Down
Loading