From fc227af847098f8ad8f520958c4e70117be5bf53 Mon Sep 17 00:00:00 2001 From: ue Date: Sat, 17 Nov 2018 14:50:34 +0100 Subject: [PATCH] created follow and unfollow screens --- .../basicUIElements/view/userListItem.js | 4 +- src/components/posts/view/postsView.js | 2 +- src/providers/steem/dsteem.js | 36 ++++-- .../follows/container/followsContainer.js | 117 ++++++++++++++++-- src/screens/follows/screen/followsScreen.js | 86 +++++-------- .../profile/container/profileContainer.js | 18 ++- 6 files changed, 182 insertions(+), 81 deletions(-) diff --git a/src/components/basicUIElements/view/userListItem.js b/src/components/basicUIElements/view/userListItem.js index e2a9c0fac..e374418f5 100644 --- a/src/components/basicUIElements/view/userListItem.js +++ b/src/components/basicUIElements/view/userListItem.js @@ -22,9 +22,9 @@ const UserListItem = ({ {username} - {reputation} + {reputation && {reputation}} - {description} + {description && {description}} {isHasRightItem && ( diff --git a/src/components/posts/view/postsView.js b/src/components/posts/view/postsView.js index f2dc1d8fb..0667d8d69 100644 --- a/src/components/posts/view/postsView.js +++ b/src/components/posts/view/postsView.js @@ -79,7 +79,7 @@ class PostsView extends Component { getFor, { tag, - limit: 10, + limit: 3, start_author: startAuthor, start_permlink: startPermlink, }, diff --git a/src/providers/steem/dsteem.js b/src/providers/steem/dsteem.js index 917e8a92e..70acc2874 100644 --- a/src/providers/steem/dsteem.js +++ b/src/providers/steem/dsteem.js @@ -107,16 +107,16 @@ export const getFollows = user => new Promise((resolve, reject) => { * @param user username * TODO: Pagination */ -export const getFollowers = user => new Promise((resolve, reject) => { - client - .call('follow_api', 'get_followers', [user, '', 'blog', 50]) - .then((result) => { - resolve(result); - }) - .catch((err) => { - reject(err); - }); -}); +// export const getFollowers = (user, limit = 100) => new Promise((resolve, reject) => { +// client +// .call('follow_api', 'get_followers', [user, '', 'blog', limit]) +// .then((result) => { +// resolve(result); +// }) +// .catch((err) => { +// reject(err); +// }); +// }); /** * @method getFollowing @@ -124,6 +124,7 @@ export const getFollowers = user => new Promise((resolve, reject) => { * TODO: Pagination */ export const getFollowing = (follower, startFollowing, followType = 'blog', limit = 100) => client.database.call('get_following', [follower, startFollowing, followType, limit]); +export const getFollowers = (follower, startFollowing, followType = 'blog', limit = 100) => client.database.call('get_followers', [follower, startFollowing, followType, limit]); export const getIsFollowing = (user, author) => new Promise((resolve, reject) => { client.database @@ -140,6 +141,21 @@ export const getIsFollowing = (user, author) => new Promise((resolve, reject) => }); }); +export const getFollowSearch = (user, targetUser) => new Promise((resolve, reject) => { + client.database + .call('get_following', [targetUser, user, 'blog', 1]) + .then((result) => { + if (result[0] && result[0].follower === targetUser && result[0].following === user) { + resolve(result[0].follower); + } else { + resolve(null); + } + }) + .catch((err) => { + reject(err); + }); +}); + export const getIsMuted = async (username, targetUsername) => { let resp; diff --git a/src/screens/follows/container/followsContainer.js b/src/screens/follows/container/followsContainer.js index 96bb52d12..576ae78a6 100644 --- a/src/screens/follows/container/followsContainer.js +++ b/src/screens/follows/container/followsContainer.js @@ -1,13 +1,14 @@ import React, { Component } from 'react'; -// Services and Actions - // Middleware // Constants +import { default as ROUTES } from '../../../constants/routeNames'; // Utilities +// Services and Actions +import { getFollowers, getFollowing, getFollowSearch } from '../../../providers/steem/dsteem'; // Component import { FollowsScreen } from '..'; @@ -20,19 +21,121 @@ import { FollowsScreen } from '..'; class FollowsContainer extends Component { constructor(props) { super(props); - this.state = {}; + this.state = { + username: null, + users: [], + count: null, + isFollowingPress: null, + startWith: '', + filterResult: null, + }; } // Component Life Cycle Functions + async componentDidMount() { + const { navigation } = this.props; + + if (navigation.state && navigation.state.params) { + const { count, username, isFollowingPress } = navigation.state.params; + + this.setState({ + count, + username, + isFollowingPress, + }); + + await this._loadFollows(username, isFollowingPress); + } + } // Component Functions + _loadFollows = async (_username = null, _isFollowingPress = null) => { + let _users; + let _startWith; + const { + username, users, isFollowingPress, startWith, count, + } = this.state; + + if (users && count === users.length + 1) return; + + const name = username || _username; + const isFollowing = isFollowingPress || _isFollowingPress; + + this.setState({ isLoading: true }); + + if (!isFollowing) { + await getFollowers(name, startWith).then((result) => { + _users = result; + _startWith = users && users[users.length - 1] && users[users.length - 1].follower; + }); + } else { + await getFollowing(name, startWith).then((result) => { + _users = result; + _startWith = users && users[users.length - 1] && users[users.length - 1].following; + }); + } + + !_username && _users.shift(); + + this.setState({ + users: !_username ? [...users, ..._users] : _users, + startWith: _startWith, + isLoading: false, + }); + }; + + _handleSearch = async (text) => { + const { users, username } = this.state; + let newData; + + newData = users.filter((item) => { + const itemName = item.follower.toUpperCase(); + const _text = text.toUpperCase(); + + return itemName.indexOf(_text) > -1; + }); + + if (newData.length <= 0) { + newData = await getFollowSearch(username, text); + } + + this.setState({ filterResult: newData }); + }; + + _handleOnUserPress = (username) => { + const { navigation } = this.props; + + navigation.navigate({ + routeName: ROUTES.SCREENS.PROFILE, + params: { + username, + }, + key: username, + }); + }; render() { - const { navigation } = this.props; - const users = navigation.state && navigation.state.params && navigation.state.params.users; - const isFollowing = navigation.state && navigation.state.params && navigation.state.params.isFollowing; + const { + isFollowingPress, users, isLoading, count, username, filterResult, + } = this.state; - return ; + if (!users) { + return null; + } + return ( + + ); } } diff --git a/src/screens/follows/screen/followsScreen.js b/src/screens/follows/screen/followsScreen.js index 9e22f7bf3..e4865f84f 100644 --- a/src/screens/follows/screen/followsScreen.js +++ b/src/screens/follows/screen/followsScreen.js @@ -1,5 +1,7 @@ import React, { Component } from 'react'; -import { View, Text, FlatList } from 'react-native'; +import { + View, Text, FlatList, ActivityIndicator, +} from 'react-native'; // Constants // Components @@ -7,7 +9,6 @@ import { EditorHeader } from '../../../components/editorHeader'; import { UserListItem } from '../../../components/basicUIElements'; // Utils -import { isBefore } from '../../../utils/time'; import styles from './followScreenStyles'; class FollowsScreen extends Component { @@ -20,90 +21,63 @@ class FollowsScreen extends Component { super(props); this.state = { data: props.data, - filterResult: null, }; } // Component Life Cycles // Component Functions - _handleOnDropdownSelect = (index) => { - const { data } = this.state; - const _data = data; - - switch (index) { - case '0': - _data.sort((a, b) => Number(b.value) - Number(a.value)); - break; - case '1': - _data.sort((a, b) => b.percent - a.percent); - break; - case '2': - _data.sort((a, b) => (isBefore(a.time, b.time) ? 1 : -1)); - break; - default: - break; - } - - this.setState({ filterResult: _data }); - }; - - _handleRightIconPress = () => {}; - - _handleSearch = (text) => { - const { data } = this.state; - - const newData = data.filter((item) => { - const itemName = item.username.toUpperCase(); - const _text = text.toUpperCase(); - - return itemName.indexOf(_text) > -1; - }); - - this.setState({ filterResult: newData }); - }; _renderItem = (item, index) => { - const { handleOnUserPress } = this.props; - const reputation = `(${item.reputation})`; - const value = `$ ${item.value}`; - const percent = `${item.percent}%`; - const avatar = `https://steemitimages.com/u/${item.follower}/avatar/small`; + const { handleOnUserPress, isFollowing } = this.props; + const username = isFollowing ? item.following : item.follower; + const avatar = `https://steemitimages.com/u/${username}/avatar/small`; return ( ); }; + _renderFooter = () => { + const { isLoading } = this.props; + + if (isLoading) { + return ( + + + + ); + } + return null; + }; + render() { - const { data, filterResult, isFollowers } = this.state; - const title = isFollowers ? 'Followers' : 'Following'; - const headerTitle = `${title} (${data && data.length})`; + const { + loadMore, data, isFollowers, count, filterResult, handleSearch, + } = this.props; + const title = !isFollowers ? 'Followers' : 'Following'; + const headerTitle = `${title} (${count})`; return ( - + - {(filterResult && data && filterResult.length > 0) || data.length > 0 ? ( + {true || (filterResult && data && filterResult.length > 0) || data.length > 0 ? ( item.voter} + onEndReached={loadMore} removeClippedSubviews={false} renderItem={({ item, index }) => this._renderItem(item, index)} + ListFooterComponent={this._renderFooter} /> ) : ( No user found. diff --git a/src/screens/profile/container/profileContainer.js b/src/screens/profile/container/profileContainer.js index 54c927ebd..b5a50a8b8 100644 --- a/src/screens/profile/container/profileContainer.js +++ b/src/screens/profile/container/profileContainer.js @@ -15,6 +15,7 @@ import { getIsFollowing, getIsMuted, getFollowers, + getFollowing, } from '../../../providers/steem/dsteem'; import { decryptKey } from '../../../utils/crypto'; import { getDigitPinCode } from '../../../providers/steem/auth'; @@ -225,16 +226,23 @@ class ProfileContainer extends Component { ); }; - _handleFollowsPress = async (usernme, isFollowingPress = false) => { + _handleFollowsPress = async (isFollowingPress) => { const { navigation } = this.props; - const { username } = this.state; - const followers = await getFollowers(username); + const { username, follows } = this.state; + let count; + + if (!isFollowingPress) { + count = follows.follower_count; + } else { + count = follows.following_count; + } navigation.navigate({ routeName: ROUTES.SCREENS.FOLLOWS, params: { - users: followers, - isFollowing: isFollowingPress, + isFollowingPress, + count, + username, }, }); };