created follow and unfollow screens

This commit is contained in:
ue 2018-11-17 14:50:34 +01:00
parent 13b7471f4a
commit fc227af847
6 changed files with 182 additions and 81 deletions

View File

@ -22,9 +22,9 @@ const UserListItem = ({
<View style={styles.userDescription}>
<Text style={styles.name}>
{username}
<Text style={styles.reputation}>{reputation}</Text>
{reputation && <Text style={styles.reputation}>{reputation}</Text>}
</Text>
<Text style={styles.date}>{description}</Text>
{description && <Text style={styles.date}>{description}</Text>}
</View>
{isHasRightItem && (
<View style={styles.rightWrapper}>

View File

@ -79,7 +79,7 @@ class PostsView extends Component {
getFor,
{
tag,
limit: 10,
limit: 3,
start_author: startAuthor,
start_permlink: startPermlink,
},

View File

@ -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;

View File

@ -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 <FollowsScreen isFollowing={isFollowing} data={users} {...this.props} />;
if (!users) {
return null;
}
return (
<FollowsScreen
loadMore={this._loadFollows}
isFollowing={isFollowingPress}
data={users}
filterResult={filterResult}
username={username}
count={count}
isLoading={isLoading}
handleSearch={this._handleSearch}
handleOnUserPress={this._handleOnUserPress}
{...this.props}
/>
);
}
}

View File

@ -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 (
<UserListItem
handleOnUserPress={handleOnUserPress}
avatar={avatar}
index={index}
username={item.follower}
reputation={reputation}
description={item.created}
isHasRightItem
isRightColor={item.is_down_vote}
rightText={value}
subRightText={percent}
username={username}
/>
);
};
_renderFooter = () => {
const { isLoading } = this.props;
if (isLoading) {
return (
<View style={styles.flatlistFooter}>
<ActivityIndicator animating size="large" />
</View>
);
}
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 (
<View>
<View style={{ flex: 1, padding: 8 }}>
<EditorHeader
title={headerTitle}
rightIconName="ios-search"
isHasSearch
handleOnSearch={this._handleSearch}
handleOnSearch={handleSearch}
/>
{(filterResult && data && filterResult.length > 0) || data.length > 0 ? (
{true || (filterResult && data && filterResult.length > 0) || data.length > 0 ? (
<FlatList
data={filterResult || data}
keyExtractor={item => item.voter}
onEndReached={loadMore}
removeClippedSubviews={false}
renderItem={({ item, index }) => this._renderItem(item, index)}
ListFooterComponent={this._renderFooter}
/>
) : (
<Text style={styles.text}>No user found.</Text>

View File

@ -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,
},
});
};