post view convert to the hook

This commit is contained in:
ue 2019-10-31 00:58:59 +03:00
parent 2acf206205
commit 88749046a8

View File

@ -1,7 +1,7 @@
/* eslint-disable react/jsx-wrap-multilines */ /* eslint-disable react/jsx-wrap-multilines */
import React, { Component, Fragment } from 'react'; import React, { useState, Fragment, useEffect, useCallback } from 'react';
import { FlatList, View, ActivityIndicator, RefreshControl } from 'react-native'; import { FlatList, View, ActivityIndicator, RefreshControl } from 'react-native';
import { injectIntl } from 'react-intl'; import { useIntl } from 'react-intl';
import { withNavigation } from 'react-navigation'; import { withNavigation } from 'react-navigation';
import { get, isEqual, unionWith } from 'lodash'; import { get, isEqual, unionWith } from 'lodash';
@ -19,78 +19,104 @@ import { ThemeContainer } from '../../../containers';
import styles from './postsStyles'; import styles from './postsStyles';
import { default as ROUTES } from '../../../constants/routeNames'; import { default as ROUTES } from '../../../constants/routeNames';
class PostsView extends Component { const PostsView = ({
constructor(props) { filterOptions,
super(props); selectedOptionIndex,
isHideImage,
this.state = { handleImagesHide,
posts: props.isConnected ? [] : props.feedPosts, feedPosts,
startAuthor: '', isConnected,
startPermlink: '', currentAccountUsername,
refreshing: false, getFor,
isLoading: false, tag,
isShowFilterBar: true, nsfw,
selectedFilterIndex: get(props, 'selectedOptionIndex', 0), setFeedPosts,
isNoPost: false, pageType,
promotedPosts: [], isLoginDone,
scrollOffsetY: 0, isLoggedIn,
lockFilterBar: false, handleOnScroll,
}; navigation,
} changeForceLoadPostState,
forceLoadPost,
async componentDidMount() { }) => {
const { isConnected, pageType } = this.props; const [posts, setPosts] = useState(isConnected ? [] : feedPosts);
const [startAuthor, setStartAuthor] = useState('');
const [startPermlink, setStartPermlink] = useState('');
const [refreshing, setRefreshing] = useState(false);
const [isLoading, setIsLoading] = useState(false);
const [isShowFilterBar, setIsShowFilterBar] = useState(true);
const [selectedFilterIndex, setSelectedFilterIndex] = useState(selectedOptionIndex || 0);
const [isNoPost, setIsNoPost] = useState(false);
const [promotedPosts, setPromotedPosts] = useState([]);
const [scrollOffsetY, setScrollOffsetY] = useState(0);
const intl = useIntl();
useEffect(() => {
if (isConnected) { if (isConnected) {
if (pageType !== 'profiles') { const fetchPromotePost = async () => {
await this._getPromotePosts(); if (pageType !== 'profiles') {
await _getPromotePosts();
}
};
fetchPromotePost();
_loadPosts();
setRefreshing(false);
setIsLoading(false);
}
}, [
_getPromotePosts,
_loadPosts,
changeForceLoadPostState,
currentAccountUsername,
forceLoadPost,
isConnected,
pageType,
selectedOptionIndex,
]);
useEffect(() => {
if (forceLoadPost) {
setPosts([]);
setStartAuthor('');
setStartPermlink('');
setRefreshing(false);
setIsLoading(false);
setSelectedFilterIndex(selectedOptionIndex || 0);
setIsNoPost(false);
_loadPosts();
if (changeForceLoadPostState) {
changeForceLoadPostState(false);
} }
this._loadPosts();
} else {
this.setState({
refreshing: false,
isLoading: false,
});
} }
} }, [
_loadPosts,
changeForceLoadPostState,
currentAccountUsername,
forceLoadPost,
selectedOptionIndex,
]);
UNSAFE_componentWillReceiveProps(nextProps) { useEffect(() => {
const { currentAccountUsername, changeForceLoadPostState } = this.props; if (!startAuthor && !startPermlink) {
_loadPosts(filterOptions[selectedFilterIndex].toLowerCase());
if (
(currentAccountUsername &&
currentAccountUsername !== nextProps.currentAccountUsername &&
nextProps.currentAccountUsername) ||
nextProps.forceLoadPost
) {
// Set all initial data (New user new rules)
this.setState(
{
posts: [],
startAuthor: '',
startPermlink: '',
refreshing: false,
isLoading: false,
selectedFilterIndex: get(nextProps, 'selectedOptionIndex', 0),
isNoPost: false,
},
() => {
this._loadPosts();
if (changeForceLoadPostState) {
changeForceLoadPostState(false);
}
},
);
} }
} }, [_loadPosts, filterOptions, selectedFilterIndex, startAuthor, startPermlink]);
_getPromotePosts = async () => { const _handleOnDropdownSelect = async index => {
const { currentAccountUsername } = this.props; setSelectedFilterIndex(index);
setPosts([]);
setStartPermlink('');
setStartAuthor('');
setIsNoPost(false);
};
const _getPromotePosts = useCallback(async () => {
await getPromotePosts() await getPromotePosts()
.then(async res => { .then(async res => {
if (res && res.length) { if (res && res.length) {
const promotedPosts = await Promise.all( const _promotedPosts = await Promise.all(
res.map(item => res.map(item =>
getPost( getPost(
get(item, 'author'), get(item, 'author'),
@ -101,165 +127,146 @@ class PostsView extends Component {
), ),
); );
this.setState({ promotedPosts }); setPromotedPosts(_promotedPosts);
} }
}) })
.catch(() => {}); .catch(() => {});
}; }, [currentAccountUsername]);
_loadPosts = async () => { const _loadPosts = useCallback(
const { async type => {
getFor, const filter =
tag, type ||
currentAccountUsername, (filterOptions &&
nsfw, filterOptions.length > 0 &&
setFeedPosts, filterOptions[selectedFilterIndex].toLowerCase());
isConnected, let options;
filterOptions, const limit = 3;
} = this.props;
const {
posts,
startAuthor,
startPermlink,
refreshing,
selectedFilterIndex,
isLoading,
promotedPosts,
} = this.state;
const filter = filterOptions[selectedFilterIndex].toLowerCase();
let options;
const limit = 3;
if (!isConnected) { if (!isConnected) {
this.setState({ setRefreshing(false);
refreshing: false, setIsLoading(false);
isLoading: false, return null;
}); }
return null;
}
if (isLoading) { // if (isLoading) {
return null; // return null;
} // }
this.setState({ isLoading: true }); setIsLoading(true);
if (filter === 'feed' || filter === 'blog' || getFor === 'blog' || filter === 'reblogs') { if (filter === 'feed' || filter === 'blog' || getFor === 'blog' || filter === 'reblogs') {
options = { options = {
tag, tag,
limit, limit,
}; };
} else { } else {
options = { options = {
limit, limit,
}; };
} }
if (startAuthor && startPermlink && !refreshing) { if (startAuthor && startPermlink && !refreshing) {
options.start_author = startAuthor; options.start_author = startAuthor;
options.start_permlink = startPermlink; options.start_permlink = startPermlink;
} }
getPostsSummary(filter, options, currentAccountUsername, nsfw) getPostsSummary(filter, options, currentAccountUsername, nsfw)
.then(result => { .then(result => {
if (result.length > 0) { if (result.length > 0) {
let _posts = result; let _posts = result;
if (filter === 'reblogs') { if (filter === 'reblogs') {
for (let i = _posts.length - 1; i >= 0; i--) { for (let i = _posts.length - 1; i >= 0; i--) {
if (_posts[i].author === currentAccountUsername) { if (_posts[i].author === currentAccountUsername) {
_posts.splice(i, 1); _posts.splice(i, 1);
}
} }
} }
} if (_posts.length > 0) {
if (_posts.length > 0) { if (posts.length > 0) {
if (posts.length > 0) { if (refreshing) {
if (refreshing) { _posts = unionWith(_posts, posts, isEqual);
_posts = unionWith(_posts, posts, isEqual); } else {
} else { _posts.shift();
_posts.shift(); _posts = [...posts, ..._posts];
_posts = [...posts, ..._posts]; }
}
}
if (posts.length < 5) {
setFeedPosts(_posts);
}
// Promoted post start
if (promotedPosts && promotedPosts.length > 0) {
const insert = (arr, index, newItem) => [
...arr.slice(0, index),
newItem,
...arr.slice(index),
];
if (refreshing) {
_posts = _posts.filter(item => !item.is_promoted);
} }
_posts.map((d, i) => { if (posts.length < 5) {
if ([3, 6, 9].includes(i)) { setFeedPosts(_posts);
const ix = i / 3 - 1; }
if (promotedPosts[ix] !== undefined) {
if (get(_posts, [i], {}).permlink !== promotedPosts[ix].permlink) { // Promoted post start
_posts = insert(_posts, i, promotedPosts[ix]); if (promotedPosts && promotedPosts.length > 0) {
const insert = (arr, index, newItem) => [
...arr.slice(0, index),
newItem,
...arr.slice(index),
];
if (refreshing) {
_posts = _posts.filter(item => !item.is_promoted);
}
_posts.map((d, i) => {
if ([3, 6, 9].includes(i)) {
const ix = i / 3 - 1;
if (promotedPosts[ix] !== undefined) {
if (get(_posts, [i], {}).permlink !== promotedPosts[ix].permlink) {
_posts = insert(_posts, i, promotedPosts[ix]);
}
} }
} }
} });
}); }
} // Promoted post end
// Promoted post end
if (refreshing) { if (refreshing) {
this.setState({ } else if (!refreshing) {
posts: _posts, setStartAuthor(result[result.length - 1] && result[result.length - 1].author);
}); setStartPermlink(result[result.length - 1] && result[result.length - 1].permlink);
} else if (!refreshing) { }
this.setState({ setPosts(_posts);
posts: _posts, setRefreshing(false);
startAuthor: result[result.length - 1] && result[result.length - 1].author, setIsLoading(false);
startPermlink: result[result.length - 1] && result[result.length - 1].permlink,
});
} }
} else if (result.length === 0) {
this.setState({ setIsNoPost(true);
refreshing: false,
isLoading: false,
});
} }
} else if (result.length === 0) { })
this.setState({ isNoPost: true }); .catch(() => {
} setRefreshing(false);
})
.catch(() => {
this.setState({
refreshing: false,
}); });
}); },
[
currentAccountUsername,
filterOptions,
getFor,
isConnected,
nsfw,
posts,
promotedPosts,
refreshing,
selectedFilterIndex,
setFeedPosts,
startAuthor,
startPermlink,
tag,
],
);
const _handleOnRefreshPosts = async () => {
setRefreshing(true);
if (pageType !== 'profiles') {
await _getPromotePosts();
}
_loadPosts();
}; };
_handleOnRefreshPosts = () => { const _renderFooter = () => {
const { pageType } = this.props;
this.setState(
{
refreshing: true,
},
async () => {
if (pageType !== 'profiles') {
await this._getPromotePosts();
}
this._loadPosts();
},
);
};
_renderFooter = () => {
const { isLoading } = this.state;
if (isLoading) { if (isLoading) {
return ( return (
<View style={styles.flatlistFooter}> <View style={styles.flatlistFooter}>
@ -267,29 +274,15 @@ class PostsView extends Component {
</View> </View>
); );
} }
return null; return null;
}; };
_handleOnDropdownSelect = async index => { const _handleOnPressLogin = () => {
await this.setState({
selectedFilterIndex: index,
posts: [],
startAuthor: '',
startPermlink: '',
isNoPost: false,
});
this._loadPosts();
};
_handleOnPressLogin = () => {
const { navigation } = this.props;
navigation.navigate(ROUTES.SCREENS.LOGIN); navigation.navigate(ROUTES.SCREENS.LOGIN);
}; };
_renderEmptyContent = () => { const _renderEmptyContent = () => {
const { intl, getFor, isLoginDone, isLoggedIn, tag } = this.props;
const { isNoPost } = this.state;
if (getFor === 'feed' && isLoginDone && !isLoggedIn) { if (getFor === 'feed' && isLoginDone && !isLoggedIn) {
return ( return (
<NoPost <NoPost
@ -298,7 +291,7 @@ class PostsView extends Component {
defaultText={intl.formatMessage({ defaultText={intl.formatMessage({
id: 'profile.login_to_see', id: 'profile.login_to_see',
})} })}
handleOnButtonPress={this._handleOnPressLogin} handleOnButtonPress={_handleOnPressLogin}
/> />
); );
} }
@ -326,73 +319,67 @@ class PostsView extends Component {
); );
}; };
_handleOnScroll = event => { const _handleOnScroll = event => {
const { scrollOffsetY } = this.state;
const { handleOnScroll } = this.props;
const currentOffset = event.nativeEvent.contentOffset.y; const currentOffset = event.nativeEvent.contentOffset.y;
if (handleOnScroll) { if (handleOnScroll) {
handleOnScroll(); handleOnScroll();
} }
this.setState({ scrollOffsetY: currentOffset });
this.setState({ isShowFilterBar: scrollOffsetY > currentOffset || scrollOffsetY <= 0 }); setScrollOffsetY(currentOffset);
setIsShowFilterBar(scrollOffsetY > currentOffset || scrollOffsetY <= 0);
}; };
render() { return (
const { refreshing, posts, isShowFilterBar } = this.state; <View style={styles.container}>
const { filterOptions, selectedOptionIndex, isHideImage, handleImagesHide } = this.props; {filterOptions && isShowFilterBar && (
<FilterBar
return ( dropdownIconName="arrow-drop-down"
<View style={styles.container}> options={filterOptions}
{filterOptions && isShowFilterBar && ( selectedOptionIndex={selectedOptionIndex}
<FilterBar defaultText={filterOptions[selectedOptionIndex]}
dropdownIconName="arrow-drop-down" rightIconName="view-module"
options={filterOptions} rightIconType="MaterialIcons"
selectedOptionIndex={selectedOptionIndex} onDropdownSelect={_handleOnDropdownSelect}
defaultText={filterOptions[selectedOptionIndex]} onRightIconPress={handleImagesHide}
rightIconName="view-module"
rightIconType="MaterialIcons"
onDropdownSelect={this._handleOnDropdownSelect}
onRightIconPress={handleImagesHide}
/>
)}
<FlatList
data={posts}
showsVerticalScrollIndicator={false}
renderItem={({ item }) =>
get(item, 'author', null) && (
<PostCard isRefresh={refreshing} content={item} isHideImage={isHideImage} />
)
}
keyExtractor={(content, i) => `${get(content, 'permlink', '')}${i.toString()}`}
onEndReached={() => this._loadPosts()}
removeClippedSubviews
refreshing={refreshing}
onRefresh={() => this._handleOnRefreshPosts()}
onEndThreshold={0}
initialNumToRender={10}
ListFooterComponent={this._renderFooter}
onScrollEndDrag={this._handleOnScroll}
ListEmptyComponent={this._renderEmptyContent}
refreshControl={
<ThemeContainer>
{({ isDarkTheme }) => (
<RefreshControl
refreshing={refreshing}
onRefresh={this._handleOnRefreshPosts}
progressBackgroundColor="#357CE6"
tintColor={!isDarkTheme ? '#357ce6' : '#96c0ff'}
titleColor="#fff"
colors={['#fff']}
/>
)}
</ThemeContainer>
}
/> />
</View> )}
);
}
}
export default withNavigation(injectIntl(PostsView)); <FlatList
data={posts}
showsVerticalScrollIndicator={false}
renderItem={({ item }) =>
get(item, 'author', null) && (
<PostCard isRefresh={refreshing} content={item} isHideImage={isHideImage} />
)
}
keyExtractor={(content, i) => `${get(content, 'permlink', '')}${i.toString()}`}
onEndReached={() => _loadPosts()}
removeClippedSubviews
refreshing={refreshing}
onRefresh={_handleOnRefreshPosts}
onEndThreshold={0}
initialNumToRender={10}
ListFooterComponent={_renderFooter}
onScrollEndDrag={_handleOnScroll}
ListEmptyComponent={_renderEmptyContent}
refreshControl={
<ThemeContainer>
{({ isDarkTheme }) => (
<RefreshControl
refreshing={refreshing}
onRefresh={_handleOnRefreshPosts}
progressBackgroundColor="#357CE6"
tintColor={!isDarkTheme ? '#357ce6' : '#96c0ff'}
titleColor="#fff"
colors={['#fff']}
/>
)}
</ThemeContainer>
}
/>
</View>
);
};
export default withNavigation(PostsView);