diff --git a/src/components/basicHeader/container/basicHeaderContainer.js b/src/components/basicHeader/container/basicHeaderContainer.js index 724474c49..3b3c581af 100644 --- a/src/components/basicHeader/container/basicHeaderContainer.js +++ b/src/components/basicHeader/container/basicHeaderContainer.js @@ -26,13 +26,15 @@ class BasicHeaderContainer extends Component { if (isNewPost) { navigation.navigate({ - routeName: ROUTES.SCREENS.HOME, + routeName: ROUTES.SCREENS.FEED, }); } else { navigation.goBack(); } - if (handleOnBackPress) handleOnBackPress(); + if (handleOnBackPress) { + handleOnBackPress(); + } }; render() { diff --git a/src/components/bottomTabBar/view/bottomTabBarView.js b/src/components/bottomTabBar/view/bottomTabBarView.js index 007e516cc..3399f7852 100644 --- a/src/components/bottomTabBar/view/bottomTabBarView.js +++ b/src/components/bottomTabBar/view/bottomTabBarView.js @@ -21,7 +21,7 @@ import styles from './bottomTabBarStyles'; const _jumpTo = (route, index, routes, jumpTo) => { const _routeName = routes[index].routeName; - if (!!get(route, 'params.scrollToTop') && _routeName === ROUTES.TABBAR.HOME) { + if (!!get(route, 'params.scrollToTop') && _routeName === ROUTES.TABBAR.FEED) { route.params.scrollToTop(); } diff --git a/src/components/filterBar/view/filterBarStyles.js b/src/components/filterBar/view/filterBarStyles.js index 8b5210bfa..76cc94521 100644 --- a/src/components/filterBar/view/filterBarStyles.js +++ b/src/components/filterBar/view/filterBarStyles.js @@ -12,8 +12,14 @@ export default EStyleSheet.create({ }, zIndex: 99, }, + dropdownWrapper: { + flexDirection: 'row', + justifyContent: 'center', + alignItems: 'center', + }, filterBarWrapper: { flexDirection: 'row', + alignItems: 'center', justifyContent: 'space-between', }, rightIconWrapper: { @@ -24,4 +30,8 @@ export default EStyleSheet.create({ color: '$darkIconColor', textAlign: 'center', }, + customOptionWrapper: { + left: 120, + position: 'absolute', + }, }); diff --git a/src/components/filterBar/view/filterBarView.js b/src/components/filterBar/view/filterBarView.js index 1b1c7ddd9..59743f0c6 100644 --- a/src/components/filterBar/view/filterBarView.js +++ b/src/components/filterBar/view/filterBarView.js @@ -1,12 +1,12 @@ import React from 'react'; -import { View, TouchableOpacity } from 'react-native'; +import { View, Text, TouchableOpacity } from 'react-native'; import { Icon } from '../../icon'; // External Components import { DropdownButton } from '../../dropdownButton'; // Components -import { LineBreak } from '../../basicUIElements'; +import { LineBreak, Tag } from '../../basicUIElements'; // Styles import styles from './filterBarStyles'; @@ -27,18 +27,27 @@ const FilterBarView = ({ rightIconName, rightIconType, selectedOptionIndex, + customOption, }) => ( {!isHide && ( - + + + + {customOption && ( + onDropdownSelect(3)} /> + )} + + + {rightIconName && ( onRightIconPress && onRightIconPress()} diff --git a/src/components/formInput/view/formInputStyles.js b/src/components/formInput/view/formInputStyles.js index 3c46154da..a87f57620 100644 --- a/src/components/formInput/view/formInputStyles.js +++ b/src/components/formInput/view/formInputStyles.js @@ -6,9 +6,9 @@ export default EStyleSheet.create({ borderTopRightRadius: 8, marginTop: 16, flexDirection: 'row', - backgroundColor: '$primaryLightBackground', height: 60, borderBottomWidth: 2, + backgroundColor: '$primaryWhiteLightBackground', }, firstImage: { width: 24, diff --git a/src/components/header/container/headerContainer.js b/src/components/header/container/headerContainer.js index 6a8871cac..8b4a910d1 100644 --- a/src/components/header/container/headerContainer.js +++ b/src/components/header/container/headerContainer.js @@ -1,80 +1,53 @@ -import React, { PureComponent } from 'react'; +import React from 'react'; import { withNavigation } from 'react-navigation'; -import { connect } from 'react-redux'; -import { get, has } from 'lodash'; +import get from 'lodash/get'; +import has from 'lodash/has'; // Component import HeaderView from '../view/headerView'; -/* - * Props Name Description Value - *@props --> props name here description here Value Type Here - * - */ - -class HeaderContainer extends PureComponent { - constructor(props) { - super(props); - this.state = {}; - } - - // Component Life Cycle Functions - - // Component Functions - - _handleOpenDrawer = () => { - const { navigation } = this.props; +import { AccountContainer, ThemeContainer } from '../../../containers'; +const HeaderContainer = ({ selectedUser, isReverse, navigation, handleOnBackPress }) => { + const _handleOpenDrawer = () => { if (has(navigation, 'openDrawer') && typeof get(navigation, 'openDrawer') === 'function') { navigation.openDrawer(); } }; - _handleOnPressBackButton = () => { - const { navigation, handleOnBackPress } = this.props; - - if (handleOnBackPress) handleOnBackPress(); + const _handleOnPressBackButton = () => { + if (handleOnBackPress) { + handleOnBackPress(); + } navigation.goBack(); }; - render() { - const { - isLoggedIn, - currentAccount, - selectedUser, - isReverse, - isLoginDone, - isDarkTheme, - } = this.props; - const _user = isReverse && selectedUser ? selectedUser : currentAccount; + return ( + + {({ isDarkTheme }) => ( + + {({ currentAccount, isLoggedIn, isLoginDone }) => { + const _user = isReverse && selectedUser ? selectedUser : currentAccount; - const displayName = get(_user, 'display_name'); - const username = get(_user, 'name'); - const reputation = get(_user, 'reputation'); + return ( + + ); + }} + + )} + + ); +}; - return ( - - ); - } -} - -const mapStateToProps = state => ({ - isLoggedIn: state.application.isLoggedIn, - isLoginDone: state.application.isLoginDone, - isDarkTheme: state.application.isDarkTheme, - - currentAccount: state.account.currentAccount, -}); - -export default connect(mapStateToProps)(withNavigation(HeaderContainer)); +export default withNavigation(HeaderContainer); diff --git a/src/components/header/view/headerStyles.js b/src/components/header/view/headerStyles.js index 0910ee81a..bf4edf9e1 100644 --- a/src/components/header/view/headerStyles.js +++ b/src/components/header/view/headerStyles.js @@ -7,7 +7,7 @@ export default EStyleSheet.create({ width: '$deviceWidth', backgroundColor: '$primaryBackgroundColor', flex: 1, - maxHeight: Platform.OS === 'ios' ? 95 : 80, + maxHeight: Platform.OS === 'ios' ? 105 : 80, }, containerReverse: { justifyContent: 'space-between', @@ -33,8 +33,7 @@ export default EStyleSheet.create({ titleWrapper: { flexDirection: 'column', justifyContent: 'center', - marginLeft: 8, - marginRight: 8, + marginHorizontal: 8, }, title: { fontSize: 14, diff --git a/src/components/header/view/headerView.js b/src/components/header/view/headerView.js index a6b50aef4..8f9bf0aa3 100644 --- a/src/components/header/view/headerView.js +++ b/src/components/header/view/headerView.js @@ -1,131 +1,107 @@ -import React, { Component } from 'react'; +import React, { useState } from 'react'; import { View, Text, SafeAreaView, TouchableOpacity } from 'react-native'; import LinearGradient from 'react-native-linear-gradient'; -import { injectIntl } from 'react-intl'; +import { useIntl } from 'react-intl'; // Components import { SearchModal } from '../../searchModal'; import { IconButton } from '../../iconButton'; import { UserAvatar } from '../../userAvatar'; + // Styles import styles from './headerStyles'; -class HeaderView extends Component { - /* Props - * ------------------------------------------------ - * @prop { boolean } hideStatusBar - Can declare status bar is hide or not. - * - */ +const HeaderView = ({ + displayName, + handleOnPressBackButton, + handleOpenDrawer, + isDarkTheme, + isLoggedIn, + isLoginDone, + isReverse, + reputation, + username, +}) => { + const [isSearchModalOpen, setIsSearchModalOpen] = useState(false); + const intl = useIntl(); + let gradientColor; - constructor(props) { - super(props); - this.state = { - isSearchModalOpen: false, - }; + if (isReverse) { + gradientColor = isDarkTheme ? ['#43638e', '#081c36'] : ['#357ce6', '#2d5aa0']; + } else { + gradientColor = isDarkTheme ? ['#081c36', '#43638e'] : ['#2d5aa0', '#357ce6']; } - // Component Life Cycles - - // Component Functions - - _handleOnCloseSearch = () => { - this.setState({ isSearchModalOpen: false }); - }; - - render() { - const { - displayName, - handleOnPressBackButton, - handleOpenDrawer, - intl, - isDarkTheme, - isLoggedIn, - isLoginDone, - isReverse, - reputation, - username, - } = this.props; - const { isSearchModalOpen } = this.state; - let gredientColor; - - if (isReverse) { - gredientColor = isDarkTheme ? ['#43638e', '#081c36'] : ['#357ce6', '#2d5aa0']; - } else { - gredientColor = isDarkTheme ? ['#081c36', '#43638e'] : ['#2d5aa0', '#357ce6']; - } - - return ( - - - handleOpenDrawer()} - disabled={isReverse} + return ( + + setIsSearchModalOpen(false)} + /> + + - - - - - {displayName || username ? ( - - {displayName && {displayName}} - - {`@${username}`} - {reputation && ` (${reputation})`} + + + + {displayName || username ? ( + + {displayName && {displayName}} + + {`@${username}`} + {reputation && ` (${reputation})`} + + + ) : ( + + {isLoginDone && !isLoggedIn && ( + + {intl.formatMessage({ + id: 'header.title', + })} - - ) : ( - - {isLoginDone && !isLoggedIn && ( - - {intl.formatMessage({ - id: 'header.title', - })} - - )} - - )} - {isReverse && ( - - handleOnPressBackButton()} - /> - - )} + )} + + )} - {!isReverse && ( - - this.setState({ isSearchModalOpen: true })} - /> - - )} - - ); - } -} + {isReverse ? ( + + + + ) : ( + + setIsSearchModalOpen(true)} + /> + + )} + + ); +}; -export default injectIntl(HeaderView); +export default HeaderView; diff --git a/src/components/points/view/pointsStyles.js b/src/components/points/view/pointsStyles.js index bb0d07464..79df62eb6 100644 --- a/src/components/points/view/pointsStyles.js +++ b/src/components/points/view/pointsStyles.js @@ -120,6 +120,7 @@ export default EStyleSheet.create({ scrollContainer: { flex: 1, backgroundColor: '$primaryBackgroundColor', + marginBottom: 60, }, popoverDetails: { flexDirection: 'row', diff --git a/src/components/posts/container/postsContainer.js b/src/components/posts/container/postsContainer.js index 4e5e4d89a..b646855b9 100644 --- a/src/components/posts/container/postsContainer.js +++ b/src/components/posts/container/postsContainer.js @@ -1,94 +1,73 @@ -import React, { PureComponent } from 'react'; -import { connect } from 'react-redux'; -import get from 'lodash/get'; +import React from 'react'; +import { connect, useDispatch } from 'react-redux'; // Component import PostsView from '../view/postsView'; +// Container +import { AccountContainer } from '../../../containers'; + // Actions import { setFeedPosts } from '../../../redux/actions/postsAction'; import { hidePostsThumbnails } from '../../../redux/actions/uiAction'; -/* - * Props Name Description Value - *@props --> props name here description here Value Type Here - * - */ - -class PostsContainer extends PureComponent { - constructor(props) { - super(props); - this.state = { - promotedPosts: [], - }; - } - - // Component Life Cycle Functions - - // Component Functions - - _setFeedPosts = posts => { - const { dispatch } = this.props; +const PostsContainer = ({ + changeForceLoadPostState, + feedPosts, + filterOptions, + forceLoadPost, + getFor, + handleOnScroll, + isConnected, + isHideImages, + pageType, + selectedOptionIndex, + tag, + nsfw, + filterOptionsValue, + customOption, +}) => { + const dispatch = useDispatch(); + const _setFeedPosts = posts => { dispatch(setFeedPosts(posts)); }; - _handleImagesHide = () => { - const { dispatch, isHideImages } = this.props; - + const _handleImagesHide = () => { dispatch(hidePostsThumbnails(!isHideImages)); }; - render() { - const { - changeForceLoadPostState, - currentAccount, - feedPosts, - filterOptions, - forceLoadPost, - getFor, - handleOnScroll, - isConnected, - isHideImages, - pageType, - selectedOptionIndex, - tag, - isLoginDone, - isLoggedIn, - nsfw, - } = this.props; - const { promotedPosts } = this.state; - - return ( - - ); - } -} + return ( + + {({ username, isLoggedIn, isLoginDone }) => ( + + )} + + ); +}; const mapStateToProps = state => ({ - currentAccount: state.account.currentAccount, - isLoggedIn: state.application.isLoggedIn, - isLoginDone: state.application.isLoginDone, nsfw: state.application.nsfw, feedPosts: state.posts.feedPosts, isConnected: state.application.isConnected, diff --git a/src/components/posts/view/postsView.js b/src/components/posts/view/postsView.js index a3bd12a72..3f45974fd 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'; @@ -13,272 +13,272 @@ import { getPromotePosts } from '../../../providers/esteem/esteem'; import { PostCard } from '../../postCard'; import { FilterBar } from '../../filterBar'; import { PostCardPlaceHolder, NoPost } from '../../basicUIElements'; -import { POPULAR_FILTERS, PROFILE_FILTERS } from '../../../constants/options/filters'; import { ThemeContainer } from '../../../containers'; // Styles 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, - }; - } - - // Component Functions - componentWillMount() { - const { navigation } = this.props; - - navigation.setParams({ - scrollToTop: this._scrollToTop, - }); - } - - 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, + filterOptionsValue, + customOption, +}) => { + 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(); - } - this._loadPosts(); - } else { - this.setState({ - refreshing: false, - isLoading: false, - }); + const fetchPromotePost = async () => { + if (pageType !== 'profiles') { + await _getPromotePosts(); + } + }; + fetchPromotePost(); + _loadPosts(); + setRefreshing(false); + setIsLoading(false); } - } + }, [ + _getPromotePosts, + _loadPosts, + changeForceLoadPostState, + currentAccountUsername, + forceLoadPost, + isConnected, + pageType, + selectedOptionIndex, + ]); - UNSAFE_componentWillReceiveProps(nextProps) { - const { currentAccountUsername, changeForceLoadPostState } = this.props; + useEffect(() => { + if (forceLoadPost) { + setPosts([]); + setStartAuthor(''); + setStartPermlink(''); + setRefreshing(false); + setIsLoading(false); + setSelectedFilterIndex(selectedOptionIndex || 0); + setIsNoPost(false); - 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(); + + if (changeForceLoadPostState) { + changeForceLoadPostState(false); + } + } + }, [ + _loadPosts, + changeForceLoadPostState, + currentAccountUsername, + forceLoadPost, + selectedOptionIndex, + ]); + + useEffect(() => { + if (!startAuthor && !startPermlink) { + _loadPosts( + filterOptions && filterOptions.length > 0 && filterOptionsValue[selectedFilterIndex], ); } - } + }, [ + _loadPosts, + filterOptions, + filterOptionsValue, + selectedFilterIndex, + startAuthor, + startPermlink, + ]); - _getPromotePosts = async () => { - const { currentAccountUsername } = this.props; + const _handleOnDropdownSelect = async index => { + setSelectedFilterIndex(index); + setPosts([]); + setStartPermlink(''); + setStartAuthor(''); + setIsNoPost(false); + }; - await getPromotePosts().then(async res => { - if (res && res.length) { - const promotedPosts = await Promise.all( - res.map(item => - getPost(get(item, 'author'), get(item, 'permlink'), currentAccountUsername, true).then( - post => post, + const _getPromotePosts = useCallback(async () => { + await getPromotePosts() + .then(async res => { + if (res && res.length) { + const _promotedPosts = await Promise.all( + res.map(item => + getPost( + get(item, 'author'), + get(item, 'permlink'), + currentAccountUsername, + true, + ).then(post => post), ), - ), - ); + ); - this.setState({ promotedPosts }); - } - }); - }; - - _scrollToTop = () => { - if (this.flatList) { - this.flatList.scrollToOffset({ x: 0, y: 0, animated: true }); - } - }; - - _loadPosts = async () => { - const { - getFor, - tag, - currentAccountUsername, - pageType, - nsfw, - setFeedPosts, - isConnected, - } = this.props; - const { - posts, - startAuthor, - startPermlink, - refreshing, - selectedFilterIndex, - isLoading, - promotedPosts, - } = this.state; - const filter = - pageType === 'posts' - ? POPULAR_FILTERS[selectedFilterIndex].toLowerCase() - : PROFILE_FILTERS[selectedFilterIndex].toLowerCase(); - let options; - const limit = 3; - - if (!isConnected) { - this.setState({ - refreshing: false, - isLoading: false, - }); - return null; - } - - if (isLoading) { - return null; - } - - this.setState({ isLoading: true }); - if (tag || filter === 'feed' || filter === 'blog' || getFor === 'blog') { - options = { - tag, - limit, - }; - } else if (filter === 'reblogs') { - options = { - tag, - limit, - }; - } else { - options = { - limit, - }; - } - - 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; - - 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); - } - - _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 - - 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, - }); - } - - this.setState({ - refreshing: false, - isLoading: false, - }); - } - } else if (result.length === 0) { - this.setState({ isNoPost: true }); + setPromotedPosts(_promotedPosts); } }) - .catch(() => { - this.setState({ - refreshing: false, + .catch(() => {}); + }, [currentAccountUsername]); + + const _loadPosts = useCallback( + async type => { + if (isLoading) { + return; + } else { + setIsLoading(true); + } + + const filter = + type || + (filterOptions && filterOptions.length > 0 && filterOptionsValue[selectedFilterIndex]); + let options; + const limit = 3; + + if (!isConnected) { + setRefreshing(false); + setIsLoading(false); + return null; + } + + 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; + } + + 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 (_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); + } + + _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 + + 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); + } + } else if (result.length === 0) { + setIsNoPost(true); + } + }) + .catch(() => { + setRefreshing(false); }); - }); + }, + [ + currentAccountUsername, + filterOptions, + filterOptionsValue, + getFor, + isConnected, + isLoading, + 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 ( @@ -286,29 +286,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 ( ); } @@ -345,76 +331,68 @@ 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 && ( - - )} - - - {({ isDarkTheme }) => ( - - 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={ - - } - ref={ref => { - this.flatList = ref; - }} + return ( + + {({ isDarkTheme }) => ( + + {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={ + + } + /> + + )} + + ); +}; + +export default withNavigation(PostsView); diff --git a/src/components/profile/profileView.js b/src/components/profile/profileView.js index 03f86c0c5..82a1fb5f8 100644 --- a/src/components/profile/profileView.js +++ b/src/components/profile/profileView.js @@ -15,7 +15,7 @@ import { TabBar } from '../tabBar'; import { Wallet } from '../wallet'; // Constants -import { PROFILE_FILTERS } from '../../constants/options/filters'; +import { PROFILE_FILTERS, PROFILE_FILTERS_VALUE } from '../../constants/options/filters'; // Utils import { getFormatedCreatedDate } from '../../utils/time'; @@ -38,13 +38,17 @@ class ProfileView extends PureComponent { _handleOnScroll = () => { const { isSummaryOpen } = this.state; - if (isSummaryOpen) this.setState({ isSummaryOpen: false }); + if (isSummaryOpen) { + this.setState({ isSummaryOpen: false }); + } }; _handleOnSummaryExpanded = () => { const { isSummaryOpen } = this.state; - if (!isSummaryOpen) this.setState({ isSummaryOpen: true }); + if (!isSummaryOpen) { + this.setState({ isSummaryOpen: true }); + } }; _handleUIChange = height => { @@ -156,7 +160,9 @@ class ProfileView extends PureComponent { estimatedWalletValue: 0, oldEstimatedWalletValue: estimatedWalletValue, }); - } else this.setState({ estimatedWalletValue: oldEstimatedWalletValue }); + } else { + this.setState({ estimatedWalletValue: oldEstimatedWalletValue }); + } }} > { + return ( + children && + children({ + accounts, + currentAccount, + isLoggedIn, + isLoginDone, + username, + }) + ); +}; + +const mapStateToProps = state => ({ + accounts: state.account.otherAccounts, + currentAccount: state.account.currentAccount, + isLoggedIn: state.application.isLoggedIn, + isLoginDone: state.application.isLoginDone, + username: state.account.currentAccount.name, +}); + +export default connect(mapStateToProps)(AccountContainer); diff --git a/src/containers/index.js b/src/containers/index.js index 2b9d0390a..eda2d5363 100644 --- a/src/containers/index.js +++ b/src/containers/index.js @@ -1,3 +1,4 @@ +import AccountContainer from './accountContainer'; import InAppPurchaseContainer from './inAppPurchaseContainer'; import PointsContainer from './pointsContainer'; import ProfileContainer from './profileContainer'; @@ -8,6 +9,7 @@ import TransferContainer from './transferContainer'; import ThemeContainer from './themeContainer'; export { + AccountContainer, InAppPurchaseContainer, PointsContainer, ProfileContainer, diff --git a/src/navigation/baseNavigator.js b/src/navigation/baseNavigator.js index 780be1a76..1ebde3f00 100644 --- a/src/navigation/baseNavigator.js +++ b/src/navigation/baseNavigator.js @@ -6,13 +6,13 @@ import ROUTES from '../constants/routeNames'; // Components import { Icon, IconContainer } from '../components/icon'; -import { Home, Notification, Profile, Points } from '../screens'; +import { Feed, Notification, Profile, Points } from '../screens'; import { PostButton, BottomTabBar } from '../components'; const BaseNavigator = createBottomTabNavigator( { - [ROUTES.TABBAR.HOME]: { - screen: Home, + [ROUTES.TABBAR.FEED]: { + screen: Feed, navigationOptions: () => ({ tabBarIcon: ({ tintColor }) => ( diff --git a/src/navigation/routes.js b/src/navigation/routes.js index 56d5dd2aa..40c83dd5e 100644 --- a/src/navigation/routes.js +++ b/src/navigation/routes.js @@ -31,7 +31,7 @@ import { SideMenu } from '../components'; const mainNavigation = createDrawerNavigator( { - [ROUTES.SCREENS.HOME]: { + [ROUTES.SCREENS.FEED]: { screen: BaseNavigator, }, }, diff --git a/src/providers/esteem/esteem.js b/src/providers/esteem/esteem.js index ca128b25e..aa8c0c52f 100644 --- a/src/providers/esteem/esteem.js +++ b/src/providers/esteem/esteem.js @@ -357,7 +357,13 @@ export const getSCAccessToken = code => api.post('/sc-token-refresh', { code }).then(resp => resolve(resp.data)); }); -export const getPromotePosts = () => api.get('/promoted-posts').then(resp => resp.data); +export const getPromotePosts = () => { + try { + return api.get('/promoted-posts').then(resp => resp.data); + } catch (error) { + return error; + } +}; export const purchaseOrder = data => api.post('/purchase-order', data).then(resp => resp.data); diff --git a/src/screens/feed/index.js b/src/screens/feed/index.js new file mode 100644 index 000000000..a3aa6e9ce --- /dev/null +++ b/src/screens/feed/index.js @@ -0,0 +1,4 @@ +import Feed from './screen/feedScreen'; + +export { Feed }; +export default Feed; diff --git a/src/screens/feed/screen/feedScreen.js b/src/screens/feed/screen/feedScreen.js new file mode 100644 index 000000000..b34090d8d --- /dev/null +++ b/src/screens/feed/screen/feedScreen.js @@ -0,0 +1,43 @@ +import React, { Fragment } from 'react'; +import { SafeAreaView } from 'react-native'; +import get from 'lodash/get'; + +// Components +import { Posts, Header } from '../../../components'; + +// Container +import { AccountContainer } from '../../../containers'; + +// Styles +import styles from './feedStyles'; + +import { + POPULAR_FILTERS, + PROFILE_FILTERS, + PROFILE_FILTERS_VALUE, + POPULAR_FILTERS_VALUE, +} from '../../../constants/options/filters'; + +const FeedScreen = () => { + return ( + + {({ currentAccount, isLoggedIn }) => ( + +
+ + + + + )} + + ); +}; + +export default FeedScreen; diff --git a/src/screens/home/screen/homeStyles.js b/src/screens/feed/screen/feedStyles.js similarity index 100% rename from src/screens/home/screen/homeStyles.js rename to src/screens/feed/screen/feedStyles.js diff --git a/src/screens/home/container/homeContainer.js b/src/screens/home/container/homeContainer.js deleted file mode 100644 index 670fd4f44..000000000 --- a/src/screens/home/container/homeContainer.js +++ /dev/null @@ -1,38 +0,0 @@ -import React, { PureComponent } from 'react'; -import { connect } from 'react-redux'; - -// Component -import HomeScreen from '../screen/homeScreen'; - -/* - * Props Name Description Value - *@props --> props name here description here Value Type Here - * - */ - -class HomeContainer extends PureComponent { - constructor(props) { - super(props); - this.state = {}; - } - - render() { - const { isLoggedIn, isLoginDone, currentAccount } = this.props; - - return ( - - ); - } -} - -const mapStateToProps = state => ({ - isLoggedIn: state.application.isLoggedIn, - isLoginDone: state.application.isLoginDone, - currentAccount: state.account.currentAccount, -}); - -export default connect(mapStateToProps)(HomeContainer); diff --git a/src/screens/home/index.js b/src/screens/home/index.js deleted file mode 100644 index b73835b3d..000000000 --- a/src/screens/home/index.js +++ /dev/null @@ -1,5 +0,0 @@ -import HomeScreen from './screen/homeScreen'; -import Home from './container/homeContainer'; - -export { HomeScreen, Home }; -export default Home; diff --git a/src/screens/home/screen/homeScreen.js b/src/screens/home/screen/homeScreen.js deleted file mode 100644 index 8201afdf4..000000000 --- a/src/screens/home/screen/homeScreen.js +++ /dev/null @@ -1,73 +0,0 @@ -import React, { PureComponent, Fragment } from 'react'; -import { View, SafeAreaView } from 'react-native'; -import ScrollableTabView from 'react-native-scrollable-tab-view'; -import { injectIntl } from 'react-intl'; - -// Components -import { TabBar, Posts, Header } from '../../../components'; - -// Styles -import styles from './homeStyles'; -import globalStyles from '../../../globalStyles'; - -import { POPULAR_FILTERS, PROFILE_FILTERS } from '../../../constants/options/filters'; - -class HomeScreen extends PureComponent { - constructor(props) { - super(props); - this.state = {}; - } - - render() { - const { currentAccount, intl, isLoggedIn } = this.props; - - return ( - -
- - ( - - )} - > - - - - - - - - - - ); - } -} - -export default injectIntl(HomeScreen); diff --git a/src/screens/index.js b/src/screens/index.js index d717c6ad1..5de20e384 100755 --- a/src/screens/index.js +++ b/src/screens/index.js @@ -2,7 +2,7 @@ import { Bookmarks } from './bookmarks'; import { Drafts } from './drafts'; import { Editor } from './editor'; import { Follows } from './follows'; -import { Home } from './home'; +import { Feed } from './feed'; import { Launch } from './launch'; import { Login } from './login'; import { Notification } from './notification'; @@ -27,7 +27,7 @@ export { Drafts, Editor, Follows, - Home, + Feed, Launch, Login, Notification, diff --git a/src/screens/launch/screen/launchScreen.js b/src/screens/launch/screen/launchScreen.js index c428b038f..7de46acf1 100644 --- a/src/screens/launch/screen/launchScreen.js +++ b/src/screens/launch/screen/launchScreen.js @@ -1,11 +1,11 @@ import React from 'react'; import { View } from 'react-native'; import LottieView from 'lottie-react-native'; - +import { initialMode as nativeThemeInitialMode } from 'react-native-dark-mode'; import styles from './launchStyles'; const LaunchScreen = () => ( - + ); diff --git a/src/screens/launch/screen/launchStyles.js b/src/screens/launch/screen/launchStyles.js index c98439d5b..59ee658cf 100644 --- a/src/screens/launch/screen/launchStyles.js +++ b/src/screens/launch/screen/launchStyles.js @@ -7,4 +7,10 @@ export default EStyleSheet.create({ alignItems: 'center', backgroundColor: '$pureWhite', }, + darkContainer: { + flex: 1, + justifyContent: 'center', + alignItems: 'center', + backgroundColor: '#1e2835', + }, }); diff --git a/src/screens/pinCode/container/pinCodeContainer.js b/src/screens/pinCode/container/pinCodeContainer.js index 6c2c0e299..424de9ccf 100644 --- a/src/screens/pinCode/container/pinCodeContainer.js +++ b/src/screens/pinCode/container/pinCodeContainer.js @@ -108,7 +108,9 @@ class PinCodeContainer extends Component { dispatch(updateCurrentAccount({ ..._currentAccount })); this._savePinCode(pin); - if (callback) callback(pin, oldPinCode); + if (callback) { + callback(pin, oldPinCode); + } dispatch(closePinCodeModal()); if (navigateTo) { NavigationService.navigate({ @@ -169,7 +171,9 @@ class PinCodeContainer extends Component { setExistUser(true).then(() => { this._savePinCode(pin); - if (callback) callback(pin, oldPinCode); + if (callback) { + callback(pin, oldPinCode); + } dispatch(closePinCodeModal()); if (navigateTo) { NavigationService.navigate({ @@ -193,7 +197,7 @@ class PinCodeContainer extends Component { } = this.props; const { oldPinCode } = this.state; - // If the user is exist, we are just checking to pin and navigating to home screen + // If the user is exist, we are just checking to pin and navigating to feed screen const pinData = { pinCode: pin, password: currentAccount ? currentAccount.password : '', diff --git a/src/screens/searchResult/screen/searchResultScreen.js b/src/screens/searchResult/screen/searchResultScreen.js index c7dee45b2..063ec0c7f 100644 --- a/src/screens/searchResult/screen/searchResultScreen.js +++ b/src/screens/searchResult/screen/searchResultScreen.js @@ -10,6 +10,13 @@ import { SearchInput, Posts, TabBar } from '../../../components'; import styles from './searchResultStyles'; import globalStyles from '../../../globalStyles'; +import { + POPULAR_FILTERS, + PROFILE_FILTERS, + PROFILE_FILTERS_VALUE, + POPULAR_FILTERS_VALUE, +} from '../../../constants/options/filters'; + class SearchResultScreen extends PureComponent { constructor(props) { super(props); @@ -46,7 +53,12 @@ class SearchResultScreen extends PureComponent { })} style={styles.tabbarItem} > - +