using stacked tabs in profile screen with content overrides

This commit is contained in:
Nouman Tahir 2021-04-13 13:13:42 +05:00
parent de487eb0a6
commit 44bec50e7d
9 changed files with 226 additions and 205 deletions

View File

@ -6,7 +6,9 @@ import { useSelector } from 'react-redux';
import { ThemeContainer } from '../../../containers';
import styles from '../view/postsListStyles';
export interface PostsListRef {
scrollToTop:()=>void
}
interface postsListContainerProps extends FlatListProps<any> {
promotedPosts:Array<any>;

View File

@ -9,13 +9,18 @@ import { CollapsibleCard } from '../collapsibleCard';
import { Comments } from '../comments';
import { Header } from '../header';
import { NoPost, ProfileSummaryPlaceHolder, WalletDetailsPlaceHolder } from '../basicUIElements';
import { Posts } from '../posts';
import { ProfileSummary } from '../profileSummary';
import { TabBar } from '../tabBar';
import { Wallet } from '../wallet';
// Constants
import { PROFILE_FILTERS, PROFILE_FILTERS_VALUE } from '../../constants/options/filters';
import {
PROFILE_FILTERS,
PROFILE_FILTERS_OWN,
PROFILE_FILTERS_VALUE,
PROFILE_SUBFILTERS,
PROFILE_SUBFILTERS_VALUE,
} from '../../constants/options/filters';
// Utils
import { getFormatedCreatedDate } from '../../utils/time';
@ -74,24 +79,25 @@ class ProfileView extends PureComponent {
return value;
};
_isCloseToBottom({ layoutMeasurement, contentOffset, contentSize }) {
return layoutMeasurement.height + contentOffset.y >= contentSize.height - 20;
}
_onTabChange = ({ i }) => {
const { estimatedWalletValue, oldEstimatedWalletValue } = this.state;
render() {
if (i !== 2) {
this.setState({
estimatedWalletValue: 0,
oldEstimatedWalletValue: estimatedWalletValue,
});
} else {
this.setState({ estimatedWalletValue: oldEstimatedWalletValue });
}
};
_renderProfileContent = () => {
const {
about,
activePage,
changeForceLoadPostState,
comments,
currencyRate,
currencySymbol,
follows,
forceLoadPost,
getReplies,
handleFollowUnfollowUser,
handleMuteUnmuteUser,
handleOnBackPress,
handleOnFavoritePress,
handleOnFollowsPress,
handleOnPressProfileEdit,
@ -104,20 +110,164 @@ class ProfileView extends PureComponent {
isOwnProfile,
isProfileLoading,
isReady,
quickProfile,
resourceCredits,
selectedUser,
username,
votingPower,
isHideImage,
} = this.props;
const {
isSummaryOpen,
collapsibleMoreHeight,
estimatedWalletValue,
oldEstimatedWalletValue,
} = this.state;
const { isSummaryOpen, collapsibleMoreHeight } = this.state;
return !isReady ? (
<ProfileSummaryPlaceHolder />
) : (
<CollapsibleCard
title={get(about, 'about')}
isTitleCenter
defaultTitle={intl.formatMessage({
id: 'profile.details',
})}
expanded={!isOwnProfile}
isExpanded={isSummaryOpen}
handleOnExpanded={this._handleOnSummaryExpanded}
moreHeight={collapsibleMoreHeight}
>
<ProfileSummary
date={getFormatedCreatedDate(get(selectedUser, 'created'))}
about={about}
followerCount={follows.follower_count}
followingCount={follows.following_count}
handleFollowUnfollowUser={handleFollowUnfollowUser}
handleMuteUnmuteUser={handleMuteUnmuteUser}
handleOnFavoritePress={handleOnFavoritePress}
handleOnFollowsPress={handleOnFollowsPress}
handleUIChange={this._handleUIChange}
hoursRC={Math.ceil((100 - resourceCredits) * 0.833333) || null}
hoursVP={Math.ceil((100 - votingPower) * 0.833333) || null}
intl={intl}
isDarkTheme={isDarkTheme}
isFavorite={isFavorite}
isFollowing={isFollowing}
isLoggedIn={isLoggedIn}
isMuted={isMuted}
isOwnProfile={isOwnProfile}
isProfileLoading={isProfileLoading}
percentRC={resourceCredits}
percentVP={votingPower}
handleOnPressProfileEdit={handleOnPressProfileEdit}
/>
</CollapsibleCard>
);
};
_contentComentsTab = () => {
const { comments, getReplies, intl, isOwnProfile, username, isHideImage } = this.props;
return (
<View key="profile.comments" style={styles.commentsTabBar}>
{comments && comments.length > 0 ? (
<ScrollView
onScroll={({ nativeEvent }) => {
this._handleOnScroll();
if (this._isCloseToBottom(nativeEvent)) {
this._loadMoreComments();
}
}}
contentContainerStyle={styles.scrollContentContainer}
//scrollEventThrottle={16}
>
<Comments
isProfilePreview
comments={comments}
fetchPost={getReplies}
isOwnProfile={isOwnProfile}
isHideImage={isHideImage}
/>
</ScrollView>
) : (
<NoPost
name={username}
text={intl.formatMessage({
id: 'profile.havent_commented',
})}
defaultText={intl.formatMessage({
id: 'profile.login_to_see',
})}
/>
)}
</View>
);
};
_contentWalletTab = () => {
const { currencyRate, currencySymbol, selectedUser } = this.props;
const { isSummaryOpen, estimatedWalletValue } = this.state;
return (
<View
key="profile.wallet"
tabLabel={
estimatedWalletValue
? `${currencySymbol} ${(estimatedWalletValue * currencyRate).toFixed()}`
: null
}
>
{selectedUser ? (
<Wallet
setEstimatedWalletValue={(value) => this.setState({ estimatedWalletValue: value })}
selectedUser={selectedUser}
handleOnScroll={isSummaryOpen ? this._handleOnScroll : null}
/>
) : (
<WalletDetailsPlaceHolder />
)}
</View>
);
};
_renderTabs = () => {
const { changeForceLoadPostState, forceLoadPost, username, isOwnProfile } = this.props;
const { isSummaryOpen } = this.state;
const filterOptions = isOwnProfile ? PROFILE_FILTERS_OWN : PROFILE_FILTERS;
//compile content overrides
const tabContentOverrides = new Map();
tabContentOverrides.set(1, this._contentComentsTab());
if (!isOwnProfile) {
tabContentOverrides.set(2, this._contentWalletTab());
}
return (
<View style={styles.postTabBar}>
<TabbedPosts
filterOptions={filterOptions}
filterOptionsValue={PROFILE_FILTERS_VALUE}
feedSubfilterOptions={PROFILE_SUBFILTERS}
feedSubfilterOptionsValue={PROFILE_SUBFILTERS_VALUE}
selectedOptionIndex={0}
pageType="profiles"
getFor="blog"
feedUsername={username}
key={username}
handleOnScroll={isSummaryOpen ? this._handleOnScroll : null}
forceLoadPost={forceLoadPost}
changeForceLoadPostState={changeForceLoadPostState}
isFeedScreen={false}
tabContentOverrides={tabContentOverrides}
onChangeTab={this._onTabChange}
stackedTabs={true}
/>
</View>
);
};
_isCloseToBottom({ layoutMeasurement, contentOffset, contentSize }) {
return layoutMeasurement.height + contentOffset.y >= contentSize.height - 20;
}
render() {
const { handleOnBackPress, isOwnProfile, quickProfile } = this.props;
return (
<View style={styles.container}>
@ -128,148 +278,8 @@ class ProfileView extends PureComponent {
handleOnBackPress={handleOnBackPress}
/>
<View style={styles.container}>
{!isReady ? (
<ProfileSummaryPlaceHolder />
) : (
<CollapsibleCard
title={get(about, 'about')}
isTitleCenter
defaultTitle={intl.formatMessage({
id: 'profile.details',
})}
expanded={!isOwnProfile}
isExpanded={isSummaryOpen}
handleOnExpanded={this._handleOnSummaryExpanded}
moreHeight={collapsibleMoreHeight}
// expanded={isLoggedIn}
// locked={!isLoggedIn}
>
<ProfileSummary
date={getFormatedCreatedDate(get(selectedUser, 'created'))}
about={about}
followerCount={follows.follower_count}
followingCount={follows.following_count}
handleFollowUnfollowUser={handleFollowUnfollowUser}
handleMuteUnmuteUser={handleMuteUnmuteUser}
handleOnFavoritePress={handleOnFavoritePress}
handleOnFollowsPress={handleOnFollowsPress}
handleUIChange={this._handleUIChange}
hoursRC={Math.ceil((100 - resourceCredits) * 0.833333) || null}
hoursVP={Math.ceil((100 - votingPower) * 0.833333) || null}
intl={intl}
isDarkTheme={isDarkTheme}
isFavorite={isFavorite}
isFollowing={isFollowing}
isLoggedIn={isLoggedIn}
isMuted={isMuted}
isOwnProfile={isOwnProfile}
isProfileLoading={isProfileLoading}
percentRC={resourceCredits}
percentVP={votingPower}
handleOnPressProfileEdit={handleOnPressProfileEdit}
/>
</CollapsibleCard>
)}
<ScrollableTabView
style={[globalStyles.tabView, styles.tabView]}
initialPage={activePage}
renderTabBar={() => (
<TabBar style={styles.tabbar} tabUnderlineDefaultWidth={80} tabUnderlineScaleX={2} />
)}
onChangeTab={({ i }) => {
if (i !== 2) {
this.setState({
estimatedWalletValue: 0,
oldEstimatedWalletValue: estimatedWalletValue,
});
} else {
this.setState({ estimatedWalletValue: oldEstimatedWalletValue });
}
}}
>
<View
tabLabel={this._getTabLabel(intl.formatMessage({ id: 'profile.post' }))}
style={styles.postTabBar}
>
<TabbedPosts
filterOptions={PROFILE_FILTERS}
filterOptionsValue={PROFILE_FILTERS_VALUE}
selectedOptionIndex={0}
pageType="profiles"
getFor="blog"
feedUsername={username}
key={username}
handleOnScroll={isSummaryOpen ? this._handleOnScroll : null}
forceLoadPost={forceLoadPost}
changeForceLoadPostState={changeForceLoadPostState}
isFeedScreen={false}
/>
</View>
<View
tabLabel={
!isOwnProfile
? this._getTabLabel(intl.formatMessage({ id: 'profile.comments' }))
: this._getTabLabel(intl.formatMessage({ id: 'profile.replies' }))
}
style={styles.commentsTabBar}
>
{comments && comments.length > 0 ? (
<ScrollView
onScroll={({ nativeEvent }) => {
this._handleOnScroll();
if (this._isCloseToBottom(nativeEvent)) {
this._loadMoreComments();
}
}}
contentContainerStyle={styles.scrollContentContainer}
//scrollEventThrottle={16}
>
<Comments
isProfilePreview
comments={comments}
fetchPost={getReplies}
isOwnProfile={isOwnProfile}
isHideImage={isHideImage}
/>
</ScrollView>
) : (
<NoPost
name={username}
text={intl.formatMessage({
id: 'profile.havent_commented',
})}
defaultText={intl.formatMessage({
id: 'profile.login_to_see',
})}
/>
)}
</View>
{!isOwnProfile && (
<View
tabLabel={
estimatedWalletValue
? `${currencySymbol} ${(estimatedWalletValue * currencyRate).toFixed()}`
: intl.formatMessage({
id: 'profile.wallet',
})
}
>
{selectedUser ? (
<Wallet
setEstimatedWalletValue={(value) =>
this.setState({ estimatedWalletValue: value })
}
selectedUser={selectedUser}
handleOnScroll={isSummaryOpen ? this._handleOnScroll : null}
/>
) : (
<WalletDetailsPlaceHolder />
)}
</View>
)}
</ScrollableTabView>
{this._renderProfileContent()}
{this._renderTabs()}
</View>
</View>
);

View File

@ -16,6 +16,9 @@ export const TabbedPosts = ({
isFeedScreen,
feedUsername,
pageType,
tabContentOverrides,
stackedTabs,
onTabChange,
...props
}:TabbedPostsProps) => {
@ -25,7 +28,7 @@ export const TabbedPosts = ({
const isHideImages = useSelector((state) => state.ui.hidePostsThumbnails);
//initialize state
const [initialTabIndex] = useState(selectedOptionIndex == 0 && isFeedScreen ? filterOptions.length : selectedOptionIndex)
const [initialTabIndex] = useState(selectedOptionIndex == 0 && stackedTabs ? filterOptions.length : selectedOptionIndex)
const [mainFilters] = useState<TabItem[]>(
filterOptions.map((label, index)=>({
@ -56,7 +59,6 @@ export const TabbedPosts = ({
}else{
setSelectedFilter(filter)
}
}
const _toggleHideImagesFlag = () => {
@ -70,19 +72,23 @@ export const TabbedPosts = ({
//initialize first set of pages
const pages = combinedFilters.map((filter)=>(
<TabContent
key={filter.filterKey}
filterKey={filter.filterKey}
tabLabel={filter.label}
isFeedScreen={isFeedScreen}
feedUsername={feedUsername}
pageType={pageType}
filterScrollRequest={filterScrollRequest}
onScrollRequestProcessed={_onScrollRequestProcessed}
{...props}
/>
))
const pages = combinedFilters.map((filter, index)=>{
if(tabContentOverrides && tabContentOverrides.has(index)){
return tabContentOverrides.get(index);
}
return (
<TabContent
key={filter.filterKey}
filterKey={filter.filterKey}
isFeedScreen={isFeedScreen}
feedUsername={feedUsername}
pageType={pageType}
filterScrollRequest={filterScrollRequest}
onScrollRequestProcessed={_onScrollRequestProcessed}
{...props}
/>
)
});
//render tab bar
@ -90,7 +96,7 @@ export const TabbedPosts = ({
return (
<StackedTabBar
{...props}
shouldStack={isFeedScreen && feedUsername}
shouldStack={stackedTabs}
firstStack={mainFilters}
secondStack={subFilters}
initialFirstStackIndex={selectedOptionIndex}
@ -106,7 +112,9 @@ export const TabbedPosts = ({
scrollWithoutAnimation={true}
locked={true}
initialPage={initialTabIndex}
renderTabBar={_renderTabBar}>
renderTabBar={_renderTabBar}
onTabChange={onTabChange}
>
{pages}
</ScrollableTabView>
);

View File

@ -11,6 +11,9 @@ export interface TabbedPostsProps {
pageType:string,
tag:string,
forceLoadPosts:boolean,
tabContentOverrides:Map<number, any>,
stackedTabs:boolean,
onTabChange:(index:number)=>void
handleOnScroll:()=>void,
}
@ -44,7 +47,6 @@ export interface TabMeta {
export interface TabContentProps {
filterKey:string,
tabLabel:string,
isFeedScreen:boolean,
getFor:string,
pageType:string,

View File

@ -20,7 +20,6 @@ interface StackedTabBarProps {
}
export const StackedTabBar = ({
activeTab,
goToPage,
tabs,
shouldStack,
@ -39,9 +38,13 @@ export const StackedTabBar = ({
return (
<>
<FilterBar
options={firstStack.map((item) =>
intl.formatMessage({ id: `home.${item.label.toLowerCase()}` }).toUpperCase(),
)}
options={firstStack.map((item, index) => {
return tabs[index]
? tabs[index]
: intl.formatMessage({ id: item.label.toLowerCase() }).toUpperCase()
})
}
selectedOptionIndex={selectedFilterIndex}
rightIconName="view-module"
rightIconType="MaterialIcons"
@ -65,7 +68,7 @@ export const StackedTabBar = ({
selectedFilterIndex == 0 && shouldStack && (
<FilterBar
options={secondStack.map((item) =>
intl.formatMessage({ id: `home.${item.label.toLowerCase()}` }).toUpperCase(),
intl.formatMessage({ id: item.label.toLowerCase() }).toUpperCase(),
)}
selectedOptionIndex={selectedSecondStackIndex}
onDropdownSelect={(index)=>{

View File

@ -8,6 +8,7 @@ import { setInitPosts } from '../../../redux/actions/postsAction';
import NewPostsPopup from './newPostsPopup';
import { calculateTimeLeftForPostCheck } from '../services/tabbedPostsReducer';
import { AppState } from 'react-native';
import { PostsListRef } from '../../postsList/container/postsListContainer';
const TabContent = ({

View File

@ -243,7 +243,7 @@
"posts": "Posts",
"friends": "Friends",
"communities": "Communities",
"popup_postfix":"Posted"
"popup_postfix":"Posted",
},
"side_menu": {
"profile": "Profile",

View File

@ -1,14 +1,18 @@
export const POPULAR_FILTERS = ['FEED', 'TOP', 'HOT', 'NEW'];
export const POPULAR_FILTERS = ['home.FEED', 'home.TOP', 'home.HOT', 'home.NEW'];
export const POPULAR_FILTERS_VALUE = ['feed', 'trending', 'hot', 'created'];
export const FEED_SUBFILTERS = ['friends', 'communities'];
export const FEED_SUBFILTERS = ['home.friends', 'home.communities'];
export const FEED_SUBFILTERS_VALUE = ['friends', 'communities'];
export const GLOBAL_POST_FILTERS = ['TOP', 'HOT', 'NEW'];
export const GLOBAL_POST_FILTERS = ['home.TOP', 'home.HOT', 'home.NEW'];
export const GLOBAL_POST_FILTERS_VALUE = ['trending', 'hot', 'created'];
export const PROFILE_FILTERS = ['BLOG', 'POSTS'];
export const PROFILE_FILTERS_VALUE = ['blog', 'posts'];
export const PROFILE_FILTERS_OWN = ['profile.post', 'profile.replies'];
export const PROFILE_FILTERS = ['profile.post', 'profile.comments', 'profile.wallet'];
export const PROFILE_FILTERS_VALUE = ['feed', 'comments', 'wallet'];
export const PROFILE_SUBFILTERS = ['home.BLOG', 'home.POSTS'];
export const PROFILE_SUBFILTERS_VALUE = ['blog', 'posts'];
// 'TRENDING',
// 'HOT',

View File

@ -34,17 +34,8 @@ const FeedScreen = () => {
selectedOptionIndex={get(currentAccount, 'name', null) ? 0 : 2}
feedUsername={get(currentAccount, 'name', null)}
isFeedScreen={true}
stackedTabs={get(currentAccount, 'name', null)}
/>
{/* <Posts
filterOptions={[...POPULAR_FILTERS]}
filterOptionsValue={[...POPULAR_FILTERS_VALUE]}
feedSubfilterOptions={[...FEED_SUBFILTERS]}
feedSubfilterOptionsValue={[...FEED_SUBFILTERS_VALUE]}
getFor={get(currentAccount, 'name', null) ? 'feed' : 'hot'}
selectedOptionIndex={get(currentAccount, 'name', null) ? 0 : 2}
feedUsername={get(currentAccount, 'name', null)}
isFeedScreen={true}
/> */}
</SafeAreaView>
</Fragment>
)}