diff options
author | Eugen Rochko <eugen@zeonfederated.com> | 2018-06-04 02:18:18 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-06-04 02:18:18 +0200 |
commit | 0deb9fa6b9b8820fcb0a9ebd221178a8ec82490a (patch) | |
tree | 8d41e4f356c41e74ea2b1d5c0b0552b058d7495a | |
parent | 00512ecf87e1098f5632eeec2cd116344a787523 (diff) |
Remove trending hashtags (#7711)
* Delete trends_controller.rb * Update routes.rb * Update trending_tags.rb * Update index.js * Update index.js * Update search_results.js * Update async-components.js * Update index.js * Delete trends.js * Delete trends.js * Delete trends_container.js * Delete trends.js * Update search_results.js * Update search_results_container.js
13 files changed, 2 insertions, 226 deletions
diff --git a/app/controllers/api/v1/trends_controller.rb b/app/controllers/api/v1/trends_controller.rb deleted file mode 100644 index bcea9857e..000000000 --- a/app/controllers/api/v1/trends_controller.rb +++ /dev/null @@ -1,17 +0,0 @@ -# frozen_string_literal: true - -class Api::V1::TrendsController < Api::BaseController - before_action :set_tags - - respond_to :json - - def index - render json: @tags, each_serializer: REST::TagSerializer - end - - private - - def set_tags - @tags = TrendingTags.get(limit_param(10)) - end -end diff --git a/app/javascript/mastodon/actions/trends.js b/app/javascript/mastodon/actions/trends.js deleted file mode 100644 index 853e4f60a..000000000 --- a/app/javascript/mastodon/actions/trends.js +++ /dev/null @@ -1,32 +0,0 @@ -import api from '../api'; - -export const TRENDS_FETCH_REQUEST = 'TRENDS_FETCH_REQUEST'; -export const TRENDS_FETCH_SUCCESS = 'TRENDS_FETCH_SUCCESS'; -export const TRENDS_FETCH_FAIL = 'TRENDS_FETCH_FAIL'; - -export const fetchTrends = () => (dispatch, getState) => { - dispatch(fetchTrendsRequest()); - - api(getState) - .get('/api/v1/trends') - .then(({ data }) => dispatch(fetchTrendsSuccess(data))) - .catch(err => dispatch(fetchTrendsFail(err))); -}; - -export const fetchTrendsRequest = () => ({ - type: TRENDS_FETCH_REQUEST, - skipLoading: true, -}); - -export const fetchTrendsSuccess = trends => ({ - type: TRENDS_FETCH_SUCCESS, - trends, - skipLoading: true, -}); - -export const fetchTrendsFail = error => ({ - type: TRENDS_FETCH_FAIL, - error, - skipLoading: true, - skipAlert: true, -}); diff --git a/app/javascript/mastodon/features/compose/components/search_results.js b/app/javascript/mastodon/features/compose/components/search_results.js index cf022362e..c351b84bb 100644 --- a/app/javascript/mastodon/features/compose/components/search_results.js +++ b/app/javascript/mastodon/features/compose/components/search_results.js @@ -1,5 +1,4 @@ import React from 'react'; -import PropTypes from 'prop-types'; import ImmutablePropTypes from 'react-immutable-proptypes'; import { FormattedMessage } from 'react-intl'; import AccountContainer from '../../../containers/account_container'; @@ -11,36 +10,14 @@ export default class SearchResults extends ImmutablePureComponent { static propTypes = { results: ImmutablePropTypes.map.isRequired, - trends: ImmutablePropTypes.list, - fetchTrends: PropTypes.func.isRequired, }; - componentDidMount () { - const { fetchTrends } = this.props; - fetchTrends(); - } - render () { - const { results, trends } = this.props; + const { results } = this.props; let accounts, statuses, hashtags; let count = 0; - if (results.isEmpty()) { - return ( - <div className='search-results'> - <div className='trends'> - <div className='trends__header'> - <i className='fa fa-fire fa-fw' /> - <FormattedMessage id='trends.header' defaultMessage='Trending now' /> - </div> - - {trends && trends.map(hashtag => <Hashtag key={hashtag.get('name')} hashtag={hashtag} />)} - </div> - </div> - ); - } - if (results.get('accounts') && results.get('accounts').size > 0) { count += results.get('accounts').size; accounts = ( diff --git a/app/javascript/mastodon/features/compose/containers/search_results_container.js b/app/javascript/mastodon/features/compose/containers/search_results_container.js index 2f879f9d9..16d95d417 100644 --- a/app/javascript/mastodon/features/compose/containers/search_results_container.js +++ b/app/javascript/mastodon/features/compose/containers/search_results_container.js @@ -1,14 +1,8 @@ import { connect } from 'react-redux'; import SearchResults from '../components/search_results'; -import { fetchTrends } from '../../../actions/trends'; const mapStateToProps = state => ({ results: state.getIn(['search', 'results']), - trends: state.getIn(['trends', 'items']), }); -const mapDispatchToProps = dispatch => ({ - fetchTrends: () => dispatch(fetchTrends()), -}); - -export default connect(mapStateToProps, mapDispatchToProps)(SearchResults); +export default connect(mapStateToProps)(SearchResults); diff --git a/app/javascript/mastodon/features/getting_started/components/trends.js b/app/javascript/mastodon/features/getting_started/components/trends.js deleted file mode 100644 index 96a646bea..000000000 --- a/app/javascript/mastodon/features/getting_started/components/trends.js +++ /dev/null @@ -1,71 +0,0 @@ -import classNames from 'classnames'; -import React from 'react'; -import ImmutablePureComponent from 'react-immutable-pure-component'; -import PropTypes from 'prop-types'; -import ImmutablePropTypes from 'react-immutable-proptypes'; -import { FormattedMessage, defineMessages } from 'react-intl'; -import Hashtag from '../../../components/hashtag'; -import { Link } from 'react-router-dom'; - -const messages = defineMessages({ - refresh_trends: { id: 'trends.refresh', defaultMessage: 'Refresh' }, -}); - -export default class Trends extends ImmutablePureComponent { - - static defaultProps = { - loading: false, - }; - - static propTypes = { - trends: ImmutablePropTypes.list, - loading: PropTypes.bool.isRequired, - showTrends: PropTypes.bool.isRequired, - fetchTrends: PropTypes.func.isRequired, - toggleTrends: PropTypes.func.isRequired, - }; - - componentDidMount () { - setTimeout(() => this.props.fetchTrends(), 5000); - } - - handleRefreshTrends = () => { - this.props.fetchTrends(); - } - - handleToggle = () => { - this.props.toggleTrends(!this.props.showTrends); - } - - render () { - const { intl, trends, loading, showTrends } = this.props; - - if (!trends || trends.size < 1) { - return null; - } - - return ( - <div className='getting-started__trends'> - <div className='column-header__wrapper'> - <h1 className='column-header'> - <button> - <i className='fa fa-fire fa-fw' /> - <FormattedMessage id='trends.header' defaultMessage='Trending now' /> - </button> - - <div className='column-header__buttons'> - {showTrends && <button onClick={this.handleRefreshTrends} className='column-header__button' title={intl.formatMessage(messages.refresh_trends)} aria-label={intl.formatMessage(messages.refresh_trends)} disabled={loading}><i className={classNames('fa', 'fa-refresh', { 'fa-spin': loading })} /></button>} - <button onClick={this.handleToggle} className='column-header__button'><i className={classNames('fa', showTrends ? 'fa-chevron-down' : 'fa-chevron-up')} /></button> - </div> - </h1> - </div> - - {showTrends && <div className='getting-started__scrollable'> - {trends.take(3).map(hashtag => <Hashtag key={hashtag.get('name')} hashtag={hashtag} />)} - <Link to='/trends' className='load-more'><FormattedMessage id='status.load_more' defaultMessage='Load more' /></Link> - </div>} - </div> - ); - } - -} diff --git a/app/javascript/mastodon/features/getting_started/containers/trends_container.js b/app/javascript/mastodon/features/getting_started/containers/trends_container.js deleted file mode 100644 index 65faeae86..000000000 --- a/app/javascript/mastodon/features/getting_started/containers/trends_container.js +++ /dev/null @@ -1,18 +0,0 @@ -import { connect } from 'react-redux'; -import { injectIntl } from 'react-intl'; -import { fetchTrends } from '../../../actions/trends'; -import Trends from '../components/trends'; -import { changeSetting } from '../../../actions/settings'; - -const mapStateToProps = state => ({ - trends: state.getIn(['trends', 'items']), - loading: state.getIn(['trends', 'isLoading']), - showTrends: state.getIn(['settings', 'trends', 'show']), -}); - -const mapDispatchToProps = dispatch => ({ - fetchTrends: () => dispatch(fetchTrends()), - toggleTrends: show => dispatch(changeSetting(['trends', 'show'], show)), -}); - -export default injectIntl(connect(mapStateToProps, mapDispatchToProps)(Trends)); diff --git a/app/javascript/mastodon/features/getting_started/index.js b/app/javascript/mastodon/features/getting_started/index.js index 67a5b282a..115dfd2b9 100644 --- a/app/javascript/mastodon/features/getting_started/index.js +++ b/app/javascript/mastodon/features/getting_started/index.js @@ -12,7 +12,6 @@ import { fetchFollowRequests } from '../../actions/accounts'; import { List as ImmutableList } from 'immutable'; import { Link } from 'react-router-dom'; import NavigationBar from '../compose/components/navigation_bar'; -import TrendsContainer from './containers/trends_container'; const messages = defineMessages({ home_timeline: { id: 'tabs_bar.home', defaultMessage: 'Home' }, @@ -132,8 +131,6 @@ export default class GettingStarted extends ImmutablePureComponent { {navItems} </div> - {multiColumn && <TrendsContainer />} - {!multiColumn && <div className='flex-spacer' />} <div className='getting-started getting-started__footer'> diff --git a/app/javascript/mastodon/features/ui/index.js b/app/javascript/mastodon/features/ui/index.js index bfed02f98..f1409b946 100644 --- a/app/javascript/mastodon/features/ui/index.js +++ b/app/javascript/mastodon/features/ui/index.js @@ -42,7 +42,6 @@ import { Mutes, PinnedStatuses, Lists, - Trends, } from './util/async-components'; import { HotKeys } from 'react-hotkeys'; import { me } from '../../initial_state'; @@ -155,7 +154,6 @@ class SwitchingColumnsArea extends React.PureComponent { <WrappedRoute path='/pinned' component={PinnedStatuses} content={children} /> <WrappedRoute path='/search' component={Compose} content={children} componentParams={{ isSearchPage: true }} /> - <WrappedRoute path='/trends' component={Trends} content={children} /> <WrappedRoute path='/statuses/new' component={Compose} content={children} /> <WrappedRoute path='/statuses/:statusId' exact component={Status} content={children} /> diff --git a/app/javascript/mastodon/features/ui/util/async-components.js b/app/javascript/mastodon/features/ui/util/async-components.js index dfc796a09..8cf2a6e7d 100644 --- a/app/javascript/mastodon/features/ui/util/async-components.js +++ b/app/javascript/mastodon/features/ui/util/async-components.js @@ -129,7 +129,3 @@ export function EmbedModal () { export function ListEditor () { return import(/* webpackChunkName: "features/list_editor" */'../../list_editor'); } - -export function Trends () { - return import(/* webpackChunkName: "features/trends" */'../../trends'); -} diff --git a/app/javascript/mastodon/reducers/index.js b/app/javascript/mastodon/reducers/index.js index 019c1f466..3d9a6a132 100644 --- a/app/javascript/mastodon/reducers/index.js +++ b/app/javascript/mastodon/reducers/index.js @@ -26,7 +26,6 @@ import height_cache from './height_cache'; import custom_emojis from './custom_emojis'; import lists from './lists'; import listEditor from './list_editor'; -import trends from './trends'; const reducers = { dropdown_menu, @@ -56,7 +55,6 @@ const reducers = { custom_emojis, lists, listEditor, - trends, }; export default combineReducers(reducers); diff --git a/app/javascript/mastodon/reducers/trends.js b/app/javascript/mastodon/reducers/trends.js deleted file mode 100644 index 5cecc8fca..000000000 --- a/app/javascript/mastodon/reducers/trends.js +++ /dev/null @@ -1,23 +0,0 @@ -import { TRENDS_FETCH_REQUEST, TRENDS_FETCH_SUCCESS, TRENDS_FETCH_FAIL } from '../actions/trends'; -import { Map as ImmutableMap, List as ImmutableList, fromJS } from 'immutable'; - -const initialState = ImmutableMap({ - items: ImmutableList(), - isLoading: false, -}); - -export default function trendsReducer(state = initialState, action) { - switch(action.type) { - case TRENDS_FETCH_REQUEST: - return state.set('isLoading', true); - case TRENDS_FETCH_SUCCESS: - return state.withMutations(map => { - map.set('items', fromJS(action.trends)); - map.set('isLoading', false); - }); - case TRENDS_FETCH_FAIL: - return state.set('isLoading', false); - default: - return state; - } -}; diff --git a/app/models/trending_tags.rb b/app/models/trending_tags.rb index 287de2a8a..c3641d7fd 100644 --- a/app/models/trending_tags.rb +++ b/app/models/trending_tags.rb @@ -1,9 +1,7 @@ # frozen_string_literal: true class TrendingTags - KEY = 'trending_tags' EXPIRE_HISTORY_AFTER = 7.days.seconds - THRESHOLD = 5 class << self def record_use!(tag, account, at_time = Time.now.utc) @@ -11,30 +9,10 @@ class TrendingTags increment_historical_use!(tag.id, at_time) increment_unique_use!(tag.id, account.id, at_time) - increment_vote!(tag.id, at_time) - end - - def get(limit) - tag_ids = redis.zrevrange(KEY, 0, limit).map(&:to_i) - tags = Tag.where(id: tag_ids).to_a.map { |tag| [tag.id, tag] }.to_h - tag_ids.map { |tag_id| tags[tag_id] }.compact end private - def increment_vote!(tag_id, at_time) - expected = redis.pfcount("activity:tags:#{tag_id}:#{(at_time - 1.day).beginning_of_day.to_i}:accounts").to_f - expected = 1.0 if expected.zero? - observed = redis.pfcount("activity:tags:#{tag_id}:#{at_time.beginning_of_day.to_i}:accounts").to_f - - if expected > observed || observed < THRESHOLD - redis.zrem(KEY, tag_id.to_s) - else - score = ((observed - expected)**2) / expected - redis.zadd(KEY, score, tag_id.to_s) - end - end - def increment_historical_use!(tag_id, at_time) key = "activity:tags:#{tag_id}:#{at_time.beginning_of_day.to_i}" redis.incrby(key, 1) diff --git a/config/routes.rb b/config/routes.rb index 31e90e2ff..a3cba24fc 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -254,7 +254,6 @@ Rails.application.routes.draw do resources :mutes, only: [:index] resources :favourites, only: [:index] resources :reports, only: [:index, :create] - resources :trends, only: [:index] namespace :apps do get :verify_credentials, to: 'credentials#show' |