Backfill follow suggestions with fallback when not enough results. Cycling
through suggestions in UI
This commit is contained in:
parent
f9c9fef157
commit
4470330385
2 changed files with 65 additions and 23 deletions
|
@ -6,7 +6,8 @@ import { Link } from 'react-router';
|
||||||
|
|
||||||
const outerStyle = {
|
const outerStyle = {
|
||||||
marginBottom: '10px',
|
marginBottom: '10px',
|
||||||
borderTop: '1px solid #616b86'
|
borderTop: '1px solid #616b86',
|
||||||
|
position: 'relative'
|
||||||
};
|
};
|
||||||
|
|
||||||
const headerStyle = {
|
const headerStyle = {
|
||||||
|
@ -41,26 +42,64 @@ const acctStyle = {
|
||||||
textOverflow: 'ellipsis'
|
textOverflow: 'ellipsis'
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const nextStyle = {
|
||||||
|
fontWeight: '400',
|
||||||
|
color: '#2b90d9'
|
||||||
|
};
|
||||||
|
|
||||||
const SuggestionsBox = React.createClass({
|
const SuggestionsBox = React.createClass({
|
||||||
|
|
||||||
propTypes: {
|
propTypes: {
|
||||||
accounts: ImmutablePropTypes.list.isRequired
|
accounts: ImmutablePropTypes.list.isRequired,
|
||||||
|
perWindow: React.PropTypes.number
|
||||||
|
},
|
||||||
|
|
||||||
|
getInitialState () {
|
||||||
|
return {
|
||||||
|
index: 0
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
getDefaultProps () {
|
||||||
|
return {
|
||||||
|
perWindow: 2
|
||||||
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
mixins: [PureRenderMixin],
|
mixins: [PureRenderMixin],
|
||||||
|
|
||||||
|
handleNextClick (e) {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
let newIndex = this.state.index + 1;
|
||||||
|
|
||||||
|
if (this.props.accounts.skip(this.props.perWindow * newIndex).size === 0) {
|
||||||
|
newIndex = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setState({ index: newIndex });
|
||||||
|
},
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const accounts = this.props.accounts.take(3);
|
const { accounts, perWindow } = this.props;
|
||||||
|
|
||||||
if (accounts.size === 0) {
|
if (accounts.size === 0) {
|
||||||
return <div />;
|
return <div />;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let nextLink = '';
|
||||||
|
|
||||||
|
if (accounts.size > perWindow) {
|
||||||
|
nextLink = <a href='#' style={nextStyle} onClick={this.handleNextClick}>Next</a>;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={outerStyle}>
|
<div style={outerStyle}>
|
||||||
<strong style={headerStyle}>Who to follow</strong>
|
<strong style={headerStyle}>
|
||||||
|
Who to follow {nextLink}
|
||||||
|
</strong>
|
||||||
|
|
||||||
{accounts.map(account => {
|
{accounts.skip(perWindow * this.state.index).take(perWindow).map(account => {
|
||||||
let displayName = account.get('display_name');
|
let displayName = account.get('display_name');
|
||||||
|
|
||||||
if (displayName.length === 0) {
|
if (displayName.length === 0) {
|
||||||
|
|
|
@ -14,9 +14,17 @@ END
|
||||||
|
|
||||||
results = neo.execute_query(query, id: for_account_id, limit: limit)
|
results = neo.execute_query(query, id: for_account_id, limit: limit)
|
||||||
|
|
||||||
return fallback(for_account_id, limit) if results.empty? || results['data'].empty?
|
if results.empty?
|
||||||
|
results = fallback(for_account_id, limit)
|
||||||
|
elsif results['data'].size < limit
|
||||||
|
results['data'] = (results['data'] + fallback(for_account_id, limit - results['data'].size)['data']).uniq
|
||||||
|
end
|
||||||
|
|
||||||
map_to_accounts(for_account_id, results)
|
account_ids = results['data'].map(&:first)
|
||||||
|
blocked_ids = Block.where(account_id: for_account_id).pluck(:target_account_id)
|
||||||
|
accounts_map = Account.where(id: account_ids - blocked_ids).map { |a| [a.id, a] }.to_h
|
||||||
|
|
||||||
|
account_ids.map { |id| accounts_map[id] }.compact
|
||||||
rescue Neography::NeographyError, Excon::Error::Socket => e
|
rescue Neography::NeographyError, Excon::Error::Socket => e
|
||||||
Rails.logger.error e
|
Rails.logger.error e
|
||||||
return []
|
return []
|
||||||
|
@ -25,23 +33,18 @@ END
|
||||||
private
|
private
|
||||||
|
|
||||||
def self.fallback(for_account_id, limit)
|
def self.fallback(for_account_id, limit)
|
||||||
neo = Neography::Rest.new
|
neo = Neography::Rest.new
|
||||||
query = 'MATCH (a) WHERE a.account_id <> {id} RETURN a.account_id ORDER BY a.nodeRank DESC LIMIT {limit}'
|
|
||||||
results = neo.execute_query(query, id: for_account_id, limit: limit)
|
|
||||||
|
|
||||||
map_to_accounts(for_account_id, results)
|
query = <<END
|
||||||
rescue Neography::NeographyError, Excon::Error::Socket => e
|
START a=node:account_index(Account={id})
|
||||||
Rails.logger.error e
|
MATCH (b)
|
||||||
return []
|
WHERE a <> b
|
||||||
end
|
AND NOT (a)-[:follows]->(b)
|
||||||
|
RETURN b.account_id
|
||||||
|
ORDER BY b.nodeRank DESC
|
||||||
|
LIMIT {limit}
|
||||||
|
END
|
||||||
|
|
||||||
def self.map_to_accounts(for_account_id, results)
|
neo.execute_query(query, id: for_account_id, limit: limit)
|
||||||
return [] if results.empty? || results['data'].empty?
|
|
||||||
|
|
||||||
account_ids = results['data'].map(&:first)
|
|
||||||
blocked_ids = Block.where(account_id: for_account_id).pluck(:target_account_id)
|
|
||||||
accounts_map = Account.where(id: account_ids - blocked_ids).map { |a| [a.id, a] }.to_h
|
|
||||||
|
|
||||||
account_ids.map { |id| accounts_map[id] }.compact
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue