Replacing follow requests in the settings area with in-UI column
This commit is contained in:
		| @@ -51,6 +51,22 @@ export const RELATIONSHIPS_FETCH_REQUEST = 'RELATIONSHIPS_FETCH_REQUEST'; | ||||
| export const RELATIONSHIPS_FETCH_SUCCESS = 'RELATIONSHIPS_FETCH_SUCCESS'; | ||||
| export const RELATIONSHIPS_FETCH_FAIL    = 'RELATIONSHIPS_FETCH_FAIL'; | ||||
|  | ||||
| export const FOLLOW_REQUESTS_FETCH_REQUEST = 'FOLLOW_REQUESTS_FETCH_REQUEST'; | ||||
| export const FOLLOW_REQUESTS_FETCH_SUCCESS = 'FOLLOW_REQUESTS_FETCH_SUCCESS'; | ||||
| export const FOLLOW_REQUESTS_FETCH_FAIL    = 'FOLLOW_REQUESTS_FETCH_FAIL'; | ||||
|  | ||||
| export const FOLLOW_REQUESTS_EXPAND_REQUEST = 'FOLLOW_REQUESTS_EXPAND_REQUEST'; | ||||
| export const FOLLOW_REQUESTS_EXPAND_SUCCESS = 'FOLLOW_REQUESTS_EXPAND_SUCCESS'; | ||||
| export const FOLLOW_REQUESTS_EXPAND_FAIL    = 'FOLLOW_REQUESTS_EXPAND_FAIL'; | ||||
|  | ||||
| export const FOLLOW_REQUEST_AUTHORIZE_REQUEST = 'FOLLOW_REQUEST_AUTHORIZE_REQUEST'; | ||||
| export const FOLLOW_REQUEST_AUTHORIZE_SUCCESS = 'FOLLOW_REQUEST_AUTHORIZE_SUCCESS'; | ||||
| export const FOLLOW_REQUEST_AUTHORIZE_FAIL    = 'FOLLOW_REQUEST_AUTHORIZE_FAIL'; | ||||
|  | ||||
| export const FOLLOW_REQUEST_REJECT_REQUEST = 'FOLLOW_REQUEST_REJECT_REQUEST'; | ||||
| export const FOLLOW_REQUEST_REJECT_SUCCESS = 'FOLLOW_REQUEST_REJECT_SUCCESS'; | ||||
| export const FOLLOW_REQUEST_REJECT_FAIL    = 'FOLLOW_REQUEST_REJECT_FAIL'; | ||||
|  | ||||
| export function setAccountSelf(account) { | ||||
|   return { | ||||
|     type: ACCOUNT_SET_SELF, | ||||
| @@ -509,3 +525,140 @@ export function fetchRelationshipsFail(error) { | ||||
|     error | ||||
|   }; | ||||
| }; | ||||
|  | ||||
| export function fetchFollowRequests() { | ||||
|   return (dispatch, getState) => { | ||||
|     dispatch(fetchFollowRequestsRequest()); | ||||
|  | ||||
|     api(getState).get('/api/v1/follow_requests').then(response => { | ||||
|       const next = getLinks(response).refs.find(link => link.rel === 'next'); | ||||
|       dispatch(fetchFollowRequestsSuccess(response.data, next ? next.uri : null)) | ||||
|     }).catch(error => dispatch(fetchFollowRequestsFail(error))); | ||||
|   }; | ||||
| }; | ||||
|  | ||||
| export function fetchFollowRequestsRequest() { | ||||
|   return { | ||||
|     type: FOLLOW_REQUESTS_FETCH_REQUEST | ||||
|   }; | ||||
| }; | ||||
|  | ||||
| export function fetchFollowRequestsSuccess(accounts, next) { | ||||
|   return { | ||||
|     type: FOLLOW_REQUESTS_FETCH_SUCCESS, | ||||
|     accounts, | ||||
|     next | ||||
|   }; | ||||
| }; | ||||
|  | ||||
| export function fetchFollowRequestsFail(error) { | ||||
|   return { | ||||
|     type: FOLLOW_REQUESTS_FETCH_FAIL, | ||||
|     error | ||||
|   }; | ||||
| }; | ||||
|  | ||||
| export function expandFollowRequests() { | ||||
|   return (dispatch, getState) => { | ||||
|     const url = getState().getIn(['user_lists', 'follow_requests', 'next']); | ||||
|  | ||||
|     if (url === null) { | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|     dispatch(expandFollowRequestsRequest()); | ||||
|  | ||||
|     api(getState).get(url).then(response => { | ||||
|       const next = getLinks(response).refs.find(link => link.rel === 'next'); | ||||
|       dispatch(expandFollowRequestsSuccess(response.data, next ? next.uri : null)) | ||||
|     }).catch(error => dispatch(expandFollowRequestsFail(error))); | ||||
|   }; | ||||
| }; | ||||
|  | ||||
| export function expandFollowRequestsRequest() { | ||||
|   return { | ||||
|     type: FOLLOW_REQUESTS_EXPAND_REQUEST | ||||
|   }; | ||||
| }; | ||||
|  | ||||
| export function expandFollowRequestsSuccess(accounts, next) { | ||||
|   return { | ||||
|     type: FOLLOW_REQUESTS_EXPAND_SUCCESS, | ||||
|     accounts, | ||||
|     next | ||||
|   }; | ||||
| }; | ||||
|  | ||||
| export function expandFollowRequestsFail(error) { | ||||
|   return { | ||||
|     type: FOLLOW_REQUESTS_EXPAND_FAIL, | ||||
|     error | ||||
|   }; | ||||
| }; | ||||
|  | ||||
| export function authorizeFollowRequest(id) { | ||||
|   return (dispatch, getState) => { | ||||
|     dispatch(authorizeFollowRequestRequest(id)); | ||||
|  | ||||
|     api(getState) | ||||
|       .post(`/api/v1/follow_requests/${id}/authorize`) | ||||
|       .then(response => dispatch(authorizeFollowRequestSuccess(id))) | ||||
|       .catch(error => dispatch(authorizeFollowRequestFail(id, error))); | ||||
|   }; | ||||
| }; | ||||
|  | ||||
| export function authorizeFollowRequestRequest(id) { | ||||
|   return { | ||||
|     type: FOLLOW_REQUEST_AUTHORIZE_REQUEST, | ||||
|     id | ||||
|   }; | ||||
| }; | ||||
|  | ||||
| export function authorizeFollowRequestSuccess(id) { | ||||
|   return { | ||||
|     type: FOLLOW_REQUEST_AUTHORIZE_SUCCESS, | ||||
|     id | ||||
|   }; | ||||
| }; | ||||
|  | ||||
| export function authorizeFollowRequestFail(id, error) { | ||||
|   return { | ||||
|     type: FOLLOW_REQUEST_AUTHORIZE_FAIL, | ||||
|     id, | ||||
|     error | ||||
|   }; | ||||
| }; | ||||
|  | ||||
|  | ||||
| export function rejectFollowRequest(id) { | ||||
|   return (dispatch, getState) => { | ||||
|     dispatch(rejectFollowRequestRequest(id)); | ||||
|  | ||||
|     api(getState) | ||||
|       .post(`/api/v1/follow_requests/${id}/reject`) | ||||
|       .then(response => dispatch(rejectFollowRequestSuccess(id))) | ||||
|       .catch(error => dispatch(rejectFollowRequestFail(id, error))); | ||||
|   }; | ||||
| }; | ||||
|  | ||||
| export function rejectFollowRequestRequest(id) { | ||||
|   return { | ||||
|     type: FOLLOW_REQUEST_REJECT_REQUEST, | ||||
|     id | ||||
|   }; | ||||
| }; | ||||
|  | ||||
| export function rejectFollowRequestSuccess(id) { | ||||
|   return { | ||||
|     type: FOLLOW_REQUEST_REJECT_SUCCESS, | ||||
|     id | ||||
|   }; | ||||
| }; | ||||
|  | ||||
| export function rejectFollowRequestFail(id, error) { | ||||
|   return { | ||||
|     type: FOLLOW_REQUEST_REJECT_FAIL, | ||||
|     id, | ||||
|     error | ||||
|   }; | ||||
| }; | ||||
|   | ||||
| @@ -27,11 +27,11 @@ const StatusList = React.createClass({ | ||||
|  | ||||
|     this._oldScrollPosition = scrollHeight - scrollTop; | ||||
|  | ||||
|     if (scrollTop === scrollHeight - clientHeight) { | ||||
|     if (scrollTop === scrollHeight - clientHeight && this.props.onScrollToBottom) { | ||||
|       this.props.onScrollToBottom(); | ||||
|     } else if (scrollTop < 100) { | ||||
|     } else if (scrollTop < 100 && this.props.onScrollToTop) { | ||||
|       this.props.onScrollToTop(); | ||||
|     } else { | ||||
|     } else if (this.props.onScroll) { | ||||
|       this.props.onScroll(); | ||||
|     } | ||||
|   }, | ||||
|   | ||||
| @@ -34,6 +34,7 @@ import Reblogs from '../features/reblogs'; | ||||
| import Favourites from '../features/favourites'; | ||||
| import HashtagTimeline from '../features/hashtag_timeline'; | ||||
| import Notifications from '../features/notifications'; | ||||
| import FollowRequests from '../features/follow_requests'; | ||||
| import { IntlProvider, addLocaleData } from 'react-intl'; | ||||
| import en from 'react-intl/locale-data/en'; | ||||
| import de from 'react-intl/locale-data/de'; | ||||
| @@ -125,6 +126,8 @@ const Mastodon = React.createClass({ | ||||
|                 <Route path='followers' component={Followers} /> | ||||
|                 <Route path='following' component={Following} /> | ||||
|               </Route> | ||||
|  | ||||
|               <Route path='follow_requests' component={FollowRequests} /> | ||||
|             </Route> | ||||
|           </Router> | ||||
|         </Provider> | ||||
|   | ||||
| @@ -0,0 +1,61 @@ | ||||
| import ImmutablePropTypes from 'react-immutable-proptypes'; | ||||
| import Permalink from '../../../components/permalink'; | ||||
| import Avatar from '../../../components/avatar'; | ||||
| import DisplayName from '../../../components/display_name'; | ||||
| import emojify from '../../../emoji'; | ||||
| import IconButton from '../../../components/icon_button'; | ||||
| import { defineMessages, injectIntl } from 'react-intl'; | ||||
|  | ||||
| const messages = defineMessages({ | ||||
|   authorize: { id: 'follow_request.authorize', defaultMessage: 'Authorize' }, | ||||
|   reject: { id: 'follow_request.reject', defaultMessage: 'Reject' } | ||||
| }); | ||||
|  | ||||
| const outerStyle = { | ||||
|   padding: '14px 10px' | ||||
| }; | ||||
|  | ||||
| const panelStyle = { | ||||
|   background: '#2f3441', | ||||
|   display: 'flex', | ||||
|   flexDirection: 'row', | ||||
|   borderTop: '1px solid #363c4b', | ||||
|   borderBottom: '1px solid #363c4b', | ||||
|   padding: '10px 0' | ||||
| }; | ||||
|  | ||||
| const btnStyle = { | ||||
|   flex: '1 1 auto', | ||||
|   textAlign: 'center' | ||||
| }; | ||||
|  | ||||
| const AccountAuthorize = ({ intl, account, onAuthorize, onReject }) => { | ||||
|   const content = { __html: emojify(account.get('note')) }; | ||||
|  | ||||
|   return ( | ||||
|     <div> | ||||
|       <div style={outerStyle}> | ||||
|         <Permalink href={account.get('url')} className='detailed-status__display-name' style={{ display: 'block', overflow: 'hidden', marginBottom: '15px' }}> | ||||
|           <div style={{ float: 'left', marginRight: '10px' }}><Avatar src={account.get('avatar')} size={48} /></div> | ||||
|           <DisplayName account={account} /> | ||||
|         </Permalink> | ||||
|  | ||||
|         <div style={{ color: '#616b86', fontSize: '14px' }} className='account__header__content' dangerouslySetInnerHTML={content} /> | ||||
|       </div> | ||||
|  | ||||
|       <div style={panelStyle}> | ||||
|         <div style={btnStyle}><IconButton title={intl.formatMessage(messages.authorize)} icon='check' onClick={onAuthorize} /></div> | ||||
|         <div style={btnStyle}><IconButton title={intl.formatMessage(messages.reject)} icon='times' onClick={onReject} /></div> | ||||
|       </div> | ||||
|     </div> | ||||
|   ) | ||||
| }; | ||||
|  | ||||
| AccountAuthorize.propTypes = { | ||||
|   account: ImmutablePropTypes.map.isRequired, | ||||
|   onAuthorize: React.PropTypes.func.isRequired, | ||||
|   onReject: React.PropTypes.func.isRequired, | ||||
|   intl: React.PropTypes.object.isRequired | ||||
| }; | ||||
|  | ||||
| export default injectIntl(AccountAuthorize); | ||||
| @@ -0,0 +1,26 @@ | ||||
| import { connect } from 'react-redux'; | ||||
| import { makeGetAccount } from '../../../selectors'; | ||||
| import AccountAuthorize from '../components/account_authorize'; | ||||
| import { authorizeFollowRequest, rejectFollowRequest } from '../../../actions/accounts'; | ||||
|  | ||||
| const makeMapStateToProps = () => { | ||||
|   const getAccount = makeGetAccount(); | ||||
|  | ||||
|   const mapStateToProps = (state, props) => ({ | ||||
|     account: getAccount(state, props.id) | ||||
|   }); | ||||
|  | ||||
|   return mapStateToProps; | ||||
| }; | ||||
|  | ||||
| const mapDispatchToProps = (dispatch, { id }) => ({ | ||||
|   onAuthorize (account) { | ||||
|     dispatch(authorizeFollowRequest(id)); | ||||
|   }, | ||||
|  | ||||
|   onReject (account) { | ||||
|     dispatch(rejectFollowRequest(id)); | ||||
|   } | ||||
| }); | ||||
|  | ||||
| export default connect(makeMapStateToProps, mapDispatchToProps)(AccountAuthorize); | ||||
| @@ -0,0 +1,66 @@ | ||||
| import { connect } from 'react-redux'; | ||||
| import PureRenderMixin from 'react-addons-pure-render-mixin'; | ||||
| import ImmutablePropTypes from 'react-immutable-proptypes'; | ||||
| import LoadingIndicator from '../../components/loading_indicator'; | ||||
| import { ScrollContainer } from 'react-router-scroll'; | ||||
| import Column from '../ui/components/column'; | ||||
| import AccountAuthorizeContainer from './containers/account_authorize_container'; | ||||
| import { fetchFollowRequests, expandFollowRequests } from '../../actions/accounts'; | ||||
| import { defineMessages, injectIntl } from 'react-intl'; | ||||
|  | ||||
| const messages = defineMessages({ | ||||
|   heading: { id: 'column.follow_requests', defaultMessage: 'Follow requests' } | ||||
| }); | ||||
|  | ||||
| const mapStateToProps = state => ({ | ||||
|   accountIds: state.getIn(['user_lists', 'follow_requests', 'items']) | ||||
| }); | ||||
|  | ||||
| const FollowRequests = React.createClass({ | ||||
|   propTypes: { | ||||
|     params: React.PropTypes.object.isRequired, | ||||
|     dispatch: React.PropTypes.func.isRequired, | ||||
|     accountIds: ImmutablePropTypes.list, | ||||
|     intl: React.PropTypes.object.isRequired | ||||
|   }, | ||||
|  | ||||
|   mixins: [PureRenderMixin], | ||||
|  | ||||
|   componentWillMount () { | ||||
|     this.props.dispatch(fetchFollowRequests()); | ||||
|   }, | ||||
|  | ||||
|   handleScroll (e) { | ||||
|     const { scrollTop, scrollHeight, clientHeight } = e.target; | ||||
|  | ||||
|     if (scrollTop === scrollHeight - clientHeight) { | ||||
|       this.props.dispatch(expandFollowRequests()); | ||||
|     } | ||||
|   }, | ||||
|  | ||||
|   render () { | ||||
|     const { intl, accountIds } = this.props; | ||||
|  | ||||
|     if (!accountIds) { | ||||
|       return ( | ||||
|         <Column> | ||||
|           <LoadingIndicator /> | ||||
|         </Column> | ||||
|       ); | ||||
|     } | ||||
|  | ||||
|     return ( | ||||
|       <Column icon='users' heading={intl.formatMessage(messages.heading)}> | ||||
|         <ScrollContainer scrollKey='follow_requests'> | ||||
|           <div className='scrollable' onScroll={this.handleScroll}> | ||||
|             {accountIds.map(id => | ||||
|               <AccountAuthorizeContainer key={id} id={id} /> | ||||
|             )} | ||||
|           </div> | ||||
|         </ScrollContainer> | ||||
|       </Column> | ||||
|     ); | ||||
|   } | ||||
| }); | ||||
|  | ||||
| export default connect(mapStateToProps)(injectIntl(FollowRequests)); | ||||
| @@ -7,7 +7,8 @@ import { connect } from 'react-redux'; | ||||
| const messages = defineMessages({ | ||||
|   heading: { id: 'getting_started.heading', defaultMessage: 'Getting started' }, | ||||
|   public_timeline: { id: 'navigation_bar.public_timeline', defaultMessage: 'Public timeline' }, | ||||
|   settings: { id: 'navigation_bar.settings', defaultMessage: 'Settings' } | ||||
|   settings: { id: 'navigation_bar.settings', defaultMessage: 'Settings' }, | ||||
|   follow_requests: { id: 'navigation_bar.follow_requests', defaultMessage: 'Follow requests' } | ||||
| }); | ||||
|  | ||||
| const mapStateToProps = state => ({ | ||||
| @@ -32,6 +33,7 @@ const GettingStarted = ({ intl, me }) => { | ||||
|         <div style={hamburgerStyle}><i className='fa fa-bars' /></div> | ||||
|         <ColumnLink icon='globe' text={intl.formatMessage(messages.public_timeline)} to='/timelines/public' /> | ||||
|         <ColumnLink icon='cog' text={intl.formatMessage(messages.settings)} href='/settings/profile' /> | ||||
|         <ColumnLink icon='users' text={intl.formatMessage(messages.follow_requests)} to='/follow_requests' /> | ||||
|       </div> | ||||
|  | ||||
|       <div className='static-content'> | ||||
| @@ -43,4 +45,9 @@ const GettingStarted = ({ intl, me }) => { | ||||
|   ); | ||||
| }; | ||||
|  | ||||
| GettingStarted.propTypes = { | ||||
|   intl: React.PropTypes.object.isRequired, | ||||
|   me: React.PropTypes.number | ||||
| }; | ||||
|  | ||||
| export default connect(mapStateToProps)(injectIntl(GettingStarted)); | ||||
|   | ||||
| @@ -6,7 +6,8 @@ import { | ||||
|   FOLLOWING_FETCH_SUCCESS, | ||||
|   FOLLOWING_EXPAND_SUCCESS, | ||||
|   ACCOUNT_TIMELINE_FETCH_SUCCESS, | ||||
|   ACCOUNT_TIMELINE_EXPAND_SUCCESS | ||||
|   ACCOUNT_TIMELINE_EXPAND_SUCCESS, | ||||
|   FOLLOW_REQUESTS_FETCH_SUCCESS | ||||
| } from '../actions/accounts'; | ||||
| import { COMPOSE_SUGGESTIONS_READY } from '../actions/compose'; | ||||
| import { | ||||
| @@ -78,6 +79,7 @@ export default function accounts(state = initialState, action) { | ||||
|     case FAVOURITES_FETCH_SUCCESS: | ||||
|     case COMPOSE_SUGGESTIONS_READY: | ||||
|     case SEARCH_SUGGESTIONS_READY: | ||||
|     case FOLLOW_REQUESTS_FETCH_SUCCESS: | ||||
|       return normalizeAccounts(state, action.accounts); | ||||
|     case NOTIFICATIONS_REFRESH_SUCCESS: | ||||
|     case NOTIFICATIONS_EXPAND_SUCCESS: | ||||
|   | ||||
| @@ -2,7 +2,10 @@ import { | ||||
|   FOLLOWERS_FETCH_SUCCESS, | ||||
|   FOLLOWERS_EXPAND_SUCCESS, | ||||
|   FOLLOWING_FETCH_SUCCESS, | ||||
|   FOLLOWING_EXPAND_SUCCESS | ||||
|   FOLLOWING_EXPAND_SUCCESS, | ||||
|   FOLLOW_REQUESTS_FETCH_SUCCESS, | ||||
|   FOLLOW_REQUEST_AUTHORIZE_SUCCESS, | ||||
|   FOLLOW_REQUEST_REJECT_SUCCESS | ||||
| } from '../actions/accounts'; | ||||
| import { | ||||
|   REBLOGS_FETCH_SUCCESS, | ||||
| @@ -14,7 +17,8 @@ const initialState = Immutable.Map({ | ||||
|   followers: Immutable.Map(), | ||||
|   following: Immutable.Map(), | ||||
|   reblogged_by: Immutable.Map(), | ||||
|   favourited_by: Immutable.Map() | ||||
|   favourited_by: Immutable.Map(), | ||||
|   follow_requests: Immutable.Map() | ||||
| }); | ||||
|  | ||||
| const normalizeList = (state, type, id, accounts, next) => { | ||||
| @@ -44,6 +48,11 @@ export default function userLists(state = initialState, action) { | ||||
|       return state.setIn(['reblogged_by', action.id], Immutable.List(action.accounts.map(item => item.id))); | ||||
|     case FAVOURITES_FETCH_SUCCESS: | ||||
|       return state.setIn(['favourited_by', action.id], Immutable.List(action.accounts.map(item => item.id))); | ||||
|     case FOLLOW_REQUESTS_FETCH_SUCCESS: | ||||
|       return state.setIn(['follow_requests', 'items'], Immutable.List(action.accounts.map(item => item.id))).setIn(['follow_requests', 'next'], action.next); | ||||
|     case FOLLOW_REQUEST_AUTHORIZE_SUCCESS: | ||||
|     case FOLLOW_REQUEST_REJECT_SUCCESS: | ||||
|       return state.updateIn(['follow_requests', 'items'], list => list.filterNot(item => item === action.id)); | ||||
|     default: | ||||
|       return state; | ||||
|   } | ||||
|   | ||||
| @@ -1,28 +0,0 @@ | ||||
| # frozen_string_literal: true | ||||
|  | ||||
| class FollowRequestsController < ApplicationController | ||||
|   layout 'auth' | ||||
|  | ||||
|   before_action :authenticate_user! | ||||
|   before_action :set_follow_request, except: :index | ||||
|  | ||||
|   def index | ||||
|     @follow_requests = FollowRequest.where(target_account: current_account) | ||||
|   end | ||||
|  | ||||
|   def authorize | ||||
|     @follow_request.authorize! | ||||
|     redirect_to follow_requests_path | ||||
|   end | ||||
|  | ||||
|   def reject | ||||
|     @follow_request.reject! | ||||
|     redirect_to follow_requests_path | ||||
|   end | ||||
|  | ||||
|   private | ||||
|  | ||||
|   def set_follow_request | ||||
|     @follow_request = FollowRequest.find(params[:id]) | ||||
|   end | ||||
| end | ||||
| @@ -1,2 +0,0 @@ | ||||
| module FollowRequestsHelper | ||||
| end | ||||
| @@ -1,16 +0,0 @@ | ||||
| - content_for :page_title do | ||||
|   = t('follow_requests.title') | ||||
|  | ||||
| - if @follow_requests.empty? | ||||
|   %p.nothing-here= t('accounts.nothing_here') | ||||
| - else | ||||
|   %table.table | ||||
|     %tbody | ||||
|       - @follow_requests.each do |follow_request| | ||||
|         %tr | ||||
|           %td= link_to follow_request.account.acct, web_path("accounts/#{follow_request.account.id}") | ||||
|           %td{ style: 'text-align: right' } | ||||
|             = table_link_to 'check-circle', t('follow_requests.authorize'), authorize_follow_request_path(follow_request), method: :post | ||||
|             = table_link_to 'times-circle', t('follow_requests.reject'), reject_follow_request_path(follow_request), method: :post | ||||
|  | ||||
| .form-footer= render "settings/shared/links" | ||||
| @@ -1,8 +1,6 @@ | ||||
| %ul.no-list | ||||
|   - if controller_name != 'profiles' | ||||
|     %li= link_to t('settings.edit_profile'), settings_profile_path | ||||
|   - if controller_name != 'follow_requests' | ||||
|     %li= link_to t('follow_requests.title'), follow_requests_path | ||||
|   - if controller_name != 'preferences' | ||||
|     %li= link_to t('settings.preferences'), settings_preferences_path | ||||
|   - if controller_name != 'registrations' | ||||
|   | ||||
| @@ -40,10 +40,6 @@ en: | ||||
|       x_minutes: "%{count}m" | ||||
|       x_months: "%{count}mo" | ||||
|       x_seconds: "%{count}s" | ||||
|   follow_requests: | ||||
|     authorize: Authorize | ||||
|     reject: Reject | ||||
|     title: Follow requests | ||||
|   generic: | ||||
|     changes_saved_msg: Changes successfully saved! | ||||
|     powered_by: powered by %{link} | ||||
|   | ||||
| @@ -48,13 +48,6 @@ Rails.application.routes.draw do | ||||
|   resources :media, only: [:show] | ||||
|   resources :tags,  only: [:show] | ||||
|  | ||||
|   resources :follow_requests do | ||||
|     member do | ||||
|       post :authorize | ||||
|       post :reject | ||||
|     end | ||||
|   end | ||||
|  | ||||
|   namespace :admin do | ||||
|     resources :pubsubhubbub, only: [:index] | ||||
|     resources :domain_blocks, only: [:index, :create] | ||||
|   | ||||
| @@ -1,16 +0,0 @@ | ||||
| require 'rails_helper' | ||||
|  | ||||
| RSpec.describe FollowRequestsController, type: :controller do | ||||
|   render_views | ||||
|  | ||||
|   before do | ||||
|     sign_in Fabricate(:user), scope: :user | ||||
|   end | ||||
|  | ||||
|   describe 'GET #index' do | ||||
|     it 'returns http success' do | ||||
|       get :index | ||||
|       expect(response).to have_http_status(:success) | ||||
|     end | ||||
|   end | ||||
| end | ||||
| @@ -1,5 +0,0 @@ | ||||
| require 'rails_helper' | ||||
|  | ||||
| RSpec.describe FollowRequestsHelper, type: :helper do | ||||
|  | ||||
| end | ||||
		Reference in New Issue
	
	Block a user