diff options
author | Eugen Rochko <eugen@zeonfederated.com> | 2016-09-18 18:18:46 +0200 |
---|---|---|
committer | Eugen Rochko <eugen@zeonfederated.com> | 2016-09-18 18:18:46 +0200 |
commit | 0967961de758b375ca61df1ba9b448aaa2e3c1f8 (patch) | |
tree | 5935732cf384f05b35d30c16814b481d9012661b /app/assets/javascripts/components/features | |
parent | dafcb021534d2a19ff5d4c1f9bedafb52a2ce77f (diff) |
Improve how account detailed view looks, load account's statuses
Diffstat (limited to 'app/assets/javascripts/components/features')
3 files changed, 77 insertions, 47 deletions
diff --git a/app/assets/javascripts/components/features/account/components/header.jsx b/app/assets/javascripts/components/features/account/components/header.jsx new file mode 100644 index 000000000..f113ffc28 --- /dev/null +++ b/app/assets/javascripts/components/features/account/components/header.jsx @@ -0,0 +1,35 @@ +import PureRenderMixin from 'react-addons-pure-render-mixin'; +import ImmutablePropTypes from 'react-immutable-proptypes'; +import Button from '../../../components/button'; + +const Header = React.createClass({ + + propTypes: { + account: ImmutablePropTypes.map.isRequired, + onFollow: React.PropTypes.func.isRequired, + onUnfollow: React.PropTypes.func.isRequired + }, + + mixins: [PureRenderMixin], + + render () { + const { account } = this.props; + + return ( + <div style={{ flex: '0 0 auto', background: '#2f3441', textAlign: 'center', backgroundImage: `url(${account.get('header')})`, backgroundSize: 'cover' }}> + <div style={{ background: 'rgba(47, 52, 65, 0.6)', padding: '30px 10px' }}> + <div style={{ width: '90px', margin: '0 auto', marginBottom: '15px', borderRadius: '90px', overflow: 'hidden' }} className='transparent-background'> + <img src={account.get('avatar')} alt='' style={{ display: 'block', width: '90px', height: '90px', borderRadius: '90px' }} /> + </div> + + <span style={{ color: '#fff', fontSize: '20px', lineHeight: '27px', fontWeight: '500', display: 'block' }}>{account.get('display_name')}</span> + <span style={{ fontSize: '14px', fontWeight: '400', display: 'block', color: '#2b90d9', marginBottom: '15px' }}>@{account.get('acct')}</span> + <p style={{ color: '#616b86', fontSize: '14px' }}>{account.get('note')}</p> + </div> + </div> + ); + } + +}); + +export default Header; diff --git a/app/assets/javascripts/components/features/account/index.jsx b/app/assets/javascripts/components/features/account/index.jsx index 0a940b608..14f22960b 100644 --- a/app/assets/javascripts/components/features/account/index.jsx +++ b/app/assets/javascripts/components/features/account/index.jsx @@ -1,15 +1,25 @@ -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'; +import { connect } from 'react-redux'; +import PureRenderMixin from 'react-addons-pure-render-mixin'; +import ImmutablePropTypes from 'react-immutable-proptypes'; +import { fetchAccount, followAccount, unfollowAccount, fetchAccountTimeline } from '../../actions/accounts'; +import { replyCompose } from '../../actions/compose'; +import { favourite, reblog } from '../../actions/interactions'; +import Header from './components/header'; +import { selectStatus } from '../../reducers/timelines'; +import StatusList from '../../components/status_list'; +import Immutable from 'immutable'; function selectAccount(state, id) { return state.getIn(['timelines', 'accounts', id], null); -} +}; + +function selectStatuses(state, accountId) { + return state.getIn(['timelines', 'accounts_timelines', accountId], Immutable.List()).map(id => selectStatus(state, id)).filterNot(status => status === null); +}; const mapStateToProps = (state, props) => ({ - account: selectAccount(state, Number(props.params.accountId)) + account: selectAccount(state, Number(props.params.accountId)), + statuses: selectStatuses(state, Number(props.params.accountId)) }); const Account = React.createClass({ @@ -17,59 +27,55 @@ const Account = React.createClass({ propTypes: { params: React.PropTypes.object.isRequired, dispatch: React.PropTypes.func.isRequired, - account: ImmutablePropTypes.map + account: ImmutablePropTypes.map, + statuses: ImmutablePropTypes.list }, mixins: [PureRenderMixin], componentWillMount () { - this.props.dispatch(fetchAccount(this.props.params.accountId)); + this.props.dispatch(fetchAccount(Number(this.props.params.accountId))); + this.props.dispatch(fetchAccountTimeline(Number(this.props.params.accountId))); }, componentWillReceiveProps(nextProps) { if (nextProps.params.accountId !== this.props.params.accountId && nextProps.params.accountId) { this.props.dispatch(fetchAccount(nextProps.params.accountId)); + this.props.dispatch(fetchAccountTimeline(nextProps.params.accountId)); } }, - handleFollowClick () { + handleFollow () { this.props.dispatch(followAccount(this.props.account.get('id'))); }, - handleUnfollowClick () { + handleUnfollow () { this.props.dispatch(unfollowAccount(this.props.account.get('id'))); }, + handleReply (status) { + this.props.dispatch(replyCompose(status)); + }, + + handleReblog (status) { + this.props.dispatch(reblog(status)); + }, + + handleFavourite (status) { + this.props.dispatch(favourite(status)); + }, + render () { - const { account } = this.props; - let action; + const { account, statuses } = this.props; 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 style={{ display: 'flex', flexDirection: 'column', 'flex': '0 0 auto', height: '100%' }}> + <Header account={account} onFollow={this.handleFollow} onUnfollow={this.handleUnfollow} /> + <StatusList statuses={statuses} onReply={this.handleReply} onReblog={this.handleReblog} onFavourite={this.handleFavourite} /> </div> ); } diff --git a/app/assets/javascripts/components/features/status/index.jsx b/app/assets/javascripts/components/features/status/index.jsx index 03719d88e..72ff6a944 100644 --- a/app/assets/javascripts/components/features/status/index.jsx +++ b/app/assets/javascripts/components/features/status/index.jsx @@ -6,21 +6,10 @@ import Immutable from 'immutable'; import EmbeddedStatus from '../../components/status'; import { favourite, reblog } from '../../actions/interactions'; import { replyCompose } from '../../actions/compose'; - -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; -}; +import { selectStatus } from '../../reducers/timelines'; function selectStatuses(state, ids) { - return ids.map(id => selectStatus(state, id)); + return ids.map(id => selectStatus(state, id)).filterNot(status => status === null); }; const mapStateToProps = (state, props) => ({ |