From 2cda5eedb3a0f3002d351899369968afbe4cc7b7 Mon Sep 17 00:00:00 2001 From: ue Date: Thu, 19 Sep 2019 01:55:49 +0300 Subject: [PATCH] created children asa container for profile side --- src/containers/index.js | 9 +- src/containers/profileContainer.js | 367 ++++++++++++++++-- .../profile/container/profileContainer.js | 4 +- 3 files changed, 350 insertions(+), 30 deletions(-) diff --git a/src/containers/index.js b/src/containers/index.js index 90e1bf14b..adb8d0f15 100644 --- a/src/containers/index.js +++ b/src/containers/index.js @@ -2,5 +2,12 @@ import PointsContainer from './pointsContainer'; import ProfileEditContainer from './profileEditContainer'; import RedeemContainer from './redeemContainer'; import TransferContainer from './transferContainer'; +import ProfileContainer from './profileContainer'; -export { PointsContainer, ProfileEditContainer, RedeemContainer, TransferContainer }; +export { + PointsContainer, + ProfileEditContainer, + RedeemContainer, + TransferContainer, + ProfileContainer, +}; diff --git a/src/containers/profileContainer.js b/src/containers/profileContainer.js index 4e5568c9c..3dde185e1 100644 --- a/src/containers/profileContainer.js +++ b/src/containers/profileContainer.js @@ -1,65 +1,378 @@ -import { Component } from 'react'; +/* eslint-disable no-unused-vars */ +import React, { Component } from 'react'; import { connect } from 'react-redux'; -import { injectIntl } from 'react-intl'; -import get from 'lodash/get'; import { withNavigation } from 'react-navigation'; +import { get, has } from 'lodash'; +import { Alert } from 'react-native'; +// Providers +import { + followUser, + unfollowUser, + ignoreUser, + getFollows, + getRepliesByLastUpdate, + getUserComments, + getUser, + getIsFollowing, + getIsMuted, +} from '../providers/steem/dsteem'; + +// Esteem providers +import { getIsFavorite, addFavorite, removeFavorite } from '../providers/esteem/esteem'; + +// Constants import { default as ROUTES } from '../constants/routeNames'; class ProfileContainer extends Component { constructor(props) { super(props); - const isReverseHeader = get(props, 'navigation.state.username', false); this.state = { - isReverseHeader, + comments: [], + follows: {}, + forceLoadPost: false, + isFavorite: false, + isFollowing: false, + isMuted: false, + isProfileLoading: false, + isReady: false, + isOwnProfile: !has(props, 'navigation.state.params.username'), + user: null, + quickProfile: { + reputation: get(props, 'navigation.state.params.reputation', ''), + name: get(props, 'navigation.state.params.username', ''), + }, }; } - // Component Life Cycles + componentDidMount() { + const { + navigation, + isConnected, + isLoggedIn, + currentAccount: { name: currentAccountUsername }, + } = this.props; + const username = get(navigation, 'state.params.username'); + const { isOwnProfile } = this.state; + let targetUsername = currentAccountUsername; - componentDidMount = () => { - const { navigation, isLoggedIn, currentAccount } = this.props; - const selectedUser = get(navigation.state, 'params'); + if (!isConnected) return; - if (!isLoggedIn && !selectedUser) { + if (!isLoggedIn && !username) { navigation.navigate(ROUTES.SCREENS.LOGIN); return; } - if (get(selectedUser, 'username', false) && selectedUser.username !== currentAccount.name) { - this._loadProfile(selectedUser.username); + if (!isOwnProfile) { + targetUsername = username; + } - if (selectedUser.username) { - const selectedQuickProfile = { - reputation: selectedUser.reputation, - name: selectedUser.username, - }; + this._loadProfile(targetUsername); + } - this.setState({ selectedQuickProfile }); + componentWillReceiveProps(nextProps) { + if (!nextProps.isConnected) return; + + const { isLoggedIn, navigation } = this.props; + const { isOwnProfile } = this.state; + + if (isLoggedIn && !nextProps.isLoggedIn) { + navigation.navigate(ROUTES.SCREENS.LOGIN); + return; + } + + if (isOwnProfile) { + const { user } = this.state; + const { activeBottomTab, currentAccount } = this.props; + + const currentUsername = + get(currentAccount, 'name') !== get(nextProps, 'currentAccount.name') && + get(nextProps, 'currentAccount.name'); + const isActiveTabChanged = + activeBottomTab !== get(nextProps, 'activeBottomTab') && + get(nextProps, 'activeBottomTab') === ROUTES.TABBAR.PROFILE; + + if ((isActiveTabChanged && user) || currentUsername) { + this._loadProfile(currentUsername); } + } + } - this.setState({ isReverseHeader: true }); + _getReplies = async user => { + const { isOwnProfile } = this.state; + let repliesAction; + + if (!isOwnProfile) { + repliesAction = getUserComments; } else { - this._loadProfile(currentAccount.name); + repliesAction = getRepliesByLastUpdate; + } + + await repliesAction({ start_author: user, limit: 10 }).then(result => { + this.setState({ + comments: result, + }); + }); + }; + + _handleFollowUnfollowUser = async isFollowAction => { + const { isFollowing, username } = this.state; + const { currentAccount, pinCode } = this.props; + const follower = get(currentAccount, 'name', ''); + const following = username; + + let followAction; + + this.setState({ + isProfileLoading: true, + }); + + if (isFollowAction && !isFollowing) { + followAction = followUser; + } else { + followAction = unfollowUser; + } + + followAction(currentAccount, pinCode, { + follower, + following, + }) + .then(() => { + this._profileActionDone(); + }) + .catch(err => { + this._profileActionDone(err); + }); + }; + + _handleMuteUnmuteUser = isMuteAction => { + this.setState({ + isProfileLoading: true, + }); + + if (isMuteAction) { + this._muteUser(); + } else { + this._handleFollowUnfollowUser(); } }; - // Component Functions + _muteUser = () => { + const { username } = this.state; + const { currentAccount, pinCode } = this.props; + const follower = currentAccount.name; + const following = username; + + ignoreUser(currentAccount, pinCode, { + follower, + following, + }) + .then(() => { + this._profileActionDone(); + }) + .catch(err => { + this._profileActionDone(err); + }); + }; + + _profileActionDone = (error = null) => { + const { username } = this.state; + + if (error) { + this.setState( + { + error, + }, + () => Alert.alert(get(error, 'message') || error.toString()), + ); + } else { + this._fetchProfile(username, true); + } + }; + + _fetchProfile = async (username = null, isProfileAction = false) => { + const { username: _username, isFollowing, isMuted, isOwnProfile } = this.state; + + if (username) { + const { currentAccount } = this.props; + let _isFollowing; + let _isMuted; + let isFavorite; + let follows; + + if (!isOwnProfile) { + _isFollowing = await getIsFollowing(username, currentAccount.name); + + _isMuted = _isFollowing ? false : await getIsMuted(username, currentAccount.name); + + getIsFavorite(username, currentAccount.name).then(isFav => { + isFavorite = isFav; + }); + } + + try { + follows = await getFollows(username); + } catch (err) { + follows = null; + } + + if (isProfileAction && (isFollowing === _isFollowing && isMuted === _isMuted)) { + this._fetchProfile(_username, true); + } else { + this.setState({ + follows, + isFollowing: _isFollowing, + isMuted: _isMuted, + isFavorite, + isReady: true, + isProfileLoading: false, + }); + } + } + }; + + _loadProfile = async (username = null) => { + let user; + + try { + user = await getUser(username); + this._fetchProfile(username); + } catch (error) { + this._profileActionDone(error); + } + + this.setState(prevState => ({ + quickProfile: { + ...prevState.quickProfile, + display_name: get(user, 'display_name'), + reputation: get(user, 'reputation'), + }, + user, + username, + })); + + this._getReplies(username); + }; + + _handleFollowsPress = async isFollowingPress => { + const { navigation } = this.props; + const { username, follows } = this.state; + const count = get(follows, !isFollowingPress ? 'follower_count' : 'following_count'); + + navigation.navigate({ + routeName: ROUTES.SCREENS.FOLLOWS, + params: { + isFollowingPress, + count, + username, + }, + key: `${username}${count}`, + }); + }; + + _handleOnFavoritePress = (isFavorite = false) => { + const { currentAccount } = this.props; + const { username } = this.state; + let favoriteAction; + + if (isFavorite) { + favoriteAction = removeFavorite; + } else { + favoriteAction = addFavorite; + } + + favoriteAction(currentAccount.name, username).then(() => { + this.setState({ isFavorite: !isFavorite }); + }); + }; + + _handleOnBackPress = () => { + const { navigation } = this.props; + const navigationParams = get(navigation.state, 'params'); + + if (get(navigationParams, 'fetchData')) { + navigationParams.fetchData(); + } + }; + + _changeForceLoadPostState = value => { + this.setState({ forceLoadPost: value }); + }; + + _handleOnPressProfileEdit = () => { + const { navigation, currentAccount } = this.props; + + navigation.navigate({ + routeName: ROUTES.SCREENS.PROFILE_EDIT, + params: { + fetchUser: () => this.setState({ user: currentAccount }), + }, + }); + }; render() { - const { isReverseHeader } = this.state; - const { children } = this.props; + const { + avatar, + comments, + error, + follows, + forceLoadPost, + isFavorite, + isFollowing, + isMuted, + isOwnProfile, + isProfileLoading, + isReady, + quickProfile, + user, + username, + } = this.state; + const { currency, isDarkTheme, isLoggedIn, navigation, children } = this.props; + const activePage = get(navigation.state.params, 'state', 0); return ( children && children({ - isReverseHeader, + about: get(user, 'about.profile'), + activePage, + avatar, + changeForceLoadPostState: this._changeForceLoadPostState, + comments, + currency, + error, + follows, + forceLoadPost, + getReplies: () => this._getReplies(username), + handleFollowUnfollowUser: this._handleFollowUnfollowUser, + handleMuteUnmuteUser: this._handleMuteUnmuteUser, + handleOnBackPress: this._handleOnBackPress, + handleOnFavoritePress: this._handleOnFavoritePress, + handleOnFollowsPress: this._handleFollowsPress, + handleOnPressProfileEdit: this._handleOnPressProfileEdit, + isDarkTheme, + isFavorite, + isFollowing, + isLoggedIn, + isMuted, + isOwnProfile, + isProfileLoading, + isReady, + quickProfile, + selectedUser: user, + username, }) ); } } +const mapStateToProps = state => ({ + currency: state.application.currency, + isConnected: state.application.isConnected, + isDarkTheme: state.application.isDarkTheme, + isLoggedIn: state.application.isLoggedIn, + pinCode: state.application.pin, + activeBottomTab: state.ui.activeBottomTab, + currentAccount: state.account.currentAccount, +}); -const mapStateToProps = state => ({}); - -export default connect(mapStateToProps)(injectIntl(withNavigation(ProfileContainer))); +export default connect(mapStateToProps)(withNavigation(ProfileContainer)); diff --git a/src/screens/profile/container/profileContainer.js b/src/screens/profile/container/profileContainer.js index c080b07a1..1f6f9181a 100644 --- a/src/screens/profile/container/profileContainer.js +++ b/src/screens/profile/container/profileContainer.js @@ -49,8 +49,6 @@ class ProfileContainer extends Component { } componentDidMount() { - if (!isConnected) return; - const { navigation, isConnected, @@ -61,6 +59,8 @@ class ProfileContainer extends Component { const { isOwnProfile } = this.state; let targetUsername = currentAccountUsername; + if (!isConnected) return; + if (!isLoggedIn && !username) { navigation.navigate(ROUTES.SCREENS.LOGIN); return;