diff --git a/src/components/posts/view/postsView.js b/src/components/posts/view/postsView.js index 80632a581..fa468de3b 100644 --- a/src/components/posts/view/postsView.js +++ b/src/components/posts/view/postsView.js @@ -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 ( @@ -267,29 +274,15 @@ class PostsView extends Component { ); } + 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 ( ); } @@ -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 ( - - {filterOptions && isShowFilterBar && ( - - )} - - - get(item, 'author', null) && ( - - ) - } - 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={ - - {({ isDarkTheme }) => ( - - )} - - } + return ( + + {filterOptions && isShowFilterBar && ( + - - ); - } -} + )} -export default withNavigation(injectIntl(PostsView)); + + get(item, 'author', null) && ( + + ) + } + 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={ + + {({ isDarkTheme }) => ( + + )} + + } + /> + + ); +}; + +export default withNavigation(PostsView);