implemented a profile children to handle comments / replies fetch and rendering

This commit is contained in:
Nouman Tahir 2021-05-19 13:28:46 +05:00
parent 2f70b6317d
commit ac30f9faef
7 changed files with 181 additions and 54 deletions

View File

@ -25,7 +25,6 @@ const CommentsContainer = ({
isOwnProfile, isOwnProfile,
fetchPost, fetchPost,
navigation, navigation,
content,
currentAccount, currentAccount,
pinCode, pinCode,
comments, comments,
@ -42,6 +41,7 @@ const CommentsContainer = ({
hasManyComments, hasManyComments,
showAllComments, showAllComments,
hideManyCommentsButton, hideManyCommentsButton,
flatListProps,
}) => { }) => {
const [lcomments, setLComments] = useState([]); const [lcomments, setLComments] = useState([]);
const [selectedPermlink, setSelectedPermlink] = useState(''); const [selectedPermlink, setSelectedPermlink] = useState('');
@ -252,6 +252,7 @@ const CommentsContainer = ({
handleOnVotersPress={_handleOnVotersPress} handleOnVotersPress={_handleOnVotersPress}
isShowSubComments={isShowSubComments} isShowSubComments={isShowSubComments}
showAllComments={showAllComments} showAllComments={showAllComments}
flatListProps={flatListProps}
/> />
); );
}; };

View File

@ -37,6 +37,9 @@ const CommentsView = ({
isShowMoreButton, isShowMoreButton,
showAllComments, showAllComments,
hideManyCommentsButton, hideManyCommentsButton,
onScroll,
onEndReached,
flatListProps,
}) => { }) => {
const [selectedComment, setSelectedComment] = useState(null); const [selectedComment, setSelectedComment] = useState(null);
const intl = useIntl(); const intl = useIntl();
@ -107,6 +110,7 @@ const CommentsView = ({
data={comments} data={comments}
renderItem={_renderItem} renderItem={_renderItem}
keyExtractor={(item) => get(item, 'permlink')} keyExtractor={(item) => get(item, 'permlink')}
{...flatListProps}
/> />
<ActionSheet <ActionSheet
ref={commentMenu} ref={commentMenu}

View File

@ -0,0 +1,132 @@
import React, {useEffect, useState} from 'react';
import { useIntl } from 'react-intl';
import {ActivityIndicator, RefreshControl, View } from 'react-native';
import { Comments, NoPost } from '../..';
import { useAppSelector } from '../../../hooks';
import { getAccountPosts } from '../../../providers/hive/dhive';
import styles from '../profileStyles';
import Matomo from 'react-native-matomo-sdk';
import {unionBy } from 'lodash';
interface CommentsTabContentProps {
username:string,
type:'comments'|'replies',
isOwnProfile:boolean,
selectedUser:any,
onScroll:()=>void,
}
const CommentsTabContent = ({isOwnProfile, username, type, onScroll, selectedUser }: CommentsTabContentProps) => {
const intl = useIntl();
const isHideImage = useAppSelector(state => state.ui.hidePostsThumbnails);
const isAnalytics = useAppSelector(state => state.application.isAnalytics);
const [data, setData] = useState([]);
const [lastAuthor, setLastAuthor] = useState('');
const [lastPermlink, setLastPermlink] = useState('');
const [loading, setLoading] = useState(false);
const [noMore, setNoMore] = useState(false);
useEffect(() => {
if(selectedUser){
_fetchData();
}
}, [selectedUser])
const _fetchData = async () => {
if(loading || noMore){
return;
}
setLoading(true);
const query:any = {
account:username,
start_author: lastAuthor,
start_permlink: lastPermlink,
limit:10,
observer:'',
sort:type
};
if (isAnalytics && selectedUser.user) {
Matomo.trackView([`/@${selectedUser.name}/${type}`]).catch((error) =>
console.warn('Failed to track screen', error),
);
}
const result = await getAccountPosts(query)
let _comments:any[] = unionBy(data, result, 'permlink');
if(Array.isArray(_comments)){
setData(_comments);
if(_comments.length > 0){
setLastAuthor(_comments[_comments.lastIndex].author)
setLastPermlink(_comments[_comments.lastIndex].permlink)
}
if(result.length == 0){
setNoMore(true);
}
}else{
setData([]);
setNoMore(true);
}
setLoading(false);
}
const _renderListEmpty = () => {
if(loading){
return null
}
return (
<NoPost
name={username}
text={intl.formatMessage({
id: 'profile.havent_commented',
})}
defaultText={intl.formatMessage({
id: 'profile.login_to_see',
})}
/>
)
}
const _renderListFooter = () => {
return (
<View style={styles.commentsListFooter}>
{loading && (
<ActivityIndicator size='large'/>
)}
</View>
)
}
return (
<View key="profile.comments" style={styles.commentsTabBar}>
<Comments
comments={data}
fetchPost={()=>{}}
isOwnProfile={isOwnProfile}
isHideImage={isHideImage}
flatListProps={{
onEndReached:_fetchData,
onScroll:onScroll,
ListEmptyComponent:_renderListEmpty,
ListFooterComponent:_renderListFooter,
onEndReachedThreshold:1
}}
/>
</View>
);
};
export default CommentsTabContent;

View File

@ -58,9 +58,12 @@ export default EStyleSheet.create({
commentsTabBar: { commentsTabBar: {
backgroundColor: '$primaryBackgroundColor', backgroundColor: '$primaryBackgroundColor',
paddingHorizontal: 16, paddingHorizontal: 16,
paddingVertical: 5, paddingTop: 5,
}, },
scrollContentContainer: { scrollContentContainer: {
paddingBottom: 60, paddingBottom: 60,
}, },
commentsListFooter: {
padding: 32,
},
}); });

View File

@ -2,6 +2,7 @@ import React, { PureComponent } from 'react';
import { View, ScrollView } from 'react-native'; import { View, ScrollView } from 'react-native';
import { injectIntl } from 'react-intl'; import { injectIntl } from 'react-intl';
import get from 'lodash/get'; import get from 'lodash/get';
import { connect } from 'react-redux';
// Components // Components
import { CollapsibleCard } from '../collapsibleCard'; import { CollapsibleCard } from '../collapsibleCard';
@ -12,11 +13,7 @@ import { ProfileSummary } from '../profileSummary';
import { Wallet } from '../wallet'; import { Wallet } from '../wallet';
// Constants // Constants
import { import { getDefaultFilters, getFilterMap } from '../../constants/options/filters';
PROFILE_FILTERS,
PROFILE_FILTERS_OWN,
PROFILE_FILTERS_VALUE,
} from '../../constants/options/filters';
// Utils // Utils
import { getFormatedCreatedDate } from '../../utils/time'; import { getFormatedCreatedDate } from '../../utils/time';
@ -25,6 +22,7 @@ import { getFormatedCreatedDate } from '../../utils/time';
import styles from './profileStyles'; import styles from './profileStyles';
import { TabbedPosts } from '../tabbedPosts'; import { TabbedPosts } from '../tabbedPosts';
import CommentsTabContent from './children/commentsTabContent';
class ProfileView extends PureComponent { class ProfileView extends PureComponent {
constructor(props) { constructor(props) {
@ -155,42 +153,16 @@ class ProfileView extends PureComponent {
); );
}; };
_contentComentsTab = () => { _contentComentsTab = (type) => {
const { comments, getReplies, intl, isOwnProfile, username, isHideImage } = this.props; const { username, isOwnProfile, selectedUser } = this.props;
return ( return (
<View key="profile.comments" style={styles.commentsTabBar}> <CommentsTabContent
{comments && comments.length > 0 ? ( username={username}
<ScrollView selectedUser={selectedUser}
onScroll={({ nativeEvent }) => {
this._handleOnScroll();
if (this._isCloseToBottom(nativeEvent)) {
this._loadMoreComments();
}
}}
contentContainerStyle={styles.scrollContentContainer}
//scrollEventThrottle={16}
>
<Comments
isProfilePreview
comments={comments}
fetchPost={getReplies}
isOwnProfile={isOwnProfile} isOwnProfile={isOwnProfile}
isHideImage={isHideImage} type={type}
onScroll={this._handleOnScroll}
/> />
</ScrollView>
) : (
<NoPost
name={username}
text={intl.formatMessage({
id: 'profile.havent_commented',
})}
defaultText={intl.formatMessage({
id: 'profile.login_to_see',
})}
/>
)}
</View>
); );
}; };
@ -221,26 +193,36 @@ class ProfileView extends PureComponent {
}; };
_renderTabs = () => { _renderTabs = () => {
const { changeForceLoadPostState, forceLoadPost, username, isOwnProfile } = this.props; const {
changeForceLoadPostState,
forceLoadPost,
username,
isOwnProfile,
profileTabs,
ownProfileTabs,
} = this.props;
const { isSummaryOpen } = this.state; const { isSummaryOpen } = this.state;
const filterOptions = isOwnProfile ? PROFILE_FILTERS_OWN : PROFILE_FILTERS; const pageType = isOwnProfile ? 'ownProfile' : 'profile';
const tabs = (isOwnProfile ? ownProfileTabs : profileTabs) || getDefaultFilters(pageType);
const filterOptions = tabs.map((key) => getFilterMap(pageType)[key]);
//compile content overrides //compile content overrides
const tabContentOverrides = new Map(); const tabContentOverrides = new Map();
tabContentOverrides.set(2, this._contentComentsTab());
if (!isOwnProfile) { tabContentOverrides.set(tabs.indexOf('replies'), this._contentComentsTab('replies'));
tabContentOverrides.set(3, this._contentWalletTab()); tabContentOverrides.set(tabs.indexOf('comments'), this._contentComentsTab('comments'));
} tabContentOverrides.set(tabs.indexOf('wallet'), this._contentWalletTab());
return ( return (
<View style={styles.postTabBar}> <View style={styles.postTabBar}>
<TabbedPosts <TabbedPosts
filterOptions={filterOptions} filterOptions={filterOptions}
filterOptionsValue={PROFILE_FILTERS_VALUE} filterOptionsValue={tabs}
selectedOptionIndex={0} selectedOptionIndex={0}
pageType={isOwnProfile ? 'ownProfile' : 'profile'} pageType={pageType}
getFor="blog" getFor="blog"
feedUsername={username} feedUsername={username}
key={username} key={username}
@ -250,7 +232,6 @@ class ProfileView extends PureComponent {
isFeedScreen={false} isFeedScreen={false}
tabContentOverrides={tabContentOverrides} tabContentOverrides={tabContentOverrides}
onChangeTab={this._onTabChange} onChangeTab={this._onTabChange}
imagesToggleEnabled={true}
/> />
</View> </View>
); );
@ -280,4 +261,9 @@ class ProfileView extends PureComponent {
} }
} }
export default injectIntl(ProfileView); const mapStateToProps = (state) => ({
profileTabs: state.customTabs.profileTabs,
ownProfileTabs: state.customTabs.ownProfileTabs,
});
export default injectIntl(connect(mapStateToProps)(ProfileView));

View File

@ -131,7 +131,6 @@ class ProfileContainer extends Component {
} }
} }
if (query) { if (query) {
delete query.author; delete query.author;
delete query.permlink; delete query.permlink;

View File

@ -20,7 +20,9 @@ const CommunityScreen = ({ navigation }) => {
const intl = useIntl(); const intl = useIntl();
const communityTabs = useAppSelector((state) => state.customTabs.communityTabs || getDefaultFilters('community')); const communityTabs = useAppSelector(
(state) => state.customTabs.communityTabs || getDefaultFilters('community'),
);
const filterOptions = communityTabs.map((key) => getFilterMap('community')[key]); const filterOptions = communityTabs.map((key) => getFilterMap('community')[key]);
const _getSelectedIndex = () => { const _getSelectedIndex = () => {