Merge pull request #606 from esteemapp/feature/comment-filter

created comment filter
This commit is contained in:
uğur erdal 2019-02-22 13:59:59 +03:00 committed by GitHub
commit 50d908d1ef
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 151 additions and 40 deletions

View File

@ -11,8 +11,6 @@ import { getComments } from '../../../providers/steem/dsteem';
// Constants
import { default as ROUTES } from '../../../constants/routeNames';
// Utilities
// Component
import { CommentsView } from '..';
@ -36,14 +34,89 @@ class CommentsContainer extends Component {
}
componentWillReceiveProps(nextProps) {
const { commentCount } = this.props;
const { commentCount, selectedFilter } = this.props;
if (nextProps.commentCount > commentCount) {
this._getComments();
}
if (selectedFilter !== nextProps.selectedFilter && nextProps.selectedFilter) {
const shortedComments = this._shortComments(nextProps.selectedFilter);
this.setState({ comments: shortedComments });
}
}
// Component Functions
_shortComments = (sortOrder) => {
const { comments: parent } = this.state;
const allPayout = c => parseFloat(c.pending_payout_value.split(' ')[0])
+ parseFloat(c.total_payout_value.split(' ')[0])
+ parseFloat(c.curator_payout_value.split(' ')[0]);
const absNegative = a => a.net_rshares < 0;
const sortOrders = {
TRENDING: (a, b) => {
if (absNegative(a)) {
return 1;
}
if (absNegative(b)) {
return -1;
}
const apayout = allPayout(a);
const bpayout = allPayout(b);
if (apayout !== bpayout) {
return bpayout - apayout;
}
return 0;
},
REPUTATION: (a, b) => {
const keyA = a.author_reputation;
const keyB = b.author_reputation;
if (keyA > keyB) return -1;
if (keyA < keyB) return 1;
return 0;
},
VOTES: (a, b) => {
const keyA = a.net_votes;
const keyB = b.net_votes;
if (keyA > keyB) return -1;
if (keyA < keyB) return 1;
return 0;
},
AGE: (a, b) => {
if (absNegative(a)) {
return 1;
}
if (absNegative(b)) {
return -1;
}
const keyA = Date.parse(a.created);
const keyB = Date.parse(b.created);
if (keyA > keyB) return -1;
if (keyA < keyB) return 1;
return 0;
},
};
parent.sort(sortOrders[sortOrder]);
return parent;
};
_getComments = () => {
const { author, permlink } = this.props;
@ -87,18 +160,19 @@ class CommentsContainer extends Component {
isLoggedIn,
commentCount,
author,
permlink,
currentAccount,
commentNumber,
comments,
fetchPost,
isShowMoreButton,
selectedFilter,
selectedPermlink: _selectedPermlink,
} = this.props;
return (
<CommentsView
key={permlink}
key={selectedFilter}
selectedFilter={selectedFilter}
selectedPermlink={_selectedPermlink || selectedPermlink}
author={author}
isShowMoreButton={isShowMoreButton}
@ -109,7 +183,6 @@ class CommentsContainer extends Component {
handleOnEditPress={this._handleOnEditPress}
handleOnReplyPress={this._handleOnReplyPress}
isLoggedIn={isLoggedIn}
permlink={permlink}
fetchPost={fetchPost}
{...this.props}
/>

View File

@ -1,5 +1,5 @@
import React, { PureComponent } from 'react';
import { View, FlatList } from 'react-native';
import { FlatList } from 'react-native';
// Components
import { Comment } from '../../comment';
@ -21,49 +21,46 @@ class CommentsView extends PureComponent {
// Component Life Cycles
// Component Functions
_handleOnDropdownSelect = () => {};
_keyExtractor = item => item.permlink;
render() {
const {
avatarSize,
commentCount,
commentNumber,
comments,
currentAccountUsername,
fetchPost,
handleOnEditPress,
handleOnReplyPress,
handleOnUserPress,
isLoggedIn,
marginLeft,
isShowSubComments,
fetchPost,
commentCount,
marginLeft,
} = this.props;
return (
<FlatList
data={comments}
keyExtractor={this._keyExtractor}
renderItem={({ item, index }) => (
<View key={index}>
<Comment
isShowMoreButton={commentNumber === 1 && item.children > 0}
comment={item}
marginLeft={marginLeft}
commentNumber={commentNumber}
fetchPost={fetchPost}
commentCount={commentCount || item.children}
isShowSubComments={isShowSubComments}
avatarSize={avatarSize}
currentAccountUsername={currentAccountUsername}
handleOnReplyPress={handleOnReplyPress}
handleOnEditPress={handleOnEditPress}
handleOnUserPress={handleOnUserPress}
isLoggedIn={isLoggedIn}
showComentsToggle={this._showComentsToggle}
/>
</View>
renderItem={({ item }) => (
<Comment
avatarSize={avatarSize}
comment={item}
commentCount={commentCount || item.children}
commentNumber={commentNumber}
currentAccountUsername={currentAccountUsername}
fetchPost={fetchPost}
handleOnEditPress={handleOnEditPress}
handleOnReplyPress={handleOnReplyPress}
handleOnUserPress={handleOnUserPress}
isLoggedIn={isLoggedIn}
isShowMoreButton={commentNumber === 1 && item.children > 0}
isShowSubComments={isShowSubComments}
key={item.permlink}
marginLeft={marginLeft}
/>
)}
/>
);

View File

@ -3,6 +3,5 @@ import EStyleSheet from 'react-native-extended-stylesheet';
export default EStyleSheet.create({
commentWrapper: {
padding: 16,
paddingBottom: 50,
},
});

View File

@ -1,9 +1,11 @@
import React, { PureComponent, Fragment } from 'react';
import { View } from 'react-native';
import { injectIntl } from 'react-intl';
// Components
import { FilterBar } from '../../filterBar';
import { Comments } from '../../comments';
import COMMENT_FILTER from '../../../constants/options/comment';
// Styles
import styles from './commentDisplayStyles';
@ -16,31 +18,39 @@ class CommentsDisplayView extends PureComponent {
constructor(props) {
super(props);
this.state = {};
this.state = {
selectedFilter: null,
};
}
// Component Life Cycles
// Component Functions
_handleOnDropdownSelect = () => {};
_handleOnDropdownSelect = (index, option) => {
this.setState({ selectedFilter: option });
};
render() {
const {
author, permlink, commentCount, fetchPost,
author, commentCount, fetchPost, intl, permlink,
} = this.props;
// TODO: implement comments filtering
const { selectedFilter } = this.state;
return (
<Fragment>
{commentCount > 0 && (
<Fragment>
<FilterBar
dropdownIconName="arrow-drop-down"
options={['TRENDING']}
defaultText="TRENDING"
options={COMMENT_FILTER.map(item => intl.formatMessage({ id: `comment_filter.${item}` }).toUpperCase())}
defaultText={intl
.formatMessage({ id: `comment_filter.${COMMENT_FILTER[0]}` })
.toUpperCase()}
onDropdownSelect={this._handleOnDropdownSelect}
/>
<View style={styles.commentWrapper}>
<Comments
selectedFilter={selectedFilter}
fetchPost={fetchPost}
commentCount={commentCount}
author={author}
@ -54,4 +64,4 @@ class CommentsDisplayView extends PureComponent {
}
}
export default CommentsDisplayView;
export default injectIntl(CommentsDisplayView);

View File

@ -20,6 +20,7 @@ export default EStyleSheet.create({
scroll: {
height: '$deviceHeight / 1.135',
backgroundColor: '$primaryBackgroundColor',
marginBottom: 50,
},
footer: {
flexDirection: 'column',

View File

@ -115,7 +115,7 @@ class PostDisplayView extends PureComponent {
const { post, fetchPost, parentPost } = this.props;
const { postHeight, scrollHeight, isLoadedComments } = this.state;
const isPostEnd = scrollHeight > postHeight;
// const isPostEnd = scrollHeight > postHeight;
const isGetComment = scrollHeight + 300 > postHeight;
const formatedTime = post && getTimeFromNow(post.created);
@ -140,7 +140,7 @@ class PostDisplayView extends PureComponent {
size={16}
/>
<PostBody body={post.body} />
<View style={[styles.footer, !isPostEnd && styles.marginFooter]}>
<View style={styles.footer}>
<Tags tags={post.json_metadata && post.json_metadata.tags} />
<Text style={styles.footerText}>
Posted by

View File

@ -199,5 +199,11 @@
"deep_link": {
"no_existing_user": "No existing user",
"no_existing_post": "No existing post"
},
"comment_filter": {
"trending": "trending",
"reputation": "reputation",
"votes": "votes",
"age": "age"
}
}

View File

@ -0,0 +1 @@
export default ['trending', 'reputation', 'votes', 'age'];

View File

@ -0,0 +1,24 @@
export default (input) => {
if (input === 0) {
return 25;
}
if (!input) {
return input;
}
let neg = false;
if (input < 0) neg = true;
let reputationLevel = Math.log10(Math.abs(input));
reputationLevel = Math.max(reputationLevel - 9, 0);
if (reputationLevel < 0) reputationLevel = 0;
if (neg) reputationLevel *= -1;
reputationLevel = reputationLevel * 9 + 25;
return Math.floor(reputationLevel);
};