parent
004382e4d0
commit
3689c119f0
@ -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)); |
@ -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,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 |
Loading…
Reference in new issue