mirror of
https://github.com/ecency/ecency-mobile.git
synced 2024-12-18 10:52:16 +03:00
post view convert to the hook
This commit is contained in:
parent
2acf206205
commit
88749046a8
@ -1,7 +1,7 @@
|
||||
/* 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 { injectIntl } from 'react-intl';
|
||||
import { useIntl } from 'react-intl';
|
||||
import { withNavigation } from 'react-navigation';
|
||||
import { get, isEqual, unionWith } from 'lodash';
|
||||
|
||||
@ -19,78 +19,104 @@ import { ThemeContainer } from '../../../containers';
|
||||
import styles from './postsStyles';
|
||||
import { default as ROUTES } from '../../../constants/routeNames';
|
||||
|
||||
class PostsView extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
posts: props.isConnected ? [] : props.feedPosts,
|
||||
startAuthor: '',
|
||||
startPermlink: '',
|
||||
refreshing: false,
|
||||
isLoading: false,
|
||||
isShowFilterBar: true,
|
||||
selectedFilterIndex: get(props, 'selectedOptionIndex', 0),
|
||||
isNoPost: false,
|
||||
promotedPosts: [],
|
||||
scrollOffsetY: 0,
|
||||
lockFilterBar: false,
|
||||
};
|
||||
}
|
||||
|
||||
async componentDidMount() {
|
||||
const { isConnected, pageType } = this.props;
|
||||
const PostsView = ({
|
||||
filterOptions,
|
||||
selectedOptionIndex,
|
||||
isHideImage,
|
||||
handleImagesHide,
|
||||
feedPosts,
|
||||
isConnected,
|
||||
currentAccountUsername,
|
||||
getFor,
|
||||
tag,
|
||||
nsfw,
|
||||
setFeedPosts,
|
||||
pageType,
|
||||
isLoginDone,
|
||||
isLoggedIn,
|
||||
handleOnScroll,
|
||||
navigation,
|
||||
changeForceLoadPostState,
|
||||
forceLoadPost,
|
||||
}) => {
|
||||
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 (pageType !== 'profiles') {
|
||||
await this._getPromotePosts();
|
||||
const fetchPromotePost = async () => {
|
||||
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) {
|
||||
const { currentAccountUsername, changeForceLoadPostState } = this.props;
|
||||
|
||||
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);
|
||||
}
|
||||
},
|
||||
);
|
||||
useEffect(() => {
|
||||
if (!startAuthor && !startPermlink) {
|
||||
_loadPosts(filterOptions[selectedFilterIndex].toLowerCase());
|
||||
}
|
||||
}
|
||||
}, [_loadPosts, filterOptions, selectedFilterIndex, startAuthor, startPermlink]);
|
||||
|
||||
_getPromotePosts = async () => {
|
||||
const { currentAccountUsername } = this.props;
|
||||
const _handleOnDropdownSelect = async index => {
|
||||
setSelectedFilterIndex(index);
|
||||
setPosts([]);
|
||||
setStartPermlink('');
|
||||
setStartAuthor('');
|
||||
setIsNoPost(false);
|
||||
};
|
||||
|
||||
const _getPromotePosts = useCallback(async () => {
|
||||
await getPromotePosts()
|
||||
.then(async res => {
|
||||
if (res && res.length) {
|
||||
const promotedPosts = await Promise.all(
|
||||
const _promotedPosts = await Promise.all(
|
||||
res.map(item =>
|
||||
getPost(
|
||||
get(item, 'author'),
|
||||
@ -101,165 +127,146 @@ class PostsView extends Component {
|
||||
),
|
||||
);
|
||||
|
||||
this.setState({ promotedPosts });
|
||||
setPromotedPosts(_promotedPosts);
|
||||
}
|
||||
})
|
||||
.catch(() => {});
|
||||
};
|
||||
}, [currentAccountUsername]);
|
||||
|
||||
_loadPosts = async () => {
|
||||
const {
|
||||
getFor,
|
||||
tag,
|
||||
currentAccountUsername,
|
||||
nsfw,
|
||||
setFeedPosts,
|
||||
isConnected,
|
||||
filterOptions,
|
||||
} = this.props;
|
||||
const {
|
||||
posts,
|
||||
startAuthor,
|
||||
startPermlink,
|
||||
refreshing,
|
||||
selectedFilterIndex,
|
||||
isLoading,
|
||||
promotedPosts,
|
||||
} = this.state;
|
||||
const filter = filterOptions[selectedFilterIndex].toLowerCase();
|
||||
let options;
|
||||
const limit = 3;
|
||||
const _loadPosts = useCallback(
|
||||
async type => {
|
||||
const filter =
|
||||
type ||
|
||||
(filterOptions &&
|
||||
filterOptions.length > 0 &&
|
||||
filterOptions[selectedFilterIndex].toLowerCase());
|
||||
let options;
|
||||
const limit = 3;
|
||||
|
||||
if (!isConnected) {
|
||||
this.setState({
|
||||
refreshing: false,
|
||||
isLoading: false,
|
||||
});
|
||||
return null;
|
||||
}
|
||||
if (!isConnected) {
|
||||
setRefreshing(false);
|
||||
setIsLoading(false);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (isLoading) {
|
||||
return null;
|
||||
}
|
||||
// if (isLoading) {
|
||||
// return null;
|
||||
// }
|
||||
|
||||
this.setState({ isLoading: true });
|
||||
if (filter === 'feed' || filter === 'blog' || getFor === 'blog' || filter === 'reblogs') {
|
||||
options = {
|
||||
tag,
|
||||
limit,
|
||||
};
|
||||
} else {
|
||||
options = {
|
||||
limit,
|
||||
};
|
||||
}
|
||||
setIsLoading(true);
|
||||
if (filter === 'feed' || filter === 'blog' || getFor === 'blog' || filter === 'reblogs') {
|
||||
options = {
|
||||
tag,
|
||||
limit,
|
||||
};
|
||||
} else {
|
||||
options = {
|
||||
limit,
|
||||
};
|
||||
}
|
||||
|
||||
if (startAuthor && startPermlink && !refreshing) {
|
||||
options.start_author = startAuthor;
|
||||
options.start_permlink = startPermlink;
|
||||
}
|
||||
if (startAuthor && startPermlink && !refreshing) {
|
||||
options.start_author = startAuthor;
|
||||
options.start_permlink = startPermlink;
|
||||
}
|
||||
|
||||
getPostsSummary(filter, options, currentAccountUsername, nsfw)
|
||||
.then(result => {
|
||||
if (result.length > 0) {
|
||||
let _posts = result;
|
||||
getPostsSummary(filter, options, currentAccountUsername, nsfw)
|
||||
.then(result => {
|
||||
if (result.length > 0) {
|
||||
let _posts = result;
|
||||
|
||||
if (filter === 'reblogs') {
|
||||
for (let i = _posts.length - 1; i >= 0; i--) {
|
||||
if (_posts[i].author === currentAccountUsername) {
|
||||
_posts.splice(i, 1);
|
||||
if (filter === 'reblogs') {
|
||||
for (let i = _posts.length - 1; i >= 0; i--) {
|
||||
if (_posts[i].author === currentAccountUsername) {
|
||||
_posts.splice(i, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (_posts.length > 0) {
|
||||
if (posts.length > 0) {
|
||||
if (refreshing) {
|
||||
_posts = unionWith(_posts, posts, isEqual);
|
||||
} else {
|
||||
_posts.shift();
|
||||
_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);
|
||||
if (_posts.length > 0) {
|
||||
if (posts.length > 0) {
|
||||
if (refreshing) {
|
||||
_posts = unionWith(_posts, posts, isEqual);
|
||||
} else {
|
||||
_posts.shift();
|
||||
_posts = [...posts, ..._posts];
|
||||
}
|
||||
}
|
||||
|
||||
_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]);
|
||||
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 ([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) {
|
||||
this.setState({
|
||||
posts: _posts,
|
||||
});
|
||||
} else if (!refreshing) {
|
||||
this.setState({
|
||||
posts: _posts,
|
||||
startAuthor: result[result.length - 1] && result[result.length - 1].author,
|
||||
startPermlink: result[result.length - 1] && result[result.length - 1].permlink,
|
||||
});
|
||||
if (refreshing) {
|
||||
} else if (!refreshing) {
|
||||
setStartAuthor(result[result.length - 1] && result[result.length - 1].author);
|
||||
setStartPermlink(result[result.length - 1] && result[result.length - 1].permlink);
|
||||
}
|
||||
setPosts(_posts);
|
||||
setRefreshing(false);
|
||||
setIsLoading(false);
|
||||
}
|
||||
|
||||
this.setState({
|
||||
refreshing: false,
|
||||
isLoading: false,
|
||||
});
|
||||
} else if (result.length === 0) {
|
||||
setIsNoPost(true);
|
||||
}
|
||||
} else if (result.length === 0) {
|
||||
this.setState({ isNoPost: true });
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
this.setState({
|
||||
refreshing: false,
|
||||
})
|
||||
.catch(() => {
|
||||
setRefreshing(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 { pageType } = this.props;
|
||||
|
||||
this.setState(
|
||||
{
|
||||
refreshing: true,
|
||||
},
|
||||
async () => {
|
||||
if (pageType !== 'profiles') {
|
||||
await this._getPromotePosts();
|
||||
}
|
||||
|
||||
this._loadPosts();
|
||||
},
|
||||
);
|
||||
};
|
||||
|
||||
_renderFooter = () => {
|
||||
const { isLoading } = this.state;
|
||||
|
||||
const _renderFooter = () => {
|
||||
if (isLoading) {
|
||||
return (
|
||||
<View style={styles.flatlistFooter}>
|
||||
@ -267,29 +274,15 @@ class PostsView extends Component {
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
_handleOnDropdownSelect = async index => {
|
||||
await this.setState({
|
||||
selectedFilterIndex: index,
|
||||
posts: [],
|
||||
startAuthor: '',
|
||||
startPermlink: '',
|
||||
isNoPost: false,
|
||||
});
|
||||
this._loadPosts();
|
||||
};
|
||||
|
||||
_handleOnPressLogin = () => {
|
||||
const { navigation } = this.props;
|
||||
const _handleOnPressLogin = () => {
|
||||
navigation.navigate(ROUTES.SCREENS.LOGIN);
|
||||
};
|
||||
|
||||
_renderEmptyContent = () => {
|
||||
const { intl, getFor, isLoginDone, isLoggedIn, tag } = this.props;
|
||||
const { isNoPost } = this.state;
|
||||
|
||||
const _renderEmptyContent = () => {
|
||||
if (getFor === 'feed' && isLoginDone && !isLoggedIn) {
|
||||
return (
|
||||
<NoPost
|
||||
@ -298,7 +291,7 @@ class PostsView extends Component {
|
||||
defaultText={intl.formatMessage({
|
||||
id: 'profile.login_to_see',
|
||||
})}
|
||||
handleOnButtonPress={this._handleOnPressLogin}
|
||||
handleOnButtonPress={_handleOnPressLogin}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@ -326,73 +319,67 @@ class PostsView extends Component {
|
||||
);
|
||||
};
|
||||
|
||||
_handleOnScroll = event => {
|
||||
const { scrollOffsetY } = this.state;
|
||||
const { handleOnScroll } = this.props;
|
||||
const _handleOnScroll = event => {
|
||||
const currentOffset = event.nativeEvent.contentOffset.y;
|
||||
|
||||
if (handleOnScroll) {
|
||||
handleOnScroll();
|
||||
}
|
||||
this.setState({ scrollOffsetY: currentOffset });
|
||||
this.setState({ isShowFilterBar: scrollOffsetY > currentOffset || scrollOffsetY <= 0 });
|
||||
|
||||
setScrollOffsetY(currentOffset);
|
||||
setIsShowFilterBar(scrollOffsetY > currentOffset || scrollOffsetY <= 0);
|
||||
};
|
||||
|
||||
render() {
|
||||
const { refreshing, posts, isShowFilterBar } = this.state;
|
||||
const { filterOptions, selectedOptionIndex, isHideImage, handleImagesHide } = this.props;
|
||||
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
{filterOptions && isShowFilterBar && (
|
||||
<FilterBar
|
||||
dropdownIconName="arrow-drop-down"
|
||||
options={filterOptions}
|
||||
selectedOptionIndex={selectedOptionIndex}
|
||||
defaultText={filterOptions[selectedOptionIndex]}
|
||||
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>
|
||||
}
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
{filterOptions && isShowFilterBar && (
|
||||
<FilterBar
|
||||
dropdownIconName="arrow-drop-down"
|
||||
options={filterOptions}
|
||||
selectedOptionIndex={selectedOptionIndex}
|
||||
defaultText={filterOptions[selectedOptionIndex]}
|
||||
rightIconName="view-module"
|
||||
rightIconType="MaterialIcons"
|
||||
onDropdownSelect={_handleOnDropdownSelect}
|
||||
onRightIconPress={handleImagesHide}
|
||||
/>
|
||||
</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);
|
||||
|
Loading…
Reference in New Issue
Block a user