master
parent
2e7aac793a
commit
5b0cef9781
@ -1,6 +1,44 @@ |
||||
import api from '../api'; |
||||
import axios from 'axios'; |
||||
|
||||
export const STATUS_FETCH = 'STATUS_FETCH'; |
||||
export const STATUS_FETCH_REQUEST = 'STATUS_FETCH_REQUEST'; |
||||
export const STATUS_FETCH_SUCCESS = 'STATUS_FETCH_SUCCESS'; |
||||
export const STATUS_FETCH_FAIL = 'STATUS_FETCH_FAIL'; |
||||
|
||||
export function fetchStatusRequest(id) { |
||||
return { |
||||
type: STATUS_FETCH_REQUEST, |
||||
id: id |
||||
}; |
||||
}; |
||||
|
||||
export function fetchStatus(id) { |
||||
return (dispatch, getState) => { |
||||
const boundApi = api(getState); |
||||
|
||||
dispatch(fetchStatusRequest(id)); |
||||
|
||||
axios.all([boundApi.get(`/api/statuses/${id}`), boundApi.get(`/api/statuses/${id}/context`)]).then(values => { |
||||
dispatch(fetchStatusSuccess(values[0].data, values[1].data)); |
||||
}).catch(error => { |
||||
dispatch(fetchStatusFail(id, error)); |
||||
}); |
||||
}; |
||||
}; |
||||
|
||||
export function fetchStatusSuccess(status, context) { |
||||
return { |
||||
type: STATUS_FETCH_SUCCESS, |
||||
status: status, |
||||
context: context |
||||
}; |
||||
}; |
||||
|
||||
export function fetchStatusFail(id, error) { |
||||
return { |
||||
type: STATUS_FETCH_FAIL, |
||||
id: id, |
||||
error: error |
||||
}; |
||||
}; |
||||
|
@ -0,0 +1,79 @@ |
||||
import { connect } from 'react-redux'; |
||||
import PureRenderMixin from 'react-addons-pure-render-mixin'; |
||||
import ImmutablePropTypes from 'react-immutable-proptypes'; |
||||
import { fetchAccount, followAccount, unfollowAccount } from '../../actions/accounts'; |
||||
import Button from '../../components/button'; |
||||
|
||||
function selectAccount(state, id) { |
||||
return state.getIn(['timelines', 'accounts', id], null); |
||||
} |
||||
|
||||
const mapStateToProps = (state, props) => ({ |
||||
account: selectAccount(state, Number(props.params.accountId)) |
||||
}); |
||||
|
||||
const Account = React.createClass({ |
||||
|
||||
propTypes: { |
||||
params: React.PropTypes.object.isRequired, |
||||
dispatch: React.PropTypes.func.isRequired, |
||||
account: ImmutablePropTypes.map |
||||
}, |
||||
|
||||
mixins: [PureRenderMixin], |
||||
|
||||
componentWillMount () { |
||||
this.props.dispatch(fetchAccount(this.props.params.accountId)); |
||||
}, |
||||
|
||||
componentWillReceiveProps(nextProps) { |
||||
if (nextProps.params.accountId !== this.props.params.accountId && nextProps.params.accountId) { |
||||
this.props.dispatch(fetchAccount(nextProps.params.accountId)); |
||||
} |
||||
}, |
||||
|
||||
handleFollowClick () { |
||||
this.props.dispatch(followAccount(this.props.account.get('id'))); |
||||
}, |
||||
|
||||
handleUnfollowClick () { |
||||
this.props.dispatch(unfollowAccount(this.props.account.get('id'))); |
||||
}, |
||||
|
||||
render () { |
||||
const { account } = this.props; |
||||
let action; |
||||
|
||||
if (account === null) { |
||||
return <div>Loading {this.props.params.accountId}...</div>; |
||||
} |
||||
|
||||
if (account.get('following')) { |
||||
action = <Button text='Unfollow' onClick={this.handleUnfollowClick} />; |
||||
} else { |
||||
action = <Button text='Follow' onClick={this.handleFollowClick} /> |
||||
} |
||||
|
||||
return ( |
||||
<div> |
||||
<p> |
||||
{account.get('display_name')} |
||||
{account.get('acct')} |
||||
</p> |
||||
|
||||
{account.get('url')} |
||||
|
||||
<p>{account.get('note')}</p> |
||||
|
||||
{account.get('followers_count')} followers<br /> |
||||
{account.get('following_count')} following<br /> |
||||
{account.get('statuses_count')} posts |
||||
|
||||
<p>{action}</p> |
||||
</div> |
||||
); |
||||
} |
||||
|
||||
}); |
||||
|
||||
export default connect(mapStateToProps)(Account); |
@ -0,0 +1,28 @@ |
||||
import { connect } from 'react-redux'; |
||||
import PureRenderMixin from 'react-addons-pure-render-mixin'; |
||||
import ImmutablePropTypes from 'react-immutable-proptypes'; |
||||
|
||||
const mapStateToProps = (state, props) => ({ |
||||
|
||||
}); |
||||
|
||||
const Settings = React.createClass({ |
||||
|
||||
propTypes: { |
||||
params: React.PropTypes.object.isRequired, |
||||
dispatch: React.PropTypes.func.isRequired |
||||
}, |
||||
|
||||
mixins: [PureRenderMixin], |
||||
|
||||
componentWillMount () { |
||||
// |
||||
}, |
||||
|
||||
render () { |
||||
return <div>Settings</div>; |
||||
} |
||||
|
||||
}); |
||||
|
||||
export default connect(mapStateToProps)(Settings); |
@ -0,0 +1,74 @@ |
||||
import { connect } from 'react-redux'; |
||||
import PureRenderMixin from 'react-addons-pure-render-mixin'; |
||||
import ImmutablePropTypes from 'react-immutable-proptypes'; |
||||
import { fetchStatus } from '../../actions/statuses'; |
||||
import Immutable from 'immutable'; |
||||
import EmbeddedStatus from '../../components/status'; |
||||
|
||||
function selectStatus(state, id) { |
||||
let status = state.getIn(['timelines', 'statuses', id]); |
||||
|
||||
status = status.set('account', state.getIn(['timelines', 'accounts', status.get('account')])); |
||||
|
||||
if (status.get('reblog') !== null) { |
||||
status = status.set('reblog', selectStatus(state, status.get('reblog'))); |
||||
} |
||||
|
||||
return status; |
||||
}; |
||||
|
||||
function selectStatuses(state, ids) { |
||||
return ids.map(id => selectStatus(state, id)); |
||||
}; |
||||
|
||||
const mapStateToProps = (state, props) => ({ |
||||
status: selectStatus(state, Number(props.params.statusId)), |
||||
ancestors: selectStatuses(state, state.getIn(['timelines', 'ancestors', Number(props.params.statusId)], Immutable.List())), |
||||
descendants: selectStatuses(state, state.getIn(['timelines', 'descendants', Number(props.params.statusId)], Immutable.List())) |
||||
}); |
||||
|
||||
const Status = React.createClass({ |
||||
|
||||
propTypes: { |
||||
params: React.PropTypes.object.isRequired, |
||||
dispatch: React.PropTypes.func.isRequired, |
||||
status: ImmutablePropTypes.map, |
||||
ancestors: ImmutablePropTypes.list.isRequired, |
||||
descendants: ImmutablePropTypes.list.isRequired |
||||
}, |
||||
|
||||
mixins: [PureRenderMixin], |
||||
|
||||
componentWillMount () { |
||||
this.props.dispatch(fetchStatus(this.props.params.statusId)); |
||||
}, |
||||
|
||||
componentWillReceiveProps (nextProps) { |
||||
if (nextProps.params.statusId !== this.props.params.statusId && nextProps.params.statusId) { |
||||
this.props.dispatch(fetchStatus(nextProps.params.statusId)); |
||||
} |
||||
}, |
||||
|
||||
renderChildren (list) { |
||||
return list.map(s => <EmbeddedStatus status={s} key={s.get('id')} />); |
||||
}, |
||||
|
||||
render () { |
||||
const { status, ancestors, descendants } = this.props; |
||||
|
||||
if (status === null) { |
||||
return <div>Loading {this.props.params.statusId}...</div>; |
||||
} |
||||
|
||||
return ( |
||||
<div> |
||||
{this.renderChildren(ancestors)} |
||||
<EmbeddedStatus status={status} /> |
||||
{this.renderChildren(descendants)} |
||||
</div> |
||||
); |
||||
} |
||||
|
||||
}); |
||||
|
||||
export default connect(mapStateToProps)(Status); |
@ -0,0 +1,28 @@ |
||||
import { connect } from 'react-redux'; |
||||
import PureRenderMixin from 'react-addons-pure-render-mixin'; |
||||
import ImmutablePropTypes from 'react-immutable-proptypes'; |
||||
|
||||
const mapStateToProps = (state, props) => ({ |
||||
|
||||
}); |
||||
|
||||
const Subscriptions = React.createClass({ |
||||
|
||||
propTypes: { |
||||
params: React.PropTypes.object.isRequired, |
||||
dispatch: React.PropTypes.func.isRequired |
||||
}, |
||||
|
||||
mixins: [PureRenderMixin], |
||||
|
||||
componentWillMount () { |
||||
// |
||||
}, |
||||
|
||||
render () { |
||||
return <div>Subscriptions</div>; |
||||
} |
||||
|
||||
}); |
||||
|
||||
export default connect(mapStateToProps)(Subscriptions); |
@ -0,0 +1,13 @@ |
||||
object false |
||||
|
||||
node :ancestors do |
||||
@ancestors.map do |status| |
||||
partial('api/statuses/show', object: status) |
||||
end |
||||
end |
||||
|
||||
node :descendants do |
||||
@descendants.map do |status| |
||||
partial('api/statuses/show', object: status) |
||||
end |
||||
end |
Loading…
Reference in new issue