logo

mastofe

My custom branche(s) on git.pleroma.social/pleroma/mastofe
commit: d0e2733f63a7bd9601e73adee1107da804f85c41
parent: f24cb32e99afdb9fa31067fb647912fec92e9ed4
Author: Eugen Rochko <eugen@zeonfederated.com>
Date:   Sat,  3 Sep 2016 14:01:10 +0200

Fix reblogs of reblogs in UI, add follow form in UI

Diffstat:

Mapp/assets/javascripts/components/actions/follow.jsx16++++++++--------
Aapp/assets/javascripts/components/components/compose_form.jsx57+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Dapp/assets/javascripts/components/components/composer_drawer.jsx57---------------------------------------------------------
Aapp/assets/javascripts/components/components/drawer.jsx17+++++++++++++++++
Aapp/assets/javascripts/components/components/follow_form.jsx40++++++++++++++++++++++++++++++++++++++++
Mapp/assets/javascripts/components/components/frontend.jsx17+++++++++++++----
Aapp/assets/javascripts/components/containers/compose_form_container.jsx29+++++++++++++++++++++++++++++
Dapp/assets/javascripts/components/containers/composer_drawer_container.jsx29-----------------------------
Aapp/assets/javascripts/components/containers/follow_form_container.jsx24++++++++++++++++++++++++
Mapp/assets/javascripts/components/reducers/timelines.jsx2++
Mapp/assets/stylesheets/components.scss2+-
Mapp/models/account.rb4++--
12 files changed, 193 insertions(+), 101 deletions(-)

diff --git a/app/assets/javascripts/components/actions/follow.jsx b/app/assets/javascripts/components/actions/follow.jsx @@ -6,41 +6,41 @@ export const FOLLOW_SUBMIT_REQUEST = 'FOLLOW_SUBMIT_REQUEST'; export const FOLLOW_SUBMIT_SUCCESS = 'FOLLOW_SUBMIT_SUCCESS'; export const FOLLOW_SUBMIT_FAIL = 'FOLLOW_SUBMIT_FAIL'; -export function followChange(text) { +export function changeFollow(text) { return { type: FOLLOW_CHANGE, text: text }; } -export function followSubmit() { +export function submitFollow() { return function (dispatch, getState) { - dispatch(followSubmitRequest()); + dispatch(submitFollowRequest()); api(getState).post('/api/follows', { uri: getState().getIn(['follow', 'text']) }).then(function (response) { - dispatch(followSubmitSuccess(response.data)); + dispatch(submitFollowSuccess(response.data)); }).catch(function (error) { - dispatch(followSubmitFail(error)); + dispatch(submitFollowFail(error)); }); }; } -export function followSubmitRequest() { +export function submitFollowRequest() { return { type: FOLLOW_SUBMIT_REQUEST }; } -export function followSubmitSuccess(account) { +export function submitFollowSuccess(account) { return { type: FOLLOW_SUBMIT_SUCCESS, account: account }; } -export function followSubmitFail(error) { +export function submitFollowFail(error) { return { type: FOLLOW_SUBMIT_FAIL, error: error diff --git a/app/assets/javascripts/components/components/compose_form.jsx b/app/assets/javascripts/components/components/compose_form.jsx @@ -0,0 +1,57 @@ +import CharacterCounter from './character_counter'; +import Button from './button'; +import PureRenderMixin from 'react-addons-pure-render-mixin'; +import ImmutablePropTypes from 'react-immutable-proptypes'; +import ReplyIndicator from './reply_indicator'; + +const ComposeForm = React.createClass({ + + propTypes: { + text: React.PropTypes.string.isRequired, + is_submitting: React.PropTypes.bool, + in_reply_to: ImmutablePropTypes.map, + onChange: React.PropTypes.func.isRequired, + onSubmit: React.PropTypes.func.isRequired, + onCancelReply: React.PropTypes.func.isRequired + }, + + mixins: [PureRenderMixin], + + handleChange (e) { + this.props.onChange(e.target.value); + }, + + handleKeyUp (e) { + if (e.keyCode === 13 && e.ctrlKey) { + this.props.onSubmit(); + } + }, + + handleSubmit () { + this.props.onSubmit(); + }, + + render () { + let replyArea = ''; + + if (this.props.in_reply_to) { + replyArea = <ReplyIndicator status={this.props.in_reply_to} onCancel={this.props.onCancelReply} />; + } + + return ( + <div style={{ marginBottom: '30px', padding: '10px' }}> + {replyArea} + + <textarea disabled={this.props.is_submitting} placeholder='What is on your mind?' value={this.props.text} onKeyUp={this.handleKeyUp} onChange={this.handleChange} className='compose-form__textarea' style={{ display: 'block', boxSizing: 'border-box', width: '100%', height: '100px', resize: 'none', border: 'none', color: '#282c37', padding: '10px', fontFamily: 'Roboto', fontSize: '14px', margin: '0' }} /> + + <div style={{ marginTop: '10px', overflow: 'hidden' }}> + <div style={{ float: 'right' }}><Button text='Publish' onClick={this.handleSubmit} disabled={this.props.is_submitting} /></div> + <div style={{ float: 'right', marginRight: '16px', lineHeight: '36px' }}><CharacterCounter text={this.props.text} /></div> + </div> + </div> + ); + } + +}); + +export default ComposeForm; diff --git a/app/assets/javascripts/components/components/composer_drawer.jsx b/app/assets/javascripts/components/components/composer_drawer.jsx @@ -1,57 +0,0 @@ -import CharacterCounter from './character_counter'; -import Button from './button'; -import PureRenderMixin from 'react-addons-pure-render-mixin'; -import ImmutablePropTypes from 'react-immutable-proptypes'; -import ReplyIndicator from './reply_indicator'; - -const ComposerDrawer = React.createClass({ - - propTypes: { - text: React.PropTypes.string.isRequired, - is_submitting: React.PropTypes.bool, - in_reply_to: ImmutablePropTypes.map, - onChange: React.PropTypes.func.isRequired, - onSubmit: React.PropTypes.func.isRequired, - onCancelReply: React.PropTypes.func.isRequired - }, - - mixins: [PureRenderMixin], - - handleChange (e) { - this.props.onChange(e.target.value); - }, - - handleKeyUp (e) { - if (e.keyCode === 13 && e.ctrlKey) { - this.props.onSubmit(); - } - }, - - handleSubmit () { - this.props.onSubmit(); - }, - - render () { - let replyArea = ''; - - if (this.props.in_reply_to) { - replyArea = <ReplyIndicator status={this.props.in_reply_to} onCancel={this.props.onCancelReply} />; - } - - return ( - <div style={{ width: '280px', boxSizing: 'border-box', background: '#454b5e', margin: '10px', marginRight: '0', padding: '10px' }}> - {replyArea} - - <textarea disabled={this.props.is_submitting} placeholder='What is on your mind?' value={this.props.text} onKeyUp={this.handleKeyUp} onChange={this.handleChange} className='compose-drawer__textarea' style={{ display: 'block', boxSizing: 'border-box', width: '100%', height: '100px', resize: 'none', border: 'none', color: '#282c37', padding: '10px', fontFamily: 'Roboto', fontSize: '14px', margin: '0' }} /> - - <div style={{ marginTop: '10px', overflow: 'hidden' }}> - <div style={{ float: 'right' }}><Button text='Publish' onClick={this.handleSubmit} disabled={this.props.is_submitting} /></div> - <div style={{ float: 'right', marginRight: '16px', lineHeight: '36px' }}><CharacterCounter text={this.props.text} /></div> - </div> - </div> - ); - } - -}); - -export default ComposerDrawer; diff --git a/app/assets/javascripts/components/components/drawer.jsx b/app/assets/javascripts/components/components/drawer.jsx @@ -0,0 +1,17 @@ +import PureRenderMixin from 'react-addons-pure-render-mixin'; + +const Drawer = React.createClass({ + + mixins: [PureRenderMixin], + + render () { + return ( + <div style={{ width: '280px', boxSizing: 'border-box', background: '#454b5e', margin: '10px', marginRight: '0', padding: '0', display: 'flex', flexDirection: 'column' }}> + {this.props.children} + </div> + ); + } + +}); + +export default Drawer; diff --git a/app/assets/javascripts/components/components/follow_form.jsx b/app/assets/javascripts/components/components/follow_form.jsx @@ -0,0 +1,40 @@ +import IconButton from './icon_button'; +import PureRenderMixin from 'react-addons-pure-render-mixin'; + +const FollowForm = React.createClass({ + + propTypes: { + text: React.PropTypes.string.isRequired, + is_submitting: React.PropTypes.bool, + onChange: React.PropTypes.func.isRequired, + onSubmit: React.PropTypes.func.isRequired + }, + + mixins: [PureRenderMixin], + + handleChange (e) { + this.props.onChange(e.target.value); + }, + + handleKeyUp (e) { + if (e.keyCode === 13) { + this.props.onSubmit(); + } + }, + + handleSubmit () { + this.props.onSubmit(); + }, + + render () { + return ( + <div style={{ display: 'flex', lineHeight: '20px', padding: '10px', background: '#373b4a' }}> + <input type='text' disabled={this.props.is_submitting} placeholder='username@domain' value={this.props.text} onKeyUp={this.handleKeyUp} onChange={this.handleChange} className='follow-form__input' style={{ flex: '1 1 auto', boxSizing: 'border-box', display: 'block', border: 'none', padding: '10px', fontFamily: 'Roboto', color: '#282c37', fontSize: '14px', margin: '0' }} /> + <div style={{ padding: '10px', paddingRight: '0' }}><IconButton title='Follow' size={20} icon='user-plus' onClick={this.handleSubmit} disabled={this.props.is_submitting} /></div> + </div> + ); + } + +}); + +export default FollowForm; diff --git a/app/assets/javascripts/components/components/frontend.jsx b/app/assets/javascripts/components/components/frontend.jsx @@ -1,6 +1,8 @@ -import ColumnsArea from './columns_area'; -import ComposerDrawerContainer from '../containers/composer_drawer_container'; -import PureRenderMixin from 'react-addons-pure-render-mixin'; +import ColumnsArea from './columns_area'; +import Drawer from './drawer'; +import ComposeFormContainer from '../containers/compose_form_container'; +import FollowFormContainer from '../containers/follow_form_container'; +import PureRenderMixin from 'react-addons-pure-render-mixin'; const Frontend = React.createClass({ @@ -9,7 +11,14 @@ const Frontend = React.createClass({ render () { return ( <div style={{ flex: '0 0 auto', display: 'flex', width: '100%', height: '100%', background: '#1a1c23' }}> - <ComposerDrawerContainer /> + <Drawer> + <div style={{ flex: '1 1 auto' }}> + <ComposeFormContainer /> + </div> + + <FollowFormContainer /> + </Drawer> + <ColumnsArea /> </div> ); diff --git a/app/assets/javascripts/components/containers/compose_form_container.jsx b/app/assets/javascripts/components/containers/compose_form_container.jsx @@ -0,0 +1,29 @@ +import { connect } from 'react-redux'; +import ComposeForm from '../components/compose_form'; +import { changeCompose, submitCompose, cancelReplyCompose } from '../actions/compose'; + +const mapStateToProps = function (state, props) { + return { + text: state.getIn(['compose', 'text']), + is_submitting: state.getIn(['compose', 'is_submitting']), + in_reply_to: state.getIn(['compose', 'in_reply_to']) + }; +}; + +const mapDispatchToProps = function (dispatch) { + return { + onChange: function (text) { + dispatch(changeCompose(text)); + }, + + onSubmit: function () { + dispatch(submitCompose()); + }, + + onCancelReply: function () { + dispatch(cancelReplyCompose()); + } + } +}; + +export default connect(mapStateToProps, mapDispatchToProps)(ComposeForm); diff --git a/app/assets/javascripts/components/containers/composer_drawer_container.jsx b/app/assets/javascripts/components/containers/composer_drawer_container.jsx @@ -1,29 +0,0 @@ -import { connect } from 'react-redux'; -import ComposerDrawer from '../components/composer_drawer'; -import { changeCompose, submitCompose, cancelReplyCompose } from '../actions/compose'; - -const mapStateToProps = function (state, props) { - return { - text: state.getIn(['compose', 'text']), - is_submitting: state.getIn(['compose', 'is_submitting']), - in_reply_to: state.getIn(['compose', 'in_reply_to']) - }; -}; - -const mapDispatchToProps = function (dispatch) { - return { - onChange: function (text) { - dispatch(changeCompose(text)); - }, - - onSubmit: function () { - dispatch(submitCompose()); - }, - - onCancelReply: function () { - dispatch(cancelReplyCompose()); - } - } -}; - -export default connect(mapStateToProps, mapDispatchToProps)(ComposerDrawer); diff --git a/app/assets/javascripts/components/containers/follow_form_container.jsx b/app/assets/javascripts/components/containers/follow_form_container.jsx @@ -0,0 +1,24 @@ +import { connect } from 'react-redux'; +import FollowForm from '../components/follow_form'; +import { changeFollow, submitFollow } from '../actions/follow'; + +const mapStateToProps = function (state, props) { + return { + text: state.getIn(['follow', 'text']), + is_submitting: state.getIn(['follow', 'is_submitting']) + }; +}; + +const mapDispatchToProps = function (dispatch) { + return { + onChange: function (text) { + dispatch(changeFollow(text)); + }, + + onSubmit: function () { + dispatch(submitFollow()); + } + } +}; + +export default connect(mapStateToProps, mapDispatchToProps)(FollowForm); diff --git a/app/assets/javascripts/components/reducers/timelines.jsx b/app/assets/javascripts/components/reducers/timelines.jsx @@ -9,6 +9,8 @@ function updateMatchingStatuses(state, needle, callback) { return list.map(function (status) { if (status.get('id') === needle.get('id')) { return callback(status); + } else if (status.getIn(['reblog', 'id'], null) === needle.get('id')) { + return status.set('reblog', callback(status.get('reblog'))); } return status; diff --git a/app/assets/stylesheets/components.scss b/app/assets/stylesheets/components.scss @@ -28,7 +28,7 @@ } } -.compose-drawer__textarea { +.compose-form__textarea, .follow-form__input { background: #fff; &:disabled { diff --git a/app/models/account.rb b/app/models/account.rb @@ -59,11 +59,11 @@ class Account < ApplicationRecord end def favourited?(status) - (status.reblog? ? status.reblog : status).favourites.where(account: self).count == 1 + (status.reblog? ? status.reblog : status).favourites.where(account: self).count > 0 end def reblogged?(status) - (status.reblog? ? status.reblog : status).reblogs.where(account: self).count == 1 + (status.reblog? ? status.reblog : status).reblogs.where(account: self).count > 0 end def keypair